diff options
Diffstat (limited to 'src/main/javassist/URLClassPath.java')
-rw-r--r-- | src/main/javassist/URLClassPath.java | 178 |
1 files changed, 178 insertions, 0 deletions
diff --git a/src/main/javassist/URLClassPath.java b/src/main/javassist/URLClassPath.java new file mode 100644 index 0000000..0cdb820 --- /dev/null +++ b/src/main/javassist/URLClassPath.java @@ -0,0 +1,178 @@ +/* + * Javassist, a Java-bytecode translator toolkit. + * Copyright (C) 1999-2007 Shigeru Chiba. All Rights Reserved. + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. Alternatively, the contents of this file may be used under + * the terms of the GNU Lesser General Public License Version 2.1 or later. + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + */ + +package javassist; + +import java.io.*; +import java.net.*; + +/** + * A class search-path specified with URL (http). + * + * @see javassist.ClassPath + * @see ClassPool#insertClassPath(ClassPath) + * @see ClassPool#appendClassPath(ClassPath) + */ +public class URLClassPath implements ClassPath { + protected String hostname; + protected int port; + protected String directory; + protected String packageName; + + /** + * Creates a search path specified with URL (http). + * + * <p>This search path is used only if a requested + * class name starts with the name specified by <code>packageName</code>. + * If <code>packageName</code> is "org.javassist." and a requested class is + * "org.javassist.test.Main", then the given URL is used for loading that class. + * The <code>URLClassPath</code> obtains a class file from: + * + * <ul><pre>http://www.javassist.org:80/java/classes/org/javassist/test/Main.class + * </pre></ul> + * + * <p>Here, we assume that <code>host</code> is "www.javassist.org", + * <code>port</code> is 80, and <code>directory</code> is "/java/classes/". + * + * <p>If <code>packageName</code> is <code>null</code>, the URL is used + * for loading any class. + * + * @param host host name + * @param port port number + * @param directory directory name ending with "/". + * It can be "/" (root directory). + * It must start with "/". + * @param packageName package name. It must end with "." (dot). + */ + public URLClassPath(String host, int port, + String directory, String packageName) { + hostname = host; + this.port = port; + this.directory = directory; + this.packageName = packageName; + } + + public String toString() { + return hostname + ":" + port + directory; + } + + /** + * Opens a class file with http. + * + * @return null if the class file could not be found. + */ + public InputStream openClassfile(String classname) { + try { + URLConnection con = openClassfile0(classname); + if (con != null) + return con.getInputStream(); + } + catch (IOException e) {} + return null; // not found + } + + private URLConnection openClassfile0(String classname) throws IOException { + if (packageName == null || classname.startsWith(packageName)) { + String jarname + = directory + classname.replace('.', '/') + ".class"; + return fetchClass0(hostname, port, jarname); + } + else + return null; // not found + } + + /** + * Returns the URL. + * + * @return null if the class file could not be obtained. + */ + public URL find(String classname) { + try { + URLConnection con = openClassfile0(classname); + InputStream is = con.getInputStream(); + if (is != null) { + is.close(); + return con.getURL(); + } + } + catch (IOException e) {} + return null; + } + + /** + * Closes this class path. + */ + public void close() {} + + /** + * Reads a class file on an http server. + * + * @param host host name + * @param port port number + * @param directory directory name ending with "/". + * It can be "/" (root directory). + * It must start with "/". + * @param classname fully-qualified class name + */ + public static byte[] fetchClass(String host, int port, + String directory, String classname) + throws IOException + { + byte[] b; + URLConnection con = fetchClass0(host, port, + directory + classname.replace('.', '/') + ".class"); + int size = con.getContentLength(); + InputStream s = con.getInputStream(); + try { + if (size <= 0) + b = ClassPoolTail.readStream(s); + else { + b = new byte[size]; + int len = 0; + do { + int n = s.read(b, len, size - len); + if (n < 0) + throw new IOException("the stream was closed: " + + classname); + + len += n; + } while (len < size); + } + } + finally { + s.close(); + } + + return b; + } + + private static URLConnection fetchClass0(String host, int port, + String filename) + throws IOException + { + URL url; + try { + url = new URL("http", host, port, filename); + } + catch (MalformedURLException e) { + // should never reache here. + throw new IOException("invalid URL?"); + } + + URLConnection con = url.openConnection(); + con.connect(); + return con; + } +} |