/* 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 gnu.java.lang.CPStringBuilder;

import gnu.java.net.loader.FileURLLoader;
import gnu.java.net.loader.JarURLLoader;
import gnu.java.net.loader.RemoteURLLoader;
import gnu.java.net.loader.Resource;
import gnu.java.net.loader.URLLoader;
import gnu.java.net.loader.URLStreamHandlerCache;

import java.io.ByteArrayOutputStream;
import java.io.EOFException;
import java.io.File;
import java.io.FilePermission;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
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.ArrayList;
import java.util.Enumeration;
import java.util.Vector;
import java.util.jar.Attributes;
import java.util.jar.Manifest;


/**
 * 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 cache to store mappings between handler factory and its
   * private protocol handler cache (also a HashMap), so we can avoid
   * creating handlers each time the same protocol comes.
   */
  private static URLStreamHandlerCache factoryCache
    = new URLStreamHandlerCache();

  /**
   * The prefix for URL loaders.
   */
  private static final String URL_LOADER_PREFIX = "gnu.java.net.loader.Load_";

  // Instance variables

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

  /**
   * 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<URLLoader> urlinfos = new Vector<URLLoader>();

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

  /**
   * 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;
    // If this factory is not yet in factoryCache, add it.
    factoryCache.add(factory);
    addURLs(urls);
  }

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

        // Create a loader for this URL.
        URLLoader 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);
            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;
          }

        // First see if we can find a handler with the correct name.
        try
          {
            Class<?> handler = Class.forName(URL_LOADER_PREFIX + protocol);
            Class<?>[] argTypes = new Class<?>[] { URLClassLoader.class,
                                                   URLStreamHandlerCache.class,
                                                   URLStreamHandlerFactory.class,
                                                   URL.class,
                                                   URL.class };
            Constructor k = handler.getDeclaredConstructor(argTypes);
            loader
              = (URLLoader) k.newInstance(new Object[] { this,
                                                         factoryCache,
                                                         factory,
                                                         newUrl,
                                                         absoluteURL });
          }
        catch (ClassNotFoundException ignore)
          {
            // Fall through.
          }
        catch (NoSuchMethodException nsme)
          {
            // Programming error in the class library.
            InternalError vme
              = new InternalError("couldn't find URLLoader constructor");
            vme.initCause(nsme);
            throw vme;
          }
        catch (InstantiationException inste)
          {
            // Programming error in the class library.
            InternalError vme
              = new InternalError("couldn't instantiate URLLoader");
            vme.initCause(inste);
            throw vme;
          }
        catch (InvocationTargetException ite)
          {
            // Programming error in the class library.
            InternalError vme
              = new InternalError("error instantiating URLLoader");
            vme.initCause(ite);
            throw vme;
          }
        catch (IllegalAccessException illae)
          {
            // Programming error in the class library.
            InternalError vme
              = new InternalError("invalid access to URLLoader");
            vme.initCause(illae);
            throw vme;
          }

        if (loader == null)
          {
            // If it is not a directory, use the jar loader.
            if (! (file.endsWith("/") || file.endsWith(File.separator)))
              loader = new JarURLLoader(this, factoryCache, factory,
                                        newUrl, absoluteURL);
            else if ("file".equals(protocol))
              loader = new FileURLLoader(this, factoryCache, factory,
                                         newUrl, absoluteURL);
            else
              loader = new RemoteURLLoader(this, factoryCache, factory,
                                           newUrl);
          }

	urlinfos.add(loader);
	ArrayList<URLLoader> extra = loader.getClassPath();
        if (extra != null)
          urlinfos.addAll(extra);
      }
  }

  /**
   * 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.
    CPStringBuilder xform = new CPStringBuilder(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)
      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();
	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.getLoader().getManifest();
            if (manifest == null)
              definePackage(packageName, null, null, null, null, null, null,
                            null);
            else
              definePackage(packageName, manifest,
                            resource.getLoader().getBaseURL());
          }

        // And finally construct the class!
        SecurityManager sm = System.getSecurityManager();
        Class result = null;
        if (sm != null && securityContext != null)
          {
            result = AccessController.doPrivileged
              (new PrivilegedAction<Class>()
                {
                  public Class 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)
      {
	throw new ClassNotFoundException(className + " not found in " + this, ioe);
      }
  }
  
  // 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)
	  {
	    CPStringBuilder sb = new CPStringBuilder();
	    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;
  }

  /**
   * 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<URL> findResources(String resourceName)
    throws IOException
  {
    Vector<URL> resources = new Vector<URL>();
    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 =
          AccessController.doPrivileged(new PrivilegedAction<URLClassLoader>()
              {
                public URLClassLoader run()
                {
                  return new URLClassLoader(parent,
                                            (AccessControlContext) securityContext);
                }
              });
        loader.addURLs(urls);
        return loader;
      }
  }
}
