blob: e1088dfaedbcaa5f0d0e5e4e9f35812664be38c0 [file] [log] [blame]
/*
* Copyright (c) 1998, 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
*
*/
import java.io.*;
import java.util.Vector;
import java.util.Stack;
import java.util.Hashtable;
import java.lang.Math;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
/**
* This abstract class enables one to subclass ObjectInputStream
* for the purpose of re-implementing serialization while preserving the
* existing public serialization API. A complimentary subclass of
* AbstractObjectInputStream must also be implemented.<p>
*
* Since serialization must override java access rules in order to
* access private, protected and package accessible Serializable fields,
* only trusted classes are allowed to subclass AbstractObjectInputStream.
* Subclasses of AbstractObjectInputStream must define SerializablePermission
* "enableAbstractSubclass" within a security policy file or this
* constructor will throw a SecurityException. Implementations of this
* class should protect themselves from being subclassed in a way that will
* provide access to object references and other sensitive info.
* Specifically, readObjectOverride() should be made final.
* <p>
*
* A subclass of AbstractObjectInputStream deserializes primitive data and
* objects previously written by a subclass of AbstractObjectOutputStream.
* The subclass ensures that the types of all objects in the graph created
* from the stream match the classes present in the Java Virtual Machine.
* Classes are loaded as required using the standard mechanisms. <p>
*
* Only objects that support the java.io.Serializable or
* java.io.Externalizable interface can be read from streams.
*
* The method <STRONG>readObjectOverride</STRONG> is used to read an object
* from the stream. Java's safe casting should be used to get the
* desired type. In Java, strings and arrays are objects and are
* treated as objects during serialization. When read with readObject()
* they need to be cast to the expected type.<p>
*
* Primitive data types can be read from the stream using the appropriate
* method on DataInput. <p>
*
* The default deserialization mechanism for objects restores the
* contents of each field to the value and type it had when it was written.
* References to other objects cause those
* objects to be read from the stream as necessary. Graphs of objects
* are restored correctly using a reference sharing mechanism. New
* objects are always allocated when deserializing, which prevents
* existing objects from being overwritten. <p>
*
* Reading an object is analogous to running the constructors of a new
* object. Memory is allocated for the object and initialized to zero
* (NULL). No-arg constructors are invoked for the first non-serializable
* super class and then the fields of the serializable classes are
* restored from the stream starting with the serializable class closest to
* java.lang.object and finishing with the object's most specifiec
* class. <p>
*
* Classes control how they are serialized by implementing either the
* java.io.Serializable or java.io.Externalizable interfaces.<P>
*
* Implementing the Serializable interface allows object serialization
* to save and restore the entire state of the object and it allows
* classes to evolve between the time the stream is written and the time it is
* read. It automatically traverses references between objects,
* saving and restoring entire graphs.
*
* Serializable classes that require special handling during the
* serialization and deserialization process should implement both
* of these methods:<p>
*
* <PRE>
* private void writeObject(java.io.ObjectOutputStream stream)
* throws IOException;
* private void readObject(java.io.ObjectInputStream stream)
* throws IOException, ClassNotFoundException;
* </PRE><p>
*
* The readObject method is responsible for reading and restoring the
* state of the object for its particular class using data written to
* the stream by the corresponding writeObject method. The method
* does not need to concern itself with the state belonging to its
* superclasses or subclasses. State is restored by reading data from
* the ObjectInputStream for the individual fields and making
* assignments to the appropriate fields of the object. Reading
* primitive data types is supported by DataInput. <p>
*
* Serialization does not read or assign values to the fields of any
* object that does not implement the java.io.Serializable interface.
* Subclasses of Objects that are not serializable can be
* serializable. In this case the non-serializable class must have an
* accessible no-arg constructor to allow its fields to be initialized.
* In this case it is the responsibility of the subclass to save and restore
* the state of the non-serializable class. It is frequently the case that
* the fields of that class are accessible (public, package, or
* protected) or that there are get and set methods that can be used
* to restore the state. <p>
*
* Implementing the Externalizable interface allows the object to
* assume complete control over the contents and format of the object's
* serialized form. The methods of the Externalizable interface,
* writeExternal and readExternal, are called to save and restore the
* objects state. When implemented by a class they can write and read
* their own state using all of the methods of ObjectOutput and
* ObjectInput. It is the responsibility of the objects to handle any
* versioning that occurs.
*
* @author Joe Fialli
*
* @see java.io.ObjectInputStream
* @see java.io.DataInput
* @see java.io.Serializable
* @see java.io.Externalizable
* @see java.io.ext.AbstractObjectOutputStream
* @since JDK1.2
*/
abstract public class AbstractObjectInputStream extends ObjectInputStream
{
protected InputStream in;
/**
* Create an ObjectInputStream that reads from the specified InputStream.<p>
*
* Add the following line to the security policy file to enable
* subclassing.
*
* <PRE>
* permission SerializablePermission "enableAbstractSubclass" ;
* </PRE><p>
*
* @exception StreamCorruptedException The version or magic number are incorrect.
* @exception IOException An exception occurred in the underlying stream.
* @exception SecurityException if subclass does not have SerializablePermiision
* "enableAbstractSubclass".
*/
public AbstractObjectInputStream(InputStream in)
throws IOException, StreamCorruptedException
{
this.in = in;
}
abstract public void close() throws IOException;
/***************************************************************/
/* Read an object from the stream. */
/**
* Read an object from the ObjectInputStream.<p>
*
* NOTE: The override method of this class should have the modifier final.<p>
*
* Default deserializing for a class can be
* overriden by defining a readObject method for the Serializable class.
* Objects referenced by this object are read transitively so
* that a complete equivalent graph of objects is reconstructed by
* readObject. <p>
*
* The root object is completely restored when all of its fields
* and the objects it references are completely restored. At this
* point the object validation callbacks are executed in order
* based on their registered priorities. The callbacks are
* registered by objects (in the readObject special methods)
* as they are individually restored. <p>
*
* For security's sake, any overrides of this method should be final.
* Serialization typically needs to disable java access rules
* to serialize private, protected and package accessible Serializable
* fields. This method gets called for ALL Serializable objects.
*
* @exception java.lang.ClassNotFoundException Class of a serialized object
* cannot be found.
* @exception InvalidClassException Something is wrong with a class used by
* serialization.
* @exception StreamCorruptedException Control information in the
* stream is inconsistent.
* @exception OptionalDataException Primitive data was found in the
* stream instead of objects.
* @exception IOException Any of the usual Input/Output related exceptions.
*
* @see java.io.ObjectInputStream#resolveObject(Object)
* @see java.io.Resolvable
* @see java.io.Externalizable
* @see java.io.ObjectInputValidation
* @see #registerValidation(ObjectInputValidation, int)
* @see java.io.ObjectInputStream#resolveClass(ObjectStreamClass)
*/
protected Object readObjectOverride()
throws OptionalDataException, ClassNotFoundException, IOException {
return null;
}
/**
* Read the Serializable fields of the current object from this stream.<p>
*
* Note: The object being deserialized is not passed to this method.
* For security purposes, the initial implementation maintained
* the state of the last object to be read by readObject
* only allowed this method to be invoked for this object.<p>
*
* @exception NotActiveException Thrown if a readObject method is not
* active.
* @exception ClassNotFoundException if no corresponding local class can be
* found in the local JVM.
*/
abstract public void defaultReadObject()
throws IOException, ClassNotFoundException, NotActiveException;
/**
* Enable allocation for subclass reimplementing serialization.<p>
*
* Note: Default allocation does not have the java access priviledges
* to invoke package and protected constructors.<p>
*
* Security alert: this JVM native method is private within ObjectInputStream; however,
* it was anticipated that re-implementors of serialization would need
* access to this method. Is this allocator considered a security problem? <p>
*
* @param ctorClass is the same class or a superclass of <STRONG>ofClass</STRONG>
* @param ofClass the type of the object to allocate.
* @return an object of <STRONG>ofClass</STRONG> type.
*
* @exception IllegalAccessException if no-arg constructor of
* <STRONG>ctorClass</STRONG> is not accessible from
* <STRONG>ofClass</STRONG>.
* @exception InstantiationException TBD.
*/
final protected native Object
allocateNewObject(Class ofClass, Class ctorClass)
throws InstantiationException, IllegalAccessException;
/**
* Enable allocation for subclass reimplementing serialization.<p>
*
* Note: Default allocation does not have the java access priviledges
* to invoke package and protected constructors.<p>
*
* Security alert: this JVM native method is private within ObjectInputStream; however,
* it was anticipated that re-implementors of serialization would need
* access to this method. Is this allocator considered a security problem?<p>
*
*
* @exception IllegalAccessException TBD.
* @exception InstantiationException TBD.
*/
final protected native Object
allocateNewArray(Class componentClass, int length)
throws InstantiationException, IllegalAccessException;
/**
* Reads the Serializable fields from the stream into a buffer
* and makes the fields available by name.
*
* @exception java.lang.ClassNotFoundException if the class of a serialized
* object could not be found.
* @exception IOException if an I/O error occurs.
* @exception NotActiveException if readObject() is not currently active.
*/
abstract public ObjectInputStream.GetField readFields()
throws IOException, ClassNotFoundException, NotActiveException;
abstract protected boolean enableResolveObject(boolean enable) throws SecurityException;
abstract public void registerValidation(ObjectInputValidation obj,
int prio)
throws NotActiveException, InvalidObjectException;
/****************************************************************/
/* Use DataInput methods to read primitive data from the stream. */
abstract public int read() throws IOException;
abstract public int read(byte[] data, int offset, int length)
throws IOException;
abstract public boolean readBoolean() throws IOException;
abstract public byte readByte() throws IOException;
abstract public int readUnsignedByte() throws IOException;
abstract public short readShort() throws IOException;
abstract public int readUnsignedShort() throws IOException;
abstract public char readChar() throws IOException;
abstract public int readInt() throws IOException;
abstract public long readLong() throws IOException;
abstract public float readFloat() throws IOException;
abstract public double readDouble() throws IOException;
abstract public void readFully(byte[] data) throws IOException;
abstract public void readFully(byte[] data, int offset, int size) throws IOException;
abstract public String readUTF() throws IOException;
abstract public int available() throws IOException;
abstract public int skipBytes(int len) throws IOException;
/* @deprecated */
abstract public String readLine() throws IOException;
};