summaryrefslogtreecommitdiffstats
path: root/sca-java-2.x/trunk/modules/core/src
diff options
context:
space:
mode:
authorbdaniel <bdaniel@13f79535-47bb-0310-9956-ffa450edef68>2010-09-17 18:10:18 +0000
committerbdaniel <bdaniel@13f79535-47bb-0310-9956-ffa450edef68>2010-09-17 18:10:18 +0000
commit51e5ca754d3d79393793fddcfd6079f3b0c70d8a (patch)
tree596d6a05fc034ec253af5caea34b735b6e4f72ac /sca-java-2.x/trunk/modules/core/src
parent7cb62d52d3c3b680c6984b987a1b212445c1bef8 (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')
-rw-r--r--sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/impl/JDKInvocationHandler.java88
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;
+ }
+
}