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


Reply via email to