gnu.java.beans.encoder
Class ScanEngine
The
ScanEngine
is the main class of the backend of the
XML persistence algorithm. It scans
Expression
and
Statement
instances and some raw objects via the
writeObject(Object)
method and feeds it to a state machine. The
state machine then constructs and object tree which is finally
written as XML by a
Writer
implementation.
How does it work?
The
ScanEngine
sits below the
XMLEncoder
class and is called by it exclusively. The
XMLEncoder
sends
interpretive data by invoking
writeExpression(Expression)
,
writeStatement(Statement)
and
writeObject(Object)
. The invocations of
writeExpression
and
writeStatement
are usually nested into each other and provide
more information then necessary to generate the XML representation.
Furthermore the meaning of certain
Expressions
differs
depending on the enclosing elements or the inner elements have to be
simply discarded.
To cope with this state dependant nature the
ScanEngine
contains a state machine which is programmed statically (no adjustments are
needed, all
ScanEngine
engines use the same setup). The
ScanEngine
's job is to decode the
Expression
s,
Statement
s and certain objects (namely
String
,
null
objects and instances which are repeatedly provided to
the encoder) into 13 low-level (event) methods, which denote the meaning of the
argument. For example an
Expression
can be an array
instantiation which provokes a call to
arrayInstantiation
or
it can be a class resolution leading to a call to
ScanEngine
.
For the state machione the 13 methods are the distinct way to transit
from one state to another. Whenever the
ScanEngine
calls
one of the event methods the current's state successor for that event
is fetched from the state machine configuration, the successpr becomes
the current state and then the event method is called in the new current
state. The last step allows the state instance to do something meaningful
to the object tree.
The state machine knows the concept of returning to the previous
state. This is done using a stack of states which is popped every
time a call to
writeStatement
,
writeExpression
in the
XMLEncoder
ends by calling the
end()
method.
Note that due to the inheritance relationship of
Encoder
and
XMLEncoder
it is impossible for the
ScanEngine
itself to decide when an expression or statement
ended. This can only be done in case of
writeObject(Object)
calls because
they are not nested.
When the XML persistence mechanism reaches an object twice (and more)
it should generate an XML element using the "idref" attribute and add
an "id" attribute to its first instantiation. This complicates things a bit
because the first instantiation will always be part of the object tree
as some
Element
subclass instance when the
second and further objects accesses are written. Therefore the
ObjectId
class was introduced which is shared between all the object tree elements
and has the notion of an "unused" state meaning that no identification
is needed. The relationship between an object and its
ObjectId
instance is stored in the
ScanEngine
and gets cleared whenever
the
flush()
method is called. This method also writes the currently
built object tree and generates the XML representation.
void | close() - Writes the final bits if the object tree and closes the stream
afterwards.
|
void | end() - Ends the current state and returns to the last one.
|
void | flush() - Writes the currently constructed object tree out as
XML and clears the object to
ObjectId relations.
|
void | revoke() - Returns to the last state and deletes the last element in the object tree.
|
void | writeExpression(Expression expr) - Scans the argument and calls one of event methods.
|
boolean | writeObject(Object o) - Scans the argument and calls one of event methods.
|
void | writeStatement(Statement stmt) - Scans the argument and calls one of event methods.
|
clone , equals , extends Object> getClass , finalize , hashCode , notify , notifyAll , toString , wait , wait , wait |
close
public void close()
Writes the final bits if the object tree and closes the stream
afterwards.
end
public void end()
Ends the current state and returns to the last one.
flush
public void flush()
Writes the currently constructed object tree out as
XML and clears the object to
ObjectId
relations.
revoke
public void revoke()
Returns to the last state and deletes the last element in the object tree.
writeExpression
public void writeExpression(Expression expr)
Scans the argument and calls one of event methods. See
the introduction of this class for details.
expr
- The expression to serialize.
writeObject
public boolean writeObject(Object o)
Scans the argument and calls one of event methods. See
the introduction of this class for details.
o
- The object to serialize.
writeStatement
public void writeStatement(Statement stmt)
Scans the argument and calls one of event methods. See
the introduction of this class for details.
stmt
- The statement to serialize.
ScanEngine.java
-- Scans the input and generates an object tree that can be written as XML.
Copyright (C) 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version.