diff options
Diffstat (limited to 'libjava/java/io/ObjectStreamClass.java')
-rw-r--r-- | libjava/java/io/ObjectStreamClass.java | 668 |
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; - } -} |