Serialize Java Data Objects to XML (Continued)
followed by several e.setPersistenceDelegate(…) actions will register any special classes you need to save. All subsequent encoders in your application will know about the registered classes. The initial encoder object doesn't have to be kept around.
Think of the delegates as little programs that will save an object and then restore an object through any of its public access points from the data in the XML file. The delegates are only needed on the encoder because the program that reads in the XML file gets all the information it needs from that XML file. To say that this mechanism serializes the java data object doesn't do it justice. Much more is happening. During the encoding step it interprets a little program you write that tells it how to save and restore an object of a given class type. That little program is composed of Statements and Expressions in the persistence delegate. The encoder runs and emits some bytecodes that happen to be XML.
During the decoding step, the little program that is now in XML form is interpreted, and the object is restored by following the recipe that the encoder originally wrote. The little program you write in a custom persistence delegate can take advantage of the DefaultPersistenceDelegate by extending it, and then you only have to tell it about things it can't figure out through introspection, which is what the StuffPersistenceDelegate does (see Listing 6).
The decoder restores an object in two steps. It instantiates the object, called the new instance, by using some constructor—a null constructor if it is a true bean—and then initializes it by applying a sequence of public method calls to mutate the new instance into something resembling the old instance that was originally saved. The public method calls are specified with a series of Statement objects that are written to the encoder object, not the output stream, so that it henceforth knows how to save objects of the specified type. Expression objects are just statements that can return a value. They invoke public methods that return values. The most common use of Expression statements is to invoke constructors that take arguments with the resulting value being the new instance.
Real-World Example
I have used a free Java graph package to produce an intermediate representation of digital circuit interconnections for a hardware simulator accelerator. Digital circuits can be specified by the Verilog language. I have written a Verilog compiler (in Java, of course) that produces large graphs that easily fill all available memory. For incremental module compilation and large designs, spilling graphs to disk and restoring them when they are needed is desirable. (David Goldschmidt wrote the graph package when he was a student at Rensselaer Polytechnic Institute. See Resources). The package was written before the Collections framework existed; it doesn't implement java.io.Serializable, and even the objects like Vertices that could be beans don't use standard get and set names for properties. In short, it's a great real-world example to see if the new persistence mechanism can save and restore graphs without any modifications to the source code of the graph package.
Back to top
|