Architecture Overview
The architecture of XStream consists of the four main components:
- Converters
- Drivers (Writer and Reader)
- Context
- Facade
Converters
Whenever XStream encounters an object that needs to be converted to/from XML, it delegates to a suitable Converter implementation associated with the class of that Object.
XStream comes bundled with many converters for common types, including primitives, String, Collections, arrays, null, Date, etc.
XStream also has a default Converter, that is used when no other Converters match a type. This uses reflection to automatically generate the XML for all the fields in an object.
If an object is composed of other objects, the Converter may delegate to other Converters.
To customize the XML for particular object type a new Converter should be implemented.
Drivers (Writer and Reader)
XStream is abstracted from the underlying XML data using the HierarchicalStreamWriter and HierarchicalStreamReader interfaces for serializing and deserializing respectively.
This abstraction allows XStream to read XML from direct streams using an XML parser or directly manipulate existing structures (such as DOM). This prevents the overhead of having to reparse if XStream is working from XML that has been partially processed by other libraries (for instance a SOAP library). It also avoids tying XStream to a particular library.
XStream comes bundled with reader and writer implementations for most major XML libraries.
Writer and Readers can be implemented allowing XStream to serialize to most XML APIs. Writers and Readers can also be created around tree based non XML structures.
Context
When XStream serializes or deserializes some objects, it creates a MarshallingContext or UnmarshallingContext, which handle the traversing of the data and delegation to the necessary Converters.
The MarshallingContext/UnmarshallingContext is made available to converters allowing them to tell XStream to process objects contained within other objects.
XStream provides three pairs of context implementations that traverse the object graph with slightly different behaviors. The default can be changed using XStream.setMode(), passing in one of the following parameters:
-
XStream.XPATH_RELATIVE_REFERENCES
(Default) Uses relative XPath references to signify duplicate references. This produces XML with the least clutter. -
XStream.XPATH_ABSOLUTE_REFERENCES
Uses absolute XPath references to signify duplicate references. This might produce for some situations better readable XML. Note, that XStream will read XML with relative paths as well as with absolute paths independent of the XPATH mode. -
XStream.ID_REFERENCES
Uses ID references to signify duplicate references. In some scenarios, such as when using hand-written XML, this is easier to work with. -
XStream.NO_REFERENCES
This disables object graph support and treats the object structure like a tree. Duplicate references are treated as two separate objects and circular references cause an exception. This is slightly faster and uses less memory than the other two modes.
A new context is created for each object graph that is serialized. Both the MarshallingContext and UnmarshallingContext implement DataHolder, a hash table passed around whilst processing the object graph that can be used as the user sees fit (in a similar way that the HttpServletRequest attributes are used in a web-application).
XStream facade
The main XStream class is typically used as the entry point. This assembles the necessary components of XStream (as described above; Context, Converter, Writer/Reader and ClassMapper) and provides a simple to use API for common operations.
Remember, the XStream class is just a facade - it can always be bypassed for more advanced operations.