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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  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 "mypack" and a requested class is
  36. * "mypack.sub.Test", then the given URL is used for loading that class.
  37. * If <code>packageName</code> is <code>null</code>, the URL is used
  38. * for loading any class.
  39. *
  40. * @param host host name
  41. * @param port port number
  42. * @param directory directory name ending with "/".
  43. * It can be "/" (root directory).
  44. * It must start with "/".
  45. * @param packageName package name.
  46. */
  47. public URLClassPath(String host, int port,
  48. String directory, String packageName) {
  49. hostname = host;
  50. this.port = port;
  51. this.directory = directory;
  52. this.packageName = packageName;
  53. }
  54. public String toString() {
  55. return hostname + ":" + port + directory;
  56. }
  57. /**
  58. * Opens a class file with http.
  59. *
  60. * @return null if the class file could not be found.
  61. */
  62. public InputStream openClassfile(String classname) {
  63. try {
  64. URLConnection con = openClassfile0(classname);
  65. if (con != null)
  66. return con.getInputStream();
  67. }
  68. catch (IOException e) {}
  69. return null; // not found
  70. }
  71. private URLConnection openClassfile0(String classname) throws IOException {
  72. if (packageName == null || classname.startsWith(packageName)) {
  73. String jarname
  74. = directory + classname.replace('.', '/') + ".class";
  75. return fetchClass0(hostname, port, jarname);
  76. }
  77. else
  78. return null; // not found
  79. }
  80. /**
  81. * Returns the URL.
  82. *
  83. * @return null if the class file could not be obtained.
  84. */
  85. public URL find(String classname) {
  86. try {
  87. URLConnection con = openClassfile0(classname);
  88. InputStream is = con.getInputStream();
  89. if (is != null) {
  90. is.close();
  91. return con.getURL();
  92. }
  93. }
  94. catch (IOException e) {}
  95. return null;
  96. }
  97. /**
  98. * Closes this class path.
  99. */
  100. public void close() {}
  101. /**
  102. * Reads a class file on an http server.
  103. *
  104. * @param host host name
  105. * @param port port number
  106. * @param directory directory name ending with "/".
  107. * It can be "/" (root directory).
  108. * It must start with "/".
  109. * @param classname fully-qualified class name
  110. */
  111. public static byte[] fetchClass(String host, int port,
  112. String directory, String classname)
  113. throws IOException
  114. {
  115. byte[] b;
  116. URLConnection con = fetchClass0(host, port,
  117. directory + classname.replace('.', '/') + ".class");
  118. int size = con.getContentLength();
  119. InputStream s = con.getInputStream();
  120. try {
  121. if (size <= 0)
  122. b = ClassPoolTail.readStream(s);
  123. else {
  124. b = new byte[size];
  125. int len = 0;
  126. do {
  127. int n = s.read(b, len, size - len);
  128. if (n < 0)
  129. throw new IOException("the stream was closed: "
  130. + classname);
  131. len += n;
  132. } while (len < size);
  133. }
  134. }
  135. finally {
  136. s.close();
  137. }
  138. return b;
  139. }
  140. private static URLConnection fetchClass0(String host, int port,
  141. String filename)
  142. throws IOException
  143. {
  144. URL url;
  145. try {
  146. url = new URL("http", host, port, filename);
  147. }
  148. catch (MalformedURLException e) {
  149. // should never reache here.
  150. throw new IOException("invalid URL?");
  151. }
  152. URLConnection con = url.openConnection();
  153. con.connect();
  154. return con;
  155. }
  156. }