1 package polyglot.types.reflect; 2 3 import polyglot.main.Report; 4 import polyglot.util.InternalCompilerError; 5 6 import java.io.*; 7 import java.util.*; 8 import java.util.zip.*; 9 import java.util.jar.*; 10 11 15 public class ClassFileLoader 16 { 17 21 Map zipCache; 22 23 26 Set packageCache; 27 28 32 Map dirContentsCache; 33 34 final static Object not_found = new Object (); 35 36 public ClassFileLoader() { 37 this.zipCache = new HashMap(); 38 this.dirContentsCache = new HashMap(); 39 this.packageCache = new HashSet(); 40 } 41 42 46 public boolean packageExists(File dir, String name) { 47 if (Report.should_report(verbose, 3)) { 48 Report.report(3, "looking in " + dir + " for " + 49 name.replace('.', File.separatorChar)); 50 } 51 52 try { 53 if (dir.getName().endsWith(".jar") || 54 dir.getName().endsWith(".zip")) { 55 56 String entryName = name.replace('.', '/'); 57 58 if (packageCache.contains(entryName)) { 59 return true; 60 } 61 62 loadZip(dir); 65 66 return packageCache.contains(entryName); 67 } 68 else { 69 String entryName = name.replace('.', File.separatorChar); 70 File f = new File(dir, entryName); 71 return f.exists() && f.isDirectory(); 72 } 73 } 74 catch (FileNotFoundException e) { 75 } 77 catch (IOException e) { 78 throw new InternalCompilerError(e); 79 } 80 81 return false; 82 } 83 84 90 public ClassFile loadClass(File dir, String name) 91 { 92 if (Report.should_report(verbose, 3)) { 93 Report.report(3, "looking in " + dir + " for " + 94 name.replace('.', File.separatorChar) + ".class"); 95 } 96 97 try { 98 if (dir.getName().endsWith(".jar") || 99 dir.getName().endsWith(".zip")) { 100 101 ZipFile zip = loadZip(dir); 102 String entryName = name.replace('.', '/') + ".class"; 103 return loadFromZip(dir, zip, entryName); 104 } 105 else { 106 return loadFromFile(name, dir); 107 } 108 } 109 catch (FileNotFoundException e) { 110 } 112 catch (IOException e) { 113 throw new InternalCompilerError(e); 114 } 115 116 return null; 117 } 118 119 ZipFile loadZip(File dir) throws IOException { 120 Object o = zipCache.get(dir); 121 if (o != not_found) { 122 ZipFile zip = (ZipFile) o; 123 if (zip != null) { 124 return zip; 125 } 126 else { 127 if (!dir.exists()) { 130 zipCache.put(dir, not_found); 132 } 133 else { 134 if (Report.should_report(verbose, 2)) 136 Report.report(2, "Opening zip " + dir); 137 if (dir.getName().endsWith(".jar")) { 138 zip = new JarFile(dir); 139 } 140 else { 141 zip = new ZipFile(dir); 142 } 143 zipCache.put(dir, zip); 144 145 for (Enumeration i = zip.entries(); i.hasMoreElements(); ) { 147 ZipEntry ei = (ZipEntry) i.nextElement(); 148 String n = ei.getName(); 149 150 int index = n.indexOf('/'); 151 while (index >= 0) { 152 packageCache.add(n.substring(0, index)); 153 index = n.indexOf('/', index+1); 154 } 155 } 156 157 return zip; 158 } 159 } 160 } 161 throw new FileNotFoundException(dir.getAbsolutePath()); 162 } 163 164 ClassFile loadFromZip(File source, ZipFile zip, String entryName) throws IOException { 165 if (Report.should_report(verbose, 2)) 166 Report.report(2, "Looking for " + entryName + " in " + zip.getName()); 167 if (zip != null) { 168 ZipEntry entry = zip.getEntry(entryName); 169 if (entry != null) { 170 if (Report.should_report(verbose, 3)) 171 Report.report(3, "found zip entry " + entry); 172 InputStream in = zip.getInputStream(entry); 173 ClassFile c = loadFromStream(source, in, entryName); 174 in.close(); 175 return c; 176 } 177 } 178 return null; 179 } 180 181 ClassFile loadFromFile(String name, File dir) throws IOException { 182 Set dirContents = (Set)dirContentsCache.get(dir); 183 if (dirContents == null) { 184 dirContents = new HashSet(); 185 dirContentsCache.put(dir, dirContents); 186 if (dir.exists() && dir.isDirectory()) { 187 String [] contents = dir.list(); 188 for (int j = 0; j < contents.length; j++) { 189 dirContents.add(contents[j]); 190 } 191 } 192 } 193 194 195 StringBuffer filenameSB = new StringBuffer (name.length() + 8); 196 int firstSeparator = -1; 197 filenameSB.append(name); 198 for (int i = 0; i < filenameSB.length(); i++) { 200 if (filenameSB.charAt(i) == '.') { 201 filenameSB.setCharAt(i, File.separatorChar); 202 if (firstSeparator == -1) 203 firstSeparator = i; 204 } 205 } 206 filenameSB.append(".class"); 207 208 String filename = filenameSB.toString(); 209 String firstPart = (firstSeparator==-1) ? filename 210 : filename.substring(0, firstSeparator); 211 212 if (!dirContents.contains(firstPart)) { 215 return null; 216 } 217 218 File file = new File(dir, filename); 220 221 FileInputStream in = new FileInputStream(file); 222 if (Report.should_report(verbose, 3)) 223 Report.report(3, "found " + file); 224 ClassFile c = loadFromStream(file, in, name); 225 in.close(); 226 return c; 227 } 228 229 232 ClassFile loadFromStream(File source, InputStream in, String name) throws IOException { 233 ByteArrayOutputStream out = new ByteArrayOutputStream(); 234 235 byte[] buf = new byte[4096]; 236 int n = 0; 237 238 do { 239 n = in.read(buf); 240 if (n >= 0) out.write(buf, 0, n); 241 } while (n >= 0); 242 243 byte[] bytecode = out.toByteArray(); 244 245 try { 246 if (Report.should_report(verbose, 3)) 247 Report.report(3, "defining class " + name); 248 return new ClassFile(source, bytecode); 249 } 250 catch (ClassFormatError e) { 251 throw new IOException(e.getMessage()); 252 } 253 } 254 255 static Collection verbose; 256 257 static { 258 verbose = new HashSet(); 259 verbose.add("loader"); 260 } 261 } 262 | Popular Tags |