You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by er...@apache.org on 2003/07/31 08:25:18 UTC
cvs commit: xml-axis/java/src/org/apache/axis/wsdl/toJava JavaBeanHelperWriter.java JavaBeanWriter.java JavaTypeWriter.java
ericf 2003/07/30 23:25:18
Modified: java/src/org/apache/axis/description TypeDesc.java
java/src/org/apache/axis/wsdl/symbolTable SchemaUtils.java
java/src/org/apache/axis/wsdl/toJava
JavaBeanHelperWriter.java JavaBeanWriter.java
JavaTypeWriter.java
Log:
fix for 21981 -- lack of support in WSDL2Java for complex types that
are derived by restriction.
TypeDesc has a new constructor which takes an additional parameter,
a boolean, indicating whether the TypeDesc is permitted to look at
the superclass(es) of the type it describes when locating metadata
about that type's fields. The default preserves the existing
behavior -- superclasses are searched. The existing constructor
is now implemented in terms of the new constructor.
SchemaUtils has a new method for locating the base type for a
complex type derived by restriction. This is substantially similar
to the existing strategy for finding the base type for derivation
by extension. Methods in that class that locate elements and
attributes in complex content models now look into restriction
nodes for content particles, just as they already did for extension
nodes.
JavaTypeWriter looks for a supertype from which the current type
is derived-by-restriction when creating JavaBeanWriter/JavaBeanHelperWriter
instances iff that type wasn't derived-by-extension. If both
searches fail, the type has no parent and the extendsType value
remains null.
JavaBeanWriter's constructor checks to see if the complex type it's
writing is derived by restriction. If it is, and the extendsType
value is defined (i.e. there is a superclass for the type being
generated), most generation hooks are disabled -- mutators/accessors;
fields; hashcode; equals. Since a type derivated-by-extension is,
by definition, a subset of the base class, it follows that the base
class (or its superclass(es)) already defines all of the members
and variables needed for the subset. So, the derived type gets
all of those members/methods for "free" through inheritance and
they do not need to be generated again. The result is a class
which extends another class (the class it restricts), defines
no member variables, no accessor/mutator methods, and no new
behavior for equals/hashCode. It does, however, define
its own TypeDesc to capture the restricted value space of
the derived type's content model.
JavaBeanHelperWriter performs the same check to see if it's a
writing a complex type derived by restriction. If it is, it uses
the new constructor for TypeDesc to *disable* searches of the class
hierarchy for additional binding metadata. Since types derived by
restriction are required to re-specify their complete content model,
including fields that are being retained from the base type, all
of the necessary metadata for the derived type is present in that
type's own TypeDesc. Further, it would be an error to allow searches
for additional metadata in the inheritance hierarchy, as any particle
which isn't explicitly re-defined in the derived type is not allowed
in its content model (this is what restriction means, in part).
In sum, this strategy ensures that the TypeDesc defines all of the
metadata needed to bind the derived type *and no more than that*.
TODO: attributes in a restricted content model can be "prohibited."
This change set does nothing to address those.
Revision Changes Path
1.34 +50 -15 xml-axis/java/src/org/apache/axis/description/TypeDesc.java
Index: TypeDesc.java
===================================================================
RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/description/TypeDesc.java,v
retrieving revision 1.33
retrieving revision 1.34
diff -u -r1.33 -r1.34
--- TypeDesc.java 13 Jul 2003 22:34:57 -0000 1.33
+++ TypeDesc.java 31 Jul 2003 06:25:18 -0000 1.34
@@ -84,11 +84,32 @@
/** Have we already introspected for the special "any" property desc? */
private boolean lookedForAny = false;
+ /** Can this instance search for metadata in parents of the type it describes? */
+ private boolean canSearchParents = true;
+
+ /**
+ * Creates a new <code>TypeDesc</code> instance. The type desc can search
+ * the metadata of its type'sparent classes.
+ *
+ * @param javaClass a <code>Class</code> value
+ */
public TypeDesc(Class javaClass) {
- this.javaClass = javaClass;
+ this(javaClass, true);
}
/**
+ * Creates a new <code>TypeDesc</code> instance.
+ *
+ * @param javaClass a <code>Class</code> value
+ * @param canSearchParents whether the type desc can search the metadata of
+ * its type's parent classes.
+ */
+ public TypeDesc(Class javaClass, boolean canSearchParents) {
+ this.javaClass = javaClass;
+ this.canSearchParents = canSearchParents;
+ }
+
+ /**
* Static function to explicitly register a type description for
* a given class.
*
@@ -169,7 +190,13 @@
}
public FieldDesc[] getFields(boolean searchParents) {
- if (searchParents) {
+ // note that if canSearchParents is false, this is identical
+ // to getFields(), because the parent type's metadata is off
+ // limits for restricted types which are required to provide a
+ // complete description of their content model in their own
+ // metadata, per the XML schema rules for
+ // derivation-by-restriction
+ if (canSearchParents && searchParents) {
// check superclasses if they exist
Class cls = javaClass.getSuperclass();
if (cls != null && !cls.getName().startsWith("java.")) {
@@ -255,11 +282,14 @@
FieldDesc desc = (FieldDesc)fieldNameMap.get(fieldName);
if (desc == null) {
// check superclasses if they exist
- Class cls = javaClass.getSuperclass();
- if (cls != null && !cls.getName().startsWith("java.")) {
- TypeDesc superDesc = getTypeDescForClass(cls);
- if (superDesc != null) {
- return superDesc.getElementNameForField(fieldName);
+ // and we are allowed to look
+ if (canSearchParents) {
+ Class cls = javaClass.getSuperclass();
+ if (cls != null && !cls.getName().startsWith("java.")) {
+ TypeDesc superDesc = getTypeDescForClass(cls);
+ if (superDesc != null) {
+ return superDesc.getElementNameForField(fieldName);
+ }
}
}
} else if (!desc.isElement()) {
@@ -277,11 +307,14 @@
FieldDesc desc = (FieldDesc)fieldNameMap.get(fieldName);
if (desc == null) {
// check superclasses if they exist
- Class cls = javaClass.getSuperclass();
- if (cls != null && !cls.getName().startsWith("java.")) {
- TypeDesc superDesc = getTypeDescForClass(cls);
- if (superDesc != null) {
- return superDesc.getAttributeNameForField(fieldName);
+ // and we are allowed to look
+ if (canSearchParents) {
+ Class cls = javaClass.getSuperclass();
+ if (cls != null && !cls.getName().startsWith("java.")) {
+ TypeDesc superDesc = getTypeDescForClass(cls);
+ if (superDesc != null) {
+ return superDesc.getAttributeNameForField(fieldName);
+ }
}
}
} else if (desc.isElement()) {
@@ -327,7 +360,8 @@
}
// check superclasses if they exist
- if (result == null) {
+ // and we are allowed to look
+ if (result == null && canSearchParents) {
Class cls = javaClass.getSuperclass();
if (cls != null && !cls.getName().startsWith("java.")) {
TypeDesc superDesc = getTypeDescForClass(cls);
@@ -371,8 +405,9 @@
}
}
- if (possibleMatch == null) {
+ if (possibleMatch == null && canSearchParents) {
// check superclasses if they exist
+ // and we are allowed to look
Class cls = javaClass.getSuperclass();
if (cls != null && !cls.getName().startsWith("java.")) {
TypeDesc superDesc = getTypeDescForClass(cls);
@@ -391,7 +426,7 @@
public FieldDesc getFieldByName(String name)
{
FieldDesc ret = (FieldDesc)fieldNameMap.get(name);
- if (ret == null) {
+ if (ret == null && canSearchParents) {
Class cls = javaClass.getSuperclass();
if (cls != null && !cls.getName().startsWith("java.")) {
TypeDesc superDesc = getTypeDescForClass(cls);
1.25 +63 -3 xml-axis/java/src/org/apache/axis/wsdl/symbolTable/SchemaUtils.java
Index: SchemaUtils.java
===================================================================
RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/wsdl/symbolTable/SchemaUtils.java,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -r1.24 -r1.25
--- SchemaUtils.java 18 Jun 2003 23:01:52 -0000 1.24
+++ SchemaUtils.java 31 Jul 2003 06:25:18 -0000 1.25
@@ -126,7 +126,7 @@
children = complexContent.getChildNodes();
for (int j = 0; j < children.getLength() && extension == null; j++) {
Node kid = children.item(j);
- if (isXSDNode(kid, "extension")) {
+ if (isXSDNode(kid, "extension") || isXSDNode(kid, "restriction")) {
extension = kid;
}
}
@@ -482,6 +482,66 @@
}
/**
+ * Look for the base type of node iff node is a complex type that has been
+ * derived by restriction; otherwise return null.
+ */
+ public static TypeEntry getComplexElementRestrictionBase(Node node, SymbolTable symbolTable) {
+ if (node == null) {
+ return null;
+ }
+ // If the node kind is an element, dive into it.
+ if (isXSDNode(node, "element")) {
+ NodeList children = node.getChildNodes();
+ Node complexNode = null;
+ for (int j = 0; j < children.getLength() && complexNode == null; j++) {
+ if (isXSDNode(children.item(j), "complexType")) {
+ complexNode = children.item(j);
+ node = complexNode;
+ }
+ }
+ }
+
+ // Expecting a schema complexType
+ if (isXSDNode(node, "complexType")) {
+
+ // Under the complexType there could be should be a complexContent &
+ // restriction elements if this is a derived type.
+ NodeList children = node.getChildNodes();
+ Node content = null;
+ Node restriction = null;
+ for (int j = 0; j < children.getLength() && content == null; j++) {
+ Node kid = children.item(j);
+ if (isXSDNode(kid, "complexContent")) {
+ content = kid;
+ }
+ }
+ if (content != null) {
+ children = content.getChildNodes();
+ for (int j = 0; j < children.getLength() && restriction == null; j++) {
+ Node kid = children.item(j);
+ if (isXSDNode(kid, "restriction")) {
+ restriction = kid;
+ }
+ }
+ }
+ if (restriction == null) {
+ return null;
+ } else {
+ // Get the QName of the extension base
+ QName restrictionType = Utils.getTypeQName(restriction, new BooleanHolder(), false);
+ if (restrictionType == null) {
+ return null;
+ } else {
+ // Return associated Type
+ return symbolTable.getType(restrictionType);
+ }
+ }
+ } else {
+ return null;
+ }
+ }
+
+ /**
* If the specified node represents a supported JAX-RPC complexType/element
* which extends another complexType. The Type of the base is returned.
*/
@@ -956,12 +1016,12 @@
break;
}
}
- // Check for extensions
+ // Check for extensions or restrictions
if (content != null) {
children = content.getChildNodes();
for (int j = 0; j < children.getLength(); j++) {
Node kid = children.item(j);
- if (isXSDNode(kid, "extension")) {
+ if (isXSDNode(kid, "extension") || isXSDNode(kid, "restriction")) {
node = kid;
break;
}
1.42 +35 -14 xml-axis/java/src/org/apache/axis/wsdl/toJava/JavaBeanHelperWriter.java
Index: JavaBeanHelperWriter.java
===================================================================
RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/wsdl/toJava/JavaBeanHelperWriter.java,v
retrieving revision 1.41
retrieving revision 1.42
diff -u -r1.41 -r1.42
--- JavaBeanHelperWriter.java 10 Jul 2003 23:10:53 -0000 1.41
+++ JavaBeanHelperWriter.java 31 Jul 2003 06:25:18 -0000 1.42
@@ -59,6 +59,7 @@
import org.apache.axis.wsdl.symbolTable.TypeEntry;
import org.apache.axis.wsdl.symbolTable.DefinedElement;
import org.apache.axis.wsdl.symbolTable.DefinedType;
+import org.apache.axis.wsdl.symbolTable.SchemaUtils;
import javax.xml.namespace.QName;
import java.io.IOException;
@@ -75,6 +76,7 @@
protected TypeEntry extendType;
protected PrintWriter wrapperPW = null;
protected Vector elementMetaData = null;
+ protected boolean canSearchParents;
/**
* Constructor.
@@ -85,16 +87,32 @@
* @param attributes Vector containing the attribute types and names
*/
protected JavaBeanHelperWriter(
- Emitter emitter,
- TypeEntry type,
- Vector elements,
- TypeEntry extendType,
- Vector attributes) {
+ Emitter emitter,
+ TypeEntry type,
+ Vector elements,
+ TypeEntry extendType,
+ Vector attributes) {
super(emitter, type.getName() + "_Helper", "helper");
this.type = type;
this.elements = elements;
this.attributes = attributes;
this.extendType = extendType;
+ // is this a complex type that is derived from other types
+ // by restriction? if so, set the policy of the generated
+ // TypeDescription to ignore metadata associated with
+ // superclasses, as restricted types are required to
+ // define their entire content model. Hence the type
+ // description associated with the current type provides
+ // all of the types (and only those types) allowed in
+ // the restricted derivation.
+ if (null != extendType
+ && null != SchemaUtils.getComplexElementRestrictionBase(type.getNode(),
+ emitter.getSymbolTable())) {
+ this.canSearchParents = false;
+ } else {
+ this.canSearchParents = true;
+ }
+
} // ctor
/**
@@ -213,19 +231,22 @@
// Character.isUpperCase(javaName.charAt(0)) ||
//!elem.getName().getNamespaceURI().equals("") ||
//elem.getMinOccursIs0()) {
- // If we did some mangling, make sure we'll write out the XML
- // the correct way.
- if (elementMetaData == null)
- elementMetaData = new Vector();
+ // If we did some mangling, make sure we'll write out the XML
+ // the correct way.
+ if (elementMetaData == null)
+ elementMetaData = new Vector();
- elementMetaData.add(elem);
+ elementMetaData.add(elem);
//}
}
}
pw.println(" // " + Messages.getMessage("typeMeta"));
pw.println(" private static org.apache.axis.description.TypeDesc typeDesc =");
- pw.println(" new org.apache.axis.description.TypeDesc(" +
- Utils.getJavaLocalName(type.getName()) + ".class);");
+ pw.println(" new org.apache.axis.description.TypeDesc("
+ + Utils.getJavaLocalName(type.getName())
+ + ".class, "
+ + (this.canSearchParents ? "true" : "false")
+ + ");");
pw.println();
pw.println(" static {");
@@ -278,7 +299,7 @@
QName xmlType = null;
if (elemType.getDimensions().length() > 1 &&
- (elemType.getClass() == DefinedType.class)) {
+ (elemType.getClass() == DefinedType.class)) {
// If we have a DefinedType with dimensions, it must
// be a SOAP array derived type. In this case, use
// the refType's QName for the metadata.
@@ -338,7 +359,7 @@
// bean property name will have a capitalized first character
// (because setURL() maps to a property named "URL", not "uRL")
if (fieldName.length() > 1 &&
- Character.isUpperCase(fieldName.charAt(1))) {
+ Character.isUpperCase(fieldName.charAt(1))) {
return Utils.capitalizeFirstChar(fieldName);
}
1.43 +18 -1 xml-axis/java/src/org/apache/axis/wsdl/toJava/JavaBeanWriter.java
Index: JavaBeanWriter.java
===================================================================
RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/wsdl/toJava/JavaBeanWriter.java,v
retrieving revision 1.42
retrieving revision 1.43
diff -u -r1.42 -r1.43
--- JavaBeanWriter.java 27 Jun 2003 17:16:25 -0000 1.42
+++ JavaBeanWriter.java 31 Jul 2003 06:25:18 -0000 1.43
@@ -92,6 +92,7 @@
protected boolean enableGetters = true;
protected boolean enableEquals = true;
protected boolean enableHashCode = true;
+ protected boolean enableMemberFields = true;
protected boolean isAny = false;
@@ -120,6 +121,20 @@
if (type.isSimpleType()) {
enableSimpleConstructors = true;
enableToString = true;
+ } else {
+ // is this a complex type that is derived from other types
+ // by restriction? if so, do not emit instance variables
+ // or accessor/mutator pairs as those are inherited from
+ // the super type, which must be non-null.
+ if (null != extendType
+ && null != SchemaUtils.getComplexElementRestrictionBase(type.getNode(),
+ emitter.getSymbolTable())) {
+ enableMemberFields = false;
+ enableGetters = false;
+ enableSetters = false;
+ enableEquals = false;
+ enableHashCode = false;
+ }
}
} // ctor
@@ -137,7 +152,9 @@
// preprocess();
// Write Member Fields
- writeMemberFields();
+ if (enableMemberFields) {
+ writeMemberFields();
+ }
// Write the default constructor
if (enableDefaultConstructor) {
1.17 +4 -0 xml-axis/java/src/org/apache/axis/wsdl/toJava/JavaTypeWriter.java
Index: JavaTypeWriter.java
===================================================================
RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/wsdl/toJava/JavaTypeWriter.java,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- JavaTypeWriter.java 22 Apr 2003 19:36:27 -0000 1.16
+++ JavaTypeWriter.java 31 Jul 2003 06:25:18 -0000 1.17
@@ -102,6 +102,10 @@
TypeEntry base = SchemaUtils.getComplexElementExtensionBase(
node, symbolTable);
if (base == null) {
+ base = SchemaUtils.getComplexElementRestrictionBase(
+ node, symbolTable);
+ }
+ if (base == null) {
QName baseQName = SchemaUtils.getSimpleTypeBase(
node);
if (baseQName != null) {