1 20 21 package com.tonicsystems.jarjar.util; 22 23 import java.util.*; 24 import java.util.zip.*; 25 import java.io.*; 26 import java.util.jar.*; 27 28 public class ClassPathIterator implements Iterator 29 { 30 private static final FileFilter CLASS_FILTER = new FileFilter() { 31 public boolean accept(File file) { 32 return file.isDirectory() || hasExtension(getName(file), ".class"); 33 } 34 }; 35 36 private static final FileFilter JAR_FILTER = new FileFilter() { 37 public boolean accept(File file) { 38 return hasExtension(getName(file), ".jar"); 39 } 40 }; 41 42 private Iterator files; 43 private File parent; 44 private Enumeration entries; 45 private Map sources = new HashMap(); 46 private ZipFile zip; 47 private Object next; 48 49 public ClassPathIterator(String classPath) { 50 this(new File(System.getProperty("user.dir")), classPath); 51 } 52 53 public ClassPathIterator(File parent, String classPath) { 54 StringTokenizer st = new StringTokenizer(classPath, System.getProperty("path.separator")); 55 List fileList = new ArrayList(); 56 while (st.hasMoreTokens()) { 57 String part = (String )st.nextElement(); 58 59 boolean wildcard = false; 60 if (part.endsWith("/*")) { 61 part = part.substring(0, part.length() - 1); 62 if (part.indexOf('*') >= 0) 63 throw new IllegalArgumentException ("Multiple wildcards are not allowed: " + part); 64 wildcard = true; 65 } else if (part.indexOf('*') >= 0) { 66 throw new IllegalArgumentException ("Incorrect wildcard usage: " + part); 67 } 68 69 File file = new File(part); 70 if (!file.isAbsolute()) 71 file = new File(parent, part); 72 if (!file.exists()) 73 throw new IllegalArgumentException ("File " + file + " does not exist"); 74 75 if (wildcard) { 76 if (!file.isDirectory()) 77 throw new IllegalArgumentException ("File " + file + " + is not a directory"); 78 fileList.addAll(findFiles(file, JAR_FILTER, false, new ArrayList())); 79 } else { 80 fileList.add(file); 81 } 82 } 83 this.files = fileList.iterator(); 84 advance(); 85 } 86 87 public boolean hasNext() { 88 return next != null; 89 } 90 91 public void close() throws IOException { 92 if (sources != null) { 93 for (Iterator it = sources.values().iterator(); it.hasNext();) { 94 Object obj = it.next(); 95 if (obj instanceof ZipFile) 96 ((ZipFile)obj).close(); 97 } 98 } 99 } 100 101 public InputStream getInputStream(Object obj) throws IOException { 102 if (obj instanceof ZipEntry) { 103 return ((ZipFile)sources.get(obj)).getInputStream((ZipEntry)obj); 104 } else { 105 return new BufferedInputStream(new FileInputStream((File)obj)); 106 } 107 } 108 109 public Object getSource(Object obj) { 110 return sources.get(obj); 111 } 112 113 public void remove() { 114 throw new UnsupportedOperationException (); 115 } 116 117 public Object next() { 118 if (!hasNext()) 119 throw new NoSuchElementException(); 120 Object result = next; 121 advance(); 122 return result; 123 } 124 125 private void advance() { 126 try { 127 128 if (entries == null) { 129 if (!files.hasNext()) { 130 next = null; 131 return; 132 } 133 zip = null; 134 File file = (File)files.next(); 135 if (hasExtension(getName(file), ".jar")) { 136 zip = new JarFile(file); 137 entries = zip.entries(); 138 } else if (hasExtension(getName(file), ".zip")) { 139 zip = new ZipFile(file); 140 entries = zip.entries(); 141 } else if (file.isDirectory()) { 142 List classes = findFiles(file, CLASS_FILTER, true, new ArrayList()); 144 for (Iterator it = classes.iterator(); it.hasNext();) { 145 sources.put(it.next(), file); 146 } 147 entries = Collections.enumeration(classes); 148 } else { 149 throw new IllegalArgumentException ("Do not know how to handle " + file); 150 } 151 } 152 153 boolean foundClass = false; 154 while (entries.hasMoreElements()) { 155 next = entries.nextElement(); 156 if (foundClass = hasExtension(getName(next), ".class")) { 157 if (zip != null) 158 sources.put(next, zip); 159 break; 160 } 161 } 162 if (!foundClass) { 163 entries = null; 164 advance(); 165 } 166 } catch (IOException e) { 167 throw new RuntimeIOException(e); 168 } 169 } 170 171 private static List findFiles(File dir, FileFilter filter, boolean recurse, List collect) { 172 File[] files = dir.listFiles(filter); 173 for (int i = 0; i < files.length; i++) { 174 if (recurse && files[i].isDirectory()) { 175 findFiles(files[i], filter, recurse, collect); 176 } else { 177 collect.add(files[i]); 178 } 179 } 180 return collect; 181 } 182 183 private static String getName(Object obj) { 184 return (obj instanceof ZipEntry) ? ((ZipEntry)obj).getName() : ((File)obj).getName(); 185 } 186 187 private static boolean hasExtension(String name, String ext) { 188 int len = name.length(); 189 if (name.length() < ext.length()) 190 return false; 191 String actual = name.substring(name.length() - ext.length()); 192 return actual.equals(ext) || actual.equals(ext.toUpperCase()); 193 } 194 } 195 | Popular Tags |