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 zi...@apache.org on 2003/10/24 01:49:03 UTC
cvs commit: xml-xmlbeans/v2/test/src/drt/drtcases MarshalTests.java
zieg 2003/10/23 16:49:03
Modified: v2 build.xml
v2/src/marshal/org/apache/xmlbeans/impl/marshal
AtomicSimpleTypeConverter.java BindingContext.java
BindingContextFactory.java
BuiltinRuntimeTypeTable.java
RuntimeBindingProperty.java RuntimeBindingType.java
RuntimeBindingTypeTable.java TypeUnmarshaller.java
Unmarshaller.java
v2/test/src/drt/drtcases MarshalTests.java
Added: v2/src/marshal/org/apache/xmlbeans/impl/marshal
ByNameRuntimeBindingType.java
ByNameUnmarshaller.java ClassLoadingUtils.java
MarshalStreamUtils.java NullUnmarshaller.java
UnmarshalContext.java UnmarshallerImpl.java
v2/test/cases/marshal doc.xml example_config.xml
v2/test/cases/marshal/com/mytest MyClass.java YourClass.java
Removed: v2/src/marshal/org/apache/xmlbeans/impl/marshal
UnmarshallContext.java
Log:
basic struct unmarshalling
review: david
Revision Changes Path
1.10 +25 -0 xml-xmlbeans/v2/build.xml
Index: build.xml
===================================================================
RCS file: /home/cvs/xml-xmlbeans/v2/build.xml,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- build.xml 22 Oct 2003 02:32:43 -0000 1.9
+++ build.xml 23 Oct 2003 23:49:03 -0000 1.10
@@ -1003,4 +1003,29 @@
<arg line='test/cases/xpath/much_ado.xml "PLAY/ACT/SCENE/SPEECH/SPEAKER"'/>
</java>
</target>
+
+ <!-- test marshal target ============================================= -->
+ <target name="test_marshal.classes" depends="marshal.classes">
+ <mkdir dir="build/private/classes/marshal"/>
+ <javac
+ srcdir="test/cases/marshal"
+ destdir="build/private/classes/marshal"
+ classpathref="testmarshal.compile.path"
+ source="1.4"
+ debug="on">
+ <classpath id="testmarshal.compile.path">
+ <pathelement location="build/classes/binding"/>
+ <pathelement location="build/classes/marshal"/>
+ <pathelement location="build/classes/common"/>
+ <pathelement location="build/classes/configschema"/>
+ <pathelement location="build/classes/typeimpl"/>
+ <pathelement location="build/classes/xmlinputstream"/>
+ <pathelement location="build/classes/xmlpublic"/>
+ <pathelement location="build/lib/jsr173_07_api.jar"/>
+ <pathelement location="build/lib/xmlpublic.jar"/>
+ </classpath>
+ </javac>
+ </target>
+
+
</project>
1.2 +11 -77 xml-xmlbeans/v2/src/marshal/org/apache/xmlbeans/impl/marshal/AtomicSimpleTypeConverter.java
Index: AtomicSimpleTypeConverter.java
===================================================================
RCS file: /home/cvs/xml-xmlbeans/v2/src/marshal/org/apache/xmlbeans/impl/marshal/AtomicSimpleTypeConverter.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- AtomicSimpleTypeConverter.java 16 Oct 2003 00:02:49 -0000 1.1
+++ AtomicSimpleTypeConverter.java 23 Oct 2003 23:49:03 -0000 1.2
@@ -56,12 +56,7 @@
package org.apache.xmlbeans.impl.marshal;
-import org.apache.xmlbeans.XmlException;
-
-import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.XMLStreamReader;
-import java.util.ArrayList;
-import java.util.Collection;
+import org.apache.xmlbeans.impl.binding.bts.BindingLoader;
/**
* Basic XmlStreamReader based impl that can handle converting
@@ -77,85 +72,24 @@
this.lexerPrinter = lexerPrinter;
}
- public Object unmarshall(UnmarshallContext context)
+ public Object unmarshal(UnmarshalContext context)
{
- final XMLStreamReader reader = context.getXmlStream();
-
- final CharSequence content;
- try {
- reader.next(); //move past start element
- content = getContent(context);
- }
- catch (XmlException ex) {
- //TODO: better error handling
- throw new AssertionError(ex);
- }
- catch (XMLStreamException xse) {
- //TODO: better error handling
- throw new AssertionError(xse);
- }
+ final CharSequence content = context.getElementText();
assert (content != null);
- //TODO: better error handling
- Collection errors = new ArrayList();
-
- return lexerPrinter.lex(content, errors);
+ return lexerPrinter.lex(content, context.getErrorCollection());
}
- private CharSequence getContent(UnmarshallContext context)
- throws XmlException, XMLStreamException
+ public Object unmarshalSimpleType(CharSequence lexicalValue,
+ UnmarshalContext context)
{
- final XMLStreamReader rdr = context.getXmlStream();
- String content = null;
- StringBuffer buf = null;
-
- FOL:
- for (int state = rdr.getEventType(); ; state = rdr.next()) {
- switch (state) {
- case XMLStreamReader.END_DOCUMENT:
- throw new XmlException("unexpected end of XML");
- case XMLStreamReader.END_ELEMENT:
- if (content == null) {
- content = "";
- }
- rdr.next(); // eat the matching end elem
- break FOL;
- case XMLStreamReader.START_ELEMENT:
- //TODO: better error handling
- throw new XmlException("unexpected start element");
- //UnmarshallUtils.skipElement(rdr);
- //break;
- case XMLStreamReader.CHARACTERS:
- if (content == null) {
- content = rdr.getText();
- } else {
- if (buf == null) {
- buf = new StringBuffer(content);
- }
- buf.append(rdr.getText());
- }
- break;
- case XMLStreamReader.PROCESSING_INSTRUCTION:
- case XMLStreamReader.COMMENT:
- break;
- default:
- throw new AssertionError("unexpected xml state " + state);
- }
-
- if (!rdr.hasNext()) {
- throw new XmlException("unexpected end of xml stream");
- }
-
- }
-
- if (buf == null) {
- assert (content != null) ;
- return content;
- } else {
- return buf.toString();
- }
+ return lexerPrinter.lex(lexicalValue, context.getErrorCollection());
+ }
+ public void initialize(RuntimeBindingTypeTable typeTable,
+ BindingLoader bindingLoader)
+ {
}
1.2 +1 -1 xml-xmlbeans/v2/src/marshal/org/apache/xmlbeans/impl/marshal/BindingContext.java
Index: BindingContext.java
===================================================================
RCS file: /home/cvs/xml-xmlbeans/v2/src/marshal/org/apache/xmlbeans/impl/marshal/BindingContext.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- BindingContext.java 16 Oct 2003 00:02:49 -0000 1.1
+++ BindingContext.java 23 Oct 2003 23:49:03 -0000 1.2
@@ -79,6 +79,6 @@
public Unmarshaller createUnmarshaller()
{
- return new Unmarshaller(bindingLoader, typeTable);
+ return new UnmarshallerImpl(bindingLoader, typeTable);
}
}
1.2 +34 -21 xml-xmlbeans/v2/src/marshal/org/apache/xmlbeans/impl/marshal/BindingContextFactory.java
Index: BindingContextFactory.java
===================================================================
RCS file: /home/cvs/xml-xmlbeans/v2/src/marshal/org/apache/xmlbeans/impl/marshal/BindingContextFactory.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- BindingContextFactory.java 16 Oct 2003 00:02:49 -0000 1.1
+++ BindingContextFactory.java 23 Oct 2003 23:49:03 -0000 1.2
@@ -97,8 +97,8 @@
{
BindingFile bf = BindingFile.forDoc(doc);
- RuntimeBindingTypeTable tbl = buildUnmarshallingTypeTable(bf);
BindingLoader bindingLoader = buildBindingLoader(bf);
+ RuntimeBindingTypeTable tbl = buildUnmarshallingTypeTable(bf, bindingLoader);
return new BindingContext(bindingLoader, tbl);
}
@@ -110,47 +110,60 @@
}
- private static RuntimeBindingTypeTable buildUnmarshallingTypeTable(BindingFile bf)
+ private static RuntimeBindingTypeTable buildUnmarshallingTypeTable(BindingFile bf,
+ BindingLoader loader)
{
RuntimeBindingTypeTable tbl = new RuntimeBindingTypeTable();
for (Iterator itr = bf.getBindingTypes().iterator(); itr.hasNext();) {
- BindingType type = (BindingType) itr.next();
+ BindingType type = (BindingType)itr.next();
- TypeUnmarshaller um = createTypeUnmarshaller(type);
+ TypeUnmarshaller um = createTypeUnmarshaller(type, loader, tbl);
tbl.putTypeUnmarshaller(type, um);
-
}
+ tbl.initUnmarshallers(loader);
+
return tbl;
}
- private static TypeUnmarshaller createTypeUnmarshaller(BindingType type)
+ private static TypeUnmarshaller createTypeUnmarshaller(BindingType type,
+ BindingLoader loader,
+ RuntimeBindingTypeTable table)
{
//TODO: cleanup this nasty instanceof stuff (Visitor?)
- if (type instanceof ByNameBean) {
- return createByNameUnmarshaller((ByNameBean) type);
- } else if (type instanceof SimpleBindingType) {
+ if (type instanceof SimpleBindingType) {
//note this could return a static for builtin types
- return createSimpleTypeUnmarshaller((SimpleBindingType) type);
+ return createSimpleTypeUnmarshaller((SimpleBindingType)type, loader, table);
+ } else if (type instanceof ByNameBean) {
+ return new ByNameUnmarshaller((ByNameBean)type);
}
- throw new AssertionError("UNIMPLEMENTED TYPE: " + type.getClass());
+
+ throw new AssertionError("UNIMPLEMENTED TYPE: " + type);
}
- private static TypeUnmarshaller createSimpleTypeUnmarshaller(SimpleBindingType stype)
+ private static TypeUnmarshaller createSimpleTypeUnmarshaller(SimpleBindingType stype,
+ BindingLoader loader,
+ RuntimeBindingTypeTable table)
{
- //TODO: take this into account!
- //XmlName asIfXmlType = stype.getAsIfXmlType();
+ TypeUnmarshaller um = table.getTypeUnmarshaller(stype);
+
+ if (um == null) {
+ //let's try using the as if type
+ BindingType asif = stype.getAsIfBindingType(loader);
+ if (asif == null) {
+ throw new AssertionError("unable to get asif type for " + stype);
+ }
+ um = table.getTypeUnmarshaller(asif);
+ }
+
+ if (um == null) {
+ String msg = "unable to get simple type unmarshaller for " + stype;
+ throw new AssertionError(msg);
+ }
- RuntimeBindingTypeTable builtin = BuiltinRuntimeTypeTable.getBuiltinTable();
- TypeUnmarshaller um = builtin.getTypeUnmarshaller(stype);
- assert um != null;
return um;
}
- private static TypeUnmarshaller createByNameUnmarshaller(ByNameBean byNameBean)
- {
- throw new UnsupportedOperationException("UNIMP");
- }
}
1.2 +1 -27 xml-xmlbeans/v2/src/marshal/org/apache/xmlbeans/impl/marshal/BuiltinRuntimeTypeTable.java
Index: BuiltinRuntimeTypeTable.java
===================================================================
RCS file: /home/cvs/xml-xmlbeans/v2/src/marshal/org/apache/xmlbeans/impl/marshal/BuiltinRuntimeTypeTable.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- BuiltinRuntimeTypeTable.java 16 Oct 2003 00:02:49 -0000 1.1
+++ BuiltinRuntimeTypeTable.java 23 Oct 2003 23:49:03 -0000 1.2
@@ -56,23 +56,15 @@
package org.apache.xmlbeans.impl.marshal;
-import org.apache.xmlbeans.impl.binding.bts.BindingLoader;
-import org.apache.xmlbeans.impl.binding.bts.BindingType;
-import org.apache.xmlbeans.impl.binding.bts.BuiltinBindingLoader;
-import org.apache.xmlbeans.impl.binding.bts.JavaName;
-import org.apache.xmlbeans.impl.binding.bts.XmlName;
-import javax.xml.namespace.QName;
/**
* A special singleton version of RuntimeBindingTypeTable that knows about
* all the builtin types that we know how to deal with.
*/
-public class BuiltinRuntimeTypeTable
+class BuiltinRuntimeTypeTable
extends RuntimeBindingTypeTable
{
- private BindingLoader bindingLoader = BuiltinBindingLoader.getInstance();
- private static final String XSD_NS = "http://www.w3.org/2001/XMLSchema";
private static final BuiltinRuntimeTypeTable INSTANCE =
new BuiltinRuntimeTypeTable();
@@ -97,24 +89,6 @@
addXsdBuiltin("string", String.class.getName(),
new AtomicSimpleTypeConverter(new StringLexerPrinter()));
- bindingLoader = null; // don't need this anymore
- }
-
- private void addXsdBuiltin(String xsdType, String javaType, TypeConverter converter)
- {
- QName xml_type = new QName(XSD_NS, xsdType);
- JavaName jName = JavaName.forString(javaType);
- XmlName xName = XmlName.forTypeNamed(xml_type);
- BindingType btype = bindingLoader.getBindingType(jName, xName);
- if (btype == null) {
- throw new AssertionError("failed to find builtin for java:" + jName +
- " - xsd:" + xName);
- }
- putTypeMarshaller(btype, converter);
- putTypeUnmarshaller(btype, converter);
-
- assert getTypeMarshaller(btype) == converter;
- assert getTypeUnmarshaller(btype) == converter;
}
1.2 +3 -14 xml-xmlbeans/v2/src/marshal/org/apache/xmlbeans/impl/marshal/RuntimeBindingProperty.java
Index: RuntimeBindingProperty.java
===================================================================
RCS file: /home/cvs/xml-xmlbeans/v2/src/marshal/org/apache/xmlbeans/impl/marshal/RuntimeBindingProperty.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- RuntimeBindingProperty.java 16 Oct 2003 00:02:49 -0000 1.1
+++ RuntimeBindingProperty.java 23 Oct 2003 23:49:03 -0000 1.2
@@ -56,21 +56,10 @@
package org.apache.xmlbeans.impl.marshal;
-import org.apache.xmlbeans.impl.binding.bts.BindingProperty;
-public class RuntimeBindingProperty
+interface RuntimeBindingProperty
{
+ TypeUnmarshaller getTypeUnmarshaller(UnmarshalContext context);
- private BindingProperty bindingProperty;
-
- public BindingProperty getBindingProperty()
- {
- return bindingProperty;
- }
-
- public void setBindingProperty(BindingProperty bindingProperty)
- {
- this.bindingProperty = bindingProperty;
- }
-
+ void fill(Object inter, Object prop_obj);
}
1.2 +18 -9 xml-xmlbeans/v2/src/marshal/org/apache/xmlbeans/impl/marshal/RuntimeBindingType.java
Index: RuntimeBindingType.java
===================================================================
RCS file: /home/cvs/xml-xmlbeans/v2/src/marshal/org/apache/xmlbeans/impl/marshal/RuntimeBindingType.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- RuntimeBindingType.java 16 Oct 2003 00:02:49 -0000 1.1
+++ RuntimeBindingType.java 23 Oct 2003 23:49:03 -0000 1.2
@@ -56,18 +56,27 @@
package org.apache.xmlbeans.impl.marshal;
-import org.apache.xmlbeans.impl.binding.bts.BindingType;
+import org.apache.xmlbeans.impl.binding.bts.BindingLoader;
-
-public class RuntimeBindingType
+/**
+ * what we need to know about a binding type at runtime.
+ * No marshalling state should be stored here.
+ * This object will be shared by many threads
+ */
+interface RuntimeBindingType
{
- private BindingType bindingType;
+ /**
+ * prepare internal data structures for use
+ *
+ * @param typeTable
+ * @param bindingLoader
+ */
+ void initialize(RuntimeBindingTypeTable typeTable,
+ BindingLoader bindingLoader);
- private RuntimeBindingProperty[] properties;
+ Object createIntermediary(UnmarshalContext context);
- public BindingType getBindingType()
- {
- throw new UnsupportedOperationException();
- }
+ Object getFinalObjectFromIntermediary(Object retval,
+ UnmarshalContext context);
}
1.2 +68 -6 xml-xmlbeans/v2/src/marshal/org/apache/xmlbeans/impl/marshal/RuntimeBindingTypeTable.java
Index: RuntimeBindingTypeTable.java
===================================================================
RCS file: /home/cvs/xml-xmlbeans/v2/src/marshal/org/apache/xmlbeans/impl/marshal/RuntimeBindingTypeTable.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- RuntimeBindingTypeTable.java 16 Oct 2003 00:02:49 -0000 1.1
+++ RuntimeBindingTypeTable.java 23 Oct 2003 23:49:03 -0000 1.2
@@ -56,37 +56,51 @@
package org.apache.xmlbeans.impl.marshal;
+import org.apache.xmlbeans.impl.binding.bts.BindingLoader;
import org.apache.xmlbeans.impl.binding.bts.BindingType;
+import org.apache.xmlbeans.impl.binding.bts.BuiltinBindingLoader;
+import org.apache.xmlbeans.impl.binding.bts.JavaName;
+import org.apache.xmlbeans.impl.binding.bts.XmlName;
+import javax.xml.namespace.QName;
import java.util.Collections;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/**
* Table of TypeMarshaller and TypeUnmarshaller objects keyed by BindingType
*/
-public class RuntimeBindingTypeTable
+class RuntimeBindingTypeTable
{
+
private final Map typeMap = new HashMap();
+ protected static final String XSD_NS = "http://www.w3.org/2001/XMLSchema";
+
+ RuntimeBindingTypeTable()
+ {
+ addBuiltins();
+ }
+
TypeUnmarshaller getTypeUnmarshaller(BindingType key)
{
- TTEntry e = (TTEntry) typeMap.get(key);
+ TTEntry e = (TTEntry)typeMap.get(key);
if (e == null) return null;
return e.typeUnmarshaller;
}
TypeMarshaller getTypeMarshaller(BindingType key)
{
- TTEntry e = (TTEntry) typeMap.get(key);
+ TTEntry e = (TTEntry)typeMap.get(key);
if (e == null) return null;
return e.typeMarshaller;
}
void putTypeUnmarshaller(BindingType key, TypeUnmarshaller um)
{
- TTEntry e = (TTEntry) typeMap.get(key);
+ TTEntry e = (TTEntry)typeMap.get(key);
if (e == null) {
e = new TTEntry();
typeMap.put(key, e);
@@ -96,7 +110,7 @@
void putTypeMarshaller(BindingType key, TypeMarshaller m)
{
- TTEntry e = (TTEntry) typeMap.get(key);
+ TTEntry e = (TTEntry)typeMap.get(key);
if (e == null) {
e = new TTEntry();
typeMap.put(key, e);
@@ -105,10 +119,58 @@
}
//debugging only
- public Set getKeys()
+ Set getKeys()
{
return Collections.unmodifiableSet(typeMap.keySet());
}
+
+ public void initUnmarshallers(BindingLoader loader)
+ {
+ for (Iterator iterator = typeMap.values().iterator(); iterator.hasNext();) {
+ TTEntry entry = (TTEntry)iterator.next();
+ entry.typeUnmarshaller.initialize(this, loader);
+ }
+ }
+
+ private void addBuiltins()
+ {
+ addXsdBuiltin("float", float.class.getName(),
+ new AtomicSimpleTypeConverter(new FloatLexerPrinter()));
+ addXsdBuiltin("float", Float.class.getName(),
+ new AtomicSimpleTypeConverter(new FloatLexerPrinter()));
+
+ addXsdBuiltin("long", long.class.getName(),
+ new AtomicSimpleTypeConverter(new LongLexerPrinter()));
+ addXsdBuiltin("long", Long.class.getName(),
+ new AtomicSimpleTypeConverter(new LongLexerPrinter()));
+
+ addXsdBuiltin("string", String.class.getName(),
+ new AtomicSimpleTypeConverter(new StringLexerPrinter()));
+
+ addXsdBuiltin("token", String.class.getName(),
+ new AtomicSimpleTypeConverter(new StringLexerPrinter()));
+ }
+
+
+ protected void addXsdBuiltin(String xsdType, String javaType, TypeConverter converter)
+ {
+ final BindingLoader bindingLoader = BuiltinBindingLoader.getInstance();
+
+ QName xml_type = new QName(XSD_NS, xsdType);
+ JavaName jName = JavaName.forString(javaType);
+ XmlName xName = XmlName.forTypeNamed(xml_type);
+ BindingType btype = bindingLoader.getBindingType(jName, xName);
+ if (btype == null) {
+ throw new AssertionError("failed to find builtin for java:" + jName +
+ " - xsd:" + xName);
+ }
+ putTypeMarshaller(btype, converter);
+ putTypeUnmarshaller(btype, converter);
+
+ assert getTypeMarshaller(btype) == converter;
+ assert getTypeUnmarshaller(btype) == converter;
+ }
+
private static class TTEntry
{
1.2 +32 -5 xml-xmlbeans/v2/src/marshal/org/apache/xmlbeans/impl/marshal/TypeUnmarshaller.java
Index: TypeUnmarshaller.java
===================================================================
RCS file: /home/cvs/xml-xmlbeans/v2/src/marshal/org/apache/xmlbeans/impl/marshal/TypeUnmarshaller.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- TypeUnmarshaller.java 16 Oct 2003 00:02:50 -0000 1.1
+++ TypeUnmarshaller.java 23 Oct 2003 23:49:03 -0000 1.2
@@ -56,21 +56,48 @@
package org.apache.xmlbeans.impl.marshal;
+import org.apache.xmlbeans.impl.binding.bts.BindingLoader;
+
/**
- * A TypeUnmarshaller knows how to unmarshall an xml
+ * A TypeUnmarshaller knows how to unmarshal an xml
* instance of a given BindingType
*/
interface TypeUnmarshaller
{
/**
* Unmarshalls the current node in the xml into a java object.
- * The UnmarshallContext must be pointing at the start element of the node
+ * The UnmarshalContext must be pointing at the start element of the node
* to be unmarshalled (such that XmlStreamReader.isStarteElement()
- * returns true). The unmarshall method must consume the entire contents
+ * returns true). The unmarshal method must consume the entire contents
* of that node including the matching end element.
*
- * @param context contains that state of the document unmarshall process
+ * @param context contains that state of the document unmarshal process
* @return Object representing the converted xml
*/
- Object unmarshall(UnmarshallContext context);
+ Object unmarshal(UnmarshalContext context);
+
+ /**
+ * unmarshal the lexical value of an instance of xsd:anySimpleType.
+ * This could be called on an attribute value or on element content.
+ *
+ * @param lexicalValue
+ * @param context
+ * @return Object representing java value of lexical
+ *
+ * @exception UnsupportedOperationException if the
+ * <tt>unmarshalSimpleType</tt> operation is not supported
+ * by this TypeUnmarshaller.
+ */
+ Object unmarshalSimpleType(CharSequence lexicalValue,
+ UnmarshalContext context);
+
+
+ /**
+ * called once per object before first use.
+ *
+ * @param typeTable
+ * @param bindingLoader
+ */
+ void initialize(RuntimeBindingTypeTable typeTable,
+ BindingLoader bindingLoader);
}
1.2 +3 -131 xml-xmlbeans/v2/src/marshal/org/apache/xmlbeans/impl/marshal/Unmarshaller.java
Index: Unmarshaller.java
===================================================================
RCS file: /home/cvs/xml-xmlbeans/v2/src/marshal/org/apache/xmlbeans/impl/marshal/Unmarshaller.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- Unmarshaller.java 16 Oct 2003 00:02:50 -0000 1.1
+++ Unmarshaller.java 23 Oct 2003 23:49:03 -0000 1.2
@@ -57,139 +57,11 @@
package org.apache.xmlbeans.impl.marshal;
import org.apache.xmlbeans.XmlException;
-import org.apache.xmlbeans.impl.binding.bts.BindingLoader;
-import org.apache.xmlbeans.impl.binding.bts.BindingType;
-import org.apache.xmlbeans.impl.binding.bts.XmlName;
-import org.apache.xmlbeans.impl.common.XsTypeConverter;
-import javax.xml.namespace.QName;
-import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
-import java.util.ArrayList;
-import java.util.List;
-/**
- * A Unmarshaller knows how to convert xml to java objects.
- */
-public class Unmarshaller
+public interface Unmarshaller
{
- private final BindingLoader bindingLoader;
- private final RuntimeBindingTypeTable typeTable;
-
-
- /*package*/
- Unmarshaller(BindingLoader bindingLoader,
- RuntimeBindingTypeTable typeTable)
- {
- this.bindingLoader = bindingLoader;
- this.typeTable = typeTable;
- }
-
- public Object unmarshal(XMLStreamReader reader)
- throws XmlException
- {
- UnmarshallContext context = createUnmarshallContext(reader);
-
- advanceToFirstItemOfInterest(reader);
-
- final BindingType bindingType = determineRootType(context);
-
- TypeUnmarshaller um =
- typeTable.getTypeUnmarshaller(bindingType);
-
- //TODO: fix this when we decide the right way to do it
- if (um == null) {
- RuntimeBindingTypeTable builtinTable =
- BuiltinRuntimeTypeTable.getBuiltinTable();
- um = builtinTable.getTypeUnmarshaller(bindingType);
- }
-
- if (um == null) {
- throw new XmlException("failed to lookup unmarshaller for " + bindingType);
- }
-
- Object type_instance = um.unmarshall(context);
-
- return type_instance;
- }
-
- private void advanceToFirstItemOfInterest(XMLStreamReader rdr)
- throws XmlException
- {
- try {
- for (int state = rdr.getEventType(); rdr.hasNext(); state = rdr.next()) {
- switch (state) {
-
- //these are things we can handle...
- case XMLStreamReader.START_ELEMENT:
- return;
-
- //eventually we'll handle these...
- case XMLStreamReader.ATTRIBUTE:
- case XMLStreamReader.CHARACTERS:
- throw new AssertionError("UNIMPLEMENTED TYPE: " + state);
-
- //bad news in the xml stream
- case XMLStreamReader.END_DOCUMENT:
- throw new XmlException("unexpected end of XML");
- case XMLStreamReader.END_ELEMENT:
- throw new XmlException("unexpected end of XML");
-
- //skip these and keep going
- case XMLStreamReader.PROCESSING_INSTRUCTION:
- case XMLStreamReader.COMMENT:
- case XMLStreamReader.START_DOCUMENT:
- case XMLStreamReader.SPACE:
- break;
-
- default:
- //this case pretty much means malformed xml or a bug
- throw new XmlException("unexpected xml state:" + state +
- "in" + rdr);
- }
- }
- throw new XmlException("unexpected end of xml stream");
- }
- catch (XMLStreamException e) {
- throw new XmlException(e);
- }
- }
-
- private BindingType determineRootType(UnmarshallContext context)
- throws XmlException
- {
- //TODO: fix this temporary hack
- //to get started we're relying on xsi:type being on the root element
- //to avoid requiring the schema
-
- final XMLStreamReader rdr = context.getXmlStream();
- assert rdr.isStartElement();
- String type_str =
- rdr.getAttributeValue("http://www.w3.org/2001/XMLSchema-instance", "type");
- if (type_str == null) {
- throw new AssertionError("xsi:type is required for now");
- }
-
- List errors = new ArrayList();
- final QName xsi_type =
- XsTypeConverter.lexQName(type_str, errors, rdr.getNamespaceContext());
- XmlName type_name = XmlName.forTypeNamed(xsi_type);
-
- BindingType bt =
- bindingLoader.getBindingTypeForXmlPojo(type_name);
-
- if (bt == null) {
- throw new XmlException("failed to load BindingType for XmlName: " +
- type_name);
- }
-
- return bt;
- }
-
- private UnmarshallContext createUnmarshallContext(XMLStreamReader reader)
- {
- return new UnmarshallContext(reader, bindingLoader);
- }
-
-
+ Object unmarshal(XMLStreamReader reader)
+ throws XmlException;
}
1.1 xml-xmlbeans/v2/src/marshal/org/apache/xmlbeans/impl/marshal/ByNameRuntimeBindingType.java
Index: ByNameRuntimeBindingType.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache
* XMLBeans", nor may "Apache" appear in their name, without prior
* written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 2000-2003 BEA Systems
* Inc., <http://www.bea.com/>. For more information on the Apache Software
* Foundation, please see <http://www.apache.org/>.
*/
package org.apache.xmlbeans.impl.marshal;
import org.apache.xmlbeans.XmlRuntimeException;
import org.apache.xmlbeans.impl.binding.bts.BindingLoader;
import org.apache.xmlbeans.impl.binding.bts.BindingProperty;
import org.apache.xmlbeans.impl.binding.bts.BindingType;
import org.apache.xmlbeans.impl.binding.bts.ByNameBean;
import org.apache.xmlbeans.impl.binding.bts.JavaName;
import org.apache.xmlbeans.impl.binding.bts.QNameProperty;
import javax.xml.namespace.QName;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Iterator;
final class ByNameRuntimeBindingType
implements RuntimeBindingType
{
private final ByNameBean byNameBean;
private final Property[] properties;
private final Class javaClass;
ByNameRuntimeBindingType(ByNameBean btype)
{
byNameBean = btype;
try {
javaClass = getJavaClass(btype, getClass().getClassLoader());
}
catch (ClassNotFoundException e) {
final String msg = "failed to load " + btype.getJavaName();
throw (RuntimeException)(new RuntimeException(msg).initCause(e));
}
properties = new Property[btype.getProperties().size()];
}
//prepare internal data structures for use
public void initialize(RuntimeBindingTypeTable typeTable,
BindingLoader loader)
{
int idx = 0;
for (Iterator itr = byNameBean.getProperties().iterator(); itr.hasNext();) {
QNameProperty bprop = (QNameProperty)itr.next();
Property prop = new Property(javaClass, bprop, typeTable, loader);
properties[idx++] = prop;
}
}
public Object createIntermediary(UnmarshalContext context)
{
return ClassLoadingUtils.newInstance(javaClass);
}
private static Class getJavaClass(BindingType btype, ClassLoader backup)
throws ClassNotFoundException
{
final JavaName javaName = btype.getJavaName();
String jclass = javaName.toString();
return ClassLoadingUtils.loadClass(jclass, backup);
}
public Object getFinalObjectFromIntermediary(Object retval,
UnmarshalContext context)
{
return retval;
}
//TODO: optimize this linear scan
RuntimeBindingProperty getMatchingElementProperty(String uri,
String localname)
{
for (int i = 0, len = properties.length; i < len; i++) {
final Property prop = properties[i];
if (prop.isAttribute()) continue;
QName qn = prop.getQName();
if (qn.getLocalPart().equals(localname) &&
qn.getNamespaceURI().equals(uri)) {
return prop;
}
}
return null;
}
//TODO: optimize this linear scan
RuntimeBindingProperty getMatchingAttributeProperty(String uri,
String localname)
{
for (int i = 0, len = properties.length; i < len; i++) {
final Property prop = properties[i];
if (!prop.isAttribute()) continue;
QName qn = prop.getQName();
if (qn.getLocalPart().equals(localname) &&
qn.getNamespaceURI().equals(uri)) {
return prop;
}
}
return null;
}
private static final class Property implements RuntimeBindingProperty
{
private final QNameProperty bindingProperty;
private final TypeUnmarshaller unmarshaller;
private final Class propertyClass;
private final Method setMethod;
private final boolean javaPrimitive;
Property(Class beanClass,
QNameProperty prop,
RuntimeBindingTypeTable typeTable,
BindingLoader loader)
{
this.bindingProperty = prop;
this.unmarshaller = lookupUnmarshaller(prop, typeTable, loader);
final BindingType bindingType = prop.getBindingType(loader);
try {
this.propertyClass = getJavaClass(bindingType, getClass().getClassLoader());
}
catch (ClassNotFoundException e) {
final String msg = "error loading " + bindingType.getJavaName();
throw (RuntimeException)(new RuntimeException(msg).initCause(e));
}
setMethod = getSetterMethod(prop, beanClass, propertyClass);
javaPrimitive = propertyClass.isPrimitive();
}
private TypeUnmarshaller lookupUnmarshaller(BindingProperty prop,
RuntimeBindingTypeTable typeTable,
BindingLoader bindingLoader)
{
final BindingType bindingType =
prop.getBindingType(bindingLoader);
TypeUnmarshaller um = typeTable.getTypeUnmarshaller(bindingType);
if (um == null) {
throw new AssertionError("failed to get unmarshaller for " + prop);
}
return um;
}
public TypeUnmarshaller getTypeUnmarshaller(UnmarshalContext context)
{
final QName xsi_type = context.getXsiType();
if (xsi_type == null)
return unmarshaller;
else
if (xsi_type == UnmarshalContext.XSI_NIL_MARKER)
return NullUnmarshaller.getInstance();
return context.getTypeUnmarshaller(xsi_type);
}
public void fill(Object inter, Object prop_obj)
{
//means xsi:nil was true but we're a primtive.
//schema should have nillable="false" so this
//is a validation problems
if (prop_obj == null && javaPrimitive)
return;
try {
setMethod.invoke(inter, new Object[]{prop_obj});
}
catch (SecurityException e) {
throw new XmlRuntimeException(e);
}
catch (IllegalAccessException e) {
throw new XmlRuntimeException(e);
}
catch (InvocationTargetException e) {
throw new XmlRuntimeException(e);
}
}
private static Method getSetterMethod(QNameProperty bindingProperty1,
Class beanClass,
Class propClass)
{
String setter = bindingProperty1.getSetterName();
try {
final Method set_method =
beanClass.getMethod(setter, new Class[]{propClass});
return set_method;
}
catch (NoSuchMethodException e) {
throw new XmlRuntimeException(e);
}
catch (SecurityException e) {
throw new XmlRuntimeException(e);
}
}
boolean isAttribute()
{
return bindingProperty.isAttribute();
}
QName getQName()
{
return bindingProperty.getQName();
}
}
}
1.1 xml-xmlbeans/v2/src/marshal/org/apache/xmlbeans/impl/marshal/ByNameUnmarshaller.java
Index: ByNameUnmarshaller.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache
* XMLBeans", nor may "Apache" appear in their name, without prior
* written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 2000-2003 BEA Systems
* Inc., <http://www.bea.com/>. For more information on the Apache Software
* Foundation, please see <http://www.apache.org/>.
*/
package org.apache.xmlbeans.impl.marshal;
import org.apache.xmlbeans.impl.binding.bts.BindingLoader;
import org.apache.xmlbeans.impl.binding.bts.ByNameBean;
final class ByNameUnmarshaller implements TypeUnmarshaller
{
private final ByNameRuntimeBindingType type;
public ByNameUnmarshaller(ByNameBean type)
{
this.type = new ByNameRuntimeBindingType(type);
}
public Object unmarshal(UnmarshalContext context)
{
final Object inter = type.createIntermediary(context);
deserializeAttributes(inter, context);
deserializeContents(inter, context);
return type.getFinalObjectFromIntermediary(inter, context);
}
public Object unmarshalSimpleType(CharSequence lexicalValue,
UnmarshalContext context)
{
throw new UnsupportedOperationException();
}
private void deserializeContents(Object inter, UnmarshalContext context)
{
while (context.advanceToNextStartElement()) {
assert context.getXmlStream().isStartElement();
RuntimeBindingProperty prop = findMatchingElementProperty(context);
if (prop != null) fillElementProp(prop, context, inter);
}
}
private static void fillElementProp(RuntimeBindingProperty prop,
UnmarshalContext context,
Object inter)
{
final TypeUnmarshaller um = prop.getTypeUnmarshaller(context);
assert um != null;
final Object prop_val = um.unmarshal(context);
prop.fill(inter, prop_val);
}
private static void fillAttributeProp(RuntimeBindingProperty prop,
CharSequence lexical,
UnmarshalContext context,
Object inter)
{
final TypeUnmarshaller um = prop.getTypeUnmarshaller(context);
assert um != null;
final Object prop_val = um.unmarshalSimpleType(lexical, context);
prop.fill(inter, prop_val);
}
private void deserializeAttributes(Object inter, UnmarshalContext context)
{
final int cnt = context.getAttributeCount();
for (int att_idx = 0; att_idx < cnt; att_idx++) {
RuntimeBindingProperty prop =
findMatchingAttributeProperty(att_idx, context);
if (prop != null) {
String att_val = context.getAttributeValue(att_idx);
fillAttributeProp(prop, att_val, context, inter);
}
}
}
private RuntimeBindingProperty findMatchingElementProperty(UnmarshalContext context)
{
String uri = context.getNamespaceURI();
String lname = context.getLocalName();
return type.getMatchingElementProperty(uri, lname);
}
private RuntimeBindingProperty findMatchingAttributeProperty(int att_idx,
UnmarshalContext context)
{
String uri = context.getAttributeNamespaceURI(att_idx);
String lname = context.getAttributeLocalName(att_idx);
return type.getMatchingAttributeProperty(uri, lname);
}
//prepare internal data structures for use
public void initialize(RuntimeBindingTypeTable typeTable,
BindingLoader bindingLoader)
{
type.initialize(typeTable, bindingLoader);
}
}
1.1 xml-xmlbeans/v2/src/marshal/org/apache/xmlbeans/impl/marshal/ClassLoadingUtils.java
Index: ClassLoadingUtils.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache
* XMLBeans", nor may "Apache" appear in their name, without prior
* written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 2000-2003 BEA Systems
* Inc., <http://www.bea.com/>. For more information on the Apache Software
* Foundation, please see <http://www.apache.org/>.
*/
package org.apache.xmlbeans.impl.marshal;
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
final class ClassLoadingUtils
{
private static final Map PRIMITIVES = new HashMap();
static
{
PRIMITIVES.put(boolean.class.getName(), boolean.class);
PRIMITIVES.put(char.class.getName(), char.class);
PRIMITIVES.put(byte.class.getName(), byte.class);
PRIMITIVES.put(short.class.getName(), short.class);
PRIMITIVES.put(int.class.getName(), int.class);
PRIMITIVES.put(long.class.getName(), long.class);
PRIMITIVES.put(float.class.getName(), float.class);
PRIMITIVES.put(double.class.getName(), double.class);
}
public static Class loadClass(String className,
ClassLoader backup_classloader)
throws ClassNotFoundException
{
Class prim_class = loadPrimitiveClass(className);
if (prim_class != null) return prim_class;
Class array_class = loadArrayClass(className, backup_classloader);
if (array_class != null)
return array_class;
else
return loadNonArrayClass(className, backup_classloader);
}
private static Class loadPrimitiveClass(String className)
{
return (Class)PRIMITIVES.get(className);
}
private static Class loadNonArrayClass(String className,
ClassLoader backup_classloader)
throws ClassNotFoundException
{
Class prim_class = loadPrimitiveClass(className);
if (prim_class != null) {
return prim_class;
}
ClassLoader cl = Thread.currentThread().getContextClassLoader();
if (cl == null) {
cl = backup_classloader;
}
try {
return cl.loadClass(className);
}
catch (ClassNotFoundException e) {
return Class.forName(className);
}
}
private static Class loadArrayClass(String className,
ClassLoader backup_classloader)
throws ClassNotFoundException
{
StringBuffer component = new StringBuffer(className.length());
int rank = getArrayComponentNameFromDecl(component, className);
if (rank < 1) return null; //not an array
int[] ranks = new int[rank];
Arrays.fill(ranks, 1);
Class component_class = loadNonArrayClass(component.toString(),
backup_classloader);
Object instance = Array.newInstance(component_class, ranks);
return instance.getClass();
}
//TODO: make sure we don't have a another version of this method somewhere
//compname holds return value
//return int is number of dimensions of array
public static int getArrayComponentNameFromDecl(StringBuffer compname,
String aname)
{
compname.setLength(0);
final int first_bracket = aname.indexOf('[');
if (first_bracket <= 0) {
compname.append(aname);
return 0;
}
final String base = aname.substring(0, first_bracket).trim();
compname.append(base);
int rank = 0;
for (int idx = aname.indexOf(']'); idx >= 0;
idx = aname.indexOf(']', idx + 1)) {
rank++;
}
assert compname.length() > 0;
assert rank > 0;
return rank;
}
static Object newInstance(Class javaClass)
{
try {
return javaClass.newInstance();
}
catch (InstantiationException e) {
//TODO: real error handling
throw (RuntimeException)(new RuntimeException(e.getMessage()).initCause(e));
}
catch (IllegalAccessException e) {
//TODO: real error handling
throw (RuntimeException)(new RuntimeException(e.getMessage()).initCause(e));
}
}
}
1.1 xml-xmlbeans/v2/src/marshal/org/apache/xmlbeans/impl/marshal/MarshalStreamUtils.java
Index: MarshalStreamUtils.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache
* XMLBeans", nor may "Apache" appear in their name, without prior
* written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 2000-2003 BEA Systems
* Inc., <http://www.bea.com/>. For more information on the Apache Software
* Foundation, please see <http://www.apache.org/>.
*/
package org.apache.xmlbeans.impl.marshal;
import org.apache.xmlbeans.XmlRuntimeException;
import org.apache.xmlbeans.impl.common.XsTypeConverter;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import java.util.Collection;
final class MarshalStreamUtils
{
static final String XSI_NS = "http://www.w3.org/2001/XMLSchema-instance";
static final String XSI_TYPE_ATTR = "type";
static final String XSI_NIL_ATTR = "nil";
//more efficient (hopefully) version of XmlStreamReader.getElementText()
//TODO: plenty of room for optimizations here...
static CharSequence getContent(XMLStreamReader reader, Collection errors)
throws XMLStreamException
{
assert reader.isStartElement();
reader.next(); //move past start element
String content = null;
StringBuffer buf = null;
FOL:
for (int state = reader.getEventType(); ; state = reader.next()) {
switch (state) {
case XMLStreamReader.END_DOCUMENT:
throw new XmlRuntimeException("unexpected end of XML");
case XMLStreamReader.END_ELEMENT:
if (content == null) {
content = "";
}
reader.next(); // eat the matching end elem
break FOL;
case XMLStreamReader.START_ELEMENT:
//TODO: better error handling
errors.add("skipping unexpected child element");
skipElement(reader);
break;
case XMLStreamReader.CHARACTERS:
if (content == null) {
content = reader.getText();
} else {
if (buf == null) {
buf = new StringBuffer(content);
}
buf.append(reader.getText());
}
break;
case XMLStreamReader.PROCESSING_INSTRUCTION:
case XMLStreamReader.COMMENT:
break;
default:
throw new AssertionError("unexpected xml state " + state);
}
if (!reader.hasNext()) {
throw new XmlRuntimeException("unexpected end of xml stream");
}
}
if (buf == null) {
assert (content != null) ;
return content;
} else {
return buf.toString();
}
}
/**
* special marker qname object used to indicate that we noticed
* an xsi:nil="true" value while we were looking for an xsi:type attribute
*
* note that such a value would never be returned by getXsiType since
* it is illegal to declare types in the instance namespace.
*/
static QName XSI_NIL_MARKER = new QName(XSI_NS, "unused");
//TODO: REVIEW: reconsider this approach
//and what about the other xsi attributes?
static QName getXsiType(final XMLStreamReader reader, Collection errors)
{
assert reader.isStartElement();
final int att_cnt = reader.getAttributeCount();
for (int att_idx = 0; att_idx < att_cnt; att_idx++) {
if (!XSI_NS.equals(reader.getAttributeNamespace(att_idx)))
continue;
final String lname = reader.getAttributeLocalName(att_idx);
if (XSI_NIL_ATTR.equals(lname)) {
final String att_val = reader.getAttributeValue(att_idx);
boolean is_nil = XsTypeConverter.lexBoolean(att_val, errors);
if (is_nil) return XSI_NIL_MARKER;
} else if (XSI_TYPE_ATTR.equals(lname)) {
final String type_str = reader.getAttributeValue(att_idx);
return XsTypeConverter.lexQName(type_str, errors,
reader.getNamespaceContext());
}
}
return null;
}
/**
* go to next start element. if reader is sitting on a start element
* then no advancing will be done. returns false if we hit and end element,
* otherwise returns true
*
* @param reader
* @return
*/
static boolean advanceToNextStartElement(XMLStreamReader reader)
{
try {
for (int state = reader.getEventType();
reader.hasNext();
state = reader.next()) {
switch (state) {
case XMLStreamReader.END_DOCUMENT:
throw new XmlRuntimeException("unexpected end of XML");
case XMLStreamReader.END_ELEMENT:
return false;
case XMLStreamReader.START_ELEMENT:
return true;
case XMLStreamReader.CHARACTERS:
//TODO: what about mixed content models
case XMLStreamReader.PROCESSING_INSTRUCTION:
case XMLStreamReader.COMMENT:
break;
default:
throw new AssertionError("unexpected xml state " + state);
}
}
}
catch (XMLStreamException e) {
throw new XmlRuntimeException(e);
}
throw new XmlRuntimeException("unexpected end of xml stream");
}
/**
* Skip current element node and all its contents.
* Reader must be on start element.
* Skips to the matching end element (not past it).
* We are just counting start/end -- the parser is
* dealing with well-formedness.
*
* @param reader
*/
static void skipElement(XMLStreamReader reader)
{
assert reader.isStartElement();
int cnt = -1;
//TODO: seem to be rechecking assertion, why not skip one ahead...
try {
for (int state = reader.getEventType(); reader.hasNext();
state = reader.next()) {
switch (state) {
case XMLStreamReader.END_DOCUMENT:
//should not happen for well-formed xml
throw new XmlRuntimeException("unexpected end of xml document");
case XMLStreamReader.END_ELEMENT:
if (cnt == 0) {
return;
} else {
cnt--;
}
break;
case XMLStreamReader.START_ELEMENT:
cnt++;
break;
default:
break;
}
}
}
catch (XMLStreamException e) {
throw new XmlRuntimeException(e);
}
//should not happen for well-formed xml
throw new XmlRuntimeException("unexpected end of xml stream");
}
public static boolean isXsiNilTrue(XMLStreamReader reader,
int att_idx,
Collection errors)
{
final String lname = reader.getAttributeLocalName(att_idx);
System.out.println("lname = " + lname);
if (!XSI_NIL_ATTR.equals(lname))
return false;
if (!XSI_NS.equals(reader.getAttributeNamespace(att_idx)))
return false;
final String att_val = reader.getAttributeValue(att_idx);
return XsTypeConverter.lexBoolean(att_val, errors);
}
}
1.1 xml-xmlbeans/v2/src/marshal/org/apache/xmlbeans/impl/marshal/NullUnmarshaller.java
Index: NullUnmarshaller.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache
* XMLBeans", nor may "Apache" appear in their name, without prior
* written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 2000-2003 BEA Systems
* Inc., <http://www.bea.com/>. For more information on the Apache Software
* Foundation, please see <http://www.apache.org/>.
*/
package org.apache.xmlbeans.impl.marshal;
import org.apache.xmlbeans.impl.binding.bts.BindingLoader;
final class NullUnmarshaller
implements TypeUnmarshaller
{
private static final TypeUnmarshaller INSTANCE = new NullUnmarshaller();
private NullUnmarshaller()
{
}
public Object unmarshal(UnmarshalContext context)
{
context.skipElement();
return null;
}
public Object unmarshalSimpleType(CharSequence lexicalValue,
UnmarshalContext context)
{
throw new UnsupportedOperationException();
}
public void initialize(RuntimeBindingTypeTable typeTable,
BindingLoader bindingLoader)
{
}
public static TypeUnmarshaller getInstance()
{
return INSTANCE;
}
}
1.1 xml-xmlbeans/v2/src/marshal/org/apache/xmlbeans/impl/marshal/UnmarshalContext.java
Index: UnmarshalContext.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache
* XMLBeans", nor may "Apache" appear in their name, without prior
* written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 2000-2003 BEA Systems
* Inc., <http://www.bea.com/>. For more information on the Apache Software
* Foundation, please see <http://www.apache.org/>.
*/
package org.apache.xmlbeans.impl.marshal;
import org.apache.xmlbeans.XmlRuntimeException;
import org.apache.xmlbeans.impl.binding.bts.BindingLoader;
import org.apache.xmlbeans.impl.binding.bts.BindingType;
import org.apache.xmlbeans.impl.binding.bts.XmlName;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import java.util.Collection;
/**
* An UnmarshalContext holds the mutable state using by an Unmarshaller
* during unmarshalling. Example contents are an id -> object table
* for href processing, and the position in the xml document.
*
* The UnmarshalContext is purposefullly unsynchronized.
* Only one thread should ever be accessing this object, and a new one will be
* required for each unmarshalling pass.
*/
final class UnmarshalContext
{
private final XMLStreamReader baseReader;
private final BindingLoader bindingLoader;
private final RuntimeBindingTypeTable typeTable;
private final Collection errors;
public UnmarshalContext(XMLStreamReader baseReader,
BindingLoader bindingLoader,
RuntimeBindingTypeTable typeTable,
Collection errors)
{
this.baseReader = baseReader;
this.bindingLoader = bindingLoader;
this.errors = errors;
this.typeTable = typeTable;
}
XMLStreamReader getXmlStream()
{
return baseReader;
}
RuntimeBindingTypeTable getTypeTable()
{
return typeTable;
}
TypeUnmarshaller getTypeUnmarshaller(QName xsi_type)
{
XmlName xname = XmlName.forTypeNamed(xsi_type);
BindingType binding_type =
bindingLoader.getBindingTypeForXmlPojo(xname);
if (binding_type == null) {
String msg = "unable to locate binding type for " + xsi_type;
throw new XmlRuntimeException(msg);
}
TypeUnmarshaller um =
typeTable.getTypeUnmarshaller(binding_type);
if (um == null) {
String msg = "unable to locate unmarshaller for " + binding_type;
throw new XmlRuntimeException(msg);
}
return um;
}
public BindingLoader getBindingLoader()
{
return bindingLoader;
}
//package only -- get read/write version of error collection
/**
* package only -- get read/write version of error collection
*
* @return read/write version of error collection
*/
Collection getErrorCollection()
{
return errors;
}
// ======================= xml access methods =======================
CharSequence getElementText()
{
try {
return MarshalStreamUtils.getContent(baseReader, errors);
}
catch (XMLStreamException e) {
throw new XmlRuntimeException(e);
}
}
/**
* special marker qname object used to indicate that we noticed
* an xsi:nil="true" value while we were looking for an xsi:type attribute
*
* note that such a value would never be returned by getXsiType since
* it is illegal to declare types in the instance namespace.
*/
static final QName XSI_NIL_MARKER = MarshalStreamUtils.XSI_NIL_MARKER;
/**
* return:
* XSI_NIL_MARKER for xsi:nil="true"
* or the QName value found for xsi:type
* or null if neither one was found
*/
QName getXsiType()
{
return MarshalStreamUtils.getXsiType(baseReader, errors);
}
/**
*
* @return false if we hit an end element (any end element at all)
*/
public boolean advanceToNextStartElement()
{
try {
//move past our current start element
baseReader.next();
}
catch (XMLStreamException e) {
throw new XmlRuntimeException(e);
}
return MarshalStreamUtils.advanceToNextStartElement(baseReader);
}
public int getAttributeCount()
{
assert baseReader.isStartElement();
return baseReader.getAttributeCount();
}
public String getLocalName()
{
return baseReader.getLocalName();
}
public String getNamespaceURI()
{
return baseReader.getNamespaceURI();
}
public String getAttributeNamespaceURI(int att_idx)
{
return baseReader.getAttributeNamespace(att_idx);
}
public String getAttributeLocalName(int att_idx)
{
return baseReader.getAttributeLocalName(att_idx);
}
public String getAttributeValue(int att_idx)
{
return baseReader.getAttributeValue(att_idx);
}
public boolean isXsiNilTrue(int att_idx)
{
return MarshalStreamUtils.isXsiNilTrue(baseReader, att_idx, errors);
}
public void skipElement()
{
MarshalStreamUtils.skipElement(baseReader);
}
}
1.1 xml-xmlbeans/v2/src/marshal/org/apache/xmlbeans/impl/marshal/UnmarshallerImpl.java
Index: UnmarshallerImpl.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache
* XMLBeans", nor may "Apache" appear in their name, without prior
* written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 2000-2003 BEA Systems
* Inc., <http://www.bea.com/>. For more information on the Apache Software
* Foundation, please see <http://www.apache.org/>.
*/
package org.apache.xmlbeans.impl.marshal;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.impl.binding.bts.BindingLoader;
import org.apache.xmlbeans.impl.binding.bts.BindingType;
import org.apache.xmlbeans.impl.binding.bts.XmlName;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
/**
* A Unmarshaller knows how to convert xml to java objects.
*/
class UnmarshallerImpl
implements Unmarshaller
{
private final BindingLoader bindingLoader;
private final RuntimeBindingTypeTable typeTable;
/*package*/
UnmarshallerImpl(BindingLoader bindingLoader,
RuntimeBindingTypeTable typeTable)
{
this.bindingLoader = bindingLoader;
this.typeTable = typeTable;
}
public Object unmarshal(XMLStreamReader reader)
throws XmlException
{
UnmarshalContext context = createUnmarshallContext(reader,
new ArrayList());
advanceToFirstItemOfInterest(reader);
final BindingType bindingType = determineRootType(context);
TypeUnmarshaller um =
typeTable.getTypeUnmarshaller(bindingType);
if (um == null) {
throw new XmlException("failed to lookup unmarshaller for " + bindingType);
}
Object type_instance = um.unmarshal(context);
final Collection errors = context.getErrorCollection();
if (!errors.isEmpty()) {
//TODO: review this ctor
System.out.println("errors = " + errors);
String msg = errorsToMsg(errors);
throw new XmlException(msg, null,
Collections.unmodifiableCollection(errors));
}
return type_instance;
}
private static String errorsToMsg(final Collection errors)
{
final int sz = errors.size();
assert sz > 0;
if (sz == 1) {
return "unmarshalling error: " + errors.iterator().next();
} else {
return "unmarshalling errors (" + sz + ")";
}
}
private void advanceToFirstItemOfInterest(XMLStreamReader rdr)
throws XmlException
{
try {
for (int state = rdr.getEventType(); rdr.hasNext(); state = rdr.next()) {
switch (state) {
//these are things we can handle...
case XMLStreamReader.START_ELEMENT:
return;
//eventually we'll handle these...
case XMLStreamReader.ATTRIBUTE:
case XMLStreamReader.CHARACTERS:
throw new AssertionError("UNIMPLEMENTED TYPE: " + state);
//bad news in the xml stream
case XMLStreamReader.END_DOCUMENT:
throw new XmlException("unexpected end of XML");
case XMLStreamReader.END_ELEMENT:
throw new XmlException("unexpected end of XML");
//skip these and keep going
case XMLStreamReader.PROCESSING_INSTRUCTION:
case XMLStreamReader.COMMENT:
case XMLStreamReader.START_DOCUMENT:
case XMLStreamReader.SPACE:
break;
default:
//this case pretty much means malformed xml or a bug
throw new XmlException("unexpected xml state:" + state +
"in" + rdr);
}
}
throw new XmlException("unexpected end of xml stream");
}
catch (XMLStreamException e) {
throw new XmlException(e);
}
}
private BindingType determineRootType(UnmarshalContext context)
throws XmlException
{
//TODO: fix this temporary hack
//to get started we're relying on xsi:type being on the root element
//to avoid requiring the schema
QName xsi_type = context.getXsiType();
if (xsi_type == UnmarshalContext.XSI_NIL_MARKER) {
throw new AssertionError("xsi:nil broken on root element for now");
}
if (xsi_type == null) {
throw new AssertionError("xsi:type is required for now");
}
XmlName type_name = XmlName.forTypeNamed(xsi_type);
BindingType bt =
bindingLoader.getBindingTypeForXmlPojo(type_name);
if (bt == null) {
throw new XmlException("failed to load BindingType for XmlName: " +
type_name);
}
return bt;
}
private UnmarshalContext createUnmarshallContext(XMLStreamReader reader,
Collection errors)
{
return new UnmarshalContext(reader, bindingLoader, typeTable, errors);
}
}
1.1 xml-xmlbeans/v2/test/cases/marshal/doc.xml
Index: doc.xml
===================================================================
<?xml version="1.0" encoding="utf-8"?>
<my:load xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:my="http://www.mytest.com/" xsi:type="my:my-type">
<my:myelt ignore="someval" my:attrib="4444.3333333" >
<my:my-float>65.34</my:my-float>
<my:your_class>
<my:myatt xsi:type="xsd:token">inner-str</my:myatt>
</my:your_class>
</my:myelt>
<!-- not working-->
<!-- <my:myatt xsi:nil="0" xsi:type="my:custom-string" >some string</my:myatt>-->
<my:myatt xsi:type="xsd:token">strval</my:myatt>
</my:load>
1.1 xml-xmlbeans/v2/test/cases/marshal/example_config.xml
Index: example_config.xml
===================================================================
<bin:binding-config xmlns:myt="http://www.mytest.com/" xmlns:bin="http://xmlbeans.apache.org/2003/09/binding-config" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<bin:bindings>
<bin:binding-type xsi:type="bin:by-name-bean">
<bin:xmlcomponent>t=my-type@http://www.mytest.com/</bin:xmlcomponent>
<bin:javatype>com.mytest.MyClass</bin:javatype>
<bin:xmlobj>false</bin:xmlobj>
<bin:qname-property>
<bin:xmlcomponent>t=your-type@http://www.mytest.com/</bin:xmlcomponent>
<bin:javatype>com.mytest.YourClass</bin:javatype>
<bin:getter>getMyelt</bin:getter>
<bin:setter>setMyelt</bin:setter>
<bin:qname>myt:myelt</bin:qname>
</bin:qname-property>
<bin:qname-property>
<bin:xmlcomponent>t=custom-string@http://www.mytest.com/</bin:xmlcomponent>
<bin:javatype>java.lang.String</bin:javatype>
<bin:getter>getMyatt</bin:getter>
<bin:setter>setMyatt</bin:setter>
<bin:qname>myt:myatt</bin:qname>
</bin:qname-property>
</bin:binding-type>
<bin:binding-type xsi:type="bin:by-name-bean">
<bin:xmlcomponent>t=your-type@http://www.mytest.com/</bin:xmlcomponent>
<bin:javatype>com.mytest.YourClass</bin:javatype>
<bin:xmlobj>false</bin:xmlobj>
<bin:qname-property>
<bin:xmlcomponent>t=my-type@http://www.mytest.com/</bin:xmlcomponent>
<bin:javatype>com.mytest.MyClass</bin:javatype>
<bin:getter>getMyClass</bin:getter>
<bin:setter>setMyClass</bin:setter>
<bin:qname>myt:your_class</bin:qname>
</bin:qname-property>
<bin:qname-property>
<bin:xmlcomponent>t=float@http://www.w3.org/2001/XMLSchema</bin:xmlcomponent>
<bin:javatype>float</bin:javatype>
<bin:getter>getMyFloat</bin:getter>
<bin:setter>setMyFloat</bin:setter>
<bin:qname>myt:my-float</bin:qname>
</bin:qname-property>
<bin:qname-property>
<bin:xmlcomponent>t=float@http://www.w3.org/2001/XMLSchema</bin:xmlcomponent>
<bin:javatype>float</bin:javatype>
<bin:getter>getAttrib</bin:getter>
<bin:setter>setAttrib</bin:setter>
<bin:qname>myt:attrib</bin:qname>
<bin:attribute>true</bin:attribute>
</bin:qname-property>
</bin:binding-type>
<bin:binding-type xsi:type="bin:simple-type">
<bin:xmlcomponent>t=custom-string@http://www.mytest.com/</bin:xmlcomponent>
<bin:javatype>java.lang.String</bin:javatype>
<bin:xmlobj>false</bin:xmlobj>
<bin:as-xml>t=string@http://www.w3.org/2001/XMLSchema</bin:as-xml>
</bin:binding-type>
</bin:bindings>
<bin:xml-to-pojo>
<bin:mapping>
<bin:xmlcomponent>t=my-type@http://www.mytest.com/</bin:xmlcomponent>
<bin:javatype>com.mytest.MyClass</bin:javatype>
</bin:mapping>
<bin:mapping>
<bin:xmlcomponent>t=your-type@http://www.mytest.com/</bin:xmlcomponent>
<bin:javatype>com.mytest.YourClass</bin:javatype>
</bin:mapping>
</bin:xml-to-pojo>
<bin:xml-to-xmlobj/>
<bin:java-to-xml>
<bin:mapping>
<bin:xmlcomponent>t=my-type@http://www.mytest.com/</bin:xmlcomponent>
<bin:javatype>com.mytest.MyClass</bin:javatype>
</bin:mapping>
<bin:mapping>
<bin:xmlcomponent>t=your-type@http://www.mytest.com/</bin:xmlcomponent>
<bin:javatype>com.mytest.YourClass</bin:javatype>
</bin:mapping>
<bin:mapping>
<bin:xmlcomponent>t=custom-string@http://www.mytest.com/</bin:xmlcomponent>
<bin:javatype>java.lang.String</bin:javatype>
</bin:mapping>
</bin:java-to-xml>
</bin:binding-config>
1.1 xml-xmlbeans/v2/test/cases/marshal/com/mytest/MyClass.java
Index: MyClass.java
===================================================================
package com.mytest;
public class MyClass {
private YourClass myelt;
private String myatt;
public YourClass getMyelt()
{
return myelt;
}
public void setMyelt(YourClass myelt)
{
this.myelt = myelt;
}
public String getMyatt()
{
return myatt;
}
public void setMyatt(String myatt)
{
this.myatt = myatt;
}
public boolean equals(Object o)
{
if (this == o) return true;
if (!(o instanceof MyClass)) return false;
final MyClass myClass = (MyClass)o;
if (myatt != null ? !myatt.equals(myClass.myatt) : myClass.myatt != null) return false;
if (myelt != null ? !myelt.equals(myClass.myelt) : myClass.myelt != null) return false;
return true;
}
public int hashCode()
{
int result;
result = (myelt != null ? myelt.hashCode() : 0);
result = 29 * result + (myatt != null ? myatt.hashCode() : 0);
return result;
}
public String toString()
{
return "com.mytest.MyClass{" +
"myelt=" + myelt +
", myatt='" + myatt + "'" +
"}";
}
}
1.1 xml-xmlbeans/v2/test/cases/marshal/com/mytest/YourClass.java
Index: YourClass.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache
* XMLBeans", nor may "Apache" appear in their name, without prior
* written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 2000-2003 BEA Systems
* Inc., <http://www.bea.com/>. For more information on the Apache Software
* Foundation, please see <http://www.apache.org/>.
*/
package com.mytest;
public class YourClass
{
private MyClass myClass;
private float myFloat;
private float attrib;
public float getMyFloat()
{
return myFloat;
}
public void setMyFloat(float myFloat)
{
this.myFloat = myFloat;
}
public MyClass getMyClass()
{
return myClass;
}
public void setMyClass(MyClass myClass)
{
this.myClass = myClass;
}
public float getAttrib()
{
return attrib;
}
public void setAttrib(float attrib)
{
this.attrib = attrib;
}
public boolean equals(Object o)
{
if (this == o) return true;
if (!(o instanceof YourClass)) return false;
final YourClass yourClass = (YourClass)o;
if (attrib != yourClass.attrib) return false;
if (myFloat != yourClass.myFloat) return false;
if (myClass != null ? !myClass.equals(yourClass.myClass) : yourClass.myClass != null) return false;
return true;
}
public int hashCode()
{
int result;
result = (myClass != null ? myClass.hashCode() : 0);
result = 29 * result + Float.floatToIntBits(myFloat);
result = 29 * result + Float.floatToIntBits(attrib);
return result;
}
public String toString()
{
return "com.mytest.YourClass{" +
"myClass=" + myClass +
", myFloat=" + myFloat +
", attrib=" + attrib +
"}";
}
}
1.2 +152 -90 xml-xmlbeans/v2/test/src/drt/drtcases/MarshalTests.java
Index: MarshalTests.java
===================================================================
RCS file: /home/cvs/xml-xmlbeans/v2/test/src/drt/drtcases/MarshalTests.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- MarshalTests.java 16 Oct 2003 00:02:50 -0000 1.1
+++ MarshalTests.java 23 Oct 2003 23:49:03 -0000 1.2
@@ -4,6 +4,7 @@
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
+import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.impl.binding.bts.BindingFile;
import org.apache.xmlbeans.impl.marshal.BindingContext;
import org.apache.xmlbeans.impl.marshal.BindingContextFactory;
@@ -12,99 +13,160 @@
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;
-import java.io.StringReader;
+import java.io.CharArrayReader;
+import java.io.CharArrayWriter;
+import java.io.File;
+import java.io.FileReader;
import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.Writer;
public class MarshalTests extends TestCase
{
- public MarshalTests(String name)
- {
- super(name);
- }
-
- public static Test suite()
- {
- return new TestSuite(MarshalTests.class);
- }
-
- public void testFloatUnmarshall()
- throws Exception
- {
- Unmarshaller unmarshaller = getSimpleUnmarshaller();
-
- final float val = 3.45f;
-
- String xmldoc = "<a xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'" +
- " xmlns:xs='http://www.w3.org/2001/XMLSchema' xsi:type='xs:float' >" +
- val + "</a>";
-
- StringReader stringReader = new StringReader(xmldoc);
- XMLStreamReader xrdr =
- XMLInputFactory.newInstance().createXMLStreamReader(stringReader);
-
- Object obj = unmarshaller.unmarshal(xrdr);
-
- Float expected = new Float(val);
- Assert.assertEquals(expected, obj);
- }
-
- public void testManySimpleTypesUnmarshall()
- throws Exception
- {
- testSimpleTypeUnmarshall(new Long(554345354445555555L), "long");
- testSimpleTypeUnmarshall(new Float(54.5423f), "float");
- testSimpleTypeUnmarshall("random string", "string");
- }
-
-
- //only works for values where .toString() is equivalent to marshalling
- public void testSimpleTypeUnmarshall(Object expected, String xsd_type)
- throws Exception
- {
- Unmarshaller unmarshaller = getSimpleUnmarshaller();
-
- String xmldoc = "<a xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'" +
- " xmlns:xs='http://www.w3.org/2001/XMLSchema' xsi:type='xs:" +
- xsd_type + "' >" + expected + "</a>";
-
- StringReader stringReader = new StringReader(xmldoc);
- XMLStreamReader xrdr =
- XMLInputFactory.newInstance().createXMLStreamReader(stringReader);
-
- Object obj = unmarshaller.unmarshal(xrdr);
-
- Assert.assertEquals(expected, obj);
-
- System.out.println("OK for " + expected);
- }
-
- private static Unmarshaller getSimpleUnmarshaller() throws IOException
- {
- BindingFile bf = new BindingFile();
- BindingConfigDocument bindingConfigDocument = bf.write();
-
- BindingContext bindingContext =
- BindingContextFactory.createBindingContext(bindingConfigDocument);
-
- Unmarshaller unmarshaller = bindingContext.createUnmarshaller();
- return unmarshaller;
- }
-
- public void testSimpleMarshall()
- throws Exception
- {
- BindingFile bf = new BindingFile();
- BindingConfigDocument bindingConfigDocument = bf.write();
-
- BindingContext bindingContext =
- BindingContextFactory.createBindingContext(bindingConfigDocument);
-
-
- final float val = 3.45f;
- final Float out_obj = new Float(val);
-
- System.out.println("obj = " + out_obj);
-
- }
+ public MarshalTests(String name)
+ {
+ super(name);
+ }
+
+ public static Test suite()
+ {
+ return new TestSuite(MarshalTests.class);
+ }
+
+ public void testManySimpleTypesUnmarshall()
+ throws Exception
+ {
+ testSimpleTypeUnmarshall(new Long(554345354445555555L), "long");
+ testSimpleTypeUnmarshall(new Float(54.5423f), "float");
+ testSimpleTypeUnmarshall("random string", "string");
+ }
+
+
+ //only works for values where .toString() is equivalent to marshalling
+ public void testSimpleTypeUnmarshall(Object expected, String xsd_type)
+ throws Exception
+ {
+ Unmarshaller unmarshaller = getSimpleUnmarshaller();
+
+ String xmldoc = "<a xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'" +
+ " xmlns:xs='http://www.w3.org/2001/XMLSchema' xsi:type='xs:" +
+ xsd_type + "' >" + expected + "</a>";
+
+ StringReader stringReader = new StringReader(xmldoc);
+ XMLStreamReader xrdr =
+ XMLInputFactory.newInstance().createXMLStreamReader(stringReader);
+
+ Object obj = unmarshaller.unmarshal(xrdr);
+
+ Assert.assertEquals(expected, obj);
+
+ System.out.println("OK for " + expected);
+ }
+
+ public void testByNameBeanUnmarshall()
+ throws Exception
+ {
+ BindingConfigDocument bcdoc = getBindingConfigDocument();
+
+ BindingContext bindingContext =
+ BindingContextFactory.createBindingContext(bcdoc);
+
+ Unmarshaller unmarshaller = bindingContext.createUnmarshaller();
+
+ Assert.assertNotNull(unmarshaller);
+
+ //TODO: remove hard coded path
+ File doc = new File("test/cases/marshal/doc.xml");
+
+
+ final XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
+ XMLStreamReader xrdr =
+ xmlInputFactory.createXMLStreamReader(new FileReader(doc));
+
+ Object obj = unmarshaller.unmarshal(xrdr);
+
+ System.out.println("obj = " + obj);
+ }
+
+ public void testPerfByNameBeanUnmarshall()
+ throws Exception
+ {
+ BindingConfigDocument bcdoc = getBindingConfigDocument();
+
+ BindingContext bindingContext =
+ BindingContextFactory.createBindingContext(bcdoc);
+
+ Unmarshaller unmarshaller = bindingContext.createUnmarshaller();
+
+ Assert.assertNotNull(unmarshaller);
+
+ //TODO: remove hard coded path
+ File doc = new File("test/cases/marshal/doc.xml");
+ final FileReader fileReader = new FileReader(doc);
+ CharArrayWriter cw = new CharArrayWriter();
+
+ bufferedStreamCopy(fileReader, cw);
+ final char[] chars = cw.toCharArray();
+ final CharArrayReader cr = new CharArrayReader(chars);
+
+ final int trials = 5000;
+
+ final XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
+
+ final long before_millis = System.currentTimeMillis();
+ for (int i = 0; i < trials; i++) {
+ cr.reset();
+ XMLStreamReader xrdr =
+ xmlInputFactory.createXMLStreamReader(cr);
+
+ Object obj = unmarshaller.unmarshal(xrdr);
+
+ if ((i % 1000) == 0)
+ System.out.println("i=" + i + "\tobj = " + obj);
+ }
+ final long after_millis = System.currentTimeMillis();
+ final long diff = (after_millis - before_millis);
+ System.out.println("milliseconds: " + diff + " trials: " + trials);
+ System.out.println("milliseconds PER trial: " + (diff / (double)trials));
+ }
+
+ protected static void bufferedStreamCopy(Reader in, Writer out)
+ throws IOException
+ {
+ int charsRead;
+ char[] buf = new char[1024];
+
+ while ((charsRead = in.read(buf)) != -1) {
+ out.write(buf, 0, charsRead);
+ }
+ }
+
+
+ private BindingConfigDocument getBindingConfigDocument()
+ throws IOException, XmlException
+ {
+ //TODO: remove hard coded path
+ File loc = new File("test/cases/marshal/example_config.xml");
+ BindingConfigDocument bcdoc = BindingConfigDocument.Factory.parse(loc);
+ return bcdoc;
+ }
+
+ private static Unmarshaller getSimpleUnmarshaller() throws IOException
+ {
+ BindingFile bf = new BindingFile();
+ BindingConfigDocument bindingConfigDocument = bf.write();
+
+ BindingContext bindingContext =
+ BindingContextFactory.createBindingContext(bindingConfigDocument);
+
+ Unmarshaller unmarshaller = bindingContext.createUnmarshaller();
+ return unmarshaller;
+ }
+
+ public static void main(String args[])
+ {
+ junit.textui.TestRunner.run(suite());
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: xmlbeans-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: xmlbeans-cvs-help@xml.apache.org