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:
@@ -40,6 +40,8 @@ package gnu.java.awt.image;
|
||||
import java.awt.image.ImageConsumer;
|
||||
import java.awt.image.ImageProducer;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.DataInput;
|
||||
import java.io.EOFException;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@@ -55,6 +57,7 @@ public abstract class ImageDecoder implements ImageProducer
|
||||
int offset;
|
||||
int length;
|
||||
InputStream input;
|
||||
DataInput datainput;
|
||||
|
||||
static
|
||||
{
|
||||
@@ -79,6 +82,11 @@ public abstract class ImageDecoder implements ImageProducer
|
||||
this.input = is;
|
||||
}
|
||||
|
||||
public ImageDecoder (DataInput datainput)
|
||||
{
|
||||
this.datainput = datainput;
|
||||
}
|
||||
|
||||
public ImageDecoder (byte[] imagedata, int imageoffset, int imagelength)
|
||||
{
|
||||
data = imagedata;
|
||||
@@ -119,6 +127,8 @@ public abstract class ImageDecoder implements ImageProducer
|
||||
{
|
||||
if (url != null)
|
||||
input = url.openStream();
|
||||
else if (datainput != null)
|
||||
input = new DataInputStreamWrapper(datainput);
|
||||
else
|
||||
{
|
||||
if (filename != null)
|
||||
@@ -153,4 +163,26 @@ public abstract class ImageDecoder implements ImageProducer
|
||||
}
|
||||
|
||||
public abstract void produce (Vector v, InputStream is) throws IOException;
|
||||
|
||||
private static class DataInputStreamWrapper extends InputStream
|
||||
{
|
||||
private final DataInput datainput;
|
||||
|
||||
DataInputStreamWrapper(DataInput datainput)
|
||||
{
|
||||
this.datainput = datainput;
|
||||
}
|
||||
|
||||
public int read() throws IOException
|
||||
{
|
||||
try
|
||||
{
|
||||
return datainput.readByte() & 0xFF;
|
||||
}
|
||||
catch (EOFException eofe)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,7 +48,6 @@ import java.awt.Graphics;
|
||||
import java.awt.Image;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Shape;
|
||||
import java.awt.SystemColor;
|
||||
import java.awt.image.ImageObserver;
|
||||
import java.text.AttributedCharacterIterator;
|
||||
|
||||
@@ -81,18 +80,23 @@ public class GdkGraphics extends Graphics
|
||||
native void initStateUnlocked (GtkComponentPeer component);
|
||||
native void initState (int width, int height);
|
||||
native void initFromImage (GtkImage image);
|
||||
native void copyState (GdkGraphics g);
|
||||
native void nativeCopyState (GdkGraphics g);
|
||||
|
||||
/**
|
||||
* A cached instance that is used by {@link #create} in order to avoid
|
||||
* massive allocation of graphics contexts.
|
||||
*/
|
||||
GdkGraphics cached = null;
|
||||
|
||||
/**
|
||||
* A link to the parent context. This is used in {@link #dispose} to put
|
||||
* this graphics context into the cache.
|
||||
*/
|
||||
GdkGraphics parent = null;
|
||||
|
||||
GdkGraphics (GdkGraphics g)
|
||||
{
|
||||
color = g.color;
|
||||
xorColor = g.xorColor;
|
||||
font = g.font;
|
||||
if (font == null)
|
||||
font = new Font ("Dialog", Font.PLAIN, 12);
|
||||
clip = new Rectangle (g.clip);
|
||||
component = g.component;
|
||||
|
||||
parent = g;
|
||||
copyState (g);
|
||||
}
|
||||
|
||||
@@ -162,12 +166,54 @@ public class GdkGraphics extends Graphics
|
||||
public native void copyArea(int x, int y, int width, int height,
|
||||
int dx, int dy);
|
||||
|
||||
public Graphics create ()
|
||||
/**
|
||||
* Creates a copy of this GdkGraphics instance. This implementation can
|
||||
* reuse a cached instance to avoid massive instantiation of Graphics objects
|
||||
* during painting.
|
||||
*
|
||||
* @return a copy of this graphics context
|
||||
*/
|
||||
public Graphics create()
|
||||
{
|
||||
return new GdkGraphics (this);
|
||||
GdkGraphics copy = cached;
|
||||
if (copy == null)
|
||||
copy = new GdkGraphics(this);
|
||||
else
|
||||
{
|
||||
copy.copyState(this);
|
||||
cached = null;
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
||||
public native void dispose();
|
||||
public native void nativeDispose();
|
||||
|
||||
/**
|
||||
* Disposes this graphics object. This puts this graphics context into the
|
||||
* cache of its parent graphics if there is one.
|
||||
*/
|
||||
public void dispose()
|
||||
{
|
||||
if (parent != null)
|
||||
{
|
||||
parent.cached = this;
|
||||
parent = null;
|
||||
}
|
||||
else
|
||||
nativeDispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* This is called when this object gets finalized by the garbage collector.
|
||||
* In addition to {@link Graphics#finalize()} this calls nativeDispose() to
|
||||
* make sure the native resources are freed before the graphics context is
|
||||
* thrown away.
|
||||
*/
|
||||
public void finalize()
|
||||
{
|
||||
super.finalize();
|
||||
nativeDispose();
|
||||
}
|
||||
|
||||
public boolean drawImage (Image img, int x, int y,
|
||||
Color bgcolor, ImageObserver observer)
|
||||
@@ -248,9 +294,8 @@ public class GdkGraphics extends Graphics
|
||||
public void drawString (String str, int x, int y)
|
||||
{
|
||||
drawString(getFontPeer(), str, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void drawString (AttributedCharacterIterator ci, int x, int y)
|
||||
{
|
||||
throw new Error ("not implemented");
|
||||
@@ -419,4 +464,23 @@ public class GdkGraphics extends Graphics
|
||||
|
||||
translateNative (x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies over the state of another GdkGraphics to this instance. This is
|
||||
* used by the {@link #GdkGraphics(GdkGraphics)} constructor and the
|
||||
* {@link #create()} method.
|
||||
*
|
||||
* @param g the GdkGraphics object to copy the state from
|
||||
*/
|
||||
private void copyState(GdkGraphics g)
|
||||
{
|
||||
color = g.color;
|
||||
xorColor = g.xorColor;
|
||||
font = g.font;
|
||||
if (font == null)
|
||||
font = new Font ("Dialog", Font.PLAIN, 12);
|
||||
clip = new Rectangle (g.clip);
|
||||
component = g.component;
|
||||
nativeCopyState(g);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,11 +180,14 @@ public class GdkGraphics2D extends Graphics2D
|
||||
else
|
||||
fg = new Color(g.fg.getRGB());
|
||||
|
||||
if (g.bg.getAlpha() != -1)
|
||||
bg = new Color(g.bg.getRed(), g.bg.getGreen(), g.bg.getBlue(),
|
||||
g.bg.getAlpha());
|
||||
else
|
||||
bg = new Color(g.bg.getRGB());
|
||||
if (g.bg != null)
|
||||
{
|
||||
if (g.bg.getAlpha() != -1)
|
||||
bg = new Color(g.bg.getRed(), g.bg.getGreen(), g.bg.getBlue(),
|
||||
g.bg.getAlpha());
|
||||
else
|
||||
bg = new Color(g.bg.getRGB());
|
||||
}
|
||||
|
||||
if (g.clip == null)
|
||||
clip = null;
|
||||
@@ -1088,6 +1091,8 @@ public class GdkGraphics2D extends Graphics2D
|
||||
|
||||
public void setBackground(Color c)
|
||||
{
|
||||
if (c == null)
|
||||
c = Color.WHITE;
|
||||
bg = c;
|
||||
}
|
||||
|
||||
|
||||
@@ -47,6 +47,7 @@ import java.awt.image.ImageConsumer;
|
||||
import java.awt.image.ImageProducer;
|
||||
import java.awt.image.Raster;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@@ -102,6 +103,11 @@ public class GdkPixbufDecoder extends gnu.java.awt.image.ImageDecoder
|
||||
0x00ff0000,
|
||||
0x0000ff00,
|
||||
0x000000ff);
|
||||
public GdkPixbufDecoder (DataInput datainput)
|
||||
{
|
||||
super (datainput);
|
||||
}
|
||||
|
||||
public GdkPixbufDecoder (InputStream in)
|
||||
{
|
||||
super (in);
|
||||
@@ -630,7 +636,14 @@ public class GdkPixbufDecoder extends gnu.java.awt.image.ImageDecoder
|
||||
boolean ignoreMetadata)
|
||||
{
|
||||
super.setInput(input, seekForwardOnly, ignoreMetadata);
|
||||
dec = new GdkPixbufDecoder((InputStream) getInput());
|
||||
Object get = getInput();
|
||||
if (get instanceof InputStream)
|
||||
dec = new GdkPixbufDecoder((InputStream) get);
|
||||
else if (get instanceof DataInput)
|
||||
dec = new GdkPixbufDecoder((DataInput) get);
|
||||
else
|
||||
throw new IllegalArgumentException("input object not supported: "
|
||||
+ get);
|
||||
}
|
||||
|
||||
public BufferedImage read(int imageIndex, ImageReadParam param)
|
||||
|
||||
@@ -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><class><Nameindex></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>
|
||||
* <element/>
|
||||
* </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>
|
||||
* <element>body</element>
|
||||
* </code>
|
||||
* by issuing <code>writeNoChildren("element", "body")</code> and <code>writeNoChildrenEnd()</code>.</p>
|
||||
*
|
||||
* <p>
|
||||
* Write
|
||||
* <code>
|
||||
* <element>
|
||||
* <child1/>
|
||||
* <child2/>
|
||||
* ...
|
||||
* <element/>
|
||||
* </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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -128,7 +128,7 @@ public class CRLFInputStream
|
||||
in.reset();
|
||||
if (i != -1)
|
||||
{
|
||||
l = in.read(b, off, i + 1); // read to CR
|
||||
l = in.read(b, off, (i + 1) - off); // read to CR
|
||||
in.read(); // skip LF
|
||||
b[i] = LF; // fix CR as LF
|
||||
}
|
||||
|
||||
@@ -38,8 +38,6 @@ exception statement from your version. */
|
||||
|
||||
package gnu.java.net;
|
||||
|
||||
import gnu.classpath.Configuration;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.DatagramPacket;
|
||||
import java.net.DatagramSocketImpl;
|
||||
@@ -64,20 +62,7 @@ import java.net.SocketException;
|
||||
*/
|
||||
public final class PlainDatagramSocketImpl extends DatagramSocketImpl
|
||||
{
|
||||
// Static initializer to load native library
|
||||
static
|
||||
{
|
||||
if (Configuration.INIT_LOAD_LIBRARY)
|
||||
{
|
||||
System.loadLibrary("javanet");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Option id for the IP_TTL (time to live) value.
|
||||
*/
|
||||
private static final int IP_TTL = 0x1E61; // 7777
|
||||
|
||||
|
||||
/**
|
||||
* This is the actual underlying file descriptor
|
||||
*/
|
||||
@@ -98,6 +83,7 @@ public final class PlainDatagramSocketImpl extends DatagramSocketImpl
|
||||
*/
|
||||
public PlainDatagramSocketImpl()
|
||||
{
|
||||
// Nothing to do here.
|
||||
}
|
||||
|
||||
protected void finalize() throws Throwable
|
||||
@@ -123,15 +109,48 @@ public final class PlainDatagramSocketImpl extends DatagramSocketImpl
|
||||
*
|
||||
* @exception SocketException If an error occurs
|
||||
*/
|
||||
protected synchronized native void bind(int port, InetAddress addr)
|
||||
throws SocketException;
|
||||
protected synchronized void bind(int port, InetAddress addr)
|
||||
throws SocketException
|
||||
{
|
||||
VMPlainDatagramSocketImpl.bind(this, port, addr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new datagram socket
|
||||
*
|
||||
* @exception SocketException If an error occurs
|
||||
*/
|
||||
protected synchronized native void create() throws SocketException;
|
||||
protected synchronized void create() throws SocketException
|
||||
{
|
||||
VMPlainDatagramSocketImpl.create(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Connects to the remote address and port specified as arguments.
|
||||
*
|
||||
* @param addr The remote address to connect to
|
||||
* @param port The remote port to connect to
|
||||
*
|
||||
* @exception SocketException If an error occurs
|
||||
*/
|
||||
protected void connect(InetAddress addr, int port) throws SocketException
|
||||
{
|
||||
VMPlainDatagramSocketImpl.connect(this, addr, port);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnects the socket.
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
protected void disconnect()
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
if (native_fd != -1)
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Time to Live value for the socket
|
||||
@@ -142,7 +161,7 @@ public final class PlainDatagramSocketImpl extends DatagramSocketImpl
|
||||
*/
|
||||
protected synchronized void setTimeToLive(int ttl) throws IOException
|
||||
{
|
||||
setOption(IP_TTL, new Integer(ttl));
|
||||
setOption(VMPlainDatagramSocketImpl.IP_TTL, new Integer(ttl));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -154,7 +173,7 @@ public final class PlainDatagramSocketImpl extends DatagramSocketImpl
|
||||
*/
|
||||
protected synchronized int getTimeToLive() throws IOException
|
||||
{
|
||||
Object obj = getOption(IP_TTL);
|
||||
Object obj = getOption(VMPlainDatagramSocketImpl.IP_TTL);
|
||||
|
||||
if (! (obj instanceof Integer))
|
||||
throw new IOException("Internal Error");
|
||||
@@ -162,20 +181,6 @@ public final class PlainDatagramSocketImpl extends DatagramSocketImpl
|
||||
return ((Integer) obj).intValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a packet of data to a remote host
|
||||
*
|
||||
* @param addr The address to send to
|
||||
* @param port The port to send to
|
||||
* @param buf The buffer to send
|
||||
* @param offset The offset of the data in the buffer to send
|
||||
* @param len The length of the data to send
|
||||
*
|
||||
* @exception IOException If an error occurs
|
||||
*/
|
||||
private native void sendto (InetAddress addr, int port,
|
||||
byte[] buf, int offset, int len)
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
* Sends a packet of data to a remote host
|
||||
@@ -186,12 +191,13 @@ public final class PlainDatagramSocketImpl extends DatagramSocketImpl
|
||||
*/
|
||||
protected void send(DatagramPacket packet) throws IOException
|
||||
{
|
||||
synchronized(SEND_LOCK)
|
||||
if (native_fd != -1)
|
||||
{
|
||||
sendto(packet.getAddress(), packet.getPort(), packet.getData(),
|
||||
packet.getOffset(), packet.getLength());
|
||||
}
|
||||
|
||||
synchronized(SEND_LOCK)
|
||||
{
|
||||
VMPlainDatagramSocketImpl.send(this, packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -206,18 +212,10 @@ public final class PlainDatagramSocketImpl extends DatagramSocketImpl
|
||||
{
|
||||
synchronized(RECEIVE_LOCK)
|
||||
{
|
||||
receive0(packet);
|
||||
VMPlainDatagramSocketImpl.receive(this, packet);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Native call to receive a UDP packet from the network
|
||||
*
|
||||
* @param packet The packet to fill in with the data received
|
||||
*
|
||||
* @exception IOException IOException If an error occurs
|
||||
*/
|
||||
private native void receive0(DatagramPacket packet) throws IOException;
|
||||
|
||||
/**
|
||||
* Sets the value of an option on the socket
|
||||
@@ -227,8 +225,11 @@ public final class PlainDatagramSocketImpl extends DatagramSocketImpl
|
||||
*
|
||||
* @exception SocketException If an error occurs
|
||||
*/
|
||||
public synchronized native void setOption(int option_id, Object val)
|
||||
throws SocketException;
|
||||
public synchronized void setOption(int option_id, Object val)
|
||||
throws SocketException
|
||||
{
|
||||
VMPlainDatagramSocketImpl.setOption(this, option_id, val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the value of an option on the socket
|
||||
@@ -239,13 +240,19 @@ public final class PlainDatagramSocketImpl extends DatagramSocketImpl
|
||||
*
|
||||
* @exception SocketException If an error occurs
|
||||
*/
|
||||
public synchronized native Object getOption(int option_id)
|
||||
throws SocketException;
|
||||
public synchronized Object getOption(int option_id)
|
||||
throws SocketException
|
||||
{
|
||||
return VMPlainDatagramSocketImpl.getOption(this, option_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the socket
|
||||
*/
|
||||
protected synchronized native void close();
|
||||
protected synchronized void close()
|
||||
{
|
||||
VMPlainDatagramSocketImpl.close(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Time to Live value for the socket
|
||||
@@ -282,7 +289,10 @@ public final class PlainDatagramSocketImpl extends DatagramSocketImpl
|
||||
*
|
||||
* @exception IOException If an error occurs
|
||||
*/
|
||||
protected synchronized native void join(InetAddress addr) throws IOException;
|
||||
protected synchronized void join(InetAddress addr) throws IOException
|
||||
{
|
||||
VMPlainDatagramSocketImpl.join(this,addr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Leaves a multicast group
|
||||
@@ -291,7 +301,10 @@ public final class PlainDatagramSocketImpl extends DatagramSocketImpl
|
||||
*
|
||||
* @exception IOException If an error occurs
|
||||
*/
|
||||
protected synchronized native void leave(InetAddress addr) throws IOException;
|
||||
protected synchronized void leave(InetAddress addr) throws IOException
|
||||
{
|
||||
VMPlainDatagramSocketImpl.leave(this, addr);
|
||||
}
|
||||
|
||||
/**
|
||||
* What does this method really do?
|
||||
@@ -308,14 +321,14 @@ public final class PlainDatagramSocketImpl extends DatagramSocketImpl
|
||||
}
|
||||
|
||||
public void joinGroup(SocketAddress address, NetworkInterface netIf)
|
||||
throws IOException
|
||||
{
|
||||
throw new InternalError
|
||||
("PlainDatagramSocketImpl::joinGroup is not implemented");
|
||||
VMPlainDatagramSocketImpl.joinGroup(this, address, netIf);
|
||||
}
|
||||
|
||||
public void leaveGroup(SocketAddress address, NetworkInterface netIf)
|
||||
throws IOException
|
||||
{
|
||||
throw new InternalError
|
||||
("PlainDatagramSocketImpl::leaveGroup is not implemented");
|
||||
VMPlainDatagramSocketImpl.leaveGroup(this, address, netIf);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,17 +39,13 @@ exception statement from your version. */
|
||||
|
||||
package gnu.java.net;
|
||||
|
||||
import gnu.classpath.Configuration;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketAddress;
|
||||
import java.net.SocketException;
|
||||
import java.net.SocketImpl;
|
||||
import java.net.SocketOptions;
|
||||
|
||||
/**
|
||||
* Written using on-line Java Platform 1.2 API Specification, as well
|
||||
@@ -69,14 +65,6 @@ import java.net.SocketOptions;
|
||||
*/
|
||||
public final class PlainSocketImpl extends SocketImpl
|
||||
{
|
||||
// Static initializer to load native library.
|
||||
static
|
||||
{
|
||||
if (Configuration.INIT_LOAD_LIBRARY)
|
||||
{
|
||||
System.loadLibrary("javanet");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The OS file handle representing the socket.
|
||||
@@ -125,10 +113,11 @@ public final class PlainSocketImpl extends SocketImpl
|
||||
}
|
||||
|
||||
/**
|
||||
* Default do nothing constructor
|
||||
* Default do nothing constructor.
|
||||
*/
|
||||
public PlainSocketImpl()
|
||||
{
|
||||
// Nothing to do here.
|
||||
}
|
||||
|
||||
protected void finalize() throws Throwable
|
||||
@@ -142,6 +131,7 @@ public final class PlainSocketImpl extends SocketImpl
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
// Nothing we can do about it.
|
||||
}
|
||||
}
|
||||
super.finalize();
|
||||
@@ -158,121 +148,111 @@ public final class PlainSocketImpl extends SocketImpl
|
||||
* Integer. The option_id parameter is one of the defined constants in
|
||||
* this interface.
|
||||
*
|
||||
* @param option_id The identifier of the option
|
||||
* @param val The value to set the option to
|
||||
* @param optionId The identifier of the option
|
||||
* @param value The value to set the option to
|
||||
*
|
||||
* @exception SocketException If an error occurs
|
||||
* @throws SocketException if an error occurs
|
||||
*/
|
||||
public native void setOption(int optID, Object value) throws SocketException;
|
||||
public void setOption(int optionId, Object value) throws SocketException
|
||||
{
|
||||
VMPlainSocketImpl.setOption(this, optionId, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current setting of the specified option. The Object returned
|
||||
* will be an Integer for options that have integer values. The option_id
|
||||
* is one of the defined constants in this interface.
|
||||
*
|
||||
* @param option_id The option identifier
|
||||
* @param optionId the option identifier
|
||||
*
|
||||
* @return The current value of the option
|
||||
* @return the current value of the option
|
||||
*
|
||||
* @exception SocketException If an error occurs
|
||||
* @throws SocketException if an error occurs
|
||||
*/
|
||||
public native Object getOption(int optID) throws SocketException;
|
||||
public Object getOption(int optionId) throws SocketException
|
||||
{
|
||||
return VMPlainSocketImpl.getOption(this, optionId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Flushes the input stream and closes it. If you read from the input stream
|
||||
* after calling this method a <code>IOException</code> will be thrown.
|
||||
*
|
||||
* @throws IOException if an error occurs
|
||||
*/
|
||||
public native void shutdownInput() throws IOException;
|
||||
public void shutdownInput() throws IOException
|
||||
{
|
||||
VMPlainSocketImpl.shutdownInput(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Flushes the output stream and closes it. If you write to the output stream
|
||||
* after calling this method a <code>IOException</code> will be thrown.
|
||||
*
|
||||
* @throws IOException if an error occurs
|
||||
*/
|
||||
public native void shutdownOutput() throws IOException;
|
||||
public void shutdownOutput() throws IOException
|
||||
{
|
||||
VMPlainSocketImpl.shutdownOutput(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new socket that is not bound to any local address/port and
|
||||
* is not connected to any remote address/port. This will be created as
|
||||
* a stream socket if the stream parameter is true, or a datagram socket
|
||||
* if the stream parameter is false.
|
||||
* is not connected to any remote address/port. The stream parameter will be
|
||||
* ignored since PlainSocketImpl always is a stream socket. Datagram sockets
|
||||
* are handled by PlainDatagramSocketImpl.
|
||||
*
|
||||
* @param stream true for a stream socket, false for a datagram socket
|
||||
* @param stream <code>true</code> for stream sockets, <code>false</code> for
|
||||
* datagram sockets
|
||||
*/
|
||||
protected synchronized native void create(boolean stream) throws IOException;
|
||||
protected synchronized void create(boolean stream) throws IOException
|
||||
{
|
||||
VMPlainSocketImpl.create(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Connects to the remote hostname and port specified as arguments.
|
||||
*
|
||||
* @param hostname The remote hostname to connect to
|
||||
* @param port The remote port to connect to
|
||||
* @param hostname the remote hostname to connect to
|
||||
* @param port the remote port to connect to
|
||||
*
|
||||
* @exception IOException If an error occurs
|
||||
* @throws IOException If an error occurs
|
||||
*/
|
||||
protected synchronized void connect(String host, int port) throws IOException
|
||||
protected synchronized void connect(String hostname, int port)
|
||||
throws IOException
|
||||
{
|
||||
connect(InetAddress.getByName(host), port);
|
||||
connect(InetAddress.getByName(hostname), port);
|
||||
}
|
||||
|
||||
/**
|
||||
* Connects to the remote address and port specified as arguments.
|
||||
*
|
||||
* @param addr The remote address to connect to
|
||||
* @param port The remote port to connect to
|
||||
* @param addr the remote address to connect to
|
||||
* @param port the remote port to connect to
|
||||
*
|
||||
* @exception IOException If an error occurs
|
||||
* @throws IOException If an error occurs
|
||||
*/
|
||||
protected native void connect(InetAddress addr, int port) throws IOException;
|
||||
protected void connect(InetAddress addr, int port) throws IOException
|
||||
{
|
||||
VMPlainSocketImpl.connect(this, addr, port);
|
||||
}
|
||||
|
||||
/**
|
||||
* Connects to the remote socket address with a specified timeout.
|
||||
*
|
||||
* @param timeout The timeout to use for this connect, 0 means infinite.
|
||||
* @param address the remote address to connect to
|
||||
* @param timeout the timeout to use for this connect, 0 means infinite.
|
||||
*
|
||||
* @exception IOException If an error occurs
|
||||
* @throws IOException If an error occurs
|
||||
*/
|
||||
protected synchronized void connect(SocketAddress address, int timeout) throws IOException
|
||||
protected synchronized void connect(SocketAddress address, int timeout)
|
||||
throws IOException
|
||||
{
|
||||
InetSocketAddress sockAddr = (InetSocketAddress) address;
|
||||
InetAddress addr = sockAddr.getAddress();
|
||||
|
||||
if (addr == null)
|
||||
throw new IllegalArgumentException("address is unresolved: " + sockAddr);
|
||||
|
||||
int port = sockAddr.getPort();
|
||||
|
||||
if (timeout < 0)
|
||||
throw new IllegalArgumentException("negative timeout");
|
||||
|
||||
Object oldTimeoutObj = null;
|
||||
|
||||
try
|
||||
{
|
||||
oldTimeoutObj = this.getOption (SocketOptions.SO_TIMEOUT);
|
||||
this.setOption (SocketOptions.SO_TIMEOUT, new Integer (timeout));
|
||||
connect (addr, port);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (oldTimeoutObj != null)
|
||||
this.setOption (SocketOptions.SO_TIMEOUT, oldTimeoutObj);
|
||||
}
|
||||
VMPlainSocketImpl.connect(this, address, timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* Binds to the specified port on the specified addr. Note that this addr
|
||||
* must represent a local IP address. **** How bind to INADDR_ANY? ****
|
||||
*
|
||||
* @param addr The address to bind to
|
||||
* @param port The port number to bind to
|
||||
* @param addr the address to bind to
|
||||
* @param port the port number to bind to
|
||||
*
|
||||
* @exception IOException If an error occurs
|
||||
* @throws IOException if an error occurs
|
||||
*/
|
||||
protected synchronized native void bind(InetAddress addr, int port)
|
||||
throws IOException;
|
||||
protected synchronized void bind(InetAddress addr, int port)
|
||||
throws IOException
|
||||
{
|
||||
VMPlainSocketImpl.bind(this, addr, port);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts listening for connections on a socket. The queuelen parameter
|
||||
@@ -282,10 +262,13 @@ public final class PlainSocketImpl extends SocketImpl
|
||||
*
|
||||
* @param queuelen The length of the pending connection queue
|
||||
*
|
||||
* @exception IOException If an error occurs
|
||||
* @throws IOException If an error occurs
|
||||
*/
|
||||
protected synchronized native void listen(int queuelen)
|
||||
throws IOException;
|
||||
protected synchronized void listen(int queuelen)
|
||||
throws IOException
|
||||
{
|
||||
VMPlainSocketImpl.listen(this, queuelen);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accepts a new connection on this socket and returns in in the
|
||||
@@ -293,33 +276,44 @@ public final class PlainSocketImpl extends SocketImpl
|
||||
*
|
||||
* @param impl The SocketImpl object to accept this connection.
|
||||
*/
|
||||
protected synchronized native void accept(SocketImpl impl)
|
||||
throws IOException;
|
||||
protected synchronized void accept(SocketImpl impl)
|
||||
throws IOException
|
||||
{
|
||||
VMPlainSocketImpl.accept(this, impl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of bytes that the caller can read from this socket
|
||||
* without blocking.
|
||||
*
|
||||
* @return The number of readable bytes before blocking
|
||||
* @return the number of readable bytes before blocking
|
||||
*
|
||||
* @exception IOException If an error occurs
|
||||
* @throws IOException if an error occurs
|
||||
*/
|
||||
protected native int available() throws IOException;
|
||||
protected int available() throws IOException
|
||||
{
|
||||
return VMPlainSocketImpl.available(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the socket. This will cause any InputStream or OutputStream
|
||||
* objects for this Socket to be closed as well.
|
||||
*
|
||||
* <p>
|
||||
* Note that if the SO_LINGER option is set on this socket, then the
|
||||
* operation could block.
|
||||
* </p>
|
||||
*
|
||||
* @exception IOException If an error occurs
|
||||
* @throws IOException if an error occurs
|
||||
*/
|
||||
protected native void close() throws IOException;
|
||||
protected void close() throws IOException
|
||||
{
|
||||
VMPlainSocketImpl.close(this);
|
||||
}
|
||||
|
||||
public void sendUrgentData(int data)
|
||||
{
|
||||
throw new InternalError ("PlainSocketImpl::sendUrgentData not implemented");
|
||||
VMPlainSocketImpl.sendUrgendData(this, data);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -327,22 +321,53 @@ public final class PlainSocketImpl extends SocketImpl
|
||||
* the connection. Reads up to len bytes of data into the buffer
|
||||
* buf starting at offset bytes into the buffer.
|
||||
*
|
||||
* @return The actual number of bytes read or -1 if end of stream.
|
||||
* @return the actual number of bytes read or -1 if end of stream.
|
||||
*
|
||||
* @exception IOException If an error occurs
|
||||
* @throws IOException if an error occurs
|
||||
*/
|
||||
protected native int read(byte[] buf, int offset, int len)
|
||||
throws IOException;
|
||||
protected int read(byte[] buf, int offset, int len)
|
||||
throws IOException
|
||||
{
|
||||
return VMPlainSocketImpl.read(this, buf, offset, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method used by SocketInputStream for reading data from
|
||||
* the connection. Reads and returns one byte of data.
|
||||
*
|
||||
* @return the read byte
|
||||
*
|
||||
* @throws IOException if an error occurs
|
||||
*/
|
||||
protected int read()
|
||||
throws IOException
|
||||
{
|
||||
return VMPlainSocketImpl.read(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method used by SocketOuputStream for writing data to
|
||||
* the connection. Writes up to len bytes of data from the buffer
|
||||
* buf starting at offset bytes into the buffer.
|
||||
*
|
||||
* @exception IOException If an error occurs
|
||||
* @throws IOException If an error occurs
|
||||
*/
|
||||
protected native void write(byte[] buf, int offset, int len)
|
||||
throws IOException;
|
||||
protected void write(byte[] buf, int offset, int len)
|
||||
throws IOException
|
||||
{
|
||||
VMPlainSocketImpl.write(this, buf, offset, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method used by SocketOuputStream for writing data to
|
||||
* the connection. Writes up one byte to the socket.
|
||||
*
|
||||
* @throws IOException If an error occurs
|
||||
*/
|
||||
protected void write(int data) throws IOException
|
||||
{
|
||||
VMPlainSocketImpl.write(this, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an InputStream object for reading from this socket. This will
|
||||
@@ -356,7 +381,7 @@ public final class PlainSocketImpl extends SocketImpl
|
||||
{
|
||||
if (in == null)
|
||||
in = new SocketInputStream();
|
||||
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
@@ -372,7 +397,7 @@ public final class PlainSocketImpl extends SocketImpl
|
||||
{
|
||||
if (out == null)
|
||||
out = new SocketOutputStream();
|
||||
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -380,7 +405,7 @@ public final class PlainSocketImpl extends SocketImpl
|
||||
* This class contains an implementation of <code>InputStream</code> for
|
||||
* sockets. It in an internal only class used by <code>PlainSocketImpl</code>.
|
||||
*
|
||||
* @author Nic Ferrier (nferrier@tapsellferrier.co.uk)
|
||||
* @author Nic Ferrier <nferrier@tapsellferrier.co.uk>
|
||||
*/
|
||||
final class SocketInputStream
|
||||
extends InputStream
|
||||
@@ -412,13 +437,7 @@ public final class PlainSocketImpl extends SocketImpl
|
||||
*/
|
||||
public int read() throws IOException
|
||||
{
|
||||
byte buf[] = new byte [1];
|
||||
int bytes_read = read(buf, 0, 1);
|
||||
|
||||
if (bytes_read == -1)
|
||||
return -1;
|
||||
|
||||
return buf[0] & 0xFF;
|
||||
return PlainSocketImpl.this.read();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -450,7 +469,7 @@ public final class PlainSocketImpl extends SocketImpl
|
||||
* <code>getOutputStream method</code>. It expects only to be used in that
|
||||
* context.
|
||||
*
|
||||
* @author Nic Ferrier (nferrier@tapsellferrier.co.uk)
|
||||
* @author Nic Ferrier <nferrier@tapsellferrier.co.uk>
|
||||
*/
|
||||
final class SocketOutputStream
|
||||
extends OutputStream
|
||||
@@ -476,8 +495,7 @@ public final class PlainSocketImpl extends SocketImpl
|
||||
*/
|
||||
public void write(int b) throws IOException
|
||||
{
|
||||
byte buf[] = { (byte) b };
|
||||
write(buf, 0, 1);
|
||||
PlainSocketImpl.this.write(b);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* FileChannelImpl.java --
|
||||
Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
|
||||
Copyright (C) 2002, 2004, 2005, 2006 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
@@ -301,8 +301,10 @@ public final class FileChannelImpl extends FileChannel
|
||||
else if (mode == MapMode.READ_WRITE || mode == MapMode.PRIVATE)
|
||||
{
|
||||
nmode = mode == MapMode.READ_WRITE ? '+' : 'c';
|
||||
if ((this.mode & (READ|WRITE)) != (READ|WRITE))
|
||||
if ((this.mode & WRITE) != WRITE)
|
||||
throw new NonWritableChannelException();
|
||||
if ((this.mode & READ) != READ)
|
||||
throw new NonReadableChannelException();
|
||||
}
|
||||
else
|
||||
throw new IllegalArgumentException ("mode: " + mode);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Provider.java --
|
||||
Copyright (C) 2002, 2005 Free Software Foundation, Inc.
|
||||
Copyright (C) 2002, 2005, 2006 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
@@ -39,6 +39,8 @@ package gnu.java.nio.charset;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.spi.CharsetProvider;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
@@ -47,6 +49,11 @@ import java.util.Iterator;
|
||||
* Charset provider for the required charsets. Used by
|
||||
* {@link Charset#charsetForName} and * {@link Charset#availableCharsets}.
|
||||
*
|
||||
* Note: This class is a privileged class, because it can be instantiated without
|
||||
* requiring the RuntimePermission("charsetProvider"). There is a check in
|
||||
* java.nio.charset.spi.CharsetProvider to skip the security check if the provider
|
||||
* is an instance of this class.
|
||||
*
|
||||
* @author Jesse Rosenstock
|
||||
* @author Robert Schuster (thebohemian@gmx.net)
|
||||
* @see Charset
|
||||
@@ -55,14 +62,6 @@ public final class Provider extends CharsetProvider
|
||||
{
|
||||
private static Provider singleton;
|
||||
|
||||
static
|
||||
{
|
||||
synchronized (Provider.class)
|
||||
{
|
||||
singleton = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Map from charset name to charset canonical name. The strings
|
||||
* are all lower-case to allow case-insensitive retrieval of
|
||||
@@ -232,8 +231,16 @@ public final class Provider extends CharsetProvider
|
||||
|
||||
public static synchronized Provider provider ()
|
||||
{
|
||||
// The default provider is safe to instantiate.
|
||||
if (singleton == null)
|
||||
singleton = new Provider ();
|
||||
singleton = (Provider) AccessController.doPrivileged
|
||||
(new PrivilegedAction()
|
||||
{
|
||||
public Object run()
|
||||
{
|
||||
return new Provider();
|
||||
}
|
||||
});
|
||||
return singleton;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* IconvProvider.java --
|
||||
Copyright (C) 2005 Free Software Foundation, Inc.
|
||||
Copyright (C) 2005, 2006 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
@@ -48,20 +48,17 @@ import java.util.Vector;
|
||||
/**
|
||||
* Charset provider wrapping iconv.
|
||||
*
|
||||
* Note: This class is a privileged class, because it can be instantiated without
|
||||
* requiring the RuntimePermission("charsetProvider"). There is a check in
|
||||
* java.nio.charset.spi.CharsetProvider to skip the security check if the provider
|
||||
* is an instance of this class.
|
||||
*
|
||||
* @author Sven de Marothy
|
||||
*/
|
||||
public final class IconvProvider extends CharsetProvider
|
||||
{
|
||||
private static IconvProvider singleton;
|
||||
|
||||
static
|
||||
{
|
||||
synchronized (IconvProvider.class)
|
||||
{
|
||||
singleton = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Declaring the construtor public may violate the use of singleton.
|
||||
// But it must be public so that an instance of this class can be
|
||||
// created by Class.newInstance(), which is the case when this provider is
|
||||
|
||||
@@ -47,6 +47,7 @@ import java.io.ObjectOutput;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.rmi.ConnectException;
|
||||
import java.rmi.Remote;
|
||||
import java.rmi.RemoteException;
|
||||
import java.rmi.server.ObjID;
|
||||
@@ -195,7 +196,7 @@ public RemoteCall newCall(RemoteObject obj, Operation[] op, int opnum, long hash
|
||||
conn = manager.getConnection();
|
||||
}
|
||||
catch (IOException e1) {
|
||||
throw new RemoteException("connection failed to host: " + manager.serverName, e1);
|
||||
throw new ConnectException("connection failed to host: " + manager.serverName, e1);
|
||||
}
|
||||
|
||||
//obj: useless?
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Engine -- generic getInstance method.
|
||||
Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
Copyright (C) 2003, 2006 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
@@ -130,7 +130,14 @@ public final class Engine
|
||||
Provider provider, Object[] initArgs)
|
||||
throws InvocationTargetException, NoSuchAlgorithmException
|
||||
{
|
||||
if (service == null || algorithm == null
|
||||
if (service != null)
|
||||
service = service.trim();
|
||||
|
||||
if (algorithm != null)
|
||||
algorithm = algorithm.trim();
|
||||
|
||||
if (service == null || service.length() == 0
|
||||
|| algorithm == null || algorithm.length() == 0
|
||||
|| provider == null || initArgs == null)
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
|
||||
@@ -0,0 +1,862 @@
|
||||
/* WeakIdentityHashMap -- an identity hashtable that keeps only weak references
|
||||
to its keys, allowing the virtual machine to reclaim them
|
||||
Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2006 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.util;
|
||||
|
||||
import java.lang.ref.ReferenceQueue;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.AbstractMap;
|
||||
import java.util.AbstractSet;
|
||||
import java.util.Collection;
|
||||
import java.util.ConcurrentModificationException;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* A weak hash map has only weak references to the key. This means that it
|
||||
* allows the key to be garbage collected if it is not used otherwise. If
|
||||
* this happens, the entry will eventually disappear from the map,
|
||||
* asynchronously.
|
||||
*
|
||||
* <p>Other strange behaviors to be aware of: The size of this map may
|
||||
* spontaneously shrink (even if you use a synchronized map and synchronize
|
||||
* it); it behaves as if another thread removes entries from this table
|
||||
* without synchronization. The entry set returned by <code>entrySet</code>
|
||||
* has similar phenomenons: The size may spontaneously shrink, or an
|
||||
* entry, that was in the set before, suddenly disappears.
|
||||
*
|
||||
* <p>A weak hash map is not meant for caches; use a normal map, with
|
||||
* soft references as values instead, or try {@link LinkedHashMap}.
|
||||
*
|
||||
* <p>The weak hash map supports null values and null keys. The null key
|
||||
* is never deleted from the map (except explictly of course). The
|
||||
* performance of the methods are similar to that of a hash map.
|
||||
*
|
||||
* <p>The value objects are strongly referenced by this table. So if a
|
||||
* value object maintains a strong reference to the key (either direct
|
||||
* or indirect) the key will never be removed from this map. According
|
||||
* to Sun, this problem may be fixed in a future release. It is not
|
||||
* possible to do it with the jdk 1.2 reference model, though.
|
||||
*
|
||||
* @author Jochen Hoenicke
|
||||
* @author Eric Blake (ebb9@email.byu.edu)
|
||||
* @author Jeroen Frijters
|
||||
*
|
||||
* @see HashMap
|
||||
* @see WeakReference
|
||||
* @see WeakHashMap
|
||||
* @see IdentityHashMap
|
||||
* @see LinkedHashMap
|
||||
*/
|
||||
public class WeakIdentityHashMap extends AbstractMap implements Map
|
||||
{
|
||||
/**
|
||||
* The default capacity for an instance of HashMap.
|
||||
* Sun's documentation mildly suggests that this (11) is the correct
|
||||
* value.
|
||||
*/
|
||||
private static final int DEFAULT_CAPACITY = 11;
|
||||
|
||||
/**
|
||||
* The default load factor of a HashMap.
|
||||
*/
|
||||
private static final float DEFAULT_LOAD_FACTOR = 0.75F;
|
||||
|
||||
/**
|
||||
* This is used instead of the key value <i>null</i>. It is needed
|
||||
* to distinguish between an null key and a removed key.
|
||||
*/
|
||||
// Package visible for use by nested classes.
|
||||
static final Object NULL_KEY = new Object();
|
||||
|
||||
/**
|
||||
* The reference queue where our buckets (which are WeakReferences) are
|
||||
* registered to.
|
||||
*/
|
||||
private final ReferenceQueue queue;
|
||||
|
||||
/**
|
||||
* The number of entries in this hash map.
|
||||
*/
|
||||
// Package visible for use by nested classes.
|
||||
int size;
|
||||
|
||||
/**
|
||||
* The load factor of this WeakIdentityHashMap. This is the maximum ratio of
|
||||
* size versus number of buckets. If size grows the number of buckets
|
||||
* must grow, too.
|
||||
*/
|
||||
private float loadFactor;
|
||||
|
||||
/**
|
||||
* The rounded product of the capacity (i.e. number of buckets) and
|
||||
* the load factor. When the number of elements exceeds the
|
||||
* threshold, the HashMap calls <code>rehash()</code>.
|
||||
*/
|
||||
private int threshold;
|
||||
|
||||
/**
|
||||
* The number of structural modifications. This is used by
|
||||
* iterators, to see if they should fail. This doesn't count
|
||||
* the silent key removals, when a weak reference is cleared
|
||||
* by the garbage collection. Instead the iterators must make
|
||||
* sure to have strong references to the entries they rely on.
|
||||
*/
|
||||
// Package visible for use by nested classes.
|
||||
int modCount;
|
||||
|
||||
/**
|
||||
* The entry set. There is only one instance per hashmap, namely
|
||||
* theEntrySet. Note that the entry set may silently shrink, just
|
||||
* like the WeakIdentityHashMap.
|
||||
*/
|
||||
private final class WeakEntrySet extends AbstractSet
|
||||
{
|
||||
/**
|
||||
* Non-private constructor to reduce bytecode emitted.
|
||||
*/
|
||||
WeakEntrySet()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size of this set.
|
||||
*
|
||||
* @return the set size
|
||||
*/
|
||||
public int size()
|
||||
{
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an iterator for all entries.
|
||||
*
|
||||
* @return an Entry iterator
|
||||
*/
|
||||
public Iterator iterator()
|
||||
{
|
||||
return new Iterator()
|
||||
{
|
||||
/**
|
||||
* The entry that was returned by the last
|
||||
* <code>next()</code> call. This is also the entry whose
|
||||
* bucket should be removed by the <code>remove</code> call. <br>
|
||||
*
|
||||
* It is null, if the <code>next</code> method wasn't
|
||||
* called yet, or if the entry was already removed. <br>
|
||||
*
|
||||
* Remembering this entry here will also prevent it from
|
||||
* being removed under us, since the entry strongly refers
|
||||
* to the key.
|
||||
*/
|
||||
WeakBucket.WeakEntry lastEntry;
|
||||
|
||||
/**
|
||||
* The entry that will be returned by the next
|
||||
* <code>next()</code> call. It is <code>null</code> if there
|
||||
* is no further entry. <br>
|
||||
*
|
||||
* Remembering this entry here will also prevent it from
|
||||
* being removed under us, since the entry strongly refers
|
||||
* to the key.
|
||||
*/
|
||||
WeakBucket.WeakEntry nextEntry = findNext(null);
|
||||
|
||||
/**
|
||||
* The known number of modification to the list, if it differs
|
||||
* from the real number, we throw an exception.
|
||||
*/
|
||||
int knownMod = modCount;
|
||||
|
||||
/**
|
||||
* Check the known number of modification to the number of
|
||||
* modifications of the table. If it differs from the real
|
||||
* number, we throw an exception.
|
||||
* @throws ConcurrentModificationException if the number
|
||||
* of modifications doesn't match.
|
||||
*/
|
||||
private void checkMod()
|
||||
{
|
||||
// This method will get inlined.
|
||||
cleanQueue();
|
||||
if (knownMod != modCount)
|
||||
throw new ConcurrentModificationException(knownMod + " != "
|
||||
+ modCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a strong reference to the next entry after
|
||||
* lastBucket.
|
||||
* @param lastEntry the previous bucket, or null if we should
|
||||
* get the first entry.
|
||||
* @return the next entry.
|
||||
*/
|
||||
private WeakBucket.WeakEntry findNext(WeakBucket.WeakEntry lastEntry)
|
||||
{
|
||||
int slot;
|
||||
WeakBucket nextBucket;
|
||||
if (lastEntry != null)
|
||||
{
|
||||
nextBucket = lastEntry.getBucket().next;
|
||||
slot = lastEntry.getBucket().slot;
|
||||
}
|
||||
else
|
||||
{
|
||||
nextBucket = buckets[0];
|
||||
slot = 0;
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
while (nextBucket != null)
|
||||
{
|
||||
WeakBucket.WeakEntry entry = nextBucket.getEntry();
|
||||
if (entry != null)
|
||||
// This is the next entry.
|
||||
return entry;
|
||||
|
||||
// Entry was cleared, try next.
|
||||
nextBucket = nextBucket.next;
|
||||
}
|
||||
|
||||
slot++;
|
||||
if (slot == buckets.length)
|
||||
// No more buckets, we are through.
|
||||
return null;
|
||||
|
||||
nextBucket = buckets[slot];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if there are more entries.
|
||||
* @return true, iff there are more elements.
|
||||
* @throws ConcurrentModificationException if the hash map was
|
||||
* modified.
|
||||
*/
|
||||
public boolean hasNext()
|
||||
{
|
||||
checkMod();
|
||||
return nextEntry != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next entry.
|
||||
* @return the next entry.
|
||||
* @throws ConcurrentModificationException if the hash map was
|
||||
* modified.
|
||||
* @throws NoSuchElementException if there is no entry.
|
||||
*/
|
||||
public Object next()
|
||||
{
|
||||
checkMod();
|
||||
if (nextEntry == null)
|
||||
throw new NoSuchElementException();
|
||||
lastEntry = nextEntry;
|
||||
nextEntry = findNext(lastEntry);
|
||||
return lastEntry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the last returned entry from this set. This will
|
||||
* also remove the bucket of the underlying weak hash map.
|
||||
* @throws ConcurrentModificationException if the hash map was
|
||||
* modified.
|
||||
* @throws IllegalStateException if <code>next()</code> was
|
||||
* never called or the element was already removed.
|
||||
*/
|
||||
public void remove()
|
||||
{
|
||||
checkMod();
|
||||
if (lastEntry == null)
|
||||
throw new IllegalStateException();
|
||||
modCount++;
|
||||
internalRemove(lastEntry.getBucket());
|
||||
lastEntry = null;
|
||||
knownMod++;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A bucket is a weak reference to the key, that contains a strong
|
||||
* reference to the value, a pointer to the next bucket and its slot
|
||||
* number. <br>
|
||||
*
|
||||
* It would be cleaner to have a WeakReference as field, instead of
|
||||
* extending it, but if a weak reference gets cleared, we only get
|
||||
* the weak reference (by queue.poll) and wouldn't know where to
|
||||
* look for this reference in the hashtable, to remove that entry.
|
||||
*
|
||||
* @author Jochen Hoenicke
|
||||
*/
|
||||
private static class WeakBucket extends WeakReference
|
||||
{
|
||||
/**
|
||||
* The value of this entry. The key is stored in the weak
|
||||
* reference that we extend.
|
||||
*/
|
||||
Object value;
|
||||
|
||||
/**
|
||||
* The next bucket describing another entry that uses the same
|
||||
* slot.
|
||||
*/
|
||||
WeakBucket next;
|
||||
|
||||
/**
|
||||
* The slot of this entry. This should be
|
||||
* <code>Math.abs(key.hashCode() % buckets.length)</code>.
|
||||
*
|
||||
* But since the key may be silently removed we have to remember
|
||||
* the slot number.
|
||||
*
|
||||
* If this bucket was removed the slot is -1. This marker will
|
||||
* prevent the bucket from being removed twice.
|
||||
*/
|
||||
int slot;
|
||||
|
||||
/**
|
||||
* Creates a new bucket for the given key/value pair and the specified
|
||||
* slot.
|
||||
* @param key the key
|
||||
* @param queue the queue the weak reference belongs to
|
||||
* @param value the value
|
||||
* @param slot the slot. This must match the slot where this bucket
|
||||
* will be enqueued.
|
||||
*/
|
||||
public WeakBucket(Object key, ReferenceQueue queue, Object value,
|
||||
int slot)
|
||||
{
|
||||
super(key, queue);
|
||||
this.value = value;
|
||||
this.slot = slot;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class gives the <code>Entry</code> representation of the
|
||||
* current bucket. It also keeps a strong reference to the
|
||||
* key; bad things may happen otherwise.
|
||||
*/
|
||||
class WeakEntry implements Map.Entry
|
||||
{
|
||||
/**
|
||||
* The strong ref to the key.
|
||||
*/
|
||||
Object key;
|
||||
|
||||
/**
|
||||
* Creates a new entry for the key.
|
||||
* @param key the key
|
||||
*/
|
||||
public WeakEntry(Object key)
|
||||
{
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the underlying bucket.
|
||||
* @return the owning bucket
|
||||
*/
|
||||
public WeakBucket getBucket()
|
||||
{
|
||||
return WeakBucket.this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the key.
|
||||
* @return the key
|
||||
*/
|
||||
public Object getKey()
|
||||
{
|
||||
return key == NULL_KEY ? null : key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value.
|
||||
* @return the value
|
||||
*/
|
||||
public Object getValue()
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* This changes the value. This change takes place in
|
||||
* the underlying hash map.
|
||||
* @param newVal the new value
|
||||
* @return the old value
|
||||
*/
|
||||
public Object setValue(Object newVal)
|
||||
{
|
||||
Object oldVal = value;
|
||||
value = newVal;
|
||||
return oldVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* The hashCode as specified in the Entry interface.
|
||||
* @return the hash code
|
||||
*/
|
||||
public int hashCode()
|
||||
{
|
||||
return System.identityHashCode(key)
|
||||
^ (value == null ? 0 : value.hashCode());
|
||||
}
|
||||
|
||||
/**
|
||||
* The equals method as specified in the Entry interface.
|
||||
* @param o the object to compare to
|
||||
* @return true iff o represents the same key/value pair
|
||||
*/
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
if (o instanceof Map.Entry)
|
||||
{
|
||||
Map.Entry e = (Map.Entry) o;
|
||||
return getKey() == e.getKey()
|
||||
&& (value == null ? e.getValue() == null
|
||||
: value.equals(e.getValue()));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return getKey() + "=" + value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This returns the entry stored in this bucket, or null, if the
|
||||
* bucket got cleared in the mean time.
|
||||
* @return the Entry for this bucket, if it exists
|
||||
*/
|
||||
WeakEntry getEntry()
|
||||
{
|
||||
final Object key = this.get();
|
||||
if (key == null)
|
||||
return null;
|
||||
return new WeakEntry(key);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The entry set returned by <code>entrySet()</code>.
|
||||
*/
|
||||
private final WeakEntrySet theEntrySet;
|
||||
|
||||
/**
|
||||
* The hash buckets. These are linked lists. Package visible for use in
|
||||
* nested classes.
|
||||
*/
|
||||
WeakBucket[] buckets;
|
||||
|
||||
/**
|
||||
* Creates a new weak hash map with default load factor and default
|
||||
* capacity.
|
||||
*/
|
||||
public WeakIdentityHashMap()
|
||||
{
|
||||
this(DEFAULT_CAPACITY, DEFAULT_LOAD_FACTOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new weak hash map with default load factor and the given
|
||||
* capacity.
|
||||
* @param initialCapacity the initial capacity
|
||||
* @throws IllegalArgumentException if initialCapacity is negative
|
||||
*/
|
||||
public WeakIdentityHashMap(int initialCapacity)
|
||||
{
|
||||
this(initialCapacity, DEFAULT_LOAD_FACTOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new weak hash map with the given initial capacity and
|
||||
* load factor.
|
||||
* @param initialCapacity the initial capacity.
|
||||
* @param loadFactor the load factor (see class description of HashMap).
|
||||
* @throws IllegalArgumentException if initialCapacity is negative, or
|
||||
* loadFactor is non-positive
|
||||
*/
|
||||
public WeakIdentityHashMap(int initialCapacity, float loadFactor)
|
||||
{
|
||||
// Check loadFactor for NaN as well.
|
||||
if (initialCapacity < 0 || ! (loadFactor > 0))
|
||||
throw new IllegalArgumentException();
|
||||
if (initialCapacity == 0)
|
||||
initialCapacity = 1;
|
||||
this.loadFactor = loadFactor;
|
||||
threshold = (int) (initialCapacity * loadFactor);
|
||||
theEntrySet = new WeakEntrySet();
|
||||
queue = new ReferenceQueue();
|
||||
buckets = new WeakBucket[initialCapacity];
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new WeakIdentityHashMap with the same mappings as the given map.
|
||||
* The WeakIdentityHashMap has a default load factor of 0.75.
|
||||
*
|
||||
* @param m the map to copy
|
||||
* @throws NullPointerException if m is null
|
||||
* @since 1.3
|
||||
*/
|
||||
public WeakIdentityHashMap(Map m)
|
||||
{
|
||||
this(m.size(), DEFAULT_LOAD_FACTOR);
|
||||
putAll(m);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simply hashes a non-null Object to its array index.
|
||||
* @param key the key to hash
|
||||
* @return its slot number
|
||||
*/
|
||||
private int hash(Object key)
|
||||
{
|
||||
return Math.abs(System.identityHashCode(key) % buckets.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleans the reference queue. This will poll all references (which
|
||||
* are WeakBuckets) from the queue and remove them from this map.
|
||||
* This will not change modCount, even if it modifies the map. The
|
||||
* iterators have to make sure that nothing bad happens. <br>
|
||||
*
|
||||
* Currently the iterator maintains a strong reference to the key, so
|
||||
* that is no problem.
|
||||
*/
|
||||
// Package visible for use by nested classes.
|
||||
void cleanQueue()
|
||||
{
|
||||
Object bucket = queue.poll();
|
||||
while (bucket != null)
|
||||
{
|
||||
internalRemove((WeakBucket) bucket);
|
||||
bucket = queue.poll();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Rehashes this hashtable. This will be called by the
|
||||
* <code>add()</code> method if the size grows beyond the threshold.
|
||||
* It will grow the bucket size at least by factor two and allocates
|
||||
* new buckets.
|
||||
*/
|
||||
private void rehash()
|
||||
{
|
||||
WeakBucket[] oldBuckets = buckets;
|
||||
int newsize = buckets.length * 2 + 1; // XXX should be prime.
|
||||
threshold = (int) (newsize * loadFactor);
|
||||
buckets = new WeakBucket[newsize];
|
||||
|
||||
// Now we have to insert the buckets again.
|
||||
for (int i = 0; i < oldBuckets.length; i++)
|
||||
{
|
||||
WeakBucket bucket = oldBuckets[i];
|
||||
WeakBucket nextBucket;
|
||||
while (bucket != null)
|
||||
{
|
||||
nextBucket = bucket.next;
|
||||
|
||||
Object key = bucket.get();
|
||||
if (key == null)
|
||||
{
|
||||
// This bucket should be removed; it is probably
|
||||
// already on the reference queue. We don't insert it
|
||||
// at all, and mark it as cleared.
|
||||
bucket.slot = -1;
|
||||
size--;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Add this bucket to its new slot.
|
||||
int slot = hash(key);
|
||||
bucket.slot = slot;
|
||||
bucket.next = buckets[slot];
|
||||
buckets[slot] = bucket;
|
||||
}
|
||||
bucket = nextBucket;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the entry corresponding to key. Since it returns an Entry
|
||||
* it will also prevent the key from being removed under us.
|
||||
* @param key the key, may be null
|
||||
* @return The WeakBucket.WeakEntry or null, if the key wasn't found.
|
||||
*/
|
||||
private WeakBucket.WeakEntry internalGet(Object key)
|
||||
{
|
||||
if (key == null)
|
||||
key = NULL_KEY;
|
||||
int slot = hash(key);
|
||||
WeakBucket bucket = buckets[slot];
|
||||
while (bucket != null)
|
||||
{
|
||||
WeakBucket.WeakEntry entry = bucket.getEntry();
|
||||
if (entry != null && key == entry.key)
|
||||
return entry;
|
||||
|
||||
bucket = bucket.next;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new key/value pair to the hash map.
|
||||
* @param key the key. This mustn't exists in the map. It may be null.
|
||||
* @param value the value.
|
||||
*/
|
||||
private void internalAdd(Object key, Object value)
|
||||
{
|
||||
if (key == null)
|
||||
key = NULL_KEY;
|
||||
int slot = hash(key);
|
||||
WeakBucket bucket = new WeakBucket(key, queue, value, slot);
|
||||
bucket.next = buckets[slot];
|
||||
buckets[slot] = bucket;
|
||||
size++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a bucket from this hash map, if it wasn't removed before
|
||||
* (e.g. one time through rehashing and one time through reference queue).
|
||||
* Package visible for use in nested classes.
|
||||
*
|
||||
* @param bucket the bucket to remove.
|
||||
*/
|
||||
void internalRemove(WeakBucket bucket)
|
||||
{
|
||||
int slot = bucket.slot;
|
||||
if (slot == -1)
|
||||
// This bucket was already removed.
|
||||
return;
|
||||
|
||||
// Mark the bucket as removed. This is necessary, since the
|
||||
// bucket may be enqueued later by the garbage collection, and
|
||||
// internalRemove will be called a second time.
|
||||
bucket.slot = -1;
|
||||
|
||||
WeakBucket prev = null;
|
||||
WeakBucket next = buckets[slot];
|
||||
while (next != bucket)
|
||||
{
|
||||
if (next == null)
|
||||
throw new InternalError("WeakIdentityHashMap in inconsistent state");
|
||||
prev = next;
|
||||
next = prev.next;
|
||||
}
|
||||
if (prev == null)
|
||||
buckets[slot] = bucket.next;
|
||||
else
|
||||
prev.next = bucket.next;
|
||||
|
||||
size--;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size of this hash map. Note that the size() may shrink
|
||||
* spontaneously, if the some of the keys were only weakly reachable.
|
||||
* @return the number of entries in this hash map.
|
||||
*/
|
||||
public int size()
|
||||
{
|
||||
cleanQueue();
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells if the map is empty. Note that the result may change
|
||||
* spontanously, if all of the keys were only weakly reachable.
|
||||
* @return true, iff the map is empty.
|
||||
*/
|
||||
public boolean isEmpty()
|
||||
{
|
||||
cleanQueue();
|
||||
return size == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells if the map contains the given key. Note that the result
|
||||
* may change spontanously, if the key was only weakly
|
||||
* reachable.
|
||||
* @param key the key to look for
|
||||
* @return true, iff the map contains an entry for the given key.
|
||||
*/
|
||||
public boolean containsKey(Object key)
|
||||
{
|
||||
cleanQueue();
|
||||
return internalGet(key) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value the key is mapped to.
|
||||
* @return the value the key was mapped to. It returns null if
|
||||
* the key wasn't in this map, or if the mapped value was
|
||||
* explicitly set to null.
|
||||
*/
|
||||
public Object get(Object key)
|
||||
{
|
||||
cleanQueue();
|
||||
WeakBucket.WeakEntry entry = internalGet(key);
|
||||
return entry == null ? null : entry.getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new key/value mapping to this map.
|
||||
* @param key the key, may be null
|
||||
* @param value the value, may be null
|
||||
* @return the value the key was mapped to previously. It returns
|
||||
* null if the key wasn't in this map, or if the mapped value
|
||||
* was explicitly set to null.
|
||||
*/
|
||||
public Object put(Object key, Object value)
|
||||
{
|
||||
cleanQueue();
|
||||
WeakBucket.WeakEntry entry = internalGet(key);
|
||||
if (entry != null)
|
||||
return entry.setValue(value);
|
||||
|
||||
modCount++;
|
||||
if (size >= threshold)
|
||||
rehash();
|
||||
|
||||
internalAdd(key, value);
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the key and the corresponding value from this map.
|
||||
* @param key the key. This may be null.
|
||||
* @return the value the key was mapped to previously. It returns
|
||||
* null if the key wasn't in this map, or if the mapped value was
|
||||
* explicitly set to null.
|
||||
*/
|
||||
public Object remove(Object key)
|
||||
{
|
||||
cleanQueue();
|
||||
WeakBucket.WeakEntry entry = internalGet(key);
|
||||
if (entry == null)
|
||||
return null;
|
||||
|
||||
modCount++;
|
||||
internalRemove(entry.getBucket());
|
||||
return entry.getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a set representation of the entries in this map. This
|
||||
* set will not have strong references to the keys, so they can be
|
||||
* silently removed. The returned set has therefore the same
|
||||
* strange behaviour (shrinking size(), disappearing entries) as
|
||||
* this weak hash map.
|
||||
* @return a set representation of the entries.
|
||||
*/
|
||||
public Set entrySet()
|
||||
{
|
||||
cleanQueue();
|
||||
return theEntrySet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all entries from this map.
|
||||
*/
|
||||
public void clear()
|
||||
{
|
||||
super.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the map contains at least one key which points to
|
||||
* the specified object as a value. Note that the result
|
||||
* may change spontanously, if its key was only weakly reachable.
|
||||
* @param value the value to search for
|
||||
* @return true if it is found in the set.
|
||||
*/
|
||||
public boolean containsValue(Object value)
|
||||
{
|
||||
cleanQueue();
|
||||
return super.containsValue(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a set representation of the keys in this map. This
|
||||
* set will not have strong references to the keys, so they can be
|
||||
* silently removed. The returned set has therefore the same
|
||||
* strange behaviour (shrinking size(), disappearing entries) as
|
||||
* this weak hash map.
|
||||
* @return a set representation of the keys.
|
||||
*/
|
||||
public Set keySet()
|
||||
{
|
||||
cleanQueue();
|
||||
return super.keySet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts all of the mappings from the given map into this one. If the
|
||||
* key already exists in this map, its value is replaced.
|
||||
* @param m the map to copy in
|
||||
*/
|
||||
public void putAll(Map m)
|
||||
{
|
||||
super.putAll(m);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a collection representation of the values in this map. This
|
||||
* collection will not have strong references to the keys, so mappings
|
||||
* can be silently removed. The returned collection has therefore the same
|
||||
* strange behaviour (shrinking size(), disappearing entries) as
|
||||
* this weak hash map.
|
||||
* @return a collection representation of the values.
|
||||
*/
|
||||
public Collection values()
|
||||
{
|
||||
cleanQueue();
|
||||
return super.values();
|
||||
}
|
||||
} // class WeakIdentityHashMap
|
||||
Reference in New Issue
Block a user