JADE v6.1

Package com.dautelle.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.

See:
          Description

Interface Summary
Representable This interface identifies classes, whose instances are serializable using the XML format.
 

Class Summary
CharData This class represents the text that is not markup and constitutes the character data of a XML document.
Constructor This class restores objects which have been serialized in XML format using an ObjectWriter.
ObjectWriter This class takes a Representable object and formats it to a stream as XML.
XmlElement This class represents a XML element.
 

Exception Summary
ConstructorException Signals that a problem of some sort has occurred when creating an object from its XML representation.
 

Package com.dautelle.xml Description

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 serialization can be used for persistency (much like Java stream serialization) but also for adaptation as the XML source is easily readable/editable (e.g. customization of Swing Panels, database resources, etc.) .

This package lets the application customizes how Java objects are represented using XML. The object's attributes can be XML attributes or nested XML elements. XML attributes are used for simple properties represented by a String whereas XML nested elements are used for complex structures or when the number of sub-elements is unknown (e.g. List).

The tag name of the XML element is the class name. Namespaces may be used to specify Java packages.

The following shows how to make instances of your class serializable/deserializable in XML format.

    public class Foo {
       String s;
       int i;
    }
Foo is serializable in XML format if it implements the Representable interface. Also, for Foo to be deserializable from XML, it (or one its ancestor class) needs to provide the reciprocal factory method valueOf(XmlElement).
    public class Foo implements Representable {
       String s;
       int i;

       // Implements Representable for serialization.
       public void toXml(XmlElement xml) {
           xml.setAttribute("s", s);
           xml.setAttribute("i", i);
       }

       // Provides factory method for deserialization.
       public static Foo valueOf(XmlElement xml) {
           Foo foo = new Foo();
           foo.s = xml.getAttribute("s", ""); // "" is default.
           foo.i = xml.getAttribute("i", 0);  // 0 is default.
           return foo;
       }
    }
Nested elements may also be used for the XML representation.
    public class MyList extends ArrayList implements Representable {
        public void toXml(XmlElement xml) {
           xml.addAll(this); // Child elements.
        }
        public static MyList valueOf(XmlElement xml) {
           MyList myList = new MyList();
           myList.addAll(xml);
           return myList;
        }
    }
Here is an example of valid XML representation for MyList instances (XML serialization/deserialization is a recursive process, e.g. MyList instances may contain other MyList instances).
      <MyList>
         <Foo s="abc" i="123"/>
         <MyList>
           <Foo s="def" i="456"/>
           <Foo s="ghi" i="789"/>
         </MyList>
      </MyList>

If you cannot modify the class (e.g. library classes), you can always extend it or use a delegate class responsible for the serialization/deserialization process. For example:

    public class JButton extends javax.swing.JButton implements Representable {
        public void toXml(XmlElement xml) {
            ...
        }
        public static JButton valueOf(XmlElement xml) {
            ...
        }
    }

Most of J.A.D.E. classes are XML serializable/deserializable.
The following illustrates how to serialize/deserialize a simple com.dautelle.math.Matrix instance:

      Matrix M = Matrix.valueOf( new Complex[][] {
          { Complex.I,
            Complex.ZERO },
          { Complex.ZERO,
            Complex.I.opposite() }
      });

      // Save Matrix.
      ObjectWriter ow = new ObjectWriter();
      ow.setNamespace("math", "com.dautelle.math"); // Use math prefix for math classes.
      ow.write(M, new FileOutputStream("C:/matrix.xml"));

      // Read Matrix.
      Constructor constructor = new Constructor();
      Matrix R = (Matrix) constructor.create(new FileInputStream("C:/matrix.xml"));
Here is the matrix.xml file created, then read:
      <?xml version="1.0" encoding="UTF-8"?>
      <math:Matrix xmlns:math="java:com.dautelle.math" row="2" column="2">
         <math:Complex real="0.0" imaginary="1.0"/>
         <math:Complex real="0.0" imaginary="0.0"/>
         <math:Complex real="0.0" imaginary="0.0"/>
         <math:Complex real="0.0" imaginary="-1.0"/>
      </math:Matrix>

Custom encodings are supported using the java.io.InputStreamReader and java.io.OutputStreamWriter library classes.

This facility is similar to existing products such as JSX or XStream, but it allows for more control over the XML representation. For example:

This control comes with a price though: A litle more work to implement the Representable interface and to provide the XML factory methods for deserialization. But at the end, JADE's XML Serialization produces significantly less data and this XML data is more "user friendly".

For more information on the usage of this package you may read the February 2001 issue of Dr Dobbs Journal.


JADE v6.1

Copyright © 2004 Jean-Marie Dautelle.