Uploaded image for project: 'Axis'
  1. Axis
  2. AXIS-2409

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

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Open
    • Blocker
    • Resolution: Unresolved
    • 1.3
    • None
    • WSDL processing
    • None
    • Windows XP professional

    Description

      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.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;
      }

      Attachments

        1. design.zip
          3 kB
          Martin Genhart
        2. SchemaUtils.java
          79 kB
          Martin Genhart

        Activity

          People

            Unassigned Unassigned
            mgenhart Martin Genhart
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated: