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 + -
显示快捷键?