# HG changeset patch # User jjg # Date 1219787579 25200 # Node ID b316e32eb90cbce844c4cc33c5add31d2cc4bd0d # Parent 853d8c191eac3a435e5970a03a1766d2d491f5df 6508981: cleanup file separator handling in JavacFileManager Reviewed-by: mcimadamore diff -r 853d8c191eac -r b316e32eb90c langtools/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java --- a/langtools/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java Fri Aug 22 11:46:29 2008 +0100 +++ b/langtools/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java Tue Aug 26 14:52:59 2008 -0700 @@ -65,6 +65,8 @@ import javax.tools.StandardJavaFileManager; import com.sun.tools.javac.code.Source; +import com.sun.tools.javac.file.RelativePath.RelativeFile; +import com.sun.tools.javac.file.RelativePath.RelativeDirectory; import com.sun.tools.javac.main.JavacOption; import com.sun.tools.javac.main.OptionName; import com.sun.tools.javac.main.RecognizedOptions; @@ -75,8 +77,8 @@ import com.sun.tools.javac.util.Log; import com.sun.tools.javac.util.Options; +import static javax.tools.StandardLocation.*; import static com.sun.tools.javac.main.OptionName.*; -import static javax.tools.StandardLocation.*; /** * This class provides access to the source, class and other files @@ -84,9 +86,6 @@ */ public class JavacFileManager implements StandardJavaFileManager { - private static final String[] symbolFileLocation = { "lib", "ct.sym" }; - private static final String symbolFilePrefix = "META-INF/sym/rt.jar/"; - boolean useZipFileIndex; private static boolean CHECK_ZIP_TIMESTAMP = false; @@ -267,6 +266,7 @@ printAscii("Invalid class name: \"%s\"", name); } } + private static void printAscii(String format, Object... args) { String message; try { @@ -278,27 +278,12 @@ System.out.println(message); } - /** Return external representation of name, - * converting '.' to File.separatorChar. - */ - private static String externalizeFileName(CharSequence name) { - return name.toString().replace('.', File.separatorChar); - } - - private static String externalizeFileName(CharSequence n, JavaFileObject.Kind kind) { - return externalizeFileName(n) + kind.extension; - } - - private static String baseName(String fileName) { - return fileName.substring(fileName.lastIndexOf(File.separatorChar) + 1); - } - /** * Insert all files in subdirectory `subdirectory' of `directory' which end * in one of the extensions in `extensions' into packageSym. */ private void listDirectory(File directory, - String subdirectory, + RelativeDirectory subdirectory, Set fileKinds, boolean recurse, ListBuffer l) { @@ -329,22 +314,6 @@ return; } } - 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 files = archive.getFiles(subdirectory); if (files != null) { @@ -356,8 +325,8 @@ } } if (recurse) { - for (String s: archive.getSubdirectories()) { - if (s.startsWith(subdirectory) && !s.equals(subdirectory)) { + for (RelativeDirectory s: archive.getSubdirectories()) { + if (subdirectory.contains(s)) { // 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. @@ -366,9 +335,7 @@ } } } else { - File d = subdirectory.length() != 0 - ? new File(directory, subdirectory) - : directory; + File d = subdirectory.getFile(directory); if (!caseMapCheck(d, subdirectory)) return; @@ -381,7 +348,7 @@ if (f.isDirectory()) { if (recurse && SourceVersion.isIdentifier(fname)) { listDirectory(directory, - subdirectory + File.separator + fname, + new RelativeDirectory(subdirectory, fname), fileKinds, recurse, l); @@ -411,7 +378,7 @@ * 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) { + private boolean caseMapCheck(File f, RelativePath name) { if (fileSystemIsCaseSensitive) return true; // Note that getCanonicalPath() returns the case-sensitive // spelled file name. @@ -422,12 +389,12 @@ return false; } char[] pcs = path.toCharArray(); - char[] ncs = name.toCharArray(); + char[] ncs = name.path.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--; + while (j >= 0 && ncs[j] == '/') j--; if (i >= 0 && j >= 0) { if (pcs[i] != ncs[j]) return false; i--; @@ -444,13 +411,13 @@ public interface Archive { void close() throws IOException; - boolean contains(String name); + boolean contains(RelativePath name); - JavaFileObject getFileObject(String subdirectory, String file); + JavaFileObject getFileObject(RelativeDirectory subdirectory, String file); - List getFiles(String subdirectory); + List getFiles(RelativeDirectory subdirectory); - Set getSubdirectories(); + Set getSubdirectories(); } public class MissingArchive implements Archive { @@ -458,30 +425,38 @@ public MissingArchive(File name) { zipFileName = name; } - public boolean contains(String name) { + public boolean contains(RelativePath name) { return false; } public void close() { } - public JavaFileObject getFileObject(String subdirectory, String file) { + public JavaFileObject getFileObject(RelativeDirectory subdirectory, String file) { return null; } - public List getFiles(String subdirectory) { + public List getFiles(RelativeDirectory subdirectory) { return List.nil(); } - public Set getSubdirectories() { + public Set getSubdirectories() { return Collections.emptySet(); } + + public String toString() { + return "MissingArchive[" + zipFileName + "]"; + } } /** A directory of zip files already opened. */ Map archives = new HashMap(); + private static final String[] symbolFileLocation = { "lib", "ct.sym" }; + private static final RelativeDirectory symbolFilePrefix + = new RelativeDirectory("META-INF/sym/rt.jar/"); + /** Open a new zip file directory. */ protected Archive openArchive(File zipFileName) throws IOException { @@ -540,8 +515,12 @@ if (!useZipFileIndex) { archive = new ZipArchive(this, zdir); } else { - archive = new ZipFileIndexArchive(this, ZipFileIndex.getZipFileIndex(zipFileName, null, - usePreindexedCache, preindexCacheLocation, options.get("writezipindexfiles") != null)); + archive = new ZipFileIndexArchive(this, + ZipFileIndex.getZipFileIndex(zipFileName, + null, + usePreindexedCache, + preindexCacheLocation, + options.get("writezipindexfiles") != null)); } } else { @@ -551,10 +530,10 @@ else { archive = new ZipFileIndexArchive(this, ZipFileIndex.getZipFileIndex(zipFileName, - symbolFilePrefix, - usePreindexedCache, - preindexCacheLocation, - options.get("writezipindexfiles") != null)); + symbolFilePrefix, + usePreindexedCache, + preindexCacheLocation, + options.get("writezipindexfiles") != null)); } } } catch (FileNotFoundException ex) { @@ -796,7 +775,7 @@ Iterable path = getLocation(location); if (path == null) return List.nil(); - String subdirectory = externalizeFileName(packageName); + RelativeDirectory subdirectory = RelativeDirectory.forPackage(packageName); ListBuffer results = new ListBuffer(); for (File directory : path) @@ -877,7 +856,7 @@ nullCheck(kind); if (!sourceOrClass.contains(kind)) throw new IllegalArgumentException("Invalid kind " + kind); - return getFileForInput(location, externalizeFileName(className, kind)); + return getFileForInput(location, RelativeFile.forClass(className, kind)); } public FileObject getFileForInput(Location location, @@ -890,35 +869,32 @@ nullCheck(packageName); if (!isRelativeUri(URI.create(relativeName))) // FIXME 6419701 throw new IllegalArgumentException("Invalid relative name: " + relativeName); - String name = packageName.length() == 0 - ? relativeName - : new File(externalizeFileName(packageName), relativeName).getPath(); + RelativeFile name = packageName.length() == 0 + ? new RelativeFile(relativeName) + : new RelativeFile(RelativeDirectory.forPackage(packageName), relativeName); return getFileForInput(location, name); } - private JavaFileObject getFileForInput(Location location, String name) throws IOException { + private JavaFileObject getFileForInput(Location location, RelativeFile name) throws IOException { Iterable path = getLocation(location); if (path == null) return null; for (File dir: path) { if (dir.isDirectory()) { - File f = new File(dir, name.replace('/', File.separatorChar)); + File f = name.getFile(dir); if (f.exists()) return new RegularFileObject(this, f); } else { Archive a = openArchive(dir); if (a.contains(name)) { - int i = name.lastIndexOf('/'); - String dirname = name.substring(0, i+1); - String basename = name.substring(i+1); - return a.getFileObject(dirname, basename); + return a.getFileObject(name.dirname(), name.basename()); } } } + return null; - } public JavaFileObject getJavaFileForOutput(Location location, @@ -933,7 +909,7 @@ nullCheck(kind); if (!sourceOrClass.contains(kind)) throw new IllegalArgumentException("Invalid kind " + kind); - return getFileForOutput(location, externalizeFileName(className, kind), sibling); + return getFileForOutput(location, RelativeFile.forClass(className, kind), sibling); } public FileObject getFileForOutput(Location location, @@ -947,14 +923,14 @@ nullCheck(packageName); if (!isRelativeUri(URI.create(relativeName))) // FIXME 6419701 throw new IllegalArgumentException("relativeName is invalid"); - String name = packageName.length() == 0 - ? relativeName - : new File(externalizeFileName(packageName), relativeName).getPath(); + RelativeFile name = packageName.length() == 0 + ? new RelativeFile(relativeName) + : new RelativeFile(RelativeDirectory.forPackage(packageName), relativeName); return getFileForOutput(location, name, sibling); } private JavaFileObject getFileForOutput(Location location, - String fileName, + RelativeFile fileName, FileObject sibling) throws IOException { @@ -967,7 +943,7 @@ if (sibling != null && sibling instanceof RegularFileObject) { siblingDir = ((RegularFileObject)sibling).f.getParentFile(); } - return new RegularFileObject(this, new File(siblingDir, baseName(fileName))); + return new RegularFileObject(this, new File(siblingDir, fileName.basename())); } } else if (location == SOURCE_OUTPUT) { dir = (getSourceOutDir() != null ? getSourceOutDir() : getClassOutDir()); @@ -980,7 +956,7 @@ } } - File file = (dir == null ? new File(fileName) : new File(dir, fileName)); + File file = fileName.getFile(dir); // null-safe return new RegularFileObject(this, file); } diff -r 853d8c191eac -r b316e32eb90c langtools/src/share/classes/com/sun/tools/javac/file/RelativePath.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javac/file/RelativePath.java Tue Aug 26 14:52:59 2008 -0700 @@ -0,0 +1,191 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package com.sun.tools.javac.file; + +import java.io.File; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import javax.tools.JavaFileObject; + +/** + * Used to represent a platform-neutral path within a platform-specific + * container, such as a directory or zip file. + * Internally, the file separator is always '/'. + */ +public abstract class RelativePath implements Comparable { + /** + * @param p must use '/' as an internal separator + */ + protected RelativePath(String p) { + path = p; + } + + public abstract RelativeDirectory dirname(); + + public abstract String basename(); + + public File getFile(File directory) { + if (path.length() == 0) + return directory; + return new File(directory, path.replace('/', File.separatorChar)); + } + + public int compareTo(RelativePath other) { + return path.compareTo(other.path); + } + + @Override + public boolean equals(Object other) { + if (!(other instanceof RelativePath)) + return false; + return path.equals(((RelativePath) other).path); + } + + @Override + public int hashCode() { + return path.hashCode(); + } + + @Override + public String toString() { + return "RelPath[" + path + "]"; + } + + public String getPath() { + return path; + } + + protected final String path; + + /** + * Used to represent a platform-neutral subdirectory within a platform-specific + * container, such as a directory or zip file. + * Internally, the file separator is always '/', and if the path is not empty, + * it always ends in a '/' as well. + */ + public static class RelativeDirectory extends RelativePath { + + static RelativeDirectory forPackage(CharSequence packageName) { + return new RelativeDirectory(packageName.toString().replace('.', '/')); + } + + /** + * @param p must use '/' as an internal separator + */ + public RelativeDirectory(String p) { + super(p.length() == 0 || p.endsWith("/") ? p : p + "/"); + } + + /** + * @param p must use '/' as an internal separator + */ + public RelativeDirectory(RelativeDirectory d, String p) { + this(d.path + p); + } + + @Override + public RelativeDirectory dirname() { + int l = path.length(); + if (l == 0) + return this; + int sep = path.lastIndexOf('/', l - 2); + return new RelativeDirectory(path.substring(0, sep + 1)); + } + + @Override + public String basename() { + int l = path.length(); + if (l == 0) + return path; + int sep = path.lastIndexOf('/', l - 2); + return path.substring(sep + 1, l - 1); + } + + /** + * Return true if this subdirectory "contains" the other path. + * A subdirectory path does not contain itself. + **/ + boolean contains(RelativePath other) { + return other.path.length() > path.length() && other.path.startsWith(path); + } + + @Override + public String toString() { + return "RelativeDirectory[" + path + "]"; + } + } + + /** + * Used to represent a platform-neutral file within a platform-specific + * container, such as a directory or zip file. + * Internally, the file separator is always '/'. It never ends in '/'. + */ + public static class RelativeFile extends RelativePath { + static RelativeFile forClass(CharSequence className, JavaFileObject.Kind kind) { + return new RelativeFile(className.toString().replace('.', '/') + kind.extension); + } + + public RelativeFile(String p) { + super(p); + if (p.endsWith("/")) + throw new IllegalArgumentException(p); + } + + /** + * @param p must use '/' as an internal separator + */ + public RelativeFile(RelativeDirectory d, String p) { + this(d.path + p); + } + + RelativeFile(RelativeDirectory d, RelativePath p) { + this(d, p.path); + } + + @Override + public RelativeDirectory dirname() { + int sep = path.lastIndexOf('/'); + return new RelativeDirectory(path.substring(0, sep + 1)); + } + + @Override + public String basename() { + int sep = path.lastIndexOf('/'); + return path.substring(sep + 1); + } + + ZipEntry getZipEntry(ZipFile zip) { + return zip.getEntry(path); + } + + @Override + public String toString() { + return "RelativeFile[" + path + "]"; + } + + } + +} diff -r 853d8c191eac -r b316e32eb90c langtools/src/share/classes/com/sun/tools/javac/file/SymbolArchive.java --- a/langtools/src/share/classes/com/sun/tools/javac/file/SymbolArchive.java Fri Aug 22 11:46:29 2008 +0100 +++ b/langtools/src/share/classes/com/sun/tools/javac/file/SymbolArchive.java Tue Aug 26 14:52:59 2008 -0700 @@ -25,47 +25,75 @@ package com.sun.tools.javac.file; -import com.sun.tools.javac.util.List; import java.io.File; import java.io.IOException; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import javax.tools.JavaFileObject; +import com.sun.tools.javac.file.RelativePath.RelativeDirectory; +import com.sun.tools.javac.file.RelativePath.RelativeFile; +import com.sun.tools.javac.util.List; + public class SymbolArchive extends ZipArchive { final File origFile; - final String prefix; + final RelativeDirectory prefix; - public SymbolArchive(JavacFileManager fileManager, File orig, ZipFile zdir, String prefix) throws IOException { - super(fileManager, zdir); + public SymbolArchive(JavacFileManager fileManager, File orig, ZipFile zdir, RelativeDirectory prefix) throws IOException { + super(fileManager, zdir, false); this.origFile = orig; this.prefix = prefix; + initMap(); } @Override void addZipEntry(ZipEntry entry) { String name = entry.getName(); - if (!name.startsWith(prefix)) { + if (!name.startsWith(prefix.path)) { return; } - name = name.substring(prefix.length()); + name = name.substring(prefix.path.length()); int i = name.lastIndexOf('/'); - String dirname = name.substring(0, i + 1); + RelativeDirectory dirname = new RelativeDirectory(name.substring(0, i+1)); String basename = name.substring(i + 1); if (basename.length() == 0) { return; } List list = map.get(dirname); - if (list == null) { + 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(prefix + subdirectory, file); + public JavaFileObject getFileObject(RelativeDirectory subdirectory, String file) { + RelativeDirectory prefix_subdir = new RelativeDirectory(prefix, subdirectory.path); + ZipEntry ze = new RelativeFile(prefix_subdir, file).getZipEntry(zdir); + return new SymbolFileObject(this, file, ze); + } + + public String toString() { + return "SymbolArchive[" + zdir.getName() + "]"; } + + /** + * A subclass of JavaFileObject representing zip entries in a symbol file. + */ + public static class SymbolFileObject extends ZipFileObject { + protected SymbolFileObject(SymbolArchive zarch, String name, ZipEntry entry) { + super(zarch, name, entry); + } + + @Override + protected String inferBinaryName(Iterable path) { + String entryName = getZipEntryName(); + String prefix = ((SymbolArchive) zarch).prefix.path; + if (entryName.startsWith(prefix)) + entryName = entryName.substring(prefix.length()); + return removeExtension(entryName).replace('/', '.'); + } + } + + } diff -r 853d8c191eac -r b316e32eb90c langtools/src/share/classes/com/sun/tools/javac/file/ZipArchive.java --- a/langtools/src/share/classes/com/sun/tools/javac/file/ZipArchive.java Fri Aug 22 11:46:29 2008 +0100 +++ b/langtools/src/share/classes/com/sun/tools/javac/file/ZipArchive.java Tue Aug 26 14:52:59 2008 -0700 @@ -25,18 +25,8 @@ package com.sun.tools.javac.file; +import java.io.File; import java.io.IOException; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; -import javax.tools.JavaFileObject; - -import com.sun.tools.javac.file.JavacFileManager.Archive; -import com.sun.tools.javac.util.List; -import java.io.File; import java.io.InputStream; import java.io.OutputStream; import java.io.Writer; @@ -44,13 +34,35 @@ import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.CharsetDecoder; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; + +import javax.tools.JavaFileObject; + +import com.sun.tools.javac.file.JavacFileManager.Archive; +import com.sun.tools.javac.file.RelativePath.RelativeDirectory; +import com.sun.tools.javac.file.RelativePath.RelativeFile; +import com.sun.tools.javac.util.List; public class ZipArchive implements Archive { public ZipArchive(JavacFileManager fm, ZipFile zdir) throws IOException { + this(fm, zdir, true); + } + + protected ZipArchive(JavacFileManager fm, ZipFile zdir, boolean initMap) throws IOException { this.fileManager = fm; this.zdir = zdir; - this.map = new HashMap>(); + this.map = new HashMap>(); + if (initMap) + initMap(); + } + + protected void initMap() throws IOException { for (Enumeration e = zdir.entries(); e.hasMoreElements(); ) { ZipEntry entry; try { @@ -67,7 +79,7 @@ void addZipEntry(ZipEntry entry) { String name = entry.getName(); int i = name.lastIndexOf('/'); - String dirname = name.substring(0, i+1); + RelativeDirectory dirname = new RelativeDirectory(name.substring(0, i+1)); String basename = name.substring(i+1); if (basename.length() == 0) return; @@ -78,26 +90,25 @@ 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); + public boolean contains(RelativePath name) { + RelativeDirectory dirname = name.dirname(); + String basename = name.basename(); if (basename.length() == 0) return false; List list = map.get(dirname); return (list != null && list.contains(basename)); } - public List getFiles(String subdirectory) { + public List getFiles(RelativeDirectory subdirectory) { return map.get(subdirectory); } - public JavaFileObject getFileObject(String subdirectory, String file) { - ZipEntry ze = zdir.getEntry(subdirectory + file); + public JavaFileObject getFileObject(RelativeDirectory subdirectory, String file) { + ZipEntry ze = new RelativeFile(subdirectory, file).getZipEntry(zdir); return new ZipFileObject(this, file, ze); } - public Set getSubdirectories() { + public Set getSubdirectories() { return map.keySet(); } @@ -105,8 +116,12 @@ zdir.close(); } + public String toString() { + return "ZipArchive[" + zdir.getName() + "]"; + } + protected JavacFileManager fileManager; - protected final Map> map; + protected final Map> map; protected final ZipFile zdir; /** @@ -118,7 +133,7 @@ ZipArchive zarch; ZipEntry entry; - public ZipFileObject(ZipArchive zarch, String name, ZipEntry entry) { + protected ZipFileObject(ZipArchive zarch, String name, ZipEntry entry) { super(zarch.fileManager); this.zarch = zarch; this.name = name; @@ -222,11 +237,6 @@ @Override protected String inferBinaryName(Iterable path) { String entryName = getZipEntryName(); - if (zarch instanceof SymbolArchive) { - String prefix = ((SymbolArchive) zarch).prefix; - if (entryName.startsWith(prefix)) - entryName = entryName.substring(prefix.length()); - } return removeExtension(entryName).replace('/', '.'); } } diff -r 853d8c191eac -r b316e32eb90c langtools/src/share/classes/com/sun/tools/javac/file/ZipFileIndex.java --- a/langtools/src/share/classes/com/sun/tools/javac/file/ZipFileIndex.java Fri Aug 22 11:46:29 2008 +0100 +++ b/langtools/src/share/classes/com/sun/tools/javac/file/ZipFileIndex.java Tue Aug 26 14:52:59 2008 -0700 @@ -25,11 +25,12 @@ package com.sun.tools.javac.file; + import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.RandomAccessFile; -import java.text.MessageFormat; +import java.lang.ref.SoftReference; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; @@ -45,6 +46,9 @@ import java.util.zip.Inflater; import java.util.zip.ZipException; +import com.sun.tools.javac.file.RelativePath.RelativeDirectory; +import com.sun.tools.javac.file.RelativePath.RelativeFile; + /** This class implements building of index of a zip archive and access to it's context. * It also uses prebuild index if available. It supports invocations where it will * serialize an optimized zip index file to disk. @@ -75,8 +79,8 @@ private static boolean NON_BATCH_MODE = System.getProperty("nonBatchMode") != null;// TODO: Use -XD compiler switch for this. - private Map directories = Collections.emptyMap(); - private Set allDirs = Collections.emptySet(); + private Map directories = Collections.emptyMap(); + private Set allDirs = Collections.emptySet(); // ZipFileIndex data entries private File zipFile; @@ -87,7 +91,7 @@ private boolean readFromIndex = false; private File zipIndexFile = null; private boolean triedToReadIndex = false; - final String symbolFilePrefix; + final RelativeDirectory symbolFilePrefix; private int symbolFilePrefixLength = 0; private boolean hasPopulatedData = false; private long lastReferenceTimeStamp = NOT_MODIFIED; @@ -97,6 +101,9 @@ private boolean writeIndex = false; + private Map > relativeDirectoryCache = + new HashMap>(); + /** * Returns a list of all ZipFileIndex entries * @@ -143,7 +150,10 @@ } } - public static ZipFileIndex getZipFileIndex(File zipFile, String symbolFilePrefix, boolean useCache, String cacheLocation, boolean writeIndex) throws IOException { + public static ZipFileIndex getZipFileIndex(File zipFile, + RelativeDirectory symbolFilePrefix, + boolean useCache, String cacheLocation, + boolean writeIndex) throws IOException { ZipFileIndex zi = null; lock.lock(); try { @@ -231,12 +241,12 @@ } } - private ZipFileIndex(File zipFile, String symbolFilePrefix, boolean writeIndex, + private ZipFileIndex(File zipFile, RelativeDirectory symbolFilePrefix, boolean writeIndex, boolean useCache, String cacheLocation) throws IOException { this.zipFile = zipFile; this.symbolFilePrefix = symbolFilePrefix; this.symbolFilePrefixLength = (symbolFilePrefix == null ? 0 : - symbolFilePrefix.getBytes("UTF-8").length); + symbolFilePrefix.getPath().getBytes("UTF-8").length); this.writeIndex = writeIndex; this.usePreindexedCache = useCache; this.preindexedCacheLocation = cacheLocation; @@ -250,7 +260,7 @@ } public String toString() { - return "ZipFileIndex of file:(" + zipFile + ")"; + return "ZipFileIndex[" + zipFile + "]"; } // Just in case... @@ -291,8 +301,8 @@ return; } - directories = Collections.emptyMap(); - allDirs = Collections.emptySet(); + directories = Collections.emptyMap(); + allDirs = Collections.emptySet(); try { openFile(); @@ -317,9 +327,9 @@ private void cleanupState() { // Make sure there is a valid but empty index if the file doesn't exist entries = Entry.EMPTY_ARRAY; - directories = Collections.emptyMap(); + directories = Collections.emptyMap(); zipFileLastModified = NOT_MODIFIED; - allDirs = Collections.emptySet(); + allDirs = Collections.emptySet(); } public void close() { @@ -346,24 +356,12 @@ /** * Returns the ZipFileIndexEntry for an absolute path, if there is one. */ - Entry getZipIndexEntry(String path) { - if (File.separatorChar != '/') { - path = path.replace('/', File.separatorChar); - } + Entry getZipIndexEntry(RelativePath path) { lock.lock(); try { checkIndex(); - String lookFor = ""; - int lastSepIndex = path.lastIndexOf(File.separatorChar); - boolean noSeparator = false; - if (lastSepIndex == -1) { - noSeparator = true; - } - - DirectoryEntry de = directories.get(noSeparator ? "" : path.substring(0, lastSepIndex)); - - lookFor = path.substring(noSeparator ? 0 : lastSepIndex + 1); - + DirectoryEntry de = directories.get(path.dirname()); + String lookFor = path.basename(); return de == null ? null : de.getEntry(lookFor); } catch (IOException e) { @@ -377,11 +375,7 @@ /** * Returns a javac List of filenames within an absolute path in the ZipFileIndex. */ - public com.sun.tools.javac.util.List getFiles(String path) { - if (File.separatorChar != '/') { - path = path.replace('/', File.separatorChar); - } - + public com.sun.tools.javac.util.List getFiles(RelativeDirectory path) { lock.lock(); try { checkIndex(); @@ -402,16 +396,10 @@ } } - public List getAllDirectories(String path) { - - if (File.separatorChar != '/') { - path = path.replace('/', File.separatorChar); - } - + public List getDirectories(RelativeDirectory path) { lock.lock(); try { checkIndex(); - path = path.intern(); DirectoryEntry de = directories.get(path); com.sun.tools.javac.util.List ret = de == null ? null : de.getDirectories(); @@ -430,24 +418,18 @@ } } - public Set getAllDirectories() { + public Set getAllDirectories() { lock.lock(); try { checkIndex(); if (allDirs == Collections.EMPTY_SET) { - Set alldirs = new HashSet(); - Iterator dirsIter = directories.keySet().iterator(); - while (dirsIter.hasNext()) { - alldirs.add(new String(dirsIter.next())); - } - - allDirs = alldirs; + allDirs = new HashSet(directories.keySet()); } return allDirs; } catch (IOException e) { - return Collections.emptySet(); + return Collections.emptySet(); } finally { lock.unlock(); @@ -461,7 +443,7 @@ * @param path A path within the zip. * @return True if the path is a file or dir, false otherwise. */ - public boolean contains(String path) { + public boolean contains(RelativePath path) { lock.lock(); try { checkIndex(); @@ -475,17 +457,15 @@ } } - public boolean isDirectory(String path) throws IOException { + public boolean isDirectory(RelativePath path) throws IOException { lock.lock(); try { // The top level in a zip file is always a directory. - if (path.length() == 0) { + if (path.getPath().length() == 0) { lastReferenceTimeStamp = System.currentTimeMillis(); return true; } - if (File.separatorChar != '/') - path = path.replace('/', File.separatorChar); checkIndex(); return directories.get(path) != null; } @@ -494,7 +474,7 @@ } } - public long getLastModified(String path) throws IOException { + public long getLastModified(RelativeFile path) throws IOException { lock.lock(); try { Entry entry = getZipIndexEntry(path); @@ -507,7 +487,7 @@ } } - public int length(String path) throws IOException { + public int length(RelativeFile path) throws IOException { lock.lock(); try { Entry entry = getZipIndexEntry(path); @@ -531,12 +511,12 @@ } } - public byte[] read(String path) throws IOException { + public byte[] read(RelativeFile path) throws IOException { lock.lock(); try { Entry entry = getZipIndexEntry(path); if (entry == null) - throw new FileNotFoundException(MessageFormat.format("Path not found in ZIP: {0}", path)); + throw new FileNotFoundException("Path not found in ZIP: " + path.path); return read(entry); } finally { @@ -557,7 +537,7 @@ } } - public int read(String path, byte[] buffer) throws IOException { + public int read(RelativeFile path, byte[] buffer) throws IOException { lock.lock(); try { Entry entry = getZipIndexEntry(path); @@ -690,7 +670,7 @@ * ----------------------------------------------------------------------------*/ private class ZipDirectory { - private String lastDir; + private RelativeDirectory lastDir; private int lastStart; private int lastLen; @@ -747,13 +727,13 @@ } throw new ZipException("cannot read zip file"); } + private void buildIndex() throws IOException { int entryCount = get2ByteLittleEndian(zipDir, 0); - entries = new Entry[entryCount]; // Add each of the files if (entryCount > 0) { - directories = new HashMap(); + directories = new HashMap(); ArrayList entryList = new ArrayList(); int pos = 2; for (int i = 0; i < entryCount; i++) { @@ -761,9 +741,11 @@ } // Add the accumulated dirs into the same list - Iterator i = directories.keySet().iterator(); - while (i.hasNext()) { - Entry zipFileIndexEntry = new Entry( (String) i.next()); + for (RelativeDirectory d: directories.keySet()) { + // use shared RelativeDirectory objects for parent dirs + RelativeDirectory parent = getRelativeDirectory(d.dirname().getPath()); + String file = d.basename(); + Entry zipFileIndexEntry = new Entry(parent, file); zipFileIndexEntry.isDir = true; entryList.add(zipFileIndexEntry); } @@ -776,7 +758,7 @@ } private int readEntry(int pos, List entryList, - Map directories) throws IOException { + Map directories) throws IOException { if (get4ByteLittleEndian(zipDir, pos) != 0x02014b50) { throw new ZipException("cannot read zip file entry"); } @@ -790,19 +772,20 @@ dirStart += zipFileIndex.symbolFilePrefixLength; fileStart += zipFileIndex.symbolFilePrefixLength; } - - // Use the OS's path separator. Keep the position of the last one. + // Force any '\' to '/'. Keep the position of the last separator. for (int index = fileStart; index < fileEnd; index++) { byte nextByte = zipDir[index]; - if (nextByte == (byte)'\\' || nextByte == (byte)'/') { - zipDir[index] = (byte)File.separatorChar; + if (nextByte == (byte)'\\') { + zipDir[index] = (byte)'/'; + fileStart = index + 1; + } else if (nextByte == (byte)'/') { fileStart = index + 1; } } - String directory = null; + RelativeDirectory directory = null; if (fileStart == dirStart) - directory = ""; + directory = getRelativeDirectory(""); else if (lastDir != null && lastLen == fileStart - dirStart - 1) { int index = lastLen - 1; while (zipDir[lastStart + index] == zipDir[dirStart + index]) { @@ -819,22 +802,23 @@ lastStart = dirStart; lastLen = fileStart - dirStart - 1; - directory = new String(zipDir, dirStart, lastLen, "UTF-8").intern(); + directory = getRelativeDirectory(new String(zipDir, dirStart, lastLen, "UTF-8")); lastDir = directory; // Enter also all the parent directories - String tempDirectory = directory; + RelativeDirectory tempDirectory = directory; while (directories.get(tempDirectory) == null) { directories.put(tempDirectory, new DirectoryEntry(tempDirectory, zipFileIndex)); - int separator = tempDirectory.lastIndexOf(File.separatorChar); - if (separator == -1) + if (tempDirectory.path.indexOf("/") == tempDirectory.path.length() - 1) break; - tempDirectory = tempDirectory.substring(0, separator); + else { + // use shared RelativeDirectory objects for parent dirs + tempDirectory = getRelativeDirectory(tempDirectory.dirname().getPath()); + } } } else { - directory = directory.intern(); if (directories.get(directory) == null) { directories.put(directory, new DirectoryEntry(directory, zipFileIndex)); } @@ -886,7 +870,7 @@ private long writtenOffsetOffset = 0; - private String dirName; + private RelativeDirectory dirName; private com.sun.tools.javac.util.List zipFileEntriesFiles = com.sun.tools.javac.util.List.nil(); private com.sun.tools.javac.util.List zipFileEntriesDirectories = com.sun.tools.javac.util.List.nil(); @@ -898,70 +882,50 @@ private int numEntries; - DirectoryEntry(String dirName, ZipFileIndex index) { - filesInited = false; + DirectoryEntry(RelativeDirectory dirName, ZipFileIndex index) { + filesInited = false; directoriesInited = false; entriesInited = false; - if (File.separatorChar == '/') { - dirName.replace('\\', '/'); - } - else { - dirName.replace('/', '\\'); - } - - this.dirName = dirName.intern(); + this.dirName = dirName; this.zipFileIndex = index; } private com.sun.tools.javac.util.List getFiles() { - if (filesInited) { - return zipFileEntriesFiles; + if (!filesInited) { + initEntries(); + for (Entry e : entries) { + if (!e.isDir) { + zipFileEntriesFiles = zipFileEntriesFiles.append(e.name); + } + } + filesInited = true; } - - initEntries(); - - for (Entry e : entries) { - if (!e.isDir) { - zipFileEntriesFiles = zipFileEntriesFiles.append(e.name); - } - } - filesInited = true; return zipFileEntriesFiles; } private com.sun.tools.javac.util.List getDirectories() { - if (directoriesInited) { - return zipFileEntriesFiles; + if (!directoriesInited) { + initEntries(); + for (Entry e : entries) { + if (e.isDir) { + zipFileEntriesDirectories = zipFileEntriesDirectories.append(e.name); + } + } + directoriesInited = true; } - - initEntries(); - - for (Entry e : entries) { - if (e.isDir) { - zipFileEntriesDirectories = zipFileEntriesDirectories.append(e.name); - } - } - - directoriesInited = true; - return zipFileEntriesDirectories; } private com.sun.tools.javac.util.List getEntries() { - if (zipFileEntriesInited) { - return zipFileEntries; + if (!zipFileEntriesInited) { + initEntries(); + zipFileEntries = com.sun.tools.javac.util.List.nil(); + for (Entry zfie : entries) { + zipFileEntries = zipFileEntries.append(zfie); + } + zipFileEntriesInited = true; } - - initEntries(); - - zipFileEntries = com.sun.tools.javac.util.List.nil(); - for (Entry zfie : entries) { - zipFileEntries = zipFileEntries.append(zfie); - } - - zipFileEntriesInited = true; - return zipFileEntries; } @@ -986,8 +950,6 @@ int to = -Arrays.binarySearch(zipFileIndex.entries, new Entry(dirName, MAX_CHAR)) - 1; - boolean emptyList = false; - for (int i = from; i < to; i++) { entries.add(zipFileIndex.entries[i]); } @@ -1071,14 +1033,14 @@ if (zipFile.lastModified() != fileStamp) { ret = false; } else { - directories = new HashMap(); + directories = new HashMap(); int numDirs = raf.readInt(); for (int nDirs = 0; nDirs < numDirs; nDirs++) { int dirNameBytesLen = raf.readInt(); byte [] dirNameBytes = new byte[dirNameBytesLen]; raf.read(dirNameBytes); - String dirNameStr = new String(dirNameBytes, "UTF-8"); + RelativeDirectory dirNameStr = getRelativeDirectory(new String(dirNameBytes, "UTF-8")); DirectoryEntry de = new DirectoryEntry(dirNameStr, this); de.numEntries = raf.readInt(); de.writtenOffsetOffset = raf.readLong(); @@ -1132,21 +1094,18 @@ raf.writeLong(zipFileLastModified); writtenSoFar += 8; - - Iterator iterDirName = directories.keySet().iterator(); List directoriesToWrite = new ArrayList(); - Map offsets = new HashMap(); + Map offsets = new HashMap(); raf.writeInt(directories.keySet().size()); writtenSoFar += 4; - while(iterDirName.hasNext()) { - String dirName = iterDirName.next(); + for (RelativeDirectory dirName: directories.keySet()) { DirectoryEntry dirEntry = directories.get(dirName); directoriesToWrite.add(dirEntry); // Write the dir name bytes - byte [] dirNameBytes = dirName.getBytes("UTF-8"); + byte [] dirNameBytes = dirName.getPath().getBytes("UTF-8"); int dirNameBytesLen = dirNameBytes.length; raf.writeInt(dirNameBytesLen); writtenSoFar += 4; @@ -1251,12 +1210,24 @@ return zipFile; } + private RelativeDirectory getRelativeDirectory(String path) { + RelativeDirectory rd; + SoftReference ref = relativeDirectoryCache.get(path); + if (ref != null) { + rd = ref.get(); + if (rd != null) + return rd; + } + rd = new RelativeDirectory(path); + relativeDirectoryCache.put(path, new SoftReference(rd)); + return rd; + } static class Entry implements Comparable { public static final Entry[] EMPTY_ARRAY = {}; // Directory related - String dir; + RelativeDirectory dir; boolean isDir; // File related @@ -1269,32 +1240,17 @@ private int nativetime; - public Entry(String path) { - int separator = path.lastIndexOf(File.separatorChar); - if (separator == -1) { - dir = "".intern(); - name = path; - } else { - dir = path.substring(0, separator).intern(); - name = path.substring(separator + 1); - } + public Entry(RelativePath path) { + this(path.dirname(), path.basename()); } - public Entry(String directory, String name) { - this.dir = directory.intern(); + public Entry(RelativeDirectory directory, String name) { + this.dir = directory; this.name = name; } public String getName() { - if (dir == null || dir.length() == 0) { - return name; - } - - StringBuilder sb = new StringBuilder(); - sb.append(dir); - sb.append(File.separatorChar); - sb.append(name); - return sb.toString(); + return new RelativeFile(dir, name).getPath(); } public String getFileName() { @@ -1331,7 +1287,7 @@ } public int compareTo(Entry other) { - String otherD = other.dir; + RelativeDirectory otherD = other.dir; if (dir != otherD) { int c = dir.compareTo(otherD); if (c != 0) @@ -1340,6 +1296,22 @@ return name.compareTo(other.name); } + @Override + public boolean equals(Object o) { + if (!(o instanceof Entry)) + return false; + Entry other = (Entry) o; + return dir.equals(other.dir) && name.equals(other.name); + } + + @Override + public int hashCode() { + int hash = 7; + hash = 97 * hash + (this.dir != null ? this.dir.hashCode() : 0); + hash = 97 * hash + (this.name != null ? this.name.hashCode() : 0); + return hash; + } + public String toString() { return isDir ? ("Dir:" + dir + " : " + name) : diff -r 853d8c191eac -r b316e32eb90c langtools/src/share/classes/com/sun/tools/javac/file/ZipFileIndexArchive.java --- a/langtools/src/share/classes/com/sun/tools/javac/file/ZipFileIndexArchive.java Fri Aug 22 11:46:29 2008 +0100 +++ b/langtools/src/share/classes/com/sun/tools/javac/file/ZipFileIndexArchive.java Tue Aug 26 14:52:59 2008 -0700 @@ -29,11 +29,8 @@ import java.util.Set; import javax.tools.JavaFileObject; -import com.sun.tools.javac.file.JavacFileManager.Archive; -import com.sun.tools.javac.util.List; import java.io.ByteArrayInputStream; import java.io.File; -import java.io.FileNotFoundException; import java.io.InputStream; import java.io.OutputStream; import java.io.Writer; @@ -42,6 +39,11 @@ import java.nio.CharBuffer; import java.nio.charset.CharsetDecoder; +import com.sun.tools.javac.file.JavacFileManager.Archive; +import com.sun.tools.javac.file.RelativePath.RelativeDirectory; +import com.sun.tools.javac.file.RelativePath.RelativeFile; +import com.sun.tools.javac.util.List; + public class ZipFileIndexArchive implements Archive { private final ZipFileIndex zfIndex; @@ -53,22 +55,22 @@ this.zfIndex = zdir; } - public boolean contains(String name) { + public boolean contains(RelativePath name) { return zfIndex.contains(name); } - public List getFiles(String subdirectory) { - return zfIndex.getFiles((subdirectory.endsWith("/") || subdirectory.endsWith("\\")) ? subdirectory.substring(0, subdirectory.length() - 1) : subdirectory); + public List getFiles(RelativeDirectory subdirectory) { + return zfIndex.getFiles(subdirectory); } - public JavaFileObject getFileObject(String subdirectory, String file) { - String fullZipFileName = subdirectory + file; + public JavaFileObject getFileObject(RelativeDirectory subdirectory, String file) { + RelativeFile fullZipFileName = new RelativeFile(subdirectory, file); ZipFileIndex.Entry entry = zfIndex.getZipIndexEntry(fullZipFileName); JavaFileObject ret = new ZipFileIndexFileObject(fileManager, zfIndex, entry, zfIndex.getZipFile().getPath()); return ret; } - public Set getSubdirectories() { + public Set getSubdirectories() { return zfIndex.getAllDirectories(); } @@ -76,6 +78,10 @@ zfIndex.close(); } + public String toString() { + return "ZipFileIndexArchive[" + zfIndex + "]"; + } + /** * A subclass of JavaFileObject representing zip entries using the com.sun.tools.javac.file.ZipFileIndex implementation. */ @@ -181,18 +187,11 @@ public URI toUri() { String zipName = new File(getZipName()).toURI().normalize().getPath(); String entryName = getZipEntryName(); - if (File.separatorChar != '/') { - entryName = entryName.replace(File.separatorChar, '/'); - } return URI.create("jar:" + zipName + "!" + entryName); } private byte[] read() throws IOException { - if (entry == null) { - entry = zfIndex.getZipIndexEntry(name); - if (entry == null) - throw new FileNotFoundException(); - } + assert entry != null; // see constructor return zfIndex.read(entry); } @@ -222,11 +221,11 @@ protected String inferBinaryName(Iterable path) { String entryName = getZipEntryName(); if (zfIndex.symbolFilePrefix != null) { - String prefix = zfIndex.symbolFilePrefix; + String prefix = zfIndex.symbolFilePrefix.path; if (entryName.startsWith(prefix)) entryName = entryName.substring(prefix.length()); } - return removeExtension(entryName).replace(File.separatorChar, '.'); + return removeExtension(entryName).replace('/', '.'); } } diff -r 853d8c191eac -r b316e32eb90c langtools/src/share/classes/com/sun/tools/javadoc/DocletInvoker.java --- a/langtools/src/share/classes/com/sun/tools/javadoc/DocletInvoker.java Fri Aug 22 11:46:29 2008 +0100 +++ b/langtools/src/share/classes/com/sun/tools/javadoc/DocletInvoker.java Tue Aug 26 14:52:59 2008 -0700 @@ -82,6 +82,7 @@ cpString = appendPath(System.getProperty("java.class.path"), cpString); cpString = appendPath(docletPath, cpString); URL[] urls = pathToURLs(cpString); + System.err.println("DocletInvoker urls=" + urls); appClassLoader = new URLClassLoader(urls); // attempt to find doclet diff -r 853d8c191eac -r b316e32eb90c langtools/src/share/classes/javax/tools/StandardLocation.java --- a/langtools/src/share/classes/javax/tools/StandardLocation.java Fri Aug 22 11:46:29 2008 +0100 +++ b/langtools/src/share/classes/javax/tools/StandardLocation.java Tue Aug 26 14:52:59 2008 -0700 @@ -27,8 +27,6 @@ import javax.tools.JavaFileManager.Location; -import java.io.File; -import java.util.*; import java.util.concurrent.*; /** diff -r 853d8c191eac -r b316e32eb90c langtools/test/tools/javac/6508981/TestInferBinaryName.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/6508981/TestInferBinaryName.java Tue Aug 26 14:52:59 2008 -0700 @@ -0,0 +1,177 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6508981 + * @summary cleanup file separator handling in JavacFileManager + * (This test is specifically to test the new impl of inferBinaryName) + * @build p.A + * @run main TestInferBinaryName + */ + +import java.io.*; +import java.util.*; +import javax.tools.*; + +import com.sun.tools.javac.file.JavacFileManager; +import com.sun.tools.javac.util.Context; +import com.sun.tools.javac.util.Options; + +import static javax.tools.JavaFileObject.Kind.*; +import static javax.tools.StandardLocation.*; + + +/** + * Verify the various implementations of inferBinaryName, but configuring + * different instances of a file manager, getting a file object, and checking + * the impl of inferBinaryName for that file object. + */ +public class TestInferBinaryName { + static final boolean IGNORE_SYMBOL_FILE = false; + static final boolean USE_SYMBOL_FILE = true; + static final boolean DONT_USE_ZIP_FILE_INDEX = false; + static final boolean USE_ZIP_FILE_INDEX = true; + + public static void main(String... args) throws Exception { + new TestInferBinaryName().run(); + } + + void run() throws Exception { + //System.err.println(System.getProperties()); + testDirectory(); + testSymbolArchive(); + testZipArchive(); + testZipFileIndexArchive(); + testZipFileIndexArchive2(); + if (errors > 0) + throw new Exception(errors + " error found"); + } + + void testDirectory() throws IOException { + String testClassName = "p.A"; + JavaFileManager fm = + getFileManager("test.classes", USE_SYMBOL_FILE, USE_ZIP_FILE_INDEX); + test("testDirectory", + fm, testClassName, "com.sun.tools.javac.file.RegularFileObject"); + } + + void testSymbolArchive() throws IOException { + String testClassName = "java.lang.String"; + JavaFileManager fm = + getFileManager("sun.boot.class.path", USE_SYMBOL_FILE, DONT_USE_ZIP_FILE_INDEX); + test("testSymbolArchive", + fm, testClassName, "com.sun.tools.javac.file.SymbolArchive$SymbolFileObject"); + } + + void testZipArchive() throws IOException { + String testClassName = "java.lang.String"; + JavaFileManager fm = + getFileManager("sun.boot.class.path", IGNORE_SYMBOL_FILE, DONT_USE_ZIP_FILE_INDEX); + test("testZipArchive", + fm, testClassName, "com.sun.tools.javac.file.ZipArchive$ZipFileObject"); + } + + void testZipFileIndexArchive() throws IOException { + String testClassName = "java.lang.String"; + JavaFileManager fm = + getFileManager("sun.boot.class.path", USE_SYMBOL_FILE, USE_ZIP_FILE_INDEX); + test("testZipFileIndexArchive", + fm, testClassName, "com.sun.tools.javac.file.ZipFileIndexArchive$ZipFileIndexFileObject"); + } + + void testZipFileIndexArchive2() throws IOException { + String testClassName = "java.lang.String"; + JavaFileManager fm = + getFileManager("sun.boot.class.path", IGNORE_SYMBOL_FILE, USE_ZIP_FILE_INDEX); + test("testZipFileIndexArchive2", + fm, testClassName, "com.sun.tools.javac.file.ZipFileIndexArchive$ZipFileIndexFileObject"); + } + + /** + * @param testName for debugging + * @param fm suitably configured file manager + * @param testClassName the classname to test + * @param implClassName the expected classname of the JavaFileObject impl, + * used for checking that we are checking the expected impl of + * inferBinaryName + */ + void test(String testName, + JavaFileManager fm, String testClassName, String implClassName) throws IOException { + JavaFileObject fo = fm.getJavaFileForInput(CLASS_PATH, testClassName, CLASS); + if (fo == null) { + System.err.println("Can't find " + testClassName); + errors++; + return; + } + + String cn = fo.getClass().getName(); + String bn = fm.inferBinaryName(CLASS_PATH, fo); + System.err.println(testName + " " + cn + " " + bn); + check(cn, implClassName); + check(bn, testClassName); + System.err.println("OK"); + } + + JavaFileManager getFileManager(String classpathProperty, + boolean symFileKind, + boolean zipFileIndexKind) + throws IOException { + Context ctx = new Context(); + // uugh, ugly back door, should be cleaned up, someday + if (zipFileIndexKind == USE_ZIP_FILE_INDEX) + System.clearProperty("useJavaUtilZip"); + else + System.setProperty("useJavaUtilZip", "true"); + Options options = Options.instance(ctx); + if (symFileKind == IGNORE_SYMBOL_FILE) + options.put("ignore.symbol.file", "true"); + JavacFileManager fm = new JavacFileManager(ctx, false, null); + List path = getPath(System.getProperty(classpathProperty)); + fm.setLocation(CLASS_PATH, path); + return fm; + } + + List getPath(String s) { + List path = new ArrayList(); + for (String f: s.split(File.pathSeparator)) { + if (f.length() > 0) + path.add(new File(f)); + } + //System.err.println("path: " + path); + return path; + } + + void check(String found, String expect) { + if (!found.equals(expect)) { + System.err.println("Expected: " + expect); + System.err.println(" Found: " + found); + errors++; + } + } + + private int errors; +} + +class A { } + diff -r 853d8c191eac -r b316e32eb90c langtools/test/tools/javac/6508981/p/A.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/6508981/p/A.java Tue Aug 26 14:52:59 2008 -0700 @@ -0,0 +1,24 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ +package p; +class A { } diff -r 853d8c191eac -r b316e32eb90c langtools/test/tools/javac/T6725036.java --- a/langtools/test/tools/javac/T6725036.java Fri Aug 22 11:46:29 2008 +0100 +++ b/langtools/test/tools/javac/T6725036.java Tue Aug 26 14:52:59 2008 -0700 @@ -35,6 +35,7 @@ import javax.tools.JavaFileObject; import com.sun.tools.javac.file.JavacFileManager; +import com.sun.tools.javac.file.RelativePath.RelativeFile; import com.sun.tools.javac.file.ZipFileIndex; import com.sun.tools.javac.file.ZipFileIndexArchive; import com.sun.tools.javac.util.Context; @@ -45,7 +46,7 @@ } void run() throws Exception { - String TEST_ENTRY_NAME = "java/lang/String.class"; + RelativeFile TEST_ENTRY_NAME = new RelativeFile("java/lang/String.class"); File f = new File(System.getProperty("java.home")); if (!f.getName().equals("jre")) @@ -53,22 +54,21 @@ File rt_jar = new File(new File(f, "lib"), "rt.jar"); JarFile j = new JarFile(rt_jar); - JarEntry je = j.getJarEntry(TEST_ENTRY_NAME); + JarEntry je = j.getJarEntry(TEST_ENTRY_NAME.getPath()); long jarEntryTime = je.getTime(); ZipFileIndex zfi = ZipFileIndex.getZipFileIndex(rt_jar, null, false, null, false); long zfiTime = zfi.getLastModified(TEST_ENTRY_NAME); - check(je, jarEntryTime, zfi + ":" + TEST_ENTRY_NAME, zfiTime); + check(je, jarEntryTime, zfi + ":" + TEST_ENTRY_NAME.getPath(), zfiTime); Context context = new Context(); JavacFileManager fm = new JavacFileManager(context, false, null); ZipFileIndexArchive zfia = new ZipFileIndexArchive(fm, zfi); - int sep = TEST_ENTRY_NAME.lastIndexOf("/"); JavaFileObject jfo = - zfia.getFileObject(TEST_ENTRY_NAME.substring(0, sep + 1), - TEST_ENTRY_NAME.substring(sep + 1)); + zfia.getFileObject(TEST_ENTRY_NAME.dirname(), + TEST_ENTRY_NAME.basename()); long jfoTime = jfo.getLastModified(); check(je, jarEntryTime, jfo, jfoTime);