/* URLClassLoader.java --  ClassLoader that loads classes from one or more URLs
   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
   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.net;

import java.io.ByteArrayOutputStream;
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FilePermission;
import java.io.IOException;
import java.io.InputStream;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.CodeSource;
import java.security.PermissionCollection;
import java.security.PrivilegedAction;
import java.security.SecureClassLoader;
import java.security.cert.Certificate;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.StringTokenizer;
import java.util.Vector;
import java.util.jar.Attributes;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import gnu.gcj.runtime.SharedLibHelper;
import gnu.gcj.Core;
import gnu.java.net.protocol.core.CoreInputStream;

/**
 * A secure class loader that can load classes and resources from
 * multiple locations.  Given an array of <code>URL</code>s this class
 * loader will retrieve classes and resources by fetching them from
 * possible remote locations.  Each <code>URL</code> is searched in
 * order in which it was added.  If the file portion of the
 * <code>URL</code> ends with a '/' character then it is interpreted
 * as a base directory, otherwise it is interpreted as a jar file from
 * which the classes/resources are resolved.
 *
 * <p>New instances can be created by two static
 * <code>newInstance()</code> methods or by three public
 * contructors. Both ways give the option to supply an initial array
 * of <code>URL</code>s and (optionally) a parent classloader (that is
 * different from the standard system class loader).</p>
 *
 * <p>Normally creating a <code>URLClassLoader</code> throws a
 * <code>SecurityException</code> if a <code>SecurityManager</code> is
 * installed and the <code>checkCreateClassLoader()</code> method does
 * not return true.  But the <code>newInstance()</code> methods may be
 * used by any code as long as it has permission to acces the given
 * <code>URL</code>s.  <code>URLClassLoaders</code> created by the
 * <code>newInstance()</code> methods also explicitly call the
 * <code>checkPackageAccess()</code> method of
 * <code>SecurityManager</code> if one is installed before trying to
 * load a class.  Note that only subclasses of
 * <code>URLClassLoader</code> can add new URLs after the
 * URLClassLoader had been created. But it is always possible to get
 * an array of all URLs that the class loader uses to resolve classes
 * and resources by way of the <code>getURLs()</code> method.</p>
 *
 * <p>Open issues:
 * <ul>
 *
 * <li>Should the URLClassLoader actually add the locations found in
 * the manifest or is this the responsibility of some other
 * loader/(sub)class?  (see <a
 * href="http://java.sun.com/products/jdk/1.4/docs/guide/extensions/spec.html">
 * Extension Mechanism Architecture - Bundles Extensions</a>)</li>
 *
 * <li>How does <code>definePackage()</code> and sealing work
 * precisely?</li>
 *
 * <li>We save and use the security context (when a created by
 * <code>newInstance()</code> but do we have to use it in more
 * places?</li>
 *
 * <li>The use of <code>URLStreamHandler</code>s has not been tested.</li>
 *
 * </ul>
 * </p>
 *
 * @since 1.2
 *
 * @author Mark Wielaard (mark@klomp.org)
 * @author Wu Gansha (gansha.wu@intel.com)
 */
public class URLClassLoader extends SecureClassLoader
{
  // Class Variables

  /**
   * A global cache to store mappings between URLLoader and URL,
   * so we can avoid do all the homework each time the same URL
   * comes.
   * XXX - Keeps these loaders forever which prevents garbage collection.
   */
  private static HashMap urlloaders = new HashMap();

  /**
   * A cache to store mappings between handler factory and its
   * private protocol handler cache (also a HashMap), so we can avoid
   * create handlers each time the same protocol comes.
   */
  private static HashMap factoryCache = new HashMap(5);

  // Instance variables

  /** Locations to load classes from */
  private final Vector urls = new Vector();

  /**
   * Store pre-parsed information for each url into this vector: each
   * element is a URL loader.  A jar file has its own class-path
   * attribute which adds to the URLs that will be searched, but this
   * does not add to the list of urls.
   */
  private final Vector urlinfos = new Vector();

  /** Factory used to get the protocol handlers of the URLs */
  private final URLStreamHandlerFactory factory;

  /**
   * The security context when created from <code>newInstance()</code>
   * or null when created through a normal constructor or when no
   * <code>SecurityManager</code> was installed.
   */
  private final AccessControlContext securityContext;

  // Helper classes

  /**
   * A <code>URLLoader</code> contains all logic to load resources from a
   * given base <code>URL</code>.
   */
  abstract static class URLLoader
  {
    /**
     * Our classloader to get info from if needed.
     */
    final URLClassLoader classloader;

    /**
     * The base URL from which all resources are loaded.
     */
    final URL baseURL;

    /**
     * A <code>CodeSource</code> without any associated certificates.
     * It is common for classes to not have certificates associated
     * with them.  If they come from the same <code>URLLoader</code>
     * then it is safe to share the associated <code>CodeSource</code>
     * between them since <code>CodeSource</code> is immutable.
     */
    final CodeSource noCertCodeSource;

    URLLoader(URLClassLoader classloader, URL baseURL)
    {
      this(classloader, baseURL, baseURL);
    }

    URLLoader(URLClassLoader classloader, URL baseURL, URL overrideURL)
    {
      this.classloader = classloader;
      this.baseURL = baseURL;
      this.noCertCodeSource = new CodeSource(overrideURL, null);
    }

    /**
     * Returns a <code>Class</code> loaded by this
     * <code>URLLoader</code>, or <code>null</code> when this loader
     * either can't load the class or doesn't know how to load classes
     * at all.
     */
    Class getClass(String className)
    {
      return null;
    }

    /**
     * Returns a <code>Resource</code> loaded by this
     * <code>URLLoader</code>, or <code>null</code> when no
     * <code>Resource</code> with the given name exists.
     */
    abstract Resource getResource(String s);

    /**
     * Returns the <code>Manifest</code> associated with the
     * <code>Resource</code>s loaded by this <code>URLLoader</code> or
     * <code>null</code> there is no such <code>Manifest</code>.
     */
    Manifest getManifest()
    {
      return null;
    }

    Vector getClassPath()
    {
      return null;
    }
  }

  /**
   * A <code>Resource</code> represents a resource in some
   * <code>URLLoader</code>. It also contains all information (e.g.,
   * <code>URL</code>, <code>CodeSource</code>, <code>Manifest</code> and
   * <code>InputStream</code>) that is necessary for loading resources
   * and creating classes from a <code>URL</code>.
   */
  abstract static class Resource
  {
    final URLLoader loader;

    Resource(URLLoader loader)
    {
      this.loader = loader;
    }

    /**
     * Returns the non-null <code>CodeSource</code> associated with
     * this resource.
     */
    CodeSource getCodeSource()
    {
      Certificate[] certs = getCertificates();
      if (certs == null)
        return loader.noCertCodeSource;
      else
        return new CodeSource(loader.baseURL, certs);
    }

    /**
     * Returns <code>Certificates</code> associated with this
     * resource, or null when there are none.
     */
    Certificate[] getCertificates()
    {
      return null;
    }

    /**
     * Return a <code>URL</code> that can be used to access this resource.
     */
    abstract URL getURL();

    /**
     * Returns the size of this <code>Resource</code> in bytes or
     * <code>-1</code> when unknown.
     */
    abstract int getLength();

    /**
     * Returns the non-null <code>InputStream</code> through which
     * this resource can be loaded.
     */
    abstract InputStream getInputStream() throws IOException;
  }

  /**
   * A <code>JarURLLoader</code> is a type of <code>URLLoader</code>
   * only loading from jar url.
   */
  static final class JarURLLoader extends URLLoader
  {
    final JarFile jarfile; // The jar file for this url
    final URL baseJarURL; // Base jar: url for all resources loaded from jar

    Vector classPath;	// The "Class-Path" attribute of this Jar's manifest

    public JarURLLoader(URLClassLoader classloader, URL baseURL,
			URL absoluteUrl)
    {
      super(classloader, baseURL, absoluteUrl);

      // Cache url prefix for all resources in this jar url.
      String external = baseURL.toExternalForm();
      StringBuffer sb = new StringBuffer(external.length() + 6);
      sb.append("jar:");
      sb.append(external);
      sb.append("!/");
      String jarURL = sb.toString();

      this.classPath = null;
      URL baseJarURL = null;
      JarFile jarfile = null;
      try
	{
	  baseJarURL =
	    new URL(null, jarURL, classloader.getURLStreamHandler("jar"));
	  
	  jarfile =
	    ((JarURLConnection) baseJarURL.openConnection()).getJarFile();
	  
	  Manifest manifest;
	  Attributes attributes;
	  String classPathString;

	  if ((manifest = jarfile.getManifest()) != null
	      && (attributes = manifest.getMainAttributes()) != null
	      && ((classPathString 
		   = attributes.getValue(Attributes.Name.CLASS_PATH)) 
		  != null))
	    {
	      this.classPath = new Vector();
	      
	      StringTokenizer st = new StringTokenizer(classPathString, " ");
	      while (st.hasMoreElements ()) 
		{  
		  String e = st.nextToken ();
		  try
		    {
		      URL url = new URL(baseURL, e);
		      this.classPath.add(url);
		    } 
		  catch (java.net.MalformedURLException xx)
		    {
		      // Give up
		    }
		}
	    }
	}
      catch (IOException ioe)
        {
	  /* ignored */
        }

      this.baseJarURL = baseJarURL;
      this.jarfile = jarfile;
    }

    /** get resource with the name "name" in the jar url */
    Resource getResource(String name)
    {
      if (jarfile == null)
        return null;

      if (name.startsWith("/"))
        name = name.substring(1);

      JarEntry je = jarfile.getJarEntry(name);
      if (je != null)
        return new JarURLResource(this, name, je);
      else
        return null;
    }

    Manifest getManifest()
    {
      try
        {
          return (jarfile == null) ? null : jarfile.getManifest();
        }
      catch (IOException ioe)
        {
          return null;
        }
    }

    Vector getClassPath()
    {
      return classPath;
    }
  }

  static final class JarURLResource extends Resource
  {
    private final JarEntry entry;
    private final String name;

    JarURLResource(JarURLLoader loader, String name, JarEntry entry)
    {
      super(loader);
      this.entry = entry;
      this.name = name;
    }

    InputStream getInputStream() throws IOException
    {
      return ((JarURLLoader) loader).jarfile.getInputStream(entry);
    }

    int getLength()
    {
      return (int) entry.getSize();
    }

    Certificate[] getCertificates()
    {
      // We have to get the entry from the jar file again, because the
      // certificates will not be available until the entire entry has
      // been read.
      return ((JarEntry) ((JarURLLoader) loader).jarfile.getEntry(name))
        .getCertificates();
    }

    URL getURL()
    {
      try
        {
          return new URL(((JarURLLoader) loader).baseJarURL, name,
                         loader.classloader.getURLStreamHandler("jar"));
        }
      catch (MalformedURLException e)
        {
          InternalError ie = new InternalError();
          ie.initCause(e);
          throw ie;
        }
    }
  }

  /**
   * Loader for remote directories.
   */
  static final class RemoteURLLoader extends URLLoader
  {
    private final String protocol;

    RemoteURLLoader(URLClassLoader classloader, URL url)
    {
      super(classloader, url);
      protocol = url.getProtocol();
    }

    /**
     * Get a remote resource.
     * Returns null if no such resource exists.
     */
    Resource getResource(String name)
    {
      try
        {
          URL url =
            new URL(baseURL, name, classloader.getURLStreamHandler(protocol));
          URLConnection connection = url.openConnection();

          // Open the connection and check the stream
          // just to be sure it exists.
          int length = connection.getContentLength();
          InputStream stream = connection.getInputStream();

          // We can do some extra checking if it is a http request
          if (connection instanceof HttpURLConnection)
            {
              int response =
                ((HttpURLConnection) connection).getResponseCode();
              if (response / 100 != 2)
                return null;
            }

          if (stream != null)
            return new RemoteResource(this, name, url, stream, length);
          else
            return null;
        }
      catch (IOException ioe)
        {
          return null;
        }
    }
  }

  /**
   * A resource from some remote location.
   */
  static final class RemoteResource extends Resource
  {
    private final URL url;
    private final InputStream stream;
    private final int length;

    RemoteResource(RemoteURLLoader loader, String name, URL url,
                   InputStream stream, int length)
    {
      super(loader);
      this.url = url;
      this.stream = stream;
      this.length = length;
    }

    InputStream getInputStream() throws IOException
    {
      return stream;
    }

    public int getLength()
    {
      return length;
    }

    public URL getURL()
    {
      return url;
    }
  }

  /**
   * A <code>SoURLLoader</code> is a type of <code>URLLoader</code>
   * that loads classes and resources from a shared library.
   */
  final static class SoURLLoader extends URLLoader
  {
    SharedLibHelper helper;

    SoURLLoader(URLClassLoader classloader, URL url)
    {
      this(classloader, url, url);
    }

    SoURLLoader(URLClassLoader classloader, URL url, URL overrideURL)
    {
      super(classloader, url, overrideURL);
      helper = SharedLibHelper.findHelper(classloader, url.getFile(),
					  noCertCodeSource, true);
    }

    Class getClass(String className)
    {
      return helper.findClass(className);
    }

    Resource getResource(String name)
    {
      URL url = helper.findResource(name);
      if (url == null)
	return null;
      return new SoResource(this, url);
    }
  }

  final static class SoResource extends Resource
  {
    SoResource(SoURLLoader loader, URL url)
    {
      super(loader);
      this.url = url;
    }

    InputStream getInputStream() throws IOException
    {
      URLConnection conn = url.openConnection();
      return conn.getInputStream();
    }

    public int getLength()
    {
      // FIXME we could find this by asking the core object.
      return -1;
    }

    public URL getURL ()
    {
      return url;
    }

    final URL url;
  }

  /**
   * A <code>FileURLLoader</code> is a type of <code>URLLoader</code>
   * only loading from file url.
   */
  static final class FileURLLoader extends URLLoader
  {
    File dir; //the file for this file url

    FileURLLoader(URLClassLoader classloader, URL url, URL absoluteUrl)
    {
      super(classloader, url, absoluteUrl);
      dir = new File(absoluteUrl.getFile());
    }

    /** get resource with the name "name" in the file url */
    Resource getResource(String name)
    {
      try 
 	{
 	  File file = new File(dir, name).getCanonicalFile();
 	  if (file.exists() && !file.isDirectory())
 	    return new FileResource(this, file);
 	}
      catch (IOException e)
 	{
 	  // Fall through...
 	}
      return null;
    }
  }

  static final class FileResource extends Resource
  {
    final File file;

    FileResource(FileURLLoader loader, File file)
    {
      super(loader);
      this.file = file;
    }

    InputStream getInputStream() throws IOException
    {
      // Delegate to the URL content handler mechanism to retrieve an
      // HTML representation of the directory listing if a directory
      if (file.isDirectory())
        {
          URL url = getURL();
          return url.openStream();
        }
      // Otherwise simply return a FileInputStream
      return new FileInputStream(file);
    }

    public int getLength()
    {
      // Delegate to the URL content handler mechanism to retrieve the
      // length of the HTML representation of the directory listing if
      // a directory, or -1 if an exception occurs opening the directory.
      if (file.isDirectory())
        {
          URL url = getURL();
          try
            {
              URLConnection connection = url.openConnection();
              return connection.getContentLength();
            }
          catch (IOException e)
            {
              return -1;
            }
        }
      // Otherwise simply return the file length
      return (int) file.length();
    }

    public URL getURL()
    {
      try
        {
          return file.toURL();
        }
      catch (MalformedURLException e)
        {
          InternalError ie = new InternalError();
          ie.initCause(e);
          throw ie;
        }
    }
  }

  /**
   * A <code>CoreURLLoader</code> is a type of <code>URLLoader</code>
   * only loading from core url.
   */
  static final class CoreURLLoader extends URLLoader
  {
    private String dir;

    CoreURLLoader(URLClassLoader classloader, URL url)
    {
      super(classloader, url);
      dir = baseURL.getFile();
    }

    /** get resource with the name "name" in the core url */
    Resource getResource(String name)
    {
      Core core = Core.find (dir + name);
      if (core != null)
        return new CoreResource(this, name, core);
      return null;
    }
  }

  static final class CoreResource extends Resource
  {
    private final Core core;
    private final String name;

    CoreResource(CoreURLLoader loader, String name, Core core)
    {
      super(loader);
      this.core = core;
      this.name = name;
    }

    InputStream getInputStream() throws IOException
    {
      return new CoreInputStream(core);
    }

    public int getLength()
    {
      return core.length;
    }

    public URL getURL()
    {
      try
        {
          return new URL(loader.baseURL, name,
                         loader.classloader.getURLStreamHandler("core"));
        }
      catch (MalformedURLException e)
        {
          InternalError ie = new InternalError();
          ie.initCause(e);
          throw ie;
        }
    }
  }

  // Constructors

  /**
   * Creates a URLClassLoader that gets classes from the supplied URLs.
   * To determine if this classloader may be created the constructor of
   * the super class (<code>SecureClassLoader</code>) is called first, which
   * can throw a SecurityException. Then the supplied URLs are added
   * in the order given to the URLClassLoader which uses these URLs to
   * load classes and resources (after using the default parent ClassLoader).
   *
   * @param urls Locations that should be searched by this ClassLoader when
   * resolving Classes or Resources.
   * @exception SecurityException if the SecurityManager disallows the
   * creation of a ClassLoader.
   * @see SecureClassLoader
   */
  public URLClassLoader(URL[] urls) throws SecurityException
  {
    super();
    this.factory = null;
    this.securityContext = null;
    addURLs(urls);
  }

  /**
   * Creates a <code>URLClassLoader</code> that gets classes from the supplied
   * <code>URL</code>s.
   * To determine if this classloader may be created the constructor of
   * the super class (<code>SecureClassLoader</code>) is called first, which
   * can throw a SecurityException. Then the supplied URLs are added
   * in the order given to the URLClassLoader which uses these URLs to
   * load classes and resources (after using the supplied parent ClassLoader).
   * @param urls Locations that should be searched by this ClassLoader when
   * resolving Classes or Resources.
   * @param parent The parent class loader used before trying this class
   * loader.
   * @exception SecurityException if the SecurityManager disallows the
   * creation of a ClassLoader.
   * @exception SecurityException
   * @see SecureClassLoader
   */
  public URLClassLoader(URL[] urls, ClassLoader parent)
    throws SecurityException
  {
    super(parent);
    this.factory = null;
    this.securityContext = null;
    addURLs(urls);
  }

  // Package-private to avoid a trampoline constructor.
  /**
   * Package-private constructor used by the static
   * <code>newInstance(URL[])</code> method.  Creates an
   * <code>URLClassLoader</code> with the given parent but without any
   * <code>URL</code>s yet. This is used to bypass the normal security
   * check for creating classloaders, but remembers the security
   * context which will be used when defining classes.  The
   * <code>URL</code>s to load from must be added by the
   * <code>newInstance()</code> method in the security context of the
   * caller.
   *
   * @param securityContext the security context of the unprivileged code.
   */
  URLClassLoader(ClassLoader parent, AccessControlContext securityContext)
  {
    super(parent);
    this.factory = null;
    this.securityContext = securityContext;
  }

  /**
   * Creates a URLClassLoader that gets classes from the supplied URLs.
   * To determine if this classloader may be created the constructor of
   * the super class (<CODE>SecureClassLoader</CODE>) is called first, which
   * can throw a SecurityException. Then the supplied URLs are added
   * in the order given to the URLClassLoader which uses these URLs to
   * load classes and resources (after using the supplied parent ClassLoader).
   * It will use the supplied <CODE>URLStreamHandlerFactory</CODE> to get the
   * protocol handlers of the supplied URLs.
   * @param urls Locations that should be searched by this ClassLoader when
   * resolving Classes or Resources.
   * @param parent The parent class loader used before trying this class
   * loader.
   * @param factory Used to get the protocol handler for the URLs.
   * @exception SecurityException if the SecurityManager disallows the
   * creation of a ClassLoader.
   * @exception SecurityException
   * @see SecureClassLoader
   */
  public URLClassLoader(URL[] urls, ClassLoader parent,
                        URLStreamHandlerFactory factory)
    throws SecurityException
  {
    super(parent);
    this.securityContext = null;
    this.factory = factory;
    addURLs(urls);

    // If this factory is still not in factoryCache, add it,
    //   since we only support three protocols so far, 5 is enough
    //   for cache initial size
    synchronized (factoryCache)
      {
        if (factory != null && factoryCache.get(factory) == null)
          factoryCache.put(factory, new HashMap(5));
      }
  }

  // Methods

  /**
   * Adds a new location to the end of the internal URL store.
   * @param newUrl the location to add
   */
  protected void addURL(URL newUrl)
  {
    urls.add(newUrl);
    addURLImpl(newUrl);
  }

  private void addURLImpl(URL newUrl)
  {
    synchronized (this)
      {
        if (newUrl == null)
          return; // Silently ignore...

	// Reset the toString() value.
	thisString = null;

        // Check global cache to see if there're already url loader
        // for this url.
        URLLoader loader = (URLLoader) urlloaders.get(newUrl);
        if (loader == null)
          {
            String file = newUrl.getFile();
            String protocol = newUrl.getProtocol();

	    // If we have a file: URL, we want to make it absolute
	    // here, before we decide whether it is really a jar.
	    URL absoluteURL;
	    if ("file".equals (protocol))
	      {
		File dir = new File(file);
		URL absUrl;
		try
		  {
		    absoluteURL = dir.getCanonicalFile().toURL();
		  }
		catch (IOException ignore)
		  {
		    try
		      {
			absoluteURL = dir.getAbsoluteFile().toURL();
		      }
		    catch (MalformedURLException _)
		      {
			// This really should not happen.
			absoluteURL = newUrl;
		      }
		  }
	      }
	    else
	      {
		// This doesn't hurt, and it simplifies the logic a
		// little.
		absoluteURL = newUrl;
	      }

            // Check that it is not a directory
	    if ("gcjlib".equals(protocol))
	      loader = new SoURLLoader(this, newUrl);
	    else if (! (file.endsWith("/") || file.endsWith(File.separator)))
              loader = new JarURLLoader(this, newUrl, absoluteURL);
            else if ("file".equals(protocol))
	      loader = new FileURLLoader(this, newUrl, absoluteURL);
	    else if ("core".equals(protocol))
	      loader = new CoreURLLoader(this, newUrl);
            else
              loader = new RemoteURLLoader(this, newUrl);

            // Cache it.
            urlloaders.put(newUrl, loader);
          }

	urlinfos.add(loader);

	Vector extraUrls = loader.getClassPath();
	if (extraUrls != null)
	  {
	    Iterator it = extraUrls.iterator();
	    while (it.hasNext())
	      {
		URL url = (URL)it.next();
		URLLoader extraLoader = (URLLoader) urlloaders.get(url);
		if (! urlinfos.contains (extraLoader))
		  addURLImpl(url);
	      }
	  }

      }
  }

  /**
   * Adds an array of new locations to the end of the internal URL
   * store.  Called from the the constructors. Should not call to the
   * protected addURL() method since that can be overridden and
   * subclasses are not yet in a good state at this point.
   * jboss 4.0.3 for example depends on this.
   *
   * @param newUrls the locations to add
   */
  private void addURLs(URL[] newUrls)
  {
    for (int i = 0; i < newUrls.length; i++)
      {
	urls.add(newUrls[i]);
	addURLImpl(newUrls[i]);
      }
  }

  /**
   * Look in both Attributes for a given value.  The first Attributes
   * object, if not null, has precedence.
   */
  private String getAttributeValue(Attributes.Name name, Attributes first,
				   Attributes second)
  {
    String result = null;
    if (first != null)
      result = first.getValue(name);
    if (result == null)
      result = second.getValue(name);
    return result;
  }

  /**
   * Defines a Package based on the given name and the supplied manifest
   * information. The manifest indicates the title, version and
   * vendor information of the specification and implementation and whether the
   * package is sealed. If the Manifest indicates that the package is sealed
   * then the Package will be sealed with respect to the supplied URL.
   *
   * @param name The name of the package
   * @param manifest The manifest describing the specification,
   * implementation and sealing details of the package
   * @param url the code source url to seal the package
   * @return the defined Package
   * @throws IllegalArgumentException If this package name already exists
   * in this class loader
   */
  protected Package definePackage(String name, Manifest manifest, URL url)
    throws IllegalArgumentException
  {
    // Compute the name of the package as it may appear in the
    // Manifest.
    StringBuffer xform = new StringBuffer(name);
    for (int i = xform.length () - 1; i >= 0; --i)
      if (xform.charAt(i) == '.')
	xform.setCharAt(i, '/');
    xform.append('/');
    String xformName = xform.toString();

    Attributes entryAttr = manifest.getAttributes(xformName);
    Attributes attr = manifest.getMainAttributes();

    String specTitle
      = getAttributeValue(Attributes.Name.SPECIFICATION_TITLE,
			  entryAttr, attr);
    String specVersion
      = getAttributeValue(Attributes.Name.SPECIFICATION_VERSION,
			  entryAttr, attr);
    String specVendor
      = getAttributeValue(Attributes.Name.SPECIFICATION_VENDOR,
			  entryAttr, attr);
    String implTitle
      = getAttributeValue(Attributes.Name.IMPLEMENTATION_TITLE,
			  entryAttr, attr);
    String implVersion
      = getAttributeValue(Attributes.Name.IMPLEMENTATION_VERSION,
			  entryAttr, attr);
    String implVendor
      = getAttributeValue(Attributes.Name.IMPLEMENTATION_VENDOR,
			  entryAttr, attr);

    // Look if the Manifest indicates that this package is sealed
    // XXX - most likely not completely correct!
    // Shouldn't we also check the sealed attribute of the complete jar?
    // http://java.sun.com/products/jdk/1.4/docs/guide/extensions/spec.html#bundled
    // But how do we get that jar manifest here?
    String sealed = attr.getValue(Attributes.Name.SEALED);
    if ("false".equals(sealed))
      // make sure that the URL is null so the package is not sealed
      url = null;

    return definePackage(name,
			 specTitle, specVendor, specVersion,
			 implTitle, implVendor, implVersion,
			 url);
  }

  /**
   * Finds (the first) class by name from one of the locations. The locations
   * are searched in the order they were added to the URLClassLoader.
   *
   * @param className the classname to find
   * @exception ClassNotFoundException when the class could not be found or
   * loaded
   * @return a Class object representing the found class
   */
  protected Class findClass(final String className)
    throws ClassNotFoundException
  {
    // Just try to find the resource by the (almost) same name
    String resourceName = className.replace('.', '/') + ".class";
    int max = urlinfos.size();
    Resource resource = null;
    for (int i = 0; i < max && resource == null; i++)
      {
	URLLoader loader = (URLLoader)urlinfos.elementAt(i);
	if (loader == null)
	  continue;

	Class k = loader.getClass(className);
	if (k != null)
	  return k;

	resource = loader.getResource(resourceName);
      }
    if (resource == null)
      {
	String message = className + " not found";
	if (runtimeInitialized())
	  message += " in " + this;
	throw new ClassNotFoundException(message);
      }

    // Try to read the class data, create the CodeSource, Package and
    // construct the class (and watch out for those nasty IOExceptions)
    try
      {
	byte[] data;
	InputStream in = resource.getInputStream();
	try
	  {
	    int length = resource.getLength();
	    if (length != -1)
	      {
		// We know the length of the data.
		// Just try to read it in all at once
		data = new byte[length];
		int pos = 0;
		while (length - pos > 0)
		  {
		    int len = in.read(data, pos, length - pos);
		    if (len == -1)
		      throw new EOFException("Not enough data reading from: "
					     + in);
		    pos += len;
		  }
	      }
	    else
	      {
		// We don't know the data length.
		// Have to read it in chunks.
		ByteArrayOutputStream out = new ByteArrayOutputStream(4096);
		byte[] b = new byte[4096];
		int l = 0;
		while (l != -1)
		  {
		    l = in.read(b);
		    if (l != -1)
		      out.write(b, 0, l);
		  }
		data = out.toByteArray();
	      }
	  }
	finally
	  {
	    in.close();
	  }
	final byte[] classData = data;

        // Now get the CodeSource
        final CodeSource source = resource.getCodeSource();

        // Find out package name
        String packageName = null;
        int lastDot = className.lastIndexOf('.');
        if (lastDot != -1)
          packageName = className.substring(0, lastDot);

        if (packageName != null && getPackage(packageName) == null)
          {
            // define the package
            Manifest manifest = resource.loader.getManifest();
            if (manifest == null)
              definePackage(packageName, null, null, null, null, null, null,
                            null);
            else
              definePackage(packageName, manifest, resource.loader.baseURL);
          }

        // And finally construct the class!
        SecurityManager sm = System.getSecurityManager();
        Class result = null;
        if (sm != null && securityContext != null)
          {
            result = (Class)AccessController.doPrivileged
              (new PrivilegedAction()
                {
                  public Object run()
                  {
                    return defineClass(className, classData,
                                       0, classData.length,
                                       source);
                  }
                }, securityContext);
          }
        else
          result = defineClass(className, classData, 0, classData.length, source);

        // Avoid NullPointerExceptions.
        Certificate[] resourceCertificates = resource.getCertificates();
        if(resourceCertificates != null)
          super.setSigners(result, resourceCertificates);
        
        return result;
      }
    catch (IOException ioe)
      {
	ClassNotFoundException cnfe;
	cnfe = new ClassNotFoundException(className + " not found in " + this);
	cnfe.initCause(ioe);
	throw cnfe;
      }
  }
  
  // Cached String representation of this URLClassLoader
  private String thisString;
  
  /**
   * Returns a String representation of this URLClassLoader giving the
   * actual Class name, the URLs that are searched and the parent
   * ClassLoader.
   */
  public String toString()
  {
    synchronized (this)
      {
	if (thisString == null)
	  {
	    StringBuffer sb = new StringBuffer();
	    sb.append(this.getClass().getName());
	    sb.append("{urls=[" );
	    URL[] thisURLs = getURLs();
	    for (int i = 0; i < thisURLs.length; i++)
	      {
		sb.append(thisURLs[i]);
		if (i < thisURLs.length - 1)
		  sb.append(',');
	      }
	    sb.append(']');
	    sb.append(", parent=");
	    sb.append(getParent());
	    sb.append('}');
	    thisString = sb.toString();
	  }
	return thisString;
      }
  }

  /**
   * Finds the first occurrence of a resource that can be found. The locations
   * are searched in the order they were added to the URLClassLoader.
   *
   * @param resourceName the resource name to look for
   * @return the URLResource for the resource if found, null otherwise
   */
  private Resource findURLResource(String resourceName)
  {
    int max = urlinfos.size();
    for (int i = 0; i < max; i++)
      {
        URLLoader loader = (URLLoader) urlinfos.elementAt(i);
        if (loader == null)
          continue;

        Resource resource = loader.getResource(resourceName);
        if (resource != null)
          return resource;
      }
    return null;
  }

  /**
   * Finds the first occurrence of a resource that can be found.
   *
   * @param resourceName the resource name to look for
   * @return the URL if found, null otherwise
   */
  public URL findResource(String resourceName)
  {
    Resource resource = findURLResource(resourceName);
    if (resource != null)
      return resource.getURL();

    // Resource not found
    return null;
  }

  /**
   * If the URLStreamHandlerFactory has been set this return the appropriate
   * URLStreamHandler for the given protocol, if not set returns null.
   *
   * @param protocol the protocol for which we need a URLStreamHandler
   * @return the appropriate URLStreamHandler or null
   */
  URLStreamHandler getURLStreamHandler(String protocol)
  {
    if (factory == null)
      return null;

    URLStreamHandler handler;
    synchronized (factoryCache)
      {
        // Check if there're handler for the same protocol in cache.
        HashMap cache = (HashMap) factoryCache.get(factory);
        handler = (URLStreamHandler) cache.get(protocol);
        if (handler == null)
          {
            // Add it to cache.
            handler = factory.createURLStreamHandler(protocol);
            cache.put(protocol, handler);
          }
      }
    return handler;
  }

  /**
   * Finds all the resources with a particular name from all the locations.
   *
   * @param resourceName the name of the resource to lookup
   * @return a (possible empty) enumeration of URLs where the resource can be
   * found
   * @exception IOException when an error occurs accessing one of the
   * locations
   */
  public Enumeration findResources(String resourceName)
    throws IOException
  {
    Vector resources = new Vector();
    int max = urlinfos.size();
    for (int i = 0; i < max; i++)
      {
        URLLoader loader = (URLLoader) urlinfos.elementAt(i);
        Resource resource = loader.getResource(resourceName);
        if (resource != null)
          resources.add(resource.getURL());
      }
    return resources.elements();
  }

  /**
   * Returns the permissions needed to access a particular code
   * source.  These permissions includes those returned by
   * <code>SecureClassLoader.getPermissions()</code> and the actual
   * permissions to access the objects referenced by the URL of the
   * code source.  The extra permissions added depend on the protocol
   * and file portion of the URL in the code source. If the URL has
   * the "file" protocol ends with a '/' character then it must be a
   * directory and a file Permission to read everything in that
   * directory and all subdirectories is added. If the URL had the
   * "file" protocol and doesn't end with a '/' character then it must
   * be a normal file and a file permission to read that file is
   * added. If the <code>URL</code> has any other protocol then a
   * socket permission to connect and accept connections from the host
   * portion of the URL is added.
   *
   * @param source The codesource that needs the permissions to be accessed
   * @return the collection of permissions needed to access the code resource
   * @see java.security.SecureClassLoader#getPermissions(CodeSource)
   */
  protected PermissionCollection getPermissions(CodeSource source)
  {
    // XXX - This implementation does exactly as the Javadoc describes.
    // But maybe we should/could use URLConnection.getPermissions()?
    // First get the permissions that would normally be granted
    PermissionCollection permissions = super.getPermissions(source);

    // Now add any extra permissions depending on the URL location.
    URL url = source.getLocation();
    String protocol = url.getProtocol();
    if (protocol.equals("file"))
      {
        String file = url.getFile();

        // If the file end in / it must be an directory.
        if (file.endsWith("/") || file.endsWith(File.separator))
          {
            // Grant permission to read everything in that directory and
            // all subdirectories.
            permissions.add(new FilePermission(file + "-", "read"));
          }
        else
          {
            // It is a 'normal' file.
            // Grant permission to access that file.
            permissions.add(new FilePermission(file, "read"));
          }
      }
    else
      {
        // Grant permission to connect to and accept connections from host
        String host = url.getHost();
        if (host != null)
          permissions.add(new SocketPermission(host, "connect,accept"));
      }

    return permissions;
  }

  /**
   * Returns all the locations that this class loader currently uses the
   * resolve classes and resource. This includes both the initially supplied
   * URLs as any URLs added later by the loader.
   * @return All the currently used URLs
   */
  public URL[] getURLs()
  {
    return (URL[]) urls.toArray(new URL[urls.size()]);
  }

  /**
   * Creates a new instance of a <code>URLClassLoader</code> that gets
   * classes from the supplied <code>URL</code>s. This class loader
   * will have as parent the standard system class loader.
   *
   * @param urls the initial URLs used to resolve classes and
   * resources
   *
   * @return the class loader
   *
   * @exception SecurityException when the calling code does not have
   * permission to access the given <code>URL</code>s
   */
  public static URLClassLoader newInstance(URL[] urls)
    throws SecurityException
  {
    return newInstance(urls, null);
  }

  /**
   * Creates a new instance of a <code>URLClassLoader</code> that gets
   * classes from the supplied <code>URL</code>s and with the supplied
   * loader as parent class loader.
   *
   * @param urls the initial URLs used to resolve classes and
   * resources
   * @param parent the parent class loader
   *
   * @return the class loader
   *
   * @exception SecurityException when the calling code does not have
   * permission to access the given <code>URL</code>s
   */
  public static URLClassLoader newInstance(URL[] urls, final ClassLoader parent)
    throws SecurityException
  {
    SecurityManager sm = System.getSecurityManager();
    if (sm == null)
      return new URLClassLoader(urls, parent);
    else
      {
        final Object securityContext = sm.getSecurityContext();

        // XXX - What to do with anything else then an AccessControlContext?
        if (! (securityContext instanceof AccessControlContext))
          throw new SecurityException("securityContext must be AccessControlContext: "
                                      + securityContext);

        URLClassLoader loader =
          (URLClassLoader) AccessController.doPrivileged(new PrivilegedAction()
              {
                public Object run()
                {
                  return new URLClassLoader(parent,
                                            (AccessControlContext) securityContext);
                }
              });
        loader.addURLs(urls);
        return loader;
      }
  }

  /**
   * Tell whether runtime initialization is complete.
   *
   * @return whether runtime initialization is complete.
   */
  private static native boolean runtimeInitialized();  
}
