xmlbeans-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From david...@apache.org
Subject cvs commit: xml-xmlbeans/v2/test/src/drt/drtcases BindingTests.java
Date Mon, 27 Oct 2003 19:17:22 GMT
davidbau    2003/10/27 11:17:22

  Modified:    v2       build.xml
               v2/src/binding/org/apache/xmlbeans/impl/binding/bts
                        BindingFile.java BindingProperty.java
                        BindingType.java JavaName.java XmlName.java
               v2/src/typeimpl/org/apache/xmlbeans/impl/schema
                        SchemaTypeImpl.java
               v2/src/typeimpl/org/apache/xmlbeans/impl/values
                        XmlObjectBase.java
               v2/src/xmlstore/org/apache/xmlbeans/impl/store Splay.java
               v2/test/src/drt/drtcases BindingTests.java
  Added:       v2/src/binding/org/apache/xmlbeans/impl/binding/compile
                        BindingFileGenerator.java JAXRPCSchemaBinder.java
                        JavaCodeGenerator.java JavaCodePrinter.java
                        SchemaToJavaResult.java
               v2/test/cases/schema/typesonly typesonly.xsd
  Log:
  Okey dokey.  Here's a bit of JAX-RPC-style schema-java compilation code.
  A test case exercising it is in BindingTests.java, and the main class to
  do the compilation is JAXRPCSchemaBinder.java.
  
  It's currently capable of generating Java classes and binding config
  for simple structures; skeleton code for arrays and so on is in there,
  but not yet exercised.
  
  Code reviewed by: Pcal
  Regression tests: passed
  
  Revision  Changes    Path
  1.11      +1 -0      xml-xmlbeans/v2/build.xml
  
  Index: build.xml
  ===================================================================
  RCS file: /home/cvs/xml-xmlbeans/v2/build.xml,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- build.xml	23 Oct 2003 23:49:03 -0000	1.10
  +++ build.xml	27 Oct 2003 19:17:21 -0000	1.11
  @@ -764,6 +764,7 @@
   
     <path id="bootstrap.compile.path">
       <pathelement location="build/classes/xmlpublic"/>
  +    <pathelement location="build/lib/jsr173_07_api.jar"/>
     </path>
   
     <property name="bootstrap.compile.path" refid="bootstrap.compile.path"/>
  
  
  
  1.6       +18 -4     xml-xmlbeans/v2/src/binding/org/apache/xmlbeans/impl/binding/bts/BindingFile.java
  
  Index: BindingFile.java
  ===================================================================
  RCS file: /home/cvs/xml-xmlbeans/v2/src/binding/org/apache/xmlbeans/impl/binding/bts/BindingFile.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- BindingFile.java	22 Oct 2003 19:03:09 -0000	1.5
  +++ BindingFile.java	27 Oct 2003 19:17:21 -0000	1.6
  @@ -221,10 +221,24 @@
           }
       }
   
  -  public Collection getBindingTypes()
  -  {
  -    return Collections.unmodifiableCollection(bindingTypes.values());
  -  }
  +    public Collection getMappedJavaNames()
  +    {
  +        return Collections.unmodifiableCollection(this.xmlFromJava.keySet());
  +    }
   
  +    public Collection getPojoMappedXmlNames()
  +    {
  +        return Collections.unmodifiableCollection(this.javaFromXmlPojo.keySet());
  +    }
  +
  +    public Collection getXmlObjectMappedXmlNames()
  +    {
  +        return Collections.unmodifiableCollection(this.javaFromXmlObj.keySet());
  +    }
  +    
  +    public Collection getBindingTypes()
  +    {
  +        return Collections.unmodifiableCollection(bindingTypes.values());
  +    }
   
   }
  
  
  
  1.2       +10 -0     xml-xmlbeans/v2/src/binding/org/apache/xmlbeans/impl/binding/bts/BindingProperty.java
  
  Index: BindingProperty.java
  ===================================================================
  RCS file: /home/cvs/xml-xmlbeans/v2/src/binding/org/apache/xmlbeans/impl/binding/bts/BindingProperty.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- BindingProperty.java	10 Oct 2003 20:09:27 -0000	1.1
  +++ BindingProperty.java	27 Oct 2003 19:17:21 -0000	1.2
  @@ -132,6 +132,16 @@
           return loader.getBindingType(tJava, tXml);
       }
       
  +    public JavaName getJavaTypeName()
  +    {
  +        return tJava;
  +    }
  +    
  +    public XmlName getXmlTypeName()
  +    {
  +        return tXml;
  +    }
  +    
       public void setBindingType(BindingType bType)
       {
           this.tJava = bType.getJavaName();
  
  
  
  1.3       +0 -1      xml-xmlbeans/v2/src/binding/org/apache/xmlbeans/impl/binding/bts/BindingType.java
  
  Index: BindingType.java
  ===================================================================
  RCS file: /home/cvs/xml-xmlbeans/v2/src/binding/org/apache/xmlbeans/impl/binding/bts/BindingType.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- BindingType.java	22 Oct 2003 19:03:09 -0000	1.2
  +++ BindingType.java	27 Oct 2003 19:17:21 -0000	1.3
  @@ -121,7 +121,6 @@
           return isXmlObj;
       }
   
  -
       /* REGISTRY OF SUBCLASSES */
   
       private static final Class[] ctorArgs = new Class[] {org.apache.xmlbeans.x2003.x09.bindingConfig.BindingType.class};
  
  
  
  1.2       +13 -0     xml-xmlbeans/v2/src/binding/org/apache/xmlbeans/impl/binding/bts/JavaName.java
  
  Index: JavaName.java
  ===================================================================
  RCS file: /home/cvs/xml-xmlbeans/v2/src/binding/org/apache/xmlbeans/impl/binding/bts/JavaName.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- JavaName.java	10 Oct 2003 20:09:27 -0000	1.1
  +++ JavaName.java	27 Oct 2003 19:17:21 -0000	1.2
  @@ -85,6 +85,19 @@
       }
       
       /**
  +     * Builds a JavaName for the array containing items with
  +     * the given JavaName.
  +     */ 
  +    public static JavaName forArray(JavaName itemType, int depth)
  +    {
  +        // efficiency later
  +        String arrayBrackets = "";
  +        while (depth > 0)
  +            arrayBrackets += "[]";
  +        return forString(itemType.toString() + arrayBrackets);
  +    }
  +    
  +    /**
        * Do not use this constructor; use forClassName instead.
        */ 
       private JavaName(String className)
  
  
  
  1.2       +204 -31   xml-xmlbeans/v2/src/binding/org/apache/xmlbeans/impl/binding/bts/XmlName.java
  
  Index: XmlName.java
  ===================================================================
  RCS file: /home/cvs/xml-xmlbeans/v2/src/binding/org/apache/xmlbeans/impl/binding/bts/XmlName.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- XmlName.java	10 Oct 2003 20:09:27 -0000	1.1
  +++ XmlName.java	27 Oct 2003 19:17:21 -0000	1.2
  @@ -6,6 +6,10 @@
   package org.apache.xmlbeans.impl.binding.bts;
   
   import org.apache.xmlbeans.impl.common.XMLChar;
  +import org.apache.xmlbeans.SchemaType;
  +import org.apache.xmlbeans.SchemaTypeLoader;
  +import org.apache.xmlbeans.XmlBeans;
  +import org.apache.xmlbeans.soap.SOAPArrayType;
   
   import javax.xml.namespace.QName;
   
  @@ -20,7 +24,7 @@
    * 
    * a-name1|t|e=name2|p.3|s|p.5|c|p.0|t|e=name3@my-namespace
    * 
  - * This reads as:
  + * This reads as:g
    * The attribute declaration called "name1" (unqualified) inside
    * the anonymous type of
    * the element declaration called "name2" (qualified) which is
  @@ -77,7 +81,7 @@
    * Notice SOAP arrays are included in the naming schema, as follows:
    * 
    * A soap array type written like this:
  - *     x:drg[,,,][,][,,,]
  + *     x:drg[,,,][,][,,]
    * 
    * Has the following signature:
    *     y.3|y.2|y.4|t=drg@foobar
  @@ -87,23 +91,24 @@
       private String namespace;
       private String path;
       
  -    public static final int NOTATION = 'n';
  -    public static final int ELEMENT = 'e';
  -    public static final int ID_CONSTRAINT = 'k';
  -    public static final int MODEL_GROUP = 'g';
  -    public static final int ALL = 'l';
  -    public static final int SEQUENCE = 's';
  -    public static final int CHOICE = 'c';
  -    public static final int PARTICLE = 'p';
  -    public static final int WILDCARD = 'w';
  -    public static final int ATTRIBUTE_USE = 'v';
  -    public static final int ATTRIBUTE = 'a';
  -    public static final int ATTRIBUTE_GROUP = 'r';
  -    public static final int TYPE = 't';
  -    public static final int DOCUMENT_TYPE = 'd';
  -    public static final int ATTRIBUTE_TYPE = 'b';
  -    public static final int MEMBER = 'm';
  -    public static final int SOAP_ARRAY = 'y';
  +    public static final char NOTATION = 'n';
  +    public static final char ELEMENT = 'e';
  +    public static final char ID_CONSTRAINT = 'k';
  +    public static final char MODEL_GROUP = 'g';
  +    public static final char ALL = 'l';
  +    public static final char SEQUENCE = 's';
  +    public static final char CHOICE = 'c';
  +    public static final char PARTICLE = 'p';
  +    public static final char WILDCARD = 'w';
  +    public static final char ATTRIBUTE_USE = 'v';
  +    public static final char ATTRIBUTE = 'a';
  +    public static final char ATTRIBUTE_GROUP = 'r';
  +    public static final char TYPE = 't';
  +    public static final char DOCUMENT_TYPE = 'd';
  +    public static final char ATTRIBUTE_TYPE = 'b';
  +    public static final char MEMBER = 'm';
  +    public static final char SOAP_ARRAY = 'y';
  +    public static final char NO_TYPE = 'z';
       
       /**
        * This function is used to see if a path is valid or not.
  @@ -118,7 +123,7 @@
           boolean hasName = (localName != null);
           boolean isAnonymous = internalIsAnonymous();
           boolean isQualified = internalIsQualified();
  -        boolean isGlobal = !isNestedComponent();
  +        boolean isGlobal = isGlobal();
       
           if (!isGlobal)
           {
  @@ -135,50 +140,69 @@
           {
               case NOTATION:
                   result = (isGlobal && hasName && isQualified);
  +                break;
                   
               case ELEMENT:
                   result = (hasName && (isGlobal && isQualified || outerType == TYPE || outerType == PARTICLE));
  +                break;
                   
               case ID_CONSTRAINT:
                   result = (hasName && outerType == ELEMENT);
  +                break;
                   
               case MODEL_GROUP:
                   result = (hasName && isGlobal);
  +                break;
                   
               case ALL:
               case SEQUENCE:
               case CHOICE:
                   result = (isAnonymous && (outerType == PARTICLE || outerType == MODEL_GROUP));
  +                break;
                   
               case PARTICLE:
                   result = (hasNumber && (outerType == SEQUENCE || outerType == CHOICE || outerType == ALL || outerType == TYPE));
  +                break;
                   
               case WILDCARD:
                   result = (isAnonymous && (outerType == PARTICLE || outerType == TYPE || outerType == ATTRIBUTE_GROUP));
  +                break;
                   
               case ATTRIBUTE_USE:
                   result = (hasName && (outerType == TYPE || outerType == ATTRIBUTE_GROUP));
  +                break;
                   
               case ATTRIBUTE:
                   result = (hasName && (isGlobal && isQualified || outerType == TYPE || outerType == ATTRIBUTE_USE));
  +                break;
                   
               case ATTRIBUTE_GROUP:
                   result = (hasName && isQualified && isGlobal);
  +                break;
                   
               case TYPE:
                   result = ((hasName && isQualified && isGlobal) || (isAnonymous && outerType == TYPE || outerType == ELEMENT || outerType == ATTRIBUTE || outerType == MEMBER));
  +                break;
                   
               case DOCUMENT_TYPE:
                   result = (hasName && isQualified && isGlobal);
  +                break;
                   
               case ATTRIBUTE_TYPE:
                   result = (hasName && isQualified && isGlobal);
  +                break;
                   
               case MEMBER:
                   result = (isAnonymous && outerType == TYPE);
  +                break;
                   
               case SOAP_ARRAY:
  -                result = (hasNumber && (outerType == SOAP_ARRAY || outerType == TYPE && !outerComponent.isNestedComponent()));
  +                result = (hasNumber && (outerType == SOAP_ARRAY || outerType == TYPE && outerComponent.isGlobal()));
  +                break;
  +                
  +            case NO_TYPE:
  +                result = (isAnonymous && isGlobal && namespace.length() == 0);
  +                break;
                   
               default:
                   result = false;
  @@ -220,25 +244,174 @@
        */ 
       public static XmlName forTypeNamed(QName name)
       {
  -        return forPathAndNamespace("t=" + name.getLocalPart(), name.getNamespaceURI());
  +        return forPathAndNamespace(TYPE + "=" + name.getLocalPart(), name.getNamespaceURI());
       }
       
       /**
        * Creates an XMLName for a global schema element with the given fully-qualified QName.
        */ 
  -    public static XmlName forElementNamed(QName name)
  +    public static XmlName forGlobalName(char kind, QName name)
       {
  -        return forPathAndNamespace("e=" + name.getLocalPart(), name.getNamespaceURI());
  +        return forPathAndNamespace(kind + "=" + name.getLocalPart(), name.getNamespaceURI());
       }
       
       /**
  -     * Creates an XMLName for a global schema attribute with the given fully-qualified QName.
  -     */ 
  -    public static XmlName forAttributeNamed(QName name)
  +     * Creates an XMLName for a nested component
  +     */
  +    public static XmlName forNestedName(char kind, String localName, boolean qualified, XmlName outer)
  +    {
  +        return forPathAndNamespace(kind + (qualified ? "=" : "-") + localName + "|" + outer.path, outer.namespace);
  +    }
  +    
  +    /**
  +     * Creates an XMLName for a nested component
  +     */
  +    public static XmlName forNestedNumber(char kind, int n, XmlName outer)
  +    {
  +        return forPathAndNamespace(kind + "." + n + "|" + outer.path, outer.namespace);
  +    }
  +
  +    /**
  +     * Creates an XMLName for a nested component
  +     */
  +    public static XmlName forNestedAnonymous(char kind, XmlName outer)
  +    {
  +        return forPathAndNamespace(kind + "|" + outer.path, outer.namespace);
  +    }
  +
  +    /**
  +     * Creates an XMLName for a particular schema type
  +     */
  +    public static XmlName forSchemaType(SchemaType sType)
  +    {
  +        if (sType.getName() != null)
  +            return forTypeNamed(sType.getName());
  +
  +        if (sType.isDocumentType())
  +            return forGlobalName(DOCUMENT_TYPE, sType.getDocumentElementName());
  +
  +        if (sType.isAttributeType())
  +            return forGlobalName(ATTRIBUTE_TYPE, sType.getAttributeTypeAttributeName());
  +
  +        if (sType.isNoType() || sType.getOuterType() == null) // latter is an error
  +            return forPathAndNamespace("" + NO_TYPE, "");
  +        
  +        SchemaType outerType = sType.getOuterType();
  +        XmlName outerName = forSchemaType(outerType);
  +        
  +        if (sType.getContainerField() != null)
  +        {
  +            boolean qualified = sType.getContainerField().getName().getNamespaceURI().length() > 0;
  +            String localName = sType.getContainerField().getName().getLocalPart();
  +            char kind = (sType.getContainerField().isAttribute() ? ATTRIBUTE : ELEMENT);
  +            return forNestedAnonymous(TYPE, forNestedName(kind, localName, qualified, outerName));
  +        }
  +        
  +        if (outerType.getSimpleVariety() == SchemaType.UNION)
  +            return forNestedAnonymous(TYPE, forNestedNumber(MEMBER, sType.getAnonymousUnionMemberOrdinal(), outerName));
  +        
  +        return forNestedAnonymous(TYPE, outerName);
  +    }
  +    
  +    /**
  +     * Creates one for a SOAPArrayType
  +     */
  +    public static XmlName forSoapArrayType(SOAPArrayType sType)
  +    {
  +        StringBuffer sb = new StringBuffer();
  +        sb.append(SOAP_ARRAY + "." + sType.getDimensions().length);
  +        int[] ranks = sType.getRanks();
  +        for (int i = ranks.length - 1; i >= 0; i-= 1)
  +        {
  +            sb.append("|" + SOAP_ARRAY + "." + ranks[i]);
  +        }
  +        QName name = sType.getQName();
  +        sb.append("|" + TYPE + "=" + name.getLocalPart());
  +        return forPathAndNamespace(sb.toString(), name.getNamespaceURI());
  +    }
  +    
  +    /**
  +     * True if it is a schema type
  +     */
  +    public boolean isSchemaType()
       {
  -        return forPathAndNamespace("a=" + name.getLocalPart(), name.getNamespaceURI());
  +        switch (getComponentType())
  +        {
  +            case TYPE:
  +            case DOCUMENT_TYPE:
  +            case ATTRIBUTE_TYPE:
  +            case NO_TYPE:
  +                return true;
  +            default:
  +                return false;
  +        }
       }
  +    
  +    /**
  +     * Finds a type with the given name.
  +     */
  +    public SchemaType findTypeIn(SchemaTypeLoader loader)
  +    {
  +        switch (getComponentType())
  +        {
  +            case NO_TYPE:
  +                return XmlBeans.NO_TYPE;
  +            case DOCUMENT_TYPE:
  +                return loader.findDocumentType(getQName());
  +            case ATTRIBUTE_TYPE:
  +                return loader.findAttributeType(getQName());
  +            default:
  +                return null;
  +            case TYPE:
  +                break;
  +        }
  +        
  +        if (isGlobal())
  +            return loader.findType(getQName());
   
  +        XmlName outerName = getOuterComponent();
  +        
  +        // if the component is contained within a type, get it
  +        for (XmlName outerTypeName = outerName; ; outerTypeName = outerTypeName.getOuterComponent())
  +        {
  +            if (outerTypeName.isSchemaType())
  +            {
  +                SchemaType outerType = outerTypeName.findTypeIn(loader);
  +                switch (outerName.getComponentType())
  +                {
  +                    default:
  +                        throw new IllegalStateException("Illegal type name " + this);
  +                
  +                    case TYPE:
  +                        return outerType.getAnonymousTypes()[0];
  +                
  +                    case ELEMENT:
  +                        return outerType.getElementType(outerName.getQName(), null, loader);
  +                        
  +                    case ATTRIBUTE:
  +                        return outerType.getAttributeType(outerName.getQName(), loader);
  +                
  +                    case MEMBER:
  +                        return outerType.getAnonymousTypes()[outerName.getNumber()];
  +                }
  +            }
  +            if (outerTypeName.isGlobal())
  +            {
  +                switch (outerName.getComponentType())
  +                {
  +                    default:
  +                        throw new IllegalStateException("Illegal type name " + this);
  +                
  +                    case ELEMENT:
  +                        return loader.findDocumentType(outerTypeName.getQName()).getElementType(outerTypeName.getQName(), null, loader);
  +                        
  +                    case ATTRIBUTE:
  +                        return loader.findAttributeType(outerTypeName.getQName()).getAttributeType(outerTypeName.getQName(), loader);
  +                }
  +            }
  +        }
  +    }
  +    
       private static XmlName forPathAndNamespace(String path, String namespace)
       {
           return new XmlName(path, namespace);
  @@ -253,13 +426,13 @@
           this.namespace = namespace;
       }
       
  -    boolean isNestedComponent()
  +    public boolean isGlobal()
       {
           int index = path.indexOf('|');
  -        return index >= 0;
  +        return index < 0;
       }
       
  -    XmlName getOuterComponent()
  +    public XmlName getOuterComponent()
       {
           int index = path.indexOf('|');
           if (index < 0)
  
  
  
  1.1                  xml-xmlbeans/v2/src/binding/org/apache/xmlbeans/impl/binding/compile/BindingFileGenerator.java
  
  Index: BindingFileGenerator.java
  ===================================================================
  /*
  * The Apache Software License, Version 1.1
  *
  *
  * Copyright (c) 2003 The Apache Software Foundation.  All rights
  * reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
  *
  * 1. Redistributions of source code must retain the above copyright
  *    notice, this list of conditions and the following disclaimer.
  *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in
  *    the documentation and/or other materials provided with the
  *    distribution.
  *
  * 3. The end-user documentation included with the redistribution,
  *    if any, must include the following acknowledgment:
  *       "This product includes software developed by the
  *        Apache Software Foundation (http://www.apache.org/)."
  *    Alternately, this acknowledgment may appear in the software itself,
  *    if and wherever such third-party acknowledgments normally appear.
  *
  * 4. The names "Apache" and "Apache Software Foundation" must
  *    not be used to endorse or promote products derived from this
  *    software without prior written permission. For written
  *    permission, please contact apache@apache.org.
  *
  * 5. Products derived from this software may not be called "Apache
  *    XMLBeans", nor may "Apache" appear in their name, without prior
  *    written permission of the Apache Software Foundation.
  *
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  * ====================================================================
  *
  * This software consists of voluntary contributions made by many
  * individuals on behalf of the Apache Software Foundation and was
  * originally based on software copyright (c) 2003 BEA Systems
  * Inc., <http://www.bea.com/>. For more information on the Apache Software
  * Foundation, please see <http://www.apache.org/>.
  */
  
  package org.apache.xmlbeans.impl.binding.compile;
  
  import java.io.IOException;
  import java.io.OutputStream;
  
  public interface BindingFileGenerator
  {
      void printBindingFile(OutputStream output) throws IOException;
  }
  
  
  
  1.1                  xml-xmlbeans/v2/src/binding/org/apache/xmlbeans/impl/binding/compile/JAXRPCSchemaBinder.java
  
  Index: JAXRPCSchemaBinder.java
  ===================================================================
  /*
  * The Apache Software License, Version 1.1
  *
  *
  * Copyright (c) 2003 The Apache Software Foundation.  All rights
  * reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
  *
  * 1. Redistributions of source code must retain the above copyright
  *    notice, this list of conditions and the following disclaimer.
  *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in
  *    the documentation and/or other materials provided with the
  *    distribution.
  *
  * 3. The end-user documentation included with the redistribution,
  *    if any, must include the following acknowledgment:
  *       "This product includes software developed by the
  *        Apache Software Foundation (http://www.apache.org/)."
  *    Alternately, this acknowledgment may appear in the software itself,
  *    if and wherever such third-party acknowledgments normally appear.
  *
  * 4. The names "Apache" and "Apache Software Foundation" must
  *    not be used to endorse or promote products derived from this
  *    software without prior written permission. For written
  *    permission, please contact apache@apache.org.
  *
  * 5. Products derived from this software may not be called "Apache
  *    XMLBeans", nor may "Apache" appear in their name, without prior
  *    written permission of the Apache Software Foundation.
  *
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  * ====================================================================
  *
  * This software consists of voluntary contributions made by many
  * individuals on behalf of the Apache Software Foundation and was
  * originally based on software copyright (c) 2003 BEA Systems
  * Inc., <http://www.bea.com/>. For more information on the Apache Software
  * Foundation, please see <http://www.apache.org/>.
  */
  
  package org.apache.xmlbeans.impl.binding.compile;
  
  import org.apache.xmlbeans.impl.binding.bts.BindingFile;
  import org.apache.xmlbeans.impl.binding.bts.BindingType;
  import org.apache.xmlbeans.impl.binding.bts.BindingLoader;
  import org.apache.xmlbeans.impl.binding.bts.XmlName;
  import org.apache.xmlbeans.impl.binding.bts.JavaName;
  import org.apache.xmlbeans.impl.binding.bts.ByNameBean;
  import org.apache.xmlbeans.impl.binding.bts.QNameProperty;
  import org.apache.xmlbeans.impl.binding.bts.SimpleBindingType;
  import org.apache.xmlbeans.impl.binding.compile.BindingFileGenerator;
  import org.apache.xmlbeans.impl.binding.compile.JavaCodeGenerator;
  import org.apache.xmlbeans.impl.binding.compile.JavaCodePrinter;
  import org.apache.xmlbeans.impl.common.NameUtil;
  import org.apache.xmlbeans.SchemaType;
  import org.apache.xmlbeans.SchemaTypeSystem;
  import org.apache.xmlbeans.SchemaProperty;
  import org.apache.xmlbeans.SchemaLocalAttribute;
  import org.apache.xmlbeans.XmlObject;
  import org.apache.xmlbeans.XmlOptions;
  import org.apache.xmlbeans.soap.SOAPArrayType;
  import org.apache.xmlbeans.soap.SchemaWSDLArrayType;
  
  import javax.xml.namespace.QName;
  import java.util.ArrayList;
  import java.util.Arrays;
  import java.util.Iterator;
  import java.util.Map;
  import java.util.LinkedHashMap;
  import java.util.Collection;
  import java.util.HashSet;
  import java.util.Set;
  import java.util.HashMap;
  import java.util.Collections;
  import java.util.AbstractCollection;
  import java.util.List;
  import java.math.BigInteger;
  import java.io.OutputStream;
  import java.io.OutputStreamWriter;
  import java.io.Writer;
  import java.io.IOException;
  
  /**
   * This is the "JAXRPC-style" Schema-to-bts compiler.
   */ 
  public class JAXRPCSchemaBinder implements JavaCodeGenerator, BindingFileGenerator, SchemaToJavaResult
  {
      private Set usedNames = new HashSet();
      private SchemaTypeSystem sts;
      private Map scratchFromXmlName = new LinkedHashMap();
      private Map scratchFromSchemaType = new HashMap(); // for convenience
      private Map scratchFromJavaNameString = new HashMap(); // for printing
      private BindingLoader path;
      private int structureCount;
      private BindingFile bindingFile = new BindingFile();
  
      private JAXRPCSchemaBinder(SchemaTypeSystem sts, BindingLoader path)
      {
          this.sts = sts;
          this.path = path;
      }
      
      /**
       * Generates a binding for the given set of schema types.
       * 
       * Defer to any previously defined bindings on the BindingLoader path
       * supplied.
       */
      public static SchemaToJavaResult bind(SchemaTypeSystem sts, BindingLoader path)
      {
          JAXRPCSchemaBinder binder = new JAXRPCSchemaBinder(sts, path);
          binder.bind();
          return binder;
      }
      
      // build up four lists:
      // 1. types <-> java classes
      // 2. elements -> java classes
      // 3. attributes -> java classes
      // 4. java classes -> elements (may not be unique)
      
      // each complex type turns into a by-name-strucutre
      // each simple type turns into a simple-type-mapping
      // each element turns into a delegated-element-binding
      // each attribute turns into a delegated-attribute-binding
      
      // javaclass -> element entered only if unique, otherwise warning
      
      // each entry is:
      // 1. created
      // 2. resolved (properties figured out etc)
      // creation can happen at any time
      // resolution must occur after the base type is resolved
      
      private void bind()
      {
          // create a scratch area for every type AND SOAP Array
          createScratchArea();
          
          // resolve or generate all names of java classes
          for (Iterator i = scratchIterator(); i.hasNext(); )
          {
              Scratch scratch = (Scratch)i.next(); 
              resolveJavaName(scratch);
              createBindingType(scratch);
          }
          
          // resolve or generate all java structure
          for (Iterator i = scratchIterator(); i.hasNext(); )
          {
              resolveJavaStructure((Scratch)i.next());
          }
      }
  
      /**
       * This function goes through all relevant schema types, plus soap
       * array types, and creates a scratch area for each.  Each
       * scratch area is also marked at this time with an XmlName,
       * a schema type, and a category.
       */ 
      private void createScratchArea()
      {
          for (Iterator i = allTypeIterator(); i.hasNext(); )
          {
              SchemaType sType = (SchemaType)i.next();
              XmlName xmlName = XmlName.forSchemaType(sType);
              Scratch scratch;
              
              if (sType.isSimpleType())
              {
                  // simple types are atomic
                  // todo: what about simple content, custom codecs, etc?
                  scratch = new Scratch(sType, xmlName, Scratch.ATOMIC_TYPE);
              }
              else if (sType.isDocumentType())
              {
                  scratch = new Scratch(sType, XmlName.forGlobalName(XmlName.ELEMENT, sType.getDocumentElementName()), Scratch.ELEMENT);
              }
              else if (sType.isAttributeType())
              {
                  scratch = new Scratch(sType, XmlName.forGlobalName(XmlName.ATTRIBUTE, sType.getDocumentElementName()), Scratch.ELEMENT);
              }
              else if (isSoapArray(sType))
              {
                  scratch = new Scratch(sType, xmlName, Scratch.SOAPARRAY_REF);
                  xmlName = soapArrayTypeName(sType);
                  scratch.setAsIf(xmlName);
                  
                  // soap arrays unroll like this
                  while (xmlName.getComponentType() == XmlName.SOAP_ARRAY)
                  {
                      scratch = new Scratch(null, xmlName, Scratch.SOAPARRAY);
                      scratchFromXmlName.put(xmlName, scratch);
                      xmlName = xmlName.getOuterComponent();
                  }
              }
              else if (isLiteralArray(sType))
              {
                  scratch = new Scratch(sType, xmlName, Scratch.LITERALARRAY_TYPE);
              }
              else
              {
                  scratch = new Scratch(sType, xmlName, Scratch.STRUCT_TYPE);
              }
              
              scratchFromXmlName.put(xmlName, scratch);
              scratchFromSchemaType.put(sType, scratch);
              
          }
      }
      
      /**
       * Computes a JavaName for each scratch.  Notice that structures and
       * atoms can be computed directly, but arrays, elements, etc, need
       * to defer to other scratch areas, so this is a resolution
       * process that occurs in dependency order.
       */ 
      private void resolveJavaName(Scratch scratch)
      {
          // already resolved (we recurse to do in dependency order)
          if (scratch.getJavaName() != null)
              return;
          
          switch (scratch.getCategory())
          {
              case Scratch.ATOMIC_TYPE:
                  {
                      resolveSimpleScratch(scratch);
                      return;
                  }
                  
              case Scratch.STRUCT_TYPE:
                  {
                      structureCount += 1;
                      JavaName javaName = pickUniqueJavaName(scratch.getSchemaType());
                      scratch.setJavaName(javaName);
                      scratchFromJavaNameString.put(javaName.toString(), scratch);
                      return;
                  }
                  
              case Scratch.LITERALARRAY_TYPE:
                  {
                      SchemaType itemType = getLiteralArrayItemType(scratch.getSchemaType());
                      Scratch itemScratch = scratchForSchemaType(itemType);
                      resolveJavaName(itemScratch);
                      scratch.setJavaName(JavaName.forArray(itemScratch.getJavaName(), 1));
                      return;
                  }
                  
              case Scratch.SOAPARRAY_REF:
                  {
                      XmlName soapArrayName = scratch.getAsIf();
                      Scratch arrayScratch = scratchForXmlName(soapArrayName);
                      resolveJavaName(arrayScratch);
                      scratch.setJavaName(arrayScratch.getJavaName());
                      return;
                  }
                  
              case Scratch.SOAPARRAY:
                  {
                      XmlName arrayName = scratch.getXmlName();
                      XmlName itemName = arrayName.getOuterComponent();
                      Scratch itemScratch = scratchForXmlName(itemName);
                      resolveJavaName(itemScratch);
                      scratch.setJavaName(JavaName.forArray(itemScratch.getJavaName(), arrayName.getNumber()));
                      return;
                  }
                  
              case Scratch.ELEMENT:
              case Scratch.ATTRIBUTE:
                  {
                      SchemaType contentType = scratch.getSchemaType().getProperties()[0].getType();
                      Scratch contentScratch = scratchForSchemaType(contentType);
                      resolveJavaName(contentScratch);
                      scratch.setJavaName(contentScratch.getJavaName());
                      return;
                  }
                  
              default:
                  throw new IllegalStateException("Unrecognized category");
          }
      }
  
      /**
       * Computes a BindingType for a scratch.
       */ 
      private void createBindingType(Scratch scratch)
      {
          assert(scratch.getBindingType() == null);
          
          switch (scratch.getCategory())
          {
              case Scratch.ATOMIC_TYPE:
                  SimpleBindingType simpleResult = new SimpleBindingType(scratch.getJavaName(), scratch.getXmlName(), false);
                  simpleResult.setAsIfXmlType(scratch.getAsIf());
                  scratch.setBindingType(simpleResult);
                  bindingFile.addBindingType(simpleResult, false, true);
                  break;
                  
              case Scratch.STRUCT_TYPE:
                  ByNameBean byNameResult = new ByNameBean(scratch.getJavaName(), scratch.getXmlName(), false);
                  scratch.setBindingType(byNameResult);
                  bindingFile.addBindingType(byNameResult, true, true);
                  break;
                  
              case Scratch.LITERALARRAY_TYPE:
                  throw new UnsupportedOperationException();
                  
              case Scratch.SOAPARRAY_REF:
                  throw new UnsupportedOperationException();
                  
              case Scratch.SOAPARRAY:
                  throw new UnsupportedOperationException();
                  
              case Scratch.ELEMENT:
              case Scratch.ATTRIBUTE:
                  throw new UnsupportedOperationException();
                  
              default:
                  throw new IllegalStateException("Unrecognized category");
          }
      }
  
      /**
       * Now we resolve the structural aspects (property names) for each
       * scratch.  Notice that we only process
       * @param scratch
       */ 
      private void resolveJavaStructure(Scratch scratch)
      {
          if (scratch.getCategory() != Scratch.STRUCT_TYPE)
              return;
          
          if (scratch.isStructureResolved())
              return;
          
          scratch.setStructureResolved(true);
          
          SchemaType baseType = scratch.getSchemaType().getBaseType();
          Collection baseProperties = null;
          if (baseType != null)
              baseProperties = extractProperties(baseType);
          if (baseProperties == null)
              baseProperties = Collections.EMPTY_LIST;
          
          // sort properties based on QName attr/elt
          Map seenAttrProps = new HashMap();
          Map seenEltProps = new HashMap();
          Set seenMethodNames = new HashSet();
          seenMethodNames.add("getClass");
          
          for (Iterator i = baseProperties.iterator(); i.hasNext(); )
          {
              QNameProperty prop = (QNameProperty)i.next();
              if (prop.isAttribute())
                  seenAttrProps.put(prop.getQName(), prop);
              else
                  seenEltProps.put(prop.getQName(), prop);
              
              // todo: probably this collision avoidance should be using Java introspection instead
              if (prop.getGetterName() != null)
                  seenMethodNames.add(prop.getGetterName());
              if (prop.getSetterName() != null)
                  seenMethodNames.add(prop.getSetterName());
          }
          
          // now deal with remaining props
          SchemaProperty[] props = scratch.getSchemaType().getProperties();
          for (int i = 0; i < props.length; i++)
          {
              QNameProperty prop = (QNameProperty)(props[i].isAttribute() ? seenAttrProps : seenEltProps).get(props[i].getName());
              if (prop != null)
              {
                  // already seen property: verify multiplicity looks cool
                  if (prop.isMultiple() != isMultiple(props[i]))
                  {
                      // todo: signal nicer error
                      throw new IllegalStateException("Can't change multiplicity");
                  }
                  
                  // todo: think about optionality and nillability too
              }
              else
              {
                  SchemaType sType = props[i].getType();
                  BindingType bType = bindingTypeForSchemaType(sType);
                  
                  String propName = pickUniquePropertyName(props[i].getName(), seenMethodNames);
                  String getter = "get" + propName;
                  String setter = "set" + propName;
                  boolean isMultiple = isMultiple(props[i]);
                  JavaName collection = null;
                  if (isMultiple)
                      collection = JavaName.forArray(bType.getJavaName(), 1);
                  
                  prop = new QNameProperty();
                  prop.setQName(props[i].getName());
                  prop.setAttribute(props[i].isAttribute());
                  prop.setSetterName(setter);
                  prop.setGetterName(getter);
                  prop.setCollectionClass(collection);
                  prop.setBindingType(bType);
                  prop.setNillable(props[i].hasNillable() != SchemaProperty.NEVER);
                  prop.setOptional(isOptional(props[i]));
                  prop.setMultiple(isMultiple);
              }
              scratch.addQNameProperty(prop);
          }
      }
      
      /**
       * Picks a property name without colliding with names of
       * previously picked getters and setters.
       */ 
      private String pickUniquePropertyName(QName name, Set seenMethodNames)
      {
          String baseName = NameUtil.upperCamelCase(name.getLocalPart());
          String propName = baseName;
          for (int i = 1; ; i += 1)
          {
              String getter = "get" + propName;
              String setter = "set" + propName;
              
              if (!seenMethodNames.contains(getter) &&
                      !seenMethodNames.contains(setter))
              {
                  seenMethodNames.add(getter);
                  seenMethodNames.add(setter);
                  return propName;
              }
              propName = baseName + i;
          }
      }
  
      /**
       * True if the given SchemaProperty has maxOccurs > 1
       */ 
      private static boolean isMultiple(SchemaProperty prop)
      {
          return (prop.getMaxOccurs() == null || prop.getMaxOccurs().compareTo(BigInteger.ONE) > 0);
      }
      
      /**
       * True if the given SchemaProperty has minOccurs < 1
       */ 
      private static boolean isOptional(SchemaProperty prop)
      {
          return (prop.getMinOccurs().signum() == 0);
      }
      
      /**
       * Returns a collection of QNameProperties for a given schema type that
       * may either be on the path or the current scratch area.
       */ 
      private Collection extractProperties(SchemaType sType)
      {
          // case 1: it's in the current area
          Scratch scratch = scratchForSchemaType(sType);
          if (scratch != null)
          {
              resolveJavaStructure(scratch);
              return scratch.getQNameProperties();
          }
          
          // case 2: it's in the path
          BindingType bType = path.getBindingTypeForXmlPojo(XmlName.forSchemaType(sType));
          if (!(bType instanceof ByNameBean))
          {
              return null;
          }
          Collection result = new ArrayList();
          ByNameBean bnb = (ByNameBean)bType;
          for (Iterator i = bnb.getProperties().iterator(); i.hasNext(); )
          {
              result.add(i.next());
          }
          
          return result;
      }
      
      /**
       * True for a schema type that is a SOAP array.
       */ 
      private static boolean isSoapArray(SchemaType sType)
      {
          // SOAP Array definition must be put on the compiletime classpath
          while (sType != null)
          {
              String signature = XmlName.forSchemaType(sType).toString();
              
              // captures both SOAP 1.1 and SOAP 1.2+
              if (signature.equals("t=Array@http://schemas.xmlsoap.org/soap/encoding/") ||
                      signature.startsWith("t=Array@http://www.w3.org/")
                      && signature.endsWith("/soap-encoding"))
                  return true;
              sType = sType.getBaseType();
          }
          return false;
      }
      
      private static final QName arrayType = new QName("http://schemas.xmlsoap.org/soap/encoding/", "arrayType");
      
      /**
       * Returns an XmlName describing a SOAP array.
       */ 
      private static XmlName soapArrayTypeName(SchemaType sType)
      {
          // first, look for wsdl:arrayType default - this will help us with multidimensional arrays
          SOAPArrayType defaultArrayType = null;
          SchemaLocalAttribute attr = sType.getAttributeModel().getAttribute(arrayType);
          if (attr != null)
              defaultArrayType = ((SchemaWSDLArrayType)attr).getWSDLArrayType();
          
          // method 1: trust wsdl:arrayType
          if (defaultArrayType != null)
              return XmlName.forSoapArrayType(defaultArrayType);
          
          // method 2: SOAP 1.2 equivalent?
          // todo: track what do WSDLs do in the world of SOAP 1.2.
          
          // method 3: look at the type of a unique element.
          SchemaType itemType = XmlObject.type;
          SchemaProperty[] props = sType.getElementProperties();
          if (props.length == 1)
              itemType = props[0].getType();
          
          return XmlName.forNestedNumber(XmlName.SOAP_ARRAY, 1, XmlName.forSchemaType(itemType));
      }
      
      /**
       * Climbs the structure of a schema type to find the namespace within
       * which it was defined.
       */ 
      private String findContainingNamespace(SchemaType sType)
      {
          for (;;)
          {
              if (sType.isDocumentType())
                  return sType.getDocumentElementName().getNamespaceURI();
              else if (sType.isAttributeType())
                  return sType.getAttributeTypeAttributeName().getNamespaceURI();
              else if (sType.getName() != null)
                  return sType.getName().getNamespaceURI();
              sType = sType.getOuterType();
          }
      }
  
      /**
       * Picks a unique fully-qualified Java class name for the given schema
       * type.  Uses and updates the "usedNames" set.
       */ 
      private JavaName pickUniqueJavaName(SchemaType sType)
      {
          QName qname = null;
          while (qname == null)
          {
              if (sType.isDocumentType())
                  qname = sType.getDocumentElementName();
              else if (sType.isAttributeType())
                  qname = sType.getAttributeTypeAttributeName();
              else if (sType.getName() != null)
                  qname = sType.getName();
              else if (sType.getContainerField() != null)
              {
                  qname = sType.getContainerField().getName();
                  if (qname.getNamespaceURI().length() == 0)
                      qname = new QName(findContainingNamespace(sType), qname.getLocalPart());
              }
              sType = sType.getOuterType();
          }
          
          String baseName = NameUtil.getClassNameFromQName(qname);
          String pickedName = baseName;
          
          for (int i = 1; usedNames.contains(pickedName); i += 1)
              pickedName = baseName + i;
          
          usedNames.add(pickedName);
          
          return JavaName.forString(pickedName);
      }
  
      /**
       * Resolves an atomic scratch all at once, including its
       * JavaName and basedOn fields.
       * 
       * This resolution method sets up a scratch so that is
       * is "based on" another binding type.  It finds the
       * underlying binding type by climing the base type
       * chain, and grabbing the first hit.
       */ 
      private void resolveSimpleScratch(Scratch scratch)
      {
          assert(scratch.getCategory() == Scratch.ATOMIC_TYPE);
                  
          if (scratch.getJavaName() != null)
              return;
          
          SchemaType baseType = scratch.getSchemaType().getBaseType();
          while (baseType != null)
          {
              // find a base type within this type system
              Scratch basedOnScratch = scratchForSchemaType(baseType);
              if (basedOnScratch != null)
              {
                  if (basedOnScratch.getCategory() != Scratch.ATOMIC_TYPE)
                      throw new IllegalStateException("Atomic types should only inherit from atomic types");
                  resolveSimpleScratch(basedOnScratch);
                  scratch.setJavaName(basedOnScratch.getJavaName());
                  scratch.setAsIf(basedOnScratch.getXmlName());
                  return;
              }
              
              // or if not within this type system, find the base type on the path
              XmlName treatAs = XmlName.forSchemaType(baseType);
              BindingType basedOnBinding = path.getBindingTypeForXmlPojo(treatAs);
              if (basedOnBinding != null)
              {
                  scratch.setJavaName(basedOnBinding.getJavaName());
                  scratch.setAsIf(treatAs);
                  return;
              }
              
              // or go to the next base type up
              baseType = baseType.getBaseType();
          }
          
          // builtin at least should give us xs:anyType
          throw new IllegalStateException("Builtin binding type loader is not on path.");
      }
      
      /**
       * Looks on both the path and in the current scratch area for
       * the binding type corresponding to the given schema type.  Must
       * be called after all the binding types have been created.
       */ 
      private BindingType bindingTypeForSchemaType(SchemaType sType)
      {
          Scratch scratch = scratchForSchemaType(sType);
          if (scratch != null)
              return scratch.getBindingType();
          return path.getBindingTypeForXmlPojo(XmlName.forSchemaType(sType));
      }
  
      /**
       * Returns the scratch area for a given schema type.  Notice that
       * SOAP arrays have an XmlName but not a schema type.
       */ 
      private Scratch scratchForSchemaType(SchemaType sType)
      {
          return (Scratch)scratchFromSchemaType.get(sType);
      }
      
      /**
       * Returns the scratch area for a given XmlName.
       */ 
      private Scratch scratchForXmlName(XmlName xmlName)
      {
          return (Scratch)scratchFromXmlName.get(xmlName);
      }
  
      /**
       * Returns the scratch area for a given JavaName.  Notice that only
       * structures generate a java class, so not non-strucuture scratch areas
       * cannot be referenced this way.
       */ 
      private Scratch scratchForJavaNameString(String javaName)
      {
          return (Scratch)scratchFromJavaNameString.get(javaName);
      }
      
      /**
       * Extracts the schema type for the array items for a literal array.
       */ 
      private static SchemaType getLiteralArrayItemType(SchemaType sType)
      {
          // consider: must the type be named "ArrayOf..."?
          
          if (sType.isSimpleType() || sType.getContentType() == SchemaType.SIMPLE_CONTENT)
              return null;
          SchemaProperty[] prop = sType.getProperties();
          if (prop.length != 1 || prop[0].isAttribute())
              return null;
          BigInteger max = prop[0].getMaxOccurs();
          if (max != null && max.compareTo(BigInteger.ONE) <= 0)
              return null;
          return prop[0].getType();
      }
  
      /**
       * True if the given schema type is interpreted as a .NET-style
       * array.
       */ 
      private static boolean isLiteralArray(SchemaType sType)
      {
          return getLiteralArrayItemType(sType) != null;
      }
      
      /**
       * Scratch area corresponding to a schema type, used for the binding
       * computation.
       */ 
      private static class Scratch
      {
          Scratch(SchemaType schemaType, XmlName xmlName, int category)
          {
              this.schemaType = schemaType;
              this.xmlName = xmlName;
              this.category = category;
          }
          
          private BindingType bindingType;
          private SchemaType schemaType; // may be null
          private JavaName javaName;
          private XmlName xmlName;
  
          private int category;
  
          // atomic types get a treatAs
          private XmlName asIf;
          private boolean isStructureResolved;
  
          // categories of Scratch, established at ctor time
          public static final int ATOMIC_TYPE = 1;
          public static final int STRUCT_TYPE = 2;
          public static final int LITERALARRAY_TYPE = 3;
          public static final int SOAPARRAY_REF = 4;
          public static final int SOAPARRAY = 5;
          public static final int ELEMENT = 6;
          public static final int ATTRIBUTE = 7;
  
          public int getCategory()
          {
              return category;
          }
  
          public JavaName getJavaName()
          {
              return javaName;
          }
  
          public void setJavaName(JavaName javaName)
          {
              this.javaName = javaName;
          }
  
          public BindingType getBindingType()
          {
              return bindingType;
          }
  
          public void setBindingType(BindingType bindingType)
          {
              this.bindingType = bindingType;
          }
  
          public SchemaType getSchemaType()
          {
              return schemaType;
          }
  
          public XmlName getXmlName()
          {
              return xmlName;
          }
  
          public void setXmlName(XmlName xmlName)
          {
              this.xmlName = xmlName;
          }
  
          public XmlName getAsIf()
          {
              return asIf;
          }
  
          public void setAsIf(XmlName xmlName)
          {
              this.asIf = xmlName;
          }
          
          public void addQNameProperty(QNameProperty prop)
          {
              if (!(bindingType instanceof ByNameBean))
                  throw new IllegalStateException();
              ((ByNameBean)bindingType).addProperty(prop);
          }
          
          public Collection getQNameProperties()
          {
              if (!(bindingType instanceof ByNameBean))
                  throw new IllegalStateException();
              return ((ByNameBean)bindingType).getProperties();
          }
  
          public boolean isStructureResolved()
          {
              return this.isStructureResolved;
          }
          
          public void setStructureResolved(boolean isStructureResolved)
          {
              this.isStructureResolved = isStructureResolved;
          }
      }
      
      /**
       * Returns an iterator for all the Scratch's
       */ 
      private Iterator scratchIterator()
      {
          return scratchFromXmlName.values().iterator();
      }
      
      /**
       * Returns an iterator for all the schema types
       */ 
      private Iterator allTypeIterator()
      {
          class AllTypeIterator implements Iterator
          {
              int index;
              List allSeenTypes;
              
              AllTypeIterator(SchemaTypeSystem sts)
              {
                  allSeenTypes = new ArrayList();
                  allSeenTypes.addAll(Arrays.asList(sts.documentTypes()));
                  allSeenTypes.addAll(Arrays.asList(sts.attributeTypes()));
                  allSeenTypes.addAll(Arrays.asList(sts.globalTypes()));
                  index = 0;
              }
              
              public boolean hasNext()
              {
                  return index < allSeenTypes.size();
              }
  
              public Object next()
              {
                  SchemaType next = (SchemaType)allSeenTypes.get(index);
                  allSeenTypes.addAll(Arrays.asList(next.getAnonymousTypes()));
                  index += 1;
                  return next;
              }
  
              public void remove()
              {
                  throw new UnsupportedOperationException();
              }
          }
          
          return new AllTypeIterator(sts);
      }
      
      /**
       * Iterates over all the top-level Java class names generated
       * by this binding.  Used by getToplevelClasses.
       */ 
      private class TopLevelClassNameIterator implements Iterator
      {
          private final Iterator si = scratchIterator();
          private Scratch next = nextStructure();
          
          public boolean hasNext()
          {
              return next != null;
          }
  
          public Object next()
          {
              String result = next.getJavaName().toString();
              next = nextStructure();
              return result;
          }
  
          private Scratch nextStructure()
          {
              while (si.hasNext())
              {
                  Scratch scratch = (Scratch)si.next();
                  if (scratch.getCategory() == Scratch.STRUCT_TYPE)
                      return scratch;
              }
              return null;
          }
  
          public void remove()
          {
              throw new UnsupportedOperationException();
          }
      }
  
  
      /**
       * Returns a collection of fully-qualified Java class name strings
       * generated by this binding.
       */
      public Collection getToplevelClasses()
      {
          return new AbstractCollection()
          {
              public Iterator iterator()
              {
                  return new TopLevelClassNameIterator();
              }
      
              public int size()
              {
                  return structureCount;
              }
          };
      }
  
      /**
       * Prints the Java source code for the given generated java class name.
       */
      public void printSourceCode(String topLevelClassName, OutputStream output) throws IOException
      {
          Scratch scratch = scratchForJavaNameString(topLevelClassName);
          if (scratch == null)
              throw new IllegalArgumentException();
          Writer writer = new OutputStreamWriter(output);
          ScratchCodePrinter printer = new ScratchCodePrinter(scratch, writer);
          printer.print();
          writer.flush();
      }
      
      /**
       * Handles the printing for one generated java class.
       */
      private class ScratchCodePrinter extends JavaCodePrinter
      {
          private Scratch scratch;
  
          ScratchCodePrinter(Scratch scratch, Writer writer)
          {
              super(writer);
              assert(scratch.getCategory() == Scratch.STRUCT_TYPE);
              this.scratch = scratch;
          }
          
          private void print() throws IOException
          {
              JavaName javaName = scratch.getJavaName();
              
              String packageName = javaName.getPackage();
              String shortClassName = javaName.getShortClassName();
              BindingType baseType = bindingTypeForSchemaType(scratch.getSchemaType().getBaseType());
              String baseJavaname = null;
              if (baseType != null)
              {
                  baseJavaname = baseType.getJavaName().toString();
                  if (baseJavaname.equals("java.lang.Object"))
                      baseJavaname = null;
              }
              
              line("package " + packageName);
              line();
              javadoc("Generated from schema type " + scratch.getXmlName());
              line("class " + shortClassName + (baseJavaname != null ? " extends " + baseJavaname : ""));
              startBlock();
              
              Collection props = scratch.getQNameProperties();
              Map fieldNames = new HashMap();
              Set seenFieldNames = new HashSet();
              
              // pick field names
              for (Iterator i = props.iterator(); i.hasNext(); )
              {
                  QNameProperty prop = (QNameProperty)i.next();
                  fieldNames.put(prop, pickUniqueFieldName(prop.getGetterName(), seenFieldNames));
              }
              
              // print private fields
              for (Iterator i = props.iterator(); i.hasNext(); )
              {
                  QNameProperty prop = (QNameProperty)i.next();
                  JavaName jType = prop.getJavaTypeName();
                  if (prop.getCollectionClass() != null)
                      jType = prop.getCollectionClass();
                  
                  line("private " + jType.toString() + " " + fieldNames.get(prop) + ";");
              }
              
              // print getters and setters
              for (Iterator i = props.iterator(); i.hasNext(); )
              {
                  QNameProperty prop = (QNameProperty)i.next();
                  JavaName jType = prop.getJavaTypeName();
                  if (prop.getCollectionClass() != null)
                      jType = prop.getCollectionClass();
                  String fieldName = (String)fieldNames.get(prop);
                  
                  line();
                  line("public " + jType.toString() + " " + prop.getGetterName() + "()");
                  startBlock();
                  line("return " + fieldName + ";");
                  endBlock();
                  line();
                  line("public void " + prop.getSetterName() + "(" + jType.toString() + " " + fieldName + ")");
                  startBlock();
                  line("this." + fieldName + " = " + fieldName + ";");
                  endBlock();
              }
              
              endBlock();
          }
          
          private String pickUniqueFieldName(String getter, Set seenNames)
          {
              String baseName;
              
              if (getter.length() > 3 && getter.startsWith("get"))
                  baseName = Character.toLowerCase(getter.charAt(3)) + getter.substring(4);
              else
                  baseName = "field";
              
              String fieldName = baseName;
              for (int i = 1; seenNames.contains(fieldName); i += 1)
                  fieldName = baseName + i;
              
              seenNames.add(fieldName);
              return fieldName;
          }
      }
  
      /**
       * Prints the binding file generated by this binding.
       */ 
      public void printBindingFile(OutputStream output) throws IOException
      {
          bindingFile.write().save(output, new XmlOptions().setSavePrettyPrint());
      }
  
      /**
       * Returns a BindingFileGenerator for this SchemaToJavaResult.
       */ 
      public BindingFileGenerator getBindingFileGenerator()
      {
          return this;
      }
  
      /**
       * Returns the JavaCodeGenerator for this SchemaToJavaResult.
       */ 
      public JavaCodeGenerator getJavaCodeGenerator()
      {
          return this;
      }
  }
  
  
  
  1.1                  xml-xmlbeans/v2/src/binding/org/apache/xmlbeans/impl/binding/compile/JavaCodeGenerator.java
  
  Index: JavaCodeGenerator.java
  ===================================================================
  /*
  * The Apache Software License, Version 1.1
  *
  *
  * Copyright (c) 2003 The Apache Software Foundation.  All rights
  * reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
  *
  * 1. Redistributions of source code must retain the above copyright
  *    notice, this list of conditions and the following disclaimer.
  *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in
  *    the documentation and/or other materials provided with the
  *    distribution.
  *
  * 3. The end-user documentation included with the redistribution,
  *    if any, must include the following acknowledgment:
  *       "This product includes software developed by the
  *        Apache Software Foundation (http://www.apache.org/)."
  *    Alternately, this acknowledgment may appear in the software itself,
  *    if and wherever such third-party acknowledgments normally appear.
  *
  * 4. The names "Apache" and "Apache Software Foundation" must
  *    not be used to endorse or promote products derived from this
  *    software without prior written permission. For written
  *    permission, please contact apache@apache.org.
  *
  * 5. Products derived from this software may not be called "Apache
  *    XMLBeans", nor may "Apache" appear in their name, without prior
  *    written permission of the Apache Software Foundation.
  *
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  * ====================================================================
  *
  * This software consists of voluntary contributions made by many
  * individuals on behalf of the Apache Software Foundation and was
  * originally based on software copyright (c) 2003 BEA Systems
  * Inc., <http://www.bea.com/>. For more information on the Apache Software
  * Foundation, please see <http://www.apache.org/>.
  */
  
  package org.apache.xmlbeans.impl.binding.compile;
  
  import java.util.Collection;
  import java.io.OutputStream;
  import java.io.IOException;
  
  public interface JavaCodeGenerator
  {
      // returns a collection of fully-qualified Java class name strings
      Collection getToplevelClasses();
      
      /**
       * Prints the .java source code for the given class.
       * 
       * Note for internationalization: the system default encoding
       * should be used for the given OutputStream, since it is conventional
       * for Java programs to be compiled from files using this encoding.
       * 
       * To produce a safely portable source file, a printer should be
       * careful to use uXXXX escape codes for any non-ascii characters.
       */ 
      void printSourceCode(String topLevelClassName, OutputStream output) throws IOException;
  }
  
  
  
  1.1                  xml-xmlbeans/v2/src/binding/org/apache/xmlbeans/impl/binding/compile/JavaCodePrinter.java
  
  Index: JavaCodePrinter.java
  ===================================================================
  /*
  * The Apache Software License, Version 1.1
  *
  *
  * Copyright (c) 2003 The Apache Software Foundation.  All rights
  * reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
  *
  * 1. Redistributions of source code must retain the above copyright
  *    notice, this list of conditions and the following disclaimer.
  *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in
  *    the documentation and/or other materials provided with the
  *    distribution.
  *
  * 3. The end-user documentation included with the redistribution,
  *    if any, must include the following acknowledgment:
  *       "This product includes software developed by the
  *        Apache Software Foundation (http://www.apache.org/)."
  *    Alternately, this acknowledgment may appear in the software itself,
  *    if and wherever such third-party acknowledgments normally appear.
  *
  * 4. The names "Apache" and "Apache Software Foundation" must
  *    not be used to endorse or promote products derived from this
  *    software without prior written permission. For written
  *    permission, please contact apache@apache.org.
  *
  * 5. Products derived from this software may not be called "Apache
  *    XMLBeans", nor may "Apache" appear in their name, without prior
  *    written permission of the Apache Software Foundation.
  *
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  * ====================================================================
  *
  * This software consists of voluntary contributions made by many
  * individuals on behalf of the Apache Software Foundation and was
  * originally based on software copyright (c) 2003 BEA Systems
  * Inc., <http://www.bea.com/>. For more information on the Apache Software
  * Foundation, please see <http://www.apache.org/>.
  */
  
  package org.apache.xmlbeans.impl.binding.compile;
  
  import java.io.Writer;
  import java.io.IOException;
  
  public class JavaCodePrinter
  {
      private Writer _writer;
      private int    _indent;
  
      private static final String LINE_SEPARATOR =
          System.getProperty("line.separator") == null
              ? "\n"
              : System.getProperty("line.separator");
  
      private static final String MAX_SPACES = "                                        ";
      private static final int INDENT_INCREMENT = 4;
  
      public JavaCodePrinter(Writer writer)
      {
          _writer = writer;
          _indent = 0;
      }
  
      public void indent()
      {
          _indent += INDENT_INCREMENT;
      }
  
      public void outdent()
      {
          _indent -= INDENT_INCREMENT;
      }
  
      public static String encodeString(String s)
      {
          StringBuffer sb = new StringBuffer();
  
          sb.append( '"' );
  
          for ( int i = 0 ; i < s.length() ; i++ )
          {
              char ch = s.charAt( i );
  
              if (ch == '"')
              {
                  sb.append( '\\' );
                  sb.append( '\"' );
              }
              else if (ch == '\\')
              {
                  sb.append( '\\' );
                  sb.append( '\\' );
              }
              else if (ch == '\r')
              {
                  sb.append( '\\' );
                  sb.append( 'r' );
              }
              else if (ch == '\n')
              {
                  sb.append( '\\' );
                  sb.append( 'n' );
              }
              else if (ch == '\t')
              {
                  sb.append( '\\' );
                  sb.append( 't' );
              }
              else
                  sb.append( ch );
          }
  
          sb.append( '"' );
  
          return sb.toString();
      }
      
      private static String intlSafe(String s)
      {
          for (int i = 0; i < s.length(); i++)
          {
              if (s.charAt(i) > 127)
                  return buildIntlSafe(s);
          }
          return s;
      }
      
      private static final char[] hexLow = {
          '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
          '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
          '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
          '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
          '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
          '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
          '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
          '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
          '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
          '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
          '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
          '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
          '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
          '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
          '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
          '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
      };
      
      private static final char[] hexHigh = {
          '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
          '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1',
          '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2',
          '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3',
          '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4',
          '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5',
          '6', '6', '6', '6', '6', '6', '6', '6', '6', '6', '6', '6', '6', '6', '6', '6',
          '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7',
          '8', '8', '8', '8', '8', '8', '8', '8', '8', '8', '8', '8', '8', '8', '8', '8',
          '9', '9', '9', '9', '9', '9', '9', '9', '9', '9', '9', '9', '9', '9', '9', '9',
          'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
          'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B',
          'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C',
          'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D',
          'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E',
          'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F',
      };
      
      private static String buildIntlSafe(String s)
      {
          StringBuffer sb = new StringBuffer();
          int i = 0;
          int j = 0;
          for (;;)
          {
              for (; i < s.length(); i++)
              {
                  if (s.charAt(i) > 127)
                      break;
              }
              if (j < i)
                  sb.append(s.substring(j, i));
              for (; i < s.length(); i++)
              {
                  int ch = s.charAt(i);
                  if (ch <= 127)
                      break;
                  int highByte = ch >>> 8;
                  int lowByte = ch & 0xFF;
                  
                  sb.append("\\u");
                  sb.append(hexHigh[highByte]);
                  sb.append(hexLow[highByte]);
                  sb.append(hexHigh[lowByte]);
                  sb.append(hexLow[lowByte]);
              }
              j = i;
          }
      }
  
      public void line(String s) throws IOException
      {
          int indent = _indent;
          
          if (indent > MAX_SPACES.length() / 2)
              indent = MAX_SPACES.length() / 4 + indent / 2;
          
          if (indent > MAX_SPACES.length())
              indent = MAX_SPACES.length();
          
          _writer.write(MAX_SPACES.substring(0, indent));
          _writer.write(intlSafe(s));
          _writer.write(LINE_SEPARATOR);
      }
      
      public void line() throws IOException
      {
          _writer.write(LINE_SEPARATOR);
      }
      
      public void javadoc(String s) throws IOException
      {
          line("/**");
          int i = 0;
          int j = 0;
          for (;;)
          {
              j = s.indexOf('\n', i);
              if (j < 0)
                  break;
              line(" * " + s.substring(i, j));
              i = j + 1;
          }
          line(" * " + s.substring(i));
          line(" */");
      }
      
      public void startBlock() throws IOException
      {
          line("{");
          indent();
      }
      
      public void startBlock(String s) throws IOException
      {
          line(s + " {");
          indent();
      }
      
      public void endBlock() throws IOException
      {
          outdent();
          line("}");
      }
      
  }
  
  
  
  1.1                  xml-xmlbeans/v2/src/binding/org/apache/xmlbeans/impl/binding/compile/SchemaToJavaResult.java
  
  Index: SchemaToJavaResult.java
  ===================================================================
  /*
  * The Apache Software License, Version 1.1
  *
  *
  * Copyright (c) 2003 The Apache Software Foundation.  All rights
  * reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
  *
  * 1. Redistributions of source code must retain the above copyright
  *    notice, this list of conditions and the following disclaimer.
  *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in
  *    the documentation and/or other materials provided with the
  *    distribution.
  *
  * 3. The end-user documentation included with the redistribution,
  *    if any, must include the following acknowledgment:
  *       "This product includes software developed by the
  *        Apache Software Foundation (http://www.apache.org/)."
  *    Alternately, this acknowledgment may appear in the software itself,
  *    if and wherever such third-party acknowledgments normally appear.
  *
  * 4. The names "Apache" and "Apache Software Foundation" must
  *    not be used to endorse or promote products derived from this
  *    software without prior written permission. For written
  *    permission, please contact apache@apache.org.
  *
  * 5. Products derived from this software may not be called "Apache
  *    XMLBeans", nor may "Apache" appear in their name, without prior
  *    written permission of the Apache Software Foundation.
  *
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  * ====================================================================
  *
  * This software consists of voluntary contributions made by many
  * individuals on behalf of the Apache Software Foundation and was
  * originally based on software copyright (c) 2003 BEA Systems
  * Inc., <http://www.bea.com/>. For more information on the Apache Software
  * Foundation, please see <http://www.apache.org/>.
  */
  
  package org.apache.xmlbeans.impl.binding.compile;
  
  import org.apache.xmlbeans.impl.binding.compile.BindingFileGenerator;
  import org.apache.xmlbeans.impl.binding.compile.JavaCodeGenerator;
  
  /**
   * The result of a Schema->Java binding.
   * 
   * The result contains: (1) a binding file, and (2) a set of
   * generated Java classes.
   */
  public interface SchemaToJavaResult
  {
      BindingFileGenerator getBindingFileGenerator();
      JavaCodeGenerator getJavaCodeGenerator();
  }
  
  
  
  1.2       +7 -7      xml-xmlbeans/v2/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaTypeImpl.java
  
  Index: SchemaTypeImpl.java
  ===================================================================
  RCS file: /home/cvs/xml-xmlbeans/v2/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaTypeImpl.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- SchemaTypeImpl.java	26 Sep 2003 21:23:28 -0000	1.1
  +++ SchemaTypeImpl.java	27 Oct 2003 19:17:21 -0000	1.2
  @@ -818,16 +818,16 @@
           }
           else
           {
  -            if (!_typedWildcardElements.contains(eltName))
  +            if (!_typedWildcardElements.contains(eltName) || wildcardTypeLoader == null)
                   return BuiltinSchemaTypeSystem.ST_NO_TYPE;
   
               SchemaGlobalElement elt = wildcardTypeLoader.findElement(eltName);
               if (elt == null)
  -                return BuiltinSchemaTypeSystem.ST_ANY_TYPE;
  +                return BuiltinSchemaTypeSystem.ST_NO_TYPE;
               type = elt.getType();
           }
   
  -        if (xsiType != null)
  +        if (xsiType != null && wildcardTypeLoader != null)
           {
               SchemaType itype = wildcardTypeLoader.findType(xsiType);
               if (itype == null)
  @@ -853,12 +853,12 @@
           if (prop != null)
               return prop.getType();
   
  -        if (!_typedWildcardAttributes.contains(attrName))
  +        if (!_typedWildcardAttributes.contains(attrName) || wildcardTypeLoader == null)
               return BuiltinSchemaTypeSystem.ST_NO_TYPE;
   
           SchemaGlobalAttribute attr = wildcardTypeLoader.findAttribute(attrName);
           if (attr == null)
  -            return BuiltinSchemaTypeSystem.ST_ANY_SIMPLE;
  +            return BuiltinSchemaTypeSystem.ST_NO_TYPE;
           return attr.getType();
       }
   
  @@ -888,7 +888,7 @@
                   if (elt != null)
                       type = elt.getType();
                   else
  -                    type = BuiltinSchemaTypeSystem.ST_ANY_TYPE;
  +                    type = BuiltinSchemaTypeSystem.ST_NO_TYPE;
               }
   
               if (xsiType != null)
  @@ -935,7 +935,7 @@
                   if (attr != null)
                       type = (SchemaTypeImpl)attr.getType();
                   else
  -                    type = BuiltinSchemaTypeSystem.ST_ANY_SIMPLE;
  +                    type = BuiltinSchemaTypeSystem.ST_NO_TYPE;
               }
           }
   
  
  
  
  1.4       +37 -40    xml-xmlbeans/v2/src/typeimpl/org/apache/xmlbeans/impl/values/XmlObjectBase.java
  
  Index: XmlObjectBase.java
  ===================================================================
  RCS file: /home/cvs/xml-xmlbeans/v2/src/typeimpl/org/apache/xmlbeans/impl/values/XmlObjectBase.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- XmlObjectBase.java	7 Oct 2003 04:08:01 -0000	1.3
  +++ XmlObjectBase.java	27 Oct 2003 19:17:21 -0000	1.4
  @@ -114,6 +114,7 @@
   import org.apache.xmlbeans.XmlBeans;
   import org.apache.xmlbeans.XmlError;
   import org.apache.xmlbeans.SchemaLocalAttribute;
  +import org.apache.xmlbeans.FilterXmlObject;
   
   import org.w3c.dom.Node;
   
  @@ -132,6 +133,19 @@
               return get_store().get_root_object();
           return this;
       }
  +    
  +    private static XmlObjectBase underlying(XmlObject obj)
  +    {
  +        if (obj == null)
  +            return null;
  +        if (obj instanceof XmlObjectBase)
  +            return (XmlObjectBase)obj;
  +        while (obj instanceof FilterXmlObject)
  +            obj = ((FilterXmlObject)obj).underlyingXmlObject();
  +        if (obj instanceof XmlObjectBase)
  +            return (XmlObjectBase)obj;
  +        throw new IllegalStateException("Non-native implementations of XmlObject should extend FilterXmlObject");
  +    }
   
       public final XmlObject copy()
       {
  @@ -144,10 +158,14 @@
               check_orphaned();
   
               // copy the type
  -            XmlObjectBase result = (XmlObjectBase)get_store().get_schematypeloader().newInstance(schemaType(), null);
  +            XmlObject result = get_store().get_schematypeloader().newInstance(schemaType(), null);
  +            
   
               // copy the data
  -            return (XmlObjectBase) result.get_store().copy_contents_from(get_store());
  +            XmlObjectBase target = underlying(result);
  +            target.get_store().copy_contents_from(get_store());
  +            
  +            return result;
           }
       }
   
  @@ -1026,27 +1044,6 @@
           return model.getAttribute(attrName);
       }
   
  -    /**
  -     * Used to simplify detection of default value situations.
  -     */
  -    private final static boolean is_XmlWhitespace(String v)
  -    {
  -        for (int i = 0; i < v.length(); i++)
  -        {
  -            switch (v.charAt(i))
  -            {
  -                case ' ':
  -                case '\t':
  -                case '\r':
  -                case '\n':
  -                    continue;
  -                default:
  -                    return false;
  -            }
  -        }
  -        return true;
  -    }
  -
   
       /**
        * Setting a string preserves any noncanonical literal
  @@ -1679,7 +1676,7 @@
                   synchronized (monitor())
                   {
                       set_prepare();
  -                    set_list(((XmlObjectBase)v).xgetListValue());
  +                    set_list(((SimpleValue)v).xgetListValue());
                       set_commit();
                       return;
                   }
  @@ -1700,42 +1697,42 @@
   
                       case SchemaType.BTC_BOOLEAN:
                       {
  -                        boolean bool = ((XmlObjectBase)v).booleanValue();
  +                        boolean bool = ((SimpleValue)v).getBooleanValue();
                           set_prepare();
                           set_boolean(bool);
                           break;
                       }
                       case SchemaType.BTC_BASE_64_BINARY:
                       {
  -                        byte[] byteArr = ((XmlObjectBase)v).byteArrayValue();
  +                        byte[] byteArr = ((SimpleValue)v).getByteArrayValue();
                           set_prepare();
                           set_b64(byteArr);
                           break;
                       }
                       case SchemaType.BTC_HEX_BINARY:
                       {
  -                        byte[] byteArr = ((XmlObjectBase)v).byteArrayValue();
  +                        byte[] byteArr = ((SimpleValue)v).getByteArrayValue();
                           set_prepare();
                           set_hex(byteArr);
                           break;
                       }
                       case SchemaType.BTC_QNAME:
                       {
  -                        QName name = ((XmlObjectBase)v).qNameValue();
  +                        QName name = ((SimpleValue)v).getQNameValue();
                           set_prepare();
                           set_QName(name);
                           break;
                       }
                       case SchemaType.BTC_FLOAT:
                       {
  -                        float f = ((XmlObjectBase)v).floatValue();
  +                        float f = ((SimpleValue)v).getFloatValue();
                           set_prepare();
                           set_float(f);
                           break;
                       }
                       case SchemaType.BTC_DOUBLE:
                       {
  -                        double d = ((XmlObjectBase)v).doubleValue();
  +                        double d = ((SimpleValue)v).getDoubleValue();
                           set_prepare();
                           set_double(d);
                           break;
  @@ -1746,35 +1743,35 @@
                           {
                               case SchemaType.SIZE_BYTE:
                               {
  -                                byte b = ((XmlObjectBase)v).byteValue();
  +                                byte b = ((SimpleValue)v).getByteValue();
                                   set_prepare();
                                   set_byte(b);
                                   break;
                               }
                               case SchemaType.SIZE_SHORT:
                               {
  -                                short s = ((XmlObjectBase)v).shortValue();
  +                                short s = ((SimpleValue)v).getShortValue();
                                   set_prepare();
                                   set_short(s);
                                   break;
                               }
                               case SchemaType.SIZE_INT:
                               {
  -                                int i = ((XmlObjectBase)v).intValue();
  +                                int i = ((SimpleValue)v).getIntValue();
                                   set_prepare();
                                   set_int(i);
                                   break;
                               }
                               case SchemaType.SIZE_LONG:
                               {
  -                                long l = ((XmlObjectBase)v).longValue();
  +                                long l = ((SimpleValue)v).getLongValue();
                                   set_prepare();
                                   set_long(l);
                                   break;
                               }
                               case SchemaType.SIZE_BIG_INTEGER:
                               {
  -                                BigInteger bi = ((XmlObjectBase)v).bigIntegerValue();
  +                                BigInteger bi = ((SimpleValue)v).getBigIntegerValue();
                                   set_prepare();
                                   set_BigInteger(bi);
                                   break;
  @@ -1786,7 +1783,7 @@
                               }
                               case SchemaType.SIZE_BIG_DECIMAL:
                               {
  -                                BigDecimal bd = ((XmlObjectBase)v).bigDecimalValue();
  +                                BigDecimal bd = ((SimpleValue)v).getBigDecimalValue();
                                   set_prepare();
                                   set_BigDecimal(bd);
                                   break;
  @@ -1810,7 +1807,7 @@
                       }
                       case SchemaType.BTC_DURATION:
                       {
  -                        GDuration gd = ((XmlObjectBase)v).gDurationValue();
  +                        GDuration gd = ((SimpleValue)v).getGDurationValue();
                           set_prepare();
                           set_GDuration(gd);
                           break;
  @@ -1824,7 +1821,7 @@
                       case SchemaType.BTC_G_DAY:
                       case SchemaType.BTC_G_MONTH:
                       {
  -                        GDate gd = ((XmlObjectBase)v).gDateValue();
  +                        GDate gd = ((SimpleValue)v).getGDateValue();
                           set_prepare();
                           set_GDate(gd);
                           break;
  @@ -1881,7 +1878,7 @@
           if (isImmutable())
               throw new IllegalStateException("Cannot set the value of an immutable XmlObject");
   
  -        XmlObjectBase obj = (XmlObjectBase) src;
  +        XmlObjectBase obj = underlying(src);
   
           TypeStoreUser newObj = this;
   
  @@ -2024,7 +2021,7 @@
               return false;
   
           if (xmlobj.schemaType().getSimpleVariety() == SchemaType.UNION)
  -            return ((XmlObjectBase)xmlobj).equal_to(this);
  +            return (underlying(xmlobj)).equal_to(this);
   
           return equal_to(xmlobj);
       }
  
  
  
  1.2       +1 -1      xml-xmlbeans/v2/src/xmlstore/org/apache/xmlbeans/impl/store/Splay.java
  
  Index: Splay.java
  ===================================================================
  RCS file: /home/cvs/xml-xmlbeans/v2/src/xmlstore/org/apache/xmlbeans/impl/store/Splay.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- Splay.java	26 Sep 2003 21:23:37 -0000	1.1
  +++ Splay.java	27 Oct 2003 19:17:21 -0000	1.2
  @@ -3190,7 +3190,7 @@
               return;
           }
   
  -        if (parentType.get_element_type( getName(), typeName ) != sType && complain)
  +        if (parentType.get_element_type( getName(), typeName ) != sType)
           {
               if (complain)
               {
  
  
  
  1.1                  xml-xmlbeans/v2/test/cases/schema/typesonly/typesonly.xsd
  
  Index: typesonly.xsd
  ===================================================================
  <xs:schema
     xmlns:xs="http://www.w3.org/2001/XMLSchema"
     xmlns:mt="http://openuri.org/typesonly"
     targetNamespace="http://openuri.org/typesonly"
     elementFormDefault="qualified"
     attributeFormDefault="unqualified" >
  
    <xs:complexType name="person">
      <xs:sequence>
        <xs:element name="firstname" type="xs:string"/>
        <xs:choice>
          <xs:element name="age">
             <xs:simpleType>
               <xs:restriction base="xs:integer">
                 <xs:minInclusive value="1"/>
                 <xs:maxInclusive value="100"/>
               </xs:restriction>
             </xs:simpleType>
          </xs:element>
          <xs:element name="birthday" type="xs:date"/>
        </xs:choice>
      </xs:sequence>
        
      <xs:attribute name="gender">
        <xs:simpleType>
          <xs:restriction base="xs:NMTOKEN">
            <xs:enumeration value="male"/>
            <xs:enumeration value="female"/>
          </xs:restriction>
        </xs:simpleType>
      </xs:attribute>
        
    </xs:complexType>
  
  </xs:schema>
  
  
  
  
  1.5       +27 -0     xml-xmlbeans/v2/test/src/drt/drtcases/BindingTests.java
  
  Index: BindingTests.java
  ===================================================================
  RCS file: /home/cvs/xml-xmlbeans/v2/test/src/drt/drtcases/BindingTests.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- BindingTests.java	16 Oct 2003 00:02:50 -0000	1.4
  +++ BindingTests.java	27 Oct 2003 19:17:22 -0000	1.5
  @@ -19,14 +19,41 @@
   import org.apache.xmlbeans.impl.binding.bts.QNameProperty;
   import org.apache.xmlbeans.impl.binding.bts.SimpleBindingType;
   import org.apache.xmlbeans.impl.binding.bts.XmlName;
  +import org.apache.xmlbeans.impl.binding.compile.JAXRPCSchemaBinder;
  +import org.apache.xmlbeans.impl.binding.compile.SchemaToJavaResult;
  +import org.apache.xmlbeans.impl.binding.compile.JavaCodeGenerator;
   import org.apache.xmlbeans.x2003.x09.bindingConfig.BindingConfigDocument;
  +import org.apache.xmlbeans.XmlBeans;
  +import org.apache.xmlbeans.XmlObject;
  +import org.apache.xmlbeans.SchemaTypeSystem;
  +import org.w3.x2001.xmlSchema.SchemaDocument;
   
   import javax.xml.namespace.QName;
  +import java.io.File;
  +import java.util.Iterator;
   
   public class BindingTests extends TestCase
   {
       public BindingTests(String name) { super(name); }
       public static Test suite() { return new TestSuite(BindingTests.class); }
  +    
  +    public void testJAXRPCBinding() throws Exception
  +    {
  +        File typesonlyfile = TestEnv.xbeanCase("schema/typesonly/typesonly.xsd");
  +        SchemaTypeSystem sts = XmlBeans.compileXsd(new XmlObject[] { SchemaDocument.Factory.parse(typesonlyfile) }, XmlBeans.getBuiltinTypeSystem(), null);
  +        SchemaToJavaResult result = JAXRPCSchemaBinder.bind(sts, BuiltinBindingLoader.getInstance());
  +        result.getBindingFileGenerator().printBindingFile(System.out);
  +        JavaCodeGenerator javacode = result.getJavaCodeGenerator();
  +        for (Iterator i = javacode.getToplevelClasses().iterator(); i.hasNext(); )
  +        {
  +            String javaclass = (String)i.next();
  +            System.out.println("=======================");
  +            System.out.println(javaclass);
  +            System.out.println("=======================");
  +            javacode.printSourceCode(javaclass, System.out);
  +        }
  +        System.out.flush();
  +    }
   
       public void testBindingFile() throws Exception
       {
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: xmlbeans-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: xmlbeans-cvs-help@xml.apache.org


Mime
View raw message