summaryrefslogtreecommitdiffstats
path: root/branches/sca-java-1.x/modules/binding-jms-runtime
diff options
context:
space:
mode:
Diffstat (limited to 'branches/sca-java-1.x/modules/binding-jms-runtime')
-rw-r--r--branches/sca-java-1.x/modules/binding-jms-runtime/src/main/java/org/apache/tuscany/sca/binding/jms/provider/ObjectMessageProcessor.java155
-rw-r--r--branches/sca-java-1.x/modules/binding-jms-runtime/src/main/java/org/apache/tuscany/sca/binding/jms/wireformat/jmsobject/runtime/WireFormatJMSObjectReferenceInterceptor.java31
-rw-r--r--branches/sca-java-1.x/modules/binding-jms-runtime/src/main/java/org/apache/tuscany/sca/binding/jms/wireformat/jmsobject/runtime/WireFormatJMSObjectReferenceProvider.java23
-rw-r--r--branches/sca-java-1.x/modules/binding-jms-runtime/src/main/java/org/apache/tuscany/sca/binding/jms/wireformat/jmsobject/runtime/WireFormatJMSObjectServiceInterceptor.java24
-rw-r--r--branches/sca-java-1.x/modules/binding-jms-runtime/src/main/java/org/apache/tuscany/sca/binding/jms/wireformat/jmsobject/runtime/WireFormatJMSObjectServiceProvider.java26
5 files changed, 236 insertions, 23 deletions
diff --git a/branches/sca-java-1.x/modules/binding-jms-runtime/src/main/java/org/apache/tuscany/sca/binding/jms/provider/ObjectMessageProcessor.java b/branches/sca-java-1.x/modules/binding-jms-runtime/src/main/java/org/apache/tuscany/sca/binding/jms/provider/ObjectMessageProcessor.java
index 97d3d861f4..331c63f20f 100644
--- a/branches/sca-java-1.x/modules/binding-jms-runtime/src/main/java/org/apache/tuscany/sca/binding/jms/provider/ObjectMessageProcessor.java
+++ b/branches/sca-java-1.x/modules/binding-jms-runtime/src/main/java/org/apache/tuscany/sca/binding/jms/provider/ObjectMessageProcessor.java
@@ -34,7 +34,6 @@ import org.osoa.sca.ServiceRuntimeException;
/**
* MessageProcessor for sending/receiving Serializable objects with the JMSBinding.
*
- * @version $Rev$ $Date$
*/
public class ObjectMessageProcessor extends AbstractMessageProcessor {
private static final Logger logger = Logger.getLogger(ObjectMessageProcessor.class.getName());
@@ -44,17 +43,6 @@ public class ObjectMessageProcessor extends AbstractMessageProcessor {
}
@Override
- protected Object extractPayload(Message msg) {
- try {
-
- return ((ObjectMessage)msg).getObject();
-
- } catch (JMSException e) {
- throw new JMSBindingException(e);
- }
- }
-
- @Override
protected Message createJMSMessage(Session session, Object o) {
if (session == null) {
logger.fine("no response session to create message: " + String.valueOf(o));
@@ -96,4 +84,147 @@ public class ObjectMessageProcessor extends AbstractMessageProcessor {
return extractPayload(msg);
}
+ @Override
+ protected Object extractPayload(Message msg) {
+ try {
+
+ return ((ObjectMessage)msg).getObject();
+
+ } catch (JMSException e) {
+ throw new JMSBindingException(e);
+ }
+ }
+
+ // special methods for handling operations with single parameters
+
+ public Message createJMSMessageForSingleParamOperation(Session session, Object o, boolean wrapSingleInput) {
+ if (session == null) {
+ logger.fine("no response session to create message: " + String.valueOf(o));
+ return null;
+ }
+ try {
+
+ ObjectMessage message = session.createObjectMessage();
+
+ if (o != null) {
+ if (!(o instanceof Serializable)) {
+ throw new IllegalStateException("JMS ObjectMessage payload not Serializable: " + o);
+ }
+
+ // If the user has specifically requests that single parameters
+ // be wrapped then leave is as is as it will have already been
+ // wrapped by Tuscany. Otherwise unwrap it.
+ if (wrapSingleInput) {
+ message.setObject((Serializable) o);
+ } else { // unwrap from array
+ message.setObject((Serializable) ((Object[]) o)[0]);
+ }
+
+ }
+
+ return message;
+
+ } catch (JMSException e) {
+ throw new JMSBindingException(e);
+ }
+ }
+
+ public Object extractPayloadFromJMSMessageForSingleParamOperation(Message msg, Class<?> argType, boolean wrapSingle) {
+ // We always have a one arg operation if this method is called so we need to
+ // decide if the data on the wire is wrapped or not. This is the algorithm.
+ //
+ // If the payload is null then create an empty array and pass it on
+ // If the payload is not an array then it must represent an unwrapped
+ // single arg. Wrap it up and pass it on
+ // If the payload is an array then determine if it's a wrapped single arg or not
+ // If the service interface arg type matches the type of the array and not it's contents
+ // then it's an unwrapped argument so wrap it and pass it on
+ // If the service interface arg type matches the type of the contents and not the type
+ // of the array then the parameter is already wrapped so pass it on as is
+ // If the service interface arg type matches both the type of the
+ // array and the type of its contents then assume that the whole array is the
+ // parameter and decide whether to unwrap it or pass it on as is based on the
+ // setting of the wrapSingle attribute
+ //
+
+ try {
+ Object payload = ((ObjectMessage) msg).getObject();
+
+ if (payload instanceof Throwable) {
+ if (payload instanceof RuntimeException) {
+ throw new ServiceRuntimeException("remote service exception, see nested exception", (RuntimeException) payload);
+ } else {
+ return new InvocationTargetException((Throwable) payload);
+ }
+ }
+
+ if (payload == null) {
+ // methodA(null) was not wrapped on wire so wrap it here in order
+ // that it passes through the rest of the Tuscany wire successfully
+ return new Object[] { payload };
+ }
+
+ boolean payloadIsArray = payload.getClass().isArray();
+
+ // Non-array payload is single arg
+ if (!payloadIsArray) {
+ // methodB(arg) wasn't wrapped on wire so wrap it here in order
+ // that it passes through the rest of the Tuscany wire successfully
+ return new Object[] { payload };
+ } else {
+ int size = ((Object[]) payload).length;
+
+ // An initial quick check to determine whether the payload is not
+ // wrapped. If the array has anything other than a single entry
+ // then it's not the result of reference side wrapping so wrap it
+ // here and pass it on
+ if (size != 1) {
+ return new Object[] { payload };
+ }
+
+ // we know the array has only one entry now so get it
+ Object arrayContents = ((Object[]) payload)[0];
+
+ // Is the operation argument the same type as the array itself?
+ if (argType.isAssignableFrom(payload.getClass())) {
+
+ // So we believe that the whole array is the argument but need
+ // to check what is in the array to be sure
+ if (arrayContents == null) {
+ // There is nothing in the array so it could be an accident that
+ // the array type matches the argument type, e.g. op(Object)
+ // so rely on the wrapSingle setting to choose
+ if (wrapSingle) {
+ return payload;
+ } else {
+ return new Object[] { payload };
+ }
+ } else if (argType.isAssignableFrom(arrayContents.getClass())) {
+ // We can't tell as the argument type matches both the array type and
+ // the array contents type so use the wrapSingle setting to choose
+ if (wrapSingle) {
+ return payload;
+ } else {
+ return new Object[] { payload };
+ }
+ } else {
+ // So by now we know the whole array is intended to be the
+ // parameter to wrap it and send it on
+ return new Object[] { payload };
+ }
+
+ } else {
+ // The array type doesn't match the argument type so assume that the
+ // array contents will match the argument type and that hence the
+ // parameter is already wrapped so just send it as is. If the contents
+ // type doesn't match the argument type a exception will be thrown further
+ // along the wire
+ return payload;
+ }
+ }
+ } catch (JMSException e) {
+ throw new JMSBindingException(e);
+ }
+ }
+
}
diff --git a/branches/sca-java-1.x/modules/binding-jms-runtime/src/main/java/org/apache/tuscany/sca/binding/jms/wireformat/jmsobject/runtime/WireFormatJMSObjectReferenceInterceptor.java b/branches/sca-java-1.x/modules/binding-jms-runtime/src/main/java/org/apache/tuscany/sca/binding/jms/wireformat/jmsobject/runtime/WireFormatJMSObjectReferenceInterceptor.java
index 6ba62d7681..22c66b0b78 100644
--- a/branches/sca-java-1.x/modules/binding-jms-runtime/src/main/java/org/apache/tuscany/sca/binding/jms/wireformat/jmsobject/runtime/WireFormatJMSObjectReferenceInterceptor.java
+++ b/branches/sca-java-1.x/modules/binding-jms-runtime/src/main/java/org/apache/tuscany/sca/binding/jms/wireformat/jmsobject/runtime/WireFormatJMSObjectReferenceInterceptor.java
@@ -20,6 +20,8 @@ package org.apache.tuscany.sca.binding.jms.wireformat.jmsobject.runtime;
import java.lang.reflect.InvocationTargetException;
+import java.util.HashMap;
+
import javax.jms.JMSException;
import javax.jms.Session;
@@ -31,6 +33,7 @@ import org.apache.tuscany.sca.binding.jms.impl.JMSBindingException;
import org.apache.tuscany.sca.binding.jms.provider.JMSMessageProcessor;
import org.apache.tuscany.sca.binding.jms.provider.JMSMessageProcessorUtil;
import org.apache.tuscany.sca.binding.jms.provider.JMSResourceFactory;
+import org.apache.tuscany.sca.binding.jms.provider.ObjectMessageProcessor;
import org.apache.tuscany.sca.binding.jms.wireformat.jmsobject.WireFormatJMSObject;
import org.apache.tuscany.sca.invocation.Interceptor;
import org.apache.tuscany.sca.invocation.Invoker;
@@ -50,13 +53,16 @@ public class WireFormatJMSObjectReferenceInterceptor implements Interceptor {
private JMSMessageProcessor requestMessageProcessor;
private JMSMessageProcessor responseMessageProcessor;
- public WireFormatJMSObjectReferenceInterceptor(JMSBinding jmsBinding, JMSResourceFactory jmsResourceFactory, RuntimeWire runtimeWire) {
+ private HashMap<String, String> singleArgMap;
+
+ public WireFormatJMSObjectReferenceInterceptor(JMSBinding jmsBinding, JMSResourceFactory jmsResourceFactory, RuntimeWire runtimeWire, HashMap<String, String> hashMap) {
super();
this.jmsBinding = jmsBinding;
this.runtimeWire = runtimeWire;
this.jmsResourceFactory = jmsResourceFactory;
this.requestMessageProcessor = JMSMessageProcessorUtil.getRequestMessageProcessor(jmsBinding);
this.responseMessageProcessor = JMSMessageProcessorUtil.getResponseMessageProcessor(jmsBinding);
+ this.singleArgMap = hashMap;
}
public Message invoke(Message msg) {
@@ -78,8 +84,27 @@ public class WireFormatJMSObjectReferenceInterceptor implements Interceptor {
// get the jms context
JMSBindingContext context = msg.getBindingContext();
Session session = context.getJmsSession();
-
- javax.jms.Message requestMsg = requestMessageProcessor.insertPayloadIntoJMSMessage(session, msg.getBody());
+
+ javax.jms.Message requestMsg;
+
+ // Tuscany automatically wraps operation arguments in an array before we
+ // get to this point so here we need to decide how they are going to appear
+ // on the wire.
+ //
+ // If the operation has a single parameter and the user has set @wrapSingle=false
+ // then
+ // send the single parameter out onto the wire unwrapped
+ // else
+ // send out the message as is
+ //
+ if (singleArgMap.get(msg.getOperation().getName()) == null) {
+ requestMsg = requestMessageProcessor.insertPayloadIntoJMSMessage(session, msg.getBody());
+ } else {
+ // we know that wrapSinle is set to false here as the provider only
+ // populates singleArgMap if it is set false
+ requestMsg = ((ObjectMessageProcessor) requestMessageProcessor).createJMSMessageForSingleParamOperation(session, msg.getBody(), false);
+ }
+
msg.setBody(requestMsg);
requestMsg.setJMSReplyTo(context.getReplyToDestination());
diff --git a/branches/sca-java-1.x/modules/binding-jms-runtime/src/main/java/org/apache/tuscany/sca/binding/jms/wireformat/jmsobject/runtime/WireFormatJMSObjectReferenceProvider.java b/branches/sca-java-1.x/modules/binding-jms-runtime/src/main/java/org/apache/tuscany/sca/binding/jms/wireformat/jmsobject/runtime/WireFormatJMSObjectReferenceProvider.java
index 644c9ebc38..702293301b 100644
--- a/branches/sca-java-1.x/modules/binding-jms-runtime/src/main/java/org/apache/tuscany/sca/binding/jms/wireformat/jmsobject/runtime/WireFormatJMSObjectReferenceProvider.java
+++ b/branches/sca-java-1.x/modules/binding-jms-runtime/src/main/java/org/apache/tuscany/sca/binding/jms/wireformat/jmsobject/runtime/WireFormatJMSObjectReferenceProvider.java
@@ -19,12 +19,16 @@
package org.apache.tuscany.sca.binding.jms.wireformat.jmsobject.runtime;
+import java.util.HashMap;
+import java.util.List;
+
import org.apache.tuscany.sca.assembly.Binding;
import org.apache.tuscany.sca.binding.jms.impl.JMSBinding;
import org.apache.tuscany.sca.binding.jms.impl.JMSBindingConstants;
import org.apache.tuscany.sca.binding.jms.wireformat.jmsobject.WireFormatJMSObject;
import org.apache.tuscany.sca.core.ExtensionPointRegistry;
import org.apache.tuscany.sca.interfacedef.InterfaceContract;
+import org.apache.tuscany.sca.interfacedef.Operation;
import org.apache.tuscany.sca.invocation.Interceptor;
import org.apache.tuscany.sca.invocation.Phase;
import org.apache.tuscany.sca.provider.WireFormatProvider;
@@ -40,6 +44,8 @@ public class WireFormatJMSObjectReferenceProvider implements WireFormatProvider
private RuntimeComponentReference reference;
private JMSBinding binding;
private InterfaceContract interfaceContract;
+
+ private HashMap<String,String> singleArgMap; //map of one arg operations, leave empty if wrapSingleInput is true
public WireFormatJMSObjectReferenceProvider(ExtensionPointRegistry registry,
RuntimeComponent component,
@@ -51,6 +57,8 @@ public class WireFormatJMSObjectReferenceProvider implements WireFormatProvider
this.reference = reference;
this.binding = (JMSBinding)binding;
+ this.singleArgMap = new HashMap<String,String>();
+
// configure the reference based on this wire format
// currently maintaining the message processor structure which
@@ -58,10 +66,21 @@ public class WireFormatJMSObjectReferenceProvider implements WireFormatProvider
// any message processors specified in the SCDL in this case
if (this.binding.getRequestWireFormat() instanceof WireFormatJMSObject){
this.binding.setRequestMessageProcessorName(JMSBindingConstants.OBJECT_MP_CLASSNAME);
+
+ //we don't need to create this map if wrapSingleInput is true
+ if (!((WireFormatJMSObject) this.binding.getRequestWireFormat()).isWrappedSingleInput()){
+ List<Operation> opList = reference.getReference().getInterfaceContract().getInterface().getOperations();
+
+ for (Operation op: opList) {
+ if (op.getInputType().getLogical().size() == 1){
+ this.singleArgMap.put(op.getName(), "");
+ }
+ }
+ }
}
if (this.binding.getResponseWireFormat() instanceof WireFormatJMSObject){
this.binding.setResponseMessageProcessorName(JMSBindingConstants.OBJECT_MP_CLASSNAME);
- }
+ }
// just point to the reference interface contract so no
// databinding transformation takes place
@@ -87,7 +106,7 @@ public class WireFormatJMSObjectReferenceProvider implements WireFormatProvider
public Interceptor createInterceptor() {
return new WireFormatJMSObjectReferenceInterceptor(binding,
null,
- reference.getRuntimeWire(binding));
+ reference.getRuntimeWire(binding), this.singleArgMap);
}
public String getPhase() {
diff --git a/branches/sca-java-1.x/modules/binding-jms-runtime/src/main/java/org/apache/tuscany/sca/binding/jms/wireformat/jmsobject/runtime/WireFormatJMSObjectServiceInterceptor.java b/branches/sca-java-1.x/modules/binding-jms-runtime/src/main/java/org/apache/tuscany/sca/binding/jms/wireformat/jmsobject/runtime/WireFormatJMSObjectServiceInterceptor.java
index b063f8d53b..5979bc9214 100644
--- a/branches/sca-java-1.x/modules/binding-jms-runtime/src/main/java/org/apache/tuscany/sca/binding/jms/wireformat/jmsobject/runtime/WireFormatJMSObjectServiceInterceptor.java
+++ b/branches/sca-java-1.x/modules/binding-jms-runtime/src/main/java/org/apache/tuscany/sca/binding/jms/wireformat/jmsobject/runtime/WireFormatJMSObjectServiceInterceptor.java
@@ -18,6 +18,8 @@
*/
package org.apache.tuscany.sca.binding.jms.wireformat.jmsobject.runtime;
+import java.util.HashMap;
+
import javax.jms.Session;
import org.apache.tuscany.sca.binding.jms.context.JMSBindingContext;
@@ -25,6 +27,7 @@ import org.apache.tuscany.sca.binding.jms.impl.JMSBinding;
import org.apache.tuscany.sca.binding.jms.provider.JMSMessageProcessor;
import org.apache.tuscany.sca.binding.jms.provider.JMSMessageProcessorUtil;
import org.apache.tuscany.sca.binding.jms.provider.JMSResourceFactory;
+import org.apache.tuscany.sca.binding.jms.provider.ObjectMessageProcessor;
import org.apache.tuscany.sca.binding.jms.wireformat.jmsobject.WireFormatJMSObject;
import org.apache.tuscany.sca.interfacedef.Operation;
import org.apache.tuscany.sca.invocation.Interceptor;
@@ -45,14 +48,19 @@ public class WireFormatJMSObjectServiceInterceptor implements Interceptor {
private JMSBinding jmsBinding;
private JMSMessageProcessor requestMessageProcessor;
private JMSMessageProcessor responseMessageProcessor;
+ private HashMap<String,Class<?>> singleArgMap;
+ private boolean wrapSingle;
- public WireFormatJMSObjectServiceInterceptor(JMSBinding jmsBinding, JMSResourceFactory jmsResourceFactory, RuntimeWire runtimeWire) {
+ public WireFormatJMSObjectServiceInterceptor(JMSBinding jmsBinding, JMSResourceFactory jmsResourceFactory,
+ RuntimeWire runtimeWire, HashMap<String, Class<?>> singleArgMap, boolean wrapSingle) {
super();
this.jmsBinding = jmsBinding;
this.runtimeWire = runtimeWire;
this.jmsResourceFactory = jmsResourceFactory;
this.requestMessageProcessor = JMSMessageProcessorUtil.getRequestMessageProcessor(jmsBinding);
this.responseMessageProcessor = JMSMessageProcessorUtil.getResponseMessageProcessor(jmsBinding);
+ this.singleArgMap = singleArgMap;
+ this.wrapSingle = wrapSingle;
}
public Message invoke(Message msg) {
@@ -79,8 +87,18 @@ public class WireFormatJMSObjectServiceInterceptor implements Interceptor {
// get the jms context
JMSBindingContext context = msg.getBindingContext();
javax.jms.Message jmsMsg = context.getJmsMsg();
-
- Object requestPayload = requestMessageProcessor.extractPayloadFromJMSMessage(jmsMsg);
+ Object requestPayload;
+
+ // If the service interface has a single argument then we need
+ // to check if the object from the wire is expected
+ // to be unwrapped or not
+ //
+ Class<?> argType = this.singleArgMap.get(msg.getOperation().getName());
+ if (argType == null) {
+ requestPayload = requestMessageProcessor.extractPayloadFromJMSMessage(jmsMsg);
+ }else {
+ requestPayload = ((ObjectMessageProcessor)requestMessageProcessor).extractPayloadFromJMSMessageForSingleParamOperation(jmsMsg, argType, wrapSingle);
+ }
if (requestPayload != null && requestPayload.getClass().isArray()) {
msg.setBody(requestPayload);
diff --git a/branches/sca-java-1.x/modules/binding-jms-runtime/src/main/java/org/apache/tuscany/sca/binding/jms/wireformat/jmsobject/runtime/WireFormatJMSObjectServiceProvider.java b/branches/sca-java-1.x/modules/binding-jms-runtime/src/main/java/org/apache/tuscany/sca/binding/jms/wireformat/jmsobject/runtime/WireFormatJMSObjectServiceProvider.java
index e5887ec1b7..dc4726f4b7 100644
--- a/branches/sca-java-1.x/modules/binding-jms-runtime/src/main/java/org/apache/tuscany/sca/binding/jms/wireformat/jmsobject/runtime/WireFormatJMSObjectServiceProvider.java
+++ b/branches/sca-java-1.x/modules/binding-jms-runtime/src/main/java/org/apache/tuscany/sca/binding/jms/wireformat/jmsobject/runtime/WireFormatJMSObjectServiceProvider.java
@@ -20,12 +20,16 @@
package org.apache.tuscany.sca.binding.jms.wireformat.jmsobject.runtime;
+import java.util.HashMap;
+import java.util.List;
+
import org.apache.tuscany.sca.assembly.Binding;
import org.apache.tuscany.sca.binding.jms.impl.JMSBinding;
import org.apache.tuscany.sca.binding.jms.impl.JMSBindingConstants;
import org.apache.tuscany.sca.binding.jms.wireformat.jmsobject.WireFormatJMSObject;
import org.apache.tuscany.sca.core.ExtensionPointRegistry;
import org.apache.tuscany.sca.interfacedef.InterfaceContract;
+import org.apache.tuscany.sca.interfacedef.Operation;
import org.apache.tuscany.sca.invocation.Interceptor;
import org.apache.tuscany.sca.invocation.Phase;
import org.apache.tuscany.sca.provider.WireFormatProvider;
@@ -41,6 +45,8 @@ public class WireFormatJMSObjectServiceProvider implements WireFormatProvider {
private RuntimeComponentService service;
private JMSBinding binding;
private InterfaceContract interfaceContract;
+ private HashMap<String,Class<?>> singleArgMap;
+ private boolean wrapSingle = true;
public WireFormatJMSObjectServiceProvider(ExtensionPointRegistry registry,
RuntimeComponent component,
@@ -51,6 +57,7 @@ public class WireFormatJMSObjectServiceProvider implements WireFormatProvider {
this.component = component;
this.service = service;
this.binding = (JMSBinding)binding;
+ this.singleArgMap = new HashMap<String,Class<?>>();
// configure the service based on this wire format
@@ -59,6 +66,17 @@ public class WireFormatJMSObjectServiceProvider implements WireFormatProvider {
// any message processors specified in the SCDL in this case
if (this.binding.getRequestWireFormat() instanceof WireFormatJMSObject){
this.binding.setRequestMessageProcessorName(JMSBindingConstants.OBJECT_MP_CLASSNAME);
+
+ List<Operation> opList = service.getService().getInterfaceContract().getInterface().getOperations();
+
+ for (Operation op: opList) {
+ if (op.getInputType().getLogical().size() == 1){
+ this.singleArgMap.put(op.getName(), op.getInputType().getLogical().get(0).getPhysical());
+ }
+ }
+
+ wrapSingle = ((WireFormatJMSObject) this.binding.getRequestWireFormat()).isWrappedSingleInput();
+
}
if (this.binding.getResponseWireFormat() instanceof WireFormatJMSObject){
this.binding.setResponseMessageProcessorName(JMSBindingConstants.OBJECT_MP_CLASSNAME);
@@ -67,6 +85,8 @@ public class WireFormatJMSObjectServiceProvider implements WireFormatProvider {
// just point to the reference interface contract so no
// databinding transformation takes place
interfaceContract = service.getInterfaceContract();
+
+
}
public InterfaceContract configureWireFormatInterfaceContract(InterfaceContract interfaceContract){
@@ -88,9 +108,9 @@ public class WireFormatJMSObjectServiceProvider implements WireFormatProvider {
/**
*/
public Interceptor createInterceptor() {
- return new WireFormatJMSObjectServiceInterceptor((JMSBinding)binding,
- null,
- service.getRuntimeWire(binding));
+
+ return new WireFormatJMSObjectServiceInterceptor((JMSBinding)binding, null,service.getRuntimeWire(binding),
+ this.singleArgMap, wrapSingle );
}
/**