Imported GNU Classpath 0.20

Imported GNU Classpath 0.20
       * Makefile.am (AM_CPPFLAGS): Add classpath/include.
       * java/nio/charset/spi/CharsetProvider.java: New override file.
       * java/security/Security.java: Likewise.
       * sources.am: Regenerated.
       * Makefile.in: Likewise.

From-SVN: r109831
This commit is contained in:
Mark Wielaard
2006-01-17 18:09:40 +00:00
parent bcb36c3e02
commit 2127637945
444 changed files with 75778 additions and 30731 deletions
@@ -0,0 +1,153 @@
/* ArrayPersistenceDelegate.java - A PersistenceDelegate that handles arrays.
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. */
package gnu.java.beans.encoder;
import java.beans.Encoder;
import java.beans.Expression;
import java.beans.PersistenceDelegate;
import java.beans.Statement;
import java.lang.reflect.Array;
import java.util.HashMap;
public class ArrayPersistenceDelegate extends PersistenceDelegate
{
private static final HashMap NULL_VALUES = new HashMap();
static
{
NULL_VALUES.put(Boolean.TYPE, Boolean.FALSE);
NULL_VALUES.put(Byte.TYPE, Byte.valueOf((byte) 0));
NULL_VALUES.put(Short.TYPE, Short.valueOf((short) 0));
NULL_VALUES.put(Integer.TYPE, Integer.valueOf(0));
NULL_VALUES.put(Long.TYPE, Long.valueOf(0));
NULL_VALUES.put(Float.TYPE, Float.valueOf(0.0f));
NULL_VALUES.put(Double.TYPE, Double.valueOf(0.0));
}
protected Expression instantiate(Object oldInstance, Encoder out)
{
Class type = oldInstance.getClass().getComponentType();
// oldInstance is expected to be an array, then
// getClass().getComponentType() should lead
// to its component type.
assert (type != null);
// Not handling primitive types in a special way here
// causes that Class.forName("int") is built as an Expression
// later which would cause an exception if executed. A special
// handling to avoid the execution for primitive types can be
// java.beans.Encoder.writeExpression() .
return new Expression(
oldInstance,
Array.class,
"newInstance",
new Object[] {
type,
new Integer(Array.getLength(oldInstance)) });
}
protected void initialize(Class type, Object oldInstance, Object newInstance,
Encoder out)
{
int length = Array.getLength(oldInstance);
// Compares the array value against a prototypical
// null value of the array's component type in order to skip
// writing the default values of an array.
// Note: I have no idea why the persistence delegate for arrays writes
// an Expression that reads the value and then writes a Statement that sets
// the value. However it turned out that object arrays work better with the
// get-Expression and primitive array work fine with the set-Statement.
type = type.getComponentType();
if (type.isPrimitive())
{
Object nullValue = NULL_VALUES.get(type);
for (int i = 0; i < length; i++)
{
Object oldValue = Array.get(oldInstance, i);
if (!oldValue.equals(nullValue))
{
out.writeExpression(new Expression(Array.class, "get",
new Object[] { oldInstance,
Integer.valueOf(i),
}));
out.writeStatement(new Statement(Array.class, "set",
new Object[] {
oldInstance,
Integer.valueOf(i),
oldValue
}));
}
}
}
else
{
for (int i = 0; i < length; i++)
{
Object oldValue = Array.get(oldInstance, i);
if (oldValue != null)
{
out.writeExpression(new Expression(Array.class, "get",
new Object[] { oldInstance,
Integer.valueOf(i),
}));
out.writeStatement(new Statement(Array.class, "set",
new Object[] {
oldInstance,
Integer.valueOf(i),
oldValue
}));
}
}
}
}
}
@@ -0,0 +1,80 @@
/* ClassPersistenceDelegate.java - A PersistenceDelegate for the Class type.
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. */
package gnu.java.beans.encoder;
import java.beans.Encoder;
import java.beans.Expression;
import java.beans.PersistenceDelegate;
/** <p>The <code>ClassPersistenceDelegate</code> creates
* <code>Expression</code> instances which denote class resolutions.</p>
*
* <p>The class resolution is always the last step when serializing a tree
* of objects. Due to the recursive nature of the algorithm we need a way
* to end the recursion. This is achieved by the implementation of this
* {@link instantiate} method. Arbitrary classes are described with a call
* to <code>Class.forName</code>. However for the <code>Class</code> class
* we call <code>getClass()</code> on a <code>String.class</code> instance.
* This in turn lead to the resolution of the String class which is always
* encoded as <code>"".getClass()</code>. Finally the <code>Encoder</code>
* treats strings in a special way so that the recursion ends here.
*
* @author Robert Schuster (robertschuster@fsfe.org)
*/
public class ClassPersistenceDelegate extends PersistenceDelegate
{
protected Expression instantiate(Object oldInstance, Encoder out)
{
Class oldClass = (Class) oldInstance;
// Due to the special handling of String instances in the Encoder
// this Expression does not lead to further class resolutions.
if (oldClass == String.class)
return new Expression(oldClass, "", "getClass", null);
// This Expression will lead to the class resolution of String.class.
if (oldClass == Class.class)
return new Expression(oldClass, String.class, "getClass", null);
// This Expression will lead to the class resolution of Class.class.
return new Expression(oldClass, Class.class, "forName",
new Object[] { oldClass.getName() });
}
}
@@ -0,0 +1,84 @@
/* CollectionPersistenceDelegate.java - A PersistenceDelegate for Collection subclasses.
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. */
package gnu.java.beans.encoder;
import java.util.Collection;
import java.beans.Encoder;
import java.beans.Expression;
import java.beans.PersistenceDelegate;
import java.beans.Statement;
import java.util.Iterator;
/** <p>A <code>PersistenceDelegate</code> implementation that calls
* the no-argument constructor to create the Collection instance and
* uses an iterator to add all the objects it reaches through it.</p>
*
* <p>It is used for <code>Set</code> and <code>List</code>
* implementations.</p>
*
* @author Robert Schuster (robertschuster@fsfe.org)
*/
public class CollectionPersistenceDelegate extends PersistenceDelegate
{
protected Expression instantiate(Object oldInstance, Encoder out)
{
return new Expression(
oldInstance,
oldInstance.getClass(),
"new",
null);
}
protected void initialize(Class type, Object oldInstance, Object newInstance,
Encoder out)
{
Iterator ite = ((Collection) oldInstance).iterator();
while (ite.hasNext())
{
out.writeStatement(new Statement(oldInstance, "add",
new Object[] { ite.next() }));
}
}
}
@@ -0,0 +1,88 @@
/* Context.java -- Provides calling context information to ScannerStates.
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. */
package gnu.java.beans.encoder;
/** A <code>Contect</code> object describes the current state
* and the call number while processing the original object
* tree in the {@link ScanEngine}.
*
* <p>The class allows to distinguish the different calling states
* and is neccessary for the child element skipping feature of
* the {@link GenericScannerState}.</p>
*
* @author Robert Schuster (robertschuster@fsfe.org)
*
*/
public class Context
{
private String state;
private int call;
Context(String newState, int newCall)
{
state = newState;
call = newCall;
}
public int hashCode()
{
int hc = 7;
hc = 31 * hc + state.hashCode();
hc = 31 * hc + call;
return hc;
}
public boolean equals(Object o)
{
if (!(o instanceof Context))
return false;
Context that = (Context) o;
return state.equals(that.state)
&& call == that.call;
}
public String toString()
{
return "Context [state=" + state + ", call=" + call + "]";
}
}
@@ -0,0 +1,257 @@
/* GenericScannerState.java
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. */
package gnu.java.beans.encoder;
import java.util.HashMap;
import gnu.java.beans.encoder.elements.ArrayInstantiation;
import gnu.java.beans.encoder.elements.Array_Get;
import gnu.java.beans.encoder.elements.Array_Set;
import gnu.java.beans.encoder.elements.ClassResolution;
import gnu.java.beans.encoder.elements.Element;
import gnu.java.beans.encoder.elements.List_Get;
import gnu.java.beans.encoder.elements.List_Set;
import gnu.java.beans.encoder.elements.MethodInvocation;
import gnu.java.beans.encoder.elements.NullObject;
import gnu.java.beans.encoder.elements.ObjectInstantiation;
import gnu.java.beans.encoder.elements.ObjectReference;
import gnu.java.beans.encoder.elements.PrimitiveInstantiation;
import gnu.java.beans.encoder.elements.StaticFieldAccess;
import gnu.java.beans.encoder.elements.StaticMethodInvocation;
import gnu.java.beans.encoder.elements.StringReference;
/**
* This class is a {@link ScannerState} implementation that creates
* suitable {@link gnu.java.beans.encoder.elements.Element} instances
* for each transition variant.
*
* <p>Furthermore it can optionally skip a certain number of child
* elements. The algorithm can cope with the fact that one
* <code>GenericScannerState</code> instance may be called at
* different levels of recursions.</p>
*
* @author Robert Schuster (robertschuster@fsfe.org)
*/
class GenericScannerState extends ScannerState
{
private int skipElements, initialSkipElements;
final Root root;
HashMap skipValues;
GenericScannerState(Root newRoot)
{
root = newRoot;
}
GenericScannerState(Root root, int skipElements)
{
this(root);
this.skipElements = initialSkipElements = skipElements;
if (skipElements > 0)
skipValues = new HashMap();
}
protected void enterImpl(Context ctx)
{
if (skipValues != null)
{
Integer skip = (Integer) skipValues.get(ctx);
if (skip == null)
{
skip = Integer.valueOf(initialSkipElements);
skipValues.put(ctx, skip);
}
skipElements = skip.intValue();
}
}
void methodInvocation(String methodName)
{
if (skipValues != null && skipElements > 0)
return;
root.addChild(new MethodInvocation(methodName));
}
void staticMethodInvocation(String className, String methodName)
{
if (skipValues != null && skipElements > 0)
return;
root.addChild(new StaticMethodInvocation(className, methodName));
}
void staticFieldAccess(String className, String fieldName)
{
if (skipValues != null && skipElements > 0)
return;
root.addChild(new StaticFieldAccess(className, fieldName));
}
void classResolution(String className)
{
if (skipValues != null && skipElements > 0)
return;
root.addChild(new ClassResolution(className));
}
void objectInstantiation(String className, ObjectId objectId)
{
if (skipValues != null && skipElements > 0)
return;
Element elem = new ObjectInstantiation(className);
elem.initId(objectId);
root.addChild(elem);
}
void primitiveInstantiation(String primitiveName, String valueAsString)
{
if (skipValues != null && skipElements > 0)
return;
root.addChild(new PrimitiveInstantiation(primitiveName, valueAsString));
}
void objectArrayInstantiation(String arrayClassName, String lengthAsString,
ObjectId objectId)
{
if (skipValues != null && skipElements > 0)
return;
Element elem = new ArrayInstantiation(arrayClassName, lengthAsString);
elem.initId(objectId);
root.addChild(elem);
}
void primitiveArrayInstantiation(String arrayClassName, String lengthAsString,
ObjectId objectId)
{
objectArrayInstantiation(arrayClassName, lengthAsString, objectId);
}
void arraySet(String indexAsString)
{
if (skipValues != null && skipElements > 0)
return;
root.addChild(new Array_Set(indexAsString));
}
void arrayGet(String indexAsString)
{
if (skipValues != null && skipElements > 0)
return;
root.addChild(new Array_Get(indexAsString));
}
void listGet()
{
if (skipValues != null && skipElements > 0)
return;
root.addChild(new List_Get());
}
void listSet()
{
if (skipValues != null && skipElements > 0)
return;
root.addChild(new List_Set());
}
void nullObject()
{
if (skipValues != null && skipElements > 0)
return;
root.addChild(new NullObject());
}
void stringReference(String string)
{
if (skipValues != null && skipElements > 0)
return;
root.addChild(new StringReference(string));
}
void objectReference(ObjectId id)
{
if (skipValues != null && skipElements > 0)
return;
root.addChild(new ObjectReference(id));
}
void end()
{
if (skipValues != null)
{
if (skipElements > 0)
skipElements--;
else
{
// Finishes the Element we are constructing.
root.end();
}
skipValues.put(context(), Integer.valueOf(skipElements));
}
else
root.end();
}
void enter()
{
}
}
@@ -0,0 +1,133 @@
/* IgnoringScannerState.java -- A ScannerState that does nothing.
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. */
package gnu.java.beans.encoder;
/** A special {@link ScannerState} implementation that ignores all child
* elements.
*
* <p>Consider the call hierarchy:
* <code>
* methodInvocation
* objectInstantiation
* classResolution*
* objectInstantiation
* classResolution
* </code>
* </p>
*
* <p>When the ignoring state is active one can filter the elements of
* one level. One has to set up the state machine that a transition
* via "class resolution" from a state that was reached via "object
* instantation" reaches an <code>IgnoringScannerState</code>.</p>
*
* <p>Setting the default successor of a <code>IgnoringScannerState</code>
* to itself causes all elements of the call hierarchy to be skipped
* until another state is reached by going back.</p>
*
* @author Robert Schuster (robertschuster@fsfe.org)
*
*/
class IgnoringScannerState extends ScannerState
{
void methodInvocation(String methodName)
{
}
void staticMethodInvocation(String className, String methodName)
{
}
void staticFieldAccess(String className, String fieldName)
{
}
void classResolution(String className)
{
}
void objectInstantiation(String className, ObjectId objectId)
{
}
void primitiveInstantiation(String primitiveName, String valueAsString)
{
}
void objectArrayInstantiation(String arrayClassName, String lengthAsString, ObjectId objectId)
{
}
void primitiveArrayInstantiation(String arrayClassName, String lengthAsString, ObjectId objectId)
{
}
void arraySet(String indexAsString)
{
}
void arrayGet(String indexAsString)
{
}
void listGet()
{
}
void listSet()
{
}
void nullObject()
{
}
void stringReference(String string)
{
}
void objectReference(ObjectId id)
{
}
void end()
{
}
}
@@ -0,0 +1,81 @@
/* MapPersistenceDelegate.java -- A PersistenceDelegate for Map subclasses.
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. */
package gnu.java.beans.encoder;
import java.util.Map;
import java.beans.Encoder;
import java.beans.Expression;
import java.beans.PersistenceDelegate;
import java.beans.Statement;
import java.util.Iterator;
/**
* @author Robert Schuster (robertschuster@fsfe.org)
*/
public class MapPersistenceDelegate extends PersistenceDelegate
{
protected Expression instantiate(Object oldInstance, Encoder out)
{
return new Expression(
oldInstance,
oldInstance.getClass(),
"new",
null);
}
protected void initialize(Class type, Object oldInstance, Object newInstance,
Encoder out)
{
Map map = (Map) oldInstance;
Iterator ite = map.keySet().iterator();
while (ite.hasNext())
{
Object key = ite.next();
out.writeStatement(new Statement(oldInstance, "put",
new Object[] { key, map.get(key) }));
}
}
}
@@ -0,0 +1,132 @@
/* ObjectId.java -- Simple object identification mechanism for XML encoding.
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. */
package gnu.java.beans.encoder;
import java.util.HashMap;
/**
* <p>
* ObjectId provides an object identification mechanism which gives each object
* a name in the form <code>&lt;class&gt;&lt;Nameindex&gt;</code>.
* </p>
*
* <p>
* Each id can be in an unused state which means that only one instance of the
* object is in use and a special id is not needed. Certain {@link
* gnu.java.beans.encoder.elements.Element} subclasses use this feature to find
* out whether they write the "id" attribute or not.
* </p>
* <p>
* An <code>ObjectId</code> instance is typically given to multiple objects.
* The second user should then invoke the {@link #init} method to generate the
* identification string and bring the id in the 'used' state.
* </p>
*
* @author Robert Schuster (robertschuster@fsfe.org)
*/
public class ObjectId
{
/**
* Stores the index an object of a specific type should be given.
*/
private static HashMap nameIndices = new HashMap();
private String id;
private Class klass;
ObjectId(Class klass)
{
this.klass = klass;
}
public boolean isUnused()
{
return id == null;
}
public String toString()
{
return (id != null) ? id : "<unused id>";
}
/**
* <p>
* Generates a simple Id by concatenating a class name with a self-increasing
* number.
* </p>
*/
public void init()
{
assert (klass != null);
if (id != null)
return;
Integer count = (Integer) nameIndices.get(klass);
if (count == null)
{
count = Integer.valueOf(0);
}
if (klass.isArray())
{
Class ct = klass.getComponentType();
if (ct == Boolean.TYPE)
id = "booleanArray" + count.intValue();
else if (ct == Byte.TYPE)
id = "byteArray" + count.intValue();
else if (ct == Short.TYPE)
id = "shortArray" + count.intValue();
else if (ct == Integer.TYPE)
id = "intArray" + count.intValue();
else if (ct == Long.TYPE)
id = "longArray" + count.intValue();
else if (ct == Float.TYPE)
id = "floatArray" + count.intValue();
else if (ct == Double.TYPE)
id = "doubleArray" + count.intValue();
}
else
id = klass.getName() + count.intValue();
nameIndices.put(klass, Integer.valueOf(count.intValue() + 1));
}
}
@@ -0,0 +1,74 @@
/* PrimitivePersistenceDelegate.java
-- A PersistenceDelegate for primitive data types.
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. */
package gnu.java.beans.encoder;
import java.beans.Encoder;
import java.beans.Expression;
import java.beans.PersistenceDelegate;
/**
* A shared PersistenceDelegate implementation for all primitive types.
*
* @author Robert Schuster (robertschuster@fsfe.org)
*/
public class PrimitivePersistenceDelegate extends PersistenceDelegate
{
protected Expression instantiate(Object oldInstance, Encoder out)
{
// The implementation relies on the fact that every primitive
// wrapper class has a constructor accepting a String argument.
// By using these constructors creating a primitive instance
// depends on the String class only.
return new Expression(oldInstance, oldInstance.getClass(), "new",
new Object[] { oldInstance.toString() });
}
protected void initialize(Class type, Object oldInstance, Object newInstance, Encoder out)
{
// This is a hack to make serializing primitive arrays work correctly.
// Instead of modifying an existing primitive instance to make it equal
// with another instance (which is not possible because primitives are
// immutable) we create a new instance. This is against the specification
// of the initialize method but make things work fine.
out.writeExpression(new Expression(oldInstance, oldInstance.getClass(), "new",
new Object[] { oldInstance.toString() }));
}
}
@@ -0,0 +1,131 @@
/* ReportingScannerState.java -- A state for debugging purposes.
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. */
package gnu.java.beans.encoder;
/**
* A <code>ScannerState</code> implementation that prints useful details
* about its arguments. Use it when the XML encoding does not work correctly
* and you want to find out how things relate to each other.
*
* @author Robert Schuster (robertschuster@fsfe.org)
*/
class ReportingScannerState extends ScannerState
{
void methodInvocation(String methodName)
{
System.out.println("methodInvocation: " + methodName + "()");
}
void staticMethodInvocation(String className, String methodName)
{
System.out.println("staticMethodInvocation: " + className + "." + methodName + "()");
}
void staticFieldAccess(String className, String fieldName)
{
System.out.println("staticFieldAccess: " + className + "." + fieldName);
}
void classResolution(String className)
{
System.out.println("classResolution: " + className);
}
void objectInstantiation(String className, ObjectId objectId)
{
System.out.println("objectInstantiation: " + className);
}
void primitiveInstantiation(String primitiveName, String valueAsString)
{
System.out.println("primitiveInstantiation: (" + primitiveName + ") " + valueAsString);
}
void objectArrayInstantiation(String arrayClassName, String lengthAsString, ObjectId objectId)
{
System.out.println("objectArrayInstantiation: new " + arrayClassName + "[" + lengthAsString + "]");
}
void primitiveArrayInstantiation(String arrayClassName, String lengthAsString, ObjectId objectId)
{
System.out.println("primitiveArrayInstantiation: new " + arrayClassName + "[" + lengthAsString + "]");
}
void arraySet(String indexAsString)
{
System.out.println("arraySet: " + indexAsString);
}
void arrayGet(String indexAsString)
{
System.out.println("arrayGet: " + indexAsString);
}
void listGet()
{
System.out.println("listGet");
}
void listSet()
{
System.out.println("listSet");
}
void nullObject()
{
System.out.println("nullObject");
}
void stringReference(String string)
{
System.out.println("stringReference: " + string);
}
void objectReference(ObjectId id)
{
System.out.println("objectReference: " + id);
}
void end()
{
System.out.println("-close");
}
}
@@ -0,0 +1,198 @@
/* Root.java -- The root of an object tree.
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. */
package gnu.java.beans.encoder;
import java.beans.XMLEncoder;
import java.util.Iterator;
import java.util.Stack;
import gnu.java.beans.encoder.elements.Element;
/** <p><code>Root</code> provides a simple interface to a tree of
* objects.</p>
*
* <p>Using an instance of this class a logical representation of
* the real object tree that is serialized can be built. When the
* actual data should be written as XML <code>Root</code> and
* {@link gnu.java.beans.encoder.elements.Element} class can provide
* context information which is used to write the best fitting
* XML representation.</p>
*
* @author Robert Schuster (robertschuster@fsfe.org)
*/
public class Root
{
private Stack parents = new Stack();
private Element rootElement, current;
private boolean started;
public Root()
{
rootElement = current = new RootElement();
}
/** <p>Adds another child element to the tree.</p>
*
* <p>The new element automatically becomes the current
* element.</p>
*
* @param elem The new child element.
*/
public void addChild(Element elem)
{
current.addChild(elem);
parents.push(current);
current = elem;
}
/**
* <p>Marks that the end of the current element
* is reached and that no more childs are added to
* it.</p>
*
* <p>The behavior is to return to the nearest parent
* element.</p>
*/
public void end()
{
current = (Element) parents.pop();
}
/**
* <p>Goes back to the nearest parent element but
* deletes the just created child.</p>
*
* <p>This is used if something went wrong while
* processing the child element's {@link java.beans.Expression}
* or {@link java.beans.Statement}.</p>
*
*/
public void deleteLast()
{
current = (Element) parents.pop();
current.removeLast();
}
/**
* <p>Traverses the elements in the object tree
* and creates their XML representation in the output
* stream of the given {@link Writer}.</p>
*
* <p>Finally the <code>Writer</code> is flushed.</p>
*
* @param writer The Writer instance that generates the XML representation.
*/
public void traverse(Writer writer)
{
if (!started)
{
writer.writePreamble();
rootElement.writeStart(writer);
}
started = true;
traverse(writer, rootElement.iterator());
rootElement.clear();
writer.flush();
}
/** Writes the closing element and closes the {@link Writer}
*
* @param writer The Writer instance that generates the XML representation.
*/
public void close(Writer writer)
{
rootElement.writeEnd(writer);
writer.close();
}
/** Recursively traverses the object tree.
*
* @param writer The Writer instance that generates the XML representation.
* @param ite An Iterator returning Element instances.
*/
private void traverse(Writer writer, Iterator ite)
{
while (ite.hasNext())
{
Element e = (Element) ite.next();
e.writeStart(writer);
traverse(writer, e.iterator());
e.writeEnd(writer);
e.clear();
}
}
/** <p>A special Element implementation that represents the
* encoder's context.</p>
*
* <p>This element is written only once per Writer.</p>
*
* <p>It is assumed that this element is never empty to simplify
* the implementation.</p>
*
* @author Robert Schuster (robertschuster@fsfe.org);
*
*/
static class RootElement extends Element
{
public void writeStart(Writer writer)
{
writer.write("java", new String[] { "version", "class" },
new String[] { System.getProperty("java.version"),
XMLEncoder.class.getName() }, false);
}
public void writeEnd(Writer writer)
{
writer.writeEnd(false);
}
}
}
@@ -0,0 +1,860 @@
/* 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. */
package gnu.java.beans.encoder;
import java.beans.Expression;
import java.beans.Statement;
import java.io.OutputStream;
import java.lang.reflect.Array;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Stack;
/** <p>The <code>ScanEngine</code> is the main class of the backend of the
* XML persistence algorithm. It scans {@link java.beans.Expression} and
* {@link java.beans.Statement} instances and some raw objects via the
* {@link #writeObject} method and feeds it to a state machine. The
* state machine then constructs and object tree which is finally
* written as XML by a {@link Writer} implementation.</p>
*
* <p>How does it work?</p>
* <p>The <code>ScanEngine</code> sits below the {@link java.beans.XMLEncoder}
* class and is called by it exclusively. The <code>XMLEncoder</code> sends
* interpretive data by invoking {@link #writeExpression}, {@link #writeStatement}
* and {@link #writeObject}. The invocations of <code>writeExpression</code> and
* <code>writeStatement</code> are usually nested into each other and provide
* more information then necessary to generate the XML representation.
* Furthermore the meaning of certain <code>Expressions</code> differs
* depending on the enclosing elements or the inner elements have to be
* simply discarded.</p>
*
* <p>To cope with this state dependant nature the <code>ScanEngine</code>
* contains a state machine which is programmed statically (no adjustments are
* needed, all <code>ScanEngine</code> engines use the same setup). The
* <code>ScanEngine</code>'s job is to decode the <code>Expression</code>s,
* <code>Statement</code>s and certain objects (namely <code>String</code>,
* <code>null</code> 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 <code>Expression</code> can be an array
* instantiation which provokes a call to {@link arrayInstantiation} or
* it can be a class resolution leading to a call to {@link #classResolution}.
* For the state machione the 13 methods are the distinct way to transit
* from one state to another. Whenever the <code>ScanEngine</code> 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.</p>
*
* <p>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 <code>writeStatement</code>, <code>writeExpression</code>
* in the <code>XMLEncoder</code> ends by calling the {@link #end} method.
* Note that due to the inheritance relationship of <code>Encoder</code>
* and <code>XMLEncoder</code> it is impossible for the
* <code>ScanEngine</code> itself to decide when an expression or statement
* ended. This can only be done in case of {@link #writeObject} calls because
* they are not nested.</p>
*
* <p>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 {@link gnu.java.beans.encoder.elements.Element} subclass instance when the
* second and further objects accesses are written. Therefore the {@link 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 <code>ObjectId</code>
* instance is stored in the <code>ScanEngine</code> and gets cleared whenever
* the {@link #flush} method is called. This method also writes the currently
* built object tree and generates the XML representation.</p>
*
* @author Robert Schuster (robertschuster@fsfe.org)
*/
public class ScanEngine
{
/** Change this to true to let the ScanEngine print state transition
* information.
*/
boolean DEBUG = false;
/**
* Stores the scanner engine states as values and their names as keys.
*/
HashMap states = new HashMap();
/**
* Stores former scanner state and makes it possible to come back to them.
*/
Stack parents = new Stack();
/**
* The currently active scanner state.
*/
ScannerState current;
/**
* The root of an object tree that is later written to XML.
*/
Root root;
/**
* The Writer used to generate the XML output.
*/
Writer writer;
/** Stores the relationship between objects and their {@link ObjectId} instance.
*/
IdentityHashMap objects = new IdentityHashMap();
public ScanEngine(OutputStream os)
{
// TODO: Provide another Writer implementation (e.g. one that does not use
// the XML APIs at all).
writer = new StAXWriter(os);
root = new Root();
final ScannerState start = current = new GenericScannerState(root);;
ScannerState conf;
// Use the ReportingScannerState to debug serialization issues.
register(ScannerState.DEFAULT_STATE_NAME, new IgnoringScannerState());
register("start", start);
// Special dead-end state where all transitions are ignored.
register("ignoreAll", new IgnoringScannerState())
.setDefaultSuccessor("ignoreAll");
// Object reference, string reference, null object
start.putSuccessor(ScannerState.TRANSITION_OBJECT_REFERENCE, "simple");
start.putSuccessor(ScannerState.TRANSITION_STRING_REFERENCE, "simple");
start.putSuccessor(ScannerState.TRANSITION_NULL_OBJECT, "simple");
register("simple", new GenericScannerState(root))
.setDefaultSuccessor("ignoreAll");
// Class resolution.
start.putSuccessor(ScannerState.TRANSITION_CLASS_RESOLUTION, "classRes0");
register("classRes0",
new GenericScannerState(root)).setDefaultSuccessor("ignoreAll");
// Object instantiation.
start.putSuccessor(ScannerState.TRANSITION_OBJECT_INSTANTIATION,
"newObj0");
conf = register("newObj0", new GenericScannerState(root));
conf.setDefaultSuccessor("ignoreAll");
// Simply use the start state to encode method invocations inside of
// objects.
conf.putSuccessor(ScannerState.TRANSITION_METHOD_INVOCATION, "start");
// Primitive instantiations.
start.putSuccessor(ScannerState.TRANSITION_PRIMITIVE_INSTANTIATION,
"newPrimitive0");
register("newPrimitive0",
new GenericScannerState(root)).setDefaultSuccessor("ignoreAll");
// Object arrays use the ARRAY_GET transition to create setting the
// array values.
start.putSuccessor(ScannerState.TRANSITION_OBJECT_ARRAY_INSTANTIATION,
"newObjectArray");
conf = register("newObjectArray", new GenericScannerState(root));
conf.putSuccessor(ScannerState.TRANSITION_ARRAY_GET, "newOArrayGet");
conf.putSuccessor(ScannerState.TRANSITION_ARRAY_SET, "ignoreAll");
conf.putSuccessor(ScannerState.TRANSITION_CLASS_RESOLUTION, "ignoreAll");
conf.putSuccessor(ScannerState.TRANSITION_PRIMITIVE_INSTANTIATION,
"ignoreAll");
// Get here when a value is set in the array.
register("newOArrayGet",
conf = new GenericScannerState(root));
conf.putSuccessor(ScannerState.TRANSITION_PRIMITIVE_INSTANTIATION,
"newOArrayGet_ignoreFirstInteger");
// "newArrayGet_ignoreFirstInteger" is set up mostly identical like the "start"
// state. Otherwise things would not behave the same when done inside
// arrays.
conf.putSuccessor(ScannerState.TRANSITION_OBJECT_REFERENCE, "simple");
conf.putSuccessor(ScannerState.TRANSITION_STRING_REFERENCE, "simple");
conf.putSuccessor(ScannerState.TRANSITION_NULL_OBJECT, "simple");
conf.putSuccessor(ScannerState.TRANSITION_CLASS_RESOLUTION, "classRes0");
conf.putSuccessor(ScannerState.TRANSITION_OBJECT_INSTANTIATION, "newObj0");
conf.putSuccessor(ScannerState.TRANSITION_PRIMITIVE_ARRAY_INSTANTIATION,
"newPrimitiveArray");
conf.putSuccessor(ScannerState.TRANSITION_OBJECT_ARRAY_INSTANTIATION,
"newObjectArray");
conf = register("newOArrayGet_ignoreFirstInteger",
new GenericScannerState(root, 1));
// In non-int primitive arrays class resolutions can happen
// but they should be ignored.
conf.putSuccessor(ScannerState.TRANSITION_CLASS_RESOLUTION, "ignoreAll");
// Spurious object and string references occur when setting array
// elements. This suppresses them.
conf.putSuccessor(ScannerState.TRANSITION_PRIMITIVE_INSTANTIATION,
"ignoreAll");
conf.putSuccessor(ScannerState.TRANSITION_OBJECT_REFERENCE, "ignoreAll");
conf.putSuccessor(ScannerState.TRANSITION_STRING_REFERENCE, "ignoreAll");
conf.setDefaultSuccessor("start");
// Primitive arrays use the ARRAY_SET transition to create setting the
// array values. This turned out to be the only working solution.
// When primitive arrays were handled by ARRAY_GET the values in boolean
// arrays were always skipped.
start.putSuccessor(ScannerState.TRANSITION_PRIMITIVE_ARRAY_INSTANTIATION,
"newPrimitiveArray");
conf = register("newPrimitiveArray", new GenericScannerState(root));
conf.putSuccessor(ScannerState.TRANSITION_ARRAY_GET, "ignoreAll");
conf.putSuccessor(ScannerState.TRANSITION_ARRAY_SET, "newPArraySet");
conf.putSuccessor(ScannerState.TRANSITION_CLASS_RESOLUTION, "ignoreAll");
conf.putSuccessor(ScannerState.TRANSITION_PRIMITIVE_INSTANTIATION,
"ignoreAll");
conf = register("newPArraySet", new GenericScannerState(root));
conf.putSuccessor(ScannerState.TRANSITION_PRIMITIVE_INSTANTIATION,
"newPArraySet_ignoreFirstInteger");
// Primitive arrays ignore all kinds of non-primitive object information.
conf.putSuccessor(ScannerState.TRANSITION_OBJECT_REFERENCE,
"ignoreAll");
conf.putSuccessor(ScannerState.TRANSITION_STRING_REFERENCE, "ignoreAll");
conf.putSuccessor(ScannerState.TRANSITION_NULL_OBJECT, "ignoreAll");
conf.putSuccessor(ScannerState.TRANSITION_CLASS_RESOLUTION, "ingoreAll");
conf.putSuccessor(ScannerState.TRANSITION_OBJECT_INSTANTIATION, "ignoreAll");
conf.putSuccessor(ScannerState.TRANSITION_PRIMITIVE_ARRAY_INSTANTIATION,
"ignoreAll");
conf.putSuccessor(ScannerState.TRANSITION_OBJECT_ARRAY_INSTANTIATION,
"ignoreAll");
conf = register("newPArraySet_ignoreFirstInteger",
new GenericScannerState(root, 1));
// In non-int primitive arrays class resolutions can happen
// but they should be ignored.
conf.putSuccessor(ScannerState.TRANSITION_CLASS_RESOLUTION, "ignoreAll");
// Spurious object and string references occur when setting array
// elements. This suppresses them.
conf.putSuccessor(ScannerState.TRANSITION_PRIMITIVE_INSTANTIATION,
"ignoreAll");
conf.putSuccessor(ScannerState.TRANSITION_OBJECT_REFERENCE, "ignoreAll");
conf.putSuccessor(ScannerState.TRANSITION_STRING_REFERENCE, "ignoreAll");
conf.setDefaultSuccessor("start");
}
/** Registers a <code>ScannerState</code> under a certain name.
*
* @param name Name of the state
* @param state The <code>ScannerState</code> instance.
* @return The second argument.
*/
private ScannerState register(String name, ScannerState state)
{
state.init(name);
states.put(name, state);
return state;
}
/** Generates or returns an id for the given object which can be activated
* later if the object is suitable.
*
* <p>Objects are unsuitable if they are an instance of a primitive wrapper
* or String.</p>
*
* @param value The object to retrieve an id for.
* @return The id for the object or <code>null</code>.
*/
private ObjectId retrieveId(Object value)
{
Class valueClass = value.getClass();
ObjectId id = null;
// Although multiple accesses to Class objects are not handled
// through ids we generate one for them, too. This allows us to detect
// second time references to such objects in the writeObject method
// and handle them in a special way.
if (valueClass != String.class
&& valueClass.getSuperclass() != Number.class
&& valueClass != Boolean.class)
{
if ((id = (ObjectId) objects.get(value)) == null)
{
id = new ObjectId(valueClass);
objects.put(value, id);
}
}
return id;
}
/** Scans the argument and calls one of event methods. See
* the introduction of this class for details.
*
* @param expr The expression to serialize.
*/
public void writeExpression(Expression expr)
{
String methodName = expr.getMethodName();
Object[] args = expr.getArguments();
Object target = expr.getTarget();
Object value = null;
try
{
value = expr.getValue();
}
catch (Exception e)
{
throw (InternalError)
new InternalError(
"The Expression's value should be available at this point.")
.initCause(e);
}
// TODO: What if the value is null?
ObjectId id;
Class valueClass = value.getClass();
if (target == Array.class)
{
if (methodName.equals("newInstance"))
{
id = retrieveId(value);
Class ct = (Class) args[0];
if (ct.isPrimitive() || ct == Boolean.class || ct == Byte.class
|| ct == Short.class || ct == Integer.class || ct == Long.class
|| ct == Float.class || ct == Double.class)
primitiveArrayInstantiation(ct.getName(),
args[1].toString(),
id);
else
objectArrayInstantiation(ct.getName(),
args[1].toString(),
id);
return;
}
else if (methodName.equals("get"))
{
arrayGet(args[1].toString());
// The encoder does not call the ScanEngine
// when an object is serialized that we already know.
// We test for this situation and insert the object reference
// manually.
// Since there is already a workaround for the Class class
// in writeObject we have to except it from this behavior.
id = (ObjectId) objects.get(value);
if (id != null && valueClass != Class.class)
{
objectReference(id);
end();
}
return;
}
else if (methodName.equals("set"))
{
arraySet(args[1].toString());
return;
}
}
id = retrieveId(value);
if (target instanceof Class)
{
if (methodName.equals("new"))
{
Class targetClass = (Class) target;
// All primitive types have short-hand forms for their
// constructors.
if (valueClass == Boolean.class)
primitiveInstantiation("boolean", args[0].toString());
else if (valueClass == Byte.class)
primitiveInstantiation("byte", args[0].toString());
else if (valueClass == Short.class)
primitiveInstantiation("short", args[0].toString());
else if (valueClass == Integer.class)
primitiveInstantiation("int", args[0].toString());
else if (valueClass == Long.class)
primitiveInstantiation("long", args[0].toString());
else if (valueClass == Float.class)
primitiveInstantiation("float", args[0].toString());
else if (valueClass == Double.class)
primitiveInstantiation("double", args[0].toString());
else
objectInstantiation(targetClass.getName(), id);
return;
}
else if (value instanceof Class)
{
String className = ((Class) value).getName();
// At this point we know that some *static* method will be called.
if (methodName.equals("forName"))
{
// However "Class.forName" represents class resolution and has a
// special syntax.
classResolution(className);
return;
}
else if (methodName.equals("getField"))
{
// The same goes for "Class.getField".
// Note: The name of the wanted field is given in
// the argument array.
staticFieldAccess(className, args[0].toString());
return;
}
else
{
// If nothing fits it is just a static method
// invocation which we decode as such.
staticMethodInvocation(className, methodName);
return;
}
}
}
else if (target instanceof List)
{
// Special behavior for indexed get and set method for list-style
// classes.
// The arguments are in the args array but we need them as subelements.
if (methodName.equals("get"))
{
listGet();
return;
}
else if (methodName.equals("set"))
{
listSet();
return;
}
}
// If nothing else could be used then this is a normal
// method invocation.
methodInvocation(methodName);
}
/**
* Ends the current state and returns to the last one.
*/
public void end()
{
current.end();
if (DEBUG) System.err.print("back from " + current.getName());
ScannerState oldCurrent = current;
current = (ScannerState) parents.pop();
if (DEBUG) System.err.println(" to " + current.getName());
}
/**
* Returns to the last state and deletes the last element in the object tree.
*/
public void revoke()
{
ScannerState oldCurrent = current;
current = (ScannerState) parents.pop();
root.deleteLast();
}
/** Scans the argument and calls one of event methods. See
* the introduction of this class for details.
*
* @param stmt The statement to serialize.
*/
public void writeStatement(Statement stmt)
{
// This is a simplified version of writeExpression. Everything
// that would not create something that is embedded in a <void> tag
// is left out (instantiation, getters, ...).
// TODO: Is this the right thing to do?
String methodName = stmt.getMethodName();
Object target = stmt.getTarget();
Object[] args = stmt.getArguments();
if (target == Array.class && methodName.equals("set"))
{
arraySet(args[1].toString());
return;
}
if (target instanceof List)
{
if (methodName.equals("set"))
{
listSet();
return;
}
}
// If nothing else could be used then this is a normal
// method invocation.
methodInvocation(methodName);
}
/** Scans the argument and calls one of event methods. See
* the introduction of this class for details.
*
* @param o The object to serialize.
*/
public boolean writeObject(Object o)
{
ObjectId id = null;
if (o == null)
{
// Handle null objects which have a special syntax.
nullObject();
end();
}
else if (o.getClass() == String.class)
{
// Handle strings which are treated extremely special
// in the encoder (they are never converted into a
// Expression).
stringReference((String) o);
end();
}
else if ((id = (ObjectId) objects.get(o)) != null)
{
// Multiple references to a Class object do not generate
// an object reference but we use the id to detect that
// situation.
if (o.getClass() == Class.class)
{
classResolution(((Class) o).getName());
end();
return false;
}
// If our object has a corresponding ObjectId instance
// then generate an objectReference. This will
// initialize the id (= brings it in the "used" state)
// when this is the first referal.
objectReference(id);
end();
return false;
}
return true;
}
/**
* Writes the currently constructed object tree out as
* XML and clears the object to {@link ObjectId} relations.
*/
public void flush()
{
// Make all references unreachable. That means we have to generate
// new object ids.
objects.clear();
root.traverse(writer);
}
/** Writes the final bits if the object tree and closes the stream
* afterwards.
*/
public void close()
{
flush();
root.close(writer);
}
/**
* Does a transition from one state to another using the given event.
*
* <p>This involves saving the current state, retrieving it's
* successor and setting it as the current state.</p>
*
* @param transition One of {@link ScannerStates]'s transition constants.
*/
private void transition(int transition)
{
parents.push(current);
String stateName = current.getSuccessor(transition);
if (DEBUG)
{
System.err.println("from state: " + current.getName() + "\n\troute: "
+ ScannerState.transitionNames[transition]
+ "\n\t\tto state: "
+ stateName);
}
ScannerState newState = (ScannerState) states.get(stateName);
newState.enter(new Context(current.getName(), current.getCalls()));
assert (newState != null) : "State '" + stateName + "' was not defined.";
current = newState;
}
/** Event method that denotes a (non-static) method invocation.
*
* <p>More details about this method can be found in this
* class' introduction.</p>
*
* @param methodName The name of the method which is called.
*/
void methodInvocation(String methodName)
{
transition(ScannerState.TRANSITION_METHOD_INVOCATION);
current.methodInvocation(methodName);
}
/** Event method that denotes a static method invocation.
*
* <p>More details about this method can be found in this
* class' introduction.</p>
*
* @param methodName The name of the method which is called.
* @param className The name of the class in which the method is called.
*/
void staticMethodInvocation(String className, String methodName)
{
transition(ScannerState.TRANSITION_STATIC_METHOD_INVOCATION);
current.staticMethodInvocation(className, methodName);
}
/** Event method that denotes the retrieval of a static field's value.
*
* <p>More details about this method can be found in this
* class' introduction.</p>
*
* @param fieldName The name of the field whose value is retrieved.
* @param className The name of the class in which the method is called.
*/
void staticFieldAccess(String className, String fieldName)
{
transition(ScannerState.TRANSITION_STATIC_FIELD_ACCESS);
current.staticFieldAccess(className, fieldName);
}
/** Event method that denotes the resolution of a class.
*
* <p>More details about this method can be found in this
* class' introduction.</p>
*
* @param className The name of the class in which the method is called.
*/
void classResolution(String className)
{
transition(ScannerState.TRANSITION_CLASS_RESOLUTION);
current.classResolution(className);
}
/** Event method that denotes the instantiation of an object.
*
* <p>More details about this method can be found in this
* class' introduction.</p>
*
* @param className The name of the class in which the method is called.
* @param objectId An ObjectId instance which can be activated later.
*/
void objectInstantiation(String className, ObjectId objectId)
{
transition(ScannerState.TRANSITION_OBJECT_INSTANTIATION);
current.objectInstantiation(className, objectId);
}
/** Event method that denotes the instantiation of a primitive.
*
* <p>More details about this method can be found in this
* class' introduction.</p>
*
* @param primitiveName One of "boolean, "byte", "short", "int", "long"
* , "float" or "double"
* @param valueAsString The value of the primitive as a String.
*/
void primitiveInstantiation(String primitiveName, String valueAsString)
{
transition(ScannerState.TRANSITION_PRIMITIVE_INSTANTIATION);
current.primitiveInstantiation(primitiveName, valueAsString);
}
/** Event method that denotes the instantiation of an object array.
*
* <p>More details about this method can be found in this
* class' introduction.</p>
*
* @param arrayClassName The array's class name.
* @param objectId An ObjectId instance which can be activated later.
* @param lengthAsString The array's length as String.
*/
void objectArrayInstantiation(String arrayClassName, String lengthAsString,
ObjectId objectId)
{
transition(ScannerState.TRANSITION_OBJECT_ARRAY_INSTANTIATION);
current.objectArrayInstantiation(arrayClassName, lengthAsString, objectId);
}
/** Event method that denotes the instantiation of a primitive array.
*
* <p>More details about this method can be found in this
* class' introduction.</p>
*
* @param arrayClassName The array's class name.
* @param objectId An ObjectId instance which can be activated later.
* @param lengthAsString The array's length as String.
*/
void primitiveArrayInstantiation(String arrayClassName, String lengthAsString,
ObjectId objectId)
{
transition(ScannerState.TRANSITION_PRIMITIVE_ARRAY_INSTANTIATION);
current.objectArrayInstantiation(arrayClassName, lengthAsString, objectId);
}
/** Event method that denotes the setting of a value in an array.
*
* <p>More details about this method can be found in this
* class' introduction.</p>
*
* @param indexAsString The index to as a String.
*/
void arraySet(String indexAsString)
{
transition(ScannerState.TRANSITION_ARRAY_SET);
current.arraySet(indexAsString);
}
/** Event method that denotes the retrieval of a value in an array.
*
* <p>More details about this method can be found in this
* class' introduction.</p>
*
* @param indexAsString The index to as a String.
*/
void arrayGet(String indexAsString)
{
transition(ScannerState.TRANSITION_ARRAY_GET);
current.arrayGet(indexAsString);
}
/** Event method that denotes the setting of a value in a list.
*
* <p>More details about this method can be found in this
* class' introduction.</p>
*/
void listSet()
{
transition(ScannerState.TRANSITION_LIST_SET);
current.listSet();
}
/** Event method that denotes the retrieval of a value in a list.
*
* <p>More details about this method can be found in this
* class' introduction.</p>
*/
void listGet()
{
transition(ScannerState.TRANSITION_LIST_GET);
current.listGet();
}
/** Event method that denotes the null value.
*/
void nullObject()
{
transition(ScannerState.TRANSITION_NULL_OBJECT);
current.nullObject();
}
/** Event method that denotes a string.
*
* @param string The string that should be written.
*/
void stringReference(String string)
{
transition(ScannerState.TRANSITION_STRING_REFERENCE);
current.stringReference(string);
}
/** Event method that denotes a reference to an existing object.
*
* @param id The ObjectId to be used.
*/
void objectReference(ObjectId id)
{
transition(ScannerState.TRANSITION_OBJECT_REFERENCE);
current.objectReference(id);
}
}
@@ -0,0 +1,236 @@
/* ScannerState.java
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. */
package gnu.java.beans.encoder;
import java.util.HashMap;
/** <p>Provides the infrastructure for the state machine and the transition
* mechanism.</p>
*
* <p>Each states knows a set of successor. There can be one successor for
* every transition variant. Furthermore a state knows about a default
* successor which is taken when there is no special setup for a
* transition.</p>
*
* @author Robert Schuster (robertschuster@fsfe.org)
*
*/
public abstract class ScannerState
{
static final int TRANSITION_METHOD_INVOCATION = 0;
static final int TRANSITION_STATIC_METHOD_INVOCATION = 1;
static final int TRANSITION_STATIC_FIELD_ACCESS = 2;
static final int TRANSITION_CLASS_RESOLUTION = 3;
static final int TRANSITION_OBJECT_INSTANTIATION = 4;
static final int TRANSITION_PRIMITIVE_INSTANTIATION = 5;
static final int TRANSITION_OBJECT_ARRAY_INSTANTIATION = 6;
static final int TRANSITION_PRIMITIVE_ARRAY_INSTANTIATION = 7;
static final int TRANSITION_ARRAY_SET = 8;
static final int TRANSITION_ARRAY_GET = 9;
static final int TRANSITION_LIST_SET = 10;
static final int TRANSITION_LIST_GET = 11;
static final int TRANSITION_NULL_OBJECT = 12;
static final int TRANSITION_STRING_REFERENCE = 13;
static final int TRANSITION_OBJECT_REFERENCE = 14;
static final int TRANSITION_FIRST = 0;
static final int TRANSITION_LAST = 14;
static final String DEFAULT_STATE_NAME = "default";
String defaultSuccessor = DEFAULT_STATE_NAME;
static String[] transitionNames = { "METHOD_INVOCATION", "STATIC_METHOD_INVOCATION",
"STATIC_FIELD_ACCESS", "CLASS_RESOLUTION",
"OBJECT_INSTANTIATION",
"PRIMITIVE_INSTANTIATION", "OBJECT_ARRAY_INSTANTIATION",
"PRIMITIVE_ARRAY_INSTANTIATION",
"ARRAY_SET", "ARRAY_GET", "LIST_SET", "LIST_GET",
"NULL_OBJECT", "STRING_REFERENCE", "OBJECT_REFERENCE" };
/**
* Stores the transition setup as the relation
* transition->successor's state name.
*/
HashMap transitions = new HashMap();
int calls;
Context context;
String name;
final void init(String newName)
{
assert (name == null);
name = newName;
}
final String getName()
{
return name;
}
final void enter(Context ctx)
{
calls++;
context = ctx;
enterImpl(ctx);
}
protected void enterImpl(Context ctx)
{
}
final Context context()
{
return context;
}
final int getCalls()
{
return calls;
}
/**
* <p>Stores a successor's state name for a certain transition.</p>
*
* <p>This method is only used at the configuration time of the state
* machine.</p>
*
* @param transition One of the transition constants.
* @param stateName The state name of the successor.
*/
final void putSuccessor(int transition, String stateName)
{
assert (transition >= TRANSITION_FIRST && transition <= TRANSITION_LAST) :
"Transition identifier '" + transition + "' is unknown.";
transitions.put(new Integer(transition), stateName);
}
/** <p>Retrieves a the state name of a successor for the given transition
* constant.</p>
*
* <p>Returns the default successor's state name if no special setup was
* prepared.</p>
*
* @param transition One of the transition constants.
* @return The state name of the successor.
*/
final String getSuccessor(int transition)
{
String state = (String) transitions.get(new Integer(transition));
return (state == null) ? defaultSuccessor : state;
}
/**
* Sets the name for the default successor state.
*
* @param newDefaultSuccessor The default successor's state name.
*/
final void setDefaultSuccessor(String newDefaultSuccessor)
{
defaultSuccessor = newDefaultSuccessor;
}
abstract void methodInvocation(String methodName);
abstract void staticMethodInvocation(String className, String methodName);
abstract void staticFieldAccess(String className, String fieldName);
abstract void classResolution(String className);
abstract void objectInstantiation(String className, ObjectId objectId);
abstract void primitiveInstantiation(String primitiveName,
String valueAsString);
abstract void objectArrayInstantiation(String arrayClassName, String lengthAsString, ObjectId objectId);
abstract void primitiveArrayInstantiation(String arrayClassName, String lengthAsString, ObjectId objectId);
abstract void arraySet(String indexAsString);
abstract void arrayGet(String indexAsString);
abstract void listGet();
abstract void listSet();
abstract void nullObject();
abstract void stringReference(String string);
abstract void objectReference(ObjectId id);
/**
* <p>A special event that does not provoke a direct transition.</p>
*
* <p>Instead the transition is done by the <code>ScanEngine</code>: It goes
* back to the previous state and just uses this method to inform the state
* about this happening.</p>
*/
abstract void end();
void enter()
{
}
}
@@ -0,0 +1,233 @@
/* StAXWriter.java
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. */
package gnu.java.beans.encoder;
import java.io.OutputStream;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
/** A {@link Writer} implementation based on the StAX API.
*
* @author Robert Schuster (robertschuster@fsfe.org)
*
*/
public class StAXWriter implements Writer
{
XMLStreamWriter writer;
int indent = 0;
public StAXWriter(OutputStream os)
{
try
{
XMLOutputFactory factory = XMLOutputFactory.newInstance();
writer = factory.createXMLStreamWriter(os);
}
catch (XMLStreamException se)
{
throw (InternalError)
new InternalError(
"Could not instantiate a streaming XML writer.")
.initCause(se);
}
}
public void flush()
{
if (writer != null)
{
try
{
writer.flush();
}
catch (XMLStreamException xse)
{
// TODO: find out
}
}
}
public void close()
{
if (writer != null)
{
try
{
writer.close();
}
catch (XMLStreamException xse)
{
// TODO: find out
}
writer = null;
}
}
public void writePreamble()
{
try
{
writer.writeStartDocument("UTF-8", "1.0");
}
catch (XMLStreamException xmlse)
{
}
}
public void writeEnd(boolean wasEmpty)
{
try
{
indent -= 2;
if (wasEmpty)
return;
for (int i = 0; i < indent; i++)
writer.writeCharacters(" ");
writer.writeEndElement();
writer.writeCharacters("\n");
}
catch (XMLStreamException xmlse)
{
}
}
public void writeEndNoChildren()
{
try
{
writer.writeEndElement();
writer.writeCharacters("\n");
}
catch (XMLStreamException xmlse)
{
}
}
public void write(String tagName, boolean empty)
{
write(tagName, null, null, null, empty);
}
public void write(String tagName, String value)
{
write(tagName, value, null, null, value == null);
}
public void writeNoChildren(String tagName, String value)
{
try
{
for (int i = 0; i < indent; i++)
writer.writeCharacters(" ");
writer.writeStartElement(tagName);
writer.writeCharacters(value);
}
catch (XMLStreamException xmlse)
{
}
}
public void write(String tagName, String attributeName,
String attributeValue, boolean empty)
{
write(tagName, null, new String[] { attributeName },
new String[] { attributeValue }, empty);
}
public void write(String tagName, String value, String[] attributeNames,
String[] attributeValues, boolean empty)
{
try
{
for (int i = 0; i < indent; i++)
writer.writeCharacters(" ");
if (empty)
writer.writeEmptyElement(tagName);
else
writer.writeStartElement(tagName);
if (attributeNames != null)
for (int i = 0; i < attributeNames.length; i++)
writer.writeAttribute(attributeNames[i], attributeValues[i]);
writer.writeCharacters("\n");
indent += 2;
if (value != null)
{
for (int i = 0; i < indent; i++)
writer.writeCharacters(" ");
writer.writeCharacters(value);
writer.writeCharacters("\n");
}
}
catch (XMLStreamException xmlse)
{
}
}
public void write(String tagName, String[] attributeNames,
String[] attributeValues, boolean empty)
{
write(tagName, null, attributeNames, attributeValues, empty);
}
}
@@ -0,0 +1,174 @@
/* Writer.java -- Writing interface for XML persistence.
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. */
package gnu.java.beans.encoder;
/** A <code>Writer</code> represents a simplified interface to an XML
* writer that is used for the XML persistence mechanism.
*
* <p>Its sole purpose is to allow multiple backends which may remove
* the need to have certain APIs in the classpath. Eg. it is possible
* to write a stripped down XML Writer that does not rely on SAX, StAX
* or DOM APIs.</p>
*
* <p>The caller may assume that every action is done immediately. However
* it is possible that the underlying implementation uses buffering streams.
* To make sure the data is written call the {@link flush} method.</p>
*
* <p>The <code>Writer</code> implementation should care about the formatting
* of the XML stream making it possible to generate three types of formats using
* a special method invocation chain.</p>
*
* <p>Write
* <code>
* &lt;element/&gt;
* </code>
* by issuing <code>write("element", true)</code> (or any of the other
* write-variants that allows specifying the <code>isEmpty</code> argument)
* and <code>writeEnd(true)</code>.</p>
*
* <p>Write
* <code>
* &lt;element&gt;body&lt;/element&gt;
* </code>
* by issuing <code>writeNoChildren("element", "body")</code> and <code>writeNoChildrenEnd()</code>.</p>
*
* <p>
* Write
* <code>
* &lt;element&gt;
* &lt;child1/&gt;
* &lt;child2/&gt;
* ...
* &lt;element/&gt;
* </code>
* by issuing <code>write("element", false)</code> (or any of the other
* write-variants that allows specifying the <code>isEmpty</code> argument)
* and <code>writeEnd(false)</code>.</p>
*
* <p>Note: It is important that the values of <code>isEmpty</code> and
* <code>wasEmpty</code> match. Otherwise strange things might happen to
* the layout.</p>
*
* @author Robert Schuster (robertschuster@fsfe.org)
*
*/
public interface Writer
{
// TODO: This interface's design is not the best. Feel free to
// improve it as you like.
/** Writes the XML preamble. */
void writePreamble();
/** Writes the end of an XML tag.
*
* <p>If your tag has not generated any body text or child
* elements provide <code>true</code> as the argument to generate
* more space efficient variant of the tag.>/p>
*
* @param wasEmpty Whether the tag was empty or not.
*/
void writeEnd(boolean wasEmpty);
/** Writes an XML tag without any attributes.
*
* @param tagName The name of the tag to write.
* @param empty Whether the element has child elements.
*/
void write(String tagName, boolean empty);
/** Writes an XML tag with one attribute name and value.
*
* @param tagName The name of the tag to write.
* @param attributeName The name of attribute.
* @param attributeValue The attribute's value.
* @param empty Whether the element has child elements.
*/
void write(String tagName, String attributeName, String attributeValue, boolean empty);
/** Writes an XML tag with multiple attributes and a body text.
*
* @param tagName The name of the tag to write.
* @param value The element's body content.
* @param attributeNames A set of attribute names.
* @param attributeValues A set of attribute values.
* @param empty Whether the element has child elements.
*/
void write(String tagName, String value, String[] attributeNames,
String[] attributeValues, boolean empty);
/** Writes an XML tag with multiple attributes without a body text.
*
* @param tagName The name of the tag to write.
* @param attributeNames A set of attribute names.
* @param attributeValues A set of attribute values.
* @param empty Whether the element has child elements.
*/
void write(String tagName, String[] attributeNames, String[] attributeValues, boolean empty);
/** Writes an XML tag with no attributes but with a body text
* that may have child elements.
*
* @param tagName The name of the tag to write.
* @param value The element's body content.
*/
void write(String tagName, String value);
/** Writes an XML tag with no attributes but with a body text
* that does not have child elements.
*
* @param tagName The name of the tag to write.
* @param value The element's body content.
*/
void writeNoChildren(String tagName, String value);
/** Writes the end of an XML tag that has no child elements.
*
* <p>Must be used in combination with {@link writeNoChildren} only.</p>
*/
void writeEndNoChildren();
/** Forces the implementation to write some data.
*/
void flush();
/** Closes the writer.
*/
void close();
}
@@ -0,0 +1,74 @@
/* ArrayInstantiation.java
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. */
package gnu.java.beans.encoder.elements;
import gnu.java.beans.encoder.ObjectId;
import gnu.java.beans.encoder.Writer;
/** Generates an XML element denoting the instantiation of an array.
*
* @author Robert Schuster (robertschuster@fsfe.org)
*
*/
public class ArrayInstantiation extends Element
{
final String className;
final String lengthAsString;
public ArrayInstantiation(String newClassName, String newLengthAsString)
{
className = newClassName;
lengthAsString = newLengthAsString;
}
public void writeStart(Writer writer)
{
ObjectId objectId = getId();
if (objectId.isUnused())
writer.write("array", new String[] { "class", "length" },
new String[] { className, lengthAsString }, isEmpty());
else
writer.write("array", new String[] { "id", "class", "length" },
new String[] { objectId.toString(), className,
lengthAsString }, isEmpty());
}
}
@@ -0,0 +1,62 @@
/* Array_Get.java
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. */
package gnu.java.beans.encoder.elements;
import gnu.java.beans.encoder.Writer;
/**
* Generates an XML element denoting the retrieval of an array value.
*
* @author Robert Schuster (robertschuster@fsfe.org)
*/
public class Array_Get extends Element
{
final String indexAsString;
public Array_Get(String newIndexAsString)
{
indexAsString = newIndexAsString;
}
public void writeStart(Writer writer)
{
writer.write("void", "index", indexAsString, isEmpty());
}
}
@@ -0,0 +1,57 @@
/* Array_Set.java -- FIXME: briefly describe file purpose
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. */
package gnu.java.beans.encoder.elements;
import gnu.java.beans.encoder.Writer;
public class Array_Set extends Element
{
final String indexAsString;
public Array_Set(String newIndexAsString)
{
indexAsString = newIndexAsString;
}
public void writeStart(Writer writer)
{
writer.write("void", "index", indexAsString, isEmpty());
}
}
@@ -0,0 +1,67 @@
/* ClassResolution.java
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. */
package gnu.java.beans.encoder.elements;
import gnu.java.beans.encoder.Writer;
/** Generates an XML element denoting the resolution of a class.
*
* @author Robert Schuster (robertschuster@fsfe.org)
*
*/
public class ClassResolution extends Element
{
final String className;
public ClassResolution(String newClassName)
{
className = newClassName;
}
public void writeStart(Writer writer)
{
writer.writeNoChildren("class", className);
}
public void writeEnd(Writer writer)
{
writer.writeEndNoChildren();
}
}
@@ -0,0 +1,157 @@
/* Element.java -- Base class for object tree elements.
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. */
package gnu.java.beans.encoder.elements;
import java.util.Iterator;
import java.util.LinkedList;
import gnu.java.beans.encoder.ObjectId;
import gnu.java.beans.encoder.Writer;
/** <code>Element</code> is the base class for the object tree elements.
*
* <p>It provides the neccessary infrastructure every element subclass
* needs in order to interact with the {@link gnu.java.beans.encoder.Root}
* class.</p>
*
* @author Robert Schuster (robertschuster@fsfe.org)
*/
public abstract class Element
{
/**
* Stores the child elements.
*/
private LinkedList children = new LinkedList();
/**
* An optional ObjectId instance which is needed for certain subclasses
* only.
*/
private ObjectId objectId;
/** Sets an {@link gnu.java.beans.encoder.ObjectId} instance in this
* <code>Element</code>.
*
* <p>This can only be done once.</p>
*
* @param objectId An ObjectId instance.
*/
public final void initId(ObjectId objectId)
{
assert (this.objectId == null);
assert (objectId != null);
this.objectId = objectId;
}
/** Adds a child element to this <code>Element</code>.
*
* @param elem The new child.
*/
public final void addChild(Element elem)
{
children.add(elem);
}
/** Removes the child element added last.
*/
public final void removeLast()
{
children.removeLast();
}
/** Provides access to the child elements via an iterator.
*
* @return An iterator for the child elements.
*/
public final Iterator iterator(){
return children.iterator();
}
/** Clears all the stored child elements.
*
*/
public final void clear()
{
children.clear();
}
/** Returns whether this element contains child elements.
*
* <p>This method is useful to decide which formatting variant
* for the XML element can be chosen.</p>
*
* @return Whether the element has child elements.
*/
public final boolean isEmpty()
{
return children.isEmpty();
}
/** Retrieves the element's {@link gnu.java.beans.encoder.ObjectId} instance
* if it has one.
*
* @return The ObjectId instance or <code>null</code>.
*/
public final ObjectId getId()
{
return objectId;
}
/** Writes the opening XML tag.
*
* @param writer The writer to be used for XML writing.
*/
public abstract void writeStart(Writer writer);
/** Writes the closing XML tag.
*
* <p>By default this does <code>writer.writeEnd(children.isEmpty())</code>.
* Override if neccessary, for example when using the
* {@link gnu.java.beans.encoder.Writer#writeNoChildren}</code> method
* variants.
*
* @param writer The writer to be used for XML writing.
*/
public void writeEnd(Writer writer)
{
writer.writeEnd(children.isEmpty());
}
}
@@ -0,0 +1,56 @@
/* List_Get.java
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. */
package gnu.java.beans.encoder.elements;
import gnu.java.beans.encoder.Writer;
/** Generates an XML element denoting the retrieval of a list's element.
*
* @author Robert Schuster (robertschuster@fsfe.org)
*
*/
public class List_Get extends Element
{
public void writeStart(Writer writer)
{
writer.write("object", "get");
}
}
@@ -0,0 +1,56 @@
/* List_Set.java
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. */
package gnu.java.beans.encoder.elements;
import gnu.java.beans.encoder.Writer;
/** Generates an XML element denoting the setting of a list's element.
*
* @author Robert Schuster (robertschuster@fsfe.org)
*
*/
public class List_Set extends Element
{
public void writeStart(Writer writer)
{
writer.write("object", "set");
}
}
@@ -0,0 +1,62 @@
/* MethodCall.java
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. */
package gnu.java.beans.encoder.elements;
import gnu.java.beans.encoder.Writer;
/** Generates an XML element denoting a non-static method call.
*
* @author Robert Schuster (robertschuster@fsfe.org)
*
*/
public class MethodInvocation extends Element
{
final String methodName;
public MethodInvocation(String newMethodName)
{
methodName = newMethodName;
}
public void writeStart(Writer writer)
{
writer.write("void", "method", methodName, isEmpty());
}
}
@@ -0,0 +1,61 @@
/* NullObject.java
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. */
package gnu.java.beans.encoder.elements;
import gnu.java.beans.encoder.Writer;
/** Generates an XML element denoting the <code>null</code> value.
*
* @author Robert Schuster (robertschuster@fsfe.org)
*
*/
public class NullObject extends Element
{
public void writeStart(Writer writer)
{
writer.write("null", true);
}
public void writeEnd(Writer writer)
{
writer.writeEnd(true);
}
}
@@ -0,0 +1,68 @@
/* ObjectInstantiation.java
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. */
package gnu.java.beans.encoder.elements;
import gnu.java.beans.encoder.ObjectId;
import gnu.java.beans.encoder.Writer;
/** Generates an XML element denoting the instantiation of an object.
*
* @author Robert Schuster (robertschuster@fsfe.org)
*
*/
public class ObjectInstantiation extends Element
{
final String className;
public ObjectInstantiation(String newClassName)
{
className = newClassName;
}
public void writeStart(Writer writer)
{
ObjectId objectId = getId();
if (objectId.isUnused())
writer.write("object", "class", className, isEmpty());
else
writer.write("object", new String[] { "id", "class" },
new String[] { objectId.toString(), className }, isEmpty());
}
}
@@ -0,0 +1,68 @@
/* StringInstantiation.java
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. */
package gnu.java.beans.encoder.elements;
import gnu.java.beans.encoder.ObjectId;
import gnu.java.beans.encoder.Writer;
/** Generates an XML element denoting referencing an existing object.
*
* @author Robert Schuster (robertschuster@fsfe.org)
*
*/
public class ObjectReference extends Element
{
final ObjectId id;
public ObjectReference(ObjectId newId)
{
id = newId;
// Initializing the Id here is making sure it gets
// actually used. This step modifies the Id instance
// in other elements.
id.init();
}
public void writeStart(Writer writer)
{
writer.write("object", "idref", id.toString(), isEmpty());
}
}
@@ -0,0 +1,69 @@
/* PrimitiveInstantiation.java
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. */
package gnu.java.beans.encoder.elements;
import gnu.java.beans.encoder.Writer;
/** Generates an XML element denoting a primitive data value.
*
* @author Robert Schuster (robertschuster@fsfe.org)
*
*/
public class PrimitiveInstantiation extends Element
{
final String primitiveName;
final String valueAsString;
public PrimitiveInstantiation(String newPrimitiveName, String newValueAsString)
{
primitiveName = newPrimitiveName;
valueAsString = newValueAsString;
}
public void writeStart(Writer writer)
{
writer.writeNoChildren(primitiveName, valueAsString);
}
public void writeEnd(Writer writer)
{
writer.writeEndNoChildren();
}
}
@@ -0,0 +1,66 @@
/* StaticFieldAccess.java
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. */
package gnu.java.beans.encoder.elements;
import gnu.java.beans.encoder.Writer;
/** Generates an XML element denoting a static method call.
*
* @author Robert Schuster (robertschuster@fsfe.org)
*
*/
public class StaticFieldAccess extends Element
{
final String className;
final String fieldName;
public StaticFieldAccess(String newClassName, String newFieldName)
{
className = newClassName;
fieldName = newFieldName;
}
public void writeStart(Writer writer)
{
writer.write("object", new String[] { "class", "field" },
new String[] { className, fieldName }, isEmpty());
}
}
@@ -0,0 +1,67 @@
/* StaticMethodCall.java
-- A class denoting an XML element which makes up a static method call.
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. */
package gnu.java.beans.encoder.elements;
import gnu.java.beans.encoder.Writer;
/**
*
* @author Robert Schuster (robertschuster@fsfe.org)
*
*/
public class StaticMethodInvocation extends Element
{
final String className;
final String methodName;
public StaticMethodInvocation(String newClassName, String newMethodName)
{
className = newClassName;
methodName = newMethodName;
}
public void writeStart(Writer writer)
{
writer.write("void", new String[] { "class", "method" },
new String[] { className, methodName }, isEmpty());
}
}
@@ -0,0 +1,63 @@
/* StringInstantiation.java
-- A class denoting an XML element which retrieves an array element.
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. */
package gnu.java.beans.encoder.elements;
import gnu.java.beans.encoder.Writer;
public class StringReference extends Element
{
final String string;
public StringReference(String newString)
{
string = newString;
}
public void writeStart(Writer writer)
{
writer.writeNoChildren("string", string);
}
public void writeEnd(Writer writer)
{
writer.writeEndNoChildren();
}
}