/* VMClassLoader.java -- Reference implementation of native interface
   required by ClassLoader
   Copyright (C) 1998, 2001, 2002, 2004, 2005, 2006, 2010
   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.lang;

import gnu.classpath.Configuration;
import gnu.classpath.SystemProperties;
import gnu.java.lang.InstrumentationImpl;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.instrument.Instrumentation;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.ProtectionDomain;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.Vector;
import java.util.zip.ZipFile;

/**
 * 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
{

  /** packages loaded by the bootstrap class loader */
  static final HashMap definedPackages = new HashMap();

  /** jars from property java.boot.class.path */
  static final HashMap bootjars = new HashMap();


  /**
   * Converts the array string of native package names to
   * Packages. The packages are then put into the
   * definedPackages hashMap
   */
  static
  {
    String[] packages = getBootPackages();

    if( packages != null)
      {
        String specName =
              SystemProperties.getProperty("java.specification.name");
        String vendor =
              SystemProperties.getProperty("java.specification.vendor");
        String version =
              SystemProperties.getProperty("java.specification.version");

        Package p;

        for(int i = 0; i < packages.length; i++)
          {
            p = new Package(packages[i],
                  specName,
                  vendor,
                  version,
                  "GNU Classpath",
                  "GNU",
                  Configuration.CLASSPATH_VERSION,
                  null,
                  null);

            definedPackages.put(packages[i], p);
          }
      }
  }

  private VMClassLoader() {} // Prohibits instantiation.

  /**
   * Helper to define a class using a string of bytes. This assumes that
   * the security checks have already been performed, if necessary.
   *
   * Implementations of this method are advised to consider the
   * situation where user code modifies the byte array after it has
   * been passed to defineClass.  This can be handled by making a
   * private copy of the array, or arranging to only read any given
   * byte a single time.
   *
   * @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 native void resolveClass(Class c);

  /**
   * 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.
   *
   * @param name the resource to find
   * @return the URL to the resource
   */
  static URL getResource(String name)
  {
    Enumeration e = getResources(name);
    if (e.hasMoreElements())
      return (URL)e.nextElement();
    return null;
  }

  /**
   * Helper to get a list of resources from the bootstrap class loader.
   *
   * @param name the resource to find
   * @return an enumeration of resources
   */
  static Enumeration getResources(String name)
  {
    StringTokenizer st = new StringTokenizer(
      SystemProperties.getProperty("java.boot.class.path", "."),
      File.pathSeparator);
    Vector v = new Vector();
    while (st.hasMoreTokens())
      {
        File file = new File(st.nextToken());
        if (file.isDirectory())
          {
            try
              {
                File f = new File(file, name);
                if (!f.exists()) continue;
                v.add(new URL("file://" + f.getAbsolutePath()));
              }
            catch (MalformedURLException e)
              {
                throw new Error(e);
              }
          }
        else if (file.isFile())
          {
            ZipFile zip;
            synchronized(bootjars)
              {
                zip = (ZipFile) bootjars.get(file.getName());
              }
            if(zip == null)
              {
                try
                  {
                    zip = new ZipFile(file);
                    synchronized(bootjars)
                      {
                        bootjars.put(file.getName(), zip);
                      }
                  }
                catch (IOException e)
                  {
                    continue;
                  }
              }
            String zname = name.startsWith("/") ? name.substring(1) : name;
            if (zip.getEntry(zname) == null)
              continue;
            try
              {
                v.add(new URL("jar:file://"
                  + file.getAbsolutePath() + "!/" + zname));
              }
            catch (MalformedURLException e)
              {
                throw new Error(e);
              }
          }
      }
    return v.elements();
  }

  /**
   * Returns a String[] of native package names. The default
   * implementation tries to load a list of package from
   * the META-INF/INDEX.LIST file in the boot jar file.
   * If not found or if any exception is raised, it returns
   * an empty array. You may decide this needs native help.
   */
  private static String[] getBootPackages()
  {
    URL indexList = getResource("META-INF/INDEX.LIST");
    if (indexList != null)
      {
        try
          {
            Set packageSet = new HashSet();
            String line;
            int lineToSkip = 3;
            BufferedReader reader = new BufferedReader(
                                                       new InputStreamReader(
                                                                             indexList.openStream()));
            while ((line = reader.readLine()) != null)
              {
                if (lineToSkip == 0)
                  {
                    if (line.length() == 0)
                      lineToSkip = 1;
                    else
                      packageSet.add(line.replace('/', '.'));
                  }
                else
                  lineToSkip--;
              }
            reader.close();
            return (String[]) packageSet.toArray(new String[packageSet.size()]);
          }
        catch (IOException e)
          {
            return new String[0];
          }
      }
    else
      return new String[0];
  }

  /**
   * Helper to get a package from the bootstrap class loader.
   *
   * @param name the name to find
   * @return the named package, if it exists
   */
  static Package getPackage(String name)
  {
    return (Package)definedPackages.get(name);
  }



  /**
   * Helper to get all packages from the bootstrap class loader.
   *
   * @return all named packages, if any exist
   */
  static Package[] getPackages()
  {
    Package[] packages = new Package[definedPackages.size()];
    definedPackages.values().toArray(packages);
    return packages;
  }

  /**
   * 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 ClassLoader getSystemClassLoader()
  {
    return ClassLoader.defaultGetSystemClassLoader();
  }

  /**
   * Find the class if this class loader previously defined this class
   * or if this class loader has been recorded as the initiating class loader
   * for this class.
   */
  static native Class findLoadedClass(ClassLoader cl, String name);

  /**
   * The Instrumentation object created by the vm when agents are defined.
   */
  static final Instrumentation instrumenter = null;

  /**
   * Call the transformers of the possible Instrumentation object. This
   * implementation assumes the instrumenter is a
   * <code>InstrumentationImpl</code> object. VM implementors would
   * have to redefine this method if they provide their own implementation
   * of the <code>Instrumentation</code> interface.
   *
   * @param loader the initiating loader
   * @param name the name of the class
   * @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 new data representing the classfile
   */
  static final Class defineClassWithTransformers(ClassLoader loader,
      String name, byte[] data, int offset, int len, ProtectionDomain pd)
  {

    if (instrumenter != null)
      {
        byte[] modifiedData = new byte[len];
        System.arraycopy(data, offset, modifiedData, 0, len);
        String jvmName = name.replace('.', '/');
        modifiedData =
          ((InstrumentationImpl)instrumenter).callTransformers(loader, jvmName,
            null, pd, modifiedData);

        return defineClass(loader, name, modifiedData, 0, modifiedData.length,
            pd);
      }
    else
      {
        return defineClass(loader, name, data, offset, len, pd);
      }
  }
}
