1 32 package net.sf.retrotranslator.transformer; 33 34 import java.io.*; 35 import java.lang.ref.SoftReference ; 36 import java.util.*; 37 import java.util.zip.*; 38 import net.sf.retrotranslator.runtime.asm.ClassReader; 39 import net.sf.retrotranslator.runtime.impl.RuntimeTools; 40 41 44 class ClassReaderFactory { 45 46 private ClassLoader classLoader; 47 private List<Entry> entries = new ArrayList<Entry>(); 48 private Map<String , SoftReference <ClassReader>> cache = new HashMap<String , SoftReference <ClassReader>>(); 49 50 public ClassReaderFactory(ClassLoader classLoader) { 51 this.classLoader = classLoader; 52 } 53 54 public void appendPath(File element) { 55 if (!element.exists()) throw new RuntimeException (element.getPath() + " not found."); 56 entries.add(element.isDirectory() ? new DirectoryEntry(element) : new ZipFileEntry(element)); 57 } 58 59 public ClassReader getClassReader(String name) throws ClassNotFoundException { 60 if (cache.containsKey(name)) { 61 SoftReference <ClassReader> reference = cache.get(name); 62 if (reference == null) throw new ClassNotFoundException (name); 63 ClassReader classReader = reference.get(); 64 if (classReader != null) return classReader; 65 } 66 InputStream stream = getStream(name + RuntimeTools.CLASS_EXTENSION); 67 if (stream == null) { 68 cache.put(name, null); 69 throw new ClassNotFoundException (name); 70 } 71 try { 72 try { 73 ClassReader classReader = new ClassReader(stream); 74 cache.put(name, new SoftReference <ClassReader>(classReader)); 75 return classReader; 76 } finally { 77 stream.close(); 78 } 79 } catch (IOException e) { 80 throw new RuntimeException (e); 81 } 82 } 83 84 private InputStream getStream(String name) { 85 for (Entry entry : entries) { 86 InputStream stream = entry.getResourceAsStream(name); 87 if (stream != null) return stream; 88 } 89 return classLoader == null ? null : classLoader.getResourceAsStream(name); 90 } 91 92 public void close() { 93 for (Entry entry : entries) { 94 try { 95 entry.close(); 96 } catch (Exception e) { 97 e.printStackTrace(); 98 } 99 } 100 } 101 102 private static interface Entry { 103 InputStream getResourceAsStream(String name); 104 105 void close(); 106 } 107 108 private static class DirectoryEntry implements Entry { 109 private File directory; 110 111 public DirectoryEntry(File directory) { 112 this.directory = directory; 113 } 114 115 public InputStream getResourceAsStream(String name) { 116 try { 117 return new FileInputStream(new File(directory, name)); 118 } catch (FileNotFoundException e) { 119 return null; 120 } 121 } 122 123 public void close() { 124 } 125 } 126 127 private static class ZipFileEntry implements Entry { 128 129 private ZipFile zipFile; 130 131 public ZipFileEntry(File file) { 132 try { 133 this.zipFile = new ZipFile(file); 134 } catch (IOException e) { 135 throw new RuntimeException (e); 136 } 137 } 138 139 public InputStream getResourceAsStream(String name) { 140 ZipEntry entry = zipFile.getEntry(name); 141 try { 142 return entry == null ? null : zipFile.getInputStream(entry); 143 } catch (IOException e) { 144 throw new RuntimeException (e); 145 } 146 } 147 148 public void close() { 149 try { 150 zipFile.close(); 151 } catch (IOException e) { 152 throw new RuntimeException (e); 153 } 154 } 155 } 156 157 } 158 | Popular Tags |