diff options
author | bdaniel <bdaniel@13f79535-47bb-0310-9956-ffa450edef68> | 2010-09-17 18:10:18 +0000 |
---|---|---|
committer | bdaniel <bdaniel@13f79535-47bb-0310-9956-ffa450edef68> | 2010-09-17 18:10:18 +0000 |
commit | 51e5ca754d3d79393793fddcfd6079f3b0c70d8a (patch) | |
tree | 596d6a05fc034ec253af5caea34b735b6e4f72ac /sca-java-2.x/trunk/modules/core/src/main | |
parent | 7cb62d52d3c3b680c6984b987a1b212445c1bef8 (diff) |
TUSCANY-3664 Migrate 1.x Holder support to 2.x and add support for non-void methods and multiple Holders
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@998232 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'sca-java-2.x/trunk/modules/core/src/main')
-rw-r--r-- | sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/impl/JDKInvocationHandler.java | 88 |
1 files changed, 82 insertions, 6 deletions
diff --git a/sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/impl/JDKInvocationHandler.java b/sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/impl/JDKInvocationHandler.java index d0095f45ee..03853a2883 100644 --- a/sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/impl/JDKInvocationHandler.java +++ b/sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/impl/JDKInvocationHandler.java @@ -27,6 +27,8 @@ import java.util.IdentityHashMap; import java.util.List; import java.util.Map; +import javax.xml.ws.Holder; + import org.apache.tuscany.sca.assembly.Endpoint; import org.apache.tuscany.sca.context.ThreadMessageContext; import org.apache.tuscany.sca.core.context.ServiceReferenceExt; @@ -103,12 +105,33 @@ public class JDKInvocationHandler implements InvocationHandler, Serializable { if (chain == null) { throw new IllegalArgumentException("No matching operation is found: " + method); - } - - // send the invocation down the source - Object result = invoke(chain, args, source); + } - return result; + // 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, source); + + // Returned Holder data <T> are placed back in Holder<T>. + boolean holderPattern = false; + Class [] parameters = method.getParameterTypes(); + if ( parameters != null ) { + for ( int i = 0, resultIdx = 0; i < parameters.length; i++ ) { + Class parameterType = parameters[ i ]; + if ( isHolder( parameterType ) ) { + holderPattern = true; + // Pop results and place in holder (demote). + Holder holder = (Holder) args[ i ]; + Object[] resultArray = (Object[])result; + holder.value = resultArray[++resultIdx]; + } + } + } + if ( holderPattern ) + return ((Object[])result)[0]; + else + return result; } /** @@ -307,5 +330,58 @@ public class JDKInvocationHandler implements InvocationHandler, Serializable { public void setCallableReference(ServiceReference<?> callableReference) { this.callableReference = (ServiceReferenceExt<?>)callableReference; } - + + /** + * 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; + } + } |