aboutsummaryrefslogtreecommitdiff
path: root/libjava/java/io/ObjectStreamClass.java
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/java/io/ObjectStreamClass.java')
-rw-r--r--libjava/java/io/ObjectStreamClass.java668
1 files changed, 0 insertions, 668 deletions
diff --git a/libjava/java/io/ObjectStreamClass.java b/libjava/java/io/ObjectStreamClass.java
deleted file mode 100644
index c43112d7a61..00000000000
--- a/libjava/java/io/ObjectStreamClass.java
+++ /dev/null
@@ -1,668 +0,0 @@
-/* ObjectStreamClass.java -- Class used to write class information
- about serialized objects.
- Copyright (C) 1998, 1999 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., 59 Temple Place, Suite 330, Boston, MA
-02111-1307 USA.
-
-As a special exception, if you link this library with other files to
-produce an executable, this library does not by itself cause the
-resulting executable to be covered by the GNU General Public License.
-This exception does not however invalidate any other reasons why the
-executable file might be covered by the GNU General Public License. */
-
-
-package java.io;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.Member;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.security.DigestOutputStream;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.Security;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.Hashtable;
-import java.util.Vector;
-import gnu.java.io.NullOutputStream;
-import gnu.java.lang.reflect.TypeSignature;
-import gnu.java.security.provider.Gnu;
-
-
-public class ObjectStreamClass implements Serializable
-{
- /**
- Returns the <code>ObjectStreamClass</code> for <code>cl</code>.
- If <code>cl</code> is null, or is not <code>Serializable</code>,
- null is returned. <code>ObjectStreamClass</code>'s are memoized;
- later calls to this method with the same class will return the
- same <code>ObjectStreamClass</code> object and no recalculation
- will be done.
-
- @see java.io.Serializable
- */
- public static ObjectStreamClass lookup (Class cl)
- {
- if (cl == null)
- return null;
-
- ObjectStreamClass osc = (ObjectStreamClass)classLookupTable.get (cl);
-
- if (osc != null)
- return osc;
- else if (! (Serializable.class).isAssignableFrom (cl))
- return null;
- else
- {
- osc = new ObjectStreamClass (cl);
- classLookupTable.put (cl, osc);
- return osc;
- }
- }
-
-
- /**
- Returns the name of the class that this
- <code>ObjectStreamClass</code> represents.
- */
- public String getName ()
- {
- return name;
- }
-
-
- /**
- Returns the class that this <code>ObjectStreamClass</code>
- represents. Null could be returned if this
- <code>ObjectStreamClass</code> was read from an
- <code>ObjectInputStream</code> and the class it represents cannot
- be found or loaded.
-
- @see java.io.ObjectInputStream
- */
- public Class forClass ()
- {
- return clazz;
- }
-
-
- /**
- Returns the serial version stream-unique identifier for the class
- represented by this <code>ObjectStreamClass</code>. This SUID is
- either defined by the class as <code>static final long
- serialVersionUID</code> or is calculated as specified in
- Javasoft's "Object Serialization Specification" XXX: add reference
- */
- public long getSerialVersionUID ()
- {
- return uid;
- }
-
-
- // Returns the serializable (non-static and non-transient) Fields
- // of the class represented by this ObjectStreamClass. The Fields
- // are sorted by name.
- // XXX doc
- public ObjectStreamField[] getFields ()
- {
- ObjectStreamField[] copy = new ObjectStreamField[ fields.length ];
- System.arraycopy (fields, 0, copy, 0, fields.length);
- return copy;
- }
-
-
- // XXX doc
- // Can't do binary search since fields is sorted by name and
- // primitiveness.
- public ObjectStreamField getField (String name)
- {
- for (int i=0; i < fields.length; i++)
- if (fields[i].getName ().equals (name))
- return fields[i];
- return null;
- }
-
-
- /**
- Returns a textual representation of this
- <code>ObjectStreamClass</code> object including the name of the
- class it represents as well as that class's serial version
- stream-unique identifier.
-
- @see getSerialVersionUID ()
- @see getName ()
- */
- public String toString ()
- {
- return "java.io.ObjectStreamClass< " + name + ", " + uid + " >";
- }
-
-
- // Returns true iff the class that this ObjectStreamClass represents
- // has the following method:
- //
- // private void writeObject (ObjectOutputStream)
- //
- // This method is used by the class to override default
- // serialization behaivior.
- boolean hasWriteMethod ()
- {
- return (flags & ObjectStreamConstants.SC_WRITE_METHOD) != 0;
- }
-
-
- // Returns true iff the class that this ObjectStreamClass represents
- // implements Serializable but does *not* implement Externalizable.
- boolean isSerializable ()
- {
- return (flags & ObjectStreamConstants.SC_SERIALIZABLE) != 0;
- }
-
-
- // Returns true iff the class that this ObjectStreamClass represents
- // implements Externalizable.
- boolean isExternalizable ()
- {
- return (flags & ObjectStreamConstants.SC_EXTERNALIZABLE) != 0;
- }
-
-
- // Returns the <code>ObjectStreamClass</code> that represents the
- // class that is the superclass of the class this
- // <code>ObjectStreamClass</cdoe> represents. If the superclass is
- // not Serializable, null is returned.
- ObjectStreamClass getSuper ()
- {
- return superClass;
- }
-
-
- // returns an array of ObjectStreamClasses that represent the super
- // classes of CLAZZ and CLAZZ itself in order from most super to
- // CLAZZ. ObjectStreamClass[0] is the highest superclass of CLAZZ
- // that is serializable.
- static ObjectStreamClass[] getObjectStreamClasses (Class clazz)
- {
- ObjectStreamClass osc = ObjectStreamClass.lookup (clazz);
-
- ObjectStreamClass[] ret_val;
-
- if (osc == null)
- return new ObjectStreamClass[0];
- else
- {
- Vector oscs = new Vector ();
-
- while (osc != null)
- {
- oscs.addElement (osc);
- osc = osc.getSuper ();
- }
-
- int count = oscs.size ();
- ObjectStreamClass[] sorted_oscs = new ObjectStreamClass[ count ];
-
- for (int i = count - 1; i >= 0; i--)
- sorted_oscs[ count - i - 1 ] = (ObjectStreamClass)oscs.elementAt (i);
-
- return sorted_oscs;
- }
- }
-
-
- // Returns an integer that consists of bit-flags that indicate
- // properties of the class represented by this ObjectStreamClass.
- // The bit-flags that could be present are those defined in
- // ObjectStreamConstants that begin with `SC_'
- int getFlags ()
- {
- return flags;
- }
-
-
- ObjectStreamClass (String name, long uid, byte flags,
- ObjectStreamField[] fields)
- {
- this.name = name;
- this.uid = uid;
- this.flags = flags;
- this.fields = fields;
- }
-
-
- void setClass (Class clazz)
- {
- this.clazz = clazz;
- }
-
-
- void setSuperclass (ObjectStreamClass osc)
- {
- superClass = osc;
- }
-
-
- void calculateOffsets ()
- {
- int i;
- ObjectStreamField field;
- primFieldSize = 0;
- int fcount = fields.length;
- for (i = 0; i < fcount; ++ i)
- {
- field = fields[i];
-
- if (! field.isPrimitive ())
- break;
-
- field.setOffset (primFieldSize);
- switch (field.getTypeCode ())
- {
- case 'B':
- case 'Z':
- ++ primFieldSize;
- break;
- case 'C':
- case 'S':
- primFieldSize += 2;
- break;
- case 'I':
- case 'F':
- primFieldSize += 4;
- break;
- case 'D':
- case 'J':
- primFieldSize += 8;
- break;
- }
- }
-
- for (objectFieldCount = 0; i < fcount; ++ i)
- fields[i].setOffset (objectFieldCount++);
- }
-
-
- private ObjectStreamClass (Class cl)
- {
- uid = 0;
- flags = 0;
-
- clazz = cl;
- name = cl.getName ();
- setFlags (cl);
- setFields (cl);
- setUID (cl);
- superClass = lookup (cl.getSuperclass ());
- }
-
-
- // Sets bits in flags according to features of CL.
- private void setFlags (Class cl)
- {
- if ((java.io.Externalizable.class).isAssignableFrom (cl))
- flags |= ObjectStreamConstants.SC_EXTERNALIZABLE;
- else if ((java.io.Serializable.class).isAssignableFrom (cl))
- // only set this bit if CL is NOT Externalizable
- flags |= ObjectStreamConstants.SC_SERIALIZABLE;
-
- try
- {
- Method writeMethod = cl.getDeclaredMethod ("writeObject",
- writeMethodArgTypes);
- int modifiers = writeMethod.getModifiers ();
-
- if (writeMethod.getReturnType () == Void.TYPE
- && Modifier.isPrivate (modifiers)
- && !Modifier.isStatic (modifiers))
- flags |= ObjectStreamConstants.SC_WRITE_METHOD;
- }
- catch (NoSuchMethodException oh_well)
- {}
- }
-
-
- // Sets fields to be a sorted array of the serializable fields of
- // clazz.
- private void setFields (Class cl)
- {
- if (! isSerializable () || isExternalizable ())
- {
- fields = NO_FIELDS;
- return;
- }
-
- try
- {
- Field serialPersistantFields
- = cl.getDeclaredField ("serialPersistantFields");
- int modifiers = serialPersistantFields.getModifiers ();
-
- if (Modifier.isStatic (modifiers)
- && Modifier.isFinal (modifiers)
- && Modifier.isPrivate (modifiers))
- {
- fields = getSerialPersistantFields (cl);
- Arrays.sort (fields);
- calculateOffsets ();
- return;
- }
- }
- catch (NoSuchFieldException ignore)
- {}
-
- int num_good_fields = 0;
- Field[] all_fields = cl.getDeclaredFields ();
-
- int modifiers;
- // set non-serializable fields to null in all_fields
- for (int i=0; i < all_fields.length; i++)
- {
- modifiers = all_fields[i].getModifiers ();
- if (Modifier.isTransient (modifiers)
- || Modifier.isStatic (modifiers))
- all_fields[i] = null;
- else
- num_good_fields++;
- }
-
- // make a copy of serializable (non-null) fields
- fields = new ObjectStreamField[ num_good_fields ];
- for (int from=0, to=0; from < all_fields.length; from++)
- if (all_fields[from] != null)
- {
- Field f = all_fields[from];
- fields[to] = new ObjectStreamField (f.getName (), f.getType ());
- to++;
- }
-
- Arrays.sort (fields);
- calculateOffsets ();
- }
-
- // Sets uid be serial version UID defined by class, or if that
- // isn't present, calculates value of serial version UID.
- private void setUID (Class cl)
- {
- try
- {
- Field suid = cl.getDeclaredField ("serialVersionUID");
- int modifiers = suid.getModifiers ();
-
- if (Modifier.isStatic (modifiers)
- && Modifier.isFinal (modifiers))
- {
- uid = getDefinedSUID (cl);
- return;
- }
- }
- catch (NoSuchFieldException ignore)
- {}
-
- // cl didn't define serialVersionUID, so we have to compute it
- try
- {
- MessageDigest md = null;
- DigestOutputStream digest_out = null;
- DataOutputStream data_out = null;
-
- try
- {
- md = MessageDigest.getInstance ("SHA");
- }
- catch (NoSuchAlgorithmException e)
- {
- // If a provider already provides SHA, use it; otherwise, use this.
- Gnu gnuProvider = new Gnu();
- Security.addProvider(gnuProvider);
- md = MessageDigest.getInstance ("SHA");
- }
-
- digest_out = new DigestOutputStream (nullOutputStream, md);
- data_out = new DataOutputStream (digest_out);
- data_out.writeUTF (cl.getName ());
-
- int modifiers = cl.getModifiers ();
- // just look at interesting bits
- modifiers = modifiers & (Modifier.ABSTRACT | Modifier.FINAL
- | Modifier.INTERFACE | Modifier.PUBLIC);
- data_out.writeInt (modifiers);
-
- Class[] interfaces = cl.getInterfaces ();
- Arrays.sort (interfaces, interfaceComparator);
- for (int i=0; i < interfaces.length; i++)
- data_out.writeUTF (interfaces[i].getName ());
-
-
- Field field;
- Field[] fields = cl.getDeclaredFields ();
- Arrays.sort (fields, memberComparator);
- for (int i=0; i < fields.length; i++)
- {
- field = fields[i];
- modifiers = field.getModifiers ();
- if (Modifier.isPrivate (modifiers)
- && (Modifier.isStatic (modifiers)
- || Modifier.isTransient (modifiers)))
- continue;
-
- data_out.writeUTF (field.getName ());
- data_out.writeInt (modifiers);
- data_out.writeUTF (TypeSignature.getEncodingOfClass (field.getType ()));
- }
-
- // write class initializer method if present
- boolean has_init;
- try
- {
- has_init = hasClassInitializer (cl);
- }
- catch (NoSuchMethodError e)
- {
- has_init = false;
- }
-
- if (has_init)
- {
- data_out.writeUTF ("<clinit>");
- data_out.writeInt (Modifier.STATIC);
- data_out.writeUTF ("()V");
- }
-
- Constructor constructor;
- Constructor[] constructors = cl.getDeclaredConstructors ();
- Arrays.sort (constructors, memberComparator);
- for (int i=0; i < constructors.length; i++)
- {
- constructor = constructors[i];
- modifiers = constructor.getModifiers ();
- if (Modifier.isPrivate (modifiers))
- continue;
-
- data_out.writeUTF ("<init>");
- data_out.writeInt (modifiers);
-
- // the replacement of '/' with '.' was needed to make computed
- // SUID's agree with those computed by JDK
- data_out.writeUTF (
- TypeSignature.getEncodingOfConstructor (constructor).replace ('/','.'));
- }
-
- Method method;
- Method[] methods = cl.getDeclaredMethods ();
- Arrays.sort (methods, memberComparator);
- for (int i=0; i < methods.length; i++)
- {
- method = methods[i];
- modifiers = method.getModifiers ();
- if (Modifier.isPrivate (modifiers))
- continue;
-
- data_out.writeUTF (method.getName ());
- data_out.writeInt (modifiers);
-
- // the replacement of '/' with '.' was needed to make computed
- // SUID's agree with those computed by JDK
- data_out.writeUTF (
- TypeSignature.getEncodingOfMethod (method).replace ('/', '.'));
- }
-
- data_out.close ();
- byte[] sha = md.digest ();
- long result = 0;
- int len = sha.length < 8 ? sha.length : 8;
- for (int i=0; i < len; i++)
- result += (long)(sha[i] & 0xFF) << (8 * i);
-
- uid = result;
- }
- catch (NoSuchAlgorithmException e)
- {
- throw new RuntimeException ("The SHA algorithm was not found to use in computing the Serial Version UID for class "
- + cl.getName ());
- }
- catch (IOException ioe)
- {
- throw new RuntimeException (ioe.getMessage ());
- }
- }
-
-
- // Returns the value of CLAZZ's final static long field named
- // `serialVersionUID'.
- private long getDefinedSUID (Class clazz)
- {
- long l = 0;
- try
- {
- // Use getDeclaredField rather than getField, since serialVersionUID
- // may not be public AND we only want the serialVersionUID of this
- // class, not a superclass or interface.
- Field f = clazz.getDeclaredField ("serialVersionUID");
- l = f.getLong (null);
- }
- catch (java.lang.NoSuchFieldException e)
- {
- }
-
- catch (java.lang.IllegalAccessException e)
- {
- }
-
- return l;
- }
-
- // Returns the value of CLAZZ's private static final field named
- // `serialPersistantFields'.
- private ObjectStreamField[] getSerialPersistantFields (Class clazz)
- {
- ObjectStreamField[] o = null;
- try
- {
- // Use getDeclaredField rather than getField for the same reason
- // as above in getDefinedSUID.
- Field f = clazz.getDeclaredField ("getSerialPersistantFields");
- o = (ObjectStreamField[])f.get (null);
- }
- catch (java.lang.NoSuchFieldException e)
- {
- }
- catch (java.lang.IllegalAccessException e)
- {
- }
-
- return o;
- }
-
-
- // Returns true if CLAZZ has a static class initializer
- // (a.k.a. <clinit>).
- //
- // A NoSuchMethodError is raised if CLAZZ has no such method.
- private static boolean hasClassInitializer (Class clazz)
- throws java.lang.NoSuchMethodError
- {
- Method m = null;
-
- try
- {
- Class classArgs[] = {};
- m = clazz.getMethod ("<clinit>", classArgs);
- }
- catch (java.lang.NoSuchMethodException e)
- {
- throw new java.lang.NoSuchMethodError ();
- }
-
- return m != null;
- }
-
- public static final ObjectStreamField[] NO_FIELDS = {};
-
- private static Hashtable classLookupTable = new Hashtable ();
- private static final NullOutputStream nullOutputStream = new NullOutputStream ();
- private static final Comparator interfaceComparator = new InterfaceComparator ();
- private static final Comparator memberComparator = new MemberComparator ();
- private static final
- Class[] writeMethodArgTypes = { java.io.ObjectOutputStream.class };
-
- private ObjectStreamClass superClass;
- private Class clazz;
- private String name;
- private long uid;
- private byte flags;
-
- // this field is package protected so that ObjectInputStream and
- // ObjectOutputStream can access it directly
- ObjectStreamField[] fields;
-
- // these are accessed by ObjectIn/OutputStream
- int primFieldSize = -1; // -1 if not yet calculated
- int objectFieldCount;
-}
-
-
-// interfaces are compared only by name
-class InterfaceComparator implements Comparator
-{
- public int compare (Object o1, Object o2)
- {
- return ((Class)o1).getName ().compareTo (((Class)o2).getName ());
- }
-}
-
-
-// Members (Methods and Constructors) are compared first by name,
-// conflicts are resolved by comparing type signatures
-class MemberComparator implements Comparator
-{
- public int compare (Object o1, Object o2)
- {
- Member m1 = (Member)o1;
- Member m2 = (Member)o2;
-
- int comp = m1.getName ().compareTo (m2.getName ());
-
- if (comp == 0)
- return TypeSignature.getEncodingOfMember (m1).
- compareTo (TypeSignature.getEncodingOfMember (m2));
- else
- return comp;
- }
-}