summaryrefslogtreecommitdiffstats
path: root/sca-java-2.x
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
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')
-rw-r--r--sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/Operation.java5
-rw-r--r--sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/ParameterMode.java28
-rw-r--r--sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/DataTypeImpl.java15
-rw-r--r--sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/OperationImpl.java6
-rw-r--r--sca-java-2.x/trunk/modules/binding-corba-runtime/src/test/java/org/apache/tuscany/sca/binding/corba/testing/service/mocks/TestOperation.java6
-rw-r--r--sca-java-2.x/trunk/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/wire/DataTransformationInterceptor.java52
-rw-r--r--sca-java-2.x/trunk/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/impl/JDKInvocationHandler.java88
-rw-r--r--sca-java-2.x/trunk/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationInvoker.java60
-rw-r--r--sca-java-2.x/trunk/modules/interface-java-jaxws/src/main/java/org/apache/tuscany/sca/interfacedef/java/jaxws/JAXWSJavaInterfaceProcessor.java21
-rw-r--r--sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceIntrospectorImpl.java45
10 files changed, 301 insertions, 25 deletions
diff --git a/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/Operation.java b/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/Operation.java
index c71225c9e2..71c641fa38 100644
--- a/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/Operation.java
+++ b/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/Operation.java
@@ -201,4 +201,9 @@ public interface Operation extends Cloneable, PolicySubject {
*/
Object clone() throws CloneNotSupportedException;
+ /**
+ * Returns the ParameterModes
+ * @return
+ */
+ List<ParameterMode> getParameterModes();
}
diff --git a/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/ParameterMode.java b/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/ParameterMode.java
new file mode 100644
index 0000000000..c4244a3480
--- /dev/null
+++ b/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/ParameterMode.java
@@ -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;
+}
diff --git a/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/DataTypeImpl.java b/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/DataTypeImpl.java
index 12ea22938c..572dd7e356 100644
--- a/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/DataTypeImpl.java
+++ b/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/DataTypeImpl.java
@@ -150,11 +150,18 @@ public class DataTypeImpl<L> implements DataType<L> {
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")
diff --git a/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/OperationImpl.java b/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/OperationImpl.java
index 606782466d..21debb6ea3 100644
--- a/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/OperationImpl.java
+++ b/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/OperationImpl.java
@@ -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 Operation {
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 Operation {
return false;
}
+ public List<ParameterMode> getParameterModes() {
+ return this.parameterModes;
+ }
+
}
diff --git a/sca-java-2.x/trunk/modules/binding-corba-runtime/src/test/java/org/apache/tuscany/sca/binding/corba/testing/service/mocks/TestOperation.java b/sca-java-2.x/trunk/modules/binding-corba-runtime/src/test/java/org/apache/tuscany/sca/binding/corba/testing/service/mocks/TestOperation.java
index 27278dd64e..8cfcf7af5c 100644
--- a/sca-java-2.x/trunk/modules/binding-corba-runtime/src/test/java/org/apache/tuscany/sca/binding/corba/testing/service/mocks/TestOperation.java
+++ b/sca-java-2.x/trunk/modules/binding-corba-runtime/src/test/java/org/apache/tuscany/sca/binding/corba/testing/service/mocks/TestOperation.java
@@ -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 Operation {
return false;
}
+ public List<ParameterMode> getParameterModes() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
}
diff --git a/sca-java-2.x/trunk/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/wire/DataTransformationInterceptor.java b/sca-java-2.x/trunk/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/wire/DataTransformationInterceptor.java
index de29088c1d..7bf9833d04 100644
--- a/sca-java-2.x/trunk/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/wire/DataTransformationInterceptor.java
+++ b/sca-java-2.x/trunk/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/wire/DataTransformationInterceptor.java
@@ -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 DataTransformationInterceptor implements Interceptor {
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 DataTransformationInterceptor implements Interceptor {
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 DataTransformationInterceptor implements Interceptor {
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;
+ }
}
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;
+ }
+
}
diff --git a/sca-java-2.x/trunk/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationInvoker.java b/sca-java-2.x/trunk/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationInvoker.java
index 13fcfbf413..9eade3ba5c 100644
--- a/sca-java-2.x/trunk/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationInvoker.java
+++ b/sca-java-2.x/trunk/modules/implementation-java-runtime/src/main/java/org/apache/tuscany/sca/implementation/java/invocation/JavaImplementationInvoker.java
@@ -20,6 +20,10 @@ package org.apache.tuscany.sca.implementation.java.invocation;
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.implementation.java.introspect.JavaIntrospectionHe
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 implements Invoker {
@SuppressWarnings("unchecked")
public Message invoke(Message msg) {
+
Operation op = msg.getOperation();
if (op == null) {
op = this.operation;
@@ -121,6 +127,30 @@ public class JavaImplementationInvoker implements Invoker {
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 implements Invoker {
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 implements Invoker {
msg.setFaultBody(cause);
break;
}
- }
-
+ }
if (!isChecked) {
if (cause instanceof RuntimeException) {
throw (RuntimeException)cause;
@@ -186,7 +237,6 @@ public class JavaImplementationInvoker implements Invoker {
}
}
- }
-
+ }
}
diff --git a/sca-java-2.x/trunk/modules/interface-java-jaxws/src/main/java/org/apache/tuscany/sca/interfacedef/java/jaxws/JAXWSJavaInterfaceProcessor.java b/sca-java-2.x/trunk/modules/interface-java-jaxws/src/main/java/org/apache/tuscany/sca/interfacedef/java/jaxws/JAXWSJavaInterfaceProcessor.java
index f18ea0118f..735f8cf269 100644
--- a/sca-java-2.x/trunk/modules/interface-java-jaxws/src/main/java/org/apache/tuscany/sca/interfacedef/java/jaxws/JAXWSJavaInterfaceProcessor.java
+++ b/sca-java-2.x/trunk/modules/interface-java-jaxws/src/main/java/org/apache/tuscany/sca/interfacedef/java/jaxws/JAXWSJavaInterfaceProcessor.java
@@ -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.interfacedef.DataType;
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 implements JavaInterfaceVisitor {
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 implements JavaInterfaceVisitor {
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 implements JavaInterfaceVisitor {
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>();
diff --git a/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceIntrospectorImpl.java b/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceIntrospectorImpl.java
index de32136abc..12b312ffb7 100644
--- a/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceIntrospectorImpl.java
+++ b/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceIntrospectorImpl.java
@@ -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.interfacedef.InvalidInterfaceException;
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 JavaInterfaceIntrospectorImpl {
}
}
+ 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 JavaInterfaceIntrospectorImpl {
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 JavaInterfaceIntrospectorImpl {
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 JavaInterfaceIntrospectorImpl {
}
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;
+ }
}