6508981: cleanup file separator handling in JavacFileManager
Reviewed-by: mcimadamore
--- 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<JavaFileObject.Kind> fileKinds,
boolean recurse,
ListBuffer<JavaFileObject> 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<String> 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<String> getFiles(String subdirectory);
+ List<String> getFiles(RelativeDirectory subdirectory);
- Set<String> getSubdirectories();
+ Set<RelativeDirectory> 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<String> getFiles(String subdirectory) {
+ public List<String> getFiles(RelativeDirectory subdirectory) {
return List.nil();
}
- public Set<String> getSubdirectories() {
+ public Set<RelativeDirectory> getSubdirectories() {
return Collections.emptySet();
}
+
+ public String toString() {
+ return "MissingArchive[" + zipFileName + "]";
+ }
}
/** A directory of zip files already opened.
*/
Map<File, Archive> archives = new HashMap<File,Archive>();
+ 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<? extends File> path = getLocation(location);
if (path == null)
return List.nil();
- String subdirectory = externalizeFileName(packageName);
+ RelativeDirectory subdirectory = RelativeDirectory.forPackage(packageName);
ListBuffer<JavaFileObject> results = new ListBuffer<JavaFileObject>();
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<? extends File> 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);
}
--- /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<RelativePath> {
+ /**
+ * @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 + "]";
+ }
+
+ }
+
+}
--- 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<String> 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<? extends File> path) {
+ String entryName = getZipEntryName();
+ String prefix = ((SymbolArchive) zarch).prefix.path;
+ if (entryName.startsWith(prefix))
+ entryName = entryName.substring(prefix.length());
+ return removeExtension(entryName).replace('/', '.');
+ }
+ }
+
+
}
--- 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<String,List<String>>();
+ this.map = new HashMap<RelativeDirectory,List<String>>();
+ if (initMap)
+ initMap();
+ }
+
+ protected void initMap() throws IOException {
for (Enumeration<? extends ZipEntry> 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<String> list = map.get(dirname);
return (list != null && list.contains(basename));
}
- public List<String> getFiles(String subdirectory) {
+ public List<String> 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<String> getSubdirectories() {
+ public Set<RelativeDirectory> getSubdirectories() {
return map.keySet();
}
@@ -105,8 +116,12 @@
zdir.close();
}
+ public String toString() {
+ return "ZipArchive[" + zdir.getName() + "]";
+ }
+
protected JavacFileManager fileManager;
- protected final Map<String,List<String>> map;
+ protected final Map<RelativeDirectory,List<String>> 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<? extends File> 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('/', '.');
}
}
--- 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<String, DirectoryEntry> directories = Collections.<String, DirectoryEntry>emptyMap();
- private Set<String> allDirs = Collections.<String>emptySet();
+ private Map<RelativeDirectory, DirectoryEntry> directories = Collections.<RelativeDirectory, DirectoryEntry>emptyMap();
+ private Set<RelativeDirectory> allDirs = Collections.<RelativeDirectory>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 <String, SoftReference<RelativeDirectory>> relativeDirectoryCache =
+ new HashMap<String, SoftReference<RelativeDirectory>>();
+
/**
* 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.<String, DirectoryEntry>emptyMap();
- allDirs = Collections.<String>emptySet();
+ directories = Collections.<RelativeDirectory, DirectoryEntry>emptyMap();
+ allDirs = Collections.<RelativeDirectory>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.<String, DirectoryEntry>emptyMap();
+ directories = Collections.<RelativeDirectory, DirectoryEntry>emptyMap();
zipFileLastModified = NOT_MODIFIED;
- allDirs = Collections.<String>emptySet();
+ allDirs = Collections.<RelativeDirectory>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<String> getFiles(String path) {
- if (File.separatorChar != '/') {
- path = path.replace('/', File.separatorChar);
- }
-
+ public com.sun.tools.javac.util.List<String> getFiles(RelativeDirectory path) {
lock.lock();
try {
checkIndex();
@@ -402,16 +396,10 @@
}
}
- public List<String> getAllDirectories(String path) {
-
- if (File.separatorChar != '/') {
- path = path.replace('/', File.separatorChar);
- }
-
+ public List<String> getDirectories(RelativeDirectory path) {
lock.lock();
try {
checkIndex();
- path = path.intern();
DirectoryEntry de = directories.get(path);
com.sun.tools.javac.util.List<String> ret = de == null ? null : de.getDirectories();
@@ -430,24 +418,18 @@
}
}
- public Set<String> getAllDirectories() {
+ public Set<RelativeDirectory> getAllDirectories() {
lock.lock();
try {
checkIndex();
if (allDirs == Collections.EMPTY_SET) {
- Set<String> alldirs = new HashSet<String>();
- Iterator<String> dirsIter = directories.keySet().iterator();
- while (dirsIter.hasNext()) {
- alldirs.add(new String(dirsIter.next()));
- }
-
- allDirs = alldirs;
+ allDirs = new HashSet<RelativeDirectory>(directories.keySet());
}
return allDirs;
}
catch (IOException e) {
- return Collections.<String>emptySet();
+ return Collections.<RelativeDirectory>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<String, DirectoryEntry>();
+ directories = new HashMap<RelativeDirectory, DirectoryEntry>();
ArrayList<Entry> entryList = new ArrayList<Entry>();
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<Entry> entryList,
- Map<String, DirectoryEntry> directories) throws IOException {
+ Map<RelativeDirectory, DirectoryEntry> 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<String> zipFileEntriesFiles = com.sun.tools.javac.util.List.<String>nil();
private com.sun.tools.javac.util.List<String> zipFileEntriesDirectories = com.sun.tools.javac.util.List.<String>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<String> 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<String> 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<Entry> 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<String, DirectoryEntry>();
+ directories = new HashMap<RelativeDirectory, DirectoryEntry>();
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<String> iterDirName = directories.keySet().iterator();
List<DirectoryEntry> directoriesToWrite = new ArrayList<DirectoryEntry>();
- Map<String, Long> offsets = new HashMap<String, Long>();
+ Map<RelativeDirectory, Long> offsets = new HashMap<RelativeDirectory, Long>();
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<RelativeDirectory> ref = relativeDirectoryCache.get(path);
+ if (ref != null) {
+ rd = ref.get();
+ if (rd != null)
+ return rd;
+ }
+ rd = new RelativeDirectory(path);
+ relativeDirectoryCache.put(path, new SoftReference<RelativeDirectory>(rd));
+ return rd;
+ }
static class Entry implements Comparable<Entry> {
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) :
--- 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<String> getFiles(String subdirectory) {
- return zfIndex.getFiles((subdirectory.endsWith("/") || subdirectory.endsWith("\\")) ? subdirectory.substring(0, subdirectory.length() - 1) : subdirectory);
+ public List<String> 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<String> getSubdirectories() {
+ public Set<RelativeDirectory> 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<? extends File> 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('/', '.');
}
}
--- 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
--- 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.*;
/**
--- /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<File> path = getPath(System.getProperty(classpathProperty));
+ fm.setLocation(CLASS_PATH, path);
+ return fm;
+ }
+
+ List<File> getPath(String s) {
+ List<File> path = new ArrayList<File>();
+ 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 { }
+
--- /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 { }
--- 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);