diff options
Diffstat (limited to 'branches/sca-java-1.x/modules/core/src')
-rw-r--r-- | branches/sca-java-1.x/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/JDKInvocationHandler.java | 86 |
1 files changed, 82 insertions, 4 deletions
diff --git a/branches/sca-java-1.x/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/JDKInvocationHandler.java b/branches/sca-java-1.x/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/JDKInvocationHandler.java index a23b9af9ad..4216217028 100644 --- a/branches/sca-java-1.x/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/JDKInvocationHandler.java +++ b/branches/sca-java-1.x/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/JDKInvocationHandler.java @@ -23,6 +23,8 @@ import java.io.Serializable; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; +import java.lang.reflect.Type; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -58,6 +60,10 @@ import org.osoa.sca.ConversationEndedException; import org.osoa.sca.ServiceReference; import org.osoa.sca.ServiceRuntimeException; +import java.util.Iterator; +import javax.xml.ws.Holder; + + /** * @version $Rev$ $Date$ */ @@ -150,8 +156,24 @@ public class JDKInvocationHandler implements InvocationHandler, Serializable { throw new IllegalArgumentException("No matching operation is found: " + method); } - // send the invocation down the wire - Object result = invoke(chain, args, wire, source); + // Holder pattern. Items stored in a Holder<T> are promoted to T. + // After the invoke, the returned data <T> are placed back in Holder<T>. + Object [] promotedArgs = promoteHolderArgs( args ); + + Object result = invoke(chain, promotedArgs, wire, source); + + // Returned Holder data <T> are placed back in Holder<T>. + Class [] parameters = method.getParameterTypes(); + if ( parameters != null ) { + for ( int i = 0; i < parameters.length; i++ ) { + Class parameterType = parameters[ i ]; + if ( isHolder( parameterType ) ) { + // Pop results and place in holder (demote). + Holder holder = (Holder) args[ i ]; + holder.value = result; + } + } + } return result; } @@ -272,8 +294,9 @@ public class JDKInvocationHandler implements InvocationHandler, Serializable { } Invoker headInvoker = chain.getHeadInvoker(); Operation operation = chain.getTargetOperation(); - msg.setOperation(operation); - msg.setBody(args); + + msg.setOperation(operation); + msg.setBody( args ); Message msgContext = ThreadMessageContext.getMessageContext(); Object currentConversationID = msgContext.getFrom().getReferenceParameters().getConversationID(); @@ -513,4 +536,59 @@ public class JDKInvocationHandler implements InvocationHandler, Serializable { } + + /** + * Creates a copy of arguments. Holder<T> values are promoted to T. + * Note. It is essential that arg Holders not be destroyed here. + * PromotedArgs should not destroy holders. They are used on response return. + * @param args containing Holders and other objects. + * @return Object [] + */ + protected static Object [] promoteHolderArgs( Object [] args ) { + if ( args == null ) + return args; + Object [] promotedArgs = new Object[ args.length ]; + + for ( int i = 0; i < args.length; i++ ) { + Object argument = args[ i ]; + if ( argument != null ) { + if ( isHolder( argument ) ) { + promotedArgs[ i ] = ((Holder)argument).value; + } else { + promotedArgs[ i ] = args[ i ]; + } + + } + } + return promotedArgs; + } + + /** + * Given a Class, tells if it is a Holder by comparing to "javax.xml.ws.Holder" + * @param testClass + * @return boolean whether class is Holder type. + */ + protected static boolean isHolder( Class testClass ) { + if ( testClass.getName().startsWith( "javax.xml.ws.Holder" )) { + return true; + } + return false; + } + + + /** + * Given an Object, tells if it is a Holder by comparing to "javax.xml.ws.Holder" + * @param testClass + * @return boolean stating whether Object is a Holder type. + * @author DOB + */ + protected static boolean isHolder( Object object ) { + String objectName = object.getClass().getName(); + if ( object instanceof javax.xml.ws.Holder ) { + return true; + } + return false; + } + + } |