/*
 * Copyright 1998-2004 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.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;
};
