// ClassLoader.java - Define policies for loading Java classes.

/* Copyright (C) 1998, 1999, 2000  Free Software Foundation

   This file is part of libgcj.

This software is copyrighted work licensed under the terms of the
Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
details.  */

package java.lang;

import java.io.InputStream;
import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import java.util.Enumeration;
import java.util.Stack;

/**
 * The class <code>ClassLoader</code> is intended to be subclassed by
 * applications in order to describe new ways of loading classes,
 * such as over the network.
 *
 * @author  Kresten Krab Thorup
 */

public abstract class ClassLoader {

  static private ClassLoader system;
  private ClassLoader parent;

  public ClassLoader getParent ()
  {
    /* FIXME: security */
    return parent;
  }
    
  public static native ClassLoader getSystemClassLoader ();

  /**
   * Creates a <code>ClassLoader</code> with no parent.
   * @exception java.lang.SecurityException if not allowed
   */
  protected ClassLoader() 
  {
    this (null);
  }

  /**
   * Creates a <code>ClassLoader</code> with the given parent.   
   * The parent may be <code>null</code>.
   * The only thing this 
   * constructor does, is to call
   * <code>checkCreateClassLoader</code> on the current 
   * security manager. 
   * @exception java.lang.SecurityException if not allowed
   */
  protected ClassLoader(ClassLoader parent) 
  {
    SecurityManager security = System.getSecurityManager ();
    if (security != null)
      security.checkCreateClassLoader ();
    this.parent = parent;
  }

  /** 
   * Loads and link the class by the given name.
   * @param     name the name of the class.
   * @return    the class loaded.
   * @see       ClassLoader#loadClass(String,boolean)
   * @exception java.lang.ClassNotFoundException 
   */ 
  public Class loadClass(String name) 
    throws java.lang.ClassNotFoundException, java.lang.LinkageError
  { 
    return loadClass (name, false);
  }

  /** 
   * Loads the class by the given name.  The default implementation
   * will search for the class in the following order (similar to jdk 1.2)
   * <ul>
   *  <li> First <code>findLoadedClass</code>.
   *  <li> If parent is non-null, <code>parent.loadClass</code>;
   *       otherwise <code>findSystemClass</code>.
   *  <li> <code>findClass</code>.
   * </ul>
   * If <code>link</code> is true, <code>resolveClass</code> is then
   * called.  <p> Normally, this need not be overridden; override
   * <code>findClass</code> instead.
   * @param     name the name of the class.
   * @param     link if the class should be linked.
   * @return    the class loaded.
   * @exception java.lang.ClassNotFoundException 
   * @deprecated 
   */ 
  protected Class loadClass(String name, boolean link)
    throws java.lang.ClassNotFoundException, java.lang.LinkageError
  {
    Class c = findLoadedClass (name);

    if (c == null)
      {
	try {
	  if (parent != null)
	    return parent.loadClass (name, link);
	  else
	    c = findSystemClass (name);
	} catch (ClassNotFoundException ex) {
	  /* ignore, we'll try findClass */;
	}
      }

    if (c == null)
      c = findClass (name);

    if (c == null)
      throw new ClassNotFoundException (name);

    if (link)
      resolveClass (c);

    return c;
  }

  /** Find a class.  This should be overridden by subclasses; the
   *  default implementation throws ClassNotFoundException.
   *
   * @param name Name of the class to find.
   * @return     The class found.
   * @exception  java.lang.ClassNotFoundException
   */
  protected Class findClass (String name)
    throws ClassNotFoundException
  {
    throw new ClassNotFoundException (name);
  }

  /** 
   * Defines a class, given the class-data.  According to the JVM, this
   * method should not be used; instead use the variant of this method
   * in which the name of the class being defined is specified
   * explicitly.   
   * <P>
   * If the name of the class, as specified (implicitly) in the class
   * data, denotes a class which has already been loaded by this class
   * loader, an instance of
   * <code>java.lang.ClassNotFoundException</code> will be thrown.
   *
   * @param     data    bytes in class file format.
   * @param     off     offset to start interpreting data.
   * @param     len     length of data in class file.
   * @return    the class defined.
   * @exception java.lang.ClassNotFoundException 
   * @exception java.lang.LinkageError
   * @see ClassLoader#defineClass(String,byte[],int,int) */
  protected final Class defineClass(byte[] data, int off, int len) 
    throws ClassFormatError
  {
    return defineClass (null, data, off, len);
  }

  /** 
   * Defines a class, given the class-data.  This is preferable
   * over <code>defineClass(byte[],off,len)</code> since it is more
   * secure.  If the expected name does not match that of the class
   * file, <code>ClassNotFoundException</code> is thrown.  If
   * <code>name</code> denotes the name of an already loaded class, a
   * <code>LinkageError</code> is thrown.
   * <p>
   * 
   * FIXME: How do we assure that the class-file data is not being
   * modified, simultaneously with the class loader running!?  If this
   * was done in some very clever way, it might break security.  
   * Right now I am thinking that defineclass should make sure never to
   * read an element of this array more than once, and that that would
   * assure the ``immutable'' appearance.  It is still to be determined
   * if this is in fact how defineClass operates.
   *
   * @param     name    the expected name.
   * @param     data    bytes in class file format.
   * @param     off     offset to start interpreting data.
   * @param     len     length of data in class file.
   * @return    the class defined.
   * @exception java.lang.ClassNotFoundException 
   * @exception java.lang.LinkageError
   */
  protected final synchronized Class defineClass(String name,
						 byte[] data,
						 int off,
						 int len)
    throws ClassFormatError
  {
    if (data==null || data.length < off+len || off<0 || len<0)
      throw new ClassFormatError ("arguments to defineClass "
				  + "are meaningless");

    // as per 5.3.5.1
    if (name != null  &&  findLoadedClass (name) != null)
      throw new java.lang.LinkageError ("class " 
					+ name 
					+ " already loaded");

    try {
      // Since we're calling into native code here, 
      // we better make sure that any generated
      // exception is to spec!

      return defineClass0 (name, data, off, len);

    } catch (ClassFormatError x) {
      throw x;		// rethrow

    } catch (java.lang.VirtualMachineError x) {
      throw x;		// rethrow

    } catch (java.lang.Throwable x) {
      // This should never happen, or we are beyond spec.  
      
      throw new InternalError ("Unexpected exception "
			       + "while defining class "
			       + name + ": " 
			       + x.toString ());
    }
  }

  /** This is the entry point of defineClass into the native code */
  private native Class defineClass0 (String name,
				     byte[] data,
				     int off,
				     int len)
    throws ClassFormatError;


  /** 
   * Link the given class.  This will bring the class to a state where
   * the class initializer can be run.  Linking involves the following
   * steps: 
   * <UL>
   * <LI>  Prepare (allocate and internalize) the constant strings that
   *       are used in this class.
   * <LI>  Allocate storage for static fields, and define the layout
   *       of instance fields.
   * <LI>  Perform static initialization of ``static final'' int,
   *       long, float, double and String fields for which there is a
   *       compile-time constant initializer.
   * <LI>  Create the internal representation of the ``vtable''.
   * </UL>
   * For <code>gcj</code>-compiled classes, only the first step is
   * performed.  The compiler will have done the rest already.
   * <P>
   * This is called by the system automatically,
   * as part of class initialization; there is no reason to ever call
   * this method directly.  
   * <P> 
   * For historical reasons, this method has a name which is easily
   * misunderstood.  Java classes are never ``resolved''.  Classes are
   * linked; whereas method and field references are resolved.
   *
   * @param     clazz the class to link.
   * @exception java.lang.LinkageError
   */
  protected final void resolveClass(Class clazz)
    throws java.lang.LinkageError
  {
    resolveClass0(clazz);
  }

  static void resolveClass0(Class clazz)
    throws java.lang.LinkageError
  {
    synchronized (clazz)
      {
	try {
	  linkClass0 (clazz);
	} catch (Throwable x) {
	  markClassErrorState0 (clazz);

	  if (x instanceof Error)
	    throw (Error)x;
	  else    
	    throw new java.lang.InternalError
	      ("unexpected exception during linking: " + x);
	}
      }
  }

  /** Internal method.  Calls _Jv_PrepareClass and
   * _Jv_PrepareCompiledClass.  This is only called from resolveClass.  */ 
  private static native void linkClass0(Class clazz)
    throws java.lang.LinkageError;

  /** Internal method.  Marks the given clazz to be in an erroneous
   * state, and calls notifyAll() on the class object.  This should only
   * be called when the caller has the lock on the class object.  */
  private static native void markClassErrorState0(Class clazz);


  /** 
   * Returns a class found in a system-specific way, typically
   * via the <code>java.class.path</code> system property.  Loads the 
   * class if necessary.
   *
   * @param     name the class to resolve.
   * @return    the class loaded.
   * @exception java.lang.LinkageError 
   * @exception java.lang.ClassNotFoundException 
   */
  protected Class findSystemClass(String name) 
    throws java.lang.ClassNotFoundException, java.lang.LinkageError
  {
    return getSystemClassLoader ().loadClass (name);
  }

  /*
   * Does currently nothing.
   */ 
  protected final void setSigners(Class claz, Object[] signers) {
    /* claz.setSigners (signers); */
  }

  /**
   * If a class named <code>name</code> was previously loaded using
   * this <code>ClassLoader</code>, then it is returned.  Otherwise
   * it returns <code>null</code>.  (Unlike the JDK this is native,
   * since we implement the class table internally.)
   * @param     name  class to find.
   * @return    the class loaded, or null.
   */ 
  protected native Class findLoadedClass(String name);

  public static final InputStream getSystemResourceAsStream(String name) {
    return getSystemClassLoader().getResourceAsStream (name);
  }

  public static final URL getSystemResource(String name) {
    return getSystemClassLoader().getResource (name);
  }

  /**
   *   Return an InputStream representing the resource name.  
   *   This is essentially like 
   *   <code>getResource(name).openStream()</code>, except
   *   it masks out any IOException and returns null on failure.
   * @param   name  resource to load
   * @return  an InputStream, or null
   * @see     java.lang.ClassLoader#getResource(String)
   * @see     java.io.InputStream
   */
  public InputStream getResourceAsStream(String name) 
  {
    try {
      URL res = getResource (name);
      if (res == null) return null;
      return res.openStream ();
    } catch (java.io.IOException x) {
      return null;
    }
  }
 
  /**
   * Return an java.io.URL representing the resouce <code>name</code>.  
   * The default implementation just returns <code>null</code>.
   * @param   name  resource to load
   * @return  a URL, or null if there is no such resource.
   * @see     java.lang.ClassLoader#getResourceAsBytes(String)
   * @see     java.lang.ClassLoader#getResourceAsStream(String)
   * @see     java.io.URL
   */
  public URL getResource (String name) 
  {
    // The rules say search the parent class if non-null,
    // otherwise search the built-in class loader (assumed to be
    // the system ClassLoader).  If not found, call
    // findResource().
    URL result = null;

    ClassLoader delegate = parent;

    if (delegate == null)
      delegate = getSystemClassLoader ();
	
    // Protect ourselves from looping.
    if (this != delegate)
      result = delegate.getResource (name);

    if (result != null)
      return result;
    else
      return findResource (name);
  }

  protected URL findResource (String name)
  {
    // Default to returning null.  Derived classes implement this.
    return null;
  }

  public Enumeration getResources (String name) throws IOException
  {
    // The rules say search the parent class if non-null,
    // otherwise search the built-in class loader (assumed to be
    // the system ClassLoader).  If not found, call
    // findResource().
    Enumeration result = null;

    ClassLoader delegate = parent;

    if (delegate == null)
      delegate = getSystemClassLoader ();
	
    // Protect ourselves from looping.
    if (this != delegate)
      result = delegate.getResources (name);

    if (result != null)
      return result;
    else
      return findResources (name);
  }

  protected Enumeration findResources (String name) throws IOException
  {
    // Default to returning null.  Derived classes implement this.
    return null;
  }
}
