ebXML Object Model
author: Heikki Doeleman
This page describes GeoNetwork's implementation of the ebXML Object Model.
Introduction
The ebXML Object Model is specified in "ebXML Registry Information Model Version 3.0" wich can be found here. It defines the types of metadata and content that can be stored in an ebXML Registry. The specification is the basis for an XML Schema for this model, which you can find inside this zip file. I have put a copy on this Wiki here.
GeoNetwork has implemented the Information Model in Java. The implementation is capable of marshalling, unmarshalling and validating XML documents that conform to the XSD mentioned above. The implementation will be loosely coupled to the Persistence Layer for storage and retrieval.
Implementation
The implementation of the Information Model is referred to as ebXML Object Model. It consists of a set of Java Beans representing the objects in the specification mentioned above. Where there are discrepancies between the specification and the XSD mentioned above, preference was given to the definition in the XSD. See here for a list of these.
The implementation is structured in the following packages, largely corresponding to the specification:
- org.geonetwork.ebxml.informationmodel.association
- org.geonetwork.ebxml.informationmodel.classification
- org.geonetwork.ebxml.informationmodel.cooperatingregistries
- org.geonetwork.ebxml.informationmodel.core
- org.geonetwork.ebxml.informationmodel.core.datatype
- org.geonetwork.ebxml.informationmodel.event
- org.geonetwork.ebxml.informationmodel.provenance
- org.geonetwork.ebxml.informationmodel.service
- org.geonetwork.ebxml.informationmodel.xsd
All of these packages correspond to a section in the specification except the org.geonetwork.ebxml.informationmodel.xsd package, which contains Java Beans to assist in representing XSD datatypes that have no equivalent in the Java language, such as xsd:duration.
Note: the Access Control section of the Information Model specification is not (yet) part of the implementation.
The implementation is complemented with a suite of unit tests, for each of the objects that may be used as a top-level element in an ebXML document. The unit tests are written in the well-known Junit framework. For each of these objects there is a testcase for marshalling and a testcase for unmarshalling. As we're dealing with XML the tests use the complimentary test library XML Unit. This allows a.o. to ignore differences in whitespace and the ordering of elements and attributes in the XML where that should be ignored. An automatic run of the test suite has been incorporated into the Ant build script and will be made part of the Continuous Integration build process.
XML binding
In order to efficiently establish an XML binding, that is to say the ability to marshal and unmarshal XML documents, the Java Beans implementation is decorated with a JiBX binding. JiBX was chosen over other binding frameworks such as XMLBeans, Castor and JAXB because of its high performance, ease of use, and non-intrusive programming model.
The core of the binding is an XML definition that relates XML elements to Java Beans (and vice versa). A simple snippet from the binding is the following, which relates a LocalizedString from the ebXML XSD and its Java Bean representation:
<mapping name="LocalizedString" class="org.geonetwork.ebxml.informationmodel.core.datatype.LocalizedString" > <value style="attribute" name="lang" field="lang" usage="optional"/> <value style="attribute" name="value" field="value" usage="optional" /> <value style="attribute" name="charset" field="charset" usage="optional" /> </mapping>
A sample of code that marshals a RegistryObject to an ebXML RIM document is the following. This and similar code you can find in the Object Model's unit test suite.
RegistryObject registryObject = new RegistryObject(); // .. // set data to this registryObject .. // .. IBindingFactory bfact = BindingDirectory.getFactory(RegistryObject.class); IMarshallingContext marshallingContext = bfact.createMarshallingContext(); Writer out = new BufferedWriter(new OutputStreamWriter(new ByteArrayOutputStream())); marshallingContext.setOutput(out); // pretty-print the XML output marshallingContext.setIndent(3); marshallingContext.marshalDocument(registryObject, "UTF-8", null);
A perhaps remarkable feature of JiBX is that it requires a post-compilation step where the JiBX binding compiler generates the binding code. Although it can be skipped and the binding done at runtime, doing this improves performance and also helps signaling possible errors in the binding definition. This has been made part of the automated build process.
For the developers amongst you, there is an Eclipse plugin available that will automatically run the binding compiler every time you build.