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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  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. * <pre>http://www.javassist.org:80/java/classes/org/javassist/test/Main.class
  41. * </pre>
  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. * Reads a class file on an http server.
  108. *
  109. * @param host host name
  110. * @param port port number
  111. * @param directory directory name ending with "/".
  112. * It can be "/" (root directory).
  113. * It must start with "/".
  114. * @param classname fully-qualified class name
  115. */
  116. public static byte[] fetchClass(String host, int port,
  117. String directory, String classname)
  118. throws IOException
  119. {
  120. byte[] b;
  121. URLConnection con = fetchClass0(host, port,
  122. directory + classname.replace('.', '/') + ".class");
  123. int size = con.getContentLength();
  124. InputStream s = con.getInputStream();
  125. try {
  126. if (size <= 0)
  127. b = ClassPoolTail.readStream(s);
  128. else {
  129. b = new byte[size];
  130. int len = 0;
  131. do {
  132. int n = s.read(b, len, size - len);
  133. if (n < 0)
  134. throw new IOException("the stream was closed: "
  135. + classname);
  136. len += n;
  137. } while (len < size);
  138. }
  139. }
  140. finally {
  141. s.close();
  142. }
  143. return b;
  144. }
  145. private static URLConnection fetchClass0(String host, int port,
  146. String filename)
  147. throws IOException
  148. {
  149. URL url;
  150. try {
  151. url = new URL("http", host, port, filename);
  152. }
  153. catch (MalformedURLException e) {
  154. // should never reache here.
  155. throw new IOException("invalid URL?");
  156. }
  157. URLConnection con = url.openConnection();
  158. con.connect();
  159. return con;
  160. }
  161. }