|
||||||||
PREV PACKAGE NEXT PACKAGE | FRAMES NO FRAMES |
See:
Description
Interface Summary | |
ExceptionListener | An ExceptionListener is notified of internal exceptions. |
Class Summary | |
DefaultPersistenceDelegate | The DefaultPersistenceDelegate is a concrete implementation of
the abstract PersistenceDelegate class and
is the delegate used by default for classes about
which no information is available. |
Encoder | An Encoder is a class which can be used to create
files or streams that encode the state of a collection of
JavaBeans in terms of their public APIs. |
EventHandler | The EventHandler class provides
support for dynamically generating event listeners whose methods
execute a simple statement involving the incoming event object
and a target object. |
Expression | An Expression object represents a primitive expression
in which a single method is applied to a target and a set of
arguments to return a result - as in "a.getFoo()" . |
PersistenceDelegate | The PersistenceDelegate class takes the responsibility for expressing the state of an instance of a given class in terms of the methods in the class's public API. |
Statement | A Statement object represents a primitive statement
in which a single method is applied to a target and
a set of arguments - as in "a.setFoo(b)" . |
XMLDecoder | The XMLDecoder class is used to read XML documents
created using the XMLEncoder and is used just like
the ObjectInputStream . |
XMLEncoder | The XMLEncoder class is a complementary alternative to
the ObjectOutputStream and can used to generate
a textual representation of a JavaBean in the same
way that the ObjectOutputStream can
be used to create binary representation of Serializable
objects. |
Contains classes related to Java Beans development. A few of the classes are used by beans while they run in an application. For example, the event classes are used by beans that fire property and vetoable change events (see PropertyChangeEvent). However, most of the classes in this package are meant to be used by a bean editor (that is, a development environment for customizing and putting together beans to create an application). In particular, these classes help the bean editor create a user interface that the user can use to customize the bean. For example, a bean may contain a property of a special type that a bean editor may not know how to handle. By using the PropertyEditor interface, a bean developer can provide an editor for this special type.
To minimize the resources used by a bean, the classes used by bean editors are loaded only when the bean is being edited. They are not needed while the bean is running in an application and therefore not loaded. This information is kept in what's called a bean-info (see BeanInfo).
A Note on Marshaling vs. Archiving
There are two main tacks to take in persistence schemes:The simplest scheme taking the first approach requires the inclusion of all the classes that define the objects -- which is too expensive. The practical alternative, which is to refrain from serializing the byte codes that define the classes themselves, is workable between identical implementations of the same libraries. The serialization framework in 1.1 implements this and is therefore the method of choice for sending faithful copies of an object graph between two similar VMs.
- Recording all state in an object graph, including non-public state.
- Recording all state that can be reconstituted using the public APIs of the objects in the graph.
In this work we implement the second approach - which cannot produce as faithful a copy of the original objects as the first but can store the state of the graph in such a way that any virtual machine with API-compatible implementations of the classes involved will be sufficient to reconstitute it. Since APIs are so much more stable than their private implementations, this single step virtually solves the versioning issues for most practical purposes. As importantly, from an deployment perspective, the behavior of the constructors residing on the client machine can be leveraged, often dramatically reducing the size of the files that need to be transferred.
Typically this architecture reduces the serialization problem for JavaBeans to the problem of providing an ordered list of properties that define the state of the JavaBean. All values of the properties of a JavaBean are assumed to be JavaBeans. To make this recursive definition work, we have to widen the notion of what is considered a JavaBean slightly so as to include all possible values that properties can take. In our implementation, Color objects are considered to be JavaBeans, as are LayoutManagers, Vectors, Hashtables, Numbers, and Boolean values. To handle the "wiring" part of the user interface it has also proven convenient to provide built-in support for some other key classes in the JDK including Method, Class, array classes, and proxy classes.
To handle all these extra classes the first requirement is that we are able to create instances of them. In all the special cases, where no nullary constructor is defined, this requires extra information that describes how a new instance should be created. For most classes this extra information simply associates the arguments of a chosen constructor with names of the properties they represent. So, for example, the java.awt.Color class is augmented with meta data recording the fact that the three integers that appear as arguments in one of the constructors are the red, green, and blue properties of the new instance. Given this extra information the recording of a Color object is reduced to the simpler problem of recording the Integer values of those properties.
In other cases, such as java.lang.Method, the extra information is used to indicate to the output stream the fact that, instead of using a constructor, the static getMethod method in java.lang.Class should be used to retrieve instances of the Method class. Near the bottom of these recursive definitions are the wrappers for the primitive types of the Java virtual machine: the Boolean class and the Number derivatives. All of these classes have a useful invariant in that they may be reconstructed by calling their single-argument constructor using the value returned by the toString method. Closing this recursive definition then, is the java.lang.String class, for which each file format must provide built-in support, and in terms of which all other objects will be represented.
In addition to the need to be able to specify the manner in which an object should be instantiated it is also necessary to find a general way to describe the way it should be initialized. This allows the user to accommodate "hidden state" which is not represented as properties but which is central to the public behavior of an object. An instance of the java.awt.Container class, for example, should have all of its children recorded if it is expected to behave like the original.
The new EventHandler class provides a convenient and concise way to make use of the Proxy APIs to create listeners for JavaBeans. Most importantly, this "trampoline" class has both a public constructor and accessors for all internal state that is required to produce it. Such classes, unlike anonymous inner classes, can therefore be archived in the same way that any other bean is archived: as a textual representation of the public API needed to create it.
|
||||||||
PREV PACKAGE NEXT PACKAGE | FRAMES NO FRAMES |