diff options
Diffstat (limited to 'libjava/classpath/gnu/java/net/loader')
9 files changed, 1058 insertions, 0 deletions
diff --git a/libjava/classpath/gnu/java/net/loader/FileResource.java b/libjava/classpath/gnu/java/net/loader/FileResource.java new file mode 100644 index 000000000..471584023 --- /dev/null +++ b/libjava/classpath/gnu/java/net/loader/FileResource.java @@ -0,0 +1,82 @@ +/* FileResource.java -- a Resource for file URLs + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.net.loader; + + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; + +public final class FileResource extends Resource +{ + final File file; + + public FileResource(FileURLLoader loader, File file) + { + super(loader); + this.file = file; + } + + public InputStream getInputStream() throws IOException + { + return new FileInputStream(file); + } + + public int getLength() + { + return (int) file.length(); + } + + public URL getURL() + { + try + { + return file.toURL(); + } + catch (MalformedURLException e) + { + InternalError ie = new InternalError(); + ie.initCause(e); + throw ie; + } + } +} diff --git a/libjava/classpath/gnu/java/net/loader/FileURLLoader.java b/libjava/classpath/gnu/java/net/loader/FileURLLoader.java new file mode 100644 index 000000000..58b6dcf05 --- /dev/null +++ b/libjava/classpath/gnu/java/net/loader/FileURLLoader.java @@ -0,0 +1,145 @@ +/* FileURLLoader.java -- a URLLoader for file URLs + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.net.loader; + + +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.net.URLClassLoader; +import java.net.URLStreamHandlerFactory; +import java.util.StringTokenizer; + +/** + * A <code>FileURLLoader</code> is a type of <code>URLLoader</code> + * only loading from file url. + */ +public final class FileURLLoader extends URLLoader +{ + File dir; //the file for this file url + + public FileURLLoader(URLClassLoader classloader, + URLStreamHandlerCache cache, + URLStreamHandlerFactory factory, + URL url, URL absoluteUrl) + { + super(classloader, cache, factory, url, absoluteUrl); + dir = new File(absoluteUrl.getFile()); + } + + /** get resource with the name "name" in the file url */ + public Resource getResource(String name) + { + try + { + // Make sure that all components in name are valid by walking through + // them + File file = walkPathComponents(name); + + if (file == null) + return null; + + return new FileResource(this, file); + } + catch (IOException e) + { + // Fall through... + } + return null; + } + + /** + * Walk all path tokens and check them for validity. At no moment, we are + * allowed to reach a directory located "above" the root directory, stored + * in "dir" property. We are also not allowed to enter a non existing + * directory or a non directory component (plain file, symbolic link, ...). + * An empty or null path is valid. Pathnames components are separated by + * <code>File.separatorChar</code> + * + * @param resourceFileName the name to be checked for validity. + * @return the canonical file pointed by the resourceFileName or null if the + * walking failed + * @throws IOException in case of issue when creating the canonical + * resulting file + * @see File#separatorChar + */ + private File walkPathComponents(String resourceFileName) throws IOException + { + StringTokenizer stringTokenizer = new StringTokenizer(resourceFileName, File.separator); + File currentFile = dir; + int tokenCount = stringTokenizer.countTokens(); + + for (int i = 0; i < tokenCount - 1; i++) + { + String currentToken = stringTokenizer.nextToken(); + + // If we are at the root directory and trying to go up, the walking is + // finished with an error + if ("..".equals(currentToken) && currentFile.equals(dir)) + return null; + + currentFile = new File(currentFile, currentToken); + + // If the current file doesn't exist or is not a directory, the walking is + // finished with an error + if (! (currentFile.exists() && currentFile.isDirectory())) + return null; + + } + + // Treat the last token differently, if it exists, because it does not need + // to be a directory + if (tokenCount > 0) + { + String currentToken = stringTokenizer.nextToken(); + + if ("..".equals(currentToken) && currentFile.equals(dir)) + return null; + + currentFile = new File(currentFile, currentToken); + + // If the current file doesn't exist, the walking is + // finished with an error + if (! currentFile.exists()) + return null; + } + + return currentFile.getCanonicalFile(); + } +} diff --git a/libjava/classpath/gnu/java/net/loader/JarURLLoader.java b/libjava/classpath/gnu/java/net/loader/JarURLLoader.java new file mode 100644 index 000000000..6f06ad3b2 --- /dev/null +++ b/libjava/classpath/gnu/java/net/loader/JarURLLoader.java @@ -0,0 +1,215 @@ +package gnu.java.net.loader; + +import gnu.java.net.IndexListParser; + +import java.io.IOException; +import java.net.JarURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.net.URLStreamHandlerFactory; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Set; +import java.util.StringTokenizer; +import java.util.jar.Attributes; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; +import java.util.jar.Manifest; + +/** + * A <code>JarURLLoader</code> is a type of <code>URLLoader</code> + * only loading from jar url. + */ +public final class JarURLLoader extends URLLoader +{ + // True if we've initialized -- i.e., tried open the jar file. + boolean initialized; + // The jar file for this url. + JarFile jarfile; + // Base jar: url for all resources loaded from jar. + final URL baseJarURL; + // The "Class-Path" attribute of this Jar's manifest. + ArrayList<URLLoader> classPath; + // If not null, a mapping from INDEX.LIST for this jar only. + // This is a set of all prefixes and top-level files that + // ought to be available in this jar. + Set indexSet; + + // This constructor is used internally. It purposely does not open + // the jar file -- it defers this until later. This allows us to + // implement INDEX.LIST lazy-loading semantics. + private JarURLLoader(URLClassLoader classloader, URLStreamHandlerCache cache, + URLStreamHandlerFactory factory, + URL baseURL, URL absoluteUrl, + Set indexSet) + { + super(classloader, cache, factory, baseURL, absoluteUrl); + + URL newBaseURL = null; + try + { + // Cache url prefix for all resources in this jar url. + String base = baseURL.toExternalForm() + "!/"; + newBaseURL = new URL("jar", "", -1, base, cache.get(factory, "jar")); + } + catch (MalformedURLException ignore) + { + // Ignore. + } + this.baseJarURL = newBaseURL; + this.classPath = null; + this.indexSet = indexSet; + } + + // This constructor is used by URLClassLoader. It will immediately + // try to read the jar file, in case we've found an index or a class-path + // setting. FIXME: it would be nice to defer this as well, but URLClassLoader + // makes this hard. + public JarURLLoader(URLClassLoader classloader, URLStreamHandlerCache cache, + URLStreamHandlerFactory factory, + URL baseURL, URL absoluteUrl) + { + this(classloader, cache, factory, baseURL, absoluteUrl, null); + initialize(); + } + + private void initialize() + { + JarFile jarfile = null; + try + { + jarfile = + ((JarURLConnection) baseJarURL.openConnection()).getJarFile(); + + Manifest manifest; + Attributes attributes; + String classPathString; + + IndexListParser parser = new IndexListParser(jarfile, baseJarURL, + baseURL); + LinkedHashMap<URL, Set<String>> indexMap = parser.getHeaders(); + if (indexMap != null) + { + // Note that the index also computes + // the resulting Class-Path -- there are jars out there + // where the index lists some required jars which do + // not appear in the Class-Path attribute in the manifest. + this.classPath = new ArrayList<URLLoader>(); + Iterator<Map.Entry<URL, Set<String>>> it = indexMap.entrySet().iterator(); + while (it.hasNext()) + { + Map.Entry<URL, Set<String>> entry = it.next(); + URL subURL = entry.getKey(); + Set<String> prefixes = entry.getValue(); + if (subURL.equals(baseURL)) + this.indexSet = prefixes; + else + { + JarURLLoader subLoader = new JarURLLoader(classloader, + cache, + factory, subURL, + subURL, + prefixes); + // Note that we don't care if the sub-loader itself has an + // index or a class-path -- only the top-level jar + // file gets this treatment; its index should cover + // everything. + this.classPath.add(subLoader); + } + } + } + else if ((manifest = jarfile.getManifest()) != null + && (attributes = manifest.getMainAttributes()) != null + && ((classPathString + = attributes.getValue(Attributes.Name.CLASS_PATH)) + != null)) + { + this.classPath = new ArrayList<URLLoader>(); + StringTokenizer st = new StringTokenizer(classPathString, " "); + while (st.hasMoreElements ()) + { + String e = st.nextToken (); + try + { + URL subURL = new URL(baseURL, e); + // We've seen at least one jar file whose Class-Path + // attribute includes the original jar. If we process + // that normally we end up with infinite recursion. + if (subURL.equals(baseURL)) + continue; + JarURLLoader subLoader = new JarURLLoader(classloader, + cache, factory, + subURL, subURL); + this.classPath.add(subLoader); + ArrayList<URLLoader> extra = subLoader.getClassPath(); + if (extra != null) + this.classPath.addAll(extra); + } + catch (java.net.MalformedURLException xx) + { + // Give up + } + } + } + } + catch (IOException ioe) + { + /* ignored */ + } + + this.jarfile = jarfile; + this.initialized = true; + } + + /** get resource with the name "name" in the jar url */ + public Resource getResource(String name) + { + if (name.startsWith("/")) + name = name.substring(1); + if (indexSet != null) + { + // Trust the index. + String basename = name; + int offset = basename.lastIndexOf('/'); + if (offset != -1) + basename = basename.substring(0, offset); + if (! indexSet.contains(basename)) + return null; + // FIXME: if the index claim to hold the resource, and jar file + // doesn't have it, we're supposed to throw an exception. However, + // in our model this is tricky to implement, as another URLLoader from + // the same top-level jar may have an overlapping index entry. + } + + if (! initialized) + initialize(); + if (jarfile == null) + return null; + + JarEntry je = jarfile.getJarEntry(name); + if (je != null) + return new JarURLResource(this, name, je); + else + return null; + } + + public Manifest getManifest() + { + try + { + return (jarfile == null) ? null : jarfile.getManifest(); + } + catch (IOException ioe) + { + return null; + } + } + + public ArrayList<URLLoader> getClassPath() + { + return classPath; + } +} diff --git a/libjava/classpath/gnu/java/net/loader/JarURLResource.java b/libjava/classpath/gnu/java/net/loader/JarURLResource.java new file mode 100644 index 000000000..1dec92fd3 --- /dev/null +++ b/libjava/classpath/gnu/java/net/loader/JarURLResource.java @@ -0,0 +1,94 @@ +/* JarURLResource.java -- a Resource for jar URLs + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.net.loader; + + +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.security.cert.Certificate; +import java.util.jar.JarEntry; + +public final class JarURLResource extends Resource +{ + private final JarEntry entry; + private final String name; + + public JarURLResource(JarURLLoader loader, String name, JarEntry entry) + { + super(loader); + this.entry = entry; + this.name = name; + } + + public InputStream getInputStream() throws IOException + { + return ((JarURLLoader) loader).jarfile.getInputStream(entry); + } + + public int getLength() + { + return (int) entry.getSize(); + } + + public Certificate[] getCertificates() + { + // We have to get the entry from the jar file again, because the + // certificates will not be available until the entire entry has + // been read. + return ((JarEntry) ((JarURLLoader) loader).jarfile.getEntry(name)) + .getCertificates(); + } + + public URL getURL() + { + try + { + return new URL(((JarURLLoader) loader).baseJarURL, name, + loader.cache.get(loader.factory, "jar")); + } + catch (MalformedURLException e) + { + InternalError ie = new InternalError(); + ie.initCause(e); + throw ie; + } + } +} diff --git a/libjava/classpath/gnu/java/net/loader/RemoteResource.java b/libjava/classpath/gnu/java/net/loader/RemoteResource.java new file mode 100644 index 000000000..dc33b6636 --- /dev/null +++ b/libjava/classpath/gnu/java/net/loader/RemoteResource.java @@ -0,0 +1,78 @@ +/* Resource.java -- a Resource for "remote" URLs + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.net.loader; + + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; + +/** + * A resource from some remote location. + */ +public final class RemoteResource extends Resource +{ + private final URL url; + private final InputStream stream; + final int length; + + public RemoteResource(RemoteURLLoader loader, String name, URL url, + InputStream stream, int length) + { + super(loader); + this.url = url; + this.stream = stream; + this.length = length; + } + + public InputStream getInputStream() throws IOException + { + return stream; + } + + public int getLength() + { + return length; + } + + public URL getURL() + { + return url; + } +} diff --git a/libjava/classpath/gnu/java/net/loader/RemoteURLLoader.java b/libjava/classpath/gnu/java/net/loader/RemoteURLLoader.java new file mode 100644 index 000000000..81ef34f9e --- /dev/null +++ b/libjava/classpath/gnu/java/net/loader/RemoteURLLoader.java @@ -0,0 +1,101 @@ +/* RemoteURLLoader.java -- a URLLoader for "remote" objects + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.net.loader; + + +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLClassLoader; +import java.net.URLConnection; +import java.net.URLStreamHandlerFactory; + +/** + * Loader for remote directories. + */ +public final class RemoteURLLoader extends URLLoader +{ + private final String protocol; + + public RemoteURLLoader(URLClassLoader classloader, + URLStreamHandlerCache cache, + URLStreamHandlerFactory factory, + URL url) + { + super(classloader, cache, factory, url); + protocol = url.getProtocol(); + } + + /** + * Get a remote resource. + * Returns null if no such resource exists. + */ + public Resource getResource(String name) + { + try + { + URL url = new URL(baseURL, name, cache.get(factory, 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; + } + } +} diff --git a/libjava/classpath/gnu/java/net/loader/Resource.java b/libjava/classpath/gnu/java/net/loader/Resource.java new file mode 100644 index 000000000..53720b039 --- /dev/null +++ b/libjava/classpath/gnu/java/net/loader/Resource.java @@ -0,0 +1,110 @@ +/* Resource.java -- a resource for URLLoader + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.net.loader; + + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.security.CodeSource; +import java.security.cert.Certificate; + +/** + * A <code>Resource</code> represents a resource in some + * <code>URLLoader</code>. It also contains all information (e.g., + * <code>URL</code>, <code>CodeSource</code>, <code>Manifest</code> and + * <code>InputStream</code>) that is necessary for loading resources + * and creating classes from a <code>URL</code>. + */ +public abstract class Resource +{ + final URLLoader loader; + + public Resource(URLLoader loader) + { + this.loader = loader; + } + + /** + * Returns the non-null <code>CodeSource</code> associated with + * this resource. + */ + public CodeSource getCodeSource() + { + Certificate[] certs = getCertificates(); + if (certs == null) + return loader.noCertCodeSource; + else + return new CodeSource(loader.baseURL, certs); + } + + /** + * Returns <code>Certificates</code> associated with this + * resource, or null when there are none. + */ + public Certificate[] getCertificates() + { + return null; + } + + /** + * Return the URLLoader for this resource. + */ + public final URLLoader getLoader() + { + return loader; + } + + /** + * Return a <code>URL</code> that can be used to access this resource. + */ + public abstract URL getURL(); + + /** + * Returns the size of this <code>Resource</code> in bytes or + * <code>-1</code> when unknown. + */ + public abstract int getLength(); + + /** + * Returns the non-null <code>InputStream</code> through which + * this resource can be loaded. + */ + public abstract InputStream getInputStream() throws IOException; +} diff --git a/libjava/classpath/gnu/java/net/loader/URLLoader.java b/libjava/classpath/gnu/java/net/loader/URLLoader.java new file mode 100644 index 000000000..337564f6a --- /dev/null +++ b/libjava/classpath/gnu/java/net/loader/URLLoader.java @@ -0,0 +1,148 @@ +/* URLLoader.java -- base helper class for URLClassLoader + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.net.loader; + +import java.net.URL; +import java.net.URLClassLoader; +import java.net.URLStreamHandlerFactory; +import java.security.CodeSource; +import java.security.cert.Certificate; +import java.util.ArrayList; +import java.util.jar.Manifest; + +/** + * A <code>URLLoader</code> contains all logic to load resources from a + * given base <code>URL</code>. + */ +public abstract class URLLoader +{ + /** + * Our classloader to get info from if needed. + */ + final URLClassLoader classloader; + + /** + * The base URL from which all resources are loaded. + */ + final URL baseURL; + + /** + * The stream handler factory. + */ + final URLStreamHandlerFactory factory; + + /** + * The source for stream handlers. + */ + final URLStreamHandlerCache cache; + + /** + * A <code>CodeSource</code> without any associated certificates. + * It is common for classes to not have certificates associated + * with them. If they come from the same <code>URLLoader</code> + * then it is safe to share the associated <code>CodeSource</code> + * between them since <code>CodeSource</code> is immutable. + */ + final CodeSource noCertCodeSource; + + public URLLoader(URLClassLoader classloader, URLStreamHandlerCache cache, + URLStreamHandlerFactory factory, + URL baseURL) + { + this(classloader, cache, factory, baseURL, baseURL); + } + + public URLLoader(URLClassLoader classloader, URLStreamHandlerCache cache, + URLStreamHandlerFactory factory, + URL baseURL, URL overrideURL) + { + this.classloader = classloader; + this.baseURL = baseURL; + this.factory = factory; + this.cache = cache; + this.noCertCodeSource = new CodeSource(overrideURL, (Certificate[]) null); + } + + /** + * Return the base URL of this loader. + */ + public final URL getBaseURL() + { + return baseURL; + } + + /** + * Returns a <code>Class</code> loaded by this + * <code>URLLoader</code>, or <code>null</code> when this loader + * either can't load the class or doesn't know how to load classes + * at all. Most subclasses do not need to override this; it is only + * useful in situations where the subclass has a more direct way of + * making <code>Class</code> objects. + */ + public Class getClass(String className) + { + return null; + } + + /** + * Returns a <code>Resource</code> loaded by this + * <code>URLLoader</code>, or <code>null</code> when no + * <code>Resource</code> with the given name exists. + */ + public abstract Resource getResource(String s); + + /** + * Returns the <code>Manifest</code> associated with the + * <code>Resource</code>s loaded by this <code>URLLoader</code> or + * <code>null</code> there is no such <code>Manifest</code>. + */ + public Manifest getManifest() + { + return null; + } + + /** + * Return a list of new URLLoader objects representing any + * class path entries added by this container. + */ + public ArrayList<URLLoader> getClassPath() + { + return null; + } +} diff --git a/libjava/classpath/gnu/java/net/loader/URLStreamHandlerCache.java b/libjava/classpath/gnu/java/net/loader/URLStreamHandlerCache.java new file mode 100644 index 000000000..b7b8bf12b --- /dev/null +++ b/libjava/classpath/gnu/java/net/loader/URLStreamHandlerCache.java @@ -0,0 +1,85 @@ +/* URLStreamHandlerCache.java -- a cache for URLStreamHandlers + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.net.loader; + +import java.net.URLStreamHandler; +import java.net.URLStreamHandlerFactory; +import java.util.HashMap; + +/** + */ +public class URLStreamHandlerCache +{ + /** + * A cache to store mappings between handler factory and its + * private protocol handler cache (also a HashMap), so we can avoid + * creating handlers each time the same protocol comes. + */ + private HashMap<URLStreamHandlerFactory, HashMap<String, URLStreamHandler>> factoryCache + = new HashMap<URLStreamHandlerFactory, HashMap<String, URLStreamHandler>>(5); + + public URLStreamHandlerCache() + { + } + + public synchronized void add(URLStreamHandlerFactory factory) + { + // Since we only support three protocols so far, 5 is enough + // for cache initial size. + if (factory != null && factoryCache.get(factory) == null) + factoryCache.put(factory, new HashMap<String, URLStreamHandler>(5)); + } + + public synchronized URLStreamHandler get(URLStreamHandlerFactory factory, + String protocol) + { + if (factory == null) + return null; + // Check if there're handler for the same protocol in cache. + HashMap<String, URLStreamHandler> cache = factoryCache.get(factory); + URLStreamHandler handler = cache.get(protocol); + if (handler == null) + { + // Add it to cache. + handler = factory.createURLStreamHandler(protocol); + cache.put(protocol, handler); + } + return handler; + } +} |