theArchive = new Archive();The Archive traces the root object's object graph, instructing each object to write its state information into the Archive. Only objects that implement the Codable interface can be written into an Archive. See "The Codable interface" below.
archiver = new Archiver(theArchive);
archiver.archiveRootObject(myObject);
Retrieving objects from an Archive involves asking for the root objects that it contains:
Codable rootObjects[];
rootObjects = Unarchiver.unarchiveRoots(theArchive);
public interface Codable {
public void describeClassInfo(ClassInfo info);
public void encode(Encoder encoder) throws CodingException;
public void decode(Decoder decoder) throws CodingException;
public void finishDecoding() throws CodingException;
}
describeClassInfo()
and encode()
. Data is placed into and retrieved from the Archive by name-type pairs, where name is a string and type is one of the data types defined in the Codable interface, such as TYPE_OBJECT or TYPE_INTEGER. The encode()
method contains the code to request that this data be stored:
public class Button extends View {In the example above, the Button class has three instance variables that it needs to store: its image, its title, and whether it is enabled. Its
Image buttonImage;
String title;
boolean enabled;
final static int VERSION = 1;
public void describeClassInfo(ClassInfo, info){
super.describeClassInfo(info);
info.addClass("netscape.application.Button",VERSION);
info.addField("image",TYPE_OBJECT);
info.addField("title",TYPE_STRING);
info.addField("enabled",TYPE_BOOLEAN);
}
public void encode(Encoder encoder) throws CodingException{
super.encode(encoder);
encode.encodeObject("image", buttonImage);
encode.encodeString("title", title);
encode.encodeBoolean("enabled", enabled);
}
}
describeClassInfo()
method declares the name-type pairs it will archive, as well as the class, in the calls to the ClassInfo's addClass()
and addField()
methods. This method also declares the class' full name, which includes its package, and a version number. The full name allows the Unarchiver to instantiate the proper type of object when recreating objects from the Archive.
The version number allows a class to record the version that archived the information so that future versions can reconstitute themselves properly from the Archive. For example, suppose Button version two includes a background color that it stores in an Archive. Its decode()
method can check the version number of the information stored in the Archive. If it encounters data stored by Button version one, rather than attempting to read the background color from the Archive, decode()
can just set the color to some default value.
decode()
and finishDecoding()
methods are called by the Unarchiver. The decode()
method contains counterpart code to the encode()
method to retrieve the object's state from the Archive. The finishDecoding()
method is called when all objects have been read from the Archive, providing a chance to perform any post unarchiving processing:
public void decode(Decoder decoder) throws CodingException{The Button's
super.decode(decoder);
buttonImage = (Image)decoder.decodeObject("image");
title = decoder.decodeString("title");
enabled = decoder.decodeBoolean("enabled");
}
public void finishDecoding() throws CodingException {
super.finishDecoding();
}
decode()
method retrieves data using the keys that it used to store the data into the Archive. Like most other Archivable implementations, its finishDecoding()
method does nothing. The finishDecoding()
method allows decoded objects to perform any post-decoding processing at a point at which all objects have been read from the Archive. For example, the View class' superview instance variable is not archived by its encode()
method; therefore, it must be restored at some point after unarchiving. The View's finishDecoding()
method sets the superview instance variable for all of its subviews to itself. It waits for the finishDecoding()
method rather than the decode()
method, so that all of its subviews are guaranteed to be completely unarchived.