/** * 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"); } }
/* * 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); }