gnu.java.beans.encoder

Class ScanEngine


public class ScanEngine
extends Object

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 Expressions, Statements 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.

Constructor Summary

ScanEngine(OutputStream os)

Method Summary

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.

Methods inherited from class java.lang.Object

clone, equals, extends Object> getClass, finalize, hashCode, notify, notifyAll, toString, wait, wait, wait

Constructor Details

ScanEngine

public ScanEngine(OutputStream os)

Method Details

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.
Parameters:
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.
Parameters:
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.
Parameters:
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.