Ajith,

Thanks for the update.  Since I need choice to upgrade to 0.95, I went ahead and implemented it.

******  In the course of this, I found a serious issue in 0.95.  The setting of the choice variable in ADBBeanTemplate is checked in,
but with the wrong code.  It is always true, which messes up the pull parser seriously.  I.e., for non-choice beans, there are local trackers
and all but one are false, so code that looks for these will miss valid properties!

There is another serious issue, in that a bug I reported earlier was propagated into commons.  Specifically, OMStAXWrapper does not obey the contract of getElementText() -- it does not leave the reader at the end element.  I had to work around that bug in the parser, and hope it gets fixed.  There is a detailed comment with the workaround.

The attached patches resolve these issues:
  1. Correct the improper setting of choice that causes Axis2 to think all adb beans are choices.
  2. Implement choice
  3. Fix recursive data types
  4. Probably fix general cases still in the parser for minOccurs=0 (e.g., the event following an empty array need not be the outer end element) and where subelements with same name as parent element would not work.  (I didn't trigger these problems with tests, but they seem to be there from looking at the code -- they are definitely not there with the patch.)
  5. Fix pull parser for serialization of 0-length arrays
  6. Work around the OMStAXWrapper problem with getElementText()
All Axis2 tests pass, and our application which has complex wsdl runs properly.

Thanks,

Chuck


Ajith Ranabahu wrote:
Hi Chuck,
Sorry for the late answer but adding choice support is still underway.
We have marked choice support as a requirement for 1.0.
I'll see to that recursive datatypes are handled properly with your pach.

On 3/26/06, Chuck Williams <[EMAIL PROTECTED]> wrote:
  
 This time with the attachment:



 Chuck Williams <[EMAIL PROTECTED]> wrote on 03/26/2006 01:41:54 AM:



 Hi All,

Axis2 0.95 still does not handle recursive data types properly. The
SchemaCompiler recurses infinitely and generates a stack overflow. I've
attached my patch to fix this upgraded for 0.95. This is a patch
against modules/codegen/src.

I see that much of the code to implement choice particles was committed,
but that the new parser does not handle them. I need to get them
working again. Is there already work underway to do this, and/or was an
approach determined? If so, I'd appreciate any information about that.
If not, I'll figure out how to do it with the new parser and send
another patch.

Thanks,

Chuck





    


--
Ajith Ranabahu
  

diff -urx .svn adb.src.orig/org/apache/axis2/databinding/utils/ADBPullParser.java adb.src.new/org/apache/axis2/databinding/utils/ADBPullParser.java
--- adb.src.orig/org/apache/axis2/databinding/utils/ADBPullParser.java	2006-03-26 16:32:21.000000000 -1000
+++ adb.src.new/org/apache/axis2/databinding/utils/ADBPullParser.java	2006-03-26 16:51:33.000000000 -1000
@@ -281,12 +281,15 @@
                 Object object = properties[currentIndex];
                 if (object instanceof String[]) {
 
+                    if (((String[])object).length==0) {
+                        currentIndex += 2;
+                        return this.next();
+                    }
+
                     complexStringArrayName = (QName) o;
                     complexObjectArray = object;
                     secondArrayIndex = 0;
 
-                    complexObjectArray = object;
-                    secondArrayIndex = 0;
                     processingComplexADBNameValuePair = true;
 
                     // use the simple name value pair processing recursively
@@ -297,6 +300,12 @@
 
 
                 } else if (object instanceof Object[]) {
+
+                    if (((Object[])object).length==0) {
+                        currentIndex += 2;
+                        return this.next();
+                    }
+
                     secondArrayIndex = 0;
                     complexArray = (Object[]) object;
                     complexArrayQName = (QName) o;
Only in adb.src.new/org/apache/axis2/databinding/utils: ADBPullParser.java~
diff -urx .svn codegen.src.orig/org/apache/axis2/schema/SchemaCompiler.java codegen.src.new/org/apache/axis2/schema/SchemaCompiler.java
--- codegen.src.orig/org/apache/axis2/schema/SchemaCompiler.java	2006-03-25 12:23:50.000000000 -1000
+++ codegen.src.new/org/apache/axis2/schema/SchemaCompiler.java	2006-03-25 21:55:26.000000000 -1000
@@ -381,7 +381,8 @@
                         //set a name
                         schemaType.setName(generatedTypeName.getLocalPart());
                         writeComplexType((XmlSchemaComplexType)schemaType,
-                                (BeanWriterMetaInfoHolder)processedAnonymousComplexTypesMap.get(xsElt));
+                                (BeanWriterMetaInfoHolder)processedAnonymousComplexTypesMap.get(xsElt),
+                                null);
                         //remove the reference from the anon list since we named the type
                         processedAnonymousComplexTypesMap.remove(xsElt);
                         innerElementMap.put(
@@ -423,7 +424,8 @@
                     referenceSchemaType.setName(generatedTypeName.getLocalPart());
 
                     writeComplexType((XmlSchemaComplexType)referenceSchemaType,
-                            (BeanWriterMetaInfoHolder)processedAnonymousComplexTypesMap.get(referencedElement));
+                            (BeanWriterMetaInfoHolder)processedAnonymousComplexTypesMap.get(referencedElement),
+                            null);
                     //remove the reference from the anon list since we named the type
                     processedAnonymousComplexTypesMap.remove(referencedElement);
 
@@ -600,12 +602,16 @@
                 || baseSchemaTypeMap.containsKey(complexType.getQName())) {
             return;
         }
+        
+        // Must do this up front to support recursive types
+        String fullyQualifiedClassName = writer.makeFullyQualifiedClassName(complexType.getQName());
+        processedTypemap.put(complexType.getQName(), fullyQualifiedClassName);
 
         BeanWriterMetaInfoHolder metaInfHolder = processComplexType(complexType,parentSchema);
 
         //write the class. This type mapping would have been populated right now
         //Note - We always write classes for named complex types
-        writeComplexType(complexType, metaInfHolder);
+        writeComplexType(complexType, metaInfHolder, fullyQualifiedClassName);
 
 
     }
@@ -614,12 +620,12 @@
      * Writes a complex type
      * @param complexType
      * @param metaInfHolder
+     * @param fullyQualifiedClassName the name returned by makeFullyQualifiedClassName() or null if it wasn't called
      * @throws SchemaCompilationException
      */
-    private void writeComplexType(XmlSchemaComplexType complexType, BeanWriterMetaInfoHolder metaInfHolder) throws SchemaCompilationException {
-        String fullyQualifiedClassName = writer.write(complexType, processedTypemap, metaInfHolder);
-        //populate the type map with the type QName
-        processedTypemap.put(complexType.getQName(), fullyQualifiedClassName);
+    private void writeComplexType(XmlSchemaComplexType complexType, BeanWriterMetaInfoHolder metaInfHolder, String fullyQualifiedClassName)
+    throws SchemaCompilationException {
+        writer.write(complexType, processedTypemap, metaInfHolder, fullyQualifiedClassName);
         processedTypeMetaInfoMap.put(complexType.getQName(),metaInfHolder);
     }
 
diff -urx .svn codegen.src.orig/org/apache/axis2/schema/template/ADBBeanTemplate.xsl codegen.src.new/org/apache/axis2/schema/template/ADBBeanTemplate.xsl
--- codegen.src.orig/org/apache/axis2/schema/template/ADBBeanTemplate.xsl	2006-03-25 12:23:50.000000000 -1000
+++ codegen.src.new/org/apache/axis2/schema/template/ADBBeanTemplate.xsl	2006-03-26 17:41:06.000000000 -1000
@@ -32,7 +32,10 @@
     <xsl:template match="bean">
 
         <xsl:variable name="name"><xsl:value-of select="@name"/></xsl:variable>
-        <xsl:variable name="choice"><xsl:value-of select="@choice"/></xsl:variable>
+        <xsl:variable name="choice" select="@choice"/>
+        <xsl:variable name="isType" select="@type"/>
+        <xsl:variable name="anon" select="@anon"/>
+        
     <!-- write the class header. this should be done only when unwrapped -->
 
         <xsl:if test="not(not(@unwrapped) or (@skip-write))">
@@ -351,326 +354,272 @@
       *  Factory class that keeps the parse method
       */
     public static class Factory{
+
+        // This is horrible, but the OM implementation of getElementText() does not obey the proper contract.  Specifically, it does
+        // does not advance the reader to the END_ELEMENT.  This bug is triggered by calls to getElementText() unpredictably, e.g. it
+        // happens with outer (document) elements, but not with inner elements.  The root bug is in OMStAXWrapper.java, which is now part
+        // of commons and so cannot just be fixed in axis2.  This method should be removed and the calls to it below replaced with 
+        // simple calls to getElementText() as soon as this serious bug can be fixed.
+        private static String getElementTextProperly(javax.xml.stream.XMLStreamReader reader) throws java.lang.Exception {
+            String value = reader.getElementText();
+            while (!reader.isEndElement())
+                reader.next();
+            return value;
+        }
+    
         /**
         * static method to create the object
         */
         public static <xsl:value-of select="$name"/> parse(javax.xml.stream.XMLStreamReader reader) throws java.lang.Exception{
-        <xsl:value-of select="$name"/> object = new <xsl:value-of select="$name"/>();
-        try {
-        int event = reader.getEventType();
-
-       //event better be a START_ELEMENT. if not we should go up to the start element here
-        while (event!= javax.xml.stream.XMLStreamReader.START_ELEMENT) {
-            event = reader.next();
-        }
-
-        <xsl:if test="not(@type)">
-        if (!MY_QNAME.equals(reader.getName())){
-                    throw new Exception("Wrong QName");
-        }
-        </xsl:if>
-
-        <xsl:if test="@nillable">
-           if ("true".equals(reader.getAttributeValue("http://www.w3.org/2001/XMLSchema-instance","nil";))){
-                 return null;
-           }
-        </xsl:if>
-
-        <!-- populate attributes here!!!. The attributes are part of an element, not part of a
-       type -->
-        <xsl:for-each select="[EMAIL PROTECTED]">
-            <xsl:variable name="propertyName"><xsl:value-of select="@name"/></xsl:variable>
-            <xsl:variable name="propertyType"><xsl:value-of select="@type"/></xsl:variable>
-            <xsl:variable name="shortTypeName"><xsl:value-of select="@shorttypename"/></xsl:variable>
-            <xsl:variable name="javaName"><xsl:value-of select="@javaname"></xsl:value-of></xsl:variable>
-            <xsl:variable name="namespace"><xsl:value-of select="@nsuri"/></xsl:variable>
-            <xsl:variable name="attribName">tempAttrib<xsl:value-of select="$propertyName"/></xsl:variable>
-
-            java.lang.String <xsl:value-of select="$attribName"/> =
-              reader.getAttributeValue("<xsl:value-of select="$namespace"/>","<xsl:value-of select="$propertyName"/>");
-           if (<xsl:value-of select="$attribName"/>!=null){
-                 object.set<xsl:value-of select="$javaName"/>(
-                   org.apache.axis2.databinding.utils.ConverterUtil.convertTo<xsl:value-of select="$shortTypeName"/>(
-                        <xsl:value-of select="$attribName"/>));
-            }
-
-        </xsl:for-each>
-
-        <!-- Now reloop and populate the code for non-attribute values-->
-        <xsl:for-each select="property[not(@attribute)]">
-            <xsl:variable name="propertyName"><xsl:value-of select="@name"/></xsl:variable>
-            <xsl:variable name="propertyType"><xsl:value-of select="@type"/></xsl:variable>
-            <xsl:variable name="shortTypeName"><xsl:value-of select="@shorttypename"/></xsl:variable>
-            <xsl:variable name="javaName"><xsl:value-of select="@javaname"></xsl:value-of></xsl:variable>
-            <xsl:variable name="listName">list<xsl:value-of select="position()"/></xsl:variable>
-            <xsl:variable name="loopBoolName">loopDone<xsl:value-of select="position()"/></xsl:variable>
-            <xsl:variable name="startQname">startQname<xsl:value-of select="position()"/></xsl:variable>
-            <xsl:variable name="stateMachineName">stateMachine<xsl:value-of select="position()"/></xsl:variable>
-            <xsl:variable name="builderName">builder<xsl:value-of select="position()"/></xsl:variable>
-            <xsl:variable name="basePropertyType"><xsl:value-of select="@arrayBaseType"/></xsl:variable>
-            <xsl:variable name="namespace"><xsl:value-of select="@nsuri"/></xsl:variable>
-            <xsl:variable name="min"><xsl:value-of select="@minOccurs"/></xsl:variable>
-
+            <xsl:value-of select="$name"/> object = new <xsl:value-of select="$name"/>();
+            try {
+                // We should already be at our outer StartElement, but make sure
+                while (!reader.isStartElement())
+                    reader.next();
+                    
+                <xsl:if test="@nillable">
+                   if ("true".equals(reader.getAttributeValue("http://www.w3.org/2001/XMLSchema-instance","nil";))){
+                         return null;
+                   }
+                </xsl:if>
 
-            <xsl:choose>
-                <!-- Start of array handling code -->
-                <xsl:when test="@array">
-                    <xsl:choose>
-                        <xsl:when test="@ours">
-                               <!-- Somebody put the magic number 5000 here. I wonder who did that! -->
-                             java.util.ArrayList <xsl:value-of select="$listName"/> = new java.util.ArrayList();
-                            <!-- Start of Array handling of ADB classes -->
-                             boolean <xsl:value-of select="$loopBoolName"/>=false;
-                             javax.xml.namespace.QName <xsl:value-of select="$startQname"/> = new javax.xml.namespace.QName(
-                                    "<xsl:value-of select="$namespace"/>",
-                                    "<xsl:value-of select="$propertyName"/>");
-
-                             // Find the first element
-                             while (!<xsl:value-of select="$loopBoolName"/>){
-                                    event = reader.getEventType();
-                                    if (javax.xml.stream.XMLStreamConstants.START_ELEMENT == event
-                                            &amp;&amp; <xsl:value-of select="$startQname"/>.equals(reader.getName())){
-                                       //we are at the first element
-                                        <xsl:value-of select="$loopBoolName"/> = true;
-                                   <xsl:if test="$min=0">
-                                     }else if (javax.xml.stream.XMLStreamConstants.END_ELEMENT == event
-                                          &amp;&amp;  !<xsl:value-of select="$startQname"/>.equals(reader.getName())){
-                                        //we've found an end element that does not belong to this type
-                                        //since this can occur zero times, this may well be empty.So return
-                                        //the empty object
-                                        return object;
+                <!-- populate attributes here!!!. The attributes are part of an element, not part of a type -->
+                <xsl:for-each select="[EMAIL PROTECTED]">
+                    <xsl:variable name="propertyName"><xsl:value-of select="@name"/></xsl:variable>
+                    <xsl:variable name="propertyType"><xsl:value-of select="@type"/></xsl:variable>
+                    <xsl:variable name="shortTypeName"><xsl:value-of select="@shorttypename"/></xsl:variable>
+                    <xsl:variable name="javaName"><xsl:value-of select="@javaname"></xsl:value-of></xsl:variable>
+                    <xsl:variable name="namespace"><xsl:value-of select="@nsuri"/></xsl:variable>
+                    <xsl:variable name="attribName">tempAttrib<xsl:value-of select="$propertyName"/></xsl:variable>
 
-                                   </xsl:if>
-                                    }else{
-                                        reader.next();
-                                    }
+                    java.lang.String <xsl:value-of select="$attribName"/> =
+                      reader.getAttributeValue("<xsl:value-of select="$namespace"/>","<xsl:value-of select="$propertyName"/>");
+                   if (<xsl:value-of select="$attribName"/>!=null){
+                         object.set<xsl:value-of select="$javaName"/>(
+                           org.apache.axis2.databinding.utils.ConverterUtil.convertTo<xsl:value-of select="$shortTypeName"/>(
+                                <xsl:value-of select="$attribName"/>));
+                    }
 
-                                }
+                </xsl:for-each>
+                    
+                <xsl:if test="$isType or $anon">
+                    <!-- Skip the outer start element in order to process the subelements. -->
+                    reader.next();
+                </xsl:if>  <!-- If we are not a type and not an element with anonymous type, then we are an element with one property for our named type. -->
+                           <!-- Our single named-type property applies to our entire outer element, so don't skip it. -->
+                <!-- First loop creates arrayLists for handling arrays -->
+                <xsl:for-each select="property">
+                    <xsl:if test="@array">
+                        java.util.ArrayList list<xsl:value-of select="position()"/> = new java.util.ArrayList();
+                    </xsl:if>
+                </xsl:for-each>
+                while(!reader.isEndElement()) {
+                    if (reader.isStartElement()){
+                        <!-- Now reloop and populate the code -->
+                        <xsl:for-each select="property">
+                            <xsl:variable name="propertyName"><xsl:value-of select="@name"/></xsl:variable>
+                            <xsl:variable name="propertyType"><xsl:value-of select="@type"/></xsl:variable>
+                            <xsl:variable name="shortTypeName"><xsl:value-of select="@shorttypename"/></xsl:variable>
+                            <xsl:variable name="javaName"><xsl:value-of select="@javaname"></xsl:value-of></xsl:variable>
+                            <xsl:variable name="listName">list<xsl:value-of select="position()"/></xsl:variable>
+                            <xsl:variable name="loopBoolName">loopDone<xsl:value-of select="position()"/></xsl:variable>
+                            <xsl:variable name="startQname">startQname<xsl:value-of select="position()"/></xsl:variable>
+                            <xsl:variable name="stateMachineName">stateMachine<xsl:value-of select="position()"/></xsl:variable>
+                            <xsl:variable name="builderName">builder<xsl:value-of select="position()"/></xsl:variable>
+                            <xsl:variable name="basePropertyType"><xsl:value-of select="@arrayBaseType"/></xsl:variable>
+                            <xsl:variable name="namespace"><xsl:value-of select="@nsuri"/></xsl:variable>
+                            <xsl:variable name="min"><xsl:value-of select="@minOccurs"/></xsl:variable>
 
-                                //Now loop and populate the array
-                                <xsl:value-of select="$loopBoolName"/> = false;
-                                while (!<xsl:value-of select="$loopBoolName"/>){
-                                    event = reader.getEventType();
-                                    if (javax.xml.stream.XMLStreamConstants.START_ELEMENT == event
-                                            &amp;&amp; <xsl:value-of select="$startQname"/>.equals(reader.getName())){
-                                       <xsl:value-of select="$listName"/>.add(<xsl:value-of select="$basePropertyType"/>.Factory.parse(reader));
-                                    }else if (javax.xml.stream.XMLStreamConstants.START_ELEMENT == event
-                                            &amp;&amp; !<xsl:value-of select="$startQname"/>.equals(reader.getName())){
-                                       <xsl:value-of select="$loopBoolName"/> = true;
-                                    }else if (javax.xml.stream.XMLStreamConstants.END_ELEMENT == event &amp;&amp;
-                                        !<xsl:value-of select="$startQname"/>.equals(reader.getName())){
-                                        <xsl:value-of select="$loopBoolName"/> = true;
-                                    }else{
+                            <xsl:if test="position()>1">else</xsl:if> if ("<xsl:value-of select="$propertyName"/>".equals(reader.getLocalName())){
+                            <xsl:choose>
+                                <xsl:when test="@array">
+                                    <!-- We must be a named type or element with anonymous type. -->
+                                    <!-- Elements with a named type have a single simple (non-array) property for their type -->
+                                    // Process the array and step past its final element's end.
+                                    <xsl:variable name="basePropertyType"><xsl:value-of select="@arrayBaseType"/></xsl:variable>
+                                    <xsl:choose>
+                                        <xsl:when test="@ours">
+                                            <xsl:value-of select="$listName"/>.add(<xsl:value-of select="$basePropertyType"/>.Factory.parse(reader));
+                                            //loop until we find a start element that is not part of this array
+                                            boolean <xsl:value-of select="$loopBoolName"/> = false;
+                                            while(!<xsl:value-of select="$loopBoolName"/>){
+                                                // We should be at the end element, but make sure
+                                                while (!reader.isEndElement())
+                                                    reader.next();
+                                                // Step out of this element
+                                                reader.next();
+                                                if (reader.isEndElement()){
+                                                    //two continuous end elements means we are exiting the xml structure
+                                                    <xsl:value-of select="$loopBoolName"/> = true;
+                                                } else if (reader.isStartElement()){
+                                                    if ("<xsl:value-of select="$propertyName"/>".equals(reader.getLocalName())){
+                                                        <xsl:value-of select="$listName"/>.add(<xsl:value-of select="$basePropertyType"/>.Factory.parse(reader));
+                                                    }else{
+                                                        <xsl:value-of select="$loopBoolName"/> = true;
+                                                    }
+                                                }
+                                            }
+                                            // call the converter utility  to convert and set the array
+                                            object.set<xsl:value-of select="$javaName"/>((<xsl:value-of select="$propertyType"/>)
+                                                org.apache.axis2.databinding.utils.ConverterUtil.convertToArray(
+                                                    <xsl:value-of select="$basePropertyType"/>.class,
+                                                    <xsl:value-of select="$listName"/>));
+                                        </xsl:when>
+                                        <xsl:when test="@default">
+                                             boolean <xsl:value-of select="$loopBoolName"/>=false;
+                                             javax.xml.namespace.QName <xsl:value-of select="$startQname"/> = new javax.xml.namespace.QName(
+                                                    "<xsl:value-of select="$namespace"/>",
+                                                    "<xsl:value-of select="$propertyName"/>");
+
+                                             while (!<xsl:value-of select="$loopBoolName"/>){
+                                                 event = reader.getEventType();
+                                                 if (javax.xml.stream.XMLStreamConstants.START_ELEMENT == event
+                                                         &amp;&amp; <xsl:value-of select="$startQname"/>.equals(reader.getName())){
+
+                                                      <!-- if-block that handles nillable -->
+                                                      <xsl:if test="@nillable">
+                                                          if ("true".equals(reader.getAttributeValue("http://www.w3.org/2001/XMLSchema-instance","nil";))){
+                                                              <xsl:value-of select="$listName"/>.add(null);
+                                                          }else{
+                                                      </xsl:if>
+
+                                                      // We need to wrap the reader so that it produces a fake START_DOCUEMENT event
+                                                      org.apache.axis2.databinding.utils.NamedStaxOMBuilder <xsl:value-of select="$builderName"/>
+                                                         = new org.apache.axis2.databinding.utils.NamedStaxOMBuilder(
+                                                              new org.apache.axis2.util.StreamWrapper(reader), <xsl:value-of select="$startQname"/>);
+  
+                                                       <xsl:value-of select="$listName"/>.add(<xsl:value-of select="$builderName"/>.getOMElement());
+                                                       <xsl:if test="@nillable">}</xsl:if>
+                                                 } else if (javax.xml.stream.XMLStreamConstants.START_ELEMENT == event &amp;&amp;
+                                                            !<xsl:value-of select="$startQname"/>.equals(reader.getName())){
+                                                     <xsl:value-of select="$loopBoolName"/> = true;
+                                                 }else if (javax.xml.stream.XMLStreamConstants.END_ELEMENT == event &amp;&amp;
+                                                           !<xsl:value-of select="$startQname"/>.equals(reader.getName())){
+                                                     <xsl:value-of select="$loopBoolName"/> = true;
+                                                 }else if (javax.xml.stream.XMLStreamConstants.END_DOCUMENT == event){
+                                                     <xsl:value-of select="$loopBoolName"/> = true;
+                                                 }else{
+                                                     reader.next();
+                                                 }
+
+                                             }
+
+                                             object.set<xsl:value-of select="$javaName"/>((<xsl:value-of select="$propertyType"/>)
+                                                 org.apache.axis2.databinding.utils.ConverterUtil.convertToArray(
+                                                     <xsl:value-of select="$basePropertyType"/>.class,<xsl:value-of select="$listName"/>));
+
+                                        </xsl:when>
+                                        <!-- End of Array handling of ADB classes -->
+                                        <xsl:otherwise>
+                                            <xsl:value-of select="$listName"/>.add(getElementTextProperly(reader));
+                                            //loop until we find a start element that is not part of this array
+                                            boolean <xsl:value-of select="$loopBoolName"/> = false;
+                                            while(!<xsl:value-of select="$loopBoolName"/>){
+                                                // Ensure we are at the EndElement
+                                                while (!reader.isEndElement()){
+                                                    reader.next();
+                                                }
+                                                // Step out of this element
+                                                reader.next();
+                                                if (reader.isEndElement()){
+                                                    //two continuous end elements means we are exiting the xml structure
+                                                    <xsl:value-of select="$loopBoolName"/> = true;
+                                                }else if (reader.isStartElement()){
+                                                    if ("<xsl:value-of select="$propertyName"/>".equals(reader.getLocalName())){
+                                                        <xsl:value-of select="$listName"/>.add(getElementTextProperly(reader));
+                                                    }else{
+                                                        <xsl:value-of select="$loopBoolName"/> = true;
+                                                    }
+                                                }
+                                            }
+                                            // call the converter utility  to convert and set the array
+                                            object.set<xsl:value-of select="$javaName"/>((<xsl:value-of select="$propertyType"/>)
+                                                org.apache.axis2.databinding.utils.ConverterUtil.convertToArray(
+                                                    <xsl:value-of select="$basePropertyType"/>.class,
+                                                    <xsl:value-of select="$listName"/>));
+                                        </xsl:otherwise>
+                                    </xsl:choose>
+                                </xsl:when>
+                                <xsl:when test="@ours">
+                                    object.set<xsl:value-of select="$javaName"/>(<xsl:value-of select="$propertyType"/>.Factory.parse(reader));
+                                    <xsl:if test="$isType or $anon">  <!-- This is a subelement property to be consumed -->
                                         reader.next();
-                                    }
-
-                                }
-
-                            object.set<xsl:value-of select="$javaName"/>(
-                                (<xsl:value-of select="$propertyType"/>)
-                               org.apache.axis2.databinding.utils.ConverterUtil.convertToArray(
-                               <xsl:value-of select="$basePropertyType"/>.class,<xsl:value-of select="$listName"/>));
-
-                            //move to the next event, probably past the last end_element event
-                            reader.next();
-                        </xsl:when>
-                        <xsl:when test="@default">
-                             <!-- Somebody put the magic number 5000 here. I wonder who did that! -->
-                             java.util.ArrayList <xsl:value-of select="$listName"/> = new java.util.ArrayList();
-                             boolean <xsl:value-of select="$loopBoolName"/>=false;
-                             javax.xml.namespace.QName <xsl:value-of select="$startQname"/> = new javax.xml.namespace.QName(
-                                    "<xsl:value-of select="$namespace"/>",
-                                    "<xsl:value-of select="$propertyName"/>");
-                            <xsl:variable name="internalLoopVar"><xsl:value-of select="$loopBoolName"/>_internal</xsl:variable>
-                                    boolean <xsl:value-of select="$internalLoopVar"/> = false;
-
-                                    while(!<xsl:value-of select="$internalLoopVar"/>){
-                                        if (reader.isStartElement() &amp;&amp; <xsl:value-of select="$startQname"/>.equals(reader.getName())){
-                                            <xsl:value-of select="$internalLoopVar"/> = true;
-                                        }else{
-                                            reader.next();
-                                        }
-                                }
-
-                                while (!<xsl:value-of select="$loopBoolName"/>){
-                                    event = reader.getEventType();
-                                    if (javax.xml.stream.XMLStreamConstants.START_ELEMENT == event
-                                            &amp;&amp; <xsl:value-of select="$startQname"/>.equals(reader.getName())){
-
-                                    <!-- if-block that handles nillable -->
-                                    <xsl:if test="@nillable">
-                                       if ("true".equals(reader.getAttributeValue("http://www.w3.org/2001/XMLSchema-instance","nil";))){
-                                             <xsl:value-of select="$listName"/>.add(null);
-                                       }else{
                                     </xsl:if>
-
-                                    // We need to wrap the reader so that it produces a fake START_DOCUEMENT event
-                                    org.apache.axis2.databinding.utils.NamedStaxOMBuilder <xsl:value-of select="$builderName"/>
-                                       = new org.apache.axis2.databinding.utils.NamedStaxOMBuilder(
-                                            new org.apache.axis2.util.StreamWrapper(reader), <xsl:value-of select="$startQname"/>);
-
-                                     <xsl:value-of select="$listName"/>.add(<xsl:value-of select="$builderName"/>.getOMElement());
-                                     <xsl:if test="@nillable">}</xsl:if>
-                                    } else if (javax.xml.stream.XMLStreamConstants.START_ELEMENT == event &amp;&amp;
-                                        !<xsl:value-of select="$startQname"/>.equals(reader.getName())){
-                                        <xsl:value-of select="$loopBoolName"/> = true;
-                                    }else if (javax.xml.stream.XMLStreamConstants.END_ELEMENT == event &amp;&amp;
-                                        !<xsl:value-of select="$startQname"/>.equals(reader.getName())){
-                                        <xsl:value-of select="$loopBoolName"/> = true;
-                                    }else if (javax.xml.stream.XMLStreamConstants.END_DOCUMENT == event){
-                                        <xsl:value-of select="$loopBoolName"/> = true;
-                                    }else{
+                                </xsl:when>
+                                <!-- start of any handling. Any can also be @default so we need to handle the any case before default! -->
+                                <xsl:when test="@any">
+                                    <!--No concerns of being nillable here. if it's ours and if the nillable attribute was present
+                                        we would have outputted a null already-->
+                                     <!--This can be any element and we may not know the name. so we pick the name of the element from the parser-->  
+                                     //use the QName from the parser as the name for the builder
+                                     javax.xml.namespace.QName <xsl:value-of select="$startQname"/> = reader.getName();
+     
+                                     // We need to wrap the reader so that it produces a fake START_DOCUMENT event
+                                     // this is needed by the builder classes
+                                     org.apache.axis2.databinding.utils.NamedStaxOMBuilder <xsl:value-of select="$builderName"/> =
+                                         new org.apache.axis2.databinding.utils.NamedStaxOMBuilder(
+                                             new org.apache.axis2.util.StreamWrapper(reader),<xsl:value-of select="$startQname"/>);
+                                     object.set<xsl:value-of select="$javaName"/>(<xsl:value-of select="$builderName"/>.getOMElement());
+                                     <xsl:if test="$isType or $anon">  <!-- This is a subelement property to be consumed -->
+                                         reader.next();
+                                     </xsl:if>
+                                </xsl:when>
+                                <!-- end of adb type handling code -->
+                                <!-- start of OMelement handling -->
+                                 <xsl:when test="@default">
+                                     boolean <xsl:value-of select="$loopBoolName"/> = false;
+                                     javax.xml.namespace.QName <xsl:value-of select="$startQname"/> = new javax.xml.namespace.QName(
+                                                                         "<xsl:value-of select="$namespace"/>",
+                                                                         "<xsl:value-of select="$propertyName"/>");
+
+                                     while(!<xsl:value-of select="$loopBoolName"/>){
+                                         if (reader.isStartElement() &amp;&amp; <xsl:value-of select="$startQname"/>.equals(reader.getName())){
+                                             <xsl:value-of select="$loopBoolName"/> = true;
+                                         }else{
+                                             reader.next();
+                                         }
+                                     }
+
+                                     <!-- todo  put the code here for nillable -->
+                                     // We need to wrap the reader so that it produces a fake START_DOCUEMENT event
+                                     // this is needed by the builder classes
+                                     org.apache.axis2.databinding.utils.NamedStaxOMBuilder <xsl:value-of select="$builderName"/> =
+                                         new org.apache.axis2.databinding.utils.NamedStaxOMBuilder(
+                                             new org.apache.axis2.util.StreamWrapper(reader),<xsl:value-of select="$startQname"/>);
+                                     object.set<xsl:value-of select="$javaName"/>(<xsl:value-of select="$builderName"/>.getOMElement());
+                                     <xsl:if test="$isType or $anon">  <!-- This is a subelement property to be consumed -->
+                                         reader.next();
+                                     </xsl:if>
+                                </xsl:when>
+                                <!-- end of OMelement handling -->
+                                <!-- start of the simple types handling -->
+                                <xsl:otherwise>
+                                    String content = getElementTextProperly(reader);
+                                    object.set<xsl:value-of select="$javaName"/>(
+                                        org.apache.axis2.databinding.utils.ConverterUtil.convertTo<xsl:value-of select="$shortTypeName"/>(content));
+                                    <xsl:if test="$isType or $anon">  <!-- This is a subelement property to be consumed -->
                                         reader.next();
-                                    }
-
-                                }
-
-                            object.set<xsl:value-of select="$javaName"/>(
-                                (<xsl:value-of select="$propertyType"/>)
-                               org.apache.axis2.databinding.utils.ConverterUtil.convertToArray(
-                               <xsl:value-of select="$basePropertyType"/>.class,<xsl:value-of select="$listName"/>));
-
+                                    </xsl:if>
+                                </xsl:otherwise>
+                            </xsl:choose>
 
-                        </xsl:when>
-                        <!-- End of Array handling of ADB classes -->
-                        <xsl:otherwise>
-                            <xsl:if test="position()>1">
-                            // Move to a start element
-                            event = reader.getEventType();
-                            while (event!= javax.xml.stream.XMLStreamReader.START_ELEMENT) {
-                                event = reader.next();
                             }
-                            </xsl:if>
-                           <!-- Start of Array handling of simple types -->
-                            org.apache.axis2.databinding.utils.SimpleArrayReaderStateMachine <xsl:value-of select="$stateMachineName"/> = new
-                                                            org.apache.axis2.databinding.utils.SimpleArrayReaderStateMachine();
-                            <xsl:value-of select="$stateMachineName"/>.setElementNameToTest(new javax.xml.namespace.QName(
-                            "<xsl:value-of select="$namespace"/>",
-                            "<xsl:value-of select="$propertyName"/>"));
-                            <xsl:if test="@nillable">
-                               <xsl:value-of select="$stateMachineName"/>.setNillable();
-                            </xsl:if>
-                            <xsl:value-of select="$stateMachineName"/>.read(reader);
-                            java.lang.String[] textArray = <xsl:value-of select="$stateMachineName"/>.getTextArray();
-                            object.set<xsl:value-of select="$javaName"/>(
-                             (<xsl:value-of select="$propertyType"/>)
-                               org.apache.axis2.databinding.utils.ConverterUtil.convertToArray(
-                               <xsl:value-of select="$basePropertyType"/>.class,<xsl:value-of select="$stateMachineName"/>.getTextArray()));
-
-                           <!-- end of Array handling of simple types -->
-                        </xsl:otherwise>
-                    </xsl:choose>
-             </xsl:when>
-             <!--  end of array handling -->
-
-             <!-- start of adb handling-->
-              <xsl:when test="@ours">
 
-                  object.set<xsl:value-of select="$javaName"/>(
-                  <xsl:value-of select="$propertyType"/>.Factory.parse(reader));
-
-
-              </xsl:when>
-
-              <!-- start of any handling. Any can also be @default so we need to
-        handle the any case before default! -->
-              <xsl:when test="@any">
-                  <!--No concerns of being nillable here. if it's ours and if the nillable attribute was present
-                      we would have outputted a null already-->
-                   boolean <xsl:value-of select="$loopBoolName"/> = false;
-                   //move to the start element
-                   while(!<xsl:value-of select="$loopBoolName"/>){
-                    if (reader.isStartElement()){
-                        <xsl:value-of select="$loopBoolName"/> = true;
-                    }else{
-                        reader.next();
-                    }
-                }
+                        </xsl:for-each>
+                        else
+                            // A start element we are not expecting indicates an invalid parameter was passed
+                            throw new java.lang.RuntimeException("Unexpected subelement " + reader.getLocalName());
+                    } else reader.next();  <!-- At neither a start nor an end element, skip it -->
 
-                   <!--This can be any element and we may not know the name. so we pick the name of the
-                   element from the parser-->  
-                //use the QName from the parser as the name for the builder
-                javax.xml.namespace.QName <xsl:value-of select="$startQname"/> = reader.getName();
-
-                // We need to wrap the reader so that it produces a fake START_DOCUEMENT event
-                // this is needed by the builder classes
-                org.apache.axis2.databinding.utils.NamedStaxOMBuilder <xsl:value-of select="$builderName"/> = new org.apache.axis2.databinding.utils.NamedStaxOMBuilder(
-                        new org.apache.axis2.util.StreamWrapper(reader),<xsl:value-of select="$startQname"/>);
-                object.set<xsl:value-of select="$javaName"/>(<xsl:value-of select="$builderName"/>.getOMElement());
-
-
-              </xsl:when>
-              <!-- end of adb type handling code -->
-              <!-- start of OMelement handling -->
-               <xsl:when test="@default">
-                boolean <xsl:value-of select="$loopBoolName"/> = false;
-                javax.xml.namespace.QName <xsl:value-of select="$startQname"/> = new javax.xml.namespace.QName(
-                                                       "<xsl:value-of select="$namespace"/>",
-                                                       "<xsl:value-of select="$propertyName"/>");
-
-                while(!<xsl:value-of select="$loopBoolName"/>){
-                    if (reader.isStartElement() &amp;&amp; <xsl:value-of select="$startQname"/>.equals(reader.getName())){
-                        <xsl:value-of select="$loopBoolName"/> = true;
-                    }else{
-                        reader.next();
-                    }
                 }
 
-                <!-- todo  put the code here for nillable -->
-                // We need to wrap the reader so that it produces a fake START_DOCUEMENT event
-                // this is needed by the builder classes
-                org.apache.axis2.databinding.utils.NamedStaxOMBuilder <xsl:value-of select="$builderName"/> = new org.apache.axis2.databinding.utils.NamedStaxOMBuilder(
-                        new org.apache.axis2.util.StreamWrapper(reader),<xsl:value-of select="$startQname"/>);
-                object.set<xsl:value-of select="$javaName"/>(<xsl:value-of select="$builderName"/>.getOMElement());
-
-                //step one more event from the current position
-                reader.next();
-              </xsl:when>
-              <!-- end of OMelement handling -->
-              <!-- start of the simple types handling -->
-              <xsl:otherwise>
-                  <xsl:if test="position()>1">
-                      // Move to a start element
-                      event = reader.getEventType();
-                      while (event!= javax.xml.stream.XMLStreamReader.START_ELEMENT) {
-                        event = reader.next();
-                      }
-                  </xsl:if>
-                org.apache.axis2.databinding.utils.SimpleElementReaderStateMachine <xsl:value-of select="$stateMachineName"/>
-                  = new org.apache.axis2.databinding.utils.SimpleElementReaderStateMachine();
-                javax.xml.namespace.QName <xsl:value-of select="$startQname"/> = new javax.xml.namespace.QName(
-                                     "<xsl:value-of select="$namespace"/>",
-                                    "<xsl:value-of select="$propertyName"/>");
-                <xsl:value-of select="$stateMachineName"/>.setElementNameToTest(<xsl:value-of select="$startQname"/>);
-                <xsl:if test="@nillable">
-                        <xsl:value-of select="$stateMachineName"/>.setNillable();
-                </xsl:if>
-                <xsl:value-of select="$stateMachineName"/>.read(reader);
-                object.set<xsl:value-of select="$javaName"/>(
-                  <xsl:choose>
-                      <xsl:when test="@nillable and not(@primitive)">
-                           <xsl:value-of select="$stateMachineName"/>.getText()==null?null:
-                             org.apache.axis2.databinding.utils.ConverterUtil.convertTo<xsl:value-of select="$shortTypeName"/>(
-                           <xsl:value-of select="$stateMachineName"/>.getText()));
-                      </xsl:when>
-                      <xsl:otherwise>
-                     org.apache.axis2.databinding.utils.ConverterUtil.convertTo<xsl:value-of select="$shortTypeName"/>(
-                           <xsl:value-of select="$stateMachineName"/>.getText()));
-                      </xsl:otherwise>
-                  </xsl:choose>
-
-              </xsl:otherwise>
-               <!-- end of simple type handling -->
-
-            </xsl:choose>
+            } catch (javax.xml.stream.XMLStreamException e) {
+                throw new java.lang.Exception(e);
+            }
 
-         </xsl:for-each>
-        } catch (javax.xml.stream.XMLStreamException e) {
-             throw new java.lang.Exception(e);
+            return object;
         }
 
-        return object;
-        }
         }//end of factory class
 
         }
diff -urx .svn codegen.src.orig/org/apache/axis2/schema/writer/BeanWriter.java codegen.src.new/org/apache/axis2/schema/writer/BeanWriter.java
--- codegen.src.orig/org/apache/axis2/schema/writer/BeanWriter.java	2006-03-25 12:23:50.000000000 -1000
+++ codegen.src.new/org/apache/axis2/schema/writer/BeanWriter.java	2006-03-25 21:55:26.000000000 -1000
@@ -1,5 +1,6 @@
 package org.apache.axis2.schema.writer;
 
+import javax.xml.namespace.QName;
 import org.apache.axis2.schema.BeanWriterMetaInfoHolder;
 import org.apache.axis2.schema.CompilerOptions;
 import org.apache.axis2.schema.SchemaCompilationException;
@@ -51,6 +52,12 @@
      * of the schema compiler may be exposed.
      */
     public Map getModelMap();
+    
+    /** Make the fully qualified class name for an element or named type
+     * @param qName the qualified Name for this element or type in the schema
+     * @return the appropriate fully qualified class name to use in generated code
+     */
+    public String makeFullyQualifiedClassName(QName qName);
 
     /**
      * Write a complex type
@@ -58,10 +65,12 @@
      * @param complexType
      * @param typeMap
      * @param metainf
+     * @param fullyQualifiedClassName the name returned by makeFullyQualifiedClassName() or null if it wasn't called
      * @return Returns String.
      * @throws SchemaCompilationException
      */
-    public String write(XmlSchemaComplexType complexType, Map typeMap, BeanWriterMetaInfoHolder metainf) throws SchemaCompilationException;
+    public String write(XmlSchemaComplexType complexType, Map typeMap, BeanWriterMetaInfoHolder metainf, String fullyQualifiedClassName)
+    throws SchemaCompilationException;
 
     /**
      * Write a element
diff -urx .svn codegen.src.orig/org/apache/axis2/schema/writer/JavaBeanWriter.java codegen.src.new/org/apache/axis2/schema/writer/JavaBeanWriter.java
--- codegen.src.orig/org/apache/axis2/schema/writer/JavaBeanWriter.java	2006-03-25 12:23:50.000000000 -1000
+++ codegen.src.new/org/apache/axis2/schema/writer/JavaBeanWriter.java	2006-03-25 21:55:26.000000000 -1000
@@ -143,7 +143,7 @@
         try {
             QName qName = element.getQName();
 
-            return process(qName, metainf, typeMap, true);
+            return process(qName, metainf, typeMap, true, null);
         } catch (Exception e) {
             throw new SchemaCompilationException(e);
         }
@@ -155,16 +155,18 @@
      * @param complexType
      * @param typeMap
      * @param metainf
+     * @param fullyQualifiedClassName the name returned by makeFullyQualifiedClassName() or null if it wasn't called
      * @throws org.apache.axis2.schema.SchemaCompilationException
      *
      * @see BeanWriter#write(org.apache.ws.commons.schema.XmlSchemaComplexType, java.util.Map, org.apache.axis2.schema.BeanWriterMetaInfoHolder)
      */
-    public String write(XmlSchemaComplexType complexType, Map typeMap, BeanWriterMetaInfoHolder metainf) throws SchemaCompilationException {
+    public String write(XmlSchemaComplexType complexType, Map typeMap, BeanWriterMetaInfoHolder metainf, String fullyQualifiedClassName)
+    throws SchemaCompilationException {
 
         try {
             //determine the package for this type.
             QName qName = complexType.getQName();
-            return process(qName, metainf, typeMap, false);
+            return process(qName, metainf, typeMap, false, fullyQualifiedClassName);
 
         } catch (SchemaCompilationException e) {
             throw e;
@@ -228,6 +230,36 @@
     }
 
 
+    /** Make the fully qualified class name for an element or named type
+     * @param qName the qualified Name for this element or type in the schema
+     * @return the appropriate fully qualified class name to use in generated code
+     */
+    public String makeFullyQualifiedClassName(QName qName) {
+
+        String nameSpaceFromURL = URLProcessor.makePackageName(qName.getNamespaceURI());
+
+        String packageName = this.packageName == null ?
+                nameSpaceFromURL :
+                this.packageName + nameSpaceFromURL;
+
+        String originalName = qName.getLocalPart();
+        String className = makeUniqueJavaClassName(this.namesList, originalName);
+
+        String packagePrefix = null;
+
+        String fullyqualifiedClassName;
+        if (wrapClasses)
+            packagePrefix =  (this.packageName == null ? DEFAULT_PACKAGE+"." : this.packageName) + WRAPPED_DATABINDING_CLASS_NAME;
+        else if (writeClasses)
+            packagePrefix = packageName;
+        if (packagePrefix!=null)
+            fullyqualifiedClassName = packagePrefix + (packagePrefix.endsWith(".")?"":".") + className;
+        else
+            fullyqualifiedClassName = className;
+        //return the fully qualified class name
+        return fullyqualifiedClassName;
+    }
+    
     /**
      * A util method that holds common code
      * for the complete schema that the generated XML complies to
@@ -237,10 +269,15 @@
      * @param metainf
      * @param typeMap
      * @param isElement
+     * @param fullyQualifiedClassName the name returned by makeFullyQualifiedClassName() or null if it wasn't called
      * @return Returns String.
      * @throws Exception
      */
-    private String process(QName qName, BeanWriterMetaInfoHolder metainf, Map typeMap, boolean isElement) throws Exception {
+    private String process(QName qName, BeanWriterMetaInfoHolder metainf, Map typeMap, boolean isElement, String fullyQualifiedClassName) throws Exception {
+        
+        if (fullyQualifiedClassName == null)
+            fullyQualifiedClassName = makeFullyQualifiedClassName(qName);
+        String className = fullyQualifiedClassName.substring(1+fullyQualifiedClassName.lastIndexOf('.'));
 
         String nameSpaceFromURL = URLProcessor.makePackageName(qName.getNamespaceURI());
 
@@ -249,11 +286,7 @@
                 this.packageName + nameSpaceFromURL;
 
         String originalName = qName.getLocalPart();
-        String className = makeUniqueJavaClassName(this.namesList, originalName);
-
-        String packagePrefix = null;
 
-        String fullyqualifiedClassName;
         ArrayList propertyNames = new ArrayList();
 
         if (!templateLoaded) {
@@ -266,7 +299,6 @@
             globalWrappedDocument.getDocumentElement().appendChild(
                     getBeanElement(globalWrappedDocument, className, originalName, packageName, qName, isElement, metainf, propertyNames, typeMap)
             );
-            packagePrefix =  (this.packageName == null ? DEFAULT_PACKAGE+"." : this.packageName) + WRAPPED_DATABINDING_CLASS_NAME;
 
         } else {
             //create the model
@@ -279,8 +311,6 @@
                 File out = createOutFile(packageName, className);
                 //parse with the template and create the files
                 parse(model, out);
-
-                packagePrefix = packageName ;
             }
 
             //add the model to the model map
@@ -291,13 +321,8 @@
 
         }
 
-        if (packagePrefix!=null){
-            fullyqualifiedClassName = packagePrefix + (packagePrefix.endsWith(".")?"":".") + className;
-        }else{
-            fullyqualifiedClassName = className;
-        }
         //return the fully qualified class name
-        return fullyqualifiedClassName;
+        return fullyQualifiedClassName;
 
     }
 

Reply via email to