urlclassloader.java

来自「纯java操作系统jnode,安装简单和操作简单的个人使用的Java操作系统」· Java 代码 · 共 1,066 行 · 第 1/3 页

JAVA
1,066
字号

    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.
   */
  final static class RemoteURLLoader extends URLLoader
  {
    final private 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.
   */
  final static class RemoteResource extends Resource
  {
    final private URL url;
    final private InputStream stream;
    final private 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>FileURLLoader</code> is a type of <code>URLLoader</code>
   * only loading from file url.
   */
  final static 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;
    }
  }

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

  /**
   * 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.
   */
  private 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)
  {
    synchronized(urlloaders)
      {
	if (newUrl == null)
	  return; // Silently ignore...
        
	// 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();
	    // Check that it is not a directory
	    if (! (file.endsWith("/") || file.endsWith(File.separator)))
	      loader = new JarURLLoader(this, newUrl);
	    else if ("file".equals(newUrl.getProtocol()))
	      loader = new FileURLLoader(this, newUrl);
	    else
	      loader = new RemoteURLLoader(this, newUrl);

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

	urls.add(newUrl);
	urlinfos.add(loader);
      }
  }

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

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?