Author: lresende
Date: Tue Jan 20 09:16:46 2009
New Revision: 736041

URL: http://svn.apache.org/viewvc?rev=736041&view=rev
Log:
TUSCANY-2270 - Applying patch from Rodolfo Dias to enable conversation to 
binding.rmi

Modified:
    tuscany/java/sca/modules/binding-rmi-runtime/pom.xml
    
tuscany/java/sca/modules/binding-rmi-runtime/src/main/java/org/apache/tuscany/sca/binding/rmi/provider/RMIBindingInvoker.java
    
tuscany/java/sca/modules/binding-rmi-runtime/src/main/java/org/apache/tuscany/sca/binding/rmi/provider/RMIReferenceBindingProvider.java
    
tuscany/java/sca/modules/binding-rmi-runtime/src/main/java/org/apache/tuscany/sca/binding/rmi/provider/RMIServiceBindingProvider.java
    
tuscany/java/sca/modules/binding-rmi-runtime/src/test/java/helloworld/HelloException.java
    
tuscany/java/sca/modules/binding-rmi-runtime/src/test/java/helloworld/HelloWorldImpl.java
    
tuscany/java/sca/modules/binding-rmi-runtime/src/test/java/helloworld/HelloWorldRmiImpl.java
    
tuscany/java/sca/modules/binding-rmi-runtime/src/test/java/helloworld/HelloWorldRmiService.java
    
tuscany/java/sca/modules/binding-rmi-runtime/src/test/java/helloworld/HelloWorldService.java
    
tuscany/java/sca/modules/binding-rmi-runtime/src/test/java/org/apache/tuscany/sca/binding/rmi/BindingTestCase.java
    
tuscany/java/sca/modules/binding-rmi-runtime/src/test/resources/HelloWorldRmiImpl.componentType
    
tuscany/java/sca/modules/binding-rmi-runtime/src/test/resources/RMIBindingTest.composite

Modified: tuscany/java/sca/modules/binding-rmi-runtime/pom.xml
URL: 
http://svn.apache.org/viewvc/tuscany/java/sca/modules/binding-rmi-runtime/pom.xml?rev=736041&r1=736040&r2=736041&view=diff
==============================================================================
--- tuscany/java/sca/modules/binding-rmi-runtime/pom.xml (original)
+++ tuscany/java/sca/modules/binding-rmi-runtime/pom.xml Tue Jan 20 09:16:46 
2009
@@ -56,11 +56,17 @@
 
         <dependency>
             <groupId>org.apache.tuscany.sca</groupId>
+            <artifactId>tuscany-core</artifactId>
+            <version>2.0-SNAPSHOT</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.tuscany.sca</groupId>
             <artifactId>tuscany-implementation-java-runtime</artifactId>
             <version>2.0-SNAPSHOT</version>
             <scope>test</scope>
         </dependency>
-
+        
         <dependency>
             <groupId>org.apache.tuscany.sca</groupId>
             <artifactId>tuscany-node-impl</artifactId>

Modified: 
tuscany/java/sca/modules/binding-rmi-runtime/src/main/java/org/apache/tuscany/sca/binding/rmi/provider/RMIBindingInvoker.java
URL: 
http://svn.apache.org/viewvc/tuscany/java/sca/modules/binding-rmi-runtime/src/main/java/org/apache/tuscany/sca/binding/rmi/provider/RMIBindingInvoker.java?rev=736041&r1=736040&r2=736041&view=diff
==============================================================================
--- 
tuscany/java/sca/modules/binding-rmi-runtime/src/main/java/org/apache/tuscany/sca/binding/rmi/provider/RMIBindingInvoker.java
 (original)
+++ 
tuscany/java/sca/modules/binding-rmi-runtime/src/main/java/org/apache/tuscany/sca/binding/rmi/provider/RMIBindingInvoker.java
 Tue Jan 20 09:16:46 2009
@@ -23,61 +23,193 @@
 import java.rmi.Remote;
 
 import org.apache.tuscany.sca.host.rmi.RMIHost;
+import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.interfacedef.java.impl.JavaInterfaceUtil;
+import org.apache.tuscany.sca.invocation.DataExchangeSemantics;
 import org.apache.tuscany.sca.invocation.Invoker;
 import org.apache.tuscany.sca.invocation.Message;
-import org.apache.tuscany.sca.invocation.DataExchangeSemantics;
 
 /**
  * Invoker for RMI References.
- *
+ * 
+ * When invoke is fire, the Service Interface can be Conversational or not, 
when
+ * Service Interface is conversational, so the Conversational Service Interface
+ * is created and loaded. Conversational Service Interface is responsable to
+ * carry conversationId to server side.
+ * 
  * @version $Rev$ $Date$
  */
 public class RMIBindingInvoker implements Invoker, DataExchangeSemantics {
 
-    private RMIHost rmiHost;
-    private String uri;
-    private Method remoteMethod;
-    private Remote proxy;
-
-    public RMIBindingInvoker(RMIHost rmiHost, String uri, Method remoteMethod) 
{
-        this.rmiHost = rmiHost;
-        this.remoteMethod = remoteMethod;
-        this.uri = uri;
-    }
-
-    public Message invoke(Message msg) {
-        try {
-
-            Object[] args = msg.getBody();
-            Object resp = invokeTarget(args);
-            msg.setBody(resp);
-    
-        } catch (InvocationTargetException e) {
-            msg.setFaultBody(e.getCause());
-        } catch (Throwable e) {
-            msg.setFaultBody(e);
-        }
-
-        return msg;
-    }
-
-    public Object invokeTarget(final Object payload) throws 
InvocationTargetException, SecurityException, NoSuchMethodException, 
IllegalArgumentException, IllegalAccessException {
-        if (proxy == null) {
-            proxy = rmiHost.findService(uri);
-        }
-
-        remoteMethod = proxy.getClass().getMethod(remoteMethod.getName(), 
remoteMethod.getParameterTypes());
-
-        if (payload != null && !payload.getClass().isArray()) {
-            return remoteMethod.invoke(proxy, payload);
-        } else {
-            return remoteMethod.invoke(proxy, (Object[])payload);
-        }
-    }
-
-    public boolean allowsPassByReference() {
-        // RMI always pass by value
-        return true;
-    }
-
+       private RMIHost rmiHost;
+       private String uri;
+       private Method referenceMethod;
+       private Remote proxy;
+       private Class<?> serviceInterface;
+
+       public RMIBindingInvoker(RMIHost rmiHost, String uri,
+                       Class<?> serviceInterface, Operation operation) {
+               this.rmiHost = rmiHost;
+               this.uri = uri;
+               this.serviceInterface = serviceInterface;
+               try {
+                       this.referenceMethod = JavaInterfaceUtil.findMethod(
+                                       serviceInterface, operation);
+               } catch (NoSuchMethodException e) {
+                       throw new IllegalArgumentException(e);
+               }
+               ;
+       }
+
+       public Message invoke(Message msg) {
+               try {
+                       Object conversationId = 
msg.getFrom().getReferenceParameters().getConversationID();
+                       boolean isConversational = conversationId != null;
+                       Object resp;
+                       if (isConversational) {
+                               initProxy(serviceInterface, true);
+                               resp = invokeConversational(conversationId, 
msg.getBody());
+                       } else {
+                               initProxy(serviceInterface, false);
+                               resp = invokeTarget(msg.getBody());
+                       }
+                       msg.setBody(resp);
+               } catch (InvocationTargetException e) {
+                       Throwable cause = getCause(e);
+                       if (cause == null) {
+                               cause = e.getCause();
+                       }
+                       msg.setFaultBody(cause);
+               } catch (Throwable e) {
+                       msg.setFaultBody(e);
+               }
+               return msg;
+       }
+
+       /**
+        * Find Remote Service
+        * 
+        * If Service Interface is conversational the Conversational Service
+        * Interface is created and loaded, this is necessary because RMI 
looking
+        * for Conversational Service Interface in client side, when any method 
in
+        * conversational service interface is called.
+        * 
+        * @param serviceInterface
+        *            The Service Interface
+        * @param isConversational
+        *            Indicate if Service Interface is Conversational.
+        */
+       private void initProxy(Class<?> serviceInterface, boolean 
isConversational) {
+               if (proxy == null) {
+                       if (isConversational) {
+                               
ConversationalServiceInterfaceFactory.create(serviceInterface);
+                       }
+                       proxy = rmiHost.findService(uri);
+               }
+       }
+
+       /**
+        * Get the original throwable.
+        * 
+        * If throwable was throws by Service Interface, than original 
throwable is
+        * returned, else null is returned.
+        * 
+        * @param e The final Throwable
+        * @return The Original Throwable or null
+        */
+       private Throwable getCause(Throwable e) {
+               Throwable cause = e.getCause();
+               Throwable expectedCause = null;
+               for (Class<?> declaredType : 
referenceMethod.getExceptionTypes()) {
+                       if (declaredType.isInstance(cause)) {
+                               expectedCause = cause;
+                               break;
+                       }
+               }
+               if (expectedCause == null) {
+                       expectedCause = getCause(cause);
+               }
+               return expectedCause;
+       }
+
+       /**
+        * Invoke the Method in Conversational Service Interface. This method 
verify
+        * the parameters of reference method and create a new argument, that 
take the
+        * conversationId.
+        * 
+        * @param conversationId
+        *            The ConversationId generated by SCA
+        * @param args
+        *            The parameters of Method of Service Interface
+        * @return The result of Method executed.
+        * @throws InvocationTargetException
+        * @throws SecurityException
+        * @throws NoSuchMethodException
+        * @throws IllegalArgumentException
+        * @throws IllegalAccessException
+        */
+       private Object invokeConversational(Object conversationId, Object args)
+                       throws InvocationTargetException, SecurityException,
+                       NoSuchMethodException, IllegalArgumentException,
+                       IllegalAccessException {
+               Object[] newParameters = null;
+               Class<?>[] newParametersType = null;
+               if (isWithoutParameters(args)) {
+                       newParameters = new Object[1];
+                       newParametersType = new Class[1];
+               } else {
+                       Object[] parameters = (Object[]) args;
+                       newParameters = new Object[parameters.length + 1];
+                       System.arraycopy(args, 0, newParameters, 0, 
parameters.length);
+                       Class<?>[] refParameters = 
referenceMethod.getParameterTypes();
+                       newParametersType = new Class[refParameters.length + 1];
+                       System.arraycopy(refParameters, 0, newParametersType, 
0, refParameters.length);
+               }
+               newParameters[newParameters.length - 1] = new 
ConversationalParameter(conversationId);
+               newParametersType[newParametersType.length - 1] = 
ConversationalParameter.class;
+               Method conversationalMethod = 
proxy.getClass().getMethod(referenceMethod.getName(), newParametersType);
+               return invoke(conversationalMethod, proxy, newParameters);
+       }
+
+       /**
+        * Invoke the Method in Service Interface
+        * 
+        * @param parameters
+        *            The parameters of Method of Service Interface
+        * @return The result of Method executed.
+        * @throws InvocationTargetException
+        * @throws SecurityException
+        * @throws NoSuchMethodException
+        * @throws IllegalArgumentException
+        * @throws IllegalAccessException
+        */
+       private Object invokeTarget(final Object parameters)
+                       throws InvocationTargetException, SecurityException,
+                       NoSuchMethodException, IllegalArgumentException,
+                       IllegalAccessException {
+               
+               Method remoteMethod = 
proxy.getClass().getMethod(referenceMethod.getName(), 
referenceMethod.getParameterTypes());
+               return invoke(remoteMethod, proxy, parameters);
+       }
+
+       private Object invoke(Method remoteMethod, Remote proxy,
+                       final Object parameters) throws 
InvocationTargetException,
+                       SecurityException, NoSuchMethodException, 
IllegalArgumentException,
+                       IllegalAccessException {
+               
+               if (parameters != null && !parameters.getClass().isArray()) {
+                       return remoteMethod.invoke(proxy, parameters);
+               } else {
+                       return remoteMethod.invoke(proxy, (Object[]) 
parameters);
+               }
+       }
+
+       public boolean allowsPassByReference() {
+               // RMI always pass by value
+               return true;
+       }
+
+       private boolean isWithoutParameters(Object parameters) {
+               return (parameters == null || (parameters.getClass().isArray() 
&& ((Object[]) parameters).length == 0));
+       }
 }

Modified: 
tuscany/java/sca/modules/binding-rmi-runtime/src/main/java/org/apache/tuscany/sca/binding/rmi/provider/RMIReferenceBindingProvider.java
URL: 
http://svn.apache.org/viewvc/tuscany/java/sca/modules/binding-rmi-runtime/src/main/java/org/apache/tuscany/sca/binding/rmi/provider/RMIReferenceBindingProvider.java?rev=736041&r1=736040&r2=736041&view=diff
==============================================================================
--- 
tuscany/java/sca/modules/binding-rmi-runtime/src/main/java/org/apache/tuscany/sca/binding/rmi/provider/RMIReferenceBindingProvider.java
 (original)
+++ 
tuscany/java/sca/modules/binding-rmi-runtime/src/main/java/org/apache/tuscany/sca/binding/rmi/provider/RMIReferenceBindingProvider.java
 Tue Jan 20 09:16:46 2009
@@ -19,14 +19,11 @@
 
 package org.apache.tuscany.sca.binding.rmi.provider;
 
-import java.lang.reflect.Method;
-
 import org.apache.tuscany.sca.binding.rmi.RMIBinding;
 import org.apache.tuscany.sca.host.rmi.RMIHost;
 import org.apache.tuscany.sca.interfacedef.InterfaceContract;
 import org.apache.tuscany.sca.interfacedef.Operation;
 import org.apache.tuscany.sca.interfacedef.java.JavaInterface;
-import org.apache.tuscany.sca.interfacedef.java.impl.JavaInterfaceUtil;
 import org.apache.tuscany.sca.invocation.Invoker;
 import org.apache.tuscany.sca.provider.ReferenceBindingProvider;
 import org.apache.tuscany.sca.runtime.RuntimeComponent;
@@ -39,43 +36,37 @@
  */
 public class RMIReferenceBindingProvider implements ReferenceBindingProvider {
 
-    private RuntimeComponentReference reference;
-    private RMIBinding binding;
-    private RMIHost rmiHost;
-    
-    public RMIReferenceBindingProvider(RuntimeComponent component,
-                                           RuntimeComponentReference reference,
-                                           RMIBinding binding,
-                                           RMIHost rmiHost) {
-           this.reference = reference;
-           this.binding = binding;
-           this.rmiHost = rmiHost;
-    }
-
-    public InterfaceContract getBindingInterfaceContract() {
-        return reference.getInterfaceContract();
-    }
-    
-    public Invoker createInvoker(Operation operation) {
-        Class<?> iface = 
((JavaInterface)reference.getInterfaceContract().getInterface()).getJavaClass();
-        Method remoteMethod;
-        try {
-            remoteMethod = JavaInterfaceUtil.findMethod(iface, operation);
-        } catch (NoSuchMethodException e) {
-            throw new IllegalArgumentException(e);
-        }
-
-        return new RMIBindingInvoker(rmiHost, binding.getURI(), remoteMethod);
-    }
-
-    public void start() {
-    }
-
-    public void stop() {
-    }
-
-    public boolean supportsOneWayInvocation() {
-        return false;
-    }
+       private RuntimeComponentReference reference;
+       private RMIBinding binding;
+       private RMIHost rmiHost;
+
+       public RMIReferenceBindingProvider(RuntimeComponent component,
+                       RuntimeComponentReference reference, RMIBinding binding,
+                       RMIHost rmiHost) {
+               this.reference = reference;
+               this.binding = binding;
+               this.rmiHost = rmiHost;
+       }
+
+       public InterfaceContract getBindingInterfaceContract() {
+               return reference.getInterfaceContract();
+       }
+
+       public Invoker createInvoker(Operation operation) {
+               Class<?> serviceInterface = ((JavaInterface) reference
+                               
.getInterfaceContract().getInterface()).getJavaClass();
+               return new RMIBindingInvoker(rmiHost, binding.getURI(),
+                               serviceInterface, operation);
+       }
+
+       public void start() {
+       }
+
+       public void stop() {
+       }
+
+       public boolean supportsOneWayInvocation() {
+               return false;
+       }
 
 }

Modified: 
tuscany/java/sca/modules/binding-rmi-runtime/src/main/java/org/apache/tuscany/sca/binding/rmi/provider/RMIServiceBindingProvider.java
URL: 
http://svn.apache.org/viewvc/tuscany/java/sca/modules/binding-rmi-runtime/src/main/java/org/apache/tuscany/sca/binding/rmi/provider/RMIServiceBindingProvider.java?rev=736041&r1=736040&r2=736041&view=diff
==============================================================================
--- 
tuscany/java/sca/modules/binding-rmi-runtime/src/main/java/org/apache/tuscany/sca/binding/rmi/provider/RMIServiceBindingProvider.java
 (original)
+++ 
tuscany/java/sca/modules/binding-rmi-runtime/src/main/java/org/apache/tuscany/sca/binding/rmi/provider/RMIServiceBindingProvider.java
 Tue Jan 20 09:16:46 2009
@@ -19,29 +19,24 @@
 
 package org.apache.tuscany.sca.binding.rmi.provider;
 
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.rmi.Remote;
+import java.rmi.RemoteException;
 import java.rmi.server.UnicastRemoteObject;
-import java.security.AccessController;
-import java.security.PrivilegedExceptionAction;
+import java.util.ArrayList;
+import java.util.List;
 
 import net.sf.cglib.asm.ClassWriter;
 import net.sf.cglib.asm.Type;
 import net.sf.cglib.core.Constants;
 import net.sf.cglib.proxy.Enhancer;
-import net.sf.cglib.proxy.MethodInterceptor;
-import net.sf.cglib.proxy.MethodProxy;
 
 import org.apache.tuscany.sca.binding.rmi.RMIBinding;
 import org.apache.tuscany.sca.host.rmi.RMIHost;
 import org.apache.tuscany.sca.host.rmi.RMIHostException;
 import org.apache.tuscany.sca.interfacedef.Interface;
 import org.apache.tuscany.sca.interfacedef.InterfaceContract;
-import org.apache.tuscany.sca.interfacedef.Operation;
 import org.apache.tuscany.sca.interfacedef.java.JavaInterface;
-import org.apache.tuscany.sca.interfacedef.java.impl.JavaInterfaceUtil;
 import org.apache.tuscany.sca.provider.ServiceBindingProvider;
 import org.apache.tuscany.sca.runtime.RuntimeComponent;
 import org.apache.tuscany.sca.runtime.RuntimeComponentService;
@@ -50,162 +45,140 @@
 
 /**
  * Implementation of a Service for the RMIBinding.
- *
+ * 
  * @version $Rev$ $Date$
  */
 public class RMIServiceBindingProvider implements ServiceBindingProvider {
 
-    private RuntimeComponent component;
-    private RuntimeComponentService service;
-    private RMIBinding binding;
-    private RMIHost rmiHost;
-    private RuntimeWire wire;
-
-    public RMIServiceBindingProvider(RuntimeComponent rc, 
RuntimeComponentService rcs, RMIBinding binding, RMIHost rmiHost) {
-        this.component = rc;
-        this.service = rcs;
-        this.binding = binding;
-        this.rmiHost = rmiHost;
-    }
-
-    public void start() {
-        // URI uri = URI.create(component.getURI() + "/" + binding.getName());
-        // binding.setURI(uri.toString());
-
-        wire = service.getRuntimeWire(binding);
-        Interface serviceInterface = 
service.getInterfaceContract().getInterface();
-
-        Remote rmiProxy = createRmiService(serviceInterface);
-
-        try {
-
-            rmiHost.registerService(binding.getURI(), rmiProxy);
-
-        } catch (RMIHostException e) {
-            throw new ServiceRuntimeException(e);
-        }
-    }
-
-    public void stop() {
-        rmiHost.unregisterService(binding.getURI());
-    }
-
-    private int getPort(String port) {
-        int portNumber = RMIHost.RMI_DEFAULT_PORT;
-        if (port != null && port.length() > 0) {
-            portNumber = Integer.decode(port);
-        }
-        return portNumber;
-    }
-
-    private Remote createRmiService(final Interface serviceInterface) {
-        Enhancer enhancer = new Enhancer();
-        enhancer.setSuperclass(UnicastRemoteObject.class);
-        enhancer.setCallback(new MethodInterceptor() {
-            public Object intercept(Object arg0, Method method, Object[] args, 
MethodProxy arg3) throws Throwable {
-                try {
-                    return 
invokeTarget(JavaInterfaceUtil.findOperation(method, 
serviceInterface.getOperations()), args);
-                } catch (InvocationTargetException e) {
-                    final Throwable cause = e.getCause();
-                    for (Class<?> declaredType : method.getExceptionTypes()) {
-                        if (declaredType.isInstance(cause)) {
-                            throw e;
-                        }
-                    }
-
-                    if (cause.getCause() != null) {
-                        // TUSCANY-2545: don't inlcude nested cause object
-                        AccessController.doPrivileged(new 
PrivilegedExceptionAction<Object>() {
-                            public Object run() throws Exception {
-                                Field field = 
Throwable.class.getDeclaredField("cause");
-                                field.setAccessible(true);
-                                field.set(cause, null);
-                                field.setAccessible(false);
-                                return null;
-                            }
-                        });
-                    }
-
-                    throw cause;
-                }
-            }
-        });
-        Class targetJavaInterface = getTargetJavaClass(serviceInterface);
-        if (!Remote.class.isAssignableFrom(targetJavaInterface)) {
-            RMIServiceClassLoader classloader = new 
RMIServiceClassLoader(targetJavaInterface.getClassLoader());
-            final byte[] byteCode = 
generateRemoteInterface(targetJavaInterface);
-            targetJavaInterface = 
classloader.defineClass(targetJavaInterface.getName(), byteCode);
-            enhancer.setClassLoader(classloader);
-        }
-        enhancer.setInterfaces(new Class[] {targetJavaInterface});
-        return (Remote)enhancer.create();
-    }
-
-    private Object invokeTarget(Operation op, Object[] args) throws 
InvocationTargetException {
-        return wire.invoke(op, args);
-    }
-
-    /**
-     * if the interface of the component whose serviceBindings must be exposed 
as RMI Service, does not
-     * implement java.rmi.Remote, then generate such an interface. This method 
will stop with just 
-     * generating the bytecode. Defining the class from the byte code must be 
the responsibility of the 
-     * caller of this method, since it requires a ClassLoader to be created to 
define and load this interface.
-     */
-    private byte[] generateRemoteInterface(Class serviceInterface) {
-        String interfazeName = serviceInterface.getName();
-        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
-
-        String simpleName = serviceInterface.getSimpleName();
-        cw.visit(Constants.V1_5, Constants.ACC_PUBLIC + Constants.ACC_ABSTRACT 
+ Constants.ACC_INTERFACE, interfazeName
-            .replace('.', '/'), null, "java/lang/Object", new String[] 
{"java/rmi/Remote"});
-
-        StringBuffer argsAndReturn = null;
-        Method[] methods = serviceInterface.getMethods();
-        for (Method method : methods) {
-            argsAndReturn = new StringBuffer("(");
-            Class[] paramTypes = method.getParameterTypes();
-            Class returnType = method.getReturnType();
-
-            for (Class paramType : paramTypes) {
-                argsAndReturn.append(Type.getType(paramType));
-            }
-            argsAndReturn.append(")");
-            argsAndReturn.append(Type.getType(returnType));
-
-            cw.visitMethod(Constants.ACC_PUBLIC + Constants.ACC_ABSTRACT,
-                           method.getName(),
-                           argsAndReturn.toString(),
-                           null,
-                           new String[] {"java/rmi/RemoteException"});
-        }
-        cw.visitEnd();
-        return cw.toByteArray();
-    }
-
-    private Class<?> getTargetJavaClass(Interface targetInterface) {
-        // TODO: right now assume that the target is always a Java
-        // Implementation. Need to figure out
-        // how to generate Java Interface in cases where the target is not a
-        // Java Implementation
-        return ((JavaInterface)targetInterface).getJavaClass();
-    }
-
-    protected class RMIServiceClassLoader extends ClassLoader {
-        public RMIServiceClassLoader(ClassLoader parent) {
-            super(parent);
-        }
-
-        public Class defineClass(String name, byte[] byteArray) {
-            return defineClass(name, byteArray, 0, byteArray.length);
-        }
-    }
-
-    public InterfaceContract getBindingInterfaceContract() {
-        return service.getInterfaceContract();
-    }
-
-    public boolean supportsOneWayInvocation() {
-        return false;
-    }
-    
+       private RuntimeComponent component;
+       private RuntimeComponentService service;
+       private RMIBinding binding;
+       private RMIHost rmiHost;
+       private RuntimeWire wire;
+
+       public RMIServiceBindingProvider(RuntimeComponent component,
+                       RuntimeComponentService service, RMIBinding binding, 
RMIHost rmiHost) {
+               this.component = component;
+               this.service = service;
+               this.binding = binding;
+               this.rmiHost = rmiHost;
+       }
+
+       public void start() {
+               wire = service.getRuntimeWire(binding);
+               Interface serviceInterface = service.getInterfaceContract()
+                               .getInterface();
+               Remote rmiProxy = createRmiService(serviceInterface);
+               try {
+                       rmiHost.registerService(binding.getURI(), rmiProxy);
+               } catch (RMIHostException e) {
+                       throw new ServiceRuntimeException(e);
+               }
+       }
+
+       public void stop() {
+               rmiHost.unregisterService(binding.getURI());
+       }
+
+       protected Remote createRmiService(final Interface serviceInterface) {
+               Enhancer enhancer = new Enhancer();
+               enhancer.setSuperclass(UnicastRemoteObject.class);
+               enhancer.setCallback(new RMIMethodInterceptor(wire, 
serviceInterface));
+               Class<?> targetJavaInterface = 
getTargetJavaClass(serviceInterface);
+               List<Class<?>> interfaces = new ArrayList<Class<?>>();
+               RMIServiceClassLoader classloader = new RMIServiceClassLoader(
+                               targetJavaInterface.getClassLoader());
+               if (!Remote.class.isAssignableFrom(targetJavaInterface)) {
+                       final byte[] byteCode = 
generateRemoteInterface(targetJavaInterface);
+                       targetJavaInterface = 
classloader.defineClass(targetJavaInterface
+                                       .getName(), byteCode);
+               }
+               interfaces.add(targetJavaInterface);
+               if (serviceInterface.isConversational()) {
+                       Class<?> conversationalInterface = 
ConversationalServiceInterfaceFactory
+                                       .create(targetJavaInterface);
+                       final byte[] byteCode = 
generateRemoteInterface(conversationalInterface);
+                       conversationalInterface = classloader.defineClass(
+                                       conversationalInterface.getName(), 
byteCode);
+                       interfaces.add(conversationalInterface);
+               }
+               enhancer.setClassLoader(classloader);
+               enhancer.setInterfaces(interfaces.toArray(new Class[] {}));
+               return (Remote) enhancer.create();
+       }
+
+       /**
+        * if the interface of the component whose serviceBindings must be 
exposed
+        * as RMI Service, does not implement java.rmi.Remote, then generate 
such an
+        * interface. This method will stop with just generating the bytecode.
+        * Defining the class from the byte code must be the responsibility of 
the
+        * caller of this method, since it requires a ClassLoader to be created 
to
+        * define and load this interface.
+        */
+       private byte[] generateRemoteInterface(Class serviceInterface) {
+               String interfazeName = serviceInterface.getName();
+               ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
+
+               cw.visit(Constants.V1_5, Constants.ACC_PUBLIC + 
Constants.ACC_ABSTRACT
+                               + Constants.ACC_INTERFACE, 
interfazeName.replace('.', '/'),
+                               null, "java/lang/Object", new String[] { 
"java/rmi/Remote" });
+               StringBuffer argsAndReturn = null;
+               Method[] methods = serviceInterface.getMethods();
+               for (Method method : methods) {
+                       argsAndReturn = new StringBuffer("(");
+                       Class<?>[] paramTypes = method.getParameterTypes();
+                       Class<?> returnType = method.getReturnType();
+
+                       for (Class<?> paramType : paramTypes) {
+                               argsAndReturn.append(Type.getType(paramType));
+                       }
+                       argsAndReturn.append(")");
+                       argsAndReturn.append(Type.getType(returnType));
+
+                       boolean hasRemoteException = false;
+                       List<String> exceptions = new ArrayList<String>();
+                       Class<?>[] exceptionTypes = method.getExceptionTypes();
+                       for (int i = 0, s = exceptionTypes.length; i < s; i++) {
+                               if 
(exceptionTypes[i].equals(RemoteException.class)) {
+                                       hasRemoteException = true;
+                               }
+                               
exceptions.add(exceptionTypes[i].getName().replace('.', '/'));
+                       }
+                       if (!hasRemoteException) {
+                               exceptions.add("java/rmi/RemoteException");
+                       }
+                       cw.visitMethod(Constants.ACC_PUBLIC + 
Constants.ACC_ABSTRACT,
+                                       method.getName(), 
argsAndReturn.toString(), null,
+                                       exceptions.toArray(new String[] {}));
+               }
+               cw.visitEnd();
+               return cw.toByteArray();
+       }
+
+       private Class<?> getTargetJavaClass(Interface targetInterface) {
+               // TODO: right now assume that the target is always a Java
+               // Implementation. Need to figure out
+               // how to generate Java Interface in cases where the target is 
not a
+               // Java Implementation
+               return ((JavaInterface) targetInterface).getJavaClass();
+       }
+
+       protected class RMIServiceClassLoader extends ClassLoader {
+               public RMIServiceClassLoader(ClassLoader parent) {
+                       super(parent);
+               }
+
+               public Class defineClass(String name, byte[] byteArray) {
+                       return defineClass(name, byteArray, 0, 
byteArray.length);
+               }
+       }
+
+       public InterfaceContract getBindingInterfaceContract() {
+               return service.getInterfaceContract();
+       }
+
+       public boolean supportsOneWayInvocation() {
+               return false;
+       }
+
 }

Modified: 
tuscany/java/sca/modules/binding-rmi-runtime/src/test/java/helloworld/HelloException.java
URL: 
http://svn.apache.org/viewvc/tuscany/java/sca/modules/binding-rmi-runtime/src/test/java/helloworld/HelloException.java?rev=736041&r1=736040&r2=736041&view=diff
==============================================================================
--- 
tuscany/java/sca/modules/binding-rmi-runtime/src/test/java/helloworld/HelloException.java
 (original)
+++ 
tuscany/java/sca/modules/binding-rmi-runtime/src/test/java/helloworld/HelloException.java
 Tue Jan 20 09:16:46 2009
@@ -24,37 +24,37 @@
  */
 public class HelloException extends Exception {
 
-    /**
-     * 
-     */
-    private static final long serialVersionUID = 2570611055132507470L;
-
-    /**
-     * 
-     */
-    public HelloException() {
-    }
-
-    /**
-     * @param message
-     */
-    public HelloException(String message) {
-        super(message);
-    }
-
-    /**
-     * @param cause
-     */
-    public HelloException(Throwable cause) {
-        super(cause);
-    }
-
-    /**
-     * @param message
-     * @param cause
-     */
-    public HelloException(String message, Throwable cause) {
-        super(message, cause);
-    }
+       /**
+        * 
+        */
+       private static final long serialVersionUID = 2570611055132507470L;
+
+       /**
+        * 
+        */
+       public HelloException() {
+       }
+
+       /**
+        * @param message
+        */
+       public HelloException(String message) {
+               super(message);
+       }
+
+       /**
+        * @param cause
+        */
+       public HelloException(Throwable cause) {
+               super(cause);
+       }
+
+       /**
+        * @param message
+        * @param cause
+        */
+       public HelloException(String message, Throwable cause) {
+               super(message, cause);
+       }
 
 }

Modified: 
tuscany/java/sca/modules/binding-rmi-runtime/src/test/java/helloworld/HelloWorldImpl.java
URL: 
http://svn.apache.org/viewvc/tuscany/java/sca/modules/binding-rmi-runtime/src/test/java/helloworld/HelloWorldImpl.java?rev=736041&r1=736040&r2=736041&view=diff
==============================================================================
--- 
tuscany/java/sca/modules/binding-rmi-runtime/src/test/java/helloworld/HelloWorldImpl.java
 (original)
+++ 
tuscany/java/sca/modules/binding-rmi-runtime/src/test/java/helloworld/HelloWorldImpl.java
 Tue Jan 20 09:16:46 2009
@@ -20,23 +20,23 @@
 
 import org.osoa.sca.annotations.Service;
 
-
 /**
  * This class implements the HelloWorld service.
- *
+ * 
  * @version $Rev$ $Date$
  */
 @Service(HelloWorldService.class)
 public class HelloWorldImpl implements HelloWorldService {
 
-    public String sayHello(String name) {
-        return "Hello from the RMI Service to - " + name;
-    }
-    
-    public String sayHi(String name, String greeter) throws HelloException {
-        if (name == null || greeter == null) {
-            throw new HelloException("Invalid name or greeter: name=" + name + 
" greeter=" + greeter);
-        }
-        return "Hi from " + greeter + " in RMI Service to - " + name;
-    }
+       public String sayHello(String name) {
+               return "Hello from the RMI Service to - " + name;
+       }
+
+       public String sayHi(String name, String greeter) throws HelloException {
+               if (name == null || greeter == null) {
+                       throw new HelloException("Invalid name or greeter: 
name=" + name
+                                       + " greeter=" + greeter);
+               }
+               return "Hi from " + greeter + " in RMI Service to - " + name;
+       }
 }

Modified: 
tuscany/java/sca/modules/binding-rmi-runtime/src/test/java/helloworld/HelloWorldRmiImpl.java
URL: 
http://svn.apache.org/viewvc/tuscany/java/sca/modules/binding-rmi-runtime/src/test/java/helloworld/HelloWorldRmiImpl.java?rev=736041&r1=736040&r2=736041&view=diff
==============================================================================
--- 
tuscany/java/sca/modules/binding-rmi-runtime/src/test/java/helloworld/HelloWorldRmiImpl.java
 (original)
+++ 
tuscany/java/sca/modules/binding-rmi-runtime/src/test/java/helloworld/HelloWorldRmiImpl.java
 Tue Jan 20 09:16:46 2009
@@ -19,32 +19,70 @@
 package helloworld;
 
 import org.osoa.sca.annotations.Reference;
+import org.osoa.sca.annotations.Scope;
 import org.osoa.sca.annotations.Service;
 
 /**
- * This class implements the HelloWorld service.
- *
+ * This class implements the HelloWorld service. The Scope is CONVERSATION to
+ * test the RMI Conversational Service and Conversational in interface and
+ * Scope("CONVERSATION") in Implementation keep the same instance of the
+ * references. But only references conversational are Stateful.
+ * HelloWorldService is stateless is keep stateless.
+ * HelloWorldConversationalService is stateful.
+ * 
+ * When BindingTestCase take a instance of HelloWorldRmiImpl it is use the same
+ * instance of the HelloWorldRmiImpl to all method invocation, how
+ * extConversationService is conversational (stateful) too, your state is keep
+ * between call, differently of the extService that is stateless.
+ * 
  * @version $Rev$ $Date$
  */
 @Service(HelloWorldRmiService.class)
+...@scope("CONVERSATION")
 public class HelloWorldRmiImpl implements HelloWorldRmiService {
-    private HelloWorldService extService;
-
-    public HelloWorldService getExtService() {
-        return extService;
-    }
-
-    @Reference
-    public void setExtService(HelloWorldService extService) {
-        this.extService = extService;
-    }
-
-    public String sayRmiHello(String name) {
-        return extService.sayHello(name) + " thro the RMI Reference";
-    }
-    
-    public String sayRmiHi(String name, String greeter) throws HelloException {
-        return extService.sayHi(name, greeter) + " thro the RMI Reference";
-    }
+       private HelloWorldService extService;
+       private HelloWorldConversationalService extConversationalService;
+       private static final String COMPLEMENT = " thro the RMI Reference";
+
+       public HelloWorldService getExtService() {
+               return extService;
+       }
+
+       @Reference
+       public void setExtService(HelloWorldService extService) {
+               this.extService = extService;
+       }
+
+       @Reference
+       public void setExtConversationalService(
+                       HelloWorldConversationalService 
extConversationalService) {
+               this.extConversationalService = extConversationalService;
+       }
+
+       public String sayRmiHello(String name) {
+               return extService.sayHello(name) + COMPLEMENT;
+       }
+
+       public String sayRmiHi(String name, String greeter) throws 
HelloException {
+               return extService.sayHi(name, greeter) + COMPLEMENT;
+       }
+
+       public String getConversationalHello() {
+               return extConversationalService.getHello() + COMPLEMENT;
+       }
+
+       public String getConversationalHi() {
+               return extConversationalService.getHi() + COMPLEMENT;
+       }
+
+       public void sayRmiConversationalHello(String name) {
+               extConversationalService.sayHello(name);
+
+       }
+
+       public void sayRmiConversationalHi(String name, String greeter)
+                       throws HelloException {
+               extConversationalService.sayHi(name, greeter);
+       }
 
 }

Modified: 
tuscany/java/sca/modules/binding-rmi-runtime/src/test/java/helloworld/HelloWorldRmiService.java
URL: 
http://svn.apache.org/viewvc/tuscany/java/sca/modules/binding-rmi-runtime/src/test/java/helloworld/HelloWorldRmiService.java?rev=736041&r1=736040&r2=736041&view=diff
==============================================================================
--- 
tuscany/java/sca/modules/binding-rmi-runtime/src/test/java/helloworld/HelloWorldRmiService.java
 (original)
+++ 
tuscany/java/sca/modules/binding-rmi-runtime/src/test/java/helloworld/HelloWorldRmiService.java
 Tue Jan 20 09:16:46 2009
@@ -18,14 +18,36 @@
  */
 package helloworld;
 
+import org.osoa.sca.annotations.Conversational;
+
 /**
- * This is the business interface of the HelloWorld greetings service.
- *
+ * This is the business interface of the HelloWorld greetings service. This
+ * interface is Conversational to test the RMI Conversational Service and
+ * Conversational in interface and Scope("CONVERSATION") in Implementation keep
+ * the same instance of the references. But only references conversational are
+ * Stateful. HelloWorldService is stateless is keep stateless.
+ * HelloWorldConversationalService is stateful.
+ * 
+ * When BindingTestCase take a instance of HelloWorldRmiImpl it is use the same
+ * instance of the HelloWorldRmiImpl in all method invocation, how
+ * extConversationService is conversational (stateful) too, your state is keep
+ * between call, differently of the extService that is stateless.
+ * 
  * @version $Rev$ $Date$
  */
+...@conversational
 public interface HelloWorldRmiService {
 
-    String sayRmiHello(String name);
-    String sayRmiHi(String name, String greeter) throws HelloException;
+       String sayRmiHello(String name);
+
+       String sayRmiHi(String name, String greeter) throws HelloException;
+
+       void sayRmiConversationalHello(String name);
+
+       void sayRmiConversationalHi(String name, String greeter)
+                       throws HelloException;
+
+       String getConversationalHello();
 
+       String getConversationalHi();
 }

Modified: 
tuscany/java/sca/modules/binding-rmi-runtime/src/test/java/helloworld/HelloWorldService.java
URL: 
http://svn.apache.org/viewvc/tuscany/java/sca/modules/binding-rmi-runtime/src/test/java/helloworld/HelloWorldService.java?rev=736041&r1=736040&r2=736041&view=diff
==============================================================================
--- 
tuscany/java/sca/modules/binding-rmi-runtime/src/test/java/helloworld/HelloWorldService.java
 (original)
+++ 
tuscany/java/sca/modules/binding-rmi-runtime/src/test/java/helloworld/HelloWorldService.java
 Tue Jan 20 09:16:46 2009
@@ -20,12 +20,13 @@
 
 /**
  * This is the business interface of the HelloWorld greetings service.
- *
+ * 
  * @version $Rev$ $Date$
  */
 public interface HelloWorldService {
 
-    String sayHello(String name);
-    String sayHi(String name, String greeter) throws HelloException;
+       String sayHello(String name);
+
+       String sayHi(String name, String greeter) throws HelloException;
 
 }

Modified: 
tuscany/java/sca/modules/binding-rmi-runtime/src/test/java/org/apache/tuscany/sca/binding/rmi/BindingTestCase.java
URL: 
http://svn.apache.org/viewvc/tuscany/java/sca/modules/binding-rmi-runtime/src/test/java/org/apache/tuscany/sca/binding/rmi/BindingTestCase.java?rev=736041&r1=736040&r2=736041&view=diff
==============================================================================
--- 
tuscany/java/sca/modules/binding-rmi-runtime/src/test/java/org/apache/tuscany/sca/binding/rmi/BindingTestCase.java
 (original)
+++ 
tuscany/java/sca/modules/binding-rmi-runtime/src/test/java/org/apache/tuscany/sca/binding/rmi/BindingTestCase.java
 Tue Jan 20 09:16:46 2009
@@ -39,8 +39,26 @@
     private static HelloWorldRmiService helloWorldRmiService;
     private static Node node;
 
+    @BeforeClass
+    public static void init() throws Exception {
+        try {
+            String contribution = 
ContributionLocationHelper.getContributionLocation(BindingTestCase.class);
+            node = 
NodeFactory.newInstance().createNode("RMIBindingTest.composite", new 
Contribution("test", contribution));
+            node.start();
+            helloWorldRmiService = node.getService(HelloWorldRmiService.class, 
"HelloWorldRmiServiceComponent");
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    @AfterClass
+    public static void destroy() throws Exception {
+        node.stop();
+        node.destroy();
+    }
+
     @Test
-    public void testRmiService() {
+    public void performRmiNormalService() {
         String msg = helloWorldRmiService.sayRmiHello("Tuscany World!");
         System.out.println(msg);
         Assert.assertEquals("Hello from the RMI Service to - Tuscany World! 
thro the RMI Reference", msg);
@@ -60,22 +78,28 @@
         }
     }
 
-    @BeforeClass
-    public static void init() throws Exception {
+    @Test
+    public void performRmiConversationalService() {
+        helloWorldRmiService.sayRmiConversationalHello("Tuscany World!");
+        String msg = helloWorldRmiService.getConversationalHello();
+        System.out.println(msg);
+        Assert.assertEquals("Hello from the RMI Service to - Tuscany World! 
thro the RMI Reference", msg);
+
         try {
-            String contribution = 
ContributionLocationHelper.getContributionLocation(BindingTestCase.class);
-            node = 
NodeFactory.newInstance().createNode("RMIBindingTest.composite", new 
Contribution("test", contribution));
-            node.start();
-            helloWorldRmiService = node.getService(HelloWorldRmiService.class, 
"HelloWorldRmiServiceComponent");
-        } catch (Exception e) {
-            e.printStackTrace();
+            helloWorldRmiService.sayRmiConversationalHi("Tuscany World!", 
"Apache World");
+            msg = helloWorldRmiService.getConversationalHi();
+            System.out.println(msg);
+            Assert.assertEquals("Hi from Apache World in RMI Service to - 
Tuscany World! thro the RMI Reference", msg);
+        } catch (HelloException e) {
+            Assert.fail(e.getMessage());
+        }
+        try {
+            helloWorldRmiService.sayRmiConversationalHi(null, "Apache World");
+            Assert.fail("HelloException should have been thrown");
+        } catch (HelloException e) {
+            System.out.println("Expected exception :" + 
e.getClass().getName());
         }
     }
 
-    @AfterClass
-    public static void destroy() throws Exception {
-        node.stop();
-        node.destroy();
-    }
 
 }

Modified: 
tuscany/java/sca/modules/binding-rmi-runtime/src/test/resources/HelloWorldRmiImpl.componentType
URL: 
http://svn.apache.org/viewvc/tuscany/java/sca/modules/binding-rmi-runtime/src/test/resources/HelloWorldRmiImpl.componentType?rev=736041&r1=736040&r2=736041&view=diff
==============================================================================
--- 
tuscany/java/sca/modules/binding-rmi-runtime/src/test/resources/HelloWorldRmiImpl.componentType
 (original)
+++ 
tuscany/java/sca/modules/binding-rmi-runtime/src/test/resources/HelloWorldRmiImpl.componentType
 Tue Jan 20 09:16:46 2009
@@ -24,4 +24,7 @@
        <reference name="extService">
                <interface.java interface="helloworld.HelloWorldService"/>
        </reference>
+       <reference name="extConversationalService">
+               <interface.java 
interface="helloworld.HelloWorldConversationalService"/>
+       </reference>
 </componentType>

Modified: 
tuscany/java/sca/modules/binding-rmi-runtime/src/test/resources/RMIBindingTest.composite
URL: 
http://svn.apache.org/viewvc/tuscany/java/sca/modules/binding-rmi-runtime/src/test/resources/RMIBindingTest.composite?rev=736041&r1=736040&r2=736041&view=diff
==============================================================================
--- 
tuscany/java/sca/modules/binding-rmi-runtime/src/test/resources/RMIBindingTest.composite
 (original)
+++ 
tuscany/java/sca/modules/binding-rmi-runtime/src/test/resources/RMIBindingTest.composite
 Tue Jan 20 09:16:46 2009
@@ -20,24 +20,37 @@
 <composite xmlns="http://www.osoa.org/xmlns/sca/1.0";
               xmlns:tuscany="http://tuscany.apache.org/xmlns/sca/1.0";
            name="HelloWorldRmiComposite">
-
+           
+       <!--                            PROVIDER                         -->
        <service name="HelloWorldRmiService" 
promote="HelloWorldServiceComponent">
         <interface.java interface="helloworld.HelloWorldService"/>
         <tuscany:binding.rmi 
uri="rmi://localhost:8099/HelloWorldRemoteService"   />
     </service>
-      
     <component name="HelloWorldServiceComponent">
         <implementation.java class="helloworld.HelloWorldImpl"/>
     </component>   
   
+    <service name="HelloWorldRmiConversationalService" 
promote="HelloWorldConversationalServiceComponent">
+        <interface.java 
interface="helloworld.HelloWorldConversationalService"/>
+        <tuscany:binding.rmi 
uri="rmi://localhost:8099/HelloWorldRemoteConversationalService"/>
+    </service>
+    <component name="HelloWorldConversationalServiceComponent">
+        <implementation.java class="helloworld.HelloWorldConversationalImpl"/>
+    </component>  
+    
+    <!--                               CONSUMER                        -->    
    <component name="HelloWorldRmiServiceComponent">
         <implementation.java class="helloworld.HelloWorldRmiImpl"/>
         <reference name="extService"></reference>
+        <reference name="extConversationalService"></reference>
     </component>        
            
        <reference name="HelloWorldRmiReference" 
promote="HelloWorldRmiServiceComponent/extService">
         <interface.java interface="helloworld.HelloWorldService"/>
         <tuscany:binding.rmi 
uri="rmi://localhost:8099/HelloWorldRemoteService"   />
     </reference>
-
+       <reference name="HelloWorldRmiConversationalReference" 
promote="HelloWorldRmiServiceComponent/extConversationalService">
+        <interface.java 
interface="helloworld.HelloWorldConversationalService"/>
+        <tuscany:binding.rmi 
uri="rmi://localhost:8099/HelloWorldRemoteConversationalService"   />
+    </reference>
 </composite>


Reply via email to