From b45ddbd9b965d35bca5c6974c7ab2cceda794fb2 Mon Sep 17 00:00:00 2001 From: nash Date: Fri, 3 Dec 2010 17:07:02 +0000 Subject: TUSCANY-3298: Enable JAXB wrappers for WSDL generation git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@1041912 13f79535-47bb-0310-9956-ffa450edef68 --- .../ws/axis2/itests/mtom/FileTransferService.java | 5 +- .../ws/wsdlgen/Interface2WSDLGenerator.java | 8 ++- .../transformers/Input2InputTransformer.java | 18 ++++++- .../transformers/Output2OutputTransformer.java | 18 ++++++- .../sca/databinding/jaxb/JAXBContextHelper.java | 62 ++++++++++++++++++---- .../sca/databinding/sdo/SDODataBinding.java | 30 +++++++++-- .../tuscany/sca/databinding/sdo/SDOTypeHelper.java | 8 +-- 7 files changed, 129 insertions(+), 20 deletions(-) (limited to 'sca-java-1.x/trunk') diff --git a/sca-java-1.x/trunk/modules/binding-ws-axis2/src/test/java/org/apache/tuscany/sca/binding/ws/axis2/itests/mtom/FileTransferService.java b/sca-java-1.x/trunk/modules/binding-ws-axis2/src/test/java/org/apache/tuscany/sca/binding/ws/axis2/itests/mtom/FileTransferService.java index ab7fc9c43a..d617047f5a 100644 --- a/sca-java-1.x/trunk/modules/binding-ws-axis2/src/test/java/org/apache/tuscany/sca/binding/ws/axis2/itests/mtom/FileTransferService.java +++ b/sca-java-1.x/trunk/modules/binding-ws-axis2/src/test/java/org/apache/tuscany/sca/binding/ws/axis2/itests/mtom/FileTransferService.java @@ -38,9 +38,12 @@ public interface FileTransferService { public String uploadDataHandlerFile(DataHandler attachment) throws Exception; public String uploadOMElementFile(OMElement attachment) throws Exception; - + + // TUSCANY-3805: produces WSDL generation error with fix for TUSCANY-3298 + /* //This method uses an user defined interface MyException as parameter type. public String sendMyException(@XmlJavaTypeAdapter(MyExceptionAdapter.class) MyException attachment) throws Exception; + */ } diff --git a/sca-java-1.x/trunk/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/Interface2WSDLGenerator.java b/sca-java-1.x/trunk/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/Interface2WSDLGenerator.java index a55670ef86..542517182c 100644 --- a/sca-java-1.x/trunk/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/Interface2WSDLGenerator.java +++ b/sca-java-1.x/trunk/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/Interface2WSDLGenerator.java @@ -344,7 +344,8 @@ public class Interface2WSDLGenerator { // call each helper in turn to populate the wsdl.types element XmlSchemaCollection schemaCollection = new XmlSchemaCollection(); - for (Map.Entry> en: getDataTypes(interfaze, false, helpers).entrySet()) { + // TUSCANY-3298: enable JAXB wrapper generation + for (Map.Entry> en: getDataTypes(interfaze, true, helpers).entrySet()) { XMLTypeHelper helper = en.getKey(); if (helper == null) { continue; @@ -1112,6 +1113,11 @@ public class Interface2WSDLGenerator { dataType.getLogical()); ElementInfo element = new ElementInfo(name, typeInfo); element.setMany(byte[].class != javaType && javaType.isArray()); + // TUSCANY-3298: Check the "many" flag set by databinding introspection + Object logical = dataType.getLogical(); + if (logical instanceof XMLType && ((XMLType)logical).isMany()) { + element.setMany(true); + } element.setNillable(!javaType.isPrimitive()); return element; } diff --git a/sca-java-1.x/trunk/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/transformers/Input2InputTransformer.java b/sca-java-1.x/trunk/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/transformers/Input2InputTransformer.java index f537dc4524..0d12d2b4fd 100644 --- a/sca-java-1.x/trunk/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/transformers/Input2InputTransformer.java +++ b/sca-java-1.x/trunk/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/transformers/Input2InputTransformer.java @@ -121,13 +121,29 @@ public class Input2InputTransformer extends BaseTransformer for (int i = 0; i < list1.size(); i++) { String n1 = list1.get(i).getQName().getLocalPart(); String n2 = list2.get(i).getQName().getLocalPart(); - if (!n1.equals(n2)) { + + // TUSCANY-3298: In the following situation: + // 1. The child is a java.util.Map type + // 2. The child's name is a Java keyword (e.g., return) + // 3. Tuscany is using a generated JAXB wrapper class for WSDL generation + // the Java to WSDL generation process results in the WSDL element name + // having a leading underscore added to the actual element name. This is + // because of a known JAXB issue that prevents the @XmlElement annotation + // being used on a java.util.Map type property field in the wrapper bean + // (see https://jaxb.dev.java.net/issues/show_bug.cgi?id=268). + // To prevent the compatibility match from failing in this situation, + // we strip any leading underscore before doing the comparison. + if (!stripLeadingUnderscore(n1).equals(stripLeadingUnderscore(n2))) { return false; } } return true; } + private static String stripLeadingUnderscore(String name) { + return name.startsWith("_") ? name.substring(1) : name; + } + @SuppressWarnings("unchecked") public Object[] transform(Object[] source, TransformationContext context) { // Check if the source operation is wrapped diff --git a/sca-java-1.x/trunk/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/transformers/Output2OutputTransformer.java b/sca-java-1.x/trunk/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/transformers/Output2OutputTransformer.java index 348d8345b2..41285a910d 100644 --- a/sca-java-1.x/trunk/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/transformers/Output2OutputTransformer.java +++ b/sca-java-1.x/trunk/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/transformers/Output2OutputTransformer.java @@ -142,13 +142,29 @@ public class Output2OutputTransformer extends BaseTransformer im for (int i = 0; i < list1.size(); i++) { String n1 = list1.get(i).getQName().getLocalPart(); String n2 = list2.get(i).getQName().getLocalPart(); - if (!n1.equals(n2)) { + + // TUSCANY-3298: In the following situation: + // 1. The child is a java.util.Map type + // 2. The child's name is a Java keyword (e.g., return) + // 3. Tuscany is using a generated JAXB wrapper class for WSDL generation + // the Java to WSDL generation process results in the WSDL element name + // having a leading underscore added to the actual element name. This is + // because of a known JAXB issue that prevents the @XmlElement annotation + // being used on a java.util.Map type property field in the wrapper bean + // (see https://jaxb.dev.java.net/issues/show_bug.cgi?id=268). + // To prevent the compatibility match from failing in this situation, + // we strip any leading underscore before doing the comparison. + if (!stripLeadingUnderscore(n1).equals(stripLeadingUnderscore(n2))) { return false; } } return true; } + private static String stripLeadingUnderscore(String name) { + return name.startsWith("_") ? name.substring(1) : name; + } + @SuppressWarnings("unchecked") public Object transform(Object response, TransformationContext context) { try { diff --git a/sca-java-1.x/trunk/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBContextHelper.java b/sca-java-1.x/trunk/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBContextHelper.java index d129ae6256..7e42c660e7 100644 --- a/sca-java-1.x/trunk/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBContextHelper.java +++ b/sca-java-1.x/trunk/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBContextHelper.java @@ -24,8 +24,10 @@ import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; import java.lang.reflect.WildcardType; import java.util.ArrayList; +import java.util.Collection; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; import javax.xml.bind.JAXBContext; @@ -343,29 +345,54 @@ public class JAXBContextHelper { WrapperInfo inputWrapperInfo = op.getInputWrapper(); WrapperInfo outputWrapperInfo = op.getOutputWrapper(); + // TUSCANY-3298: Add the wrapper type instead of individual elements + // if possible. JAXB will implicitly add all types that are statically + // reachable from the wrapper class, with the exception of type arguments + // for parameterized types that aren't collections. + DataType dt1 = null; if (useWrapper && (inputWrapperInfo != null)) { - DataType dt1 = inputWrapperInfo.getWrapperType(); + dt1 = inputWrapperInfo.getWrapperType(); if (dt1 != null) { dataTypes.add(dt1); + for (DataType in : op.getInputType().getLogical()) { + if (isParameterizedNonCollectionType(in)) { + // JAXB won't add the type arguments, so we need to add them + dataTypes.add(in); + } + } + } + } + if (dt1 == null) { + // We couldn't add the wrapper, so add the elements individually + for (DataType dt : op.getInputType().getLogical()) { + dataTypes.add(dt); } } + + // TUSCANY-3298: Add the wrapper type instead of the output type + // if possible. JAXB will implicitly add all types that are statically + // reachable from the wrapper class, with the exception of type arguments + // for parameterized types that aren't collections or maps. + DataType dt2 = null; if (useWrapper && (outputWrapperInfo != null)) { - DataType dt2 = outputWrapperInfo.getWrapperType(); + dt2 = outputWrapperInfo.getWrapperType(); if (dt2 != null) { dataTypes.add(dt2); + DataType out = op.getOutputType(); + if (out != null && isParameterizedNonCollectionType(out)) { + // JAXB won't add the type arguments, so we need to add them + dataTypes.add(out); + } } } - // FIXME: [rfeng] We may need to find the referenced classes in the child types - // else - { - for (DataType dt1 : op.getInputType().getLogical()) { - dataTypes.add(dt1); - } - DataType dt2 = op.getOutputType(); + if (dt2 == null) { + // We couldn't add the wrapper, so add the output type directly + dt2 = op.getOutputType(); if (dt2 != null) { dataTypes.add(dt2); } } + for (DataType dt3 : op.getFaultTypes()) { DataType dt4 = dt3.getLogical(); if (dt4 != null) { @@ -374,6 +401,23 @@ public class JAXBContextHelper { } } + /* + * We need to add parameterized non-collection types to the JAXB context + * explicitly, because type argument information for these types is erased + * from the generated wrapper bean. + */ + private static boolean isParameterizedNonCollectionType(DataType dt) { + Type type = dt.getGenericType(); + if (type instanceof ParameterizedType) { + Class physical = dt.getPhysical(); + if (!Collection.class.isAssignableFrom(physical) && + !Map.class.isAssignableFrom(physical)) { + return true; + } + } + return false; + } + @SuppressWarnings("unchecked") public static Class getJavaType(DataType dataType) { if (dataType == null) { diff --git a/sca-java-1.x/trunk/modules/databinding-sdo/src/main/java/org/apache/tuscany/sca/databinding/sdo/SDODataBinding.java b/sca-java-1.x/trunk/modules/databinding-sdo/src/main/java/org/apache/tuscany/sca/databinding/sdo/SDODataBinding.java index 39e9ffc161..8e00a20c5f 100644 --- a/sca-java-1.x/trunk/modules/databinding-sdo/src/main/java/org/apache/tuscany/sca/databinding/sdo/SDODataBinding.java +++ b/sca-java-1.x/trunk/modules/databinding-sdo/src/main/java/org/apache/tuscany/sca/databinding/sdo/SDODataBinding.java @@ -19,8 +19,10 @@ package org.apache.tuscany.sca.databinding.sdo; +import java.lang.reflect.ParameterizedType; import java.security.AccessController; import java.security.PrivilegedAction; +import java.util.Collection; import javax.xml.namespace.QName; @@ -60,7 +62,7 @@ public class SDODataBinding extends BaseDataBinding { @Override public boolean introspect(DataType dataType, final Operation operation) { - final Class javaType = dataType.getPhysical(); + Class javaType = dataType.getPhysical(); // Allow privileged access to read system properties. Requires PropertyPermission // java.specification.version read in security policy. final HelperContext context = AccessController.doPrivileged(new PrivilegedAction() { @@ -72,11 +74,33 @@ public class SDODataBinding extends BaseDataBinding { final Type type = context.getTypeHelper().getType(javaType); if (type == null) { // FIXME: Need a better to test dynamic SDO + // TUSCANY-3298: get underlying element type for collections + boolean isMany = false; + if (Collection.class.isAssignableFrom(javaType)) { + java.lang.reflect.Type genericType = dataType.getGenericType(); + if (genericType instanceof ParameterizedType) { + java.lang.reflect.Type actualType = ((ParameterizedType)genericType).getActualTypeArguments()[0]; + if (actualType instanceof Class) { + javaType = (Class)actualType; + isMany = true; + } + } + } if (DataObject.class.isAssignableFrom(javaType)) { // Dynamic SDO dataType.setDataBinding(getName()); - if (dataType.getLogical() == null) { - dataType.setLogical(XMLType.UNKNOWN); + // TUSCANY-3298: use XMLType many value to indicate a collection + Object logical = dataType.getLogical(); + if (logical == null) { + if (!isMany) { + dataType.setLogical(XMLType.UNKNOWN); + } else { + XMLType xmlType = new XMLType(null, null); + xmlType.setMany(true); + dataType.setLogical(xmlType); + } + } else if (logical instanceof XMLType && isMany) { + ((XMLType)logical).setMany(true); } return true; } diff --git a/sca-java-1.x/trunk/modules/databinding-sdo/src/main/java/org/apache/tuscany/sca/databinding/sdo/SDOTypeHelper.java b/sca-java-1.x/trunk/modules/databinding-sdo/src/main/java/org/apache/tuscany/sca/databinding/sdo/SDOTypeHelper.java index e3ec6dc6b7..6f5443fe0c 100644 --- a/sca-java-1.x/trunk/modules/databinding-sdo/src/main/java/org/apache/tuscany/sca/databinding/sdo/SDOTypeHelper.java +++ b/sca-java-1.x/trunk/modules/databinding-sdo/src/main/java/org/apache/tuscany/sca/databinding/sdo/SDOTypeHelper.java @@ -70,16 +70,16 @@ public class SDOTypeHelper implements XMLTypeHelper { QName xmlType = JavaXMLMapper.getXMLType(javaType); if (xmlType != null) { return new TypeInfo(xmlType, true, null); - } else if (javaType == commonj.sdo.DataObject.class) { - return new TypeInfo(SimpleTypeMapperImpl.XSD_ANYTYPE, true, null); } else { // introspect(javaType, xsdTypesMap, typesMap); if (logical instanceof XMLType) { xmlType = ((XMLType)logical).getTypeName(); } if (xmlType == null) { - xmlType = - new QName(JavaXMLMapper.getNamespace(javaType), Introspector.decapitalize(javaType.getSimpleName())); + // TUSCANY-3298: dynamic SDO or collection of dynamic SDO + return new TypeInfo(SimpleTypeMapperImpl.XSD_ANYTYPE, true, null); + //xmlType = + // new QName(JavaXMLMapper.getNamespace(javaType), Introspector.decapitalize(javaType.getSimpleName())); } return new TypeInfo(xmlType, false, null); } -- cgit v1.2.3