📄 javacfilemanager.java
字号:
if (subdirectory.length() != 0) { if (!useZipFileIndex) { subdirectory = subdirectory.replace('\\', '/'); if (!subdirectory.endsWith("/")) subdirectory = subdirectory + "/"; } else { if (File.separatorChar == '/') { subdirectory = subdirectory.replace('\\', '/'); } else { subdirectory = subdirectory.replace('/', '\\'); } if (!subdirectory.endsWith(File.separator)) subdirectory = subdirectory + File.separator; } } List<String> files = archive.getFiles(subdirectory); if (files != null) { for (String file; !files.isEmpty(); files = files.tail) { file = files.head; if (isValidFile(file, fileKinds)) { l.append(archive.getFileObject(subdirectory, file)); } } } if (recurse) { for (String s: archive.getSubdirectories()) { if (s.startsWith(subdirectory) && !s.equals(subdirectory)) { // Because the archive map is a flat list of directories, // the enclosing loop will pick up all child subdirectories. // Therefore, there is no need to recurse deeper. listDirectory(directory, s, fileKinds, false, l); } } } } else { File d = subdirectory.length() != 0 ? new File(directory, subdirectory) : directory; if (!caseMapCheck(d, subdirectory)) return; File[] files = d.listFiles(); if (files == null) return; for (File f: files) { String fname = f.getName(); if (f.isDirectory()) { if (recurse && SourceVersion.isIdentifier(fname)) { listDirectory(directory, subdirectory + File.separator + fname, fileKinds, recurse, l); } } else { if (isValidFile(fname, fileKinds)) { JavaFileObject fe = new RegularFileObject(fname, new File(d, fname)); l.append(fe); } } } } } private boolean isValidFile(String s, Set<JavaFileObject.Kind> fileKinds) { int lastDot = s.lastIndexOf("."); String extn = (lastDot == -1 ? s : s.substring(lastDot)); JavaFileObject.Kind kind = getKind(extn); return fileKinds.contains(kind); } private static final boolean fileSystemIsCaseSensitive = File.separatorChar == '/'; /** Hack to make Windows case sensitive. Test whether given path * ends in a string of characters with the same case as given name. * Ignore file separators in both path and name. */ private boolean caseMapCheck(File f, String name) { if (fileSystemIsCaseSensitive) return true; // Note that getCanonicalPath() returns the case-sensitive // spelled file name. String path; try { path = f.getCanonicalPath(); } catch (IOException ex) { return false; } char[] pcs = path.toCharArray(); char[] ncs = name.toCharArray(); int i = pcs.length - 1; int j = ncs.length - 1; while (i >= 0 && j >= 0) { while (i >= 0 && pcs[i] == File.separatorChar) i--; while (j >= 0 && ncs[j] == File.separatorChar) j--; if (i >= 0 && j >= 0) { if (pcs[i] != ncs[j]) return false; i--; j--; } } return j < 0; } /** * An archive provides a flat directory structure of a ZipFile by * mapping directory names to lists of files (basenames). */ public interface Archive { void close() throws IOException; boolean contains(String name); JavaFileObject getFileObject(String subdirectory, String file); List<String> getFiles(String subdirectory); Set<String> getSubdirectories(); } public class ZipArchive implements Archive { protected final Map<String,List<String>> map; protected final ZipFile zdir; public ZipArchive(ZipFile zdir) throws IOException { this.zdir = zdir; this.map = new HashMap<String,List<String>>(); for (Enumeration<? extends ZipEntry> e = zdir.entries(); e.hasMoreElements(); ) { ZipEntry entry; try { entry = e.nextElement(); } catch (InternalError ex) { IOException io = new IOException(); io.initCause(ex); // convenience constructors added in Mustang :-( throw io; } addZipEntry(entry); } } void addZipEntry(ZipEntry entry) { String name = entry.getName(); int i = name.lastIndexOf('/'); String dirname = name.substring(0, i+1); String basename = name.substring(i+1); if (basename.length() == 0) return; List<String> list = map.get(dirname); if (list == null) list = List.nil(); list = list.prepend(basename); map.put(dirname, list); } public boolean contains(String name) { int i = name.lastIndexOf('/'); String dirname = name.substring(0, i+1); String basename = name.substring(i+1); if (basename.length() == 0) return false; List<String> list = map.get(dirname); return (list != null && list.contains(basename)); } public List<String> getFiles(String subdirectory) { return map.get(subdirectory); } public JavaFileObject getFileObject(String subdirectory, String file) { ZipEntry ze = zdir.getEntry(subdirectory + file); return new ZipFileObject(file, zdir, ze); } public Set<String> getSubdirectories() { return map.keySet(); } public void close() throws IOException { zdir.close(); } } public class SymbolArchive extends ZipArchive { final File origFile; public SymbolArchive(File orig, ZipFile zdir) throws IOException { super(zdir); this.origFile = orig; } @Override void addZipEntry(ZipEntry entry) { // called from super constructor, may not refer to origFile. String name = entry.getName(); if (!name.startsWith(symbolFilePrefix)) return; name = name.substring(symbolFilePrefix.length()); int i = name.lastIndexOf('/'); String dirname = name.substring(0, i+1); String basename = name.substring(i+1); if (basename.length() == 0) return; List<String> list = map.get(dirname); if (list == null) list = List.nil(); list = list.prepend(basename); map.put(dirname, list); } @Override public JavaFileObject getFileObject(String subdirectory, String file) { return super.getFileObject(symbolFilePrefix + subdirectory, file); } } public class MissingArchive implements Archive { final File zipFileName; public MissingArchive(File name) { zipFileName = name; } public boolean contains(String name) { return false; } public void close() { } public JavaFileObject getFileObject(String subdirectory, String file) { return null; } public List<String> getFiles(String subdirectory) { return List.nil(); } public Set<String> getSubdirectories() { return Collections.emptySet(); } } /** A directory of zip files already opened. */ Map<File, Archive> archives = new HashMap<File,Archive>(); /** Open a new zip file directory. */ protected Archive openArchive(File zipFileName) throws IOException { Archive archive = archives.get(zipFileName); if (archive == null) { File origZipFileName = zipFileName; if (!ignoreSymbolFile && paths.isBootClassPathRtJar(zipFileName)) { File file = zipFileName.getParentFile().getParentFile(); // ${java.home} if (new File(file.getName()).equals(new File("jre"))) file = file.getParentFile(); // file == ${jdk.home} for (String name : symbolFileLocation) file = new File(file, name); // file == ${jdk.home}/lib/ct.sym if (file.exists()) zipFileName = file; } try { ZipFile zdir = null; boolean usePreindexedCache = false; String preindexCacheLocation = null; if (!useZipFileIndex) { zdir = new ZipFile(zipFileName); } else { usePreindexedCache = options.get("usezipindex") != null; preindexCacheLocation = options.get("java.io.tmpdir"); String optCacheLoc = options.get("cachezipindexdir"); if (optCacheLoc != null && optCacheLoc.length() != 0) { if (optCacheLoc.startsWith("\"")) { if (optCacheLoc.endsWith("\"")) { optCacheLoc = optCacheLoc.substring(1, optCacheLoc.length() - 1); } else { optCacheLoc = optCacheLoc.substring(1); } } File cacheDir = new File(optCacheLoc); if (cacheDir.exists() && cacheDir.canWrite()) { preindexCacheLocation = optCacheLoc; if (!preindexCacheLocation.endsWith("/") && !preindexCacheLocation.endsWith(File.separator)) { preindexCacheLocation += File.separator; } } } } if (origZipFileName == zipFileName) { if (!useZipFileIndex) { archive = new ZipArchive(zdir); } else { archive = new ZipFileIndexArchive(this, ZipFileIndex.getZipFileIndex(zipFileName, 0, usePreindexedCache, preindexCacheLocation, options.get("writezipindexfiles") != null)); } } else { if (!useZipFileIndex) { archive = new SymbolArchive(origZipFileName, zdir); } else { archive = new ZipFileIndexArchive(this, ZipFileIndex.getZipFileIndex(zipFileName, symbolFilePrefixLength, usePreindexedCache, preindexCacheLocation, options.get("writezipindexfiles") != null)); } } } catch (FileNotFoundException ex) { archive = new MissingArchive(zipFileName); } catch (IOException ex) { log.error("error.reading.file", zipFileName, ex.getLocalizedMessage()); archive = new MissingArchive(zipFileName); } archives.put(origZipFileName, archive); } return archive; } /** Flush any output resources. */ public void flush() { contentCache.clear(); } /** * Close the JavaFileManager, releasing resources. */ public void close() { for (Iterator<Archive> i = archives.values().iterator(); i.hasNext(); ) { Archive a = i.next(); i.remove(); try { a.close();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -