import org.eclipse.persistence.oxm.XMLContext;
MyProject proj = new MyProject();
XMLContext ctx = new XMLContext(proj);
Object o = ctx.createUnmarshaller().unmarshal(new File("instance-1.xml"));
System.out.println("OBJECT: " + o + " ("+ o.getClass() + ")");
Result:
OBJECT: 16.0 (class java.lang.Double)
Use Case 2: Element Type Doesn't Match Schema
Instance Document (instance-2.xml
):
<?xml version="1.0"?>
<aValue xsi:type="date">16</aValue>
Use Case 3: Unexpected Content
Instance Document (instance-3.xml
):
<?xml version="1.0"?>
<aValue>
<other>Something Else</other>
Hello World!
</aValue>
Use Case 4: Datatype is a Union
Instance Document (instance-4.xml
):
Prototype
Following is an overview of the prototype implementation.
XMLDatatypeDescriptor
The information required to work with primitive data types is encapsulated in a new class, XMLDatatypeDescriptor
. This is far less complicated than the other types of Eclipselink descriptors, storing only the following data:
// org.eclipse.persistence.oxm.XMLDatatypeDescriptor
public class XMLDatatypeDescriptor {
// Element's QName; also used as the key in XMLContext's datatypesByQName Map
private QName qName;
// Java class this element will be converted to
private Class javaClass;
// Element's XSD Type
private QName schemaType;
XMLContext's datatypesByQName Map
A hash map is added to XMLContext
to keep track of which user-defined types represent restrictions ("subclasses") of XML primitive types. The values of this map are XMLDatatypeDescriptor
s, keyed on the element's QName
.
// org.eclipse.persistence.oxm.XMLContext
public class XMLContext {
private Map<QName, XMLDatatypeDescriptor> datatypesByQName;
During unmarshal operations, if the QName
of the element being unmarshalled is present in datatypesByQName
, a new XMLRootRecord
is created. XMLRootRecord
is a SAX ContentHandler, and control will be passed to it to unmarshal the primitive element:
// org.eclipse.persistence.internal.oxm.record.SAXUnmarshallerHandler
public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
XMLDescriptor xmlDescriptor = xmlContext.getDescriptor(rootQName);
if (null == xmlDescriptor) {
// Check to see if there is an XMLDatatypeDescriptor for this QName
XMLDatatypeDescriptor wrapper = (XMLDatatypeDescriptor) xmlContext.getDatatypesByQName().get(rootQName);
if (wrapper != null) {
XMLRootRecord rootRecord = new XMLRootRecord(wrapper.getJavaClass(), this, wrapper.getSchemaType());
rootRecord.setSession((AbstractSession) xmlContext.getSession(wrapper));
rootRecord.startElement(namespaceURI, localName, qName, atts);
xmlReader.setContentHandler(rootRecord);
return;
This map is populated in one of three ways:
1. (SDO) When the user defines a schema using SDOXSDHelper.define()
, a new XMLDatatypeDescriptor will be created and put into the map during type generation:
// org.eclipse.persistence.sdo.helper.SDOTypesGenerator
private void addRootElementToDescriptor(SDOProperty p, String targetNamespace, String xsdName) {
if (!p.getType().isDataType()) {
} else {
// This must be a primitive, so add to XMLContext's primitivesByQName map
SDOXMLHelper helper = (SDOXMLHelper) ((SDOType)p.getType()).getHelperContext().getXMLHelper();
QName qn = new QName(targetNamespace, xsdName);
Class primitiveClass = p.getType().getInstanceClass();
QName xsdTypeQN = ((SDOType)p.getType()).getXsdType();
XMLDatatypeDescriptor wrapper = new XMLDatatypeDescriptor(qn, primitiveClass, xsdTypeQN);
helper.getXmlContext().getDatatypesByQName().put(qn, wrapper);
2. (SDO) When the user specifies types directly, using SDOTypeHelper.define()
, a new XMLDatatypeDescriptor will be put into the map in defineOpenContentProperty():
// org.eclipse.persistence.sdo.helper.delegates.SDOTypeHelperDelegate
private void defineOpenContentProperty(String propertyUri, String propertyName, Property property) {
if (propertyUri != null) {
XMLDescriptor aDescriptor = ((SDOType)property.getType()).getXmlDescriptor();
if (aDescriptor != null) {
} else {
// This must be a primitive, so add to XMLContext's primitivesByQName map
SDOXMLHelper helper = (SDOXMLHelper) ((SDOType)property.getType()).getHelperContext().getXMLHelper();
Class primitiveClass = property.getType().getInstanceClass();
QName xsdTypeQN = ((SDOType)property.getType()).getXsdType();
XMLDatatypeDescriptor wrapper = new XMLDatatypeDescriptor(propertyQName, primitiveClass, xsdTypeQN);
helper.getXmlContext().getDatatypesByQName().put(propertyQName, wrapper);
3. When the user explicitly adds primitive type information to XMLLogin
in code:
XMLLogin xmlLogin = new XMLLogin();
Project oxmProject = new Project(xmlLogin);
QName qname = new QName("myBase64Binary-NS", "myBase64Binary");
XMLDatatypeDescriptor desc = new XMLDatatypeDescriptor(qname, Byte[].class, XMLConstants.BASE_64_BINARY_QNAME);
xmlLogin.addXMLDatatypeDescriptor(desc);
XMLContext xmlContext = new XMLContext(oxmProject);
Project Metadata
XMLDatatypeDescriptors
are persisted to XML as part of the XMLLogin
element, and are accessed through the public API on XMLLogin
shown above. An example of a project containing primitive information:
<?xml version="1.0" encoding="UTF-8"?>
<eclipselink:object-persistence version="Eclipse Persistence Services - 1.0 (Build SNAPSHOT - 20080227)" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:eclipselink="http://xmlns.oracle.com/ias/xsds/eclipselink">
<eclipselink:name>My OXM Project</eclipselink:name>
<eclipselink:login xsi:type="eclipselink:xml-login">
<eclipselink:platform-class>org.eclipse.persistence.oxm.platform.SAXPlatform</eclipselink:platform-class>
<eclipselink:user-name></eclipselink:user-name>
<eclipselink:password></eclipselink:password>
<eclipselink:datatype-descriptors>
<eclipselink:datatype-descriptor>
<eclipselink:java-class>java.lang.Float</eclipselink:java-class>
<eclipselink:schema-type>{http://www.w3.org/2001/XMLSchema}float</eclipselink:schema-type>
<eclipselink:qname>{myFloat-NS}myFloat</eclipselink:qname>
</eclipselink:datatype-descriptor>
</eclipselink:datatype-descriptors>
</eclipselink:login>
</eclipselink:object-persistence>
Documentation
EclipseLink User Documentation should be updated to demonstrate how documents containing Simple Type root elements are supported.
Open Issues
Issue #
Owner
Description / Notes
Decisions
Issue #
Description / Notes
Decision
Future Considerations