You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tuscany.apache.org by bd...@apache.org on 2010/09/17 20:10:19 UTC

svn commit: r998232 - in /tuscany/sca-java-2.x/trunk/modules: assembly/src/main/java/org/apache/tuscany/sca/interfacedef/ assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/ binding-corba-runtime/src/test/java/org/apache/tuscany/sca/bindin...

Author: bdaniel
Date: Fri Sep 17 18:10:18 2010
New Revision: 998232

URL: http://svn.apache.org/viewvc?rev=998232&view=rev
Log:
TUSCANY-3664 Migrate 1.x Holder support to 2.x and add support for non-void methods and multiple Holders

Added:
    tuscany/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/ParameterMode.java   (with props)
Modified:
    tuscany/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/Operation.java
    tuscany/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/DataTypeImpl.java
    tuscany/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/OperationImpl.java
    tuscany/sca-java-2.x/trunk/modules/binding-corba-runtime/src/test/java/org/apache/tuscany/sca/binding/corba/testing/service/mocks/TestOperation.java
    tuscany/sca-java-2.x/trunk/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/wire/DataTransformationInterceptor.java
    tuscany/sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/impl/JDKInvocationHandler.java
    tuscany/sca-java-2.x/trunk/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationInvoker.java
    tuscany/sca-java-2.x/trunk/modules/interface-java-jaxws/src/main/java/org/apache/tuscany/sca/interfacedef/java/jaxws/JAXWSJavaInterfaceProcessor.java
    tuscany/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceIntrospectorImpl.java

Modified: tuscany/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/Operation.java
URL: http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/Operation.java?rev=998232&r1=998231&r2=998232&view=diff
==============================================================================
--- tuscany/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/Operation.java (original)
+++ tuscany/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/Operation.java Fri Sep 17 18:10:18 2010
@@ -201,4 +201,9 @@ public interface Operation extends Clone
      */
     Object clone() throws CloneNotSupportedException;
 
+    /**
+     * Returns the ParameterModes
+     * @return
+     */
+    List<ParameterMode> getParameterModes();
 }

Added: tuscany/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/ParameterMode.java
URL: http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/ParameterMode.java?rev=998232&view=auto
==============================================================================
--- tuscany/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/ParameterMode.java (added)
+++ tuscany/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/ParameterMode.java Fri Sep 17 18:10:18 2010
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.interfacedef;
+
+/**
+ * Parameter mode
+ * @see http://java.sun.com/javase/6/docs/api/javax/jws/WebParam.Mode.html
+ */
+public enum ParameterMode {
+    IN, OUT, INOUT;
+}

Propchange: tuscany/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/ParameterMode.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: tuscany/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/DataTypeImpl.java
URL: http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/DataTypeImpl.java?rev=998232&r1=998231&r2=998232&view=diff
==============================================================================
--- tuscany/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/DataTypeImpl.java (original)
+++ tuscany/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/DataTypeImpl.java Fri Sep 17 18:10:18 2010
@@ -150,11 +150,18 @@ public class DataTypeImpl<L> implements 
         this.dataBinding = dataBinding;
     }
 
+        
     @Override
-    public String toString() {
-        StringBuffer sb = new StringBuffer();
-        sb.append(physical).append(" ").append(dataBinding).append(" ").append(logical);
-        return sb.toString();
+    public String toString() {    	
+    	StringBuilder b = new StringBuilder( 256 );
+    	b.append( "DataType[" );
+    	b.append( "dataBinding=" + ((dataBinding==null) ? "null" : dataBinding) );
+    	b.append( ", genericType=" + ((genericType==null) ? "null" : genericType) ); 
+    	b.append( ", physical=" + ((physical==null) ? "null" : physical) ); 
+    	b.append( ", logical=" + ((logical==null) ? "null" : logical) );
+    	b.append( ", metaData size=" + ((metaDataMap==null) ? "0" : metaDataMap.size()) );
+    	b.append( "]" );
+    	return b.toString();
     }
 
     @SuppressWarnings("unchecked")

Modified: tuscany/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/OperationImpl.java
URL: http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/OperationImpl.java?rev=998232&r1=998231&r2=998232&view=diff
==============================================================================
--- tuscany/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/OperationImpl.java (original)
+++ tuscany/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/OperationImpl.java Fri Sep 17 18:10:18 2010
@@ -29,6 +29,7 @@ import javax.xml.namespace.QName;
 import org.apache.tuscany.sca.interfacedef.DataType;
 import org.apache.tuscany.sca.interfacedef.Interface;
 import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.interfacedef.ParameterMode;
 import org.apache.tuscany.sca.interfacedef.util.WrapperInfo;
 import org.apache.tuscany.sca.interfacedef.util.XMLType;
 import org.apache.tuscany.sca.policy.ExtensionType;
@@ -49,6 +50,7 @@ public class OperationImpl implements Op
     private DataType<List<DataType>> inputType;
     private List<DataType> faultTypes;
     private Interface interfaze;
+    private List<ParameterMode> parameterModes = new ArrayList<ParameterMode>();
     private boolean nonBlocking;
     private boolean wrapperStyle;
     private WrapperInfo wrapper;
@@ -279,4 +281,8 @@ public class OperationImpl implements Op
 		return false;
 	}
 
+	public List<ParameterMode> getParameterModes() {
+		return this.parameterModes;
+	}
+
 }

Modified: tuscany/sca-java-2.x/trunk/modules/binding-corba-runtime/src/test/java/org/apache/tuscany/sca/binding/corba/testing/service/mocks/TestOperation.java
URL: http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/binding-corba-runtime/src/test/java/org/apache/tuscany/sca/binding/corba/testing/service/mocks/TestOperation.java?rev=998232&r1=998231&r2=998232&view=diff
==============================================================================
--- tuscany/sca-java-2.x/trunk/modules/binding-corba-runtime/src/test/java/org/apache/tuscany/sca/binding/corba/testing/service/mocks/TestOperation.java (original)
+++ tuscany/sca-java-2.x/trunk/modules/binding-corba-runtime/src/test/java/org/apache/tuscany/sca/binding/corba/testing/service/mocks/TestOperation.java Fri Sep 17 18:10:18 2010
@@ -27,6 +27,7 @@ import javax.xml.namespace.QName;
 import org.apache.tuscany.sca.interfacedef.DataType;
 import org.apache.tuscany.sca.interfacedef.Interface;
 import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.interfacedef.ParameterMode;
 import org.apache.tuscany.sca.interfacedef.util.WrapperInfo;
 import org.apache.tuscany.sca.interfacedef.util.XMLType;
 import org.apache.tuscany.sca.policy.ExtensionType;
@@ -174,4 +175,9 @@ public class TestOperation implements Op
 		return false;
 	}
 
+	public List<ParameterMode> getParameterModes() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
 }

Modified: tuscany/sca-java-2.x/trunk/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/wire/DataTransformationInterceptor.java
URL: http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/wire/DataTransformationInterceptor.java?rev=998232&r1=998231&r2=998232&view=diff
==============================================================================
--- tuscany/sca-java-2.x/trunk/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/wire/DataTransformationInterceptor.java (original)
+++ tuscany/sca-java-2.x/trunk/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/wire/DataTransformationInterceptor.java Fri Sep 17 18:10:18 2010
@@ -19,11 +19,16 @@
 
 package org.apache.tuscany.sca.core.databinding.wire;
 
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 import org.apache.tuscany.sca.databinding.Mediator;
+import org.apache.tuscany.sca.interfacedef.DataType;
 import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.interfacedef.java.JavaOperation;
 import org.apache.tuscany.sca.invocation.Interceptor;
 import org.apache.tuscany.sca.invocation.Invoker;
 import org.apache.tuscany.sca.invocation.Message;
@@ -50,6 +55,21 @@ public class DataTransformationIntercept
         super();
         this.sourceOperation = sourceOperation;
         this.targetOperation = targetOperation;
+        if ( sourceOperation instanceof JavaOperation ) {
+        	JavaOperation javaOp = (JavaOperation) sourceOperation;
+        	Method sourceMethod = javaOp.getJavaMethod();
+        }
+        // Holder pattern. In order to perform data mediation on Holder return types, it is
+        // necessary to set up a data transformation on the Holder<T> class T. on return.
+        DataType<DataType> returnTargetType = getFirstHolderType( sourceOperation.getInputType() );
+        if ( returnTargetType != null ) {
+        	this.sourceOperation.setOutputType(returnTargetType);               
+        }
+        returnTargetType = getFirstHolderType( targetOperation.getInputType() );
+        if ( returnTargetType != null ) {
+        	this.targetOperation.setOutputType(returnTargetType);               
+        }
+        	        
         this.mediator = mediator;
         this.invocable = invocable;
     }
@@ -64,12 +84,14 @@ public class DataTransformationIntercept
         Object input = mediator.mediateInput(msg.getBody(), sourceOperation, targetOperation, metadata);
         msg.setBody(input);
         Message resultMsg = next.invoke(msg);
-        Object result = resultMsg.getBody();
+       
         if (sourceOperation.isNonBlocking()) {
             // Not to reset the message body
             return resultMsg;
         }
 
+        Object result = resultMsg.getBody();
+        
         if (resultMsg.isFault()) {
             Object transformedFault = null;
             if ((result instanceof Exception) && !(result instanceof RuntimeException)) {
@@ -95,4 +117,32 @@ public class DataTransformationIntercept
         this.next = next;
     }
 
+    /**
+     * Returns return type for first Holder in input list.
+     * Returns null if the inputs do not contain a Holder.
+     */
+    protected static DataType<DataType> getFirstHolderType( DataType<List<DataType>> inputTypes ) {
+    	if (inputTypes != null) {
+    		List<DataType> logicalType = inputTypes.getLogical();
+    		if (logicalType != null) {
+    			for (int i = 0; i < logicalType.size(); i++) {
+    				DataType dataType = logicalType.get(i);
+    				if (isHolder(dataType.getGenericType())) {
+    					// Fix up output from void to returned data type.
+    					// System.out.println("DataTransformationInterceptor.<> source input[" + i + "] is Holder, logicalType=" + dataType);
+    					return dataType;
+    				}
+    			}
+    		}
+    	}
+    	return null;
+    }
+    
+    protected static boolean isHolder( Type type ) {
+    	String typeString = type.toString();
+    	if ( typeString.startsWith( "javax.xml.ws.Holder" ) ) {
+    		return true;
+    	}
+    	return false;        
+    }
 }

Modified: tuscany/sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/impl/JDKInvocationHandler.java
URL: http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/impl/JDKInvocationHandler.java?rev=998232&r1=998231&r2=998232&view=diff
==============================================================================
--- tuscany/sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/impl/JDKInvocationHandler.java (original)
+++ tuscany/sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/impl/JDKInvocationHandler.java Fri Sep 17 18:10:18 2010
@@ -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 implem
         
         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 implem
     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;        
+    }
+        
 }

Modified: tuscany/sca-java-2.x/trunk/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationInvoker.java
URL: http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationInvoker.java?rev=998232&r1=998231&r2=998232&view=diff
==============================================================================
--- tuscany/sca-java-2.x/trunk/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationInvoker.java (original)
+++ tuscany/sca-java-2.x/trunk/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationInvoker.java Fri Sep 17 18:10:18 2010
@@ -20,6 +20,10 @@ package org.apache.tuscany.sca.implement
 
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.ws.Holder;
 
 import org.apache.tuscany.sca.assembly.EndpointReference;
 import org.apache.tuscany.sca.core.factory.ObjectCreationException;
@@ -33,6 +37,7 @@ import org.apache.tuscany.sca.implementa
 import org.apache.tuscany.sca.interfacedef.DataType;
 import org.apache.tuscany.sca.interfacedef.InterfaceContract;
 import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.interfacedef.ParameterMode;
 import org.apache.tuscany.sca.interfacedef.java.JavaInterface;
 import org.apache.tuscany.sca.interfacedef.java.impl.JavaInterfaceUtil;
 import org.apache.tuscany.sca.invocation.Invoker;
@@ -74,6 +79,7 @@ public class JavaImplementationInvoker i
 
     @SuppressWarnings("unchecked")
     public Message invoke(Message msg) {
+    	
         Operation op = msg.getOperation();
         if (op == null) {
             op = this.operation;
@@ -121,6 +127,30 @@ public class JavaImplementationInvoker i
             
             Thread.currentThread().setContextClassLoader(instance.getClass().getClassLoader());
             
+            int argumentHolderCount = 0;
+
+            // Holder pattern. Any payload parameters <T> which are should be in holders are placed in Holder<T>.
+            // Only check Holder for remotable interfaces
+            if (imethod != null && op.getInterface().isRemotable()) {
+                List<DataType> inputTypes = op.getInputType().getLogical();
+                for (int i = 0, size = inputTypes.size(); i < size; i++) {
+                    if (ParameterMode.IN != op.getParameterModes().get(i)) {
+                        // Promote array params from [<T>] to [Holder<T>]
+                        Object[] payloadArray = (Object[])payload;
+                  
+                        if ( ParameterMode.INOUT == op.getParameterModes().get(i)) {
+                        	Object item = payloadArray[i];                           
+                        	payloadArray[i] = new Holder(item);
+                        } else {
+                        	// Create an empty Holder since we should not pass values for OUT parameters
+                        	payloadArray[i] = new Holder();
+                        }
+                        
+                        argumentHolderCount++;
+                    }
+                }
+            }
+
             Object ret;
             if (payload != null && !payload.getClass().isArray()) {
                 ret = imethod.invoke(instance, payload);
@@ -130,7 +160,29 @@ public class JavaImplementationInvoker i
 
             scopeContainer.returnWrapper(wrapper, contextId);
             
-            msg.setBody(ret);
+                        
+            if (argumentHolderCount > 0) {
+                // Holder pattern. Any payload Holder<T> types are returned as the message body.
+                List<Object> returnArgs = new ArrayList<Object>();
+                returnArgs.add(ret);
+                if (imethod != null) {
+                	Object[] payloadArray = (Object[])payload;
+                    for (int i = 0, size = op.getParameterModes().size(); i < size; i++) {
+                        // System.out.println( "JavaImplementationInvoker.invoke return parameter " + i + " type=" + parameter.getClass().getName() );
+                        if (ParameterMode.IN != op.getParameterModes().get(i)) {                        	
+                            // Demote array params from Holder<T> to <T>.                                                   
+                                Holder<Object> item = (Holder<Object>)payloadArray[i];
+                                payloadArray[i] = item.value;
+                                returnArgs.add(payloadArray[i]);
+                        }
+                    }
+                }
+
+                msg.setBody(returnArgs.toArray());
+
+            } else {
+                msg.setBody(ret);
+            }
         } catch (InvocationTargetException e) {
             Throwable cause = e.getTargetException();
             boolean isChecked = false;
@@ -140,8 +192,7 @@ public class JavaImplementationInvoker i
                     msg.setFaultBody(cause);
                     break;
                 }
-            } 
-            
+            }
             if (!isChecked) {
                 if (cause instanceof RuntimeException) {
                     throw (RuntimeException)cause;
@@ -186,7 +237,6 @@ public class JavaImplementationInvoker i
 			}
 		}
 		
-	}
-			
+	}		
 
 }

Modified: tuscany/sca-java-2.x/trunk/modules/interface-java-jaxws/src/main/java/org/apache/tuscany/sca/interfacedef/java/jaxws/JAXWSJavaInterfaceProcessor.java
URL: http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/interface-java-jaxws/src/main/java/org/apache/tuscany/sca/interfacedef/java/jaxws/JAXWSJavaInterfaceProcessor.java?rev=998232&r1=998231&r2=998232&view=diff
==============================================================================
--- tuscany/sca-java-2.x/trunk/modules/interface-java-jaxws/src/main/java/org/apache/tuscany/sca/interfacedef/java/jaxws/JAXWSJavaInterfaceProcessor.java (original)
+++ tuscany/sca-java-2.x/trunk/modules/interface-java-jaxws/src/main/java/org/apache/tuscany/sca/interfacedef/java/jaxws/JAXWSJavaInterfaceProcessor.java Fri Sep 17 18:10:18 2010
@@ -31,14 +31,13 @@ import java.util.List;
 import javax.jws.Oneway;
 import javax.jws.WebMethod;
 import javax.jws.WebParam;
+import javax.jws.WebParam.Mode;
 import javax.jws.WebResult;
-import javax.jws.WebService;
 import javax.jws.soap.SOAPBinding;
 import javax.jws.soap.SOAPBinding.Style;
 import javax.xml.namespace.QName;
 import javax.xml.ws.RequestWrapper;
 import javax.xml.ws.ResponseWrapper;
-import javax.xml.ws.WebServiceProvider;
 
 import org.apache.tuscany.sca.core.ExtensionPointRegistry;
 import org.apache.tuscany.sca.core.FactoryExtensionPoint;
@@ -51,14 +50,13 @@ import org.apache.tuscany.sca.interfaced
 import org.apache.tuscany.sca.interfacedef.FaultExceptionMapper;
 import org.apache.tuscany.sca.interfacedef.InvalidInterfaceException;
 import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.interfacedef.ParameterMode;
 import org.apache.tuscany.sca.interfacedef.impl.DataTypeImpl;
 import org.apache.tuscany.sca.interfacedef.java.JavaInterface;
-import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceContract;
 import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory;
 import org.apache.tuscany.sca.interfacedef.java.JavaOperation;
 import org.apache.tuscany.sca.interfacedef.java.introspect.JavaInterfaceVisitor;
 import org.apache.tuscany.sca.interfacedef.util.ElementInfo;
-import org.apache.tuscany.sca.interfacedef.util.JavaXMLMapper;
 import org.apache.tuscany.sca.interfacedef.util.TypeInfo;
 import org.apache.tuscany.sca.interfacedef.util.WrapperInfo;
 import org.apache.tuscany.sca.interfacedef.util.XMLType;
@@ -89,10 +87,21 @@ public class JAXWSJavaInterfaceProcessor
         this.wsdlFactory = factories.getFactory(WSDLFactory.class);
     }
 
+  
     public JAXWSJavaInterfaceProcessor() {
         super();
     }
 
+    private ParameterMode getParameterMode(WebParam.Mode mode) {
+    	if (mode == Mode.INOUT) {
+    		return ParameterMode.INOUT;
+    	} else if (mode == Mode.OUT) {
+    		return ParameterMode.OUT;
+    	} else {
+    		return ParameterMode.IN;
+    	}
+    }
+    
     private static String capitalize(String name) {
         if (name == null || name.length() == 0) {
             return name;
@@ -173,6 +182,7 @@ public class JAXWSJavaInterfaceProcessor
                         if (logical instanceof XMLType) {
                             ((XMLType)logical).setElementName(element);
                         }
+                        operation.getParameterModes().set(i, getParameterMode(param.mode()));
                     }
                 }
                 WebResult result = method.getAnnotation(WebResult.class);
@@ -282,6 +292,9 @@ public class JAXWSJavaInterfaceProcessor
                         type = ((XMLType)logical).getTypeName();
                     }
                     inputElements.add(new ElementInfo(element, new TypeInfo(type, false, null)));
+                    if (param != null) {
+                    	operation.getParameterModes().set(i, getParameterMode(param.mode()));
+                    }
                 }
 
                 List<ElementInfo> outputElements = new ArrayList<ElementInfo>();

Modified: tuscany/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceIntrospectorImpl.java
URL: http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceIntrospectorImpl.java?rev=998232&r1=998231&r2=998232&view=diff
==============================================================================
--- tuscany/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceIntrospectorImpl.java (original)
+++ tuscany/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceIntrospectorImpl.java Fri Sep 17 18:10:18 2010
@@ -35,6 +35,7 @@ import java.util.concurrent.Future;
 
 import javax.xml.namespace.QName;
 import javax.xml.ws.AsyncHandler;
+import javax.xml.ws.Holder;
 import javax.xml.ws.Response;
 
 import org.apache.tuscany.sca.interfacedef.DataType;
@@ -44,6 +45,7 @@ import org.apache.tuscany.sca.interfaced
 import org.apache.tuscany.sca.interfacedef.InvalidOperationException;
 import org.apache.tuscany.sca.interfacedef.Operation;
 import org.apache.tuscany.sca.interfacedef.OverloadedOperationException;
+import org.apache.tuscany.sca.interfacedef.ParameterMode;
 import org.apache.tuscany.sca.interfacedef.impl.DataTypeImpl;
 import org.apache.tuscany.sca.interfacedef.java.JavaInterface;
 import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory;
@@ -220,6 +222,9 @@ public class JavaInterfaceIntrospectorIm
                 }
             }
 
+            JavaOperation operation = new JavaOperationImpl();
+            operation.setName(name);
+            
             // Set outputType to null for void
             XMLType xmlReturnType = new XMLType(new QName(ns, "return"), null);
             DataType<XMLType> returnDataType =
@@ -229,10 +234,24 @@ public class JavaInterfaceIntrospectorIm
             Type[] genericParamTypes = method.getGenericParameterTypes();
             for (int i = 0; i < parameterTypes.length; i++) {
                 Class<?> paramType = parameterTypes[i];
-                XMLType xmlParamType = new XMLType(new QName(ns, "arg" + i), null);
-                paramDataTypes.add(new DataTypeImpl<XMLType>(UNKNOWN_DATABINDING, paramType, genericParamTypes[i],
-                                                             xmlParamType));
+                XMLType xmlParamType = new XMLType(new QName(ns, "arg" + i), null);                            
+     
+                DataTypeImpl<XMLType> xmlDataType = new DataTypeImpl<XMLType>(
+                		UNKNOWN_DATABINDING, paramType, genericParamTypes[i],xmlParamType);
+                ParameterMode mode = ParameterMode.IN;
+                // Holder pattern. Physical types of Holder<T> classes are updated to <T> to aid in transformations.
+                if ( Holder.class == paramType) {
+                	Type firstActual = getFirstActualType( genericParamTypes[ i ] );
+                	if ( firstActual != null ) {
+                		xmlDataType.setPhysical( (Class<?>)firstActual );
+                		mode = ParameterMode.INOUT;
+                	}
+                }
+                paramDataTypes.add( xmlDataType);
+                operation.getParameterModes().add(mode);
             }
+                    
+            // Fault types                                                          
             List<DataType> faultDataTypes = new ArrayList<DataType>(faultTypes.length);
             Type[] genericFaultTypes = method.getGenericExceptionTypes();
             if( method.isAnnotationPresent(AsyncFault.class) ) {
@@ -254,8 +273,7 @@ public class JavaInterfaceIntrospectorIm
 
             DataType<List<DataType>> inputType =
                 new DataTypeImpl<List<DataType>>(IDL_INPUT, Object[].class, paramDataTypes);
-            JavaOperation operation = new JavaOperationImpl();
-            operation.setName(name);
+           
             operation.setInputType(inputType);
             operation.setOutputType(returnDataType);
             operation.setFaultTypes(faultDataTypes);
@@ -305,5 +323,22 @@ public class JavaInterfaceIntrospectorIm
         }
         return false;
     }
+    
+
+    /**
+     * Given a Class<T>, returns T, otherwise null.
+     * @param testClass
+     * @return
+     */
+    protected static Type getFirstActualType(Type genericType) {
+        if (genericType instanceof ParameterizedType) {
+            ParameterizedType pType = (ParameterizedType)genericType;
+            Type[] actualTypes = pType.getActualTypeArguments();
+            if ((actualTypes != null) && (actualTypes.length > 0)) {
+                return actualTypes[0];
+            }
+        }
+        return null;
+    }
 
 }