PageRenderTime 125ms CodeModel.GetById 31ms RepoModel.GetById 1ms app.codeStats 0ms

/tags/v-2007-06-19/src/utils/ClassPathInfo.java

https://bitbucket.org/yossi_gil/services
Java | 220 lines | 129 code | 25 blank | 66 comment | 23 complexity | b9a6f76d7edb82baf0966f05db229f98 MD5 | raw file
  1. package utils;
  2. import java.io.File;
  3. import java.io.IOException;
  4. import java.net.URL;
  5. import java.net.URLClassLoader;
  6. import java.util.ArrayList;
  7. import java.util.Enumeration;
  8. import java.util.Iterator;
  9. import java.util.List;
  10. import java.util.StringTokenizer;
  11. import java.util.zip.ZipEntry;
  12. import java.util.zip.ZipFile;
  13. /**
  14. * This class records all classes that are found on a certain class path
  15. *
  16. * @author Itay Maman
  17. * @date Jul 6, 2006
  18. */
  19. public class ClassPathInfo implements Iterable<String> {
  20. private final ArrayList<String> elements = new ArrayList<String>();
  21. @Override public String toString() {
  22. return Separator.separateBy(elements, File.pathSeparator);
  23. }
  24. /**
  25. * Initialize a new empty instance
  26. */
  27. public ClassPathInfo() {
  28. //
  29. }
  30. /**
  31. * Obtain a ClassPathInfo object that is initialized with the location
  32. * of the JRE on the local machine.
  33. *
  34. * Note that Java does not have an API that provides this information so
  35. * we have to intelligently guess it as follows:
  36. * <ul>
  37. * <li>If the default class loader is an instance of URLClassLoader, then
  38. * use its getURLs() method.
  39. * <li>Use the system property "sun.boot.class.path" which points to the JRE
  40. * location, but only in JVMs by Sun.
  41. * </ul>
  42. * @param ignore An array of file objects. Class path entries that are located
  43. * below one of the array's entires will be excluded.
  44. * @return A new ClassPathInfo object
  45. */
  46. public static ClassPathInfo getJreClassPath(File... ignore) {
  47. List<File> fs = new ArrayList<File>();
  48. ClassLoader cl = Object.class.getClassLoader();
  49. if(cl instanceof URLClassLoader) {
  50. URL[] urls = ((URLClassLoader) cl).getURLs();
  51. for(URL url : urls)
  52. fs.add(new File(url.getFile()));
  53. }
  54. String cp = System.getProperty("sun.boot.class.path");
  55. for (StringTokenizer st = new StringTokenizer(cp, File.pathSeparator); st.hasMoreTokens();) {
  56. File f = new File(st.nextToken());
  57. fs.add(f);
  58. }
  59. return build(fs, ignore);
  60. }
  61. /**
  62. * Add a new classpath element.
  63. *
  64. * @param f
  65. * A File object specifying either a single directory or a single
  66. * jar file
  67. * @return The receiver object.
  68. */
  69. public ClassPathInfo add(File f) {
  70. elements.add(f.getAbsolutePath());
  71. return this;
  72. }
  73. public File[] asFiles() {
  74. File[] result = new File[elements.size()];
  75. for (int i = 0; i < elements.size(); ++i)
  76. result[i] = new File(elements.get(i));
  77. return result;
  78. }
  79. public Iterator<String> iterator() {
  80. try {
  81. return getClasses().iterator();
  82. } catch (Exception e) {
  83. throw new RuntimeException(e);
  84. }
  85. }
  86. /**
  87. * Find all classes on the classpath represented by the receiver
  88. *
  89. * @return List of fully qualified names of all such classes
  90. * @throws Exception
  91. */
  92. public ArrayList<String> getClasses() throws Exception {
  93. ArrayList<String> result = new ArrayList<String>();
  94. for (String s : elements)
  95. addFromDirectory(new File(s), s, result);
  96. return result;
  97. }
  98. /**
  99. * Recursively adding all classes residing in specified directory into
  100. * cache.
  101. *
  102. * @param dirOrFile
  103. * file or directory
  104. * @param root
  105. * the root directory
  106. * @throws Exception
  107. */
  108. private void addFromDirectory(File dirOrFile, String root, ArrayList<String> result) throws Exception {
  109. if (dirOrFile.isDirectory()) {
  110. String[] children = dirOrFile.list();
  111. for (String s : children)
  112. addFromDirectory(new File(dirOrFile, s), root, result);
  113. return;
  114. }
  115. String fileName = dirOrFile.getPath();
  116. // *** checking if file is .jar or .zip
  117. String suffix = getSuffix(fileName);
  118. // *** name without suffix
  119. if (suffix.length() > 0)
  120. fileName = fileName.substring(0, fileName.length() - suffix.length());
  121. if (suffix.equalsIgnoreCase(".jar") || suffix.equalsIgnoreCase(".zip")) {
  122. addFromArchive(dirOrFile.getPath(), result);
  123. return;
  124. }
  125. if (suffix.equalsIgnoreCase(".class")) {
  126. fileName = fileName.replace(root + File.separator, "");
  127. fileName = fileName.replace(File.separatorChar, '.');
  128. result.add(fileName);
  129. }
  130. }
  131. /**
  132. * Getting a file extention i.e. .class
  133. *
  134. * @param s
  135. * name of file
  136. * @return the file extention
  137. */
  138. private String getSuffix(String s) {
  139. return !s.contains(".") ? "" : s.substring(s.lastIndexOf("."), s.length());
  140. }
  141. /**
  142. * Adding all classes residing in archive to cache
  143. *
  144. * @param arc_name
  145. * name of archive ( .jar or .zip )
  146. * @throws Exception
  147. */
  148. private void addFromArchive(String jarFile, ArrayList<String> result) throws Exception {
  149. try {
  150. ZipFile f = new ZipFile(jarFile);
  151. Enumeration<? extends ZipEntry> entries = f.entries();
  152. while (entries.hasMoreElements()) {
  153. String s = entries.nextElement().toString();
  154. if (!s.contains("."))
  155. continue;
  156. String suffix = getSuffix(s);
  157. if (!suffix.equalsIgnoreCase(".class"))
  158. continue;
  159. s = s.replace(".class", "");
  160. s = s.replace(File.separator, ".");
  161. s = s.replace("/", ".");
  162. result.add(s);
  163. }
  164. } catch (IOException e) {
  165. throw new Exception("File=" + jarFile, e);
  166. }
  167. }
  168. private static ClassPathInfo build(Iterable<File> fs, File[] ignore) {
  169. ClassPathInfo result = new ClassPathInfo();
  170. for(File f : fs) {
  171. f = f.getAbsoluteFile();
  172. if (!f.exists())
  173. continue;
  174. boolean add = true;
  175. for(File ig : ignore) {
  176. ig = ig.getAbsoluteFile();
  177. for(File curr = f; !add && curr != null; curr = curr.getParentFile())
  178. if(curr.equals(ig))
  179. add = false;
  180. }
  181. if(add)
  182. result.add(f);
  183. }
  184. return result;
  185. }
  186. public static void main(String[] args) throws Exception {
  187. ClassPathInfo cpi = new ClassPathInfo();
  188. String s = "/usr/local/java/jdk1.5.0_05/jre/lib/rt.jar:samples-bin";
  189. for (StringTokenizer st = new StringTokenizer(s, File.pathSeparator); st.hasMoreTokens();) {
  190. File f = new File(st.nextToken());
  191. cpi.add(f);
  192. }
  193. System.out.println(cpi.getClasses().size());
  194. }
  195. }