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