urlclasspath.java
来自「This is a resource based on j2me embedde」· Java 代码 · 共 922 行 · 第 1/2 页
JAVA
922 行
/* * @(#)URLClassPath.java 1.74 06/10/11 * * Copyright 1990-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation. * * This program 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 version 2 for more details (a copy is * included at /legal/license.txt). * * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. * */package sun.misc;import java.util.Enumeration;import java.util.HashMap;import java.util.LinkedList;import java.util.Hashtable;import java.util.NoSuchElementException;import java.util.Stack;import java.util.Set;import java.util.HashSet;import java.util.StringTokenizer;import java.util.ArrayList;import java.util.jar.JarFile;import sun.net.www.ParseUtil;import java.util.zip.ZipEntry;import java.util.jar.JarEntry;import java.util.jar.Manifest;import java.util.jar.Attributes;import java.util.jar.Attributes.Name;import java.net.JarURLConnection;import java.net.MalformedURLException;import java.net.URL;import java.net.URLConnection;import java.net.HttpURLConnection;import java.net.URLStreamHandler;import java.net.URLStreamHandlerFactory;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.InputStream;import java.io.IOException;import java.security.AccessController;import java.security.AccessControlException;import java.security.Permission;import java.security.PrivilegedExceptionAction;import java.security.cert.Certificate;/** * This class is used to maintain a search path of URLs for loading classes * and resources from both JAR files and directories. * * @author David Connelly * @version 1.62, 03/09/00 */public class URLClassPath { final static String USER_AGENT_JAVA_VERSION = "UA-Java-Version"; final static String JAVA_VERSION; static { JAVA_VERSION = (String) java.security.AccessController.doPrivileged( new sun.security.action.GetPropertyAction("java.version")); } /* The original search path of URLs. */ private ArrayList path = new ArrayList(); /* The stack of unopened URLs */ private Stack urls = new Stack(); /* The resulting search path of Loaders */ private ArrayList loaders = new ArrayList(); /* Map of each URL opened to its corresponding Loader */ private HashMap lmap = new HashMap(); /* The jar protocol handler to use when creating new URLs */ private URLStreamHandler jarHandler; /** * Creates a new URLClassPath for the given URLs. The URLs will be * searched in the order specified for classes and resources. A URL * ending with a '/' is assumed to refer to a directory. Otherwise, * the URL is assumed to refer to a JAR file. * * @param urls the directory and JAR file URLs to search for classes * and resources * @param factory the URLStreamHandlerFactory to use when creating new URLs */ public URLClassPath(URL[] urls, URLStreamHandlerFactory factory) { for (int i = 0; i < urls.length; i++) { path.add(urls[i]); } push(urls); if (factory != null) { jarHandler = factory.createURLStreamHandler("jar"); } } public URLClassPath(URL[] urls) { this(urls, null); } /** * Appends the specified URL to the search path of directory and JAR * file URLs from which to load classes and resources. */ public void addURL(URL url) { synchronized (urls) { urls.add(0, url); path.add(url); } } /** * Returns the original search path of URLs. */ public URL[] getURLs() { synchronized (urls) { return (URL[])path.toArray(new URL[path.size()]); } } /** * Finds the resource with the specified name on the URL search path * or null if not found or security check fails. * * @param name the name of the resource * @param check whether to perform a security check * @return a <code>URL</code> for the resource, or <code>null</code> * if the resource could not be found. */ public URL findResource(String name, boolean check) { Loader loader; for (int i = 0; (loader = getLoader(i)) != null; i++) { URL url = loader.findResource(name, check); if (url != null) { return url; } } return null; } /** * Finds the first Resource on the URL search path which has the specified * name. Returns null if no Resource could be found. * * @param name the name of the Resource * @param check whether to perform a security check * @return the Resource, or null if not found */ public Resource getResource(String name, boolean check) { Loader loader; for (int i = 0; (loader = getLoader(i)) != null; i++) { Resource res = loader.getResource(name, check); if (res != null) { return res; } } return null; } /** * Finds all resources on the URL search path with the given name. * Returns an enumeration of the URL objects. * * @param name the resource name * @return an Enumeration of all the urls having the specified name */ public Enumeration findResources(final String name, final boolean check) { return new Enumeration() { private int index = 0; private URL url = null; private boolean next() { if (url != null) { return true; } else { Loader loader; while ((loader = getLoader(index++)) != null) { url = loader.findResource(name, check); if (url != null) { return true; } } return false; } } public boolean hasMoreElements() { return next(); } public Object nextElement() { if (!next()) { throw new NoSuchElementException(); } URL u = url; url = null; return u; } }; } public Resource getResource(String name) { return getResource(name, true); } /** * Finds all resources on the URL search path with the given name. * Returns an enumeration of the Resource objects. * * @param name the resource name * @return an Enumeration of all the resources having the specified name */ public Enumeration getResources(final String name, final boolean check) { return new Enumeration() { private int index = 0; private Resource res = null; private boolean next() { if (res != null) { return true; } else { Loader loader; while ((loader = getLoader(index++)) != null) { res = loader.getResource(name, check); if (res != null) { return true; } } return false; } } public boolean hasMoreElements() { return next(); } public Object nextElement() { if (!next()) { throw new NoSuchElementException(); } Resource r = res; res = null; return r; } }; } public Enumeration getResources(final String name) { return getResources(name, true); } /* * Returns the Loader at the specified position in the URL search * path. The URLs are opened and expanded as needed. Returns null * if the specified index is out of range. */ private synchronized Loader getLoader(int index) { // Expand URL search path until the request can be satisfied // or the URL stack is empty. while (loaders.size() < index + 1) { // Pop the next URL from the URL stack URL url; synchronized (urls) { if (urls.empty()) { return null; } else { url = (URL)urls.pop(); } } // Skip this URL if it already has a Loader. (Loader // may be null in the case where URL has not been opened // but is referenced by a JAR index.) if (lmap.containsKey(url)) { continue; } // Otherwise, create a new Loader for the URL. Loader loader; try { loader = getLoader(url); // If the loader defines a local class path then add the // URLs to the list of URLs to be opened. URL[] urls = loader.getClassPath(); if (urls != null) { push(urls); } } catch (IOException e) { // Silently ignore for now... continue; } // Finally, add the Loader to the search path. loaders.add(loader); lmap.put(url, loader); } return (Loader)loaders.get(index); } /* * Returns the Loader for the specified base URL. */ private Loader getLoader(final URL url) throws IOException { try { return (Loader)java.security.AccessController.doPrivileged (new java.security.PrivilegedExceptionAction() { public Object run() throws IOException { String file = url.getFile(); if (file != null && file.endsWith("/")) { if ("file".equals(url.getProtocol())) { return new FileLoader(url); } else { return new Loader(url); } } else { return new JarLoader(url, jarHandler, lmap); } } }); } catch (java.security.PrivilegedActionException pae) { throw (IOException)pae.getException(); } } /* * Pushes the specified URLs onto the list of unopened URLs. */ private void push(URL[] us) { synchronized (urls) { for (int i = us.length - 1; i >= 0; --i) { urls.push(us[i]); } } } /** * Convert class path specification into an array of file URLs. * * The path of the file is encoded before conversion into URL * form so that reserved characters can safely appear in the path. */ public static URL[] pathToURLs(String path) { StringTokenizer st = new StringTokenizer(path, File.pathSeparator); URL[] urls = new URL[st.countTokens()]; int count = 0; while (st.hasMoreTokens()) { File f = new File(st.nextToken()); try { f = new File(f.getCanonicalPath()); } catch (IOException x) { // use the non-canonicalized filename } try { urls[count++] = ParseUtil.fileToEncodedURL(f); } catch (IOException x) { } } if (urls.length != count) { URL[] tmp = new URL[count]; System.arraycopy(urls, 0, tmp, 0, count); urls = tmp; } return urls; } /* * Check whether the resource URL should be returned. * Return null on security check failure. * Called by java.net.URLClassLoader. */ public URL checkURL(URL url) { try { check(url); } catch (Exception e) { return null; } return url; } /* * Check whether the resource URL should be returned. * Throw exception on failure. * Called internally within this file. */ static void check(URL url) throws IOException { SecurityManager security = System.getSecurityManager(); if (security != null) { URLConnection urlConnection = url.openConnection(); Permission perm = urlConnection.getPermission(); if (perm != null) { try { security.checkPermission(perm); } catch (SecurityException se) { // fallback to checkRead/checkConnect for pre 1.2 // security managers if ((perm instanceof java.io.FilePermission) && perm.getActions().indexOf("read") != -1) { security.checkRead(perm.getName()); } else if ((perm instanceof java.net.SocketPermission) && perm.getActions().indexOf("connect") != -1) { URL locUrl = url; if (urlConnection instanceof JarURLConnection) { locUrl = ((JarURLConnection)urlConnection).getJarFileURL(); } security.checkConnect(locUrl.getHost(), locUrl.getPort()); } else { throw se; } } } } } /** * Inner class used to represent a loader of resources and classes * from a base URL. */ private static class Loader { private final URL base; /* * Creates a new Loader for the specified URL. */ Loader(URL url) { base = url; } /* * Returns the base URL for this Loader. */ URL getBaseURL() { return base; } URL findResource(final String name, boolean check) { /* Bugid 5018127: do not throw exception if name is null */ if (name == null) return null; URL url; try {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?