1 17 package org.apache.tools.ant.taskdefs.optional.sitraka.bytecode; 18 19 import java.io.BufferedInputStream ; 20 import java.io.ByteArrayInputStream ; 21 import java.io.ByteArrayOutputStream ; 22 import java.io.File ; 23 import java.io.FileInputStream ; 24 import java.io.FilenameFilter ; 25 import java.io.IOException ; 26 import java.io.InputStream ; 27 import java.util.Enumeration ; 28 import java.util.Hashtable ; 29 import java.util.NoSuchElementException ; 30 import java.util.StringTokenizer ; 31 import java.util.Vector ; 32 import java.util.zip.ZipEntry ; 33 import java.util.zip.ZipFile ; 34 35 39 public class ClassPathLoader { 40 41 public static final FileLoader NULL_LOADER = new NullLoader(); 42 43 44 private File [] files; 45 46 51 public ClassPathLoader(String classPath) { 52 StringTokenizer st = new StringTokenizer (classPath, File.pathSeparator); 53 Vector entries = new Vector (); 54 while (st.hasMoreTokens()) { 55 File file = new File (st.nextToken()); 56 entries.addElement(file); 57 } 58 files = new File [entries.size()]; 59 entries.copyInto(files); 60 } 61 62 66 public ClassPathLoader(String [] entries) { 67 files = new File [entries.length]; 68 for (int i = 0; i < entries.length; i++) { 69 files[i] = new File (entries[i]); 70 } 71 } 72 73 77 public ClassPathLoader(File [] entries) { 78 files = entries; 79 } 80 81 82 public interface FileLoader { 83 84 File getFile(); 85 86 87 ClassFile[] getClasses() throws IOException ; 88 } 89 90 93 public Enumeration loaders() { 94 return new LoaderEnumeration(); 95 } 96 97 108 public Hashtable getClasses() throws IOException { 109 Hashtable map = new Hashtable (); 110 Enumeration e = loaders(); 111 while (e.hasMoreElements()) { 112 FileLoader loader = (FileLoader) e.nextElement(); 113 System.out.println("Processing " + loader.getFile()); 114 long t0 = System.currentTimeMillis(); 115 ClassFile[] classes = loader.getClasses(); 116 long dt = System.currentTimeMillis() - t0; 117 System.out.println("" + classes.length + " classes loaded in " + dt + "ms"); 118 for (int j = 0; j < classes.length; j++) { 119 String name = classes[j].getFullName(); 120 if (!map.containsKey(name)) { 123 map.put(name, classes[j]); 124 } 125 } 126 } 127 return map; 128 } 129 130 131 private class LoaderEnumeration implements Enumeration { 132 private int index = 0; 133 134 public boolean hasMoreElements() { 135 return index < files.length; 136 } 137 138 public Object nextElement() { 139 if (index >= files.length) { 140 throw new NoSuchElementException (); 141 } 142 File file = files[index++]; 143 if (!file.exists()) { 144 return new NullLoader(file); 145 } 146 if (file.isDirectory()) { 147 return new DirectoryLoader(file); 149 } else if (file.getName().endsWith(".zip") || file.getName().endsWith(".jar")) { 150 return new JarLoader(file); 152 } 153 return new NullLoader(file); 154 155 } 156 } 157 158 163 public static InputStream getCachedStream(InputStream is) throws IOException { 164 final InputStream bis = new BufferedInputStream (is); 165 final byte[] buffer = new byte[8192]; 166 final ByteArrayOutputStream bos = new ByteArrayOutputStream (2048); 167 int n; 168 bos.reset(); 169 while ((n = bis.read(buffer, 0, buffer.length)) != -1) { 170 bos.write(buffer, 0, n); 171 } 172 is.close(); 173 return new ByteArrayInputStream (bos.toByteArray()); 174 } 175 } 176 177 178 final class NullLoader implements ClassPathLoader.FileLoader { 179 private File file; 180 181 NullLoader() { 182 this(null); 183 } 184 185 NullLoader(File file) { 186 this.file = file; 187 } 188 189 public File getFile() { 190 return file; 191 } 192 193 public ClassFile[] getClasses() throws IOException { 194 return new ClassFile[0]; 195 } 196 } 197 198 203 final class JarLoader implements ClassPathLoader.FileLoader { 204 private File file; 205 206 JarLoader(File file) { 207 this.file = file; 208 } 209 210 public File getFile() { 211 return file; 212 } 213 214 public ClassFile[] getClasses() throws IOException { 215 ZipFile zipFile = new ZipFile (file); 216 Vector v = new Vector (); 217 Enumeration entries = zipFile.entries(); 218 while (entries.hasMoreElements()) { 219 ZipEntry entry = (ZipEntry ) entries.nextElement(); 220 if (entry.getName().endsWith(".class")) { 221 InputStream is = ClassPathLoader.getCachedStream(zipFile.getInputStream(entry)); 222 ClassFile classFile = new ClassFile(is); 223 is.close(); 224 v.addElement(classFile); 225 } 226 } 227 ClassFile[] classes = new ClassFile[v.size()]; 228 v.copyInto(classes); 229 return classes; 230 } 231 } 232 233 238 final class DirectoryLoader implements ClassPathLoader.FileLoader { 239 private File directory; 240 private static final FilenameFilter DIRECTORY_FILTER = new DirectoryFilter(); 241 private static final FilenameFilter CLASS_FILTER = new ClassFilter(); 242 243 DirectoryLoader(File dir) { 244 directory = dir; 245 } 246 247 public File getFile() { 248 return directory; 249 } 250 251 public ClassFile[] getClasses() throws IOException { 252 Vector v = new Vector (127); 253 Vector files = listFiles(directory, CLASS_FILTER, true); 254 final int filesCount = files.size(); 255 for (int i = 0; i < filesCount; i++) { 256 File file = (File ) files.elementAt(i); 257 InputStream is = null; 258 try { 259 is = ClassPathLoader.getCachedStream(new FileInputStream (file)); 260 ClassFile classFile = new ClassFile(is); 261 is.close(); 262 is = null; 263 v.addElement(classFile); 264 } finally { 265 if (is != null) { 266 try { 267 is.close(); 268 } catch (IOException ignored) { 269 } 270 } 271 } 272 } 273 ClassFile[] classes = new ClassFile[v.size()]; 274 v.copyInto(classes); 275 return classes; 276 } 277 278 287 public static Vector listFiles(File directory, FilenameFilter filter, boolean recurse) { 288 if (!directory.isDirectory()) { 289 throw new IllegalArgumentException (directory + " is not a directory"); 290 } 291 Vector list = new Vector (512); 292 listFilesTo(list, directory, filter, recurse); 293 return list; 294 } 295 296 305 private static Vector listFilesTo(Vector list, File directory, 306 FilenameFilter filter, boolean recurse) { 307 String [] files = directory.list(filter); 308 for (int i = 0; i < files.length; i++) { 309 list.addElement(new File (directory, files[i])); 310 } 311 files = null; if (recurse) { 313 String [] subdirs = directory.list(DIRECTORY_FILTER); 314 for (int i = 0; i < subdirs.length; i++) { 315 listFilesTo(list, new File (directory, subdirs[i]), filter, recurse); 316 } 317 } 318 return list; 319 } 320 321 } 322 323 324 final class DirectoryFilter implements FilenameFilter { 325 public boolean accept(File directory, String name) { 326 File pathname = new File (directory, name); 327 return pathname.isDirectory(); 328 } 329 } 330 331 332 final class ClassFilter implements FilenameFilter { 333 public boolean accept(File dir, String name) { 334 return name.endsWith(".class"); 335 } 336 } 337 | Popular Tags |