Interface ILcdXMLUnmarshaller<T>

All Known Implementing Classes:
TLcdXMLUnmarshallerAdapter

public interface ILcdXMLUnmarshaller<T>
An 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.
The following code snippet can be used as a template:

 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. The TLcdXMLUnmarshallerProvider 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 the ILcdXMLDocumentContext documentation for more information on the use of the document context.

Note about thread-safety

One unmarshaller instance can be used by a TLcdXMLDecoder to unmarshal several XML document concurrently. Implementations of this interface should therefore be thread-safe.

Since:
8.2
See Also:
  • Method Summary

    Modifier and Type
    Method
    Description
    Unmarshals (deserializes) the XML element at the current cursor position of the specified XMLStreamReader and returns the resulting Java object graph.
  • Method Details

    • unmarshal

      T unmarshal(XMLStreamReader aReader, ILcdXMLDocumentContext aContext) throws XMLStreamException
      Unmarshals (deserializes) the XML element at the current cursor position of the specified XMLStreamReader 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 - a ILcdXMLDocumentContext 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).