/tags/v-2007-06-19/src/utils/ClassPathInfo.java
Java | 220 lines | 129 code | 25 blank | 66 comment | 23 complexity | b9a6f76d7edb82baf0966f05db229f98 MD5 | raw file
- package utils;
- import java.io.File;
- import java.io.IOException;
- import java.net.URL;
- import java.net.URLClassLoader;
- import java.util.ArrayList;
- import java.util.Enumeration;
- import java.util.Iterator;
- import java.util.List;
- import java.util.StringTokenizer;
- import java.util.zip.ZipEntry;
- import java.util.zip.ZipFile;
- /**
- * This class records all classes that are found on a certain class path
- *
- * @author Itay Maman
- * @date Jul 6, 2006
- */
- public class ClassPathInfo implements Iterable<String> {
- private final ArrayList<String> elements = new ArrayList<String>();
- @Override public String toString() {
- return Separator.separateBy(elements, File.pathSeparator);
- }
- /**
- * Initialize a new empty instance
- */
- public ClassPathInfo() {
- //
- }
- /**
- * Obtain a ClassPathInfo object that is initialized with the location
- * of the JRE on the local machine.
- *
- * Note that Java does not have an API that provides this information so
- * we have to intelligently guess it as follows:
- * <ul>
- * <li>If the default class loader is an instance of URLClassLoader, then
- * use its getURLs() method.
- * <li>Use the system property "sun.boot.class.path" which points to the JRE
- * location, but only in JVMs by Sun.
- * </ul>
- * @param ignore An array of file objects. Class path entries that are located
- * below one of the array's entires will be excluded.
- * @return A new ClassPathInfo object
- */
- public static ClassPathInfo getJreClassPath(File... ignore) {
- List<File> fs = new ArrayList<File>();
-
- ClassLoader cl = Object.class.getClassLoader();
- if(cl instanceof URLClassLoader) {
- URL[] urls = ((URLClassLoader) cl).getURLs();
- for(URL url : urls)
- fs.add(new File(url.getFile()));
- }
-
- String cp = System.getProperty("sun.boot.class.path");
- for (StringTokenizer st = new StringTokenizer(cp, File.pathSeparator); st.hasMoreTokens();) {
- File f = new File(st.nextToken());
- fs.add(f);
- }
-
- return build(fs, ignore);
- }
-
- /**
- * Add a new classpath element.
- *
- * @param f
- * A File object specifying either a single directory or a single
- * jar file
- * @return The receiver object.
- */
- public ClassPathInfo add(File f) {
- elements.add(f.getAbsolutePath());
- return this;
- }
- public File[] asFiles() {
- File[] result = new File[elements.size()];
- for (int i = 0; i < elements.size(); ++i)
- result[i] = new File(elements.get(i));
- return result;
- }
-
-
- public Iterator<String> iterator() {
- try {
- return getClasses().iterator();
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
- /**
- * Find all classes on the classpath represented by the receiver
- *
- * @return List of fully qualified names of all such classes
- * @throws Exception
- */
- public ArrayList<String> getClasses() throws Exception {
- ArrayList<String> result = new ArrayList<String>();
- for (String s : elements)
- addFromDirectory(new File(s), s, result);
- return result;
- }
- /**
- * Recursively adding all classes residing in specified directory into
- * cache.
- *
- * @param dirOrFile
- * file or directory
- * @param root
- * the root directory
- * @throws Exception
- */
- private void addFromDirectory(File dirOrFile, String root, ArrayList<String> result) throws Exception {
- if (dirOrFile.isDirectory()) {
- String[] children = dirOrFile.list();
- for (String s : children)
- addFromDirectory(new File(dirOrFile, s), root, result);
- return;
- }
- String fileName = dirOrFile.getPath();
- // *** checking if file is .jar or .zip
- String suffix = getSuffix(fileName);
- // *** name without suffix
- if (suffix.length() > 0)
- fileName = fileName.substring(0, fileName.length() - suffix.length());
- if (suffix.equalsIgnoreCase(".jar") || suffix.equalsIgnoreCase(".zip")) {
- addFromArchive(dirOrFile.getPath(), result);
- return;
- }
- if (suffix.equalsIgnoreCase(".class")) {
- fileName = fileName.replace(root + File.separator, "");
- fileName = fileName.replace(File.separatorChar, '.');
- result.add(fileName);
- }
- }
- /**
- * Getting a file extention i.e. .class
- *
- * @param s
- * name of file
- * @return the file extention
- */
- private String getSuffix(String s) {
- return !s.contains(".") ? "" : s.substring(s.lastIndexOf("."), s.length());
- }
- /**
- * Adding all classes residing in archive to cache
- *
- * @param arc_name
- * name of archive ( .jar or .zip )
- * @throws Exception
- */
- private void addFromArchive(String jarFile, ArrayList<String> result) throws Exception {
- try {
- ZipFile f = new ZipFile(jarFile);
- Enumeration<? extends ZipEntry> entries = f.entries();
- while (entries.hasMoreElements()) {
- String s = entries.nextElement().toString();
- if (!s.contains("."))
- continue;
- String suffix = getSuffix(s);
- if (!suffix.equalsIgnoreCase(".class"))
- continue;
- s = s.replace(".class", "");
- s = s.replace(File.separator, ".");
- s = s.replace("/", ".");
- result.add(s);
- }
- } catch (IOException e) {
- throw new Exception("File=" + jarFile, e);
- }
- }
- private static ClassPathInfo build(Iterable<File> fs, File[] ignore) {
- ClassPathInfo result = new ClassPathInfo();
- for(File f : fs) {
- f = f.getAbsoluteFile();
- if (!f.exists())
- continue;
-
- boolean add = true;
- for(File ig : ignore) {
- ig = ig.getAbsoluteFile();
- for(File curr = f; !add && curr != null; curr = curr.getParentFile())
- if(curr.equals(ig))
- add = false;
- }
-
- if(add)
- result.add(f);
- }
-
- return result;
- }
-
- public static void main(String[] args) throws Exception {
- ClassPathInfo cpi = new ClassPathInfo();
- String s = "/usr/local/java/jdk1.5.0_05/jre/lib/rt.jar:samples-bin";
- for (StringTokenizer st = new StringTokenizer(s, File.pathSeparator); st.hasMoreTokens();) {
- File f = new File(st.nextToken());
- cpi.add(f);
- }
- System.out.println(cpi.getClasses().size());
- }
-
-
- }