Issue Details (XML | Word | Printable)

Key: AXIS-2409
Type: Bug Bug
Status: Open Open
Priority: Blocker Blocker
Assignee: Unassigned
Reporter: Martin Genhart
Votes: 0
Watchers: 1
Operations

If you were logged in you would be able to see more operations.
Axis

WSDL processing does not resolve references made within sequences to global elements.

Created: 17/Feb/06 03:26 AM   Updated: 17/Feb/06 03:29 AM
Component/s: WSDL processing
Affects Version/s: 1.3
Fix Version/s: None

Time Tracking:
Not Specified

File Attachments:
  Size
Zip Archive Licensed for inclusion in ASF works design.zip 2006-02-17 03:28 AM Martin Genhart 3 kB
Java Source File Licensed for inclusion in ASF works SchemaUtils.java 2006-02-17 03:29 AM Martin Genhart 79 kB
Environment: Windows XP professional


 Description  « Hide
The following schema element PSKeyword/Choices references a globally defined element PSKeywordChoice in a sequence. This will not be resolved during WSDL processing while creating the type description in the produced java object. Because of that the array serializer produces the wrong XML and of course the array deserializer fails because it did expect XML as defined in the schema. If the same schema construct if made with local elements it is processed fine, see PSHierarchyNode/Properties in the schema below.

<xsd:schema targetNamespace="urn:www.percussion.com/6.0.0/contentServices" xmlns:cons="urn:www.percussion.com/6.0.0/contentServices" xmlns:com="urn:www.percussion.com/6.0.0/common" xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="qualified">
   <xsd:simpleType name="NodeType">
      <xsd:restriction base="xsd:string">
         <xsd:enumeration value="folder"/>
         <xsd:enumeration value="placeholder"/>
      </xsd:restriction>
   </xsd:simpleType>
   <xsd:element name="PSHierarchyNode">
      <xsd:complexType>
         <xsd:sequence>
            <xsd:element name="Properties" minOccurs="0">
               <xsd:complexType>
                  <xsd:sequence>
                     <xsd:element name="Property" maxOccurs="unbounded">
                        <xsd:complexType>
                           <xsd:attribute name="parentId" type="xsd:string"/>
                           <xsd:attribute name="name" type="xsd:string" use="required"/>
                           <xsd:attribute name="value" type="xsd:string"/>
                        </xsd:complexType>
                     </xsd:element>
                  </xsd:sequence>
               </xsd:complexType>
            </xsd:element>
         </xsd:sequence>
         <xsd:attribute name="id" type="xsd:string"/>
         <xsd:attribute name="parentId" type="xsd:string"/>
         <xsd:attribute name="type" type="cons:NodeType" use="required"/>
         <xsd:attribute name="name" type="xsd:string" use="required"/>
      </xsd:complexType>
   </xsd:element>
   <xsd:element name="PSKeyword">
      <xsd:complexType>
         <xsd:simpleContent>
            <xsd:extension base="xsd:string">
               <xsd:attribute name="label" type="xsd:string" use="required">
                  <xsd:annotation>
                     <xsd:documentation>The label of the keyword as displayed to end users.</xsd:documentation>
                  </xsd:annotation>
               </xsd:attribute>
               <xsd:attribute name="value" type="xsd:string" use="required"/>
               <xsd:attribute name="keywordType" type="xsd:string" use="required"/>
               <xsd:attribute name="sequence" type="xsd:int"/>
            </xsd:extension>
         </xsd:simpleContent>
      </xsd:complexType>
   </xsd:element>
   <xsd:element name="PSKeywordChoice">
      <xsd:complexType>
         <xsd:attribute name="label" type="xsd:string" use="required"/>
         <xsd:attribute name="value" type="xsd:string" use="required"/>
         <xsd:attribute name="description" type="xsd:string"/>
         <xsd:attribute name="sequence" type="xsd:int" default="0"/>
      </xsd:complexType>
   </xsd:element>
</xsd:schema>

I will upload the WSLD / schema so that you are able to reproduce the problem. I run org.apache.axis.wsdl.WSDL2Java with these arguments:

-o d:\temp\wsdl -W -s -S false -d Request -T 1.1 D:\temp\wsdl\design\rhythmyx.wsdl

The meta data produced for PSKeyword are:

    static {
        typeDesc.setXmlType(new javax.xml.namespace.QName("urn:www.percussion.com/6.0.0/contentServices", ">PSKeyword"));
        org.apache.axis.description.AttributeDesc attrField = new org.apache.axis.description.AttributeDesc();
        attrField.setFieldName("label");
        attrField.setXmlName(new javax.xml.namespace.QName("", "label"));
        attrField.setXmlType(new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", "string"));
        typeDesc.addFieldDesc(attrField);
        attrField = new org.apache.axis.description.AttributeDesc();
        attrField.setFieldName("value");
        attrField.setXmlName(new javax.xml.namespace.QName("", "value"));
        attrField.setXmlType(new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", "string"));
        typeDesc.addFieldDesc(attrField);
        attrField = new org.apache.axis.description.AttributeDesc();
        attrField.setFieldName("keywordType");
        attrField.setXmlName(new javax.xml.namespace.QName("", "keywordType"));
        attrField.setXmlType(new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", "string"));
        typeDesc.addFieldDesc(attrField);
        attrField = new org.apache.axis.description.AttributeDesc();
        attrField.setFieldName("sequence");
        attrField.setXmlName(new javax.xml.namespace.QName("", "sequence"));
        attrField.setXmlType(new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", "int"));
        typeDesc.addFieldDesc(attrField);
        org.apache.axis.description.ElementDesc elemField = new org.apache.axis.description.ElementDesc();
        elemField.setFieldName("choices");
        elemField.setXmlName(new javax.xml.namespace.QName("urn:www.percussion.com/6.0.0/contentServices", "Choices"));
        elemField.setXmlType(new javax.xml.namespace.QName("urn:www.percussion.com/6.0.0/contentServices", "PSKeywordChoice"));
        elemField.setMinOccurs(0);
        elemField.setNillable(false);
        typeDesc.addFieldDesc(elemField);
    }

But it should be:

    static {
        typeDesc.setXmlType(new javax.xml.namespace.QName("urn:www.percussion.com/6.0.0/contentServices", ">PSKeyword"));
        org.apache.axis.description.AttributeDesc attrField = new org.apache.axis.description.AttributeDesc();
        attrField.setFieldName("label");
        attrField.setXmlName(new javax.xml.namespace.QName("", "label"));
        attrField.setXmlType(new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", "string"));
        typeDesc.addFieldDesc(attrField);
        attrField = new org.apache.axis.description.AttributeDesc();
        attrField.setFieldName("value");
        attrField.setXmlName(new javax.xml.namespace.QName("", "value"));
        attrField.setXmlType(new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", "string"));
        typeDesc.addFieldDesc(attrField);
        attrField = new org.apache.axis.description.AttributeDesc();
        attrField.setFieldName("keywordType");
        attrField.setXmlName(new javax.xml.namespace.QName("", "keywordType"));
        attrField.setXmlType(new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", "string"));
        typeDesc.addFieldDesc(attrField);
        attrField = new org.apache.axis.description.AttributeDesc();
        attrField.setFieldName("sequence");
        attrField.setXmlName(new javax.xml.namespace.QName("", "sequence"));
        attrField.setXmlType(new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", "int"));
        typeDesc.addFieldDesc(attrField);
        org.apache.axis.description.ElementDesc elemField = new org.apache.axis.description.ElementDesc();
        elemField.setFieldName("choices");
        elemField.setXmlName(new javax.xml.namespace.QName("urn:www.percussion.com/6.0.0/contentServices", "Choices"));
        elemField.setXmlType(new javax.xml.namespace.QName("urn:www.percussion.com/6.0.0/contentServices", "PSKeywordChoice"));
        elemField.setMinOccurs(0);
        elemField.setNillable(false);
        elemField.setItemQName(new javax.xml.namespace.QName("urn:www.percussion.com/6.0.0/contentServices", "PSKeywordChoice"));
        typeDesc.addFieldDesc(elemField);
    }

I found that the problem is in class org.apache.axis.wsdl.symbolTable.SchemUtils.java:

    public static QName getCollectionComponentQName(Node node,
                                                    QNameHolder itemQName,
                                                    BooleanHolder forElement,
                                                    SymbolTable symbolTable) {
        // If we're going to turn "wrapped" arrays into types such that
        // <complexType><sequence>
        // <element name="foo" type="xs:string" maxOccurs="unbounded"/>
        // </sequence></complexType>
        // becomes just "String []", we need to keep track of the inner
        // element name "foo" in metadata... This flag indicates whether to
        // do so.
        boolean storeComponentQName = false;

        if (node == null) {
            return null;
        }

        if (itemQName != null && isXSDNode(node, "complexType")) {
            // If this complexType is a sequence of exactly one element
            // we will continue processing below using that element, and
            // let the type checking logic determine if this is an array
            // or not.
            Node sequence = SchemaUtils.getChildByName(node, "sequence");
            if (sequence == null) {
                return null;
            }
            NodeList children = sequence.getChildNodes();
            Node element = null;
            for (int i = 0; i < children.getLength(); i++) {
                if (children.item(i).getNodeType() == Node.ELEMENT_NODE) {
                    if (element == null) {
                        element = children.item(i);
                    } else {
                        return null;
                    }
                }
            }
            if (element == null) {
                return null;
            }

            // OK, exactly one element child of <sequence>,
            // continue the processing using that element ...
            node = element;
            storeComponentQName = true;
            try {
                symbolTable.createTypeFromRef(node);
            } catch (IOException e) {
                throw new RuntimeException(Messages.getMessage("exception01",e.toString()));
            }
        }

        // If the node kind is an element, dive to get its type.
        if (isXSDNode(node, "element")) {

            // Compare the componentQName with the name of the
            // full name. If different, return componentQName
            QName componentTypeQName = Utils.getTypeQName(node,
                                                          forElement,
                                                          true);

            if (componentTypeQName != null) {
                QName fullQName = Utils.getTypeQName(node, forElement, false);

                if (!componentTypeQName.equals(fullQName)) {
                    if (storeComponentQName) {
                        String name = Utils.getAttribute(node, "name");
                        
+++ // maybe its a reference
+++ if (name == null)
+++ {
+++ String ref = Utils.getAttribute(node, "ref");
+++ if (ref != null)
+++ {
+++ // strip any namespace info, it will be added later
+++ String[] parts = ref.split(":");
+++ name = parts[parts.length-1];
+++ }
                        }
                        
                        if (name != null) {
                            // check elementFormDefault on schema element
                            String def = Utils.getScopedAttribute(node,
                                    "elementFormDefault");
                            String namespace = "";
                            if ((def != null) && def.equals("qualified")) {
                                 namespace = Utils.getScopedAttribute(node, "targetNamespace");
                            }
                            itemQName.value = new QName(namespace, name);
                        }
                    }
                    return componentTypeQName;
                }
            }
        }

        return null;
    }



 All   Comments   Work Log   Change History   Subversion Commits      Sort Order: Ascending order - Click to sort in descending order
Martin Genhart added a comment - 17/Feb/06 03:28 AM
The WSDL / schema used to reproduce the problem.

Martin Genhart made changes - 17/Feb/06 03:28 AM
Field Original Value New Value
Attachment design.zip [ 12323063 ]
Martin Genhart added a comment - 17/Feb/06 03:29 AM
The change that fixes the problem.

Martin Genhart made changes - 17/Feb/06 03:29 AM
Attachment SchemaUtils.java [ 12323064 ]