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.7KB

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