summaryrefslogtreecommitdiffstats
path: root/sandbox/old/contrib/implementation-ruby/container/src/main/java/org/apache/tuscany/container/ruby/RubyReferenceProxy.java
diff options
context:
space:
mode:
Diffstat (limited to 'sandbox/old/contrib/implementation-ruby/container/src/main/java/org/apache/tuscany/container/ruby/RubyReferenceProxy.java')
-rw-r--r--sandbox/old/contrib/implementation-ruby/container/src/main/java/org/apache/tuscany/container/ruby/RubyReferenceProxy.java127
1 files changed, 127 insertions, 0 deletions
diff --git a/sandbox/old/contrib/implementation-ruby/container/src/main/java/org/apache/tuscany/container/ruby/RubyReferenceProxy.java b/sandbox/old/contrib/implementation-ruby/container/src/main/java/org/apache/tuscany/container/ruby/RubyReferenceProxy.java
new file mode 100644
index 0000000000..4d91194484
--- /dev/null
+++ b/sandbox/old/contrib/implementation-ruby/container/src/main/java/org/apache/tuscany/container/ruby/RubyReferenceProxy.java
@@ -0,0 +1,127 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.container.ruby;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+
+import org.jruby.IRuby;
+import org.jruby.RubyException;
+
+import net.sf.cglib.asm.ClassWriter;
+import net.sf.cglib.asm.CodeVisitor;
+import net.sf.cglib.asm.Constants;
+import net.sf.cglib.asm.Type;
+
+/**
+ * This is a proxy that will mediate reference calls from the JavaScript. The mediation code here will be reviewed when the DataMediation
+ * infrastructure is ready. This proxy assmes that there is no verloading of service methods on the reference interface i.e. there are no two service
+ * methods that have the same method name or operation name.
+ */
+public class RubyReferenceProxy {
+
+ private Class interfaze;
+
+ private Object wireProxy;
+
+ private IRuby rubyEngine;
+
+ public RubyReferenceProxy(Class interfaze, Object wireProxy, IRuby rubyEng) {
+ this.interfaze = interfaze;
+ this.wireProxy = wireProxy;
+ this.rubyEngine = rubyEng;
+ }
+
+ public Object createProxy() {
+ try {
+ GenericProxyClassLoader classloader = new GenericProxyClassLoader();
+ final byte[] byteCode = generateGenericInterface(interfaze);
+
+ Class genericInterface = classloader.defineClass(byteCode);
+ InvocationHandler proxyHandler = new RubyRefInvocInterceptor(wireProxy, interfaze, rubyEngine);
+ // return genericInterface.cast(Proxy.newProxyInstance(classloader, new Class[]{genericInterface}, proxyHandler));
+ return Proxy.newProxyInstance(classloader,
+ new Class[]{genericInterface},
+ proxyHandler);
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ private static byte[] generateGenericInterface(Class serviceInterface) {
+ String interfazeName = serviceInterface.getCanonicalName();
+ ClassWriter cw = new ClassWriter(false);
+
+ cw.visit(Constants.V1_5,
+ Constants.ACC_PUBLIC + Constants.ACC_ABSTRACT + Constants.ACC_INTERFACE,
+ interfazeName.replace('.',
+ '/'),
+ "java/lang/Object",
+ null,
+ serviceInterface.getSimpleName() + ".java");
+
+ StringBuffer argsAndReturn = new StringBuffer("(");
+ Method[] methods = serviceInterface.getMethods();
+ for (int count = 0; count < methods.length; ++count) {
+ argsAndReturn = new StringBuffer("(");
+ Class[] paramTypes = methods[count].getParameterTypes();
+ Class returnType = methods[count].getReturnType();
+
+ for (int paramCount = 0; paramCount < paramTypes.length; ++paramCount) {
+ argsAndReturn.append(Type.getType(Object.class));
+ }
+ argsAndReturn.append(")");
+ argsAndReturn.append(Type.getType(Object.class));
+
+ Class[] exceptionTypes = methods[count].getExceptionTypes();
+ String[] exceptions = new String[exceptionTypes.length];
+ for (int excCount = 0; excCount < exceptionTypes.length; ++excCount) {
+ exceptions[excCount] = exceptionTypes[excCount].getName();
+ exceptions[excCount] = exceptions[excCount].replace('.',
+ '/');
+ }
+
+ CodeVisitor cv = cw.visitMethod(Constants.ACC_PUBLIC + Constants.ACC_ABSTRACT,
+ methods[count].getName(),
+ argsAndReturn.toString(),
+ exceptions,
+ null);
+ cw.visitEnd();
+ }
+
+ cw.visitEnd();
+
+ return cw.toByteArray();
+ }
+
+ private class GenericProxyClassLoader extends ClassLoader {
+ public Class defineClass(byte[] byteArray) {
+ try {
+ return defineClass(null,
+ byteArray,
+ 0,
+ byteArray.length);
+ } catch (Throwable e) {
+ return null;
+ }
+ }
+
+ }
+}