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
This commit is contained in:
parent
eeabc3ec37
commit
b45ddbd9b9
7 changed files with 133 additions and 24 deletions
|
@ -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;
|
||||
*/
|
||||
}
|
||||
|
||||
|
|
|
@ -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<XMLTypeHelper, List<DataType>> en: getDataTypes(interfaze, false, helpers).entrySet()) {
|
||||
// TUSCANY-3298: enable JAXB wrapper generation
|
||||
for (Map.Entry<XMLTypeHelper, List<DataType>> 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;
|
||||
}
|
||||
|
|
|
@ -121,13 +121,29 @@ public class Input2InputTransformer extends BaseTransformer<Object[], Object[]>
|
|||
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
|
||||
|
|
|
@ -142,13 +142,29 @@ public class Output2OutputTransformer extends BaseTransformer<Object, Object> 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 {
|
||||
|
|
|
@ -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();
|
||||
if (dt2 != null) {
|
||||
dataTypes.add(dt2);
|
||||
}
|
||||
}
|
||||
// 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();
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
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<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) {
|
||||
|
|
|
@ -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<HelperContext>() {
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue