您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

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