summaryrefslogtreecommitdiffstats
path: root/sca-java-2.x/trunk/modules/binding-sca-runtime/src/main/java/org/apache/tuscany
diff options
context:
space:
mode:
Diffstat (limited to 'sca-java-2.x/trunk/modules/binding-sca-runtime/src/main/java/org/apache/tuscany')
-rw-r--r--sca-java-2.x/trunk/modules/binding-sca-runtime/src/main/java/org/apache/tuscany/sca/binding/sca/provider/RuntimeSCAReferenceBindingProvider.java10
-rw-r--r--sca-java-2.x/trunk/modules/binding-sca-runtime/src/main/java/org/apache/tuscany/sca/binding/sca/provider/SCABindingInvoker.java69
2 files changed, 73 insertions, 6 deletions
diff --git a/sca-java-2.x/trunk/modules/binding-sca-runtime/src/main/java/org/apache/tuscany/sca/binding/sca/provider/RuntimeSCAReferenceBindingProvider.java b/sca-java-2.x/trunk/modules/binding-sca-runtime/src/main/java/org/apache/tuscany/sca/binding/sca/provider/RuntimeSCAReferenceBindingProvider.java
index 22b1e5bd99..ec4e893b5f 100644
--- a/sca-java-2.x/trunk/modules/binding-sca-runtime/src/main/java/org/apache/tuscany/sca/binding/sca/provider/RuntimeSCAReferenceBindingProvider.java
+++ b/sca-java-2.x/trunk/modules/binding-sca-runtime/src/main/java/org/apache/tuscany/sca/binding/sca/provider/RuntimeSCAReferenceBindingProvider.java
@@ -27,6 +27,8 @@ import org.apache.tuscany.sca.assembly.SCABinding;
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 @@ public class RuntimeSCAReferenceBindingProvider implements ReferenceBindingProvi
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 @@ public class RuntimeSCAReferenceBindingProvider implements ReferenceBindingProvi
(BindingProviderFactory<DistributedSCABinding>)factoryExtensionPoint
.getProviderFactory(DistributedSCABinding.class);
+ this.mediator = extensionPoints.getExtensionPoint(UtilityExtensionPoint.class).getUtility(Mediator.class);
}
public boolean isTargetRemote() {
@@ -185,7 +189,11 @@ public class RuntimeSCAReferenceBindingProvider implements ReferenceBindingProvi
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;
diff --git a/sca-java-2.x/trunk/modules/binding-sca-runtime/src/main/java/org/apache/tuscany/sca/binding/sca/provider/SCABindingInvoker.java b/sca-java-2.x/trunk/modules/binding-sca-runtime/src/main/java/org/apache/tuscany/sca/binding/sca/provider/SCABindingInvoker.java
index 4dee1b8601..0f46e9390f 100644
--- a/sca-java-2.x/trunk/modules/binding-sca-runtime/src/main/java/org/apache/tuscany/sca/binding/sca/provider/SCABindingInvoker.java
+++ b/sca-java-2.x/trunk/modules/binding-sca-runtime/src/main/java/org/apache/tuscany/sca/binding/sca/provider/SCABindingInvoker.java
@@ -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 @@ public class SCABindingInvoker implements Interceptor, DataExchangeSemantics {
* @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();
}
}