/* VMClassLoader.java -- Reference implementation of native interface
   required by ClassLoader
   Copyright (C) 1998, 2001, 2002, 2003, 2004, 2005 Free Software Foundation

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.lang;

import gnu.java.util.EmptyEnumeration;
import java.lang.reflect.Constructor;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.security.AllPermission;
import java.security.Permission;
import java.security.Permissions;
import java.security.ProtectionDomain;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.StringTokenizer;
import gnu.gcj.runtime.BootClassLoader;

/**
 * java.lang.VMClassLoader is a package-private helper for VMs to implement
 * on behalf of java.lang.ClassLoader.
 *
 * @author John Keiser
 * @author Mark Wielaard <mark@klomp.org>
 * @author Eric Blake <ebb9@email.byu.edu>
 */
final class VMClassLoader
{
  // Protection Domain definitions 
  // FIXME: should there be a special protection domain used for native code?
  
  // The permission required to check what a classes protection domain is.
  static final Permission protectionDomainPermission
    = new RuntimePermission("getProtectionDomain");
  // The protection domain returned if we cannot determine it. 
  static ProtectionDomain unknownProtectionDomain;

  static
  {
    Permissions permissions = new Permissions();
    permissions.add(new AllPermission());
    unknownProtectionDomain = new ProtectionDomain(null, permissions);  
  }

  static final HashMap definedPackages = new HashMap();

  // This is a helper for handling java.endorsed.dirs.  It is null
  // until we've initialized the system, at which point it is created.
  static BootClassLoader bootLoader;

  // This keeps track of shared libraries we've already tried to load.
  private static HashSet tried_libraries;

  // Holds one of the LIB_* constants; used to determine how shared
  // library loads are done.
  private static int lib_control;

  private static final int LIB_FULL = 0;
  private static final int LIB_CACHE = 1;
  private static final int LIB_NEVER = 2;

  /**
   * Helper to define a class using a string of bytes. This assumes that
   * the security checks have already been performed, if necessary.
   *
   * <strong>For backward compatibility, this just ignores the protection
   * domain; that is the wrong behavior, and you should directly implement
   * this method natively if you can.</strong>
   *
   * @param name the name to give the class, or null if unknown
   * @param data the data representing the classfile, in classfile format
   * @param offset the offset into the data where the classfile starts
   * @param len the length of the classfile data in the array
   * @param pd the protection domain
   * @return the class that was defined
   * @throws ClassFormatError if data is not in proper classfile format
   */
  static final native Class defineClass(ClassLoader cl, String name,
					byte[] data, int offset, int len,
					ProtectionDomain pd)
    throws ClassFormatError;

  /**
   * Helper to resolve all references to other classes from this class.
   *
   * @param c the class to resolve
   */
  static final void resolveClass(Class clazz)
  {
    // There doesn't seem to be a need for this to do anything.
    // Testing reveals that the JDK doesn't seem to do anything here,
    // either.
  }

  /**
   * Helper to load a class from the bootstrap class loader.
   *
   * @param name the class name to load
   * @param resolve whether to resolve it
   * @return the class, loaded by the bootstrap classloader or null
   * if the class wasn't found. Returning null is equivalent to throwing
   * a ClassNotFoundException (but a possible performance optimization).
   */
  static final native Class loadClass(String name, boolean resolve)
    throws ClassNotFoundException;

  /**
   * Helper to load a resource from the bootstrap class loader.
   *
   * In libgcj, this does nothing, as the default system loader knows
   * how to find resources that have been linked in.
   *
   * @param name the resource to find
   * @return the URL to the resource
   */
  static URL getResource(String name)
  {
    if (bootLoader != null)
      return bootLoader.bootGetResource(name);
    return null;
  }

  /**
   * Helper to get a list of resources from the bootstrap class loader.
   *
   * In libgcj, this does nothing, as the default system loader knows
   * how to find resources that have been linked in.
   *
   * @param name the resource to find
   * @return an enumeration of resources
   * @throws IOException if one occurs
   */
  static Enumeration getResources(String name) throws IOException
  {
    if (bootLoader != null)
      return bootLoader.bootGetResources(name);
    return EmptyEnumeration.getInstance();
  }

  /**
   * Helper to get a package from the bootstrap class loader.  The default
   * implementation of returning null may be adequate, or you may decide
   * that this needs some native help.
   *
   * @param name the name to find
   * @return the named package, if it exists
   */
  static synchronized Package getPackage(String name)
  {
    return (Package) definedPackages.get(name);
  }

  /**
   * Helper to get all packages from the bootstrap class loader.  The default
   * implementation of returning an empty array may be adequate, or you may
   * decide that this needs some native help.
   *
   * @return all named packages, if any exist
   */
  static synchronized Package[] getPackages()
  {
    Package[] packages = new Package[definedPackages.size()];
    return (Package[]) definedPackages.values().toArray(packages);
  }

  // Define a package for something loaded natively.
  static synchronized void definePackageForNative(String className)
  {
    int lastDot = className.lastIndexOf('.');
    if (lastDot != -1)
      {
	String packageName = className.substring(0, lastDot);
	if (getPackage(packageName) == null)
	  {
	    // FIXME: this assumes we're defining the core, which
	    // isn't necessarily so.  We could detect this and set up
	    // appropriately.  We could also look at a manifest file
	    // compiled into the .so.
	    Package p = new Package(packageName,
				    "Java Platform API Specification",
				    "GNU", "1.4", "gcj", "GNU",
				    null, // FIXME: gcj version.
				    null);
	    definedPackages.put(packageName, p);
	  }
      }
  }

  /**
   * Helper for java.lang.Integer, Byte, etc to get the TYPE class
   * at initialization time. The type code is one of the chars that
   * represents the primitive type as in JNI.
   *
   * <ul>
   * <li>'Z' - boolean</li>
   * <li>'B' - byte</li>
   * <li>'C' - char</li>
   * <li>'D' - double</li>
   * <li>'F' - float</li>
   * <li>'I' - int</li>
   * <li>'J' - long</li>
   * <li>'S' - short</li>
   * <li>'V' - void</li>
   * </ul>
   *
   * @param type the primitive type
   * @return a "bogus" class representing the primitive type
   */
  static final native Class getPrimitiveClass(char type);

  /**
   * The system default for assertion status. This is used for all system
   * classes (those with a null ClassLoader), as well as the initial value for
   * every ClassLoader's default assertion status.
   *
   * XXX - Not implemented yet; this requires native help.
   *
   * @return the system-wide default assertion status
   */
  static final boolean defaultAssertionStatus()
  {
    return true;
  }

  /**
   * The system default for package assertion status. This is used for all
   * ClassLoader's packageAssertionStatus defaults. It must be a map of
   * package names to Boolean.TRUE or Boolean.FALSE, with the unnamed package
   * represented as a null key.
   *
   * XXX - Not implemented yet; this requires native help.
   *
   * @return a (read-only) map for the default packageAssertionStatus
   */
  static final Map packageAssertionStatus()
  {
    return new HashMap();
  }

  /**
   * The system default for class assertion status. This is used for all
   * ClassLoader's classAssertionStatus defaults. It must be a map of
   * class names to Boolean.TRUE or Boolean.FALSE
   *
   * XXX - Not implemented yet; this requires native help.
   *
   * @return a (read-only) map for the default classAssertionStatus
   */
  static final Map classAssertionStatus()
  {
    return new HashMap();
  }

  static native ClassLoader getSystemClassLoaderInternal();

  static native void initBootLoader(String libdir);

  static void initialize(String libdir)
  {
    initBootLoader(libdir);

    String p
      = System.getProperty ("gnu.gcj.runtime.VMClassLoader.library_control",
			    "");
    if ("never".equals(p))
      lib_control = LIB_NEVER;
    else if ("cache".equals(p))
      lib_control = LIB_CACHE;
    else if ("full".equals(p))
      lib_control = LIB_FULL;
    else
      lib_control = LIB_NEVER;

    tried_libraries = new HashSet();
  }

  /**
   * Possibly load a .so and search it for classes.
   */
  static native Class nativeFindClass(String name);

  static ClassLoader getSystemClassLoader()
  {
    // This method is called as the initialization of systemClassLoader,
    // so if there is a null value, this is the first call and we must check
    // for java.system.class.loader.
    String loader = System.getProperty("java.system.class.loader");
    ClassLoader default_sys = getSystemClassLoaderInternal();
    if (loader != null)
      {
	try
	  {
	    Class load_class = Class.forName(loader, true, default_sys);
	    Constructor c
	      = load_class.getConstructor(new Class[] { ClassLoader.class });
	    default_sys
	      = (ClassLoader) c.newInstance(new Object[] { default_sys });
	  }
	catch (Exception ex)
	  {
	    throw new Error("Failed to load requested system classloader "
			       + loader, ex);
	  }
      }

    return default_sys;
  }
}
