/* URLClassLoader.java --  ClassLoader that loads classes from one or more URLs
   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
   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., 59 Temple Place, Suite 330, Boston, MA
02111-1307 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;
    final String name;

    Resource(URLLoader loader, String name)
    {
      this.loader = loader;
      this.name = name;
    }

    /**
     * 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)
    {
      super(classloader, baseURL);

      // 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;

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

    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, name);
      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, name, url);
    }
  }

  final static class SoResource extends Resource
  {
    SoResource(SoURLLoader loader, String name, URL url)
    {
      super(loader, name);
      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)
    {
      super(classloader, url);
      dir = new File(baseURL.getFile());
    }

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

  static final class FileResource extends Resource
  {
    final File file;

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

    InputStream getInputStream() throws IOException
    {
      return new FileInputStream(file);
    }

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

    public URL getURL()
    {
      try
        {
          return new URL(loader.baseURL, name,
                         loader.classloader.getURLStreamHandler("file"));
        }
      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
  {
    final Core core;

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

    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).
   *
   * @exception SecurityException if the SecurityManager disallows the
   * creation of a ClassLoader.
   * @param urls Locations that should be searched by this ClassLoader when
   * resolving Classes or Resources.
   * @see SecureClassLoader
   */
  public URLClassLoader(URL[] urls) throws SecurityException
  {
    super();
    this.factory = null;
    this.securityContext = null;
    addURLs(urls);
  }

  /**
   * Private constructor used by the static
   * <code>newInstance(URL[])</code> method.  Creates an
   * <code>URLClassLoader</code> 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.
   */
  private URLClassLoader(AccessControlContext securityContext)
  {
    super();
    this.factory = null;
    this.securityContext = securityContext;
  }

  /**
   * 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).
   * @exception SecurityException if the SecurityManager disallows the
   * creation of a ClassLoader.
   * @exception SecurityException
   * @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.
   * @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.
   * @exception SecurityException if the SecurityManager disallows the
   * creation of a ClassLoader.
   * @exception SecurityException
   * @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.
   * @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 (urlloaders)
      {
        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();

            // 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);
            else if ("file".equals(protocol))
              loader = new FileURLLoader(this, newUrl);
	    else if ("xxxFIXMExxxcore".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.
   * @param newUrls the locations to add
   */
  private void addURLs(URL[] newUrls)
  {
    for (int i = 0; i < newUrls.length; i++)
      addURL(newUrls[i]);
  }

  /**
   * Defines a Package based on the given name and the supplied manifest
   * information. The manifest indicates the tile, version and
   * vendor information of the specification and implementation and wheter 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.
   *
   * @exception IllegalArgumentException If this package name already exists
   * in this class loader
   * @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
   */
  protected Package definePackage(String name, Manifest manifest, URL url)
    throws IllegalArgumentException
  {
    Attributes attr = manifest.getMainAttributes();
    String specTitle = attr.getValue(Attributes.Name.SPECIFICATION_TITLE);
    String specVersion = attr.getValue(Attributes.Name.SPECIFICATION_VERSION);
    String specVendor = attr.getValue(Attributes.Name.SPECIFICATION_VENDOR);
    String implTitle = attr.getValue(Attributes.Name.IMPLEMENTATION_TITLE);
    String implVersion = attr.getValue(Attributes.Name.IMPLEMENTATION_VERSION);
    String implVendor = attr.getValue(Attributes.Name.IMPLEMENTATION_VENDOR);

    // 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, specVersion, specVendor, implTitle,
                         implVersion, implVendor, 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)
      throw new ClassNotFoundException(className + " not found in " + this);

    // 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();
	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();
          }
        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);

        super.setSigners(result, resource.getCertificates());
        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 (urlloaders)
      {
	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.
   *
   * @exception IOException when an error occurs accessing one of the
   * locations
   * @param resourceName the name of the resource to lookup
   * @return a (possible empty) enumeration of URLs where the resource can be
   * found
   */
  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()
   */
  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;
      }
  }
}
