javolution.xml

Home
Java Source Code / Java Documentation
1.6.0 JDK Core
2.6.0 JDK Modules
3.6.0 JDK Modules com.sun
4.6.0 JDK Modules com.sun.java
5.6.0 JDK Modules sun
6.6.0 JDK Platform
7.Ajax
8.Apache Harmony Java SE
9.Aspect oriented
10.Authentication Authorization
11.Blogger System
12.Build
13.Byte Code
14.Cache
15.Chart
16.Chat
17.Code Analyzer
18.Collaboration
19.Content Management System
20.Database Client
21.Database DBMS
22.Database JDBC Connection Pool
23.Database ORM
24.Development
25.EJB Server
26.ERP CRM Financial
27.ESB
28.Forum
29.Game
30.GIS
31.Graphic 3D
32.Graphic Library
33.Groupware
34.HTML Parser
35.IDE
36.IDE Eclipse
37.IDE Netbeans
38.Installer
39.Internationalization Localization
40.Inversion of Control
41.Issue Tracking
42.J2EE
43.J2ME
44.JBoss
45.JMS
46.JMX
47.Library
48.Mail Clients
49.Music
50.Natural Language Processing
51.Net
52.Parser
53.PDF
54.Portal
55.Profiler
56.Project Management
57.Report
58.RSS RDF
59.Rule Engine
60.Science
61.Scripting
62.Search Engine
63.Security
64.Sevlet Container
65.Source Control
66.Swing Library
67.Template Engine
68.Test Coverage
69.Testing
70.UML
71.Web Crawler
72.Web Framework
73.Web Mail
74.Web Server
75.Web Services
76.Web Services apache cxf 2.2.6
77.Web Services AXIS2
78.Wiki Engine
79.Workflow Engines
80.XML
81.XML UI
Java Source Code / Java Documentation  » Development » Javolution » javolution.xml 
javolution.xml

Provides support for the encoding of objects, and the objects reachable from them, into XML; and the complementary reconstruction of the object graph from XML.

XML marshalling/unmarshalling facility:

XML Data Binding

Key Advantages:

  • Real-time characteristics with no adverse effect on memory footprint or garbage collection (e.g. it can be used for time critical communications). {@link javolution.xml.XMLFormat XMLFormat} is basically a "smart" wrapper around our real-time StAX-like {@link javolution.xml.stream.XMLStreamReader XMLStreamReader} and {@link javolution.xml.stream.XMLStreamWriter XMLStreamWriter}.
  • Works directly with your existing Java classes, no need to create new classes or customize your implementation in any way.
  • The XML representation can be high level and impervious to obfuscation or changes to your implementation.
  • Performance on a par or better than default JavaTM Serialization/Deserialization (See bindmark for performance comparison).
  • Runs on any platform including J2ME CLDC 1.0 It does not require reflection or or any interface (e.g. Serializable) to be implemented.
  • The XML mapping can be defined for a top class (or interface) and is automatically inherited by all sub-classes (or all implementing classes).
  • Supports object references (to avoid expanding objects already formatted).

The default XML mapping for a class and its sub-classes is typically defined using a static final {@link javolution.xml.XMLFormat XMLFormat} instance. For example:[code] public abstract class Graphic implements XMLSerializable { private boolean _isVisible; private Paint _paint; // null if none. private Stroke _stroke; // null if none. private Transform _transform; // null if none. // Default XML format with name associations (members identified by an unique name). // See XMLFormat for examples of positional associations. protected static final XMLFormat XML = new XMLFormat(Graphic.class) { public void write(Graphic g, OutputElement xml) throws XMLStreamException { xml.setAttribute("isVisible", g._isVisible); xml.add(g._paint, "Paint"); xml.add(g._stroke, "Stroke"); xml.add(g._transform, "Transform"); } public void read(InputElement xml, Graphic g) throws XMLStreamException { g._isVisible = xml.getAttribute("isVisible", true); g._paint = xml.get("Paint"); g._stroke = xml.get("Stroke"); g._transform = xml.get("Transform"); } }; }[/code] Sub-classes may override the inherited XML format:[code] public class Area extends Graphic { private Shape _geometry; // Adds geometry to format. protected static final XMLFormat XML = new XMLFormat(Area.class) { public void write(Area area, OutputElement xml) throws XMLStreamException { Graphic.XML.write(area, xml); // Calls parent write. xml.add(area._geometry, "Geometry"); } public void read(InputElement xml, Area area) throws XMLStreamException { Graphic.XML.read(xml, area); // Calls parent read. area._geometry = xml.get("Geometry"); } }; }[/code] The following writes a graphic area to a file, then reads it:[code] // Creates some useful aliases for class names. XMLBinding binding = new XMLBinding(); binding.setAlias(Color.class, "Color"); binding.setAlias(Polygon.class, "Polygon"); binding.setClassAttribute("type"); // Use "type" instead of "class" for class attribute. // Writes the area to a file. XMLObjectWriter writer = XMLObjectWriter.newInstance(new FileOutputStream("C:/area.xml")); writer.setBinding(binding); // Optional. writer.setIndentation("\t"); // Optional (use tabulation for indentation). writer.write(area, "Area", Area.class); writer.close(); // Reads the area back XMLObjectReader reader = XMLObjectReader.newInstance(new FileInputStream("C:/area.xml")); reader.setBinding(binding); Area a = reader.read("Area", Area.class); reader.close(); [/code] Here is an example of valid XML representation for an area:[code] [/code]

The following table illustrates the variety of XML representations supported (Foo class with a single String member named text):

XML FORMAT XML DATA
[code]XMLFormat XML = new XMLFormat(Foo.class) { public void write(Foo foo, OutputElement xml) throws XMLStreamException { xml.setAttribute("text", foo.text); } public void read(InputElement xml, Foo foo) throws XMLStreamException { foo.text = xml.getAttribute("text", ""); } };[/code]
 <!-- Member as attribute -->
 <Foo text="This is a text"/>
[code]XMLFormat XML = new XMLFormat(Foo.class) { public void write(Foo foo, OutputElement xml) throws XMLStreamException { xml.add(foo.text); } public void read(InputElement xml, Foo foo) throws XMLStreamException { foo.text = xml.getNext(); } };[/code]
 <!-- Member as anonymous nested element -->
 <Foo>
     <java.lang.String value="This is a text"/>
 </Foo>
[code]XMLFormat XML = new XMLFormat(Foo.class) { public void write(Foo foo, OutputElement xml) throws XMLStreamException { xml.addText(foo.text); // or xml.getStreamWriter().writeCDATA(foo.text) to use CDATA block. } public void read(InputElement xml, Foo foo) throws XMLStreamException { foo.text = xml.getText().toString(); // Content of a text-only element. } };[/code]
 <!-- Member as Character Data -->
 <Foo>This is a text</Foo>
[code]XMLFormat XML = new XMLFormat(Foo.class) { public void write(Foo foo, OutputElement xml) throws XMLStreamException { xml.add(foo.text, "Text"); } public void read(InputElement xml, Foo foo) throws XMLStreamException { foo.text = xml.get("Text"); } };[/code]
 <!-- Member as named element of unknown type  -->
 <Foo>
     <Text class="java.lang.String" value="This is a text"/>
 </Foo>
[code]XMLFormat XML = new XMLFormat(Foo.class) { public void write(Foo foo, OutputElement xml) throws XMLStreamException { xml.add(foo.text, "Text", String.class); } public void read(InputElement xml, Foo foo) throws XMLStreamException { foo.text = xml.get("Text", String.class); } };[/code]
 <!-- Member as named element of actual type known -->
 <Foo>
     <Text value="This is a text"/>
 </Foo>

The {@link javolution.xml.XMLFormat XMLFormat} does not have to use the class public no-arg constructor, instances can be created using factory methods, private constructors (with constructor parameters set from the XML element) or even retrieved from a collection (if the object is shared or unique). For example:[code] public final class Point implements XMLSerializable { // Default XMLFormat can be private as the class cannot be extended. static final XMLFormat XML = new XMLFormat(Point.class) { public boolean isReferencable() { return false; // Always manipulates by value. } public Point newInstance(Class cls, InputElement xml) throws XMLStreamException { return Point.valueOf(xml.getAttribute("x", 0), xml.getAttribute("y", 0)); } public void write(Point point, OutputElement xml) throws XMLStreamException { xml.setAttribute("x", point._x); xml.setAttribute("y", point._y); } public void read(InputElement xml, Point point) throws XMLStreamException { // Do nothing immutable. } }; private int _x; private int _y; private Point() {}; // No-arg constructor not visible. public static Point valueOf(int x, int y) { ... } }[/code]

Document cross-references are supported, including circular references. Let's take for example:[code] public class Polygon implements Shape, XMLSerializable { private Point[] _vertices; static final XMLFormat XML = new XMLFormat(Polygon.class) { public void write(Polygon polygon, OutputElement xml) throws XMLStreamException { xml.setAttibutes("count", _vertices.length); for (int i=0; i < _vertices.length; i++) { xml.add(_vertices[i], "Vertex", Point.class); } } public void read(InputElement xml, Polygon polygon) throws XMLStreamException { int count = xml.getAttributes("count", 0); polygon._vertices = new Point[count]; for (int i=0; i < count; i++) { _vertices[i] = xml.get("Vertex", Point.class); } } }; } Polygon[] polygons = new Polygon[] {p1, p2, p1}; ... TextBuilder xml = TextBuilder.newInstance(); AppendableWriter out = new AppendableWriter().setOutput(xml) XMLObjectWriter writer = XMLObjectWriter.newInstance(out); writer.setXMLReferenceResolver(new XMLReferenceResolver()); // Enables cross-references. writer.write(polygons, "Polygons", Polygon[].class); writer.close(); System.out.println(xml); [/code] Prints the following (noticed that the first polygon and last one are being shared).[code] [/code]

ALGORITHMS:

Our {@link javolution.xml.XMLObjectReader XMLObjectReader}/{@link javolution.xml.XMLObjectWriter XMLObjectWriter} are in fact simple wrappers around our Javolution high-performance StAX-like {@link javolution.xml.stream.XMLStreamReader XMLStreamReader} and {@link javolution.xml.stream.XMLStreamWriter XMLStreamWriter} classes. The logic of these wrappers is described below:

Marshalling:

Input: object, referenceResolver, binding
Output: outputElement 

1. class = object.getClass()
    
2. outputElement.getStreamWriter().writeStartElement(name/uri)

   The new element name/uri is:
   
      a - Specified by caller, e.g. add(object, name, uri, class) 
          If the class is not specified e.g. add(object, name, uri) a class attribute is written.
                    
      b - binding.getLocalName(class)/binding.getURI(class), e.g add(object)

3. isReference = referenceResolver.writeReference(object, outputElement)
   
4. if (!isReference) binding.getFormat(class).write(object, outputElement)

5. outputElement.getStreamWriter().writeEndElement()

6. end


Unmarshalling:

Input: inputElement, referenceResolver, binding
Output: object

1. object = referenceResolver.readReference(inputElement)
   
2. if (object != null) Goto 8 // Found reference

3. class is either:

    a - Specified by caller, e.g. get("name", class)
    
    b - binding.getClass(class attribute value)
    
    c - binding.getClass(element name, element uri)

4. format = binding.getFormat(class)

5. object = format.newInstance(class, inputElement)

6. referenceResolver.createReference(object, inputElement) // Done before parsing to support circular references.

7. format.read(inputElement, object)

8. inputElement.getStreamReader().nextTag()

9. end

Java Source File NameTypeComment
XMLBinding.javaClass

This class represents the binding between Java classes and their XML representation ( XMLFormat ); the binding may be shared among multiple XMLObjectReader / XMLObjectWriter instances (thread-safe).

Custom XML bindings can also be used to alias class names and ensure that the XML representation is:

  • Impervious to obfuscation.
  • Unnaffected by any class refactoring.
  • Can be mapped to multiple implementations.
XMLFormat.javaClass

This class represents the format base class for XML serialization and deserialization.

Application classes typically define a default XML format for their instances using static XMLFormat class members.

XMLObjectReader.javaClass

This class restores objects which have been serialized in XML format using an XMLObjectWriter .

When the XML document is parsed, each elements are recursively processed and Java objects are created using the XMLFormat of the class as identified by the XMLBinding .

Multiple objects can be read from the same XML input.

XMLObjectWriter.javaClass

This class takes an object and formats it to XML; the resulting XML can be deserialized using a XMLObjectReader .

When an object is formatted, the XMLFormat of the object's class as identified by the XMLBinding is used to write its XML representation.

Multiple objects can be written to the same XML output.

XMLReferenceResolver.javaClass
XMLSerializable.javaInterface

This interface identifies classes supporting XML serialization (XML serialization is still possible for classes not implementing this interface through dynamic XMLBinding though).

Typically, classes implementing this interface have a static XMLFormat holding their default XML representation.

w___w__w__.___j___a___v__a__2s__._c___om___ | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.