From de7789044d196dfadab3b8ddfddf2f26f7a1bbd8 Mon Sep 17 00:00:00 2001 From: scottkurz Date: Thu, 20 Jan 2011 14:57:06 +0000 Subject: Fix for TUSCANY-3819 (still need to cleanup bare case, wsdlgen). git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@1061329 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/tuscany/sca/interfacedef/Operation.java | 17 ++- .../impl/InterfaceContractMapperImpl.java | 9 +- .../sca/interfacedef/impl/InterfaceImpl.java | 6 +- .../sca/interfacedef/impl/OperationImpl.java | 79 ++++++------ .../tuscany/sca/interfacedef/util/WrapperInfo.java | 23 ++-- .../corba/testing/service/mocks/TestOperation.java | 4 +- .../jsonrpc/provider/JSONRPCServiceServlet.java | 2 +- .../ws/wsdlgen/Interface2WSDLGenerator.java | 38 +++++- .../Exception2ExceptionTransformer.java | 6 +- .../transformers/Input2InputTransformer.java | 5 +- .../transformers/Output2OutputTransformer.java | 140 ++++++++++++--------- .../core/invocation/impl/JDKInvocationHandler.java | 55 ++++++-- .../tuscany/sca/databinding/DataBinding.java | 13 +- .../tuscany/sca/databinding/impl/MediatorImpl.java | 51 ++++---- .../java/invocation/JavaImplementationInvoker.java | 73 ++++++++--- .../java/jaxws/JAXWSAsyncInterfaceProcessor.java | 4 +- .../java/jaxws/JAXWSJavaInterfaceProcessor.java | 63 ++++++---- .../java/impl/JavaInterfaceIntrospectorImpl.java | 58 ++++----- .../wsdl/impl/WSDLOperationIntrospectorImpl.java | 35 ++---- .../WSDLOperationIntrospectorTestCase.java | 5 +- 20 files changed, 401 insertions(+), 285 deletions(-) (limited to 'sca-java-2.x/trunk') 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 fd47ece34c..c3a7ca972a 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 @@ -210,7 +210,20 @@ public interface Operation extends Cloneable, PolicySubject { * Returns true * @return */ - public boolean hasHolders(); + public boolean hasArrayWrappedOutput(); - public void setHasHolders(boolean value); + public void setHasArrayWrappedOutput(boolean value); + + /** + * A special databinding for input message of an operation + */ + String IDL_INPUT = "idl:input"; + /** + * A special databinding for output message of an operation + */ + String IDL_OUTPUT = "idl:output"; + /** + * A special databinding for fault message of an operation + */ + String IDL_FAULT = "idl:fault"; } diff --git a/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/InterfaceContractMapperImpl.java b/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/InterfaceContractMapperImpl.java index c28694c930..486081dfec 100644 --- a/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/InterfaceContractMapperImpl.java +++ b/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/InterfaceContractMapperImpl.java @@ -260,16 +260,14 @@ public class InterfaceContractMapperImpl implements InterfaceContractMapper { List sourceInputType = source.getInputType().getLogical(); if (source.isWrapperStyle() && source.getWrapper() != null) { sourceInputType = source.getWrapper().getUnwrappedInputType().getLogical(); - sourceOutputType = new ArrayList(); - sourceOutputType.add(source.getWrapper().getUnwrappedOutputType()); + sourceOutputType = source.getWrapper().getUnwrappedOutputType().getLogical(); checkSourceWrapper = false; } boolean checkTargetWrapper = true; List targetInputType = target.getInputType().getLogical(); if (target.isWrapperStyle() && target.getWrapper() != null) { targetInputType = target.getWrapper().getUnwrappedInputType().getLogical(); - targetOutputType = new ArrayList(); - targetOutputType.add(target.getWrapper().getUnwrappedOutputType()); + targetOutputType = target.getWrapper().getUnwrappedOutputType().getLogical(); checkTargetWrapper = false; } @@ -278,8 +276,7 @@ public class InterfaceContractMapperImpl implements InterfaceContractMapper { return true; } */ - - + if ( sourceOutputType.size() != targetOutputType.size()) { if (audit != null){ audit.append("different number of output types"); diff --git a/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/InterfaceImpl.java b/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/InterfaceImpl.java index eeab73e14e..1daa6baf9c 100644 --- a/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/InterfaceImpl.java +++ b/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/InterfaceImpl.java @@ -222,9 +222,11 @@ public class InterfaceImpl implements Interface { setDataBinding(d, dataBinding); } } - DataType unwrappedOutputType = wrapper.getUnwrappedOutputType(); + DataType> unwrappedOutputType = wrapper.getUnwrappedOutputType(); if (unwrappedOutputType != null) { - setDataBinding(unwrappedOutputType, dataBinding); + for (DataType d : unwrappedOutputType.getLogical()) { + setDataBinding(d, dataBinding); + } } } } 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 350135d974..c1fa4d4e4c 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 @@ -63,14 +63,15 @@ public class OperationImpl implements Operation { private List policySets = new ArrayList(); private List requiredIntents = new ArrayList(); private ExtensionType type; - private DataType> outputType; - private boolean hasHolders; + private DataType> outputType; + private boolean hasMultipleOutputs; /** * @param name */ public OperationImpl() { - inputType = new DataTypeImpl>("idl:input", Object[].class, new ArrayList()); + inputType = new DataTypeImpl>(IDL_INPUT, Object[].class, new ArrayList()); + outputType = new DataTypeImpl>(IDL_OUTPUT, Object[].class, new ArrayList()); faultTypes = new ArrayList(); faultBeans = new HashMap>>(); } @@ -123,15 +124,15 @@ public class OperationImpl implements Operation { * @return the outputType */ public DataType> getOutputType() { - return this.outputType; + return this.outputType; } - + /** * @param outputType the outputType to set */ public void setOutputType(DataType> outputType) { - this.outputType = outputType; + this.outputType = outputType; } /** @@ -237,24 +238,24 @@ public class OperationImpl implements Operation { copy.inputType = clonedInputType; if ( outputType != null ) { - List clonedLogicalOutputTypes = new ArrayList(); - for ( DataType t : outputType.getLogical()) { - if ( t == null ) { - clonedLogicalOutputTypes.add(null); - } else { - DataType type = (DataType) t.clone(); - clonedLogicalOutputTypes.add(type); - } - } - DataType> clonedOutputType = - new DataTypeImpl>(outputType.getPhysical(), clonedLogicalOutputTypes); - clonedOutputType.setDataBinding(outputType.getDataBinding()); - copy.outputType = clonedOutputType; + List clonedLogicalOutputTypes = new ArrayList(); + for ( DataType t : outputType.getLogical()) { + if ( t == null ) { + clonedLogicalOutputTypes.add(null); + } else { + DataType type = (DataType) t.clone(); + clonedLogicalOutputTypes.add(type); + } + } + DataType> clonedOutputType = + new DataTypeImpl>(outputType.getPhysical(), clonedLogicalOutputTypes); + clonedOutputType.setDataBinding(outputType.getDataBinding()); + copy.outputType = clonedOutputType; } copy.attributes = new ConcurrentHashMap(); copy.attributes.putAll(attributes); - + // [rfeng] We need to clone the wrapper as it holds the databinding information if (wrapper != null) { copy.wrapper = (WrapperInfo)wrapper.clone(); @@ -287,24 +288,24 @@ public class OperationImpl implements Operation { return attributes; } - /** - * Indicates if this operation is an async server style of operation - * @return true if the operation is async server style - */ - public boolean isAsyncServer() { - return false; - } - - public List getParameterModes() { - return this.parameterModes; - } - - public boolean hasHolders() { - return this.hasHolders; - } - - public void setHasHolders(boolean value) { - this.hasHolders = value; - } + /** + * Indicates if this operation is an async server style of operation + * @return true if the operation is async server style + */ + public boolean isAsyncServer() { + return false; + } + + public List getParameterModes() { + return this.parameterModes; + } + + public boolean hasArrayWrappedOutput() { + return this.hasMultipleOutputs; + } + + public void setHasArrayWrappedOutput(boolean value) { + this.hasMultipleOutputs = value; + } } diff --git a/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/util/WrapperInfo.java b/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/util/WrapperInfo.java index 2252434c39..9f083a4083 100644 --- a/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/util/WrapperInfo.java +++ b/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/util/WrapperInfo.java @@ -60,8 +60,8 @@ public class WrapperInfo implements Cloneable { // The data type of the unwrapped input child elements private DataType> unwrappedInputType; - // The data type of the unwrapped output child element (we only supports one child) - private DataType unwrappedOutputType; + // The data type of the unwrapped output child elements + private DataType> unwrappedOutputType; // The data for the input/output wrappers private String dataBinding; @@ -141,21 +141,16 @@ public class WrapperInfo implements Cloneable { /** * @return the unwrappedOutputType */ - public DataType getUnwrappedOutputType() { + public DataType> getUnwrappedOutputType() { if (unwrappedOutputType == null) { - List elements = getOutputChildElements(); - if (elements != null && elements.size() > 0) { - if (elements.size() > 1) { - // We don't support output with multiple parts - // throw new IllegalArgumentException("Multi-part output is not supported"); - } - ElementInfo element = elements.get(0); - - unwrappedOutputType = getDataType(element); + List childTypes = new ArrayList(); + for (ElementInfo element : getOutputChildElements()) { + DataType type = getDataType(element); + childTypes.add(type); } + unwrappedOutputType = new DataTypeImpl>("idl:unwrapped.input", Object[].class, childTypes); } - return unwrappedOutputType; - } + return unwrappedOutputType; } public Class getInputWrapperClass() { return inputWrapperType == null ? null : inputWrapperType.getPhysical(); 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 1a82a16bbd..fe62d1babb 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 @@ -186,12 +186,12 @@ public class TestOperation implements Operation { } - public boolean hasHolders() { + public boolean hasArrayWrappedOutput() { // TODO Auto-generated method stub return false; } - public void setHasHolders(boolean arg0) { + public void setHasArrayWrappedOutput(boolean arg0) { // TODO Auto-generated method stub } diff --git a/sca-java-2.x/trunk/modules/binding-jsonrpc-runtime/src/main/java/org/apache/tuscany/sca/binding/jsonrpc/provider/JSONRPCServiceServlet.java b/sca-java-2.x/trunk/modules/binding-jsonrpc-runtime/src/main/java/org/apache/tuscany/sca/binding/jsonrpc/provider/JSONRPCServiceServlet.java index 0a68fcca86..47f74720a0 100644 --- a/sca-java-2.x/trunk/modules/binding-jsonrpc-runtime/src/main/java/org/apache/tuscany/sca/binding/jsonrpc/provider/JSONRPCServiceServlet.java +++ b/sca-java-2.x/trunk/modules/binding-jsonrpc-runtime/src/main/java/org/apache/tuscany/sca/binding/jsonrpc/provider/JSONRPCServiceServlet.java @@ -327,7 +327,7 @@ public class JSONRPCServiceServlet extends JSONRPCServlet { result = responseMessage.getBody(); return result.toString().getBytes("UTF-8"); } else { - if (jsonOperation.getOutputType().getLogical().get(0) == null) { + if (jsonOperation.getOutputType().getLogical().size() == 0) { // void operation (json-rpc notification) try { JSONObject jsonResponse = new JSONObject(); diff --git a/sca-java-2.x/trunk/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/Interface2WSDLGenerator.java b/sca-java-2.x/trunk/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/Interface2WSDLGenerator.java index be1222f094..542b9d556e 100644 --- a/sca-java-2.x/trunk/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/Interface2WSDLGenerator.java +++ b/sca-java-2.x/trunk/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/Interface2WSDLGenerator.java @@ -56,6 +56,7 @@ import org.apache.tuscany.sca.databinding.jaxb.JAXBDataBinding; 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.impl.DataTypeImpl; import org.apache.tuscany.sca.interfacedef.java.JavaInterface; import org.apache.tuscany.sca.interfacedef.java.JavaOperation; @@ -240,7 +241,9 @@ public class Interface2WSDLGenerator { if (useOutputWrapper) { addDataType(dataTypes, dt2, helpers); } else { - dt2 = op.getOutputType().getLogical().get(0); + if (op.getOutputType().getLogical().size() != 0) { + dt2 = op.getOutputType().getLogical().get(0); + } addDataType(dataTypes, dt2, helpers); } @@ -646,7 +649,7 @@ public class Interface2WSDLGenerator { outputMsg.addPart(generateWrapperPart(definition, op, helpers, wrappers, false)); } else { - if ((op.getOutputType() != null) && ( op.getOutputType().getLogical().get(0) != null)) { + if ((op.getOutputType() != null) && ( op.getOutputType().getLogical().size() != 0)) { DataType outputType = op.getOutputType().getLogical().get(0); outputMsg.addPart(generatePart(definition, outputType, "return")); elements = new ArrayList(); @@ -748,18 +751,41 @@ public class Interface2WSDLGenerator { */ Method method = ((JavaOperation)operation).getJavaMethod(); + + /* + * Making this change, though not understanding: + * + * 1. Whether we can assume JAXWSJavaInterfaceProcessor was already used to process + * + * 2. What the purpose is of calling getElementInfo() when we already have an ElementInfo + * + */ if (input) { Class[] paramTypes = method.getParameterTypes(); - for (int i = 0; i < paramTypes.length; i++) { - DataType dataType = operation.getInputType().getLogical().get(i); - elements.set(i, getElementInfo(paramTypes[i], dataType, elements.get(i).getQName(), helpers)); + for (int i = 0, inputsSeen = 0; i < paramTypes.length; i++) { + ParameterMode mode = operation.getParameterModes().get(i); + if (!mode.equals(ParameterMode.OUT)) { + DataType dataType = operation.getInputType().getLogical().get(i); + elements.set(inputsSeen, getElementInfo(paramTypes[i], dataType, elements.get(inputsSeen).getQName(), helpers)); + inputsSeen++; + } } } else { + int outputsSeen = 0; Class returnType = method.getReturnType(); if (returnType != Void.TYPE) { DataType dataType = operation.getOutputType().getLogical().get(0); - elements.set(0, getElementInfo(returnType, dataType, elements.get(0).getQName(), helpers)); + elements.set(outputsSeen++, getElementInfo(returnType, dataType, elements.get(0).getQName(), helpers)); } + Class[] paramTypes = method.getParameterTypes(); + for (int i = 0; i < paramTypes.length; i++) { + ParameterMode mode = operation.getParameterModes().get(i); + if (!mode.equals(ParameterMode.IN)) { + DataType dataType = operation.getOutputType().getLogical().get(i); + elements.set(outputsSeen, getElementInfo(paramTypes[i], dataType, elements.get(outputsSeen).getQName(), helpers)); + outputsSeen++; + } + } } } return part; diff --git a/sca-java-2.x/trunk/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/transformers/Exception2ExceptionTransformer.java b/sca-java-2.x/trunk/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/transformers/Exception2ExceptionTransformer.java index e78610cce0..f0e4a0fa10 100644 --- a/sca-java-2.x/trunk/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/transformers/Exception2ExceptionTransformer.java +++ b/sca-java-2.x/trunk/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/transformers/Exception2ExceptionTransformer.java @@ -21,13 +21,13 @@ package org.apache.tuscany.sca.core.databinding.transformers; import org.apache.tuscany.sca.core.ExtensionPointRegistry; import org.apache.tuscany.sca.core.UtilityExtensionPoint; -import org.apache.tuscany.sca.databinding.DataBinding; import org.apache.tuscany.sca.databinding.Mediator; import org.apache.tuscany.sca.databinding.PullTransformer; import org.apache.tuscany.sca.databinding.TransformationContext; import org.apache.tuscany.sca.databinding.BaseTransformer; import org.apache.tuscany.sca.interfacedef.DataType; import org.apache.tuscany.sca.interfacedef.FaultExceptionMapper; +import static org.apache.tuscany.sca.interfacedef.Operation.IDL_FAULT; /** * This is a special transformer to transform the exception from one IDL to the @@ -56,12 +56,12 @@ public class Exception2ExceptionTransformer extends BaseTransformer @Override public String getSourceDataBinding() { - return DataBinding.IDL_INPUT; + return IDL_INPUT; } @Override public String getTargetDataBinding() { - return DataBinding.IDL_INPUT; + return IDL_INPUT; } /** diff --git a/sca-java-2.x/trunk/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/transformers/Output2OutputTransformer.java b/sca-java-2.x/trunk/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/transformers/Output2OutputTransformer.java index d02a98bfbe..ad37eaccb8 100644 --- a/sca-java-2.x/trunk/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/transformers/Output2OutputTransformer.java +++ b/sca-java-2.x/trunk/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/transformers/Output2OutputTransformer.java @@ -32,6 +32,7 @@ import org.apache.tuscany.sca.databinding.TransformationException; import org.apache.tuscany.sca.databinding.WrapperHandler; import org.apache.tuscany.sca.interfacedef.DataType; import org.apache.tuscany.sca.interfacedef.Operation; +import static org.apache.tuscany.sca.interfacedef.Operation.IDL_OUTPUT; import org.apache.tuscany.sca.interfacedef.util.ElementInfo; import org.apache.tuscany.sca.interfacedef.util.WrapperInfo; import org.apache.tuscany.sca.interfacedef.util.XMLType; @@ -57,12 +58,12 @@ public class Output2OutputTransformer extends BaseTransformer im @Override public String getSourceDataBinding() { - return DataBinding.IDL_OUTPUT; + return IDL_OUTPUT; } @Override public String getTargetDataBinding() { - return DataBinding.IDL_OUTPUT; + return IDL_OUTPUT; } /** @@ -147,7 +148,8 @@ public class Output2OutputTransformer extends BaseTransformer im @SuppressWarnings("unchecked") public Object transform(Object response, TransformationContext context) { try { - DataType sourceType = context.getSourceDataType(); + + DataType> sourceType = context.getSourceDataType(); Operation sourceOp = context.getSourceOperation(); boolean sourceWrapped = sourceOp != null && sourceOp.isWrapperStyle() && sourceOp.getWrapper() != null; boolean sourceBare = sourceOp != null && !sourceOp.isWrapperStyle() && sourceOp.getWrapper() == null; @@ -156,14 +158,14 @@ public class Output2OutputTransformer extends BaseTransformer im String sourceDataBinding = getDataBinding(sourceOp); sourceWrapperHandler = getWrapperHandler(sourceDataBinding, sourceWrapped); - DataType targetType = context.getTargetDataType(); + DataType> targetType = context.getTargetDataType(); Operation targetOp = (Operation)context.getTargetOperation(); boolean targetWrapped = targetOp != null && targetOp.isWrapperStyle() && targetOp.getWrapper() != null; boolean targetBare = targetOp != null && !targetOp.isWrapperStyle() && targetOp.getWrapper() == null; WrapperHandler targetWrapperHandler = null; String targetDataBinding = getDataBinding(targetOp); - targetWrapperHandler = getWrapperHandler(targetDataBinding, targetWrapped); + targetWrapperHandler = getWrapperHandler(targetDataBinding, targetWrapped); if ((!sourceWrapped &&!sourceBare) && targetWrapped) { // Unwrapped --> Wrapped @@ -172,6 +174,13 @@ public class Output2OutputTransformer extends BaseTransformer im List childElements = wrapper.getOutputChildElements(); Class targetWrapperClass = wrapper != null ? wrapper.getOutputWrapperClass() : null; + Object[] outputs = null; + if ( !sourceOp.hasArrayWrappedOutput() ) { + outputs = new Object[] {response}; + } else { + outputs = (Object[])response; + } + // If the source can be wrapped, wrapped it first if (sourceWrapperHandler != null) { WrapperInfo sourceWrapperInfo = sourceOp.getWrapper(); @@ -186,13 +195,12 @@ public class Output2OutputTransformer extends BaseTransformer im if (!childElements.isEmpty()) { // Set the return value sourceWrapperHandler.setChildren(sourceWrapper, - new Object[] {response}, + outputs, sourceOp, false); } - DataType> targetLogicalType = targetType.getLogical(); Object targetWrapper = - mediator.mediate(sourceWrapper, sourceWrapperType, targetLogicalType.getLogical().get(0), context + mediator.mediate(sourceWrapper, sourceWrapperType, targetType.getLogical().get(0), context .getMetadata()); return targetWrapper; } @@ -205,26 +213,21 @@ public class Output2OutputTransformer extends BaseTransformer im return targetWrapper; } - DataType argType = wrapper.getUnwrappedOutputType(); - - if ( !sourceOp.hasHolders() ) { - Object child = response; - DataType> sourceLogicalType = sourceType.getLogical(); - child = mediator.mediate(response, sourceLogicalType.getLogical().get(0), argType, context.getMetadata()); - targetWrapperHandler.setChildren(targetWrapper, new Object[] {child}, targetOp, false); - return targetWrapper; - } else { - Object[] child = (Object[])response; - ArrayList children = new ArrayList(); - for ( int i=0; i < child.length; i++) { - DataType> sourceLogicalType = sourceType.getLogical(); - DataType childType = sourceLogicalType.getLogical().get(i); - if ( childType != null ) - children.add(mediator.mediate(child[i], childType, argType, context.getMetadata())); - } - targetWrapperHandler.setChildren(targetWrapper, children.toArray(), targetOp, false); - return targetWrapper; + // No source wrapper, so we want to transform the child and then wrap the child-level target with the + // target wrapper handler. + + Object[] targetChildren = new Object[outputs.length]; + for (int i = 0; i < outputs.length; i++) { + DataType targetOutputType = wrapper.getUnwrappedOutputType().getLogical().get(i); + targetChildren[i] = + mediator.mediate(outputs[i], sourceType.getLogical().get(i), targetOutputType, context.getMetadata()); } + targetWrapperHandler.setChildren(targetWrapper, + targetChildren, + targetOp, + false); + return targetWrapper; + } else if (sourceWrapped && (!targetWrapped && !targetBare)) { // Wrapped to Unwrapped Object sourceWrapper = response; @@ -245,48 +248,61 @@ public class Output2OutputTransformer extends BaseTransformer im targetWrapperInfo != null ? targetWrapperInfo.getOutputWrapperType() : null; if (targetWrapperType != null && matches(sourceOp.getWrapper(), targetOp.getWrapper())) { - DataType> sourceLogicalType = sourceType.getLogical(); Object targetWrapper = - mediator.mediate(sourceWrapper, sourceLogicalType.getLogical().get(0), targetWrapperType, context + mediator.mediate(sourceWrapper, sourceType.getLogical().get(0), targetWrapperType, context .getMetadata()); - return targetWrapperHandler.getChildren(targetWrapper, targetOp, false).get(0); + List targetChildren = targetWrapperHandler.getChildren(targetWrapper, targetOp, false); + if (targetOp.hasArrayWrappedOutput()) { + return targetChildren.toArray(); + } else { + return targetChildren.get(0); + } } } } - if ( !targetOp.hasHolders()) { - Object child = sourceWrapperHandler.getChildren(sourceWrapper, sourceOp, false).get(0); - DataType childType = sourceOp.getWrapper().getUnwrappedOutputType(); - DataType> foo = targetType.getLogical(); - return mediator.mediate(child, childType, foo.getLogical().get(0), context.getMetadata()); + + // Otherwise we need to unwrap on the source side, and then transform each child + Object[] sourceChildren = sourceWrapperHandler.getChildren(sourceWrapper, sourceOp, false).toArray(); + Object[] target = new Object[sourceChildren.length]; + for (int i = 0; i < sourceChildren.length; i++) { + DataType childType = sourceOp.getWrapper().getUnwrappedOutputType().getLogical().get(i); + target[i] = + mediator.mediate(sourceChildren[i], childType, targetType.getLogical().get(i), context + .getMetadata()); + } + + if (targetOp.hasArrayWrappedOutput()) { + return target; + } else { + if (target.length > 1 ) { + throw new IllegalStateException("Expecting only one output based on Operation model, found: " + + target.length + " # of outputs."); + } + return target[0]; + } + } else { + Object[] outputs = null; + if ( !sourceOp.hasArrayWrappedOutput() ) { + outputs = new Object[] {response}; } else { - Object[] child = sourceWrapperHandler.getChildren(sourceWrapper, sourceOp, false).toArray(); - DataType childType = sourceOp.getWrapper().getUnwrappedOutputType(); - DataType> targetLogicalType = targetType.getLogical(); - - Object[] target = child; - if ( targetLogicalType.getLogical().get(0) == null ) { - target = new Object[child.length +1]; - target[0] = null; - for ( int i=1; i <= child.length; i++ ) { -// if ( targetLogicalType.getLogical().get(i).getDataBinding() == null ) -// targetLogicalType.getLogical().get(i).setDataBinding(targetDataBinding); - target[i] = mediator.mediate(child[i-1], childType, targetLogicalType.getLogical().get(i), context.getMetadata()); - } - } else { - for ( int i=0; i < child.length; i++) { -// if ( targetLogicalType.getLogical().get(i).getDataBinding() == null ) -// targetLogicalType.getLogical().get(i).setDataBinding(targetDataBinding); - target[i] = mediator.mediate(child[i], childType, targetLogicalType.getLogical().get(i) , context.getMetadata()); - } - } - return target; + outputs = (Object[])response; + } + Object[] target = new Object[outputs.length]; + for (int i = 0; i < outputs.length; i++) { + Object child = + mediator.mediate(outputs[i], sourceType.getLogical().get(i), targetType.getLogical().get(i), context + .getMetadata()); + target[i] = child; + } + if (targetOp.hasArrayWrappedOutput()) { + return target; + } else { + if (target.length > 1 ) { + throw new IllegalStateException("Expecting only one output based on Operation model, found: " + + target.length + " # of outputs."); + } + return target[0]; } - } else { - // FIXME: Do we want to handle wrapped to wrapped? - DataType> sourceLogical = sourceType.getLogical(); - DataType> targetLogical = targetType.getLogical(); - return mediator.mediate(response, sourceLogical.getLogical().get(0), targetLogical.getLogical().get(0), context - .getMetadata()); } } catch (Exception e) { throw new TransformationException(e); 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 df378e55a0..5bb2354520 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 @@ -23,6 +23,7 @@ import java.io.Serializable; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; +import java.util.ArrayList; import java.util.IdentityHashMap; import java.util.List; import java.util.Map; @@ -34,6 +35,7 @@ import org.apache.tuscany.sca.context.ThreadMessageContext; import org.apache.tuscany.sca.core.context.ServiceReferenceExt; import org.apache.tuscany.sca.interfacedef.DataType; import org.apache.tuscany.sca.interfacedef.Operation; +import org.apache.tuscany.sca.interfacedef.ParameterMode; import org.apache.tuscany.sca.interfacedef.java.JavaOperation; import org.apache.tuscany.sca.invocation.InvocationChain; import org.apache.tuscany.sca.invocation.Invoker; @@ -109,15 +111,29 @@ public class JDKInvocationHandler implements InvocationHandler, Serializable { // Holder pattern. Items stored in a Holder are promoted to T. // After the invoke, the returned data are placed back in Holder. - Object [] promotedArgs = promoteHolderArgs( args ); - + Object [] promotedArgs = promoteHolderArgs( args ); + + // Strip out OUT-only arguments. Not too sure if the presence + // of a sourceOperation is exactly the right check to use to + // know whether or not to do this, but will assume it is until + // learning otherwise. + Operation sourceOp = chain.getSourceOperation(); + if (sourceOp != null) { + promotedArgs = removeOutOnlyArgs(sourceOp, promotedArgs ); + } + Object result = invoke(chain, promotedArgs, source); + // TODO - Based on the code in JavaInterfaceIntrospectorImpl, it seems there are + // some cases involving generics that we're not taking into account. + boolean voidReturnType = (void.class == method.getReturnType() ? true : false); + // Returned Holder data are placed back in Holder. boolean holderPattern = false; Class [] parameters = method.getParameterTypes(); if ( parameters != null ) { - for ( int i = 0, resultIdx = 0; i < parameters.length; i++ ) { + int resultIdx = (voidReturnType ? 0 : 1); + for ( int i = 0; i < parameters.length; i++ ) { Class parameterType = parameters[ i ]; if ( isHolder( parameterType ) ) { holderPattern = true; @@ -126,15 +142,20 @@ public class JDKInvocationHandler implements InvocationHandler, Serializable { Object[] results = (Object[])result; if ( result != null ) { - holder.value = results[++resultIdx]; + holder.value = results[resultIdx++]; } } } } - if ( holderPattern && result != null) - return ((Object[])result)[0]; - else - return result; + if (holderPattern && result != null) { + if (voidReturnType) { + return null; + } else { + return ((Object[])result)[0]; + } + } else { + return result; + } } /** @@ -360,6 +381,24 @@ public class JDKInvocationHandler implements InvocationHandler, Serializable { return promotedArgs; } + /** + * Given an argument array, filters out (removes) OUT-only parameters + * @param sourceOp + * @return array of filtered arguments + */ + Object[] removeOutOnlyArgs(Operation sourceOp, Object[] args) { + if ( args == null ) + return args; + ArrayList retValList = new ArrayList(); + List parmList = sourceOp.getParameterModes(); + for (int i = 0; i < args.length; i++) { + if (parmList.get(i) != ParameterMode.OUT) { + retValList.add(args[i]); + } + } + return retValList.toArray(); + } + /** * Given a Class, tells if it is a Holder by comparing to "javax.xml.ws.Holder" * @param testClass diff --git a/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/DataBinding.java b/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/DataBinding.java index fd5cf4ac1d..46806c77f1 100644 --- a/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/DataBinding.java +++ b/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/DataBinding.java @@ -30,18 +30,7 @@ import org.apache.tuscany.sca.interfacedef.Operation; * @tuscany.spi.extension.asclient */ public interface DataBinding { - /** - * A special databinding for input message of an operation - */ - String IDL_INPUT = "idl:input"; - /** - * A special databinding for output message of an operation - */ - String IDL_OUTPUT = "idl:output"; - /** - * A special databinding for fault message of an operation - */ - String IDL_FAULT = "idl:fault"; + /** * The name of a databinding should be case-insensitive and unique * diff --git a/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/impl/MediatorImpl.java b/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/impl/MediatorImpl.java index d6d56e2711..6759edc992 100644 --- a/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/impl/MediatorImpl.java +++ b/sca-java-2.x/trunk/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/impl/MediatorImpl.java @@ -18,8 +18,8 @@ */ package org.apache.tuscany.sca.databinding.impl; -import static org.apache.tuscany.sca.databinding.DataBinding.IDL_FAULT; -import static org.apache.tuscany.sca.databinding.DataBinding.IDL_OUTPUT; +import static org.apache.tuscany.sca.interfacedef.Operation.IDL_FAULT; +import static org.apache.tuscany.sca.interfacedef.Operation.IDL_OUTPUT; import java.io.Serializable; import java.lang.reflect.Array; @@ -51,6 +51,7 @@ import org.apache.tuscany.sca.interfacedef.DataType; import org.apache.tuscany.sca.interfacedef.FaultExceptionMapper; import org.apache.tuscany.sca.interfacedef.InterfaceContractMapper; 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.util.FaultException; import org.apache.tuscany.sca.interfacedef.util.XMLType; @@ -390,8 +391,8 @@ public class MediatorImpl implements Mediator { Operation targetOperation, Map metadata) { - DataType sourceType = new DataTypeImpl(IDL_OUTPUT, Object.class, sourceOperation.getOutputType()); - DataType targetType = new DataTypeImpl(IDL_OUTPUT, Object.class, targetOperation.getOutputType()); + DataType sourceType = sourceOperation.getOutputType(); + DataType targetType = targetOperation.getOutputType(); if (sourceType == targetType || (sourceType != null && sourceType.equals(targetType))) { return output; @@ -558,24 +559,30 @@ public class MediatorImpl implements Mediator { List inputTypesTarget = targetOperation == null ? null : targetOperation.getInputType().getLogical(); Object[] copy = new Object[data.length]; Map map = new IdentityHashMap(); - for (int i = 0, size = inputTypes.size(); i < size; i++) { - Object arg = data[i]; - if (arg == null) { - copy[i] = null; - } else { - Object copiedArg = map.get(arg); - if (copiedArg != null) { - copy[i] = copiedArg; + for (int i = 0, nextIndex = 0; i < inputTypes.size(); i++) { + // Account for OUT-only parameters. Would be more thorough to look at targetOperation + // and ensure it has the same parameter mode, but we'll let that go for now. + ParameterMode mode = sourceOperation.getParameterModes().get(i); + if (!mode.equals(ParameterMode.OUT)) { + Object arg = data[nextIndex]; + if (arg == null) { + copy[nextIndex] = null; } else { - copiedArg = - copy(arg, - inputTypes.get(i), - inputTypesTarget == null ? null : inputTypesTarget.get(i), - sourceOperation, - targetOperation); - map.put(arg, copiedArg); - copy[i] = copiedArg; + Object copiedArg = map.get(arg); + if (copiedArg != null) { + copy[nextIndex] = copiedArg; + } else { + copiedArg = + copy(arg, + inputTypes.get(i), + inputTypesTarget == null ? null : inputTypesTarget.get(i), + sourceOperation, + targetOperation); + map.put(arg, copiedArg); + copy[nextIndex] = copiedArg; + } } + nextIndex++; } } return copy; @@ -590,7 +597,7 @@ public class MediatorImpl implements Mediator { return null; Object[] output = null; - if ( !sourceOperation.hasHolders() ) { + if ( !sourceOperation.hasArrayWrappedOutput() ) { output = new Object[] {data}; } else { output = (Object[])data; @@ -620,7 +627,7 @@ public class MediatorImpl implements Mediator { } } } - if ( !targetOperation.hasHolders()) { + if ( !targetOperation.hasArrayWrappedOutput()) { return copy[0]; } else { return copy; 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 69da9019a8..ef325e4ae9 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 @@ -133,22 +133,28 @@ public class JavaImplementationInvoker implements Invoker { // Only check Holder for remotable interfaces if (imethod != null && op.getInterface().isRemotable()) { List 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 [] to [Holder] - 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(); - } - + Object[] payloadArray = (Object[])payload; + List payloadList = new ArrayList(); + for (int i = 0, nextIndex = 0; i < inputTypes.size(); i++) { + ParameterMode mode = op.getParameterModes().get(i); + if (ParameterMode.IN == mode ) { + payloadList.add(payloadArray[nextIndex++]); + } else if (ParameterMode.INOUT == mode ) { + // Promote array params from [] to [Holder] + Object item = payloadArray[nextIndex++]; + Holder itemHolder = new Holder(item); + payloadList.add(itemHolder); argumentHolderCount++; - } + } else { + // Create an empty Holder since we should not pass values for OUT parameters + payloadList.add(new Holder()); + argumentHolderCount++; + } } + + // Maybe a bit odd to do but this way I don't have to worry about how the invoke if/else + // immediately following might need to be changed. + payload = payloadList.toArray(); } Object ret; @@ -164,18 +170,47 @@ public class JavaImplementationInvoker implements Invoker { if (argumentHolderCount > 0) { // Holder pattern. Any payload Holder types are returned as part of the message body. - Object[] payloadArray = (Object[])payload; + Object[] payloadArray = (Object[])payload; + + ArrayList holderOutputs = new ArrayList(); ArrayList result = new ArrayList(); - if (imethod != null) { - - result.add(ret); + if (imethod != null) { + for (int i = 0, size = op.getParameterModes().size(); i < size; i++) { if (ParameterMode.IN != op.getParameterModes().get(i)) { // Demote array params from Holder to . Holder item = (Holder)payloadArray[i]; payloadArray[i] = item.value; - result.add(payloadArray[i]); + holderOutputs.add(payloadArray[i]); + } + } + + // + // Now we account for the fact that we may have a null because of a void return type, + // which is not part of the output DataType, and so should not be returned with the array + // of outputs, or we may have a null as value returned + // from a method with signature with return type other than void, which should be returned + // in the output array. + // + // The logic here is if we already have as many outputs in holders as we have outputs + // altogether, then we don't worry about the return value (which should be null). Might + // be simpler to just check for void, but the code in the Java introspector has a lot + // of quirks for handling parameterized types, and this seems simpler for now. + // + int holderOutputSize = holderOutputs.size(); + int numberOperationOutputs = op.getOutputType().getLogical().size(); + if (holderOutputSize == numberOperationOutputs) { + if (ret != null) { + throw new IllegalStateException("Number of holder outputs equal to number of operations outputs." + + "\nNum = " + holderOutputSize + ", but non-null return value seen: " + ret); } + result = holderOutputs; + } else if (holderOutputSize == numberOperationOutputs - 1) { + result.add(ret); + result.addAll(1, holderOutputs); + } else { + throw new IllegalStateException("Number of holder outputs seen: " + holderOutputSize + + "\nNumber of operation outputs: " + numberOperationOutputs); } } diff --git a/sca-java-2.x/trunk/modules/interface-java-jaxws/src/main/java/org/apache/tuscany/sca/interfacedef/java/jaxws/JAXWSAsyncInterfaceProcessor.java b/sca-java-2.x/trunk/modules/interface-java-jaxws/src/main/java/org/apache/tuscany/sca/interfacedef/java/jaxws/JAXWSAsyncInterfaceProcessor.java index a57a0b4678..315054fc82 100644 --- a/sca-java-2.x/trunk/modules/interface-java-jaxws/src/main/java/org/apache/tuscany/sca/interfacedef/java/jaxws/JAXWSAsyncInterfaceProcessor.java +++ b/sca-java-2.x/trunk/modules/interface-java-jaxws/src/main/java/org/apache/tuscany/sca/interfacedef/java/jaxws/JAXWSAsyncInterfaceProcessor.java @@ -82,7 +82,7 @@ public class JAXWSAsyncInterfaceProcessor implements JavaInterfaceVisitor { */ private static boolean isJAXWSAsyncPoolingOperation(Operation operation, Operation asyncOperation) { - if (asyncOperation.getOutputType().getLogical().get(0) == null || Response.class != asyncOperation.getOutputType().getLogical().get(0).getPhysical()) { + if (asyncOperation.getOutputType().getLogical().size() == 0 || Response.class != asyncOperation.getOutputType().getLogical().get(0).getPhysical()) { // The return type is not Response return false; } @@ -149,7 +149,7 @@ public class JAXWSAsyncInterfaceProcessor implements JavaInterfaceVisitor { */ private static boolean isJAXWSAsyncCallbackOperation(Operation operation, Operation asyncOperation) { - if (asyncOperation.getOutputType().getLogical().get(0) == null || Future.class != asyncOperation.getOutputType().getLogical().get(0).getPhysical()) { + if (asyncOperation.getOutputType().getLogical().size() == 0 || Future.class != asyncOperation.getOutputType().getLogical().get(0).getPhysical()) { // The return type is not Future return false; } 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 74b2b53543..da70b3ffba 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 @@ -276,27 +276,11 @@ public class JAXWSJavaInterfaceProcessor implements JavaInterfaceVisitor { }); QName outputWrapper = outputWrapperDT.getLogical().getElementName(); - List inputElements = new ArrayList(); - for (int i = 0; i < method.getParameterTypes().length; i++) { - WebParam param = getAnnotation(method, i, WebParam.class); - ns = param != null ? param.targetNamespace() : ""; - // Default to "" for doc-lit-wrapped && non-header - ns = getValue(ns, documentStyle && (param == null || !param.header()) ? "" : tns); - name = param != null ? param.name() : ""; - name = getValue(name, "arg" + i); - QName element = new QName(ns, name); - Object logical = operation.getInputType().getLogical().get(i).getLogical(); - QName type = null; - if (logical instanceof XMLType) { - ((XMLType)logical).setElementName(element); - type = ((XMLType)logical).getTypeName(); - } - inputElements.add(new ElementInfo(element, new TypeInfo(type, false, null))); - if (param != null) { - operation.getParameterModes().set(i, getParameterMode(param.mode())); - } - } - + + // + // Since JAX-WS specifies that the output wrapper bean consists of the return type output first followed + // by any other outputs carried in Holder(s), let's look at the output first. + // List outputElements = new ArrayList(); WebResult result = method.getAnnotation(WebResult.class); // Default to "" for doc-lit-wrapped && non-header @@ -306,7 +290,8 @@ public class JAXWSJavaInterfaceProcessor implements JavaInterfaceVisitor { name = getValue(name, "return"); QName element = new QName(ns, name); - if ((operation.getOutputType() != null) && ( operation.getOutputType().getLogical().get(0) != null)) { + // This must be a check for void? + if ((operation.getOutputType() != null) && (operation.getOutputType().getLogical().size() != 0)) { Object logical = operation.getOutputType().getLogical().get(0).getLogical(); QName type = null; if (logical instanceof XMLType) { @@ -315,7 +300,39 @@ public class JAXWSJavaInterfaceProcessor implements JavaInterfaceVisitor { } outputElements.add(new ElementInfo(element, new TypeInfo(type, false, null))); } - + + List inputElements = new ArrayList(); + for (int i = 0; i < method.getParameterTypes().length; i++) { + WebParam param = getAnnotation(method, i, WebParam.class); + ns = param != null ? param.targetNamespace() : ""; + // Default to "" for doc-lit-wrapped && non-header + ns = getValue(ns, documentStyle && (param == null || !param.header()) ? "" : tns); + name = param != null ? param.name() : ""; + name = getValue(name, "arg" + i); + element = new QName(ns, name); + Object logical = operation.getInputType().getLogical().get(i).getLogical(); + QName type = null; + if (logical instanceof XMLType) { + ((XMLType)logical).setElementName(element); + type = ((XMLType)logical).getTypeName(); + } + + if (param != null) { + ParameterMode mode = getParameterMode(param.mode()); + operation.getParameterModes().set(i, mode); + } + ParameterMode mode = operation.getParameterModes().get(i); + + if (mode.equals(ParameterMode.INOUT)) { + inputElements.add(new ElementInfo(element, new TypeInfo(type, false, null))); + outputElements.add(new ElementInfo(element, new TypeInfo(type, false, null))); + } else if (mode.equals(ParameterMode.OUT)) { + outputElements.add(new ElementInfo(element, new TypeInfo(type, false, null))); + } else { + inputElements.add(new ElementInfo(element, new TypeInfo(type, false, null))); + } + } + String db = inputWrapperDT != null ? inputWrapperDT.getDataBinding() : JAXB_DATABINDING; WrapperInfo wrapperInfo = new WrapperInfo(db, new ElementInfo(inputWrapper, null), new ElementInfo(outputWrapper, null), 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 ac12cf6bef..6979e1d6cd 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 @@ -44,6 +44,8 @@ import org.apache.tuscany.sca.interfacedef.InvalidCallbackException; import org.apache.tuscany.sca.interfacedef.InvalidInterfaceException; import org.apache.tuscany.sca.interfacedef.InvalidOperationException; import org.apache.tuscany.sca.interfacedef.Operation; +import static org.apache.tuscany.sca.interfacedef.Operation.IDL_INPUT; +import static org.apache.tuscany.sca.interfacedef.Operation.IDL_OUTPUT; import org.apache.tuscany.sca.interfacedef.OverloadedOperationException; import org.apache.tuscany.sca.interfacedef.ParameterMode; import org.apache.tuscany.sca.interfacedef.impl.DataTypeImpl; @@ -63,8 +65,6 @@ import org.oasisopen.sca.annotation.Remotable; * @version $Rev$ $Date$ */ public class JavaInterfaceIntrospectorImpl { - public static final String IDL_INPUT = "idl:input"; - public static final String IDL_OUTPUT = "idl:output"; private static final String UNKNOWN_DATABINDING = null; @@ -216,7 +216,7 @@ public class JavaInterfaceIntrospectorImpl { List operations = new ArrayList(methods.length); Set names = remotable ? new HashSet() : null; for (Method method : methods) { - boolean hasHolders = false; + boolean hasMultipleOutputs = false; if (method.getDeclaringClass() == Object.class) { // Skip the methods on the Object.class continue; @@ -279,7 +279,7 @@ public class JavaInterfaceIntrospectorImpl { ParameterMode mode = ParameterMode.IN; // Holder pattern. Physical types of Holder classes are updated to to aid in transformations. if ( Holder.class == paramType) { - hasHolders = true; + hasMultipleOutputs = true; genericHolderTypes.add(genericParamTypes[i]); Type firstActual = getFirstActualType( genericParamTypes[ i ] ); if ( firstActual != null ) { @@ -293,26 +293,22 @@ public class JavaInterfaceIntrospectorImpl { paramDataTypes.add( xmlDataType); operation.getParameterModes().add(mode); } - - - // Get Output Types - List outputDataTypes = new ArrayList(allOutputTypes.length); - Type genericReturnType = method.getGenericReturnType(); - - for ( int i=0; i <= genericHolderTypes.size(); i++ ) { - Class paramType = allOutputTypes[i]; - XMLType xmlOutputType = new XMLType(new QName(ns, "out" + i), null); - - if ( i == 0 ) { - outputDataTypes.add(returnDataType); - } else { - DataTypeImpl xmlDataType = xmlDataType = new DataTypeImpl( - UNKNOWN_DATABINDING, physicalHolderTypes.get(i-1), genericHolderTypes.get(i-1), xmlOutputType); - outputDataTypes.add(xmlDataType); - } - - } - + + // Get Output Types, but skip over void return type + List outputDataTypes = new ArrayList(); + if (returnDataType != null) { + outputDataTypes.add(returnDataType); + } + + // Start at 1, for the first holder, since we already accounted for the return type itself + for ( int i=1; i < allOutputTypes.length; i++ ) { + Class paramType = allOutputTypes[i]; + XMLType xmlOutputType = new XMLType(new QName(ns, "out" + i), null); + DataTypeImpl xmlDataType = xmlDataType = new DataTypeImpl( + UNKNOWN_DATABINDING, physicalHolderTypes.get(i-1), genericHolderTypes.get(i-1), xmlOutputType); + outputDataTypes.add(xmlDataType); + } + // Fault types List faultDataTypes = new ArrayList(faultTypes.length); Type[] genericFaultTypes = method.getGenericExceptionTypes(); @@ -344,7 +340,7 @@ public class JavaInterfaceIntrospectorImpl { operation.setFaultTypes(faultDataTypes); operation.setNonBlocking(nonBlocking); operation.setJavaMethod(method); - operation.setHasHolders(hasHolders); + operation.setHasArrayWrappedOutput(hasMultipleOutputs); operations.add(operation); } return operations; @@ -352,15 +348,15 @@ public class JavaInterfaceIntrospectorImpl { private Class[] getOutputTypes(Class returnType, Class[] parameterTypes) { - Class[] returnTypes = new Class[parameterTypes.length + 1]; - returnTypes[0] = returnType; - int idx = 1; + + ArrayList> returnTypes = new ArrayList>(); + returnTypes.add(returnType); for ( Class clazz : parameterTypes ) { if ( Holder.class == clazz ) - returnTypes[idx++] = clazz; + returnTypes.add(clazz); } - - return returnTypes; + Class[] arrayType = new Class[0]; + return returnTypes.toArray(arrayType); } diff --git a/sca-java-2.x/trunk/modules/interface-wsdl/src/main/java/org/apache/tuscany/sca/interfacedef/wsdl/impl/WSDLOperationIntrospectorImpl.java b/sca-java-2.x/trunk/modules/interface-wsdl/src/main/java/org/apache/tuscany/sca/interfacedef/wsdl/impl/WSDLOperationIntrospectorImpl.java index 67191cd43d..48aab67ded 100644 --- a/sca-java-2.x/trunk/modules/interface-wsdl/src/main/java/org/apache/tuscany/sca/interfacedef/wsdl/impl/WSDLOperationIntrospectorImpl.java +++ b/sca-java-2.x/trunk/modules/interface-wsdl/src/main/java/org/apache/tuscany/sca/interfacedef/wsdl/impl/WSDLOperationIntrospectorImpl.java @@ -38,6 +38,8 @@ import org.apache.tuscany.sca.contribution.processor.ProcessorContext; import org.apache.tuscany.sca.contribution.resolver.ModelResolver; import org.apache.tuscany.sca.interfacedef.DataType; import org.apache.tuscany.sca.interfacedef.Operation; +import static org.apache.tuscany.sca.interfacedef.Operation.IDL_INPUT; +import static org.apache.tuscany.sca.interfacedef.Operation.IDL_OUTPUT; import org.apache.tuscany.sca.interfacedef.impl.DataTypeImpl; import org.apache.tuscany.sca.interfacedef.util.ElementInfo; import org.apache.tuscany.sca.interfacedef.util.FaultException; @@ -132,52 +134,29 @@ public class WSDLOperationIntrospectorImpl { /** * @return - * @throws InvalidServiceContractException + * @throws InvalidWSDLException */ public DataType> getInputType() throws InvalidWSDLException { if (inputType == null) { Input input = operation.getInput(); Message message = (input == null) ? null : input.getMessage(); inputType = getMessageType(message); - inputType.setDataBinding("idl:input"); + inputType.setDataBinding(IDL_INPUT); } return inputType; } /** * @return - * @throws NotSupportedWSDLException + * @throws InvalidWSDLException */ @SuppressWarnings("unchecked") public DataType> getOutputType() throws InvalidWSDLException { if (outputType == null) { Output output = operation.getOutput(); Message outputMsg = (output == null) ? null : output.getMessage(); - - operation.getInput(); - List outputParts = (outputMsg == null) ? null : outputMsg.getOrderedParts(null); - ArrayList partTypes = new ArrayList(); - if (outputParts != null && outputParts.size() > 0) { -// if (outputParts.size() > 1) { -// // We don't support output with multiple parts -// if (logger.isLoggable(Level.WARNING)) { -// logger.warning("Multi-part output is not supported, please use BARE parameter style."); -// } -// // throw new InvalidWSDLException("Multi-part output is not supported"); -// } - for ( Part part : outputParts ) { - DataType partType = new WSDLPart(part, Object.class).getDataType(); - partTypes.add(partType); - } - - // outputType.setMetadata(WSDLOperation.class.getName(), this); - } else { - partTypes.add(null); - } - - - outputType = - new DataTypeImpl>(dataBinding, Object[].class, partTypes); + outputType = getMessageType(outputMsg); + outputType.setDataBinding(IDL_OUTPUT); } return outputType; } diff --git a/sca-java-2.x/trunk/modules/interface-wsdl/src/test/java/org/apache/tuscany/sca/interfacedef/wsdl/introspect/WSDLOperationIntrospectorTestCase.java b/sca-java-2.x/trunk/modules/interface-wsdl/src/test/java/org/apache/tuscany/sca/interfacedef/wsdl/introspect/WSDLOperationIntrospectorTestCase.java index f16ab9c73a..cb0b347ae4 100644 --- a/sca-java-2.x/trunk/modules/interface-wsdl/src/test/java/org/apache/tuscany/sca/interfacedef/wsdl/introspect/WSDLOperationIntrospectorTestCase.java +++ b/sca-java-2.x/trunk/modules/interface-wsdl/src/test/java/org/apache/tuscany/sca/interfacedef/wsdl/introspect/WSDLOperationIntrospectorTestCase.java @@ -79,7 +79,10 @@ public class WSDLOperationIntrospectorTestCase extends AbstractWSDLTestCase { DataType childType = childTypes.get(0); Assert.assertEquals(new QName(null, "tickerSymbol"), childType.getLogical().getElementName()); - childType = op.getWrapper().getUnwrappedOutputType(); + DataType> unwrappedOutputType = op.getWrapper().getUnwrappedOutputType(); + childTypes = unwrappedOutputType.getLogical(); + Assert.assertEquals(1, childTypes.size()); + childType = childTypes.get(0); Assert.assertEquals(new QName(null, "price"), childType.getLogical().getElementName()); } -- cgit v1.2.3