File FormatsAs explained in the earlier sections, the archiving package deals with the syntax of the archives as a separate and replaceable last stage of the writing process and as a separate and replaceable first stage of the reading process. This way, the bulk of the archiving infrastructure is syntax-independent and we insulate the work that goes into providing special support for the archival of new JavaBeans from the ongoing process of supporting new file formats, such as XML and its many emerging schemas. This section deals with the syntaxes that are provided in this release.In the current implementation we encapsulate the "syntax modules"
that support the different formats as concrete implementations of
the The new streams included in this package augment
The XML format can be used to write object graphs as XML documents.
Although the XML archives are slightly more verbose than the other
formats, they conform to the W3 specification and so can be viewed
and manipulated by generic XML tools. The The XML FormatHere's an example of an archive that defines a simple Swing GUI. It represents aJPanel which contains a number of components.
One of the components is a JButton which has a custom
object as its action listener.
This is just one possible XML format and is an example of a declarative
style encoding where the structure
of the document reflects the containment relations amongst
the objects in the graph. We use the term "containment" to describe
the relationship between any object that holds references to other
(child) objects. All property values of a JavaBean are deemed "contained"
by the bean that owns them as is all other state that can be directly
managed by the API of the bean. In this sense, a The format we have chosen is closely
tied to the Java language in that, as well as being able to define
properties on objects, it is also possible to call methods on them.
The advantage of this is that the persistent
state which is not represented as JavaBeans
properties, like the elements of a <OBJECT PROPERTY="text" VALUE="cut"/> declares the "text" property of the enclosing object, the
JButton0.setText("cut"); The outermost object, the <OBJECT METHOD="add">
This code is declaring the JButton JButton0 = new JButton(); Information on how these expressions can be generated automatically
by the Many other XML persistence schemes (including all of our first implementations) solved the meta data problem by using "synthetic properties" or "registries" of meta data to handle the special cases. Some of these schemes can produce smaller XML documents because the information about how these pieces of data should be added to the objects when they are read is not part of the archive. The disadvantage of these schemes however is that the XML document cannot be read unless the registries exist in the (run time) environment which reads them. Moving to a more explicit format allows all the special cases to be dealt with entirely in the design time environment; with all class-specific "meta data" being included as part of the class's BeanInfo. The Structure of the XML EncodingAll XML archives begin with a single XML Element:
and end with:
This seemingly superfluous element serves only to denote the version of the archive and place the (potentially many) object graphs that were written to the archive in a single block (a requirement for a well formed XML document). In the main body of the archive, there are just two tags: OBJECT and CLASS. The CLASS tag has two attributes: ID and NAME. The CLASS tag is used, before the actual object graph, somewhat like an import statement in a Java program to create a reference to a class with a given, fully qualified, name. Like import statements, these statements do not directly contribute to the object graph but will define all the classes that will be required to create it. After the part of the archive that declares the classes comes the
actual object graph which is represented as a set of nested elements
using a single tag: the OBJECT tag. OBJECTS typically contain other
OBJECTS and form a tree of nodes which are "contained" within each
other. Circularities in the object graph are closed with XML's built-in
ID and IDREF directives. The OBJECT tag has five other attributes:
PROPERTY, PROPERTYREF, CLASS, METHOD and VALUE. Properties are set
using the PROPERTY attribute and retrieved with the PROPERTYREF
attribute. Methods are called using the METHOD attribute and applied
to classes, rather than instances, when the CLASS attribute is defined.
The default method name is The Java FormatTheJavaOutputStream creates .java files
in accordance with the Java Language Specification. There is no JavaInputStream,
instead Java files must be compiled and loaded into the VM as .class
files. No information is available from the .java file
other than what is defined in the Specification and so no information
is lost when the file is compiled and loaded as a class. All parts
of the file may be edited and all edits are valid provided they result
in a .java file which compiles and creates the desired
object graph when the resulting .class file is loaded.
If the JavaOutputStream is used to write out an object
graph from a modified .java program the .java
program will, almost invariably, be structured differently to the
original .java file. Even so the new .java
file will, within the limitations of the meta data defining the objects
it contains, produce the same object graph as the original.
The The BeanScript FormatHere is an archive representing the same object graph as in the XML archive above, in BeanScript:
BeanScript is a very simple file format which fulfills all of the
fundamental requirements of an archive of a graph of JavaBeans.
BeanScript files are typically a little smaller than the corresponding
Unlike the XML format, BeanScript is procedural and each syntactic construct corresponds to an action to be taken when the file is read. It defines syntactic forms for the three essential operations of the unarchiving process: instantiating objects, giving them a name and setting properties on them. For familiarity's sake, the syntax is Java-like except for the omission of the static type information which is not required by the evaluator. The syntax of BeanScript is defined by a simple grammar involving
the following special characters: ".", "=", ":", ";", ",", "()",
"let" and "{}". Parentheses are used for Java-style method invocations
and curly braces denote a block. A block construct is required to
delimit multiple The syntax for calling methods is the same as it is in Java and statements are terminated with the ";" character. To call a method "m" defined by an object "o" on arguments "a1", "a2", etc. we write: o.m(a1, a2, ...); Local variables may be declared using the Java conventions, except that the static type of the variable is replaced with the keyword "let". Eg. let a = 1; Assignment to a variable or property is written: a := c; In fact, the ":" and "let" tokens are currently thrown away by the parser; the "a = b" syntax can be used in place of the longer forms. The reason these extraneous tokens are included in the archives generated by the BeanScriptOutputStream is so that the precise meaning of the assignment and declaration operators can be changed whilst preserving backward compatibility of existing archives. Blocks are the equivalent of LISP's PROGN and evaluate a list of expressions returning the value of last one. E.g. the following block evaluates to the number 2. {1; 2}; Like LISP and Scheme there are no restrictions on which constructs can appear inside others, it is possible to use an assignment or a block as an argument to a method. E.g.: o.m({let x = 1; x}); BeanScript is sufficiently concise that an interactive interpreter,
which can be used to instantiate and introspect user interfaces
on the fly, can be created simply by using the To run the interpreter type: java TestShell You can then type expressions in BeanScript, which will be parsed an evaluated like the statements in a block. > F = Class.forName("javax.swing.JFrame"); When the visible property of the Evaluation SemanticsAll of the readers use the same evaluation model and pass an expression tree to the evaluator as the last part of theirreadObject
implementation. Object arrays are currently used to represent the
parse tree. The evaluator is a minimal evaluation engine defining
the six operations required in the reconstruction of an object graph;
it uses the simple conventions of the Scheme programming language.
The interpreter has four variables bound on startup:
new. The properties of an object are the read-write properties
defined by the introspector. Arrays are treated as objects with properties
that are Integers instead of Strings.
Class objects can be created using the static
| ||||||||||||||||||
|
| ||||||||||||