You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tuscany.apache.org by an...@apache.org on 2010/02/11 05:21:01 UTC

svn commit: r908835 - in /tuscany/sca-java-2.x/trunk/modules: binding-sca-runtime/ binding-sca-runtime/META-INF/ binding-sca-runtime/src/main/java/org/apache/tuscany/sca/binding/sca/provider/ core-databinding/src/main/java/org/apache/tuscany/sca/core/d...

Author: antelder
Date: Thu Feb 11 04:21:00 2010
New Revision: 908835

URL: http://svn.apache.org/viewvc?rev=908835&view=rev
Log:
TUSCANY-2586: Fix pass-by-value copies as described in the JIRA with the SCA binding doing the necessary copies. Also update the copy code so that the new copy is in the correct class loader so that invocations across Nodes in the same JVM work

Modified:
    tuscany/sca-java-2.x/trunk/modules/binding-sca-runtime/META-INF/MANIFEST.MF
    tuscany/sca-java-2.x/trunk/modules/binding-sca-runtime/pom.xml
    tuscany/sca-java-2.x/trunk/modules/binding-sca-runtime/src/main/java/org/apache/tuscany/sca/binding/sca/provider/RuntimeSCAReferenceBindingProvider.java
    tuscany/sca-java-2.x/trunk/modules/binding-sca-runtime/src/main/java/org/apache/tuscany/sca/binding/sca/provider/SCABindingInvoker.java
    tuscany/sca-java-2.x/trunk/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/wire/DataBindingRuntimeWireProcessor.java
    tuscany/sca-java-2.x/trunk/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBDataBinding.java
    tuscany/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/DataBinding.java
    tuscany/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/DefaultDataBindingExtensionPoint.java
    tuscany/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/Mediator.java
    tuscany/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/impl/BaseDataBinding.java
    tuscany/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/impl/MediatorImpl.java
    tuscany/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/javabeans/JavaBeansDataBinding.java

Modified: tuscany/sca-java-2.x/trunk/modules/binding-sca-runtime/META-INF/MANIFEST.MF
URL: http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/binding-sca-runtime/META-INF/MANIFEST.MF?rev=908835&r1=908834&r2=908835&view=diff
==============================================================================
--- tuscany/sca-java-2.x/trunk/modules/binding-sca-runtime/META-INF/MANIFEST.MF (original)
+++ tuscany/sca-java-2.x/trunk/modules/binding-sca-runtime/META-INF/MANIFEST.MF Thu Feb 11 04:21:00 2010
@@ -16,6 +16,7 @@
  org.apache.tuscany.sca.contribution.processor;version="2.0.0",
  org.apache.tuscany.sca.contribution.resolver;version="2.0.0";resolution:=optional,
  org.apache.tuscany.sca.core;version="2.0.0",
+ org.apache.tuscany.sca.databinding;version="2.0.0",
  org.apache.tuscany.sca.definitions;version="2.0.0",
  org.apache.tuscany.sca.interfacedef;version="2.0.0",
  org.apache.tuscany.sca.invocation;version="2.0.0",

Modified: tuscany/sca-java-2.x/trunk/modules/binding-sca-runtime/pom.xml
URL: http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/binding-sca-runtime/pom.xml?rev=908835&r1=908834&r2=908835&view=diff
==============================================================================
--- tuscany/sca-java-2.x/trunk/modules/binding-sca-runtime/pom.xml (original)
+++ tuscany/sca-java-2.x/trunk/modules/binding-sca-runtime/pom.xml Thu Feb 11 04:21:00 2010
@@ -58,7 +58,7 @@
 
          <dependency>
             <groupId>org.apache.tuscany.sca</groupId>
-            <artifactId>tuscany-core-spi</artifactId>
+            <artifactId>tuscany-databinding</artifactId>
             <version>2.0-SNAPSHOT</version>
         </dependency>       
         

Modified: tuscany/sca-java-2.x/trunk/modules/binding-sca-runtime/src/main/java/org/apache/tuscany/sca/binding/sca/provider/RuntimeSCAReferenceBindingProvider.java
URL: http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/binding-sca-runtime/src/main/java/org/apache/tuscany/sca/binding/sca/provider/RuntimeSCAReferenceBindingProvider.java?rev=908835&r1=908834&r2=908835&view=diff
==============================================================================
--- tuscany/sca-java-2.x/trunk/modules/binding-sca-runtime/src/main/java/org/apache/tuscany/sca/binding/sca/provider/RuntimeSCAReferenceBindingProvider.java (original)
+++ tuscany/sca-java-2.x/trunk/modules/binding-sca-runtime/src/main/java/org/apache/tuscany/sca/binding/sca/provider/RuntimeSCAReferenceBindingProvider.java Thu Feb 11 04:21:00 2010
@@ -27,6 +27,8 @@
 import org.apache.tuscany.sca.assembly.SCABindingFactory;
 import org.apache.tuscany.sca.core.ExtensionPointRegistry;
 import org.apache.tuscany.sca.core.FactoryExtensionPoint;
+import org.apache.tuscany.sca.core.UtilityExtensionPoint;
+import org.apache.tuscany.sca.databinding.Mediator;
 import org.apache.tuscany.sca.interfacedef.InterfaceContract;
 import org.apache.tuscany.sca.interfacedef.Operation;
 import org.apache.tuscany.sca.invocation.InvocationChain;
@@ -63,6 +65,7 @@
     private BindingProviderFactory<DistributedSCABinding> distributedProviderFactory = null;
     private ReferenceBindingProvider distributedProvider = null;
     private SCABindingFactory scaBindingFactory;
+    private Mediator mediator;
 
     public RuntimeSCAReferenceBindingProvider(ExtensionPointRegistry extensionPoints,
                                               RuntimeEndpointReference endpointReference) {
@@ -82,6 +85,7 @@
             (BindingProviderFactory<DistributedSCABinding>)factoryExtensionPoint
                 .getProviderFactory(DistributedSCABinding.class);
 
+        this.mediator = extensionPoints.getExtensionPoint(UtilityExtensionPoint.class).getUtility(Mediator.class);
     }
 
     public boolean isTargetRemote() {
@@ -185,7 +189,11 @@
             RuntimeComponentService service = (RuntimeComponentService)target.getService();
             if (service != null) { // not a callback wire
                 InvocationChain chain = ((RuntimeEndpoint) target).getInvocationChain(operation);
-                return chain == null ? null : new SCABindingInvoker(chain);
+                
+                // it turns out that the chain source and target operations are the same, and are the operation 
+                // from the target, not sure if thats by design or a bug. The SCA binding invoker needs to know 
+                // the source and target class loaders so pass in the real source operation in the constructor 
+                return chain == null ? null : new SCABindingInvoker(chain, operation, mediator);
             }
         }
         return null;

Modified: tuscany/sca-java-2.x/trunk/modules/binding-sca-runtime/src/main/java/org/apache/tuscany/sca/binding/sca/provider/SCABindingInvoker.java
URL: http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/binding-sca-runtime/src/main/java/org/apache/tuscany/sca/binding/sca/provider/SCABindingInvoker.java?rev=908835&r1=908834&r2=908835&view=diff
==============================================================================
--- tuscany/sca-java-2.x/trunk/modules/binding-sca-runtime/src/main/java/org/apache/tuscany/sca/binding/sca/provider/SCABindingInvoker.java (original)
+++ tuscany/sca-java-2.x/trunk/modules/binding-sca-runtime/src/main/java/org/apache/tuscany/sca/binding/sca/provider/SCABindingInvoker.java Thu Feb 11 04:21:00 2010
@@ -19,25 +19,34 @@
 
 package org.apache.tuscany.sca.binding.sca.provider;
 
+import org.apache.tuscany.sca.databinding.Mediator;
+import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.invocation.DataExchangeSemantics;
 import org.apache.tuscany.sca.invocation.Interceptor;
 import org.apache.tuscany.sca.invocation.InvocationChain;
 import org.apache.tuscany.sca.invocation.Invoker;
 import org.apache.tuscany.sca.invocation.Message;
-import org.apache.tuscany.sca.invocation.DataExchangeSemantics;
 
 /**
  * @version $Rev$ $Date$
  */
 public class SCABindingInvoker implements Interceptor, DataExchangeSemantics {
     private InvocationChain chain;
+    private Mediator mediator;
+    private Operation sourceOperation;
+    private Operation targetOperation;
+    private boolean copyArgs;
     
     /**
      * Construct a SCABindingInvoker that delegates to the service invocaiton chain
-     * @param chain
      */
-    public SCABindingInvoker(InvocationChain chain) {
+    public SCABindingInvoker(InvocationChain chain, Operation sourceOperation, Mediator mediator) {
         super();
         this.chain = chain;
+        this.mediator = mediator;
+        this.sourceOperation = sourceOperation;
+        this.targetOperation = chain.getTargetOperation();
+        initCopyArgs();
     }
 
     /**
@@ -58,15 +67,65 @@
      * @see org.apache.tuscany.sca.invocation.Invoker#invoke(org.apache.tuscany.sca.invocation.Message)
      */
     public Message invoke(Message msg) {
-        return getNext().invoke(msg);
+
+        if (copyArgs) {
+            msg.setBody(mediator.copyInput(msg.getBody(), sourceOperation, targetOperation));
+        }
+        
+        Message resultMsg = getNext().invoke(msg);
+        
+        if (copyArgs) {
+            // Note source and target operation swapped so result is in source class loader
+            if (resultMsg.isFault()) {
+                resultMsg.setFaultBody(mediator.copyFault(resultMsg.getBody(), targetOperation, sourceOperation));
+            } else {
+                if (sourceOperation.getOutputType() != null) {
+                    resultMsg.setBody(mediator.copyOutput(resultMsg.getBody(), targetOperation, sourceOperation));
+                }
+            }
+        }
+
+        return resultMsg;
+    }
+
+    /**
+     * Work out if pass-by-value copies or cross classloader copies need to be done
+     * - if source and target are in different classloaders
+     * - if the interfaces are remotable unless @AllowsPassByReference or 
+     *   a data transformation has been done in the chain
+     * - what else?
+     *    - have a flag to optionally disable copies for individual composite/service/operation
+     *      to improve the performance of specific local invocations?
+     */
+    private void initCopyArgs() {
+        this.copyArgs = crossClassLoaders() || isRemotable();
     }
 
+    private boolean crossClassLoaders() {
+        // TODO: for now if the operation is remotable the cross classloader copying will 
+        // happen automatically but this needs also to check the non-remotable operation classloaders 
+        return false;
+    }
+
+    /**
+     * Pass-by-value copies are required if the interfaces are remotable unless the
+     * implementation uses the @AllowsPassByReference annotation.
+     */
+    protected boolean isRemotable() {
+        if (!sourceOperation.getInterface().isRemotable()) {
+            return false;
+        }
+        if (!chain.getTargetOperation().getInterface().isRemotable()) {
+            return false;
+        }
+        return true;
+    }
+    
     /**
      * @see org.apache.tuscany.sca.invocation.DataExchangeSemantics#allowsPassByReference()
      */
     public boolean allowsPassByReference() {
         return false;
-//        return chain.allowsPassByReference();
     }
 
 }

Modified: tuscany/sca-java-2.x/trunk/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/wire/DataBindingRuntimeWireProcessor.java
URL: http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/wire/DataBindingRuntimeWireProcessor.java?rev=908835&r1=908834&r2=908835&view=diff
==============================================================================
--- tuscany/sca-java-2.x/trunk/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/wire/DataBindingRuntimeWireProcessor.java (original)
+++ tuscany/sca-java-2.x/trunk/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/wire/DataBindingRuntimeWireProcessor.java Thu Feb 11 04:21:00 2010
@@ -123,29 +123,6 @@
         return isTransformationRequired(sourceOperation, targetOperation);
     }
 
-    /**
-     * FIXME: TUSCANY-2586, temporary work around till the JIRA is fixed to prevent
-     *  the PassByValueInterceptor being used for services when the binding protocol
-     *  doesn't need the copies done.
-     */
-    protected boolean isOnMessage(Operation op) {
-        return "onMessage".equals(op.getName());
-    }
-
-    /**
-     * Pass-by-value copies are required if the interfaces are remotable unless the
-     * implementation uses the @AllowsPassByReference annotation.
-     */
-    protected boolean isRemotable(InvocationChain chain, Operation sourceOperation, Operation targetOperation) {
-        if (!sourceOperation.getInterface().isRemotable()) {
-            return false;
-        }
-        if (!targetOperation.getInterface().isRemotable()) {
-            return false;
-        }
-        return true;
-    }
-
     public void process(RuntimeEndpoint endpoint) {
         InterfaceContract sourceContract = endpoint.getBindingInterfaceContract();
         InterfaceContract targetContract = endpoint.getComponentTypeServiceInterfaceContract();
@@ -165,15 +142,7 @@
             if (isTransformationRequired(sourceContract, sourceOperation, targetContract, targetOperation)) {
                 // Add the interceptor to the source side because multiple
                 // references can be wired to the same service
-                interceptor =
-                    new DataTransformationInterceptor(endpoint, sourceOperation, targetOperation, mediator);
-            } else {
-                // assume pass-by-values copies are required if interfaces are remotable and there is no data binding
-                // transformation, i.e. a transformation will result in a copy so another pass-by-value copy is unnecessary
-                if (!isOnMessage(targetOperation) && isRemotable(chain, sourceOperation, targetOperation)) {
-                    interceptor =
-                        new PassByValueInterceptor(mediator, chain, targetOperation);
-                }
+                interceptor = new DataTransformationInterceptor(endpoint, sourceOperation, targetOperation, mediator);
             }
             if (interceptor != null) {
                 String phase = Phase.SERVICE_INTERFACE;
@@ -202,15 +171,7 @@
             if (isTransformationRequired(sourceContract, sourceOperation, targetContract, targetOperation)) {
                 // Add the interceptor to the source side because multiple
                 // references can be wired to the same service
-                interceptor =
-                    new DataTransformationInterceptor(endpointReference, sourceOperation, targetOperation, mediator);
-            } else {
-                // assume pass-by-values copies are required if interfaces are remotable and there is no data binding
-                // transformation, i.e. a transformation will result in a copy so another pass-by-value copy is unnecessary
-                if (!isOnMessage(targetOperation) && isRemotable(chain, sourceOperation, targetOperation)) {
-                    interceptor =
-                        new PassByValueInterceptor(mediator, chain, targetOperation);
-                }
+                interceptor = new DataTransformationInterceptor(endpointReference, sourceOperation, targetOperation, mediator);
             }
             if (interceptor != null) {
                 String phase = Phase.REFERENCE_INTERFACE;

Modified: tuscany/sca-java-2.x/trunk/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBDataBinding.java
URL: http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBDataBinding.java?rev=908835&r1=908834&r2=908835&view=diff
==============================================================================
--- tuscany/sca-java-2.x/trunk/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBDataBinding.java (original)
+++ tuscany/sca-java-2.x/trunk/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBDataBinding.java Thu Feb 11 04:21:00 2010
@@ -95,9 +95,14 @@
         return true;
     }
 
-    @SuppressWarnings("unchecked")
     @Override
     public Object copy(Object arg, DataType dataType, Operation operation) {
+        return copy(arg, dataType, operation, dataType);
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public Object copy(Object arg, DataType dataType, Operation operation, DataType targetDataType) {
         try {
             boolean isElement = false;
             if (dataType == null) {
@@ -112,7 +117,15 @@
             arg = JAXBContextHelper.createJAXBElement(context, dataType, arg);
             Document doc = domHelper.newDocument();
             context.createMarshaller().marshal(arg, doc);
-            Object value = context.createUnmarshaller().unmarshal(doc, dataType.getPhysical());
+            
+            Object value;
+            if (targetDataType != null && targetDataType.getPhysical() != dataType.getPhysical()) {
+                JAXBContext targetContext = contextHelper.createJAXBContext(targetDataType);
+                value = targetContext.createUnmarshaller().unmarshal(doc, targetDataType.getPhysical());
+            } else {
+                value = context.createUnmarshaller().unmarshal(doc, dataType.getPhysical());
+            }
+            
             if (isElement && value instanceof JAXBElement) {
                 return value;
             }

Modified: tuscany/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/DataBinding.java
URL: http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/DataBinding.java?rev=908835&r1=908834&r2=908835&view=diff
==============================================================================
--- tuscany/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/DataBinding.java (original)
+++ tuscany/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/DataBinding.java Thu Feb 11 04:21:00 2010
@@ -83,6 +83,16 @@
     Object copy(Object object, DataType dataType, Operation operation);
     
     /**
+     * Make a copy of the object for "pass-by-value" semantics and cross classloader invocations.
+     *
+     * @param object source object to copy 
+     * @param dataType The data type
+     * @param operation The operation
+     * @return copy of the object passed in as argument
+     */
+    Object copy(Object object, DataType dataType, Operation operation, DataType targetdataType);
+
+    /**
      * Get the XML type helper for Java types
      * @return The databinding-specific XML type helper class
      */

Modified: tuscany/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/DefaultDataBindingExtensionPoint.java
URL: http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/DefaultDataBindingExtensionPoint.java?rev=908835&r1=908834&r2=908835&view=diff
==============================================================================
--- tuscany/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/DefaultDataBindingExtensionPoint.java (original)
+++ tuscany/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/DefaultDataBindingExtensionPoint.java Thu Feb 11 04:21:00 2010
@@ -169,6 +169,10 @@
             return getDataBinding().copy(object, dataType, operation);
         }
 
+        public Object copy(Object object, DataType dataType, Operation operation, DataType targetdataType) {
+            return getDataBinding().copy(object, dataType, operation, targetdataType);
+        }
+
         public String getName() {
             return name;
         }

Modified: tuscany/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/Mediator.java
URL: http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/Mediator.java?rev=908835&r1=908834&r2=908835&view=diff
==============================================================================
--- tuscany/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/Mediator.java (original)
+++ tuscany/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/Mediator.java Thu Feb 11 04:21:00 2010
@@ -100,6 +100,15 @@
     Object copy(Object data, DataType dataType);
 
     /**
+     * Copy the data
+     * @param data The orginal data
+     * @param dataType The data type
+     * @param targetDataType The target data type
+     * @return The copy
+     */
+    Object copy(Object data, DataType dataType, DataType targetDataType);
+
+    /**
      * Copy an array of data objects passed to an operation
      * @param data array of objects to copy
      * @return the copy
@@ -107,6 +116,13 @@
     public Object copyInput(Object input, Operation operation);
 
     /**
+     * Copy an array of data objects passed to an operation
+     * @param data array of objects to copy
+     * @return the copy
+     */
+    public Object copyInput(Object input, Operation operation, Operation targetOperation);
+
+    /**
      * Copy the output data
      * @param data The orginal output
      * @param operation The operation
@@ -115,6 +131,15 @@
     Object copyOutput(Object data, Operation operation);
 
     /**
+     * Copy the output data
+     * @param data The orginal output
+     * @param operation The operation
+     * @param targetOperation The target operation
+     * @return The copy
+     */
+    Object copyOutput(Object data, Operation operation, Operation targetOperation);
+
+    /**
      * Copy the fault data
      * @param fault The orginal fault data
      * @param operation The operation
@@ -123,6 +148,15 @@
     Object copyFault(Object fault, Operation operation);
 
     /**
+     * Copy the fault data
+     * @param fault The orginal fault data
+     * @param operation The operation
+     * @param targetOperation The target operation
+     * @return The copy
+     */
+    Object copyFault(Object fault, Operation operation, Operation targetOperation);
+
+    /**
      * Get the DataBindings used by this mediator.
      * @return
      */

Modified: tuscany/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/impl/BaseDataBinding.java
URL: http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/impl/BaseDataBinding.java?rev=908835&r1=908834&r2=908835&view=diff
==============================================================================
--- tuscany/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/impl/BaseDataBinding.java (original)
+++ tuscany/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/impl/BaseDataBinding.java Thu Feb 11 04:21:00 2010
@@ -100,6 +100,10 @@
     }
 
     public Object copy(Object object, DataType dataType, Operation operation) {
+        return copy(object, dataType, operation, dataType);
+    }
+
+    public Object copy(Object object, DataType dataType, Operation operation, DataType targetDataType) {
         return object;
     }
 

Modified: tuscany/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/impl/MediatorImpl.java
URL: http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/impl/MediatorImpl.java?rev=908835&r1=908834&r2=908835&view=diff
==============================================================================
--- tuscany/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/impl/MediatorImpl.java (original)
+++ tuscany/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/impl/MediatorImpl.java Thu Feb 11 04:21:00 2010
@@ -443,7 +443,11 @@
     }
 
     public Object copy(Object data, DataType dataType) {
-        return copy(data, dataType, null);
+        return copy(data, dataType, null, null);
+    }
+
+    public Object copy(Object data, DataType dataType, DataType targetDataType) {
+        return copy(data, dataType, null, targetDataType);
     }
 
     /**
@@ -452,7 +456,7 @@
      * @param dataType
      * @return a copy of the data
      */
-    private Object copy(Object data, DataType dataType, Operation operation) {
+    private Object copy(Object data, DataType dataType, Operation operation, DataType targetDataType) {
         if (data == null) {
             return null;
         }
@@ -515,11 +519,11 @@
             }
         }
 
-        if (dataBinding != null) {
-            return dataBinding.copy(data, dataType, operation);
-        } else {
+        if (dataBinding == null) {
             return data;
         }
+
+        return dataBinding.copy(data, dataType, operation, targetDataType);
     }
 
     /**
@@ -528,11 +532,15 @@
      * @return the copy
      */
     public Object copyInput(Object input, Operation operation) {
+        return copyInput(input, operation, null);
+    }
+    public Object copyInput(Object input, Operation operation, Operation targetOperation) {
         if (input == null) {
             return null;
         }
         Object[] data = (input instanceof Object[]) ? (Object[])input : new Object[] {input};
         List<DataType> inputTypes = operation.getInputType().getLogical();
+        List<DataType> inputTypesTarget = targetOperation == null ? null : targetOperation.getInputType().getLogical();
         Object[] copy = new Object[data.length];
         Map<Object, Object> map = new IdentityHashMap<Object, Object>();
         for (int i = 0, size = inputTypes.size(); i < size; i++) {
@@ -544,7 +552,7 @@
                 if (copiedArg != null) {
                     copy[i] = copiedArg;
                 } else {
-                    copiedArg = copy(arg, inputTypes.get(i));
+                    copiedArg = copy(arg, inputTypes.get(i), inputTypesTarget == null ? null : inputTypesTarget.get(i));
                     map.put(arg, copiedArg);
                     copy[i] = copiedArg;
                 }
@@ -554,14 +562,22 @@
     }
 
     public Object copyOutput(Object data, Operation operation) {
-        return copy(data, operation.getOutputType(), operation);
+        return copyOutput(data, operation, null);
+    }
+    public Object copyOutput(Object data, Operation operation, Operation targetOperation) {
+        return copy(data, operation.getOutputType(), operation, targetOperation.getOutputType());
     }
 
     public Object copyFault(Object fault, Operation operation) {
+        return copyFault(fault, operation, null);
+    }
+    public Object copyFault(Object fault, Operation operation, Operation targetOperation) {
         if (faultExceptionMapper == null) {
             return fault;
         }
-        for (DataType et : operation.getFaultTypes()) {
+        List<DataType> fts = operation.getFaultTypes();
+        for (int i=0; i<fts.size(); i++) {
+            DataType et = fts.get(i); 
             if (et.getPhysical().isInstance(fault)) {
                 Throwable ex = (Throwable)fault;
                 DataType<DataType> exType =
@@ -569,9 +585,15 @@
                 faultExceptionMapper.introspectFaultDataType(exType, operation, false);
                 DataType faultType = exType.getLogical();
                 Object faultInfo = faultExceptionMapper.getFaultInfo(ex, faultType.getPhysical(), operation);
-                faultInfo = copy(faultInfo, faultType);
-                fault =
-                    faultExceptionMapper.wrapFaultInfo(exType, ex.getMessage(), faultInfo, ex.getCause(), operation);
+                DataType targetFaultType;
+                try {
+                    targetFaultType = (DataType)faultType.clone();
+                } catch (CloneNotSupportedException e) {
+                    throw new IllegalStateException(e);
+                }
+                targetFaultType.setPhysical(targetOperation.getFaultTypes().get(i).getPhysical());
+                faultInfo = copy(faultInfo, faultType, targetFaultType);
+                fault = faultExceptionMapper.wrapFaultInfo(exType, ex.getMessage(), faultInfo, ex.getCause(), operation);
                 return fault;
             }
         }

Modified: tuscany/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/javabeans/JavaBeansDataBinding.java
URL: http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/javabeans/JavaBeansDataBinding.java?rev=908835&r1=908834&r2=908835&view=diff
==============================================================================
--- tuscany/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/javabeans/JavaBeansDataBinding.java (original)
+++ tuscany/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/javabeans/JavaBeansDataBinding.java Thu Feb 11 04:21:00 2010
@@ -59,7 +59,7 @@
     }
 
     @Override
-    public Object copy(Object arg, DataType dataType, Operation operation) {
+    public Object copy(Object arg, DataType dataType, Operation operation, DataType targetDataType) {
         if (arg == null) {
             return null;
         }
@@ -82,12 +82,16 @@
 
                 // Work out which ClassLoader to use for deserializing arg
                 // We want to use:
+                //   * The ClassLoader of the targetDataType if it is not the System ClassLoader
                 //   * The ClassLoader of arg if it is not the System ClassLoader
                 //   * The ThreadContext ClassLoader if the ClassLoader of arg is the System ClassLoader
                 //     because Collection classes are loaded by the System ClassLoader but their contents
                 //     may be loaded from another ClassLoader
                 //
-                ClassLoader classLoaderToUse = clazz.getClassLoader();
+                ClassLoader classLoaderToUse = targetDataType.getPhysical().getClassLoader();
+                if (classLoaderToUse == null) {
+                    classLoaderToUse = clazz.getClassLoader();
+                }
                 if (classLoaderToUse == null)
                 {
                     // ClassLoader of arg is the System ClassLoader so we will use the ThreadContext ClassLoader