/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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 in the LICENSE file that
* accompanied this code).
*
* 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* 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
*/
public class URLClassPath {
private static final boolean DEBUG;
private static final boolean DISABLE_JAR_CHECKING;
static {
}
/* The original search path of URLs. */
/* The stack of unopened URLs */
/* The resulting search path of Loaders */
/* Map of each URL opened to its corresponding Loader */
/* The jar protocol handler to use when creating new URLs */
/* Whether this URLClassLoader has been closed yet */
private boolean closed = false;
/**
* 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
*/
}
}
}
}
if (closed) {
return Collections.emptyList();
}
try {
} catch (IOException e) {
}
}
closed = true;
return result;
}
/**
* Appends the specified URL to the search path of directory and JAR
* file URLs from which to load classes and resources.
* <p>
* If the URL specified is null or is already in the list of
* URLs, then invoking this method has no effect.
*/
if (closed)
return;
synchronized (urls) {
return;
}
}
/**
* Returns the original search path of URLs.
*/
synchronized (urls) {
}
}
/**
* 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.
*/
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
*/
if (DEBUG) {
}
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
*/
final boolean check) {
return new Enumeration<URL>() {
private int index = 0;
private boolean next() {
return true;
} else {
return true;
}
}
return false;
}
}
public boolean hasMoreElements() {
return next();
}
public URL nextElement() {
if (!next()) {
throw new NoSuchElementException();
}
return u;
}
};
}
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
*/
final boolean check) {
return new Enumeration<Resource>() {
private int index = 0;
private boolean next() {
return true;
} else {
return true;
}
}
return false;
}
}
public boolean hasMoreElements() {
return next();
}
public Resource nextElement() {
if (!next()) {
throw new NoSuchElementException();
}
return r;
}
};
}
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.
*/
if (closed) {
return null;
}
// Expand URL search path until the request can be satisfied
// or the URL stack is empty.
// Pop the next URL from the URL stack
synchronized (urls) {
return null;
} else {
}
}
// 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.)
continue;
}
// Otherwise, create a new Loader for the URL.
try {
// If the loader defines a local class path then add the
// URLs to the list of URLs to be opened.
}
} catch (IOException e) {
// Silently ignore for now...
continue;
}
// Finally, add the Loader to the search path.
}
}
/*
* Returns the Loader for the specified base URL.
*/
try {
return new FileLoader(url);
} else {
}
} else {
}
}
});
}
}
/*
* Pushes the specified URLs onto the list of unopened URLs.
*/
synchronized (urls) {
}
}
}
/**
* 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.
*/
int count = 0;
while (st.hasMoreTokens()) {
try {
f = new File(f.getCanonicalPath());
} catch (IOException x) {
// use the non-canonicalized filename
}
try {
} catch (IOException x) { }
}
}
return urls;
}
/*
* Check whether the resource URL should be returned.
* Return null on security check failure.
* Called by java.net.URLClassLoader.
*/
try {
} catch (Exception e) {
return null;
}
return url;
}
/*
* Check whether the resource URL should be returned.
* Throw exception on failure.
* Called internally within this file.
*/
try {
} catch (SecurityException se) {
// fallback to checkRead/checkConnect for pre 1.2
// security managers
} else if ((perm instanceof
if (urlConnection instanceof JarURLConnection) {
}
} else {
throw se;
}
}
}
}
}
/**
* Inner class used to represent a loader of resources and classes
* from a base URL.
*/
/*
* Creates a new Loader for the specified URL.
*/
}
/*
* Returns the base URL for this Loader.
*/
return base;
}
try {
} catch (MalformedURLException e) {
throw new IllegalArgumentException("name");
}
try {
if (check) {
}
/*
* For a HTTP connection we use the HEAD method to
* check if the resource exists.
*/
if (uc instanceof HttpURLConnection) {
return null;
}
} else {
// our best guess for the other cases
}
return url;
} catch (Exception e) {
return null;
}
}
try {
} catch (MalformedURLException e) {
throw new IllegalArgumentException("name");
}
final URLConnection uc;
try {
if (check) {
}
if (uc instanceof JarURLConnection) {
/* Need to remember the jar file so it can be closed
* in a hurry.
*/
}
} catch (Exception e) {
return null;
}
return new Resource() {
return uc.getInputStream();
}
public int getContentLength() throws IOException {
return uc.getContentLength();
}
};
}
/*
* Returns the Resource for the specified name, or null if not
* found or the caller does not have the permission to get the
* resource.
*/
return getResource(name, true);
}
/*
* close this loader and release all resources
* method overridden in sub-classes
*/
}
}
/*
* Returns the local class path for this loader, or null if none.
*/
return null;
}
}
/*
* Inner class used to represent a Loader of resources from a JAR URL.
*/
private boolean closed = false;
/*
* Creates a new JarLoader for the specified URL referring to
* a JAR file.
*/
throws IOException
{
if (!isOptimizable(url)) {
ensureOpen();
} else {
// If the meta index is found but the file is not
// installed, set metaIndex to null. A typical
// senario is charsets.jar which won't be installed
// when the user is running in certain locale environment.
// The side effect of null metaIndex will cause
// ensureOpen get called so that IOException is thrown.
}
}
// metaIndex is null when either there is no such jar file
// entry recorded in meta-index file or such jar file is
// missing in JRE. See bug 6340399.
ensureOpen();
}
}
}
// closing is synchronized at higher level
if (!closed) {
closed = true;
// in case not already open.
ensureOpen();
}
}
return jar;
}
}
try {
if (DEBUG) {
}
// Add all the dependent URLs to the lmap so that loaders
// will not be created for them by URLClassPath.getLoader(int)
// if the same URL occurs later on the main class path. We set
// Loader to null here to avoid creating a Loader for each
// URL until we actually need to try to load something from them.
try {
// If a non-null loader already exists, leave it alone.
}
} catch (MalformedURLException e) {
continue;
}
}
}
return null;
}
}
);
}
}
}
/* Throws if the given jar file is does not start with the correct LOC */
try {
} catch (IOException ex) {
x.addSuppressed(ex);
}
throw x;
}
return jar;
}
// Optimize case where url refers to a local jar file
if (isOptimizable(url)) {
if (!p.exists()) {
throw new FileNotFoundException(p.getPath());
}
}
}
/*
* Returns the index of this JarLoader if it exists.
*/
try {
ensureOpen();
} catch (IOException e) {
}
return index;
}
/*
* Creates the resource and if the check flag is set to true, checks if
* is its okay to return the resource.
*/
try {
if (check) {
}
} catch (MalformedURLException e) {
return null;
// throw new IllegalArgumentException("name");
} catch (IOException e) {
return null;
} catch (AccessControlException e) {
return null;
}
return new Resource() {
public int getContentLength()
{ return jar.getManifest(); };
public Certificate[] getCertificates()
{ return entry.getCertificates(); };
public CodeSigner[] getCodeSigners()
{ return entry.getCodeSigners(); };
};
}
/*
* Returns true iff atleast one resource in the jar file has the same
* package name as that of the specified resource name.
*/
int pos;
}
while (enum_.hasMoreElements()) {
return true;
}
}
return false;
}
/*
* Returns the URL for a resource with the specified name
*/
}
return null;
}
/*
* Returns the JAR Resource for the specified name.
*/
return null;
}
}
try {
ensureOpen();
} catch (IOException e) {
}
return null;
}
/*
* Version of getResource() that tracks the jar files that have been
* visited by linking through the index files. This helper method uses
* a HashSet to store the URLs of jar files that have been searched and
* uses it to avoid going into an infinite loop, looking for a
* non-existent resource
*/
boolean done = false;
int count = 0;
/* If there no jar files in the index that can potential contain
* this resource then return immediately.
*/
return null;
do {
/* loop through the mapped jar file list */
try{
/* no loader has been set up for this jar file
* before
*/
new PrivilegedExceptionAction<JarLoader>() {
lmap);
}
});
/* this newly opened jar file has its own index,
* merge it into the parent's index, taking into
* account the relative path.
*/
}
/* put it in the global hashtable */
}
continue;
} catch (MalformedURLException e) {
continue;
}
/* Note that the addition of the url to the list of visited
* jars incorporates a check for presence in the hashmap
*/
if (!visitedURL) {
try {
} catch (IOException e) {
}
}
/* Verify that at least one other resource with the
* same package name as the lookedup resource is
* present in the new jar
*/
/* the mapping is wrong */
throw new InvalidJarIndexException("Invalid index");
}
}
/* If newLoader is the current loader or if it is a
* loader that has already been searched or if the new
* loader does not have an index then skip it
* and move on to the next loader.
*/
if (visitedURL || newLoader == this ||
continue;
}
/* Process the index of the new loader
*/
!= null) {
return res;
}
}
// Get the list of jar files again as the list could have grown
// due to merging of index files.
// If the count is unchanged, we are done.
return null;
}
/*
* Returns the JAR file local class path, or null if none.
*/
return null;
}
return null;
}
ensureOpen();
if (SharedSecrets.javaUtilJarAccess().jarFileHasClassPathAttribute(jar)) { // Only get manifest when necessary
}
}
}
}
return null;
}
/*
* parse the standard extension dependencies
*/
}
/*
* Parses value of the Class-Path manifest attribute and returns
* an array of URLs relative to the specified base URL.
*/
throws MalformedURLException
{
int i = 0;
while (st.hasMoreTokens()) {
i++;
}
return urls;
}
}
/*
* Inner class used to represent a loader of classes and resources
* from a file URL that refers to a directory.
*/
/* Canonicalized File */
super(url);
throw new IllegalArgumentException("url");
}
}
/*
* Returns the URL for a resource with the specified name
*/
}
return null;
}
try {
// requested resource had ../..'s in path
return null;
}
if (check)
.getCanonicalFile();
/* outside of base dir */
return null;
}
} else {
}
return new Resource() {
{ return new FileInputStream(file); };
public int getContentLength() throws IOException
};
}
} catch (Exception e) {
return null;
}
return null;
}
}
}