You are viewing a plain text version of this content. The canonical link for it is here.
Posted to xmlbeans-cvs@xml.apache.org by da...@apache.org on 2003/10/03 23:18:18 UTC

cvs commit: xml-xmlbeans/v2/test/src/drt/drtcases BindingTests.java

davidbau    2003/10/03 14:18:18

  Modified:    v2       build.xml
               v2/src/xmlstore/org/apache/xmlbeans/impl/store Saver.java
  Added:       v2/src/binding/org/apache/xmlbeans/impl/binding
                        BindingFile.java BindingLoader.java
                        BindingProperty.java BindingType.java
                        ByNameBean.java JavaName.java JaxbBean.java
                        KindRegistry.java ParticleProperty.java
                        PathBindingLoader.java QNameProperty.java
                        XmlName.java
               v2/src/configschema/schema binding-config.xsd
               v2/test/src/drt/drtcases BindingTests.java
  Removed:     v2/src/bindingconfig/schema binding-config.xsd
  Log:
  (1) Slightly modified binding-config.xsd to make it easier to persist
  (2) Added an in-memory API for dealing with binding config
  (3) Ported over a recent Saver.java fix from v1 to v2
  (4) Added tests for the new binding-config stuff.
  
  Code review: Scott
  DRT: passed
  
  Revision  Changes    Path
  1.3       +23 -1     xml-xmlbeans/v2/build.xml
  
  Index: build.xml
  ===================================================================
  RCS file: /home/cvs/xml-xmlbeans/v2/build.xml,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- build.xml	29 Sep 2003 19:20:29 -0000	1.2
  +++ build.xml	3 Oct 2003 21:18:18 -0000	1.3
  @@ -447,7 +447,7 @@
     <target name="xbean.jar"
           depends="dirs, xmlpublic.classes, typestore.classes,
                    common.classes, typeimpl.classes, xmlcomp.classes,
  -                 xmlstore.classes,
  +                 xmlstore.classes, binding.classes,
                    oldxbean.jar, xsdschema.classes,
                    xmlinputstream.classes">
       <jar jarfile="build/lib/xbean.jar" index="true">
  @@ -462,6 +462,7 @@
         <fileset dir="build/classes/xmlschema"/>
         <fileset dir="build/classes/xmlstore"/>
         <fileset dir="build/classes/xmlinputstream"/>
  +      <fileset dir="build/classes/binding"/>
         <fileset dir="build/classes/repackage"/>
         <fileset dir="src/license"/>
       </jar>
  @@ -601,6 +602,27 @@
       <mkdir dir="build/classes/xmlcomp"/>
       <javac srcdir="src/xmlcomp" destdir="build/classes/xmlcomp" source="1.4" debug="on">
         <classpath>
  +        <pathelement location="build/classes/xmlinputstream"/>
  +        <pathelement location="build/classes/xmlpublic"/>
  +        <pathelement location="build/classes/common"/>
  +        <pathelement location="build/classes/repackage"/>
  +        <pathelement location="build/classes/typeimpl"/>
  +        <pathelement location="build/classes/xmlconfig"/>
  +        <pathelement location="build/classes/configschema"/>
  +        <pathelement location="build/classes/toolschema"/>
  +        <pathelement location="build/classes/xsdschema"/>
  +      </classpath>
  +    </javac>
  +
  +  </target>
  +
  +  <!-- binding target =============================================== -->
  +
  +  <target name="binding.classes" depends="dirs, repackage.classes, typeimpl.classes, xmlpublic.classes, typestore.classes, configschema.classes">
  +    <mkdir dir="build/classes/binding"/>
  +    <javac srcdir="src/binding" destdir="build/classes/binding" source="1.4" debug="on">
  +      <classpath>
  +        <pathelement location="build/classes/configschema"/>
           <pathelement location="build/classes/xmlinputstream"/>
           <pathelement location="build/classes/xmlpublic"/>
           <pathelement location="build/classes/common"/>
  
  
  
  1.1                  xml-xmlbeans/v2/src/binding/org/apache/xmlbeans/impl/binding/BindingFile.java
  
  Index: BindingFile.java
  ===================================================================
  /**
   * XBeans implementation.
   * Author: David Bau
   * Date: Oct 1, 2003
   */
  package org.apache.xmlbeans.impl.binding;
  
  import org.apache.xmlbeans.XmlOptions;
  
  import java.util.Map;
  import java.util.LinkedHashMap;
  import java.util.ArrayList;
  import java.util.List;
  import java.util.Iterator;
  import java.io.IOException;
  
  public class BindingFile extends BindingLoader
  {
      private Map bindingTypes = new LinkedHashMap();    // name-pair -> BindingType
      private Map xmlFromJava = new LinkedHashMap();     // javaName -> xmlName
      private Map javaFromXmlPojo = new LinkedHashMap(); // xmlName -> javaName (pojo)
      private Map javaFromXmlObj = new LinkedHashMap();  // xmlName -> javaName (xmlobj)
      
      /**
       * This constructor is used when making a new one out of the blue.
       */ 
      public BindingFile()
      {
          // nothing to do - all maps are empty
      }
      
      /**
       * Loader
       */ 
      public static BindingFile forDoc(org.apache.xmlbeans.x2003.x09.bindingConfig.BindingConfigDocument doc)
      {
          return new BindingFile(doc);
      }
      
      /**
       * This constructor loads an instance from an XML file
       */ 
      protected BindingFile(org.apache.xmlbeans.x2003.x09.bindingConfig.BindingConfigDocument doc)
      {
          List errors = new ArrayList();
          if (!doc.validate(new XmlOptions().setErrorListener(errors)))
              throw new IllegalArgumentException(errors.size() > 0 ? errors.get(0).toString() : "Invalid binding-config document");
          
          // todo: in the loops below, validate that entries are unique, or modify schema to do so.
          
          org.apache.xmlbeans.x2003.x09.bindingConfig.BindingType[] btNodes =
                  doc.getBindingConfig().getBindings().getBindingTypeArray();
          for (int i = 0; i < btNodes.length; i++)
          {
              BindingType next = BindingType.loadFromBindingTypeNode(this, btNodes[i]);
              addBindingType(next, false, false);
          }
          org.apache.xmlbeans.x2003.x09.bindingConfig.Mapping[] mNodes =
                  doc.getBindingConfig().getJavaToXml().getMappingArray();
          for (int i = 0; i < mNodes.length; i++)
          {
              JavaName jName = JavaName.forString(mNodes[i].getJavatype());
              XmlName xName = XmlName.forString(mNodes[i].getXmlcomponent());
              xmlFromJava.put(jName, xName);
          }
          
          mNodes = doc.getBindingConfig().getXmlToPojo().getMappingArray();
          for (int i = 0; i < mNodes.length; i++)
          {
              JavaName jName = JavaName.forString(mNodes[i].getJavatype());
              XmlName xName = XmlName.forString(mNodes[i].getXmlcomponent());
              javaFromXmlPojo.put(xName, jName);
          }
  
          mNodes = doc.getBindingConfig().getXmlToXmlobj().getMappingArray();
          for (int i = 0; i < mNodes.length; i++)
          {
              JavaName jName = JavaName.forString(mNodes[i].getJavatype());
              XmlName xName = XmlName.forString(mNodes[i].getXmlcomponent());
              javaFromXmlObj.put(xName, jName);
          }
      }
      
      /**
       * Writes out to XML
       */ 
      public org.apache.xmlbeans.x2003.x09.bindingConfig.BindingConfigDocument write() throws IOException
      {
          org.apache.xmlbeans.x2003.x09.bindingConfig.BindingConfigDocument doc =
                  org.apache.xmlbeans.x2003.x09.bindingConfig.BindingConfigDocument.Factory.newInstance();
          write(doc);
          return doc;
      }
      
      /**
       * This function copies an instance into an empty doc.
       */ 
      private void write(org.apache.xmlbeans.x2003.x09.bindingConfig.BindingConfigDocument doc)
      {
          if (doc.getBindingConfig() != null)
              throw new IllegalArgumentException("Can only write into empty doc");
          org.apache.xmlbeans.x2003.x09.bindingConfig.BindingConfigDocument.BindingConfig bcNode = doc.addNewBindingConfig();
          
          // make tables
          org.apache.xmlbeans.x2003.x09.bindingConfig.BindingTable btabNode = bcNode.addNewBindings();
          org.apache.xmlbeans.x2003.x09.bindingConfig.MappingTable jtabNode = bcNode.addNewJavaToXml();
          org.apache.xmlbeans.x2003.x09.bindingConfig.MappingTable pojotabNode = bcNode.addNewXmlToPojo();
          org.apache.xmlbeans.x2003.x09.bindingConfig.MappingTable xotabNode = bcNode.addNewXmlToXmlobj();
          
          // fill em in: binding types (delegate to BindingType.write)
          for (Iterator i = bindingTypes.values().iterator(); i.hasNext(); )
          {
              BindingType bType = (BindingType)i.next();
              org.apache.xmlbeans.x2003.x09.bindingConfig.BindingType btNode = btabNode.addNewBindingType();
              bType.write(btNode);
          }
  
          // from-java mappings
          for (Iterator i = xmlFromJava.entrySet().iterator(); i.hasNext(); )
          {
              Map.Entry entry = (Map.Entry)i.next();
              JavaName jName = (JavaName)entry.getKey();
              XmlName xName = (XmlName)entry.getValue();
              org.apache.xmlbeans.x2003.x09.bindingConfig.Mapping mNode = jtabNode.addNewMapping();
              mNode.setJavatype(jName.toString());
              mNode.setXmlcomponent(xName.toString());
          }
              
          // to-pojo
          for (Iterator i = javaFromXmlPojo.entrySet().iterator(); i.hasNext(); )
          {
              Map.Entry entry = (Map.Entry)i.next();
              JavaName jName = (JavaName)entry.getValue();
              XmlName xName = (XmlName)entry.getKey();
              org.apache.xmlbeans.x2003.x09.bindingConfig.Mapping mNode = pojotabNode.addNewMapping();
              mNode.setJavatype(jName.toString());
              mNode.setXmlcomponent(xName.toString());
          }
  
          // to-xmlobj
          for (Iterator i = javaFromXmlObj.entrySet().iterator(); i.hasNext(); )
          {
              Map.Entry entry = (Map.Entry)i.next();
              JavaName jName = (JavaName)entry.getValue();
              XmlName xName = (XmlName)entry.getKey();
              org.apache.xmlbeans.x2003.x09.bindingConfig.Mapping mNode = xotabNode.addNewMapping();
              mNode.setJavatype(jName.toString());
              mNode.setXmlcomponent(xName.toString());
          }
      }
  
  
      public void addBindingType(BindingType bType, boolean fromJavaDefault, boolean fromXmlDefault)
      {
          bindingTypes.put(pair(bType.getJavaName(), bType.getXmlName()), bType);
          if (fromJavaDefault)
          {
              if (bType.isXmlObject())
                  javaFromXmlObj.put(bType.getXmlName(), bType.getJavaName());
              else
                  javaFromXmlPojo.put(bType.getXmlName(), bType.getJavaName());
          }
          if (fromXmlDefault)
          {
              xmlFromJava.put(bType.getJavaName(), bType.getXmlName());
          }
      }
      
      public BindingType getBindingType(JavaName jName, XmlName xName)
      {
          return (BindingType)bindingTypes.get(pair(jName, xName));
      }
      
      public BindingType getBindingTypeForXmlPojo(XmlName xName)
      {
          JavaName jName = (JavaName)javaFromXmlPojo.get(xName);
          if (jName == null)
              return null;
          
          return (BindingType)bindingTypes.get(pair(jName, xName));
      }
  
      public BindingType getBindingTypeForXmlObj(XmlName xName)
      {
          JavaName jName = (JavaName)javaFromXmlObj.get(xName);
          if (jName == null)
              return null;
          
          return (BindingType)bindingTypes.get(pair(jName, xName));
      }
      
      public BindingType getBindingTypeForJava(JavaName jName)
      {
          XmlName xName = (XmlName)xmlFromJava.get(jName);
          if (xName == null)
              return null;
          
          return (BindingType)bindingTypes.get(pair(jName, xName));
      }
      
      
      protected static NamePair pair(JavaName jName, XmlName xName)
      {
          return new NamePair(jName, xName);
      }
  
      private static class NamePair
      {
          private final JavaName jName;
          private final XmlName xName;
  
          NamePair(JavaName jName, XmlName xName)
          {
              this.jName = jName;
              this.xName = xName;
          }
  
          public JavaName getJavaName()
          {
              return jName;
          }
  
          public XmlName getXmlName()
          {
              return xName;
          }
  
          public boolean equals(Object o)
          {
              if (this == o) return true;
              if (!(o instanceof BindingFile.NamePair)) return false;
  
              final BindingFile.NamePair namePair = (BindingFile.NamePair) o;
  
              if (!jName.equals(namePair.jName)) return false;
              if (!xName.equals(namePair.xName)) return false;
  
              return true;
          }
  
          public int hashCode()
          {
              int result;
              result = jName.hashCode();
              result = 29 * result + xName.hashCode();
              return result;
          }
      }
      
  }
  
  
  
  1.1                  xml-xmlbeans/v2/src/binding/org/apache/xmlbeans/impl/binding/BindingLoader.java
  
  Index: BindingLoader.java
  ===================================================================
  /**
   * XBeans implementation.
   * Author: David Bau
   * Date: Oct 2, 2003
   */
  package org.apache.xmlbeans.impl.binding;
  
  public abstract class BindingLoader
  {
      public abstract BindingType getBindingType(JavaName jName, XmlName xName);
  
      public abstract BindingType getBindingTypeForXmlPojo(XmlName xName);
  
      public abstract BindingType getBindingTypeForXmlObj(XmlName xName);
  
      public abstract BindingType getBindingTypeForJava(JavaName jName);
  
  }
  
  
  
  1.1                  xml-xmlbeans/v2/src/binding/org/apache/xmlbeans/impl/binding/BindingProperty.java
  
  Index: BindingProperty.java
  ===================================================================
  /**
   * XBeans implementation.
   * Author: David Bau
   * Date: Oct 1, 2003
   */
  package org.apache.xmlbeans.impl.binding;
  
  import org.apache.xmlbeans.SchemaType;
  
  public abstract class BindingProperty
  {
      private BindingLoader bLoader;
      
      private JavaName tJava;
      private XmlName tXml;
      private String getter;
      private String setter;
      private String field;
      private JavaName collection;
      
      /**
       * This kind of constructor is used when making a new one out of the blue.
       * 
       * Subclasses should call super(..) when defining constructors that init new BindingTypes.
       */ 
      protected BindingProperty(BindingLoader bFile)
      {
          this.bLoader = bFile;
      }
      
      /**
       * This constructor loads an instance from an XML file
       * 
       * Subclasses should have ctors of the same signature and call super(..) first.
       */ 
      protected BindingProperty(BindingLoader bLoader, org.apache.xmlbeans.x2003.x09.bindingConfig.BindingProperty node)
      {
          this.bLoader = bLoader;
          this.tJava = JavaName.forString(node.getJavatype());
          this.tXml = XmlName.forString(node.getXmlcomponent());
          this.getter = node.getGetter();
          this.setter = node.getSetter();
          this.field = node.getField();
          String collection = node.getCollection();
          if (collection != null)
              this.collection = JavaName.forString(collection);
      }
      
      /**
       * This function copies an instance back out to the relevant part of the XML file.
       * 
       * Subclasses should override and call super.write first.
       */ 
      protected org.apache.xmlbeans.x2003.x09.bindingConfig.BindingProperty write(org.apache.xmlbeans.x2003.x09.bindingConfig.BindingProperty node)
      {
          node = (org.apache.xmlbeans.x2003.x09.bindingConfig.BindingProperty)node.changeType(kinds.typeForClass(this.getClass()));
          
          node.setJavatype(tJava.toString());
          node.setXmlcomponent(tXml.toString());
          if (getFieldName() != null)
              node.setField(getFieldName());
          if (getGetterName() != null)
              node.setGetter(getGetterName());
          if (getSetterName() != null)
              node.setSetter(getSetterName());
          if (getCollectionClass() != null)
              node.setCollection(getCollectionClass().toString());
          return node;
      }
      
      public boolean isField()
      {
          return field != null;
      }
      
      public BindingType getBindingType()
      {
          return bLoader.getBindingType(tJava, tXml);
      }
      
      public void setBindingType(BindingType bType)
      {
          this.tJava = bType.getJavaName();
          this.tXml = bType.getXmlName();
      }
      
      public String getGetterName()
      {
          return isField() ? null : getter;
      }
      
      public void setGetterName(String getter)
      {
          this.getter = getter;
      }
      
      public boolean hasSetter()
      {
          return !isField() && setter != null;
      }
      
      public String getSetterName()
      {
          return isField() ? null : setter;
      }
      
      public void setSetterName(String setter)
      {
          this.setter = setter; 
      }
      
      public String getFieldName()
      {
          return field;
      }
      
      public void setFieldName(String field)
      {
          this.field = field;
      }
      
      public JavaName getCollectionClass()
      {
          return collection;
      }
      
      public void setCollectionClass(JavaName jName)
      {
          collection = jName;
      }
      
      /* REGISTRY OF SUBCLASSES */
      
      private static final Class[] ctorArgs = new Class[] {BindingLoader.class, org.apache.xmlbeans.x2003.x09.bindingConfig.BindingProperty.class};
      
      public static BindingProperty forNode(BindingLoader bLoader, org.apache.xmlbeans.x2003.x09.bindingConfig.BindingProperty node)
      {
          try
          {
              Class clazz = kinds.classForType(node.schemaType());
              return (BindingProperty)clazz.getConstructor(ctorArgs).newInstance(new Object[] {bLoader, node});
          }
          catch (Exception e)
          {
              throw (IllegalStateException)new IllegalStateException("Cannot load class for " + node.schemaType() + ": should be registered.").initCause(e);
          }
      }
      
      /**
       * Should only be called by BindingFile, when loading up bindingtypes
       */
      static KindRegistry kinds = new KindRegistry();
      
      public static void registerClassAndType(Class clazz, SchemaType type)
      {
          if (!BindingProperty.class.isAssignableFrom(clazz))
              throw new IllegalArgumentException("Classes must inherit from BindingProperty");
          if (!org.apache.xmlbeans.x2003.x09.bindingConfig.BindingProperty.type.isAssignableFrom(type))
              throw new IllegalArgumentException("Schema types must inherit from binding-property");
          kinds.registerClassAndType(clazz, type);
      }
      
      static
      {
          registerClassAndType(QNameProperty.class, org.apache.xmlbeans.x2003.x09.bindingConfig.QnameProperty.type);
          registerClassAndType(ParticleProperty.class, org.apache.xmlbeans.x2003.x09.bindingConfig.ParticleProperty.type);
      }
  }
  
  
  
  1.1                  xml-xmlbeans/v2/src/binding/org/apache/xmlbeans/impl/binding/BindingType.java
  
  Index: BindingType.java
  ===================================================================
  /**
   * XBeans implementation.
   * Author: David Bau
   * Date: Oct 1, 2003
   */
  package org.apache.xmlbeans.impl.binding;
  
  import org.apache.xmlbeans.SchemaType;
  
  public abstract class BindingType
  {
      private BindingLoader bLoader;
      private JavaName jName;
      private XmlName xName;
      private boolean isXmlObj;
      
      /**
       * This kind of constructor is used when making a new one out of the blue.
       * 
       * Subclasses should call super(..) when defining constructors that init new BindingTypes.
       */ 
      protected BindingType(BindingLoader bLoader, JavaName jName, XmlName xName, boolean isXmlObj)
      {
          this.bLoader = bLoader;
          this.jName = jName;
          this.xName = xName;
          this.isXmlObj = isXmlObj;
      }
      
      /**
       * This constructor loads an instance from an XML file
       * 
       * Subclasses should have ctors of the same signature and call super(..) first.
       */ 
      protected BindingType(BindingLoader bLoader, org.apache.xmlbeans.x2003.x09.bindingConfig.BindingType node)
      {
          this.bLoader = bLoader;
          this.jName = JavaName.forString(node.getJavatype());
          this.xName = XmlName.forString(node.getXmlcomponent());
          this.isXmlObj = node.getXmlobj();
      }
      
      /**
       * This function copies an instance back out to the relevant part of the XML file.
       * 
       * Subclasses should override and call super.write first.
       */ 
      protected org.apache.xmlbeans.x2003.x09.bindingConfig.BindingType write(org.apache.xmlbeans.x2003.x09.bindingConfig.BindingType node)
      {
          node = (org.apache.xmlbeans.x2003.x09.bindingConfig.BindingType)node.changeType(kinds.typeForClass(this.getClass()));
          node.setJavatype(jName.toString());
          node.setXmlcomponent(xName.toString());
          node.setXmlobj(isXmlObj);
          return node;
      }
      
      public final BindingLoader getBindingLoader()
      {
          return bLoader;
      }
      
      public final JavaName getJavaName()
      {
          return jName;
      }
      
      public final XmlName getXmlName()
      {
          return xName;
      }
      
      public final boolean isXmlObject()
      {
          return isXmlObj;
      }
      
      
      /* REGISTRY OF SUBCLASSES */
      
      private static final Class[] ctorArgs = new Class[] {BindingLoader.class, org.apache.xmlbeans.x2003.x09.bindingConfig.BindingType.class};
      
      public static BindingType loadFromBindingTypeNode(BindingLoader bLoader, org.apache.xmlbeans.x2003.x09.bindingConfig.BindingType node)
      {
          try
          {
              Class clazz = kinds.classForType(node.schemaType());
              return (BindingType)clazz.getConstructor(ctorArgs).newInstance(new Object[] {bLoader, node});
          }
          catch (Exception e)
          {
              throw (IllegalStateException)new IllegalStateException("Cannot load class for " + node.schemaType() + ": should be registered.").initCause(e);
          }
      }
      
      /**
       * Should only be called by BindingFile, when loading up bindingtypes
       */
      static KindRegistry kinds = new KindRegistry();
      
      public static void registerClassAndType(Class clazz, SchemaType type)
      {
          if (!BindingType.class.isAssignableFrom(clazz))
              throw new IllegalArgumentException("Classes must inherit from BindingType");
          if (!org.apache.xmlbeans.x2003.x09.bindingConfig.BindingType.type.isAssignableFrom(type))
              throw new IllegalArgumentException("Schema types must inherit from binding-type");
          kinds.registerClassAndType(clazz, type);
      }
      
      static
      {
          registerClassAndType(JaxbBean.class, org.apache.xmlbeans.x2003.x09.bindingConfig.JaxbBean.type);
          registerClassAndType(ByNameBean.class, org.apache.xmlbeans.x2003.x09.bindingConfig.ByNameBean.type);
      }
  
  }
  
  
  
  1.1                  xml-xmlbeans/v2/src/binding/org/apache/xmlbeans/impl/binding/ByNameBean.java
  
  Index: ByNameBean.java
  ===================================================================
  /**
   * XBeans implementation.
   * Author: David Bau
   * Date: Oct 1, 2003
   */
  package org.apache.xmlbeans.impl.binding;
  
  import javax.xml.namespace.QName;
  import java.util.Map;
  import java.util.List;
  import java.util.ArrayList;
  import java.util.HashMap;
  import java.util.Iterator;
  import java.util.Collections;
  import java.util.Collection;
  
  public class ByNameBean extends BindingType
  {
      List props = new ArrayList(); // of QNameProperties
      Map eltProps = new HashMap(); // QName -> prop (elts)
      Map attProps = new HashMap(); // QName -> prop (attrs)
      
      public ByNameBean(BindingLoader bLoader, JavaName jName, XmlName xName, boolean isXmlObj)
      {
          super(bLoader, jName, xName, isXmlObj);
      }
  
      public ByNameBean(BindingLoader bFile, org.apache.xmlbeans.x2003.x09.bindingConfig.BindingType node)
      {
          super(bFile, node);
          
          org.apache.xmlbeans.x2003.x09.bindingConfig.QnameProperty[] propArray =
             ((org.apache.xmlbeans.x2003.x09.bindingConfig.ByNameBean)node).getQnamePropertyArray();
          
          for (int i = 0; i < propArray.length; i++)
          {
              addProperty((QNameProperty)BindingProperty.forNode(getBindingLoader(), propArray[i]));
          }
      }
      
      /**
       * This function copies an instance back out to the relevant part of the XML file.
       * 
       * Subclasses should override and call super.write first.
       */ 
      protected org.apache.xmlbeans.x2003.x09.bindingConfig.BindingType write(org.apache.xmlbeans.x2003.x09.bindingConfig.BindingType node)
      {
          org.apache.xmlbeans.x2003.x09.bindingConfig.ByNameBean bnNode = (org.apache.xmlbeans.x2003.x09.bindingConfig.ByNameBean)super.write(node);
          for (Iterator i = props.iterator(); i.hasNext(); )
          {
              QNameProperty qProp = (QNameProperty)i.next();
              org.apache.xmlbeans.x2003.x09.bindingConfig.QnameProperty qpNode = bnNode.addNewQnameProperty();
              qProp.write(qpNode);
          }
          return bnNode;
      }
      
      /**
       * Returns an unmodifiable collection of QNameProperty objects.
       */ 
      public Collection getProperties()
      {
          return Collections.unmodifiableCollection(props);
      }
      
      /**
       * Looks up a property by attribute name, null if no match.
       */ 
      public QNameProperty getPropertyForAttribute(QName name)
      {
          return (QNameProperty)attProps.get(name);
      }
      
      /**
       * Looks up a property by element name, null if no match.
       */ 
      public QNameProperty getPropertyForElement(QName name)
      {
          return (QNameProperty)eltProps.get(name);
      }
      
      /**
       * Adds a new property
       */
      public void addProperty(QNameProperty newProp)
      {
          if (newProp.isAttribute() ? attProps.containsKey(newProp.getQName()) : eltProps.containsKey(newProp.getQName()))
              throw new IllegalArgumentException();
          
          props.add(newProp);
          if (newProp.isAttribute())
              attProps.put(newProp.getQName(), newProp);
          else
              eltProps.put(newProp.getQName(), newProp);
      }
  }
  
  
  
  1.1                  xml-xmlbeans/v2/src/binding/org/apache/xmlbeans/impl/binding/JavaName.java
  
  Index: JavaName.java
  ===================================================================
  /**
   * XBeans implementation.
   * Author: David Bau
   * Date: Oct 1, 2003
   */
  package org.apache.xmlbeans.impl.binding;
  
  public final class JavaName
  {
      private final String className;
      private final String arrayString;
  
      /**
       * Returns a JavaName object for a fully-qualified class name.
       * The class-name should be dot-separated for packages and
       * dollar-separated for inner classes.
       * 
       * The names "int", "byte" etc are considered special.
       * Arrays are dealt with as [][][] at the end.
       * 
       * This is a static function to permit pooling in the future.
       */
      public static JavaName forString(String className)
      {
          return new JavaName(className);
      }
      
      /**
       * Do not use this constructor; use forClassName instead.
       */ 
      private JavaName(String className)
      {
          if (className == null)
              throw new IllegalArgumentException();
          
          int arrayDepth = 0;
          for (int i = className.length() - 2; i >= 0; i -= 2)
          {
              if (className.charAt(i) != '[' || className.charAt(i + 1) != ']')
                  break;
              arrayDepth += 1;
          }
          this.className = className.substring(0, className.length() - 2 * arrayDepth);
          this.arrayString = className.substring(className.length() - 2 * arrayDepth);
      }
      
      /**
       * Returns the fully-qualified class name.
       */ 
      public String toString()
      {
          return className + arrayString;
      }
      
      /**
       * Returns the array depth, 0 for non-arrays, 1 for [], 2 for [][], etc.
       */ 
      public int getArrayDepth()
      {
          return arrayString.length() / 2;
      }
      
      /**
       * Returns the dot-separated package name.
       */ 
      public String getPackage()
      {
          int index = className.lastIndexOf('.');
          if (index <= 0)
              return "";
          return className.substring(0, index);
      }
      
      /**
       * True if this is an inner class name.
       */ 
      public boolean isInnerClass()
      {
          return (className.lastIndexOf('$') >= 0);
      }
      
      /**
       * Returns the JavaName of the containing class, or null if this
       * is not an inner class name.
       */ 
      public JavaName getContainingClass()
      {
          int index = className.lastIndexOf('$');
          if (index < 0)
              return null;
          return JavaName.forString(className.substring(0, index));
      }
      
      /**
       * Returns the short class name (i.e., no dots or dollars).
       */ 
      public String getShortClassName()
      {
          int index = className.lastIndexOf('$');
          int index2 = className.lastIndexOf('.');
          if (index2 > index)
              index = index2;
          if (index < 0)
              return className;
          return className.substring(index + 1);
      }
  
      public boolean equals(Object o)
      {
          if (this == o) return true;
          if (!(o instanceof JavaName)) return false;
  
          final JavaName javaName = (JavaName) o;
  
          if (!className.equals(javaName.className)) return false;
  
          return true;
      }
  
      public int hashCode()
      {
          return className.hashCode();
      }
  }
  
  
  
  1.1                  xml-xmlbeans/v2/src/binding/org/apache/xmlbeans/impl/binding/JaxbBean.java
  
  Index: JaxbBean.java
  ===================================================================
  /**
   * XBeans implementation.
   * Author: David Bau
   * Date: Oct 1, 2003
   */
  package org.apache.xmlbeans.impl.binding;
  
  import javax.xml.namespace.QName;
  import java.util.List;
  import java.util.ArrayList;
  import java.util.Map;
  import java.util.Iterator;
  import java.util.Collection;
  import java.util.Collections;
  import java.util.LinkedHashMap;
  
  public class JaxbBean extends BindingType
  {
      Map partProps = new LinkedHashMap(); // XmlName -> prop (particles)
      Map eltProps = new LinkedHashMap(); // QName -> prop (elts)
      Map attProps = new LinkedHashMap(); // QName -> prop (attrs)
      
      public JaxbBean(BindingLoader bFile, JavaName jName, XmlName xName)
      {
          super(bFile, jName, xName, false);
      }
  
      public JaxbBean(BindingLoader bFile, org.apache.xmlbeans.x2003.x09.bindingConfig.BindingType node)
      {
          super(bFile, node);
          
          org.apache.xmlbeans.x2003.x09.bindingConfig.JaxbBean jbNode = (org.apache.xmlbeans.x2003.x09.bindingConfig.JaxbBean)node;
          
          org.apache.xmlbeans.x2003.x09.bindingConfig.ParticleProperty[] ppropArray = jbNode.getParticlePropertyArray();
          for (int i = 0; i < ppropArray.length; i++)
          {
              addProperty(BindingProperty.forNode(getBindingLoader(), ppropArray[i]));
          }
          
          org.apache.xmlbeans.x2003.x09.bindingConfig.QnameProperty[] qpropArray = jbNode.getQnamePropertyArray();
          for (int i = 0; i < qpropArray.length; i++)
          {
              addProperty(BindingProperty.forNode(getBindingLoader(), qpropArray[i]));
          }
      }
      
      
      /**
       * This function copies an instance back out to the relevant part of the XML file.
       * 
       * Subclasses should override and call super.write first.
       */ 
      protected org.apache.xmlbeans.x2003.x09.bindingConfig.BindingType write(org.apache.xmlbeans.x2003.x09.bindingConfig.BindingType node)
      {
          org.apache.xmlbeans.x2003.x09.bindingConfig.JaxbBean jbNode = (org.apache.xmlbeans.x2003.x09.bindingConfig.JaxbBean)super.write(node);
          for (Iterator i = getProperties().iterator(); i.hasNext(); )
          {
              BindingProperty bProp = (BindingProperty)i.next();
              if (bProp instanceof ParticleProperty)
              {
                  org.apache.xmlbeans.x2003.x09.bindingConfig.ParticleProperty ppNode = jbNode.addNewParticleProperty();
                  bProp.write(ppNode);
              }
              else
              {
                  org.apache.xmlbeans.x2003.x09.bindingConfig.QnameProperty qpNode = jbNode.addNewQnameProperty();
                  bProp.write(qpNode);
                  
              }
          }
          return jbNode;
      }
      
      /**
       * Returns an unmodifiable collection of QNameProperty objects.
       */ 
      public Collection getProperties()
      {
          List result = new ArrayList();
          result.addAll(partProps.values());
          result.addAll(eltProps.values());
          result.addAll(attProps.values());
          return Collections.unmodifiableCollection(result);
      }
      
      /**
       * Looks up a property by attribute name, null if no match.
       */ 
      public QNameProperty getPropertyForAttribute(QName name)
      {
          return (QNameProperty)attProps.get(name);
      }
      
      /**
       * Looks up a property by element name, null if no match.
       */ 
      public QNameProperty getPropertyForElement(QName name)
      {
          return (QNameProperty)eltProps.get(name);
      }
      
      /**
       * Adds a new property
       */
      public void addProperty(BindingProperty newProp)
      {
          if (newProp instanceof ParticleProperty)
          {
              partProps.put(newProp.getBindingType().getXmlName(), newProp);
          }
          else if (newProp instanceof QNameProperty)
          {
              QNameProperty qProp = (QNameProperty)newProp;
              if (qProp.isAttribute())
                  attProps.put(qProp.getQName(), newProp);
              else
                  eltProps.put(qProp.getQName(), newProp);
          }
          else
          {
              throw new IllegalArgumentException();
          }
      }
      
  }
  
  
  
  1.1                  xml-xmlbeans/v2/src/binding/org/apache/xmlbeans/impl/binding/KindRegistry.java
  
  Index: KindRegistry.java
  ===================================================================
  /**
   * XBeans implementation.
   * Author: David Bau
   * Date: Oct 2, 2003
   */
  package org.apache.xmlbeans.impl.binding;
  
  import org.apache.xmlbeans.SchemaType;
  
  import java.util.Map;
  import java.util.HashMap;
  
  
  /* package protected */
  
  /**
   * Note that this is NOT a generic binding registry for users' binding; this is
   * a registry that is used internally just to manage binding between
   * XBeans for BindingTypes and BindingType wrapper classes.  The reason
   * for this mechanism is that XMLBeans binding is NOT YET powerful enough
   * to bind the various kinds of BindingTypes directly to schema yet.
   * 
   * However, in the future, we hope to make it powerful enough to do so,
   * so that most of the hand-coded binding betwen Java and XML can go away.
   * This class, and all the mechanisms that use it, should go away too.
   */
  class KindRegistry
  {
      private Map registryClassFromType = new HashMap();
      private Map registryTypeFromClass = new HashMap();
      
      synchronized void registerClassAndType(Class bindingTypeClass, SchemaType bindingTypeSchemaType)
      {
          registryClassFromType.put(bindingTypeSchemaType, bindingTypeClass);
          registryTypeFromClass.put(bindingTypeClass, bindingTypeSchemaType);
      }
      
      synchronized Class classForType(SchemaType type)
      {
          return (Class)registryClassFromType.get(type);
      }
      
      synchronized SchemaType typeForClass(Class clazz)
      {
          return (SchemaType)registryTypeFromClass.get(clazz);
      }
  }
  
  
  
  1.1                  xml-xmlbeans/v2/src/binding/org/apache/xmlbeans/impl/binding/ParticleProperty.java
  
  Index: ParticleProperty.java
  ===================================================================
  /**
   * XBeans implementation.
   * Author: David Bau
   * Date: Oct 1, 2003
   */
  package org.apache.xmlbeans.impl.binding;
  
  public class ParticleProperty extends BindingProperty
  {
      public ParticleProperty(BindingLoader bFile)
      {
          super(bFile);
      }
  
      public ParticleProperty(BindingLoader bFile, org.apache.xmlbeans.x2003.x09.bindingConfig.BindingProperty node)
      {
          super(bFile, node);
      }
  }
  
  
  
  1.1                  xml-xmlbeans/v2/src/binding/org/apache/xmlbeans/impl/binding/PathBindingLoader.java
  
  Index: PathBindingLoader.java
  ===================================================================
  /**
   * XBeans implementation.
   * Author: David Bau
   * Date: Oct 2, 2003
   */
  package org.apache.xmlbeans.impl.binding;
  
  import java.util.ArrayList;
  import java.util.List;
  import java.util.Iterator;
  import java.util.IdentityHashMap;
  import java.util.Collections;
  import java.util.Collection;
  
  public class PathBindingLoader extends BindingLoader
  {
      private final Collection loaderPath;
      public static final PathBindingLoader EMPTY_LOADER = new PathBindingLoader(Collections.EMPTY_LIST);
      
      public static BindingLoader forPath(BindingLoader[] pathArray)
      {
          IdentityHashMap seen = new IdentityHashMap();
          
          List path = new ArrayList(pathArray.length);
          for (int i = 0; i < pathArray.length; i++)
              addToPath(path, seen, pathArray[i]);
          
          if (path.size() == 0)
              return EMPTY_LOADER;
          
          if (path.size() == 1)
              return (BindingLoader)path.get(0);
          
          return new PathBindingLoader(path);
      }
      
      private static void addToPath(List path, IdentityHashMap seen, BindingLoader loader)
      {
          if (seen.containsKey(loader))
              return;
          
          if (loader instanceof PathBindingLoader)
              for (Iterator j = ((PathBindingLoader)path).loaderPath.iterator(); j.hasNext(); )
                  addToPath(path, seen, (BindingLoader)j.next());
          else
              path.add(loader);
      }
      
      private PathBindingLoader(List path)
      {
          loaderPath = Collections.unmodifiableList(path);
      }
      
      public BindingType getBindingType(JavaName jName, XmlName xName)
      {
          BindingType result = null;
          for (Iterator i = loaderPath.iterator(); i.hasNext(); )
          {
              result = ((BindingLoader)i.next()).getBindingType(jName, xName);
              if (result != null)
                  return result;
          }
          return null;
      }
  
      public BindingType getBindingTypeForXmlPojo(XmlName xName)
      {
          BindingType result = null;
          for (Iterator i = loaderPath.iterator(); i.hasNext(); )
          {
              result = ((BindingLoader)i.next()).getBindingTypeForXmlPojo(xName);
              if (result != null)
                  return result;
          }
          return null;
      }
  
      public BindingType getBindingTypeForXmlObj(XmlName xName)
      {
          BindingType result = null;
          for (Iterator i = loaderPath.iterator(); i.hasNext(); )
          {
              result = ((BindingLoader)i.next()).getBindingTypeForXmlObj(xName);
              if (result != null)
                  return result;
          }
          return null;
      }
  
      public BindingType getBindingTypeForJava(JavaName jName)
      {
          BindingType result = null;
          for (Iterator i = loaderPath.iterator(); i.hasNext(); )
          {
              result = ((BindingLoader)i.next()).getBindingTypeForJava(jName);
              if (result != null)
                  return result;
          }
          return null;
      }
  }
  
  
  
  1.1                  xml-xmlbeans/v2/src/binding/org/apache/xmlbeans/impl/binding/QNameProperty.java
  
  Index: QNameProperty.java
  ===================================================================
  /**
   * XBeans implementation.
   * Author: David Bau
   * Date: Oct 1, 2003
   */
  package org.apache.xmlbeans.impl.binding;
  
  import javax.xml.namespace.QName;
  
  public class QNameProperty extends BindingProperty
  {
      private QName theName;
      private boolean isAttribute;
      private boolean isMultiple;
      private boolean isOptional;
      private boolean isNillable;
      
      public QNameProperty(BindingLoader bFile)
      {
          super(bFile);
      }
  
      public QNameProperty(BindingLoader bFile, org.apache.xmlbeans.x2003.x09.bindingConfig.BindingProperty node)
      {
          super(bFile, node);
          org.apache.xmlbeans.x2003.x09.bindingConfig.QnameProperty qpNode =
                  (org.apache.xmlbeans.x2003.x09.bindingConfig.QnameProperty)node;
          theName = qpNode.getQname();
          isAttribute = qpNode.getAttribute();
          isMultiple = qpNode.getMultiple();
          isNillable = qpNode.getNillable();
          isOptional = qpNode.getOptional();
      }
      
      /**
       * This function copies an instance back out to the relevant part of the XML file.
       * 
       * Subclasses should override and call super.write first.
       */ 
      protected org.apache.xmlbeans.x2003.x09.bindingConfig.BindingProperty write(org.apache.xmlbeans.x2003.x09.bindingConfig.BindingProperty node)
      {
          node = super.write(node);
          
          org.apache.xmlbeans.x2003.x09.bindingConfig.QnameProperty qpNode =
                  (org.apache.xmlbeans.x2003.x09.bindingConfig.QnameProperty)node;
          
          qpNode.setQname(theName);
          if (isAttribute)
              qpNode.setAttribute(true);
          if (isMultiple)
              qpNode.setMultiple(true);
          if (isOptional)
              qpNode.setOptional(true);
          if (isNillable)
              qpNode.setNillable(true);
          return qpNode;
      }
  
      public QName getQName()
      {
          return theName;
      }
      
      public void setQName(QName theName)
      {
          this.theName = theName;
      }
  
      public boolean isAttribute()
      {
          return isAttribute;
      }
  
      public void setAttribute(boolean attribute)
      {
          isAttribute = attribute;
      }
  
      public boolean isMultiple()
      {
          return isMultiple;
      }
  
      public void setMultiple(boolean multiple)
      {
          isMultiple = multiple;
      }
  
      public boolean isOptional()
      {
          return isOptional;
      }
  
      public void setOptional(boolean optional)
      {
          isOptional = optional;
      }
  
      public boolean isNillable()
      {
          return isNillable;
      }
  
      public void setNillable(boolean nillable)
      {
          isNillable = nillable;
      }
  }
  
  
  
  1.1                  xml-xmlbeans/v2/src/binding/org/apache/xmlbeans/impl/binding/XmlName.java
  
  Index: XmlName.java
  ===================================================================
  /**
   * XBeans implementation.
   * Author: David Bau
   * Date: Oct 1, 2003
   */
  package org.apache.xmlbeans.impl.binding;
  
  import org.apache.xmlbeans.impl.common.XMLChar;
  
  import javax.xml.namespace.QName;
  
  /**
   * An XmlName is a way of uniquely identifying any
   * logical component in a schema.
   * 
   * For a diagram of the kinds of components that can be referenced,
   * see http://www.w3.org/TR/xmlschema-1/components.gif
   * 
   * A signature looks like this:
   * 
   * a-name1|t|e=name2|p.3|s|p.5|c|p.0|t|e=name3@my-namespace
   * 
   * This reads as:
   * The attribute declaration called "name1" (unqualified) inside
   * the anonymous type of
   * the element declaration called "name2" (qualified) which is
   * the third particle of
   * the sequence which is
   * the fifth particle of
   * the choice which is
   * the zeroth particle of
   * the anonymous type of
   * the element named name3 (qualified) in
   * the namespace my-namespace.
   * 
   * Hyphens (-) introduce unqualified names
   * Equals (=) introduce qualified names
   * Dot (.) introduce numbers
   * Anonymous components are just single-letters.
   *
   * There are these types of components
   *
   * n = Notations (named, global only)
   * e = Element decls (named, global or inside t or p)
   * Identity constraint defs
   *   k = key/unique/keyref (named, in elts only)
   * g = Model group defs (named, global only)
   * Model group compositors:
   *   l = All compositors (anon, inside p or g)
   *   s = Sequence compositors (anon, inside p or g)
   *   c = Choice compositors (anon, inside p or g)
   * p = Particles (numbered, inside t or l or s or c)
   * w = Wildcards (anon, inside p only)
   * v = Attribute Uses (named, in type only, inside t)
   * a = Attribute Declarations (named, global or inside t or v)
   * r = Attribute group definitions (named, global only)
   * t = Type definitions (name when global, or anon inside i, m, e, a, t)
   * 
   * Not part of the spec, but we treat as components:
   * d = document type definition (named, global only)
   * b = attribute-container type definition (named, global only)
   * m = union member definition (numbered, inside t only)
   * y = soap array of dimension n (numbered, referencing global t or another y only)
   *
   * A canonical signature will shortcut the following:
   * 
   * - global elements do not need to be explicitly nested inside their
   *   containing document types (e=name|d=name@namespace -> e=name@namespace)
   * - global attributes do not need to be explicitly nested inside their
   *   containing attribute types (e=name|d=name@namespace -> e=name@namespace)
   * - an element of a type, if its name is unique, may be referenced without the
   *   intervening particle path.  (e.g., e=name2|p.3|s|p.5|c|p.0|t can be
   *   reduced to e=name2|t)
   * - an attribute of a type may be referenced without explicitly putting it
   *   inside an attribute use (e.g., a-name1|v-name1|t -> a-name1|t)
   * 
   * Notice SOAP arrays are included in the naming schema, as follows:
   * 
   * A soap array type written like this:
   *     x:drg[,,,][,][,,,]
   * 
   * Has the following signature:
   *     y.3|y.2|y.4|t=drg@foobar
   */
  public class XmlName
  {
      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';
      
      /**
       * This function is used to see if a path is valid or not.
       */ 
      public boolean valid()
      {
          XmlName outerComponent = null;
          int outerType = 0;
          String localName = internalGetStringName();
          
          boolean hasNumber = internalGetNumber() >= 0;
          boolean hasName = (localName != null);
          boolean isAnonymous = internalIsAnonymous();
          boolean isQualified = internalIsQualified();
          boolean isGlobal = !isNestedComponent();
      
          if (!isGlobal)
          {
              outerComponent = getOuterComponent();
              outerType = outerComponent.getComponentType();
          }
          
          boolean result;
          
          if (localName != null && !XMLChar.isValidNCName(localName))
              return false;
          
          switch (getComponentType())
          {
              case NOTATION:
                  result = (isGlobal && hasName && isQualified);
                  
              case ELEMENT:
                  result = (hasName && (isGlobal && isQualified || outerType == TYPE || outerType == PARTICLE));
                  
              case ID_CONSTRAINT:
                  result = (hasName && outerType == ELEMENT);
                  
              case MODEL_GROUP:
                  result = (hasName && isGlobal);
                  
              case ALL:
              case SEQUENCE:
              case CHOICE:
                  result = (isAnonymous && (outerType == PARTICLE || outerType == MODEL_GROUP));
                  
              case PARTICLE:
                  result = (hasNumber && (outerType == SEQUENCE || outerType == CHOICE || outerType == ALL || outerType == TYPE));
                  
              case WILDCARD:
                  result = (isAnonymous && (outerType == PARTICLE || outerType == TYPE || outerType == ATTRIBUTE_GROUP));
                  
              case ATTRIBUTE_USE:
                  result = (hasName && (outerType == TYPE || outerType == ATTRIBUTE_GROUP));
                  
              case ATTRIBUTE:
                  result = (hasName && (isGlobal && isQualified || outerType == TYPE || outerType == ATTRIBUTE_USE));
                  
              case ATTRIBUTE_GROUP:
                  result = (hasName && isQualified && isGlobal);
                  
              case TYPE:
                  result = ((hasName && isQualified && isGlobal) || (isAnonymous && outerType == TYPE || outerType == ELEMENT || outerType == ATTRIBUTE || outerType == MEMBER));
                  
              case DOCUMENT_TYPE:
                  result = (hasName && isQualified && isGlobal);
                  
              case ATTRIBUTE_TYPE:
                  result = (hasName && isQualified && isGlobal);
                  
              case MEMBER:
                  result = (isAnonymous && outerType == TYPE);
                  
              case SOAP_ARRAY:
                  result = (hasNumber && (outerType == SOAP_ARRAY || outerType == TYPE && !outerComponent.isNestedComponent()));
                  
              default:
                  result = false;
          }
          if (!result)
              return false;
          
          if (isGlobal)
              return true;
          
          return outerComponent.valid();
      }
      
      /**
       * Creates an XMLName based on the given String signature.
       * 
       * This signature is described in the javadoc for this class.
       */ 
      public static XmlName forString(String signature)
      {
          String path;
          String namespace;
          int atSign = signature.indexOf('@');
          if (atSign < 0)
          {
              namespace = "";
              path = signature;
          }
          else
          {
              namespace = signature.substring(atSign + 1);
              path = signature.substring(0, atSign);
          }
          return forPathAndNamespace(path, namespace);
      }
      
      /**
       * Creates an XMLName for a schema type with the given fully-qualified QName.
       */ 
      public static XmlName forTypeNamed(QName name)
      {
          return forPathAndNamespace("t=" + name.getLocalPart(), name.getNamespaceURI());
      }
      
      /**
       * Creates an XMLName for a global schema element with the given fully-qualified QName.
       */ 
      public static XmlName forElementNamed(QName name)
      {
          return forPathAndNamespace("e=" + name.getLocalPart(), name.getNamespaceURI());
      }
      
      /**
       * Creates an XMLName for a global schema attribute with the given fully-qualified QName.
       */ 
      public static XmlName forAttributeNamed(QName name)
      {
          return forPathAndNamespace("a=" + name.getLocalPart(), name.getNamespaceURI());
      }
  
      private static XmlName forPathAndNamespace(String path, String namespace)
      {
          return new XmlName(path, namespace);
      }
      
      private XmlName(String path, String namespace)
      {
          if (path == null || namespace == null)
              throw new IllegalArgumentException();
          
          this.path = path;
          this.namespace = namespace;
      }
      
      boolean isNestedComponent()
      {
          int index = path.indexOf('|');
          return index >= 0;
      }
      
      XmlName getOuterComponent()
      {
          int index = path.indexOf('|');
          if (index < 0)
              return null;
          return forPathAndNamespace(path.substring(index + 1), namespace);
      }
      
      public int getComponentType()
      {
          if (path.length() > 0)
              return path.charAt(0);
          return 0; // unknown type
      }
      
      /**
       * Returns negative if there is no number
       */ 
      private int internalGetNumber()
      {
          if (path.length() <= 1 || path.charAt(1) != '.')
              return -1;
          
          int index = path.indexOf('|');
          if (index < 0)
              index = path.length();
          
          try
          {
              return Integer.parseInt(path.substring(2, index));
          }
          catch (Exception e)
          {
              return -1;
          }
      }
      
      /**
       * Returns the number locating this component within its parent,
       * or throws an exception if there is none.  Only union members (m)
       * and particles (p) have numbers.
       */ 
      public int getNumber()
      {
          int result = internalGetNumber();
          if (result < 0)
              throw new IllegalStateException("Path has no number");
          return result;
      }
      
      private String internalGetStringName()
      {
          if (path.length() <= 1 || path.charAt(1) != '=' && path.charAt(1) != '-')
              return null;
          
          int index = path.indexOf('|');
          if (index < 0)
              index = path.length();
          
          return path.substring(2, index);
      }
      
      private boolean internalIsQualified()
      {
          return (path.length() > 1 && path.charAt(1) == '=');
      }
      
      private boolean internalIsAnonymous()
      {
          return (path.length() <= 1 || path.charAt(1) == '|');
      }
  
      /**
       * Returns the name locating this component within its parent, or
       * returns null if there is none.  Notice that if looking up elements
       * by name in a type, you get the first element defintion when there
       * are multiple ones.  A full particle path can disambiguate.
       * 
       * This name will be qualified in a namespace if appropriate, but,
       * for example, local unqualified attributes will have a QName that
       * is unqualified.
       * 
       * Element, attributes, identity constraints, model/attribute groups,
       * and notations have names.
       */ 
      public QName getQName()
      {
          String localName = internalGetStringName();
          if (localName == null)
              return null;
          
          if (internalIsQualified())
              return new QName(namespace, localName);
          else
              return new QName(localName);
      }
      
      /**
       * Returns the signature string.
       */ 
      public String toString()
      {
          if (namespace.length() == 0)
              return path;
          
          return path + '@' + namespace;
      }
  
      public boolean equals(Object o)
      {
          if (this == o) return true;
          if (!(o instanceof XmlName)) return false;
  
          final XmlName xmlName = (XmlName) o;
  
          if (!namespace.equals(xmlName.namespace)) return false;
          if (!path.equals(xmlName.path)) return false;
  
          return true;
      }
  
      public int hashCode()
      {
          int result;
          result = namespace.hashCode();
          result = 29 * result + path.hashCode();
          return result;
      }
  }
  
  
  
  1.1                  xml-xmlbeans/v2/src/configschema/schema/binding-config.xsd
  
  Index: binding-config.xsd
  ===================================================================
  <xs:schema
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:tns="http://xmlbeans.apache.org/2003/09/binding-config"
    targetNamespace="http://xmlbeans.apache.org/2003/09/binding-config"
    elementFormDefault="qualified">
  
    <xs:element name="binding-config">
      <xs:complexType>
        <xs:sequence>
          <xs:element name="bindings" type="tns:binding-table"/>
          <xs:element name="xml-to-pojo" type="tns:mapping-table"/>
          <xs:element name="xml-to-xmlobj" type="tns:mapping-table"/>
          <xs:element name="java-to-xml" type="tns:mapping-table"/>
        </xs:sequence>
      </xs:complexType>
    </xs:element>
  
  
    <xs:complexType name="binding-table">
      <xs:sequence>
        <xs:element name="binding-type" type="tns:binding-type" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
    </xs:complexType>
  
    <xs:complexType name="mapping-table">
      <xs:sequence>
        <xs:element name="mapping" type="tns:mapping" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
    </xs:complexType>
  
    <xs:complexType name="mapping">
      <xs:sequence>
        <xs:element name="xmlcomponent" type="tns:xml-signature"/>
        <xs:element name="javatype" type="tns:java-class-name"/>
      </xs:sequence>
    </xs:complexType>
  
    <xs:complexType name="binding-type" abstract="true">
      <xs:sequence>
        <xs:element name="xmlcomponent" type="tns:xml-signature"/>
        <xs:element name="javatype" type="tns:java-class-name"/>
        <xs:element name="xmlobj" type="xs:boolean"/>
        <!-- todo: maybe more java info, e.g., instanceType, is-interface, is-xmlobj etc? -->
      </xs:sequence>
    </xs:complexType>
  
    <xs:complexType name="by-name-bean">
      <xs:complexContent>
        <xs:extension base="tns:binding-type">
          <xs:choice minOccurs="0" maxOccurs="unbounded">
            <xs:element name="qname-property" type="tns:qname-property"/>
          </xs:choice>
        </xs:extension>
      </xs:complexContent>
    </xs:complexType>
  
    <xs:complexType name="jaxb-bean">
      <xs:complexContent>
        <xs:extension base="tns:binding-type">
          <xs:choice minOccurs="0" maxOccurs="unbounded">
            <xs:element name="particle-property" type="tns:particle-property"/>
            <xs:element name="qname-property" type="tns:qname-property"/>
          </xs:choice>
        </xs:extension>
      </xs:complexContent>
    </xs:complexType>
  
    <xs:complexType name="binding-property" abstract="true">
      <xs:sequence>
        <xs:element name="xmlcomponent" type="tns:xml-signature"/>
        <xs:element name="javatype" type="tns:java-class-name"/>
        <xs:choice>
          <xs:sequence>
            <xs:element name="getter" type="tns:java-property-name"/>
            <xs:element name="setter" type="tns:java-property-name" minOccurs="0"/>
          </xs:sequence>
          <xs:element name="field" type="tns:java-field-name"/>
          <xs:element name="static" type="tns:java-field-name"/>
        </xs:choice>
        <xs:element name="collection" type="tns:java-class-name" minOccurs="0"/>
      </xs:sequence>
    </xs:complexType>
  
    <xs:complexType name="qname-property">
      <xs:complexContent>
        <xs:extension base="tns:binding-property">
          <xs:sequence>
            <xs:element name="qname" type="xs:QName"/>
            <xs:element name="attribute" type="xs:boolean" default="false" minOccurs="0"/>
            <xs:element name="multiple" type="xs:boolean" default="false" minOccurs="0"/>
            <xs:element name="nillable" type="xs:boolean" default="false" minOccurs="0"/>
            <xs:element name="optional" type="xs:boolean" default="false" minOccurs="0"/>
          </xs:sequence>
        </xs:extension>
      </xs:complexContent>
    </xs:complexType>
  
    <xs:complexType name="particle-property">
      <xs:complexContent>
        <!-- implicit restriction: xmlcomponent must be a particle -->
        <xs:extension base="tns:binding-property">
        </xs:extension>
      </xs:complexContent>
    </xs:complexType>
  
  
    <xs:simpleType name="java-class-name">
      <xs:restriction base="xs:token">
      </xs:restriction>
    </xs:simpleType>
  
    <xs:simpleType name="xml-signature">
      <xs:restriction base="xs:token">
      </xs:restriction>
    </xs:simpleType>
  
    <xs:simpleType name="java-property-name">
      <xs:restriction base="xs:token">
      </xs:restriction>
    </xs:simpleType>
  
    <xs:simpleType name="java-field-name">
      <xs:restriction base="xs:token">
      </xs:restriction>
    </xs:simpleType>
  
  
  </xs:schema>
  
  
  
  1.2       +45 -32    xml-xmlbeans/v2/src/xmlstore/org/apache/xmlbeans/impl/store/Saver.java
  
  Index: Saver.java
  ===================================================================
  RCS file: /home/cvs/xml-xmlbeans/v2/src/xmlstore/org/apache/xmlbeans/impl/store/Saver.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- Saver.java	26 Sep 2003 21:23:37 -0000	1.1
  +++ Saver.java	3 Oct 2003 21:18:18 -0000	1.2
  @@ -79,7 +79,6 @@
   import java.util.HashMap;
   import java.util.LinkedHashMap;
   import java.util.HashSet;
  -import java.util.LinkedHashSet;
   import java.util.Iterator;
   import java.util.Map;
   import java.util.ConcurrentModificationException;
  @@ -274,7 +273,8 @@
   
       // Called when a synthetic prefix is created.
       
  -    protected void syntheticNamespace ( String prefix, String uri ) { }
  +    protected void syntheticNamespace (
  +        String prefix, String uri, boolean considerCreatingDefault ) { }
   
       /*
        * It is vital that the saver does not modify the tree in the process of
  @@ -641,7 +641,9 @@
           // which has no namespace, then we must make sure that pushing
           // the mappings causes the default namespace to be empty
   
  -        pushMappings( c, name != null && nameUri.length() == 0 );
  +        boolean ensureDefaultEmpty = name != null && nameUri.length() == 0;
  +
  +        pushMappings( c, ensureDefaultEmpty );
   
           //
           // There are four things which use mappings:
  @@ -655,7 +657,7 @@
           // 1) The element name (not for starts)
   
           if (name != null)
  -            ensureMapping( nameUri, null );
  +            ensureMapping( nameUri, null, !ensureDefaultEmpty, false );
   
           assert noText();
   
  @@ -676,7 +678,7 @@
                   _attrNames.add( s.getName() );
                   
                   // 3) Attribute name
  -                ensureMapping( s.getUri(), null );
  +                ensureMapping( s.getUri(), null, false, true );
   
                   String invalidValue = null;
                   
  @@ -735,13 +737,6 @@
               }
               else
               {
  -if (c.isLeaf())
  -{
  -    System.err.println( "LEAF ALERT!!!!!" );
  -    System.err.println( "Top is " + _top.getKind() );
  -    new Exception().printStackTrace( System.err );
  -}
  -                
                   assert !c.isLeaf();
                   
                   Splay s = c.nextSplay();
  @@ -788,10 +783,13 @@
   
           if (_preComputedNamespaces != null && (name != null || _needsFrag))
           {
  -            for ( Iterator i = _preComputedNamespaces.iterator() ;
  -                  i.hasNext() ; )
  +            for ( Iterator i = _preComputedNamespaces.keySet().iterator() ; i.hasNext() ; )
               {
  -                ensureMapping( (String) i.next(), null );
  +                String uri = (String) i.next();
  +                
  +                ensureMapping(
  +                    uri, null,
  +                    _preComputedNamespaces.get( uri ) != null && !ensureDefaultEmpty, false );
               }
   
               // Set to null so we do this once at the top
  @@ -876,7 +874,7 @@
           else
           {
               pushFragmentMappings( null );
  -            ensureMapping( s.getUri(), s.getLocal() );
  +            ensureMapping( s.getUri(), s.getLocal(), false, true );
               emitXmlnsFragment( s );
           }
       }
  @@ -904,7 +902,7 @@
   
           pushFragmentMappings( s );
   
  -        ensureMapping( s.getUri(), null );
  +        ensureMapping( s.getUri(), null, false, true );
   
           assert noText();
   
  @@ -1106,7 +1104,7 @@
           if (renameUri != null)
           {
               // See if this prefix is already mapped to this uri.  If
  -            // som then add to the stack, but there is nothing to rename
  +            // so, then add to the stack, but there is nothing to rename
           
               if (renameUri.equals( uri ))
                   renameUri = null;
  @@ -1182,11 +1180,21 @@
                   break;
               }
   
  -            _uriMap.put(
  -                _namespaceStack.get( i - 7 ), _namespaceStack.get( i - 8 ) );
  +            Object oldUri = _namespaceStack.get( i - 7 ); 
  +            Object oldPrefix = _namespaceStack.get( i - 8 ); 
   
  -            _prefixMap.put(
  -                _namespaceStack.get( i - 4 ), _namespaceStack.get( i - 3 ) );
  +            if (oldPrefix == null) 
  +                _uriMap.remove( oldUri ); 
  +            else 
  +                _uriMap.put( oldUri, oldPrefix ); 
  +
  +            oldPrefix = _namespaceStack.get( i - 4 ); 
  +            oldUri = _namespaceStack.get( i - 3 ); 
  +
  +            if (oldUri == null) 
  +                _prefixMap.remove( oldPrefix ); 
  +            else 
  +                _prefixMap.put( oldPrefix, oldUri ); 
   
               String uri = (String) _namespaceStack.get( i - 5 );
   
  @@ -1234,7 +1242,9 @@
           return true;
       }
   
  -    protected final String ensureMapping ( String uri, String candidatePrefix )
  +    protected final String ensureMapping (
  +        String uri, String candidatePrefix,
  +        boolean considerCreatingDefault, boolean mustHavePrefix )
       {
           assert uri != null;
           assert candidatePrefix == null || candidatePrefix.length() > 0;
  @@ -1246,7 +1256,7 @@
   
           String prefix = (String) _uriMap.get( uri );
   
  -        if (prefix != null)
  +        if (prefix != null && (prefix.length() > 0 || !mustHavePrefix))
               return prefix;
   
           //
  @@ -1266,7 +1276,7 @@
               {
                   candidatePrefix = (String) _suggestedPrefixes.get( uri );
               }
  -            else if (_useDefaultNamespace && tryPrefix( "" ))
  +            else if (considerCreatingDefault && _useDefaultNamespace && tryPrefix( "" ))
                   candidatePrefix = "";
               else
               {
  @@ -1285,7 +1295,7 @@
   
           assert candidatePrefix != null;
   
  -        syntheticNamespace( candidatePrefix, uri );
  +        syntheticNamespace( candidatePrefix, uri, considerCreatingDefault );
   
           addMapping( candidatePrefix, uri );
   
  @@ -1297,7 +1307,9 @@
           assert uri != null;
           assert prefix == null || prefix.length() > 0;
   
  -        return ensureMapping( uri, prefix );
  +        boolean emptyUri = uri.length() == 0;
  +        
  +        return ensureMapping( uri, prefix, emptyUri, !emptyUri );
       }
   
       public final String getNamespaceForPrefix ( String prefix )
  @@ -1313,7 +1325,7 @@
           if (_fragment.getNamespaceURI().length() == 0)
               return "";
           
  -        return ensureMapping( _fragment.getNamespaceURI(), "frag" );
  +        return ensureMapping( _fragment.getNamespaceURI(), "frag", false, false );
       }
   
       /**
  @@ -1322,16 +1334,17 @@
       
       static final class SynthNamespaceSaver extends Saver
       {
  -        LinkedHashSet _synthNamespaces = new LinkedHashSet();
  +        LinkedHashMap _synthNamespaces = new LinkedHashMap();
           
           SynthNamespaceSaver ( Root r, Splay s, int p, XmlOptions options )
           {
               super( r, s, p, options );
           }
           
  -        protected void syntheticNamespace ( String prefix, String uri )
  +        protected void syntheticNamespace (
  +            String prefix, String uri, boolean considerCreatingDefault )
           {
  -            _synthNamespaces.add( uri );
  +            _synthNamespaces.put( uri, considerCreatingDefault ? "useDefault" : null );
           }
           
           protected void emitXmlnsFragment ( Splay s ) { }
  @@ -4755,7 +4768,7 @@
       private boolean   _firstPush;
       private String    _initialDefaultUri;
       
  -    private HashSet _preComputedNamespaces;
  +    private HashMap _preComputedNamespaces;
       private String  _filterProcinst;
       private Map     _suggestedPrefixes;
   
  
  
  
  1.1                  xml-xmlbeans/v2/test/src/drt/drtcases/BindingTests.java
  
  Index: BindingTests.java
  ===================================================================
  /**
   * XBeans implementation.
   * Author: David Bau
   * Date: Oct 3, 2003
   */
  package drtcases;
  
  import junit.framework.TestCase;
  import junit.framework.Test;
  import junit.framework.TestSuite;
  import junit.framework.Assert;
  import org.apache.xmlbeans.impl.binding.BindingFile;
  import org.apache.xmlbeans.impl.binding.BindingType;
  import org.apache.xmlbeans.impl.binding.ByNameBean;
  import org.apache.xmlbeans.impl.binding.JavaName;
  import org.apache.xmlbeans.impl.binding.XmlName;
  import org.apache.xmlbeans.impl.binding.QNameProperty;
  import org.apache.xmlbeans.x2003.x09.bindingConfig.BindingConfigDocument;
  
  import javax.xml.namespace.QName;
  
  public class BindingTests extends TestCase
  {
      public BindingTests(String name) { super(name); }
      public static Test suite() { return new TestSuite(BindingTests.class); }
  
      public void testBindingFile() throws Exception
      {
          BindingFile bf = new BindingFile();
          
          ByNameBean bnb = new ByNameBean(bf, JavaName.forString("com.mytest.MyClass"), XmlName.forString("t=my-type@http://www.mytest.com/"), false);
          bf.addBindingType(bnb, true, true);
          ByNameBean bnb2 = new ByNameBean(bf, JavaName.forString("com.mytest.YourClass"), XmlName.forString("t=your-type@http://www.mytest.com/"), false);
          bf.addBindingType(bnb2, true, true);
          
          // bnb
                          
          QNameProperty prop = new QNameProperty(bf);
          prop.setQName(new QName("http://www.mytest.com/", "myelt"));
          prop.setSetterName("setMyelt");
          prop.setGetterName("getMyelt");
          prop.setBindingType(bnb2);
          bnb.addProperty(prop);
          
          prop = new QNameProperty(bf);
          prop.setQName(new QName("http://www.mytest.com/", "myelt2"));
          prop.setSetterName("setMyelt2");
          prop.setGetterName("getMyelt2");
          prop.setBindingType(bnb);
          bnb.addProperty(prop);
          
          prop = new QNameProperty(bf);
          prop.setQName(new QName("http://www.mytest.com/", "myatt"));
          prop.setSetterName("setMyatt");
          prop.setGetterName("getMyatt");
          prop.setBindingType(bnb); // need to do simples
          bnb.addProperty(prop);
          
          // now bnb2
          
          prop = new QNameProperty(bf);
          prop.setQName(new QName("http://www.mytest.com/", "yourelt"));
          prop.setSetterName("setYourelt");
          prop.setGetterName("getYourelt");
          prop.setBindingType(bnb2);
          bnb2.addProperty(prop);
          
          prop = new QNameProperty(bf);
          prop.setQName(new QName("http://www.mytest.com/", "yourelt2"));
          prop.setSetterName("setYourelt2");
          prop.setGetterName("getYourelt2");
          prop.setBindingType(bnb);
          bnb2.addProperty(prop);
          
          // now serialize
          BindingConfigDocument doc = bf.write();
          System.out.println(doc.toString());
          
          // now load
          BindingFile bfc = BindingFile.forDoc(doc);
          ByNameBean bnbc = (ByNameBean)bfc.getBindingType(JavaName.forString("com.mytest.MyClass"), XmlName.forString("t=my-type@http://www.mytest.com/"));
          ByNameBean bnb2c = (ByNameBean)bfc.getBindingType(JavaName.forString("com.mytest.YourClass"), XmlName.forString("t=your-type@http://www.mytest.com/"));
          
          // check bnb
          prop = bnbc.getPropertyForElement(new QName("http://www.mytest.com/", "myelt"));
          Assert.assertEquals("setMyelt", prop.getSetterName());
          Assert.assertEquals("getMyelt", prop.getGetterName());
          Assert.assertEquals(bnb2c, prop.getBindingType());
  
          prop = bnbc.getPropertyForElement(new QName("http://www.mytest.com/", "myelt2"));
          Assert.assertEquals("setMyelt2", prop.getSetterName());
          Assert.assertEquals("getMyelt2", prop.getGetterName());
          Assert.assertEquals(bnbc, prop.getBindingType());
          
          prop = bnbc.getPropertyForElement(new QName("http://www.mytest.com/", "myatt"));
          Assert.assertEquals("setMyatt", prop.getSetterName());
          Assert.assertEquals("getMyatt", prop.getGetterName());
          Assert.assertEquals(bnbc, prop.getBindingType());
          
          // check bnb2
          prop = bnb2c.getPropertyForElement(new QName("http://www.mytest.com/", "yourelt"));
          Assert.assertEquals("setYourelt", prop.getSetterName());
          Assert.assertEquals("getYourelt", prop.getGetterName());
          Assert.assertEquals(bnb2c, prop.getBindingType());
  
          prop = bnb2c.getPropertyForElement(new QName("http://www.mytest.com/", "yourelt2"));
          Assert.assertEquals("setYourelt2", prop.getSetterName());
          Assert.assertEquals("getYourelt2", prop.getGetterName());
          Assert.assertEquals(bnbc, prop.getBindingType());
      }
  }
  
  
  

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