/Users/lyon/j4p/src/javassist/URLClassPath.java
|
1 /*
2 * Javassist, a Java-bytecode translator toolkit.
3 * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
4 *
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. Alternatively, the contents of this file may be used under
8 * the terms of the GNU Lesser General Public License Version 2.1 or later.
9 *
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
14 */
15
16 package javassist;
17
18 import java.io.*;
19 import java.net.*;
20
21 /**
22 * A class search-path specified with URL (http).
23 *
24 * @see javassist.ClassPath
25 * @see ClassPool#insertClassPath(ClassPath)
26 * @see ClassPool#appendClassPath(ClassPath)
27 */
28 public class URLClassPath implements ClassPath {
29 protected String hostname;
30 protected int port;
31 protected String directory;
32 protected String packageName;
33
34 /**
35 * Creates a search path specified with URL (http).
36 *
37 * <p>This search path is used only if a requested
38 * class name starts with the name specified by <code>packageName</code>.
39 * If <code>packageName</code> is "mypack" and a requested class is
40 * "mypack.sub.Test", then the given URL is used for loading that class.
41 * If <code>packageName</code> is <code>null</code>, the URL is used
42 * for loading any class.
43 *
44 * @param host host name
45 * @param port port number
46 * @param directory directory name ending with "/".
47 * It can be "/" (root directory).
48 * @param packageName package name.
49 */
50 public URLClassPath(String host, int port,
51 String directory, String packageName) {
52 hostname = host;
53 this.port = port;
54 this.directory = directory;
55 this.packageName = packageName;
56 }
57
58 public String toString() {
59 return hostname + ":" + port + directory;
60 }
61
62 /**
63 * Opens a class file with http.
64 */
65 public InputStream openClassfile(String classname) {
66 try {
67 if (packageName == null || classname.startsWith(packageName)) {
68 String jarname
69 = directory + classname.replace('.', '/') + ".class";
70 URLConnection con = fetchClass0(hostname, port, jarname);
71 return con.getInputStream();
72 }
73 } catch (IOException e) {
74 }
75 return null; // not found
76 }
77
78 /**
79 * Closes this class path.
80 */
81 public void close() {
82 }
83
84 /**
85 * Reads a class file on an http server.
86 *
87 * @param host host name
88 * @param port port number
89 * @param directory directory name ending with "/".
90 * It can be "/" (root directory).
91 * @param classname fully-qualified class name
92 */
93 public static byte[] fetchClass(String host, int port,
94 String directory, String classname)
95 throws IOException {
96 byte[] b;
97 URLConnection con = fetchClass0(host, port,
98 directory + classname.replace('.', '/') + ".class");
99 int size = con.getContentLength();
100 InputStream s = con.getInputStream();
101 try {
102 if (size <= 0)
103 b = ClassPoolTail.readStream(s);
104 else {
105 b = new byte[size];
106 int len = 0;
107 do {
108 int n = s.read(b, len, size - len);
109 if (n < 0)
110 throw new IOException("the stream was closed: "
111 + classname);
112
113 len += n;
114 } while (len < size);
115 }
116 } finally {
117 s.close();
118 }
119
120 return b;
121 }
122
123 private static URLConnection fetchClass0(String host, int port,
124 String filename)
125 throws IOException {
126 URL url;
127 try {
128 url = new URL("http", host, port, filename);
129 } catch (MalformedURLException e) {
130 // should never reache here.
131 throw new IOException("invalid URL?");
132 }
133
134 URLConnection con = url.openConnection();
135 con.connect();
136 return con;
137 }
138 }
139