| /* Copyright (C) 1999, 2000 Free Software Foundation | |
| This file is part of libgcj. | |
| This software is copyrighted work licensed under the terms of the | |
| Libgcj License. Please consult the file "LIBGCJ_LICENSE" for | |
| details. */ | |
| package java.net; | |
| import java.io.*; | |
| import java.util.jar.*; | |
| import java.util.Enumeration; | |
| import java.util.Vector; | |
| public class URLClassLoader extends ClassLoader | |
| { | |
| // The URLStreamHandlerFactory | |
| URLStreamHandlerFactory factory = null; | |
| // `path' contains simply the URL's we're using for the searching. | |
| private Vector path; | |
| // If path[n] is a zip/jar, then this holds a JarURLConnection for | |
| // that thing, otherwise, path[n] is null. | |
| private Vector info; | |
| private URLStreamHandler getHandler0 (String protocol) | |
| { | |
| if (factory != null) | |
| return factory.createURLStreamHandler(protocol); | |
| else | |
| return null; | |
| } | |
| public URLClassLoader (URL[] urls) | |
| { | |
| this (urls, null, null); | |
| } | |
| public URLClassLoader (URL[] urls, ClassLoader parent) | |
| { | |
| this (urls, parent, null); | |
| } | |
| // A File URL may actually be a Jar URL. Convert if possible. | |
| private URL jarFileize (URL url) | |
| { | |
| if (! url.getProtocol ().equals ("jar")) | |
| { | |
| String f = url.getFile (); | |
| // If it ends with '/' we'll take it for a directory, | |
| // otherwise it's a jar file. This is how JDK 1.2 defines | |
| // it, so we will not try to be smart here. | |
| if (f.charAt (f.length ()-1) != '/') | |
| { | |
| try | |
| { | |
| url = new URL ("jar", "", -1, (url.toExternalForm ())+"!/", | |
| getHandler0 ("jar")); | |
| } | |
| catch (MalformedURLException x) | |
| { | |
| /* ignore */ | |
| } | |
| } | |
| } | |
| return url; | |
| } | |
| protected void addURL (URL url) | |
| { | |
| JarURLConnection conn = null; | |
| // Convert a Jar File URL into Jar URL if possible. | |
| url = jarFileize (url); | |
| path.addElement (url); | |
| if (url.getProtocol ().equals ("jar")) | |
| { | |
| try | |
| { | |
| conn = (JarURLConnection) url.openConnection (); | |
| } | |
| catch (java.io.IOException x) | |
| { | |
| /* ignore */ | |
| } | |
| } | |
| info.addElement (conn); | |
| } | |
| public URLClassLoader (URL[] urls, ClassLoader parent, | |
| URLStreamHandlerFactory fac) | |
| { | |
| super (parent); | |
| factory = fac; | |
| if (urls == null || urls.length == 0) | |
| { | |
| path = new Vector (1); | |
| info = new Vector (1); | |
| return; | |
| } | |
| path = new Vector (urls.length); | |
| info = new Vector (urls.length); | |
| for (int i = 0; i < urls.length; i++) | |
| { | |
| // Convert a Jar File URL into a Jar URL is possible. | |
| URL u = jarFileize(urls[i]); | |
| path.addElement (u); | |
| if (u.getProtocol ().equals ("jar")) | |
| { | |
| JarURLConnection conn = null; | |
| try | |
| { | |
| conn = (JarURLConnection) u.openConnection (); | |
| } | |
| catch (java.io.IOException x) | |
| { | |
| /* ignore */ | |
| } | |
| info.addElement (conn); | |
| } | |
| else | |
| { | |
| info.addElement (null); | |
| } | |
| } | |
| } | |
| public URL[] getURLs () | |
| { | |
| URL[] urls = new URL[path.size()]; | |
| path.copyInto (urls); | |
| return urls; | |
| } | |
| public Enumeration findResources (String name) | |
| { | |
| Vector results = new Vector (); | |
| for (int i = 0; i < path.size(); i++) | |
| { | |
| URL u = (URL)path.elementAt (i); | |
| try { | |
| JarURLConnection conn = (JarURLConnection) info.elementAt (i); | |
| if (conn != null) | |
| { | |
| if (conn.getJarFile().getJarEntry (name) != null) | |
| results.addElement (new URL(u, name, getHandler0 (u.getProtocol()))); | |
| } | |
| else | |
| { | |
| URL p = new URL (u, name, getHandler0 (u.getProtocol())); | |
| InputStream is = p.openStream(); | |
| if (is != null) | |
| { | |
| is.close(); | |
| results.addElement (p); | |
| } | |
| } | |
| // if we get an exception ... try the next path element | |
| } catch (IOException x) { | |
| continue; | |
| } | |
| } | |
| return results.elements (); | |
| } | |
| public URL findResource (String name) | |
| { | |
| for (int i = 0; i < path.size(); i++) | |
| { | |
| URL u = (URL)path.elementAt (i); | |
| try { | |
| JarURLConnection conn = (JarURLConnection) info.elementAt (i); | |
| if (conn != null) | |
| { | |
| if (conn.getJarFile().getJarEntry (name) != null) | |
| return new URL(u, name, getHandler0 (u.getProtocol())); | |
| } | |
| else | |
| { | |
| URL p = new URL (u, name, getHandler0 (u.getProtocol())); | |
| InputStream is = p.openStream(); | |
| if (is != null) | |
| { | |
| is.close(); | |
| return p; | |
| } | |
| } | |
| // if we get an exception ... try the next path element | |
| } catch (IOException x) { | |
| continue; | |
| } | |
| } | |
| return null; | |
| } | |
| // and finally, we can implement our class loader functionality. | |
| protected Class findClass (String name) | |
| throws ClassNotFoundException | |
| { | |
| if (name == null) | |
| throw new ClassNotFoundException ("null"); | |
| try | |
| { | |
| URL u = getResource (name.replace ('.', '/') + ".class"); | |
| if (u == null) | |
| throw new ClassNotFoundException (name); | |
| URLConnection connection = u.openConnection (); | |
| InputStream is = connection.getInputStream (); | |
| int len = connection.getContentLength (); | |
| byte[] data = new byte[len]; | |
| int left = len; | |
| int off = 0; | |
| while (left > 0) | |
| { | |
| int c = is.read (data, off, len-off); | |
| if (c == -1 || c == 0) | |
| throw new InternalError ("premature end of file"); | |
| left -= c; | |
| off += c; | |
| } | |
| return defineClass (name, data, 0, len); | |
| } | |
| catch (java.io.IOException x) | |
| { | |
| throw new ClassNotFoundException(name); | |
| } | |
| } | |
| } | |