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) {