classpath
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

please test: XMLEncoder patch


From: Robert Schuster
Subject: please test: XMLEncoder patch
Date: Tue, 20 Dec 2005 02:34:56 +0100
User-agent: Mozilla/5.0 (X11; U; Linux i686; de-AT; rv:1.7.12) Gecko/20051208

Hi.

Here is another preview of the implementation of an IMHO underspecified API
called java.beans.[XML]Encoder. It contains these classes and everything that is
related like PersistenceDelegate, DefaultPersistenceDelegate and Expression as
well as some 'secret' (= not officially listed) set of PersistenceDelegate
implementations for lists and maps.

By poking around with Encoder.getPersistenceDelegate(Class) I know that more
implementations are needed for AWT and Swing classes but the encoder is already
in a useable state now and I can fix this easily at a later time.

What I am interested in is whether your real world stuff works and if not how it
breaks. The attached patch is *not* cleaned up. It contains useful debugging
output which I need to track down your problem. If you have a situation where my
encoder generates wrong or malformed output or just throws unfriendly exceptions
I need the following from you:
- the object graph (and any PersistenceDelegates you may have implemented 
yourself)
- the output which is printed to (System.err and System.out)

Known issues:
- instead of generating a <property> element it makes an ordinary method call
(AFAIK this is functionally equivalent)
- it creates superfluous id (again this is not harming the general
functionality. however I am going to fix that.)

Other things:
If you take a deeper look at the code you probably end up asking yourself why
stuff is done this way. I can only say that I
- did what the reference implementation's API doc said
- tried to replicate the reference implementation's behavior which it had shown
in my test cases

What I am planning to do now:
- hope that people test this code
- convert my development work test cases into mauve tests
- hope that people really test this code
- fix the id issue
- hope that people test the code and send me some hints about the issues
- find out more about the AWT/Swing delegates and implement them
- add documentation to the internal classes and do some method renaming every
there and then

I am pretty sure that a later version of this patch will end up in 0.20. With
your help I can make sure that the XMLEncoder will work mostly correct in that
GNU Classpath release. :)

Happy hacking!

cya
Robert
? gnu/java/beans/encoder/ListPersistenceDelegate.java
? gnu/java/beans/encoder/MapPersistenceDelegate.java
? gnu/java/beans/encoder/ObjectId.java
? gnu/java/beans/encoder/Root.java
? gnu/java/beans/encoder/StAXWriter.java
? gnu/java/beans/encoder/Writer.java
Index: java/beans/DefaultPersistenceDelegate.java
===================================================================
RCS file: java/beans/DefaultPersistenceDelegate.java
diff -N java/beans/DefaultPersistenceDelegate.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ java/beans/DefaultPersistenceDelegate.java  20 Dec 2005 00:31:55 -0000
@@ -0,0 +1,187 @@
+/* DefaultPersistenceDelegate.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 java.beans;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+public class DefaultPersistenceDelegate extends PersistenceDelegate
+{
+
+  private String[] constructorPropertyNames;
+
+  public DefaultPersistenceDelegate()
+  {
+  }
+
+  public DefaultPersistenceDelegate(String[] constructorPropertyNames)
+  {
+    this.constructorPropertyNames = constructorPropertyNames;
+  }
+
+  protected boolean mutatesTo(Object oldInstance, Object newInstance)
+  {
+    try
+      {
+
+        return (constructorPropertyNames != null
+                && constructorPropertyNames.length > 0 && 
oldInstance.getClass().getDeclaredMethod(
+                                                                               
                    "equals",
+                                                                               
                    new Class[] { Object.class }) != null) ? 
oldInstance.equals(newInstance)
+                                                                               
                                                          : super.mutatesTo(
+                                                                               
                                                                            
oldInstance,
+                                                                               
                                                                            
newInstance);
+      }
+    catch (NoSuchMethodException nsme)
+      {
+        return super.mutatesTo(oldInstance, newInstance);
+      }
+  }
+
+  protected Expression instantiate(Object oldInstance, Encoder out)
+  {
+    Object[] args = null;
+
+    try
+      {
+        // If there are property names in the array, then we create
+        // a corresponding argument array and store every
+        // argument in it. To retrieve an argument object we have
+        // dig up the right property in the bean class' BeanInfo
+        // object.
+        // This is so costly in terms of execution time I better
+        // not think twice about it ...
+        if (constructorPropertyNames != null)
+          {
+            args = new Object[constructorPropertyNames.length];
+
+            // Look up the properties of oldInstance's class to find matches 
for
+            // the
+            // names given in the constructor.
+            PropertyDescriptor[] propertyDescs = Introspector.getBeanInfo(
+                                                                          
oldInstance.getClass()).getPropertyDescriptors();
+
+            for (int i = 0; i < constructorPropertyNames.length; i++)
+              {
+                // Scan the property descriptions for a matching name.
+                for (int j = 0; j < propertyDescs.length; j++)
+                  {
+                    if (propertyDescs[i].getName().equals(
+                                                          
constructorPropertyNames[i]))
+                      {
+                        Method readMethod = propertyDescs[i].getReadMethod();
+
+                        args[i] = readMethod.invoke(oldInstance, null);
+                      }
+                  }
+              }
+          }
+
+      }
+    catch (IllegalAccessException iae)
+      {
+        out.getExceptionListener().exceptionThrown(iae);
+      }
+    catch (IllegalArgumentException iarge)
+      {
+        out.getExceptionListener().exceptionThrown(iarge);
+      }
+    catch (InvocationTargetException ite)
+      {
+        out.getExceptionListener().exceptionThrown(ite);
+      }
+    catch (IntrospectionException ie)
+      {
+        out.getExceptionListener().exceptionThrown(ie);
+      }
+
+    return new Expression(oldInstance, oldInstance.getClass(), "new", args);
+  }
+
+  protected void initialize(Class type, Object oldInstance, Object newInstance,
+                            Encoder out)
+  {
+    try
+      {
+        PropertyDescriptor[] propertyDescs = Introspector.getBeanInfo(
+                                                                      
oldInstance.getClass()).getPropertyDescriptors();
+
+        for (int i = 0; i < propertyDescs.length; i++)
+          {
+            if (propertyDescs[i] instanceof IndexedPropertyDescriptor)
+              {
+                /* TODO: handle IndexedProperties - use a TestBean again  
+                IndexedPropertyDescriptor indexed = 
(IndexedPropertyDescriptor) propertyDescs[i]
+                                                                               
               
+                Method readMethod = indexed.getIndexedReadMethod();
+                Method writeMethod = indexed.getIndexedWriteMethod();
+
+                for (int j=0;j<indexed.)
+                  */
+              }
+            else
+              {
+                Method readMethod = propertyDescs[i].getReadMethod();
+                Method writeMethod = propertyDescs[i].getWriteMethod();
+
+                if (readMethod != null && writeMethod != null)
+                  {
+                    Object oldValue = readMethod.invoke(oldInstance, null);
+
+                    out.writeStatement(new Statement(oldInstance,
+                                                     writeMethod.getName(),
+                                                     new Object[] { oldValue 
}));
+                  }
+              }
+          }
+      }
+    catch (IntrospectionException ie)
+      {
+        out.getExceptionListener().exceptionThrown(ie);
+      }
+    catch (IllegalAccessException iae)
+      {
+        out.getExceptionListener().exceptionThrown(iae);
+      }
+    catch (InvocationTargetException ite)
+      {
+        out.getExceptionListener().exceptionThrown(ite);
+      }
+  }
+}
Index: java/beans/Encoder.java
===================================================================
RCS file: java/beans/Encoder.java
diff -N java/beans/Encoder.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ java/beans/Encoder.java     20 Dec 2005 00:31:55 -0000
@@ -0,0 +1,418 @@
+/* Encoder.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 java.beans;
+
+import gnu.java.beans.encoder.ArrayPersistenceDelegate;
+import gnu.java.beans.encoder.ClassPersistenceDelegate;
+import gnu.java.beans.encoder.ListPersistenceDelegate;
+import gnu.java.beans.encoder.MapPersistenceDelegate;
+import gnu.java.beans.encoder.PrimitivePersistenceDelegate;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.SortedMap;
+import java.util.TreeMap;
+import java.util.Vector;
+
+public class Encoder
+{
+
+  /**
+   * An internal DefaultPersistenceDelegate instance that is used for every
+   * class that does not a have a special special PersistenceDelegate.
+   */
+  private static PersistenceDelegate defaultPersistenceDelegate;
+
+  private static PersistenceDelegate fakePersistenceDelegate;
+
+  /**
+   * Stores the relation Class->PersistenceDelegate.
+   */
+  private static HashMap delegates = new HashMap();
+
+  /**
+   * Stores the relation oldInstance->newInstance
+   */
+  private HashMap candidates = new HashMap();
+
+  private ExceptionListener exceptionListener;
+
+  /**
+   * A simple number that is used to restrict the access to writeExpression and
+   * writeStatement. The rule is that both methods should only be used when an
+   * object is written to the stream (= writeObject). Therefore accessCounter 
is
+   * incremented just before the call to writeObject and decremented 
afterwards.
+   * Then writeStatement and writeExpression allow execution only if
+   * accessCounter is bigger than zero.
+   */
+  private int accessCounter = 0;
+
+  public Encoder()
+  {
+    setupDefaultPersistenceDelegates();
+
+    setExceptionListener(null);
+  }
+
+  /**
+   * Sets up a bunch of address@hidden PersistenceDelegate} instances which 
are needed
+   * for the basic working of a address@hidden Encoder}s.
+   */
+  private static void setupDefaultPersistenceDelegates()
+  {
+    synchronized (delegates)
+      {
+        if (defaultPersistenceDelegate != null)
+          return;
+
+        delegates.put(Class.class, new ClassPersistenceDelegate());
+
+        PersistenceDelegate pd = new PrimitivePersistenceDelegate();
+        delegates.put(Boolean.class, pd);
+        delegates.put(Byte.class, pd);
+        delegates.put(Short.class, pd);
+        delegates.put(Integer.class, pd);
+        delegates.put(Long.class, pd);
+        delegates.put(Float.class, pd);
+        delegates.put(Double.class, pd);
+
+        delegates.put(Object[].class, new ArrayPersistenceDelegate());
+
+        pd = new ListPersistenceDelegate();
+        delegates.put(ArrayList.class, pd);
+        delegates.put(LinkedList.class, pd);
+        delegates.put(Vector.class, pd);
+        
+        pd = new MapPersistenceDelegate();
+        delegates.put(HashMap.class, pd);
+        delegates.put(TreeMap.class, pd);
+        delegates.put(java.util.Hashtable.class, pd);
+        delegates.put(java.util.IdentityHashMap.class, pd);
+        
+        delegates.put(java.util.LinkedHashMap.class, pd);
+        delegates.put(java.util.Properties.class, pd);
+
+        delegates.put(java.awt.RenderingHints.class, pd);
+        delegates.put(java.util.WeakHashMap.class, pd);
+        delegates.put(javax.swing.UIDefaults.class, pd);
+        
+        // TODO: These classes need to be implemented first
+        //delegates.put(java.security.AuthProvider.class, pd);
+        //delegates.put(java.util.concurrent.ConcurrentHashMap.class, pd);
+        //delegates.put(java.util.EnumMap.class, pd);
+        //delegates.put(javax.management.openmbean.TabularDataSupport.class, 
pd);
+        
+        defaultPersistenceDelegate = new DefaultPersistenceDelegate();
+        delegates.put(Object.class, defaultPersistenceDelegate);
+
+        // Creates a PersistenceDelegate implementation which is
+        // returned for 'null'. In practice this instance is
+        // not used in any way and is just here to be compatible
+        // with the reference implementation which returns a
+        // similar instance when calling getPersistenceDelegate(null) .
+        fakePersistenceDelegate = new PersistenceDelegate()
+        {
+          protected Expression instantiate(Object o, Encoder e)
+          {
+            return null;
+          }
+        };
+
+      }
+  }
+
+  protected void writeObject(Object o)
+  {
+    // 'null' has no PersistenceDelegate and will not
+    // create an Expression which has to be cloned.
+    // However subclasses should be aware that writeObject
+    // may be called with a 'null' argument and should
+    // write the proper representation of it.
+    if (o == null)
+      return;
+
+    PersistenceDelegate pd = getPersistenceDelegate(o.getClass());
+
+    accessCounter++;
+    pd.writeObject(o, this);
+    accessCounter--;
+  }
+
+  /**
+   * Sets the address@hidden ExceptionListener} instance to be used for 
reporting
+   * recorable exceptions in the instantiation and initialization sequence. If
+   * the argument is <code>null</code> a default instance will be used that
+   * prints the thrown exception to <code>System.err</code>.
+   */
+  public void setExceptionListener(ExceptionListener listener)
+  {
+    exceptionListener = (listener != null) ? listener : new ExceptionListener()
+    {
+      public void exceptionThrown(Exception e)
+      {
+        System.err.println("exception thrown: " + e);
+        e.printStackTrace();
+      }
+    };
+  }
+
+  /**
+   * Returns the currently active address@hidden ExceptionListener} instance.
+   */
+  public ExceptionListener getExceptionListener()
+  {
+    return exceptionListener;
+  }
+
+  public PersistenceDelegate getPersistenceDelegate(Class type)
+  {
+    // This is not specified but the JDK behaves like this.
+    if (type == null)
+      return fakePersistenceDelegate;
+
+    // Treats all array classes in the same way and assigns
+    // them a shared PersistenceDelegate implementation tailored
+    // for array instantation and initialization.
+    if (type.isArray())
+      return (PersistenceDelegate) delegates.get(Object[].class);
+
+    PersistenceDelegate pd = (PersistenceDelegate) delegates.get(type);
+
+    return (pd != null) ? pd : (PersistenceDelegate) 
defaultPersistenceDelegate;
+  }
+
+  /**
+   * Sets the address@hidden PersistenceDelegate} instance for the given class.
+   * <p>
+   * Note: Throws a <code>NullPointerException</code> if the argument is
+   * <code>null</code>.
+   * </p>
+   * <p>
+   * Note: Silently ignores PersistenceDelegates for Array types and primitive
+   * wrapper classes.
+   * </p>
+   * <p>
+   * Note: Although this method is not declared <code>static</code> changes to
+   * the address@hidden PersistenceDelegate}s affect <strong>all</strong>
+   * address@hidden Encoder} instances. <strong>In this 
implementation</strong> the
+   * access is thread safe.
+   * </p>
+   */
+  public void setPersistenceDelegate(Class type, PersistenceDelegate delegate)
+  {
+    // If the argument is null this will cause a NullPointerException
+    // which is expected behavior.
+
+    // This makes custom PDs for array and primitive types impossible but
+    // this is how the JDK behaves.
+    if (type.isArray() || type.isPrimitive())
+      return;
+
+    synchronized (delegates)
+      {
+        delegates.put(type, delegate);
+      }
+
+  }
+
+  public Object remove(Object oldInstance)
+  {
+    return candidates.remove(oldInstance);
+  }
+
+  /**
+   * Returns the replacement object which has been created by the encoder 
during
+   * the instantiation sequence or <code>null</code> if the object has not
+   * been processed yet.
+   * <p>
+   * Note: The <code>String</code> class acts as an endpoint for the
+   * inherently recursive algorithm of the address@hidden Encoder}. Therefore 
instances
+   * of <code>String</code> will always be returned by this method. In other
+   * words the assertion: <code>
+   * assert (anyEncoder.get(anyString) == anyString)
+   * </code<
+   * will always hold.</p>
+   *
+   * <p>Note: If <code>null</code> is requested, the result will
+   * always be <code>null</code>.</p>
+   */
+  public Object get(Object oldInstance)
+  {
+    // String instances are handled in a special way.
+    // No one knows why this is not officially specified
+    // because this is a rather important design decision.
+    return (oldInstance == null) ? null : 
+             (oldInstance.getClass() == String.class) ?
+               oldInstance : candidates.get(oldInstance);
+  }
+
+  /**
+   * <p>
+   * Note: If you call this method not from within an object instantiation and
+   * initialization sequence it will be silently ignored.
+   * </p>
+   */
+  public void writeStatement(Statement stmt)
+  {
+    // Silently ignore out of bounds calls.
+    if (accessCounter <= 0)
+      return;
+
+    Object target = stmt.getTarget();
+
+    Object newTarget = get(target);
+    if (newTarget == null)
+      {
+        writeObject(target);
+        newTarget = get(target);
+      }
+
+    Object[] args = stmt.getArguments();
+    Object[] newArgs = new Object[args.length];
+
+    for (int i = 0; i < args.length; i++)
+      {
+        // get() never returns null for Strings and so it should be more
+        // clever to swap both expression but by doing it this way we are
+        // behaving more like the JDK.
+        if ((newArgs[i] = get(args[i])) == null || args[i] instanceof String)
+          {
+            writeObject(args[i]);
+            newArgs[i] = get(args[i]);
+          }
+      }
+
+    Statement newStmt = new Statement(newTarget, stmt.getMethodName(), 
newArgs);
+
+    try
+      {
+        newStmt.execute();
+      }
+    catch (Exception e)
+      {
+        exceptionListener.exceptionThrown(e);
+      }
+
+  }
+
+  /**
+   * <p>
+   * Note: If you call this method not from within an object instantiation and
+   * initialization sequence it will be silently ignored.
+   * </p>
+   */
+  public void writeExpression(Expression expr)
+  {
+    // Silently ignore out of bounds calls.
+    if (accessCounter <= 0)
+      return;
+
+    Object target = expr.getTarget();
+    Object value = null;
+
+    try
+      {
+        value = expr.getValue();
+      }
+    catch (Exception e)
+      {
+        exceptionListener.exceptionThrown(e);
+        return;
+      }
+
+    if (get(value) == null)
+      {
+        Object newTarget = get(target);
+        if (newTarget == null)
+          {
+            writeObject(target);
+            newTarget = get(target);
+
+            // May happen if exception was thrown.
+            if (newTarget == null)
+              {
+                return;
+              }
+          }
+
+        Object[] args = expr.getArguments();
+        Object[] newArgs = new Object[args.length];
+
+        for (int i = 0; i < args.length; i++)
+          {
+            if ((newArgs[i] = get(args[i])) == null)
+              {
+                writeObject(args[i]);
+                newArgs[i] = get(args[i]);
+              }
+          }
+        
+        Expression newExpr = new Expression(newTarget, expr.getMethodName(),
+                                            newArgs);
+        
+        // Fakes the result of Class.forName(<primitiveType>) to make it 
possible
+        // to hand such a type to the encoding process.
+        if(value instanceof Class && ((Class) value).isPrimitive())
+          newExpr.setValue(value);
+        
+        // Instantiates the new object.
+        try
+          {
+            Object newValue = newExpr.getValue();
+
+            candidates.put(value, newValue);
+          }
+        catch (Exception e)
+          {
+            exceptionListener.exceptionThrown(e);
+            return;
+          }
+        writeObject(value);
+
+      }
+    else
+      {
+        //writeObject(target);
+      }
+
+  }
+
+}
Index: java/beans/Expression.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/beans/Expression.java,v
retrieving revision 1.3
diff -u -r1.3 Expression.java
--- java/beans/Expression.java  30 Aug 2005 01:30:00 -0000      1.3
+++ java/beans/Expression.java  20 Dec 2005 00:31:55 -0000
@@ -35,16 +35,13 @@
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version. */
 
-
 package java.beans;
 
 /**
- * class Expression
- *
- * An Expression captures the execution of an object method that
- * returns a value.  It stores an object, the method to call, and the
+ * class Expression An Expression captures the execution of an object method
+ * that returns a value. It stores an object, the method to call, and the
  * arguments to pass to the method.
- *
+ * 
  * @since 1.4
  */
 public class Expression extends Statement
@@ -53,38 +50,40 @@
   // yet;
   private static final Object UNSET = new Object();
 
-  // The value to return.  This is equal to unset until getValue is called.
+  // The value to return. This is equal to unset until getValue is called.
   private Object value;
-   
 
   /**
-   * Constructor
-   *
-   * Constructs an Expression representing the invocation of
-   * object.methodName(arg[0], arg[1], ...);  However, it will never
-   * be executed.  Instead, value will always be returned.
-   *
-   * @param value The value to return.
-   * @param target The object to invoke the method on.
-   * @param methodName The object method to invoke.
-   * @param arguments An array of arguments to pass to the method.
+   * Constructor Constructs an Expression representing the invocation of
+   * object.methodName(arg[0], arg[1], ...); However, it will never be 
executed.
+   * Instead, value will always be returned.
+   * 
+   * @param value
+   *          The value to return.
+   * @param target
+   *          The object to invoke the method on.
+   * @param methodName
+   *          The object method to invoke.
+   * @param arguments
+   *          An array of arguments to pass to the method.
    */
   public Expression(Object value, Object target, String methodName,
-                   Object[] arguments)
+                    Object[] arguments)
   {
     super(target, methodName, arguments);
     this.value = value;
   }
 
   /**
-   * Constructor
-   *
-   * Constructs an Expression representing the invocation of
+   * Constructor Constructs an Expression representing the invocation of
    * object.methodName(arg[0], arg[1], ...);
-   *
-   * @param target The object to invoke the method on.
-   * @param methodName The object method to invoke.
-   * @param arguments An array of arguments to pass to the method.
+   * 
+   * @param target
+   *          The object to invoke the method on.
+   * @param methodName
+   *          The object method to invoke.
+   * @param arguments
+   *          An array of arguments to pass to the method.
    */
   public Expression(Object target, String methodName, Object[] arguments)
   {
@@ -93,15 +92,14 @@
   }
 
   /**
-   * Return the result of executing the method.
-   *
-   * If the cached value has not yet been set, the method is
-   * executed in the same way as Statement.execute(), except that
-   * the value is cached, and then returned.  If the value has been
+   * Return the result of executing the method. If the cached value has not yet
+   * been set, the method is executed in the same way as Statement.execute(),
+   * except that the value is cached, and then returned. If the value has been
    * set, it is returned without executing the method again.
-   *
+   * 
    * @return the result of executing the method.
-   * @exception Exception if an error occurs
+   * @exception Exception
+   *              if an error occurs
    */
   public Object getValue() throws Exception
   {
@@ -112,14 +110,15 @@
 
   /**
    * Set the cached value to be returned by getValue()
-   *
-   * @param value the value to cache and return.
+   * 
+   * @param value
+   *          the value to cache and return.
    */
   public void setValue(Object value)
   {
     this.value = value;
   }
-    
+
   /**
    * Return a string representation of this expression.
    */
@@ -127,7 +126,7 @@
   {
     String result = super.toString();
     if (value != UNSET)
-      return value.getClass().getName() + " " + result;
+      return value.getClass().getName() + "=" + result;
     return result;
   }
 }
Index: java/beans/PersistenceDelegate.java
===================================================================
RCS file: java/beans/PersistenceDelegate.java
diff -N java/beans/PersistenceDelegate.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ java/beans/PersistenceDelegate.java 20 Dec 2005 00:31:55 -0000
@@ -0,0 +1,79 @@
+/* java.beans.Expression
+   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 java.beans;
+
+public abstract class PersistenceDelegate
+{
+
+  protected void initialize(Class type, Object oldInstance, Object newInstance,
+                            Encoder out)
+  {
+    if (type != Object.class)
+      {
+        type = type.getSuperclass();
+
+        PersistenceDelegate pd = out.getPersistenceDelegate(
+          oldInstance.getClass().getSuperclass());
+
+        pd.initialize(type, oldInstance, newInstance, out);
+      }
+  }
+
+  public void writeObject(Object oldInstance, Encoder out)
+  {
+    Object streamCandidate = out.get(oldInstance);
+
+    if (mutatesTo(oldInstance, streamCandidate))
+      {
+        initialize(oldInstance.getClass(), oldInstance, streamCandidate, out);
+      }
+    else
+      {
+        out.remove(oldInstance);
+        out.writeExpression(instantiate(oldInstance, out));
+      }
+  }
+
+  protected boolean mutatesTo(Object oldInstance, Object newInstance)
+  {
+    return (newInstance != null)
+           && oldInstance.getClass() == newInstance.getClass();
+  }
+
+  protected abstract Expression instantiate(Object oldInstance, Encoder out);
+}
Index: java/beans/Statement.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/beans/Statement.java,v
retrieving revision 1.3
diff -u -r1.3 Statement.java
--- java/beans/Statement.java   30 Aug 2005 01:30:00 -0000      1.3
+++ java/beans/Statement.java   20 Dec 2005 00:31:55 -0000
@@ -1,4 +1,4 @@
-/* java.beans.Statement
+/* Statement.java
    Copyright (C) 2004, 2005 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
@@ -48,26 +48,25 @@
 /**
  * class Statement
  *
- * A Statement captures the execution of an object method.  It stores
+ * <p>A Statement captures the execution of an object method.  It stores
  * the object, the method to call, and the arguments to the method and
  * provides the ability to execute the method on the object, using the
- * provided arguments.
+ * provided arguments.</p>
  *
+ * @author Jerry Quinn (address@hidden)
+ * @author Robert Schuster (address@hidden)
  * @since 1.4
  */
 public class Statement
 {
-  /** Nested map for the relation between a class, its instances and their
-    * names.
-    */
-  private static HashMap classMaps = new HashMap();
-
   private Object target;
   private String methodName;
   private Object[] arguments;
 
-  // One or the other of these will get a value after execute is
-  // called once, but not both.
+  /**
+   * One or the other of these will get a value after execute is
+   * called once, but not both.
+   */
   private transient Method method;
   private transient Constructor ctor;
 
@@ -87,76 +86,44 @@
     this.target = target;
     this.methodName = methodName;
     this.arguments = (arguments != null) ? arguments : new Object[0];
-    storeTargetName(target);
-  }
-
-  /** Creates a name for the target instance or does nothing if the object's
-   * name is already known. This makes sure that there *is* a name for every
-   * target instance.
-   */
-  private static synchronized void storeTargetName(Object obj)
-  {
-    Class klass = obj.getClass();
-    WeakHashMap names = (WeakHashMap) classMaps.get(klass);
-
-    if ( names == null )
-    {
-      names = new WeakHashMap();
-
-      names.put(obj,
-        ( klass == String.class ? ("\"" + obj + "\"") :
-        (klass.getName() + names.size()) ));
-
-      classMaps.put(klass, names);
-
-      return;
-    }
-
-    String targetName = (String) names.get(obj);
-    if ( targetName == null )
-    {
-      names.put(obj,
-        ( klass == String.class ? ("\"" + obj + "\"") :
-        (klass.getName() + names.size()) ));
-    }
-
-    // Nothing to do. The given object was already stored.
   }
 
   /**
    * Execute the statement.
    *
-   * Finds the specified method in the target object and calls it with
-   * the arguments given in the constructor.
+   * <p>Finds the specified method in the target object and calls it with
+   * the arguments given in the constructor.</p>
    *
-   * The most specific method according to the JLS(15.11) is used when
-   * there are multiple methods with the same name.
+   * <p>The most specific method according to the JLS(15.11) is used when
+   * there are multiple methods with the same name.</p>
    *
-   * Execute performs some special handling for methods and
+   * <p>Execute performs some special handling for methods and
    * parameters:
+   * <ul>
+   * <li>Static methods can be executed by providing the class as a
+   * target.</li>
    *
-   * Static methods can be executed by providing the class as a
-   * target.
-   *
-   * The method name new is reserved to call the constructor 
+   * <li>The method name new is reserved to call the constructor 
    * new() will construct an object and return it.  Not useful unless
-   * an expression :-)
+   * an expression :-)</li>
    *
-   * If the target is an array, get and set as defined in
+   * <li>If the target is an array, get and set as defined in
    * java.util.List are recognized as valid methods and mapped to the
-   * methods of the same name in java.lang.reflect.Array.
+   * methods of the same name in java.lang.reflect.Array.</li>
    *
-   * The native datatype wrappers Boolean, Byte, Character, Double,
+   * <li>The native datatype wrappers Boolean, Byte, Character, Double,
    * Float, Integer, Long, and Short will map to methods that have
    * native datatypes as parameters, in the same way as Method.invoke.
    * However, these wrappers also select methods that actually take
-   * the wrapper type as an argument.
+   * the wrapper type as an argument.</li>
+   * </ul>
+   * </p>
    *
-   * The Sun spec doesn't deal with overloading between int and
+   * <p>The Sun spec doesn't deal with overloading between int and
    * Integer carefully.  If there are two methods, one that takes an
    * Integer and the other taking an int, the method chosen is not
    * specified, and can depend on the order in which the methods are
-   * declared in the source file.
+   * declared in the source file.</p>
    *
    * @throws Exception if an exception occurs while locating or
    *                  invoking the method.
@@ -178,8 +145,10 @@
       Integer.TYPE, Long.TYPE, Short.TYPE
     };
 
-  // Given a wrapper class, return the native class for it.  For
-  // example, if c is Integer, Integer.TYPE is returned.
+  /** Given a wrapper class, return the native class for it.
+   * <p>For example, if <code>c</code> is <code>Integer</code>, 
+   * <code>Integer.TYPE</code> is returned.</p>
+   */
   private Class unwrap(Class c)
   {
     for (int i = 0; i < wrappers.length; i++)
@@ -188,8 +157,11 @@
     return null;
   }
 
-  // Return true if all args can be assigned to params, false
-  // otherwise.  Arrays are guaranteed to be the same length.
+  /** Returns <code>true</code> if all args can be assigned to
+   * <code>params</code>, <code>false</code> otherwise.
+   *
+   * <p>Arrays are guaranteed to be the same length.</p>
+   */
   private boolean compatible(Class[] params, Class[] args)
   {
     for (int i = 0; i < params.length; i++)
@@ -208,14 +180,15 @@
   }
 
   /**
-   * Return true if the method arguments in first are more specific
-   * than the method arguments in second, i.e. all args in first can
-   * be assigned to those in second.
+   * Returns <code>true</code> if the method arguments in first are
+   * more specific than the method arguments in second, i.e. all
+   * arguments in <code>first</code> can be assigned to those in
+   * <code>second</code>.
    *
-   * A method is more specific if all parameters can also be fed to
+   * <p>A method is more specific if all parameters can also be fed to
    * the less specific method, because, e.g. the less specific method
    * accepts a base class of the equivalent argument for the more
-   * specific one.
+   * specific one.</p>
    *
    * @param first a <code>Class[]</code> value
    * @param second a <code>Class[]</code> value
@@ -333,6 +306,19 @@
       }
     if (method == null)
       throw new NoSuchMethodException("No matching method for statement " + 
toString());
+
+    // If we were calling Class.forName(String) we intercept and call the
+    // forName-variant that allows a ClassLoader argument. We take the
+    // system classloader (aka application classloader) here to make sure
+    // that application defined classes can be resolved. If we would not
+    // do that the Class.forName implementation would use the class loader
+    // of java.beans.Statement which is <null> and cannot resolve application
+    // defined classes.
+    if ( method.equals(
+           Class.class.getMethod("forName", new Class[] { String.class })) )
+      return Class.forName(
+               (String) args[0], true, ClassLoader.getSystemClassLoader());
+
     return method.invoke(target, args);
   }
 
@@ -352,9 +338,13 @@
   {
     StringBuffer result = new StringBuffer(); 
 
-    Class klass = target.getClass();
+    String targetName = target.getClass().getName();
+    if ( targetName.startsWith("java"))
+      {
+        targetName = targetName.substring(targetName.lastIndexOf('.') + 1);
+      }
 
-    result.append( ((WeakHashMap) classMaps.get(klass)).get(target));
+    result.append(targetName);
     result.append(".");
     result.append(methodName);
     result.append("(");
@@ -363,11 +353,15 @@
     for (int i = 0; i < arguments.length; i++)
       {
         result.append(sep);
-        result.append(arguments[i].getClass().getName());
+        result.append(
+          ( arguments[i] == null ) ? "null" : 
+            ( arguments[i] instanceof String ) ? "\"" + arguments[i] + "\"" :
+            arguments[i].getClass().getName());
         sep = ", ";
       }
     result.append(")");
 
     return result.toString();
   }
+  
 }
Index: java/beans/XMLEncoder.java
===================================================================
RCS file: java/beans/XMLEncoder.java
diff -N java/beans/XMLEncoder.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ java/beans/XMLEncoder.java  20 Dec 2005 00:31:55 -0000
@@ -0,0 +1,110 @@
+/* XMLEncoder.java
+   Copyright (C) 2004, 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 java.beans;
+
+import gnu.java.beans.encoder.ScanEngine;
+
+import java.io.OutputStream;
+
+public class XMLEncoder extends Encoder
+{
+  Object owner;
+
+  Exception exception;
+
+  boolean skip = false;
+
+  ScanEngine scanEngine;
+
+  public XMLEncoder(OutputStream os)
+  {
+    scanEngine = new ScanEngine(os);
+  }
+
+  public void close()
+  {
+    if (scanEngine != null)
+      {
+        scanEngine.close();
+        scanEngine = null;
+      }
+  }
+
+  public void flush()
+  {
+    scanEngine.flush();
+  }
+
+  public void writeExpression(Expression expr)
+  {
+    scanEngine.writeExpression(expr);
+
+    super.writeExpression(expr);
+
+    scanEngine.end();
+  }
+
+  public void writeStatement(Statement stmt)
+  {
+    scanEngine.writeStatement(stmt);
+
+    super.writeStatement(stmt);
+
+    scanEngine.end();
+  }
+
+  public void writeObject(Object o)
+  {
+    scanEngine.writeObject(o);
+
+    super.writeObject(o);
+  }
+
+  public void setOwner(Object o)
+  {
+    owner = o;
+  }
+
+  public Object getOwner()
+  {
+    return owner;
+  }
+
+}
Index: gnu/java/beans/encoder/ArrayPersistenceDelegate.java
===================================================================
RCS file: gnu/java/beans/encoder/ArrayPersistenceDelegate.java
diff -N gnu/java/beans/encoder/ArrayPersistenceDelegate.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ gnu/java/beans/encoder/ArrayPersistenceDelegate.java        20 Dec 2005 
00:31:55 -0000
@@ -0,0 +1,130 @@
+/* ArrayPersistenceDelegate.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.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. The special handling for primitive types is done in
+    // 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.
+    
+    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.writeStatement(new Statement(Array.class, "set",
+                                               new Object[] { oldInstance,
+                                                             new Integer(i),
+                                                             oldValue }));
+          }
+      }
+    else
+      {
+
+        for (int i = 0; i < length; i++)
+          {
+            Object oldValue = Array.get(oldInstance, i);
+
+            if (oldValue != null)
+              out.writeStatement(new Statement(Array.class, "set",
+                                               new Object[] { oldInstance,
+                                                             new Integer(i),
+                                                             oldValue }));
+
+          }
+      }
+  }
+
+}
Index: gnu/java/beans/encoder/ClassPersistenceDelegate.java
===================================================================
RCS file: gnu/java/beans/encoder/ClassPersistenceDelegate.java
diff -N gnu/java/beans/encoder/ClassPersistenceDelegate.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ gnu/java/beans/encoder/ClassPersistenceDelegate.java        20 Dec 2005 
00:31:55 -0000
@@ -0,0 +1,63 @@
+/* ClassPersistenceDelegate.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.beans.Encoder;
+import java.beans.Expression;
+import java.beans.PersistenceDelegate;
+
+public class ClassPersistenceDelegate extends PersistenceDelegate
+{
+
+  protected Expression instantiate(Object oldInstance, Encoder out)
+  {
+    Class oldClass = (Class) oldInstance;
+    
+    // Due to this definition resolving the String and the Class
+    // class does not depend on anything else.
+    if (oldClass == String.class)
+      return new Expression(oldClass, "", "getClass", null);
+
+    if (oldClass == Class.class)
+      return new Expression(oldClass, String.class, "getClass", null);
+
+    return new Expression(oldClass, Class.class, "forName",
+                          new Object[] { oldClass.getName() });
+  }
+
+}
Index: gnu/java/beans/encoder/GenericScannerState.java
===================================================================
RCS file: gnu/java/beans/encoder/GenericScannerState.java
diff -N gnu/java/beans/encoder/GenericScannerState.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ gnu/java/beans/encoder/GenericScannerState.java     20 Dec 2005 00:31:55 
-0000
@@ -0,0 +1,204 @@
+/* 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 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;
+
+class GenericScannerState extends ScannerState
+{
+  private int skipElements, initialSkipElements;
+
+  GenericScannerState()
+  {
+  }
+
+  GenericScannerState(int skipElements)
+  {
+    this.skipElements = initialSkipElements = skipElements;
+  }
+
+  void methodInvocation(String methodName)
+  {
+    if (skipElements > 0)
+      return;
+
+    root().addChild(new MethodInvocation(methodName));
+  }
+
+  void staticMethodInvocation(String className, String methodName)
+  {
+    if (skipElements > 0)
+      return;
+
+    root().addChild(new StaticMethodInvocation(className, methodName));
+  }
+
+  void staticFieldAccess(String className, String fieldName)
+  {
+    if (skipElements > 0)
+      return;
+
+    root().addChild(new StaticFieldAccess(className, fieldName));
+  }
+
+  void classResolution(String className)
+  {
+    if (skipElements > 0)
+      return;
+
+    root().addChild(new ClassResolution(className));
+  }
+
+  void objectInstantiation(String className, ObjectId objectId)
+  {
+    if (skipElements > 0)
+      return;
+
+    Element elem = new ObjectInstantiation(className);
+    elem.initId(objectId);
+    
+    root().addChild(elem);
+  }
+
+  void primitiveInstantiation(String primitiveName, String valueAsString)
+  {
+    if (skipElements > 0)
+      return;
+
+    root().addChild(new PrimitiveInstantiation(primitiveName, valueAsString));
+  }
+
+  void arrayInstantiation(String arrayClassName, String lengthAsString, 
ObjectId objectId)
+  {
+    if (skipElements > 0)
+      return;
+
+    Element elem = new ArrayInstantiation(arrayClassName, lengthAsString);
+    elem.initId(objectId);
+    
+    root().addChild(elem);
+  }
+
+  void arraySet(String indexAsString)
+  {
+    if (skipElements > 0)
+      return;
+
+    root().addChild(new Array_Set(indexAsString));
+  }
+
+  void arrayGet(String indexAsString)
+  {
+    if (skipElements > 0)
+      return;
+
+    root().addChild(new Array_Get(indexAsString));
+  }
+
+  void listGet()
+  {
+    if (skipElements > 0)
+      return;
+
+    root().addChild(new List_Get());
+  }
+
+  void listSet()
+  {
+    if (skipElements > 0)
+      return;
+
+    root().addChild(new List_Set());
+  }
+
+  void nullObject()
+  {
+    if (skipElements > 0)
+      return;
+
+    root().addChild(new NullObject());
+  }
+
+  void stringReference(String string)
+  {
+    if (skipElements > 0)
+      return;
+
+    root().addChild(new StringReference(string));
+  }
+
+  void objectReference(String id)
+  {
+    if (skipElements > 0)
+      return;
+
+    root().addChild(new ObjectReference(id));
+  }
+
+  void childEnded(ScannerState child)
+  {
+    // Do nothing here (Cannot interact with child states).
+  }
+
+  void end()
+  {
+    if (skipElements > 0)
+      skipElements--;
+    else
+      {
+        super.end(); // Important.
+        skipElements = initialSkipElements;
+      }
+  }
+
+}
Index: gnu/java/beans/encoder/IgnoringScannerState.java
===================================================================
RCS file: gnu/java/beans/encoder/IgnoringScannerState.java
diff -N gnu/java/beans/encoder/IgnoringScannerState.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ gnu/java/beans/encoder/IgnoringScannerState.java    20 Dec 2005 00:31:55 
-0000
@@ -0,0 +1,111 @@
+/* IgnoringScannerState.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;
+
+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 arrayInstantiation(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(String id)
+  {
+  }
+  
+  void end()
+  {
+    // Important: This overrides an otherwise default behavior which would
+    // issue to write a closing XML tag.
+  }
+  
+  void childEnded(ScannerState child)
+  {
+    
+  }
+  
+}
Index: gnu/java/beans/encoder/PrimitivePersistenceDelegate.java
===================================================================
RCS file: gnu/java/beans/encoder/PrimitivePersistenceDelegate.java
diff -N gnu/java/beans/encoder/PrimitivePersistenceDelegate.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ gnu/java/beans/encoder/PrimitivePersistenceDelegate.java    20 Dec 2005 
00:31:55 -0000
@@ -0,0 +1,60 @@
+/* PrimitivePersistenceDelegate.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.beans.Encoder;
+import java.beans.Expression;
+import java.beans.PersistenceDelegate;
+
+/**
+ * A shared PersistenceDelegate implementation for all primitive types.
+ */
+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() });
+  }
+
+}
Index: gnu/java/beans/encoder/ReportingScannerState.java
===================================================================
RCS file: gnu/java/beans/encoder/ReportingScannerState.java
diff -N gnu/java/beans/encoder/ReportingScannerState.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ gnu/java/beans/encoder/ReportingScannerState.java   20 Dec 2005 00:31:55 
-0000
@@ -0,0 +1,124 @@
+/* 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;
+
+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 arrayInstantiation(String arrayClassName, String lengthAsString, 
ObjectId objectId)
+  {
+       System.out.println("arrayInstantiation: 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(String id)
+  {
+    System.out.println("objectReference: " + id);
+  }
+
+ void end()
+ {
+       System.out.println("-close");
+ }
+
+ void childEnded(ScannerState child)
+ {
+   System.out.println("childEnded: " + child);
+ }
+ 
+}
Index: gnu/java/beans/encoder/ScanEngine.java
===================================================================
RCS file: gnu/java/beans/encoder/ScanEngine.java
diff -N gnu/java/beans/encoder/ScanEngine.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ gnu/java/beans/encoder/ScanEngine.java      20 Dec 2005 00:31:55 -0000
@@ -0,0 +1,551 @@
+/* ScanEngine.java 
+ -- Main scan engine of the java.beans.XMLEncoder.
+ 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;
+
+public class ScanEngine
+{
+
+  /**
+   * Stores the scanner engine states as values and their names as keys.
+   */
+  HashMap states = new HashMap();
+
+  ScannerState current = new GenericScannerState();
+
+  Writer issuer;
+
+  Stack parents = new Stack();
+
+  Root root;
+
+  IdentityHashMap objects = new IdentityHashMap();
+
+  public ScanEngine(OutputStream os)
+  {
+    issuer = new StAXWriter(os);
+    root = new Root();
+
+    current.enter(root);
+
+    // Scanner configuration:
+    // null - no changes
+    // string - no changes
+    final ScannerState start = current;
+    ScannerState conf;
+
+    // TODO: Develop ReportingScannerState and put it in here
+    register(ScannerState.DEFAULT_STATE_NAME, new ReportingScannerState());
+
+    register("start", start);
+
+    // Special dead-end state where all transitions are ignored
+    register("reportAll", new ReportingScannerState()).setDefaultSuccessor(
+                                                                           
"reportAll");
+    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());
+
+    // ClassResolution
+    start.putSuccessor(ScannerState.TRANSITION_CLASS_RESOLUTION, "classRes0");
+    register("classRes0", new GenericScannerState()).setDefaultSuccessor(
+                                                                         
"ignoreAll");
+
+    // Object Instantiation
+    start.putSuccessor(ScannerState.TRANSITION_OBJECT_INSTANTIATION, 
"newObj0");
+    conf = register("newObj0", new GenericScannerState());
+    conf.setDefaultSuccessor("ignoreAll");
+    // Simply use the start state to encode method invocations inside of 
objects
+    conf.putSuccessor(ScannerState.TRANSITION_METHOD_INVOCATION, "start");
+
+    start.putSuccessor(ScannerState.TRANSITION_PRIMITIVE_INSTANTIATION,
+                       "newPrimitive0");
+    register("newPrimitive0", new GenericScannerState()).setDefaultSuccessor(
+                                                                             
"ignoreAll");
+
+    start.putSuccessor(ScannerState.TRANSITION_ARRAY_INSTANTIATION, 
"newArray0");
+    conf = register("newArray0", new GenericScannerState());
+    conf.putSuccessor(ScannerState.TRANSITION_ARRAY_SET, "newArray_set");
+    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("newArray_set", new GenericScannerState()).setDefaultSuccessor(
+                                                                            
"newArray_set_ignorefirst");
+    conf = register("newArray_set_ignorefirst", new GenericScannerState(1));
+    // can happen in non-int primitive arrays
+    conf.putSuccessor(ScannerState.TRANSITION_CLASS_RESOLUTION, "ignoreAll");
+    conf.setDefaultSuccessor("start");
+
+  }
+
+  private ScannerState register(String name, ScannerState state)
+  {
+    states.put(name, state);
+
+    state.name = name;
+
+    return state;
+  }
+
+  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);
+      }
+
+    Class valueClass = value.getClass();
+    ObjectId id = null;
+    if (valueClass != String.class && valueClass != Class.class
+        && valueClass.getSuperclass() != Number.class
+        && valueClass != Boolean.class)
+      {
+        System.err.println("id management for class: " + valueClass);
+
+        id = (ObjectId) objects.get(value);
+        if (id == null)
+          {
+            System.err.println("idmgnt: creating new empty id");
+            id = new ObjectId();
+            objects.put(value, id);
+          }
+        /*
+         * else { System.err.println("idmgnt: reusing id"); if(id.isUnused())
+         * id.generateId(valueClass); objectReference(id.toString()); return; }
+         */
+      }
+
+    if (target == Array.class)
+      {
+        if (methodName.equals("newInstance"))
+          {
+            arrayInstantiation(((Class) args[0]).getName(), args[1].toString(),
+                               id);
+            return;
+          }
+        else if (methodName.equals("get"))
+          {
+            arrayGet(args[1].toString());
+            return;
+          }
+        else if (methodName.equals("set"))
+          {
+            arraySet(args[1].toString());
+            return;
+          }
+      }
+
+    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 some static method will be called.
+
+            // However "Class.forName" represents class resolution and has a
+            // different syntax.
+            if (methodName.equals("forName"))
+              {
+                classResolution(className);
+                return;
+              }
+            else
+            // The same goes for "Class.getField".
+            // Note: The name of the wanted field is given in
+            // the argument array.
+            if (methodName.equals("getField"))
+              {
+                staticFieldAccess(className, args[0].toString());
+                return;
+              }
+            else
+              {
+                staticMethodInvocation(className, methodName);
+                return;
+              }
+          }
+      }
+    else if (target instanceof List)
+      {
+        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);
+  }
+
+  public void end()
+  {
+    current.end();
+
+    ScannerState oldCurrent = current;
+    current = (ScannerState) parents.pop();
+
+    // Gives the parent the possibility to interact with the child state.
+    current.childEnded(current);
+  }
+
+  public void writeStatement(Statement stmt)
+  {
+    // That is probably wrong. Everything here should
+    // be void things.
+
+    String methodName = stmt.getMethodName();
+    Object target = stmt.getTarget();
+    Object[] args = stmt.getArguments();
+    Object value = null;
+
+    ObjectId id = new ObjectId();
+
+    if (target == Array.class)
+      {
+        if (methodName.equals("newInstance"))
+          {
+            arrayInstantiation(((Class) args[0]).getName(), args[1].toString(),
+                               id);
+            return;
+          }
+        else if (methodName.equals("get"))
+          {
+            arrayGet(args[1].toString());
+            return;
+          }
+        else if (methodName.equals("set"))
+          {
+            arraySet(args[1].toString());
+            return;
+          }
+      }
+
+    if (target instanceof Class)
+      {
+        if (methodName.equals("new"))
+          {
+            Class targetClass = (Class) target;
+
+            Class valueClass = value.getClass();
+
+            // 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 some static method will be called.
+
+            // However "Class.forName" represents class resolution and has a
+            // different syntax.
+            if (methodName.equals("forName"))
+              {
+                classResolution(className);
+                return;
+              }
+            else
+            // The same goes for "Class.getField".
+            // Note: The name of the wanted field is given in
+            // the argument array.
+            if (methodName.equals("getField"))
+              {
+                staticFieldAccess(className, args[0].toString());
+                return;
+              }
+            else
+              {
+                staticMethodInvocation(className, methodName);
+                return;
+              }
+          }
+      }
+    else if (target instanceof List)
+      {
+        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);
+  }
+
+  public void writeObject(Object o)
+  {
+    ObjectId id = null;
+
+    if (o == null)
+      {
+        nullObject();
+        end();
+      }
+    else if (o instanceof String)
+      {
+        stringReference((String) o);
+        end();
+      }
+    else if ((id = (ObjectId) objects.get(o)) != null)
+      {
+        System.err.println("idmgnt: reusing id");
+
+        if (id.isUnused())
+          id.generateId(o.getClass());
+
+        objectReference(id.toString());
+        end();
+        return;
+      }
+
+  }
+
+  public void flush()
+  {
+    root.traverse(issuer);
+    issuer.flush();
+  }
+
+  public void close()
+  {
+    root.traverse(issuer);
+    issuer.close();
+  }
+
+  private void transition(int transition)
+  {
+    parents.push(current);
+
+    String stateName = current.getSuccessor(transition);
+    System.err.println("from state: " + current.name + "\n\troute: "
+                       + ScannerState.getTransitionName(transition)
+                       + "\n\t\tto state: " + stateName);
+
+    ScannerState newState = (ScannerState) states.get(stateName);
+
+    assert (newState != null) : "State '" + stateName + "' was not defined.";
+
+    newState.enter(root);
+    current = newState;
+  }
+
+  void methodInvocation(String methodName)
+  {
+    transition(ScannerState.TRANSITION_METHOD_INVOCATION);
+
+    current.methodInvocation(methodName);
+  }
+
+  void staticMethodInvocation(String className, String methodName)
+  {
+    transition(ScannerState.TRANSITION_STATIC_METHOD_INVOCATION);
+
+    current.staticMethodInvocation(className, methodName);
+  }
+
+  void staticFieldAccess(String className, String fieldName)
+  {
+    transition(ScannerState.TRANSITION_STATIC_FIELD_ACCESS);
+
+    current.staticFieldAccess(className, fieldName);
+  }
+
+  void classResolution(String className)
+  {
+    transition(ScannerState.TRANSITION_CLASS_RESOLUTION);
+
+    current.classResolution(className);
+  }
+
+  void objectInstantiation(String className, ObjectId objectId)
+  {
+    transition(ScannerState.TRANSITION_OBJECT_INSTANTIATION);
+
+    current.objectInstantiation(className, objectId);
+  }
+
+  void primitiveInstantiation(String primitiveName, String valueAsString)
+  {
+    transition(ScannerState.TRANSITION_PRIMITIVE_INSTANTIATION);
+
+    current.primitiveInstantiation(primitiveName, valueAsString);
+  }
+
+  void arrayInstantiation(String arrayClassName, String lengthAsString,
+                          ObjectId objectId)
+  {
+    transition(ScannerState.TRANSITION_ARRAY_INSTANTIATION);
+
+    current.arrayInstantiation(arrayClassName, lengthAsString, objectId);
+  }
+
+  void arraySet(String indexAsString)
+  {
+    transition(ScannerState.TRANSITION_ARRAY_SET);
+
+    current.arraySet(indexAsString);
+  }
+
+  void arrayGet(String indexAsString)
+  {
+    transition(ScannerState.TRANSITION_ARRAY_GET);
+
+    current.arrayGet(indexAsString);
+  }
+
+  void listSet()
+  {
+    transition(ScannerState.TRANSITION_LIST_SET);
+
+    current.listSet();
+  }
+
+  void listGet()
+  {
+    transition(ScannerState.TRANSITION_LIST_GET);
+
+    current.listGet();
+  }
+
+  void nullObject()
+  {
+    transition(ScannerState.TRANSITION_NULL_OBJECT);
+
+    current.nullObject();
+  }
+
+  void stringReference(String string)
+  {
+    transition(ScannerState.TRANSITION_STRING_REFERENCE);
+
+    current.stringReference(string);
+  }
+
+  void objectReference(String id)
+  {
+    transition(ScannerState.TRANSITION_OBJECT_REFERENCE);
+
+    current.objectReference(id);
+  }
+
+}
Index: gnu/java/beans/encoder/ScannerState.java
===================================================================
RCS file: gnu/java/beans/encoder/ScannerState.java
diff -N gnu/java/beans/encoder/ScannerState.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ gnu/java/beans/encoder/ScannerState.java    20 Dec 2005 00:31:55 -0000
@@ -0,0 +1,170 @@
+/* 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;
+
+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_ARRAY_INSTANTIATION = 6;
+
+  static final int TRANSITION_ARRAY_SET = 7;
+
+  static final int TRANSITION_ARRAY_GET = 8;
+
+  static final int TRANSITION_LIST_SET = 9;
+
+  static final int TRANSITION_LIST_GET = 10;
+
+  static final int TRANSITION_NULL_OBJECT = 11;
+
+  static final int TRANSITION_STRING_REFERENCE = 12;
+
+  static final int TRANSITION_OBJECT_REFERENCE = 13;
+
+  static final int TRANSITION_FIRST = 0;
+
+  static final int TRANSITION_LAST = 13;
+
+  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", "ARRAY_INSTANTIATION",
+                              "ARRAY_SET", "ARRAY_GET", "LIST_SET", "LIST_GET",
+                              "NULL_OBJECT", "STRING_REFERENCE", 
"OBJECT_REREFERENCE" };
+
+  HashMap transitions = new HashMap();
+
+  Root root;
+  
+  // DEBUG only
+  String name;
+
+  static String getTransitionName(int i)
+  {
+    return transitionNames[i];
+  }
+  
+  void end()
+  {
+    // Note: Overridden for a special cause in IgnoringScannerState!
+    root.end();
+  }
+
+  void enter(Root newRoot)
+  {
+    root = newRoot;
+  }
+
+  Root root()
+  {
+    return root;
+  }
+
+  void putSuccessor(int transition, String stateName)
+  {
+    if (transition < TRANSITION_FIRST && transition > TRANSITION_LAST)
+      {
+        throw new IllegalStateException("Transition identifier '" + transition
+                                        + "' is unknown.");
+      }
+
+    transitions.put(new Integer(transition), stateName);
+  }
+
+  String getSuccessor(int transition)
+  {
+    String state = (String) transitions.get(new Integer(transition));
+
+    return (state == null) ? defaultSuccessor : state;
+  }
+
+  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 arrayInstantiation(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(String id);
+
+  abstract void childEnded(ScannerState child);
+}
Index: gnu/java/beans/encoder/elements/ArrayInstantiation.java
===================================================================
RCS file: gnu/java/beans/encoder/elements/ArrayInstantiation.java
diff -N gnu/java/beans/encoder/elements/ArrayInstantiation.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ gnu/java/beans/encoder/elements/ArrayInstantiation.java     20 Dec 2005 
00:31:55 -0000
@@ -0,0 +1,69 @@
+/* ArrayInstantiation.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.ObjectId;
+import gnu.java.beans.encoder.Writer;
+
+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());
+
+  }
+
+}
Index: gnu/java/beans/encoder/elements/Array_Get.java
===================================================================
RCS file: gnu/java/beans/encoder/elements/Array_Get.java
diff -N gnu/java/beans/encoder/elements/Array_Get.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ gnu/java/beans/encoder/elements/Array_Get.java      20 Dec 2005 00:31:55 
-0000
@@ -0,0 +1,57 @@
+/* Array_Get.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_Get extends Element
+{
+  final String indexAsString;
+
+  public Array_Get(String newIndexAsString)
+  {
+    indexAsString = newIndexAsString;
+  }
+
+  public void writeStart(Writer writer)
+  {
+    writer.write("object", "index", indexAsString, isEmpty());
+  }
+
+}
Index: gnu/java/beans/encoder/elements/Array_Set.java
===================================================================
RCS file: gnu/java/beans/encoder/elements/Array_Set.java
diff -N gnu/java/beans/encoder/elements/Array_Set.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ gnu/java/beans/encoder/elements/Array_Set.java      20 Dec 2005 00:31:55 
-0000
@@ -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());
+  }
+
+}
Index: gnu/java/beans/encoder/elements/ClassResolution.java
===================================================================
RCS file: gnu/java/beans/encoder/elements/ClassResolution.java
diff -N gnu/java/beans/encoder/elements/ClassResolution.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ gnu/java/beans/encoder/elements/ClassResolution.java        20 Dec 2005 
00:31:55 -0000
@@ -0,0 +1,62 @@
+/* ClassResolution.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 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();
+  }
+
+}
Index: gnu/java/beans/encoder/elements/Element.java
===================================================================
RCS file: gnu/java/beans/encoder/elements/Element.java
diff -N gnu/java/beans/encoder/elements/Element.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ gnu/java/beans/encoder/elements/Element.java        20 Dec 2005 00:31:55 
-0000
@@ -0,0 +1,87 @@
+/* Element.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 java.util.ArrayList;
+import java.util.Iterator;
+
+import gnu.java.beans.encoder.ObjectId;
+import gnu.java.beans.encoder.Writer;
+
+public abstract class Element
+{
+  private ArrayList children = new ArrayList();
+  
+  private ObjectId objectId;
+  
+  public void initId(ObjectId objectId)
+  {
+    assert (this.objectId == null);
+    assert (objectId != null);
+    
+    this.objectId = objectId;
+  }
+  
+  public void addChild(Element elem)
+  {
+    children.add(elem);
+  }
+  
+  public Iterator iterator(){
+    return children.iterator();
+  }
+  
+  public final boolean isEmpty()
+  {
+    return children.isEmpty(); 
+  }
+  
+  protected ObjectId getId()
+  {
+    return objectId;
+  }
+  
+  public abstract void writeStart(Writer writer);
+  
+  public void writeEnd(Writer writer)
+  {
+    writer.writeEnd(children.isEmpty());
+  }
+  
+}
Index: gnu/java/beans/encoder/elements/List_Get.java
===================================================================
RCS file: gnu/java/beans/encoder/elements/List_Get.java
diff -N gnu/java/beans/encoder/elements/List_Get.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ gnu/java/beans/encoder/elements/List_Get.java       20 Dec 2005 00:31:55 
-0000
@@ -0,0 +1,51 @@
+/* List_Get.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 List_Get extends Element
+{
+
+  public void writeStart(Writer writer)
+  {
+    writer.write("object", "get");
+  }
+  
+}
Index: gnu/java/beans/encoder/elements/List_Set.java
===================================================================
RCS file: gnu/java/beans/encoder/elements/List_Set.java
diff -N gnu/java/beans/encoder/elements/List_Set.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ gnu/java/beans/encoder/elements/List_Set.java       20 Dec 2005 00:31:55 
-0000
@@ -0,0 +1,51 @@
+/* List_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 List_Set extends Element
+{
+
+  public void writeStart(Writer writer)
+  {
+    writer.write("object", "set");
+  }
+  
+}
Index: gnu/java/beans/encoder/elements/MethodInvocation.java
===================================================================
RCS file: gnu/java/beans/encoder/elements/MethodInvocation.java
diff -N gnu/java/beans/encoder/elements/MethodInvocation.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ gnu/java/beans/encoder/elements/MethodInvocation.java       20 Dec 2005 
00:31:55 -0000
@@ -0,0 +1,57 @@
+/* MethodCall.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 MethodInvocation extends Element
+{
+  final String methodName;
+  
+  public MethodInvocation(String newMethodName)
+  {
+    methodName = newMethodName;
+  }
+  
+  public void writeStart(Writer writer)
+  {
+    writer.write("void", "method", methodName, isEmpty());
+  }
+  
+}
Index: gnu/java/beans/encoder/elements/NullObject.java
===================================================================
RCS file: gnu/java/beans/encoder/elements/NullObject.java
diff -N gnu/java/beans/encoder/elements/NullObject.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ gnu/java/beans/encoder/elements/NullObject.java     20 Dec 2005 00:31:55 
-0000
@@ -0,0 +1,56 @@
+/* NullObject.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 NullObject extends Element
+{
+
+  public void writeStart(Writer writer)
+  {
+    writer.write("null", true);
+  }
+  
+  public void writeEnd(Writer writer)
+  {
+    writer.writeEnd(true);
+  }
+
+}
Index: gnu/java/beans/encoder/elements/ObjectInstantiation.java
===================================================================
RCS file: gnu/java/beans/encoder/elements/ObjectInstantiation.java
diff -N gnu/java/beans/encoder/elements/ObjectInstantiation.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ gnu/java/beans/encoder/elements/ObjectInstantiation.java    20 Dec 2005 
00:31:55 -0000
@@ -0,0 +1,63 @@
+/* ObjectInstantiation.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.ObjectId;
+import gnu.java.beans.encoder.Writer;
+
+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());
+  }
+
+}
Index: gnu/java/beans/encoder/elements/ObjectReference.java
===================================================================
RCS file: gnu/java/beans/encoder/elements/ObjectReference.java
diff -N gnu/java/beans/encoder/elements/ObjectReference.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ gnu/java/beans/encoder/elements/ObjectReference.java        20 Dec 2005 
00:31:55 -0000
@@ -0,0 +1,57 @@
+/* StringInstantiation.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 ObjectReference extends Element
+{
+  final String id;
+
+  public ObjectReference(String newId)
+  {
+    id = newId;
+  }
+
+  public void writeStart(Writer writer)
+  {
+    writer.write("object", "idref", id, isEmpty());
+  }
+  
+}
Index: gnu/java/beans/encoder/elements/PrimitiveInstantiation.java
===================================================================
RCS file: gnu/java/beans/encoder/elements/PrimitiveInstantiation.java
diff -N gnu/java/beans/encoder/elements/PrimitiveInstantiation.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ gnu/java/beans/encoder/elements/PrimitiveInstantiation.java 20 Dec 2005 
00:31:55 -0000
@@ -0,0 +1,64 @@
+/* PrimitiveInstantiation.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 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();
+  }
+}
Index: gnu/java/beans/encoder/elements/StaticFieldAccess.java
===================================================================
RCS file: gnu/java/beans/encoder/elements/StaticFieldAccess.java
diff -N gnu/java/beans/encoder/elements/StaticFieldAccess.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ gnu/java/beans/encoder/elements/StaticFieldAccess.java      20 Dec 2005 
00:31:55 -0000
@@ -0,0 +1,61 @@
+/* StaticFieldAccess.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 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());
+  }
+
+}
Index: gnu/java/beans/encoder/elements/StaticMethodInvocation.java
===================================================================
RCS file: gnu/java/beans/encoder/elements/StaticMethodInvocation.java
diff -N gnu/java/beans/encoder/elements/StaticMethodInvocation.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ gnu/java/beans/encoder/elements/StaticMethodInvocation.java 20 Dec 2005 
00:31:55 -0000
@@ -0,0 +1,61 @@
+/* StaticMethodCall.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 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());
+  }
+  
+}
Index: gnu/java/beans/encoder/elements/StringReference.java
===================================================================
RCS file: gnu/java/beans/encoder/elements/StringReference.java
diff -N gnu/java/beans/encoder/elements/StringReference.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ gnu/java/beans/encoder/elements/StringReference.java        20 Dec 2005 
00:31:55 -0000
@@ -0,0 +1,62 @@
+/* StringInstantiation.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 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();
+  }
+
+}

Attachment: signature.asc
Description: OpenPGP digital signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]