Package com.luciad.format.xml.bind
Interface ILcdXMLUnmarshaller<T>
- All Known Implementing Classes:
TLcdXMLUnmarshallerAdapter
public interface ILcdXMLUnmarshaller<T>
An A template for the
The
ILcdXMLUnmarshaller
is responsible for unmarshalling (deserializing) XML data into newly created Java
content trees. More precisely, an unmarshaller is responsible for unmarshalling one specific XML element and
all of its contents into instances of one (sometimes more) Java class, or, in case of complex data structures,
Java object graphs. The XML data are provided via the Streaming API for XML (StAX).
Please refer to the package documentation
for a general overview
of the XML Binding Framework.
A template for the unmarshal
method
The unmarshal
method should perform the following steps:
- Create a new Java instance into which the XML element should be unmarshalled.
- Read the element's name and store it in the unmarshalled Java object (if relevant).
- Read all the attributes, and store them in the Java object.
- Read all the other contents (simple content and/or child elements), and store them in the Java object.
- Verify that the StAX cursor is now at the end tag of the element which was unmarshalled. If any unexpected content is left, an XMLStreamException is thrown.
public Object unmarshal( XMLStreamReader aReader, Map aContext ) throws XMLStreamException {
// Create a new Java instance for the unmarshalled object.
MyObject unmarshalled_object = new MyObject();
// Read and store the element's name.
QName name = aReader.getName();
unmarshalled_object.setXMLName(name);
// Unmarshal the element's attributes.
unmarshalled_object.setAttributeX(aReader.getAttributeValue("NamespaceURI","AttributeName");
[...]
// Unmarshal the element's children.
[...]
// Verify that there is no unexpected content left.
if ( aReader.getEventType() != XMLStreamReader.END_ELEMENT || !name.equals( aReader.getName() )) {
throw new XMLStreamException( "Unexpected XML content at " + aReader.getLocation() + ": " + aReader.getName() );
}
return unmarshalled_object;
}
If the unmarshaller uses an ILcdXMLTypeUnmarshaller
for reading its contents,
this can be simplified to the following:
public Object unmarshal( XMLStreamReader aReader, Map aContext ) throws XMLStreamException {
// Create a new Java instance for the unmarshalled object.
MyObject unmarshalled_object = new MyObject();
// Read and store the element's name.
QName name = aReader.getName();
unmarshalled_object.setXMLName(name);
// Unmarshal the element's contents.
fTypeUnmarshaller.unmarshalType(unmarshalled_object, aReader, aContext);
// Verify that there is no unexpected content left.
if ( aReader.getEventType() != XMLStreamReader.END_ELEMENT || !name.equals( aReader.getName() )) {
throw new XMLStreamException( "Unexpected XML content at " + aReader.getLocation() + ": " + aReader.getName() );
}
return unmarshalled_object;
}
Delegating child unmarshalling to other unmarshallers
Although it is allowed to write one monolithic unmarshaller containing not only the code for unmarshalling the XML element itself but also all child elements, it is advised to split up the unmarshalling code and write one unmarshaller per element. This allows reusage of unmarshallers (the same element can be a child element of different other elements) and increases the overall readability of the code. TheTLcdXMLUnmarshallerProvider
class
provides functionality for sharing unmarshallers.
The following code snippet briefly illustrates how unmarshalling a child element via delegation to another unmarshaller
should be done:
// The unmarshaller keeps a link to its unmarshaller provider.
private TLcdXMLUnmarshallerProvider fUnmarshallerProvider;
public Object unmarshal( Object aObject, XMLStreamReader aReader, Map aContext ) throws XMLStreamException {
[...]
// Retrieve the unmarshaller for the child element.
ILcdXMLUnmarshaller child_unmarshaller = fUnmarshallerProvider.getUnmarshaller( MyConstants.MY_CHILD, MyChild.class );
// Unmarshal the child.
MyChild child = (MyChild ) child_unmarshaller.unmarshal( aReader, aContext );
// Configure the child on the unmarshalled object.
unmarshalled_object.setChild(child);
// The XML cursor is now at the end element of the child. It should be moved to the next position to continue with the next child.
aReader.nextTag();
[...]
}
Communication between unmarshallers
To allow communication between unmarshallers, the unmarshalling methods all have a document context argument, which is a Java Map-like interface, in/from which objects can be stored/retrieved. This context is unique per document to be unmarshalled. Unmarshallers should document clearly which information they expect to be present in the context Map, and which information they store into the context themselves. See theILcdXMLDocumentContext
documentation for more information on the use of the
document context.
Note about thread-safety
One unmarshaller instance can be used by aTLcdXMLDecoder
to unmarshal several XML document
concurrently. Implementations of this interface should therefore be thread-safe.
- Since:
- 8.2
- See Also:
-
Method Summary
Modifier and TypeMethodDescriptionunmarshal
(XMLStreamReader aReader, ILcdXMLDocumentContext aContext) Unmarshals (deserializes) the XML element at the current cursor position of the specifiedXMLStreamReader
and returns the resulting Java object graph.
-
Method Details
-
unmarshal
Unmarshals (deserializes) the XML element at the current cursor position of the specifiedXMLStreamReader
and returns the resulting Java object graph. At the moment this method is called, the cursor should be positioned at the start tag of the element to be unmarshalled. When this method returns, the cursor should be left at the end tag of the element which was unmarshalled.- Parameters:
aReader
- the StAX reader to unmarshal XML data from.aContext
- aILcdXMLDocumentContext
which can be used to store and retrieve information which is shared between multiple unmarshallers. This context is unique per unmarshalled XML document.- Returns:
- the newly created Java object graph representing the XML element that was unmarshalled.
- Throws:
XMLStreamException
- if any unexpected content occurs within the XML element to be unmarshalled.- Preconditions:
- The cursor should be positioned at the start tag of the element to be unmarshalled
(
aReader.getEventType() == XMLStreamReader.START_ELEMENT
). - Postconditions:
- The cursor should be left at the end tag of the element which was unmarshalled
(
aReader.getEventType() == XMLStreamReader.START_ELEMENT
).
-