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

  
  /**
   * 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);
        modifiedData =
          ((InstrumentationImpl)instrumenter).callTransformers(loader, name,
            null, pd, modifiedData);
        
        return defineClass(loader, name, modifiedData, 0, modifiedData.length,
            pd);
      }
    else
      {
        return defineClass(loader, name, data, offset, len, pd);
      }
  }
}
