/* Externalizable.java -- Interface for saving and restoring object data
   Copyright (C) 1998 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.io;

/**
 * This interface provides a way that classes can completely control how
 * the data of their object instances  are written and read to and from 
 * streams.  It has two methods which are used to write the data to a stream 
 * and to read the data from a stream.  The read method must read the data 
 * in exactly the way it was written by the write method. 
 * <p>
 * Note that classes which implement this interface must take into account
 * that all superclass data must also be written to the stream as well.  
 * The class implementing this interface must figure out how to make that
 * happen.
 * <p>
 * This interface can be used to provide object persistence.  When an 
 * object is to be stored externally, the <code>writeExternal</code> method is
 * called to save state.  When the object is restored, an instance is
 * created using the default no-argument constructor and the 
 * <code>readExternal</code> method is used to restore the state.
 *
 * @author Aaron M. Renn (arenn@urbanophile.com)
 */
public interface Externalizable extends Serializable
{
  /**
   * This method restores an object's state by reading in the instance data
   * for the object from the passed in stream.  Note that this stream is not
   * a subclass of <code>InputStream</code>, but rather is a class that 
   * implements
   * the <code>ObjectInput</code> interface.  That interface provides a 
   * mechanism for
   * reading in Java data types from a stream.
   * <p>
   * Note that this method must be compatible with <code>writeExternal</code>.
   * It must read back the exact same types that were written by that
   * method in the exact order they were written.
   * <p>
   * If this method needs to read back an object instance, then the class
   * for that object must be found and loaded.  If that operation fails,
   * then this method throws a <code>ClassNotFoundException</code>
   *
   * @param in An <code>ObjectInput</code> instance for reading in the object 
   * state
   *
   * @exception ClassNotFoundException If the class of an object being 
   * restored cannot be found
   * @exception IOException If any other error occurs
   */
  void readExternal(ObjectInput in) 
    throws ClassNotFoundException, IOException;

  /**
   * This method is responsible for writing the instance data of an object
   * to the passed in stream.  Note that this stream is not a subclass of
   * <code>OutputStream</code>, but rather is a class that implements the
   * <code>ObjectOutput</code> interface.  That interface provides a 
   * number of methods
   * for writing Java data values to a stream.
   * <p>
   * Not that the implementation of this method must be coordinated with
   * the implementation of <code>readExternal</code>.
   *
   * @param out An <code>ObjectOutput</code> instance for writing the 
   * object state
   *
   * @exception IOException If an error occurs
   */
  void writeExternal(ObjectOutput out) throws IOException;
}
