/* ObjectStreamField.java -- Class used to store name and class of fields
   Copyright (C) 1998, 1999, 2003, 2004, 2005  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;

import gnu.java.lang.reflect.TypeSignature;

import java.lang.reflect.Field;
import java.security.AccessController;
import java.security.PrivilegedAction;

/**
 * This class intends to describe the field of a class for the serialization
 * subsystem. Serializable fields in a serializable class can be explicitly
 * exported using an array of ObjectStreamFields.
 *
 * @author Tom Tromey (tromey@redhat.com)
 * @author Jeroen Frijters (jeroen@frijters.net)
 * @author Guilhem Lavaux (guilhem@kaffe.org)
 * @author Michael Koch (konqueror@gmx.de)
 * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
 */
public class ObjectStreamField 
  implements Comparable<Object>
{
  private String name;
  private Class<?> type;
  private String typename;
  private int offset = -1; // XXX make sure this is correct
  private boolean unshared;
  private boolean persistent = false;
  private boolean toset = true;
  Field field;

  ObjectStreamField (Field field)
  {
    this (field.getName(), field.getType());
    this.field = field;
  }

  /**
   * This constructor creates an ObjectStreamField instance 
   * which represents a field named <code>name</code> and is
   * of the type <code>type</code>.
   *
   * @param name Name of the field to export.
   * @param type Type of the field in the concerned class.
   */
  public ObjectStreamField (String name, Class<?> type)
  {
    this (name, type, false);
  }

  /**
   * This constructor creates an ObjectStreamField instance 
   * which represents a field named <code>name</code> and is
   * of the type <code>type</code>.
   *
   * @param name Name of the field to export.
   * @param type Type of the field in the concerned class.
   * @param unshared true if field will be unshared, false otherwise.
   */
  public ObjectStreamField (String name, Class<?> type, boolean unshared)
  {
    if (name == null)
      throw new NullPointerException();

    this.name = name;
    this.type = type;
    this.typename = TypeSignature.getEncodingOfClass(type);
    this.unshared = unshared;
  }
 
  /**
   * There are many cases you can not get java.lang.Class from typename 
   * if your context class loader cannot load it, then use typename to
   * construct the field.
   *
   * @param name Name of the field to export.
   * @param typename The coded name of the type for this field.
   */
  ObjectStreamField (String name, String typename)
  {
    this.name = name;
    this.typename = typename;
  }

  void resolveType(ClassLoader loader)
  {
    try
      {
        type = TypeSignature.getClassForEncoding(typename, true, loader);
      }
    catch(ClassNotFoundException e)
      {
      }
  }
  
  /**
   * This method returns the name of the field represented by the
   * ObjectStreamField instance.
   *
   * @return A string containing the name of the field.
   */
  public String getName ()
  {
    return name;
  }

  /**
   * This method returns the class representing the type of the
   * field which is represented by this instance of ObjectStreamField.
   *
   * @return A class representing the type of the field.
   */
  public Class<?> getType ()
  {
    return type;
  }

  /**
   * This method returns the char encoded type of the field which
   * is represented by this instance of ObjectStreamField.
   *
   * @return A char representing the type of the field.
   */
  public char getTypeCode ()
  {
    return typename.charAt (0);
  }

  /**
   * This method returns a more explicit type name than
   * {@link #getTypeCode()} in the case the type is a real
   * class (and not a primitive).
   *
   * @return The name of the type (class name) if it is not a 
   * primitive, in the other case null is returned.
   */
  public String getTypeString ()
  {
    // use intern()
    if (isPrimitive())
      return null;
    return typename.intern();
  }

  /**
   * This method returns the current offset of the field in
   * the serialization stream relatively to the other fields.
   * The offset is expressed in bytes.
   *
   * @return The offset of the field in bytes.
   * @see #setOffset(int)
   */
  public int getOffset ()
  {
    return offset;
  }

  /**
   * This method sets the current offset of the field.
   * 
   * @param off The offset of the field in bytes.
   * @see #getOffset()
   */
  protected void setOffset (int off)
  {
    offset = off;
  }

  /**
   * This method returns whether the field represented by this object is
   * unshared or not.
   *
   * @return Tells if this field is unshared or not.
   */
  public boolean isUnshared ()
  {
    return unshared;
  }

  /**
   * This method returns true if the type of the field
   * represented by this instance is a primitive.
   *
   * @return true if the type is a primitive, false
   * in the other case.
   */
  public boolean isPrimitive ()
  {
    return typename.length() == 1;
  }

  /**
   * Compares this object to the given object.
   *
   * @param obj the object to compare to.
   *
   * @return -1, 0 or 1.
   */
  public int compareTo (Object obj)
  {
    ObjectStreamField f = (ObjectStreamField) obj;
    boolean this_is_primitive = isPrimitive ();
    boolean f_is_primitive = f.isPrimitive ();

    if (this_is_primitive && !f_is_primitive)
      return -1;

    if (!this_is_primitive && f_is_primitive)
      return 1;

    return getName ().compareTo (f.getName ());
  }

  /**
   * This method is specific to classpath's implementation and so has the default
   * access. It changes the state of this field to "persistent". It means that
   * the field should not be changed when the stream is read (if it is not
   * explicitly specified using serialPersistentFields).
   *
   * @param persistent True if the field is persistent, false in the 
   * other cases.
   * @see #isPersistent()
   */
  void setPersistent(boolean persistent)
  {
    this.persistent = persistent;
  }

  /**
   * This method returns true if the field is marked as persistent.
   *
   * @return True if persistent, false in the other cases.
   * @see #setPersistent(boolean)
   */
  boolean isPersistent()
  {
    return persistent;
  }

  /**
   * This method is specific to classpath's implementation and so 
   * has the default access. It changes the state of this field as
   * to be set by ObjectInputStream.
   *
   * @param toset True if this field should be set, false in the other
   * cases.
   * @see #isToSet()
   */
  void setToSet(boolean toset)
  {
    this.toset = toset;
  }

  /**
   * This method returns true if the field is marked as to be
   * set.
   *
   * @return True if it is to be set, false in the other cases.
   * @see #setToSet(boolean)
   */
  boolean isToSet()
  {
    return toset;
  }

  /**
   * This method searches for its field reference in the specified class
   * object. It requests privileges. If an error occurs the internal field
   * reference is not modified.
   *
   * @throws NoSuchFieldException if the field name does not exist in this class.
   * @throws SecurityException if there was an error requesting the privileges.
   */
  void lookupField(Class clazz) throws NoSuchFieldException, SecurityException
  {
    final Field f = clazz.getDeclaredField(name);
    
    AccessController.doPrivileged(new PrivilegedAction()
      {
	public Object run()
	{
	  f.setAccessible(true);
	  return null;
	}
      });
    
    this.field = f;
  }

  /**
   * This method check whether the field described by this
   * instance of ObjectStreamField is compatible with the
   * actual implementation of this field.
   *
   * @throws NullPointerException if this field does not exist
   * in the real class.
   * @throws InvalidClassException if the types are incompatible.
   */
  void checkFieldType() throws InvalidClassException
  {
    Class<?> ftype = field.getType();

    if (!ftype.isAssignableFrom(type))
      throw new InvalidClassException
	("invalid field type for " + name +
	 " in class " + field.getDeclaringClass());
  }

  /**
   * Returns a string representing this object.
   *
   * @return the string.
   */
  public String toString ()
  {
    return "ObjectStreamField< " + type + " " + name + " >";
  }

  final void setBooleanField(Object obj, boolean val)
  {
    VMObjectStreamClass.setBooleanNative(field, obj, val);  
  }

  final void setByteField(Object obj, byte val)
  {
    VMObjectStreamClass.setByteNative(field, obj, val);
  }
  
  final void setCharField(Object obj, char val)
  {
    VMObjectStreamClass.setCharNative(field, obj, val);
  }
  
  final void setShortField(Object obj, short val)
  {
    VMObjectStreamClass.setShortNative(field, obj, val);
  }

  final void setIntField(Object obj, int val)
  {
    VMObjectStreamClass.setIntNative(field, obj, val);
  }
  
  final void setLongField(Object obj, long val)
  {
    VMObjectStreamClass.setLongNative(field, obj, val);
  }
  
  final void setFloatField(Object obj, float val)
  {
    VMObjectStreamClass.setFloatNative(field, obj, val);
  }
  
  final void setDoubleField(Object obj, double val)
  {
    VMObjectStreamClass.setDoubleNative(field, obj, val);
  }
  
  final void setObjectField(Object obj, Object val)
  { 
    VMObjectStreamClass.setObjectNative(field, obj, val);
  }
}
