Hi Ajith and all,

I ran into another code generation problem.  minOccurs=0 elements are not supported in the 0 case.  I.e., for an optional element that is not present or a zero-length array, the parsing has bugs.  The core serialization in adb also fails to handle this case.  For the parsing (deserialization), the argumentCount mechanism in the generated parse() methods fails when no elements for a minOccurs=0 property are present.  For serialization,  the  next() method in the ADBPullParser fails to handle zero-length arrays as it assumes that every array-valued property has at least one element.

Also, I found another bug in the generated parse() methods.  If an element named foo has a subelement also named foo, and especially if the types of the two foo elements are different (e.g., one is complex and one is simple), then the parse() method fails.

I believe these issues are addressed in the attached patches, although they have only been lightly tested so far.  At least all the exceptions are gone and visual inspection of the serialized and deserialized results seems correct.  I'm sending this now because I know you are working on the code generator and want to bring these issues to your attention in case you have not already addressed them.  Our project will be heavily testing all of this in the coming week.

These fixes overlap with some of my earlier ones, so I can't create separate patches now.  The attached files are consolidated patches to fix all of these issues:
  1. Add support for choice particles
  2. Add support for recursive data types
  3. Add support for minOccurs=0 elements in the 0 case (i.e., where no elements for the property are present)
  4. Fix bug where a subelement with the same name as its parent element, but different types, was confused by the parse() methods
codgen.patch applies to modules/codegen/src and adb.patch applies to modules/adb/src, both against Axis2 0.94 source distribution.

Chuck

diff -ur 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-04 22:55:03.000000000 -1000
+++ adb.src.new/org/apache/axis2/databinding/utils/ADBPullParser.java	2006-03-04 22:49:45.000000000 -1000
@@ -115,6 +115,21 @@
         this.elementQName = adbBeansQName;
         this.attributes = attributes;
         namespaceMap = new HashMap();
+        if (attributes==null || attributes.length==0) {
+            if (properties==null || properties.length==0)
+                isEndElementFinished = true;
+            else {
+                boolean allEmptyArrays = true;
+                for (int i=1; i<properties.length; i+=2) {
+                    if (!(properties[i] instanceof Object[] && ((Object[])properties[i]).length==0)) {
+                        allEmptyArrays = false;
+                        break;
+                    }
+                }
+                if (allEmptyArrays)
+                    isEndElementFinished = true;
+            }
+        }
     }
 
     /**
@@ -265,8 +280,12 @@
             if (o instanceof QName) {
                 Object object = properties[currentIndex];
                 if (object instanceof Object[]) {
-                    secondArrayIndex = 0;
                     complexArray = (Object[]) object;
+                    if (complexArray.length==0) {
+                        currentIndex += 2;
+                        return this.next();
+                    }
+                    secondArrayIndex = 0;
                     complexArrayQName = (QName) o;
                     getPullParser(complexArray[secondArrayIndex], complexArrayQName);
                     processingComplexArray = true;
@@ -286,8 +305,12 @@
 
                 if (property instanceof String[]) {
 
-                    complexStringArrayName = simplePropertyName;
                     complexStringArray = (String[]) property;
+                    if (complexStringArray.length==0) {
+                        currentIndex += 2;
+                        return this.next();
+                    }
+                    complexStringArrayName = simplePropertyName;
                     secondArrayIndex = 0;
                     processingComplexADBNameValuePair = true;
 
diff -urX exclude.files codegen.src.orig/org/apache/axis2/schema/BeanWriterMetaInfoHolder.java codegen.src.new/org/apache/axis2/schema/BeanWriterMetaInfoHolder.java
--- codegen.src.orig/org/apache/axis2/schema/BeanWriterMetaInfoHolder.java	2006-01-24 18:14:07.000000000 -1000
+++ codegen.src.new/org/apache/axis2/schema/BeanWriterMetaInfoHolder.java	2006-02-08 22:24:45.000000000 -1000
@@ -32,6 +32,7 @@
 
 
     private boolean ordered = false;
+    private boolean choice = false;
     private boolean anonymous = false;
     private boolean extension = false;
     private String extensionClassName = "";
@@ -115,6 +116,24 @@
     public void setOrdered(boolean ordered) {
         this.ordered = ordered;
     }
+        
+    /**
+     * Gets the choice status.
+     *
+     * @return Returns boolean.
+     */
+    public boolean isChoice() {
+        return choice;
+    }
+
+    /**
+     * Sets the choice flag. 
+     *
+     * @param choice
+     */
+    public void setChoice(boolean choice) {
+        this.choice = choice;
+    }
 
     /**
      * Registers a mapping.
diff -urX exclude.files 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-01-24 18:14:07.000000000 -1000
+++ codegen.src.new/org/apache/axis2/schema/SchemaCompiler.java	2006-03-02 23:53:47.000000000 -1000
@@ -404,6 +404,10 @@
                 || 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);
 
         XmlSchemaParticle particle = complexType.getParticle();
         BeanWriterMetaInfoHolder metaInfHolder = new BeanWriterMetaInfoHolder();
@@ -440,10 +444,7 @@
 
         //write the class. This type mapping would have been populated right now
         //Note - We always write classes for complex types
-        String fullyQualifiedClassName = writer.write(complexType, processedTypemap, metaInfHolder);
-        //populate the type mapping with the elements
-        processedTypemap.put(complexType.getQName(), fullyQualifiedClassName);
-
+        writer.write(complexType, processedTypemap, metaInfHolder, fullyQualifiedClassName);
 
     }
 
@@ -497,7 +498,9 @@
             XmlSchemaObjectCollection items = ((XmlSchemaAll) particle).getItems();
             process(items, metainfHolder, false);
         } else if (particle instanceof XmlSchemaChoice) {
-            //put the code here to handle the choice!
+            XmlSchemaObjectCollection items = ((XmlSchemaChoice) particle).getItems();
+            metainfHolder.setChoice(true);
+            process(items, metainfHolder, false);
         }
     }
 
diff -urX exclude.files 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-01-24 18:14:07.000000000 -1000
+++ codegen.src.new/org/apache/axis2/schema/template/ADBBeanTemplate.xsl	2006-03-04 15:20:10.000000000 -1000
@@ -32,6 +32,10 @@
     <xsl:template match="bean">
 
         <xsl:variable name="name"><xsl:value-of select="@name"/></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))">
@@ -50,7 +54,7 @@
         public <xsl:if test="not(@unwrapped) or (@skip-write)">static</xsl:if> class <xsl:value-of select="$name"/> <xsl:if test="@extension"> extends <xsl:value-of select="@extension"/></xsl:if>
         implements org.apache.axis2.databinding.ADBBean{
         <xsl:choose>
-            <xsl:when test="@type">/* This type was generated from the piece of schema that had
+            <xsl:when test="$isType">/* This type was generated from the piece of schema that had
                 name = <xsl:value-of select="@originalName"/>
                 Namespace URI = <xsl:value-of select="@nsuri"/>
                 Namespace Prefix = <xsl:value-of select="@nsprefix"/>
@@ -64,8 +68,18 @@
 
             </xsl:otherwise>
         </xsl:choose>
-
-
+        
+        <xsl:if test="$choice">
+            /** Whenever a new property is set ensure all others are unset
+             *  There can be only one choice and the last one wins
+             */
+            private void clearAllSettingTrackers() {
+            <xsl:for-each select="property">
+                local<xsl:value-of select="@javaname"/>Tracker = false;
+            </xsl:for-each>
+            }
+        </xsl:if>
+        
         <xsl:for-each select="property">
             <xsl:variable name="propertyType"><xsl:value-of select="@type"></xsl:value-of></xsl:variable>
             <xsl:variable name="propertyName"><xsl:value-of select="@name"></xsl:value-of></xsl:variable>
@@ -81,7 +95,7 @@
             private <xsl:value-of select="$propertyType"/><xsl:text> </xsl:text><xsl:value-of select="$varName" /> ;
             <!-- Generate a tracker only if the min occurs is zero, which means if the user does
                  not bother to set that value, we do not send it -->
-            <xsl:if test="$min=0">
+            <xsl:if test="($min=0) or $choice">
             /*  This tracker boolean wil be used to detect whether the user called the set method
                 for this attribute. It will be used to determine whether to include this field
                 in the serialized XML
@@ -115,10 +129,13 @@
                     }
                 </xsl:if>
             </xsl:if>
-             <xsl:if test="$min=0">
-             //update the setting tracker
-             <xsl:value-of select="$settingTracker"/> = true;
-             </xsl:if>
+            <xsl:if test="$choice">
+                clearAllSettingTrackers();
+            </xsl:if>
+            <xsl:if test="($min=0) or $choice">
+                //update the setting tracker
+                <xsl:value-of select="$settingTracker"/> = true;
+            </xsl:if>
             this.<xsl:value-of select="$varName"/>=param;
             }
         </xsl:for-each>
@@ -131,7 +148,7 @@
 
 
         <xsl:choose>
-            <xsl:when test="@type|@anon">
+            <xsl:when test="$isType or $anon">
                  java.util.ArrayList elementList = new java.util.ArrayList();
                  java.util.ArrayList attribList = new java.util.ArrayList();
 
@@ -143,7 +160,7 @@
                     <xsl:variable name="settingTracker">local<xsl:value-of select="@javaname"/>Tracker</xsl:variable>
 
 
-                    <xsl:if test="$min=0"> if (<xsl:value-of select="$settingTracker"/>){</xsl:if>
+                    <xsl:if test="($min=0) or $choice"> if (<xsl:value-of select="$settingTracker"/>){</xsl:if>
                     <xsl:choose>
                         <xsl:when test="@ours or @any">
                             elementList.add(new javax.xml.namespace.QName("<xsl:value-of select="$namespace"/>",
@@ -160,7 +177,7 @@
                              elementList.add(org.apache.axis2.databinding.utils.ConverterUtil.convertToString(<xsl:value-of select="$varName"/>));
                         </xsl:otherwise>
                     </xsl:choose>
-                    <xsl:if test="$min=0">}</xsl:if>
+                    <xsl:if test="($min=0) or $choice">}</xsl:if>
                 </xsl:for-each>
 
                 <xsl:for-each select="[EMAIL PROTECTED]">
@@ -214,140 +231,133 @@
         * Note -  This is not complete
         */
         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();
-        int count = 0;
-        int argumentCount = <xsl:value-of select="count(property)"/> ;
-        boolean done =false;
-        //event better be a START_ELEMENT. if not we should go up to the start element here
-        while (!reader.isStartElement()){
-        event = reader.next();
-        }
-        <!-- 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()"></xsl:value-of> = new java.util.ArrayList(5000);
-            </xsl:if>
-        </xsl:for-each>
-        while(!done){
-        if (javax.xml.stream.XMLStreamConstants.START_ELEMENT==event){
-        <!-- 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: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="$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: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"/>.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"/>.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:otherwise>
+                                            <xsl:value-of select="$listName"/>.add(reader.getElementText());
+                                            //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(reader.getElementText());
+                                                    }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"/>.parse(reader));
+                                    <xsl:if test="$isType or $anon">  <!-- This is a subelement property to be consumed -->
+                                        reader.next();
+                                    </xsl:if>
+                                </xsl:when>
+                                <xsl:when test="@any">
+                                    //any not supported yet!!!!
+                                    throw new UnsupportedOperationException();
+                                </xsl:when>
+                                <xsl:otherwise>
+                                    String content = reader.getElementText();
+                                    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();
+                                    </xsl:if>
+                                </xsl:otherwise>
+                            </xsl:choose>
 
-            if ("<xsl:value-of select="$propertyName"/>".equals(reader.getLocalName())){
-            <xsl:choose>
-                <xsl:when test="@array">
-                    <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"/>.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"/>){
-                            //loop to the end element
-                            while (!reader.isEndElement()){
-                            event = reader.next();
-                            }
-                            //step one event
-                            event = 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"/>.parse(reader));
-                            }else{
-                            <xsl:value-of select="$loopBoolName"/> = true;
-                            }
-                            }
                             }
 
+                        </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 -->
 
-                            // 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"/>));
-
-                            count++;
-                        </xsl:when>
-                        <xsl:otherwise>
-                            <xsl:value-of select="$listName"/>.add(reader.getElementText());
-                            //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"/>){
-                            //loop to the end element
-                            while (!reader.isEndElement()){
-                            event = reader.next();
-                            }
-                            //step one event
-                            event = 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(reader.getElementText());
-                            }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"/>));
-                            count++;
-                        </xsl:otherwise>
-                    </xsl:choose>
-                </xsl:when>
-                <xsl:when test="@ours">
-                    object.set<xsl:value-of select="$javaName"/>(
-                    <xsl:value-of select="$propertyType"/>.parse(reader));
-                    count++;
-                </xsl:when>
-                <xsl:when test="@any">
-                    //do nothing yet!!!!
-                </xsl:when>
-                <xsl:otherwise>
-                    String content = reader.getElementText();
-                    object.set<xsl:value-of select="$javaName"/>(
-                    org.apache.axis2.databinding.utils.ConverterUtil.convertTo<xsl:value-of select="$shortTypeName"/>(content));
-                    count++;
-                </xsl:otherwise>
-            </xsl:choose>
+                }
 
+            } catch (javax.xml.stream.XMLStreamException e) {
+                throw new java.lang.Exception(e);
             }
 
-        </xsl:for-each>
-        }
-
-        if (argumentCount==count){
-        done=true;
-        }
-
-        if (!done){
-        event = reader.next();
-        }
-
-        }
-
-        } catch (javax.xml.stream.XMLStreamException e) {
-        throw new java.lang.Exception(e);
-        }
-
-        return object;
+            return object;
         }
 
         }
diff -urX exclude.files 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-01-24 18:14:07.000000000 -1000
+++ codegen.src.new/org/apache/axis2/schema/writer/BeanWriter.java	2006-03-02 23:54:38.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,11 @@
      * @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 exclude.files 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-01-24 18:14:07.000000000 -1000
+++ codegen.src.new/org/apache/axis2/schema/writer/JavaBeanWriter.java	2006-03-02 23:54:38.000000000 -1000
@@ -138,7 +138,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);
         }
@@ -150,16 +150,17 @@
      * @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;
@@ -223,6 +224,31 @@
     }
 
 
+    /** 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
@@ -235,7 +261,11 @@
      * @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());
 
@@ -244,11 +274,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) {
@@ -261,7 +287,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
@@ -275,7 +300,6 @@
                 //parse with the template and create the files
                 parse(model, out);
 
-                packagePrefix = packageName ;
             }
 
             //add the model to the model map
@@ -286,11 +310,6 @@
 
         }
 
-        if (packagePrefix!=null){
-            fullyqualifiedClassName = packagePrefix + (packagePrefix.endsWith(".")?"":".") + className;
-        }else{
-            fullyqualifiedClassName = className;
-        }
         //return the fully qualified class name
         return fullyqualifiedClassName;
 
@@ -342,6 +361,11 @@
         if (metainf.isExtension()) {
             XSLTUtils.addAttribute(model, "extension", metainf.getExtensionClassName(), rootElt);
         }
+        
+        if (metainf.isChoice()) {
+            XSLTUtils.addAttribute(model, "choice", "yes", rootElt);
+        }
+        
         // go in the loop and add the part elements
         QName[] qNames;
         if (metainf.isOrdered()) {

Reply via email to