You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

URLClassPath.java 5.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. /*
  2. * Javassist, a Java-bytecode translator toolkit.
  3. * Copyright (C) 1999-2006 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. package javassist;
  16. import java.io.*;
  17. import java.net.*;
  18. /**
  19. * A class search-path specified with URL (http).
  20. *
  21. * @see javassist.ClassPath
  22. * @see ClassPool#insertClassPath(ClassPath)
  23. * @see ClassPool#appendClassPath(ClassPath)
  24. */
  25. public class URLClassPath implements ClassPath {
  26. protected String hostname;
  27. protected int port;
  28. protected String directory;
  29. protected String packageName;
  30. /**
  31. * Creates a search path specified with URL (http).
  32. *
  33. * <p>This search path is used only if a requested
  34. * class name starts with the name specified by <code>packageName</code>.
  35. * If <code>packageName</code> is "org.javassist" and a requested class is
  36. * "org.javassist.test.Main", then the given URL is used for loading that class.
  37. * The <code>URLClassPath</code> obtains a class file from:
  38. *
  39. * <ul><pre>http://www.javassist.org:80/java/classes/org/javassist/test/Main.class
  40. * </pre></ul>
  41. *
  42. * <p>Here, we assume that <code>host</code> is "www.javassist.org",
  43. * <code>port</code> is 80, and <code>directory</code> is "/java/classes/".
  44. *
  45. * <p>If <code>packageName</code> is <code>null</code>, the URL is used
  46. * for loading any class.
  47. *
  48. * @param host host name
  49. * @param port port number
  50. * @param directory directory name ending with "/".
  51. * It can be "/" (root directory).
  52. * It must start with "/".
  53. * @param packageName package name.
  54. */
  55. public URLClassPath(String host, int port,
  56. String directory, String packageName) {
  57. hostname = host;
  58. this.port = port;
  59. this.directory = directory;
  60. this.packageName = packageName;
  61. }
  62. public String toString() {
  63. return hostname + ":" + port + directory;
  64. }
  65. /**
  66. * Opens a class file with http.
  67. *
  68. * @return null if the class file could not be found.
  69. */
  70. public InputStream openClassfile(String classname) {
  71. try {
  72. URLConnection con = openClassfile0(classname);
  73. if (con != null)
  74. return con.getInputStream();
  75. }
  76. catch (IOException e) {}
  77. return null; // not found
  78. }
  79. private URLConnection openClassfile0(String classname) throws IOException {
  80. if (packageName == null || classname.startsWith(packageName)) {
  81. String jarname
  82. = directory + classname.replace('.', '/') + ".class";
  83. return fetchClass0(hostname, port, jarname);
  84. }
  85. else
  86. return null; // not found
  87. }
  88. /**
  89. * Returns the URL.
  90. *
  91. * @return null if the class file could not be obtained.
  92. */
  93. public URL find(String classname) {
  94. try {
  95. URLConnection con = openClassfile0(classname);
  96. InputStream is = con.getInputStream();
  97. if (is != null) {
  98. is.close();
  99. return con.getURL();
  100. }
  101. }
  102. catch (IOException e) {}
  103. return null;
  104. }
  105. /**
  106. * Closes this class path.
  107. */
  108. public void close() {}
  109. /**
  110. * Reads a class file on an http server.
  111. *
  112. * @param host host name
  113. * @param port port number
  114. * @param directory directory name ending with "/".
  115. * It can be "/" (root directory).
  116. * It must start with "/".
  117. * @param classname fully-qualified class name
  118. */
  119. public static byte[] fetchClass(String host, int port,
  120. String directory, String classname)
  121. throws IOException
  122. {
  123. byte[] b;
  124. URLConnection con = fetchClass0(host, port,
  125. directory + classname.replace('.', '/') + ".class");
  126. int size = con.getContentLength();
  127. InputStream s = con.getInputStream();
  128. try {
  129. if (size <= 0)
  130. b = ClassPoolTail.readStream(s);
  131. else {
  132. b = new byte[size];
  133. int len = 0;
  134. do {
  135. int n = s.read(b, len, size - len);
  136. if (n < 0)
  137. throw new IOException("the stream was closed: "
  138. + classname);
  139. len += n;
  140. } while (len < size);
  141. }
  142. }
  143. finally {
  144. s.close();
  145. }
  146. return b;
  147. }
  148. private static URLConnection fetchClass0(String host, int port,
  149. String filename)
  150. throws IOException
  151. {
  152. URL url;
  153. try {
  154. url = new URL("http", host, port, filename);
  155. }
  156. catch (MalformedURLException e) {
  157. // should never reache here.
  158. throw new IOException("invalid URL?");
  159. }
  160. URLConnection con = url.openConnection();
  161. con.connect();
  162. return con;
  163. }
  164. }