diff --git a/src/share/classes/com/sun/tools/javac/file/BaseFileObject.java b/src/share/classes/com/sun/tools/javac/file/BaseFileObject.java index 95774280440e9cf221ba8744ad548d3f9139a1a5..71f5c46e708b8978f196a2c8b3fc41f9a0c01e80 100644 --- a/src/share/classes/com/sun/tools/javac/file/BaseFileObject.java +++ b/src/share/classes/com/sun/tools/javac/file/BaseFileObject.java @@ -25,6 +25,7 @@ package com.sun.tools.javac.file; +import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.io.Reader; @@ -36,6 +37,9 @@ import javax.tools.JavaFileObject; import static javax.tools.JavaFileObject.Kind.*; public abstract class BaseFileObject implements JavaFileObject { + protected BaseFileObject(JavacFileManager fileManager) { + this.fileManager = fileManager; + } public JavaFileObject.Kind getKind() { String n = getName(); @@ -76,4 +80,14 @@ public abstract class BaseFileObject implements JavaFileObject { throw new UnsupportedOperationException(); } + protected abstract String inferBinaryName(Iterable path); + + protected static String removeExtension(String fileName) { + int lastDot = fileName.lastIndexOf("."); + return (lastDot == -1 ? fileName : fileName.substring(0, lastDot)); + } + + /** The file manager that created this JavaFileObject. */ + protected final JavacFileManager fileManager; + } diff --git a/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java b/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java index 5e8c305f7d5beb270ebe1d4b4e3b3f34462986c5..86fc3f20fd9f5c5cadcb452ff9aaa06d2385e953 100644 --- a/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java +++ b/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2005-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 @@ -25,21 +25,16 @@ package com.sun.tools.javac.file; -import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; -import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; -import java.io.OutputStream; import java.io.OutputStreamWriter; -import java.io.Writer; import java.lang.ref.SoftReference; import java.net.MalformedURLException; import java.net.URI; -import java.net.URISyntaxException; import java.net.URL; import java.net.URLClassLoader; import java.nio.ByteBuffer; @@ -56,13 +51,11 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.EnumSet; -import java.util.Enumeration; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; -import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import javax.lang.model.SourceVersion; @@ -96,15 +89,6 @@ public class JavacFileManager implements StandardJavaFileManager { boolean useZipFileIndex; - private static int symbolFilePrefixLength = 0; - static { - try { - symbolFilePrefixLength = symbolFilePrefix.getBytes("UTF-8").length; - } catch (java.io.UnsupportedEncodingException uee) { - // Can't happen...UTF-8 is always supported. - } - } - private static boolean CHECK_ZIP_TIMESTAMP = false; private static Map isDirectory = new ConcurrentHashMap(); @@ -202,7 +186,7 @@ public class JavacFileManager implements StandardJavaFileManager { } public JavaFileObject getRegularFile(File file) { - return new RegularFileObject(file); + return new RegularFileObject(this, file); } public JavaFileObject getFileForOutput(String classname, @@ -405,7 +389,7 @@ public class JavacFileManager implements StandardJavaFileManager { } else { if (isValidFile(fname, fileKinds)) { JavaFileObject fe = - new RegularFileObject(fname, new File(d, fname)); + new RegularFileObject(this, fname, new File(d, fname)); l.append(fe); } } @@ -469,106 +453,13 @@ public class JavacFileManager implements StandardJavaFileManager { Set getSubdirectories(); } - public class ZipArchive implements Archive { - protected final Map> map; - protected final ZipFile zdir; - public ZipArchive(ZipFile zdir) throws IOException { - this.zdir = zdir; - this.map = new HashMap>(); - for (Enumeration e = zdir.entries(); e.hasMoreElements(); ) { - ZipEntry entry; - try { - entry = e.nextElement(); - } catch (InternalError ex) { - IOException io = new IOException(); - io.initCause(ex); // convenience constructors added in Mustang :-( - throw io; - } - addZipEntry(entry); - } - } - - void addZipEntry(ZipEntry entry) { - String name = entry.getName(); - int i = name.lastIndexOf('/'); - String dirname = name.substring(0, i+1); - String basename = name.substring(i+1); - if (basename.length() == 0) - return; - List list = map.get(dirname); - if (list == null) - list = List.nil(); - list = list.prepend(basename); - map.put(dirname, list); - } - - public boolean contains(String name) { - int i = name.lastIndexOf('/'); - String dirname = name.substring(0, i+1); - String basename = name.substring(i+1); - if (basename.length() == 0) - return false; - List list = map.get(dirname); - return (list != null && list.contains(basename)); - } - - public List getFiles(String subdirectory) { - return map.get(subdirectory); - } - - public JavaFileObject getFileObject(String subdirectory, String file) { - ZipEntry ze = zdir.getEntry(subdirectory + file); - return new ZipFileObject(file, zdir, ze); - } - - public Set getSubdirectories() { - return map.keySet(); - } - - public void close() throws IOException { - zdir.close(); - } - } - - public class SymbolArchive extends ZipArchive { - final File origFile; - public SymbolArchive(File orig, ZipFile zdir) throws IOException { - super(zdir); - this.origFile = orig; - } - - @Override - void addZipEntry(ZipEntry entry) { - // called from super constructor, may not refer to origFile. - String name = entry.getName(); - if (!name.startsWith(symbolFilePrefix)) - return; - name = name.substring(symbolFilePrefix.length()); - int i = name.lastIndexOf('/'); - String dirname = name.substring(0, i+1); - String basename = name.substring(i+1); - if (basename.length() == 0) - return; - List list = map.get(dirname); - if (list == null) - list = List.nil(); - list = list.prepend(basename); - map.put(dirname, list); - } - - @Override - public JavaFileObject getFileObject(String subdirectory, String file) { - return super.getFileObject(symbolFilePrefix + subdirectory, file); - } - } - public class MissingArchive implements Archive { final File zipFileName; public MissingArchive(File name) { zipFileName = name; } public boolean contains(String name) { - return false; + return false; } public void close() { @@ -647,19 +538,23 @@ public class JavacFileManager implements StandardJavaFileManager { if (origZipFileName == zipFileName) { if (!useZipFileIndex) { - archive = new ZipArchive(zdir); + archive = new ZipArchive(this, zdir); } else { - archive = new ZipFileIndexArchive(this, ZipFileIndex.getZipFileIndex(zipFileName, 0, + archive = new ZipFileIndexArchive(this, ZipFileIndex.getZipFileIndex(zipFileName, null, usePreindexedCache, preindexCacheLocation, options.get("writezipindexfiles") != null)); } } else { if (!useZipFileIndex) { - archive = new SymbolArchive(origZipFileName, zdir); + archive = new SymbolArchive(this, origZipFileName, zdir, symbolFilePrefix); } else { - archive = new ZipFileIndexArchive(this, ZipFileIndex.getZipFileIndex(zipFileName, symbolFilePrefixLength, - usePreindexedCache, preindexCacheLocation, options.get("writezipindexfiles") != null)); + archive = new ZipFileIndexArchive(this, + ZipFileIndex.getZipFileIndex(zipFileName, + symbolFilePrefix, + usePreindexedCache, + preindexCacheLocation, + options.get("writezipindexfiles") != null)); } } } catch (FileNotFoundException ex) { @@ -695,7 +590,17 @@ public class JavacFileManager implements StandardJavaFileManager { } } - private Map> contentCache = new HashMap>(); + CharBuffer getCachedContent(JavaFileObject file) { + SoftReference r = contentCache.get(file); + return (r == null ? null : r.get()); + } + + void cache(JavaFileObject file, CharBuffer cb) { + contentCache.put(file, new SoftReference(cb)); + } + + private final Map> contentCache + = new HashMap>(); private String defaultEncodingName; private String getDefaultEncodingName() { @@ -725,7 +630,7 @@ public class JavacFileManager implements StandardJavaFileManager { /** * Make a byte buffer from an input stream. */ - private ByteBuffer makeByteBuffer(InputStream in) + ByteBuffer makeByteBuffer(InputStream in) throws IOException { int limit = in.available(); if (mmappedIO && in instanceof FileInputStream) { @@ -751,6 +656,10 @@ public class JavacFileManager implements StandardJavaFileManager { return (ByteBuffer)result.flip(); } + void recycleByteBuffer(ByteBuffer bb) { + byteBufferCache.put(bb); + } + /** * A single-element cache of direct byte buffers. */ @@ -769,9 +678,10 @@ public class JavacFileManager implements StandardJavaFileManager { cached = x; } } + private final ByteBufferCache byteBufferCache; - private CharsetDecoder getDecoder(String encodingName, boolean ignoreEncodingErrors) { + CharsetDecoder getDecoder(String encodingName, boolean ignoreEncodingErrors) { Charset charset = (this.charset == null) ? Charset.forName(encodingName) : this.charset; @@ -791,7 +701,7 @@ public class JavacFileManager implements StandardJavaFileManager { /** * Decode a ByteBuffer into a CharBuffer. */ - private CharBuffer decode(ByteBuffer inbuf, boolean ignoreEncodingErrors) { + CharBuffer decode(ByteBuffer inbuf, boolean ignoreEncodingErrors) { String encodingName = getEncodingName(); CharsetDecoder decoder; try { @@ -901,48 +811,14 @@ public class JavacFileManager implements StandardJavaFileManager { // Need to match the path semantics of list(location, ...) Iterable path = getLocation(location); if (path == null) { - //System.err.println("Path for " + location + " is null"); return null; } - //System.err.println("Path for " + location + " is " + path); - - if (file instanceof RegularFileObject) { - RegularFileObject r = (RegularFileObject) file; - String rPath = r.getPath(); - //System.err.println("RegularFileObject " + file + " " +r.getPath()); - for (File dir: path) { - //System.err.println("dir: " + dir); - String dPath = dir.getPath(); - if (!dPath.endsWith(File.separator)) - dPath += File.separator; - if (rPath.regionMatches(true, 0, dPath, 0, dPath.length()) - && new File(rPath.substring(0, dPath.length())).equals(new File(dPath))) { - String relativeName = rPath.substring(dPath.length()); - return removeExtension(relativeName).replace(File.separatorChar, '.'); - } - } - } else if (file instanceof ZipFileObject) { - ZipFileObject z = (ZipFileObject) file; - String entryName = z.getZipEntryName(); - if (entryName.startsWith(symbolFilePrefix)) - entryName = entryName.substring(symbolFilePrefix.length()); - return removeExtension(entryName).replace('/', '.'); - } else if (file instanceof ZipFileIndexFileObject) { - ZipFileIndexFileObject z = (ZipFileIndexFileObject) file; - String entryName = z.getZipEntryName(); - if (entryName.startsWith(symbolFilePrefix)) - entryName = entryName.substring(symbolFilePrefix.length()); - return removeExtension(entryName).replace(File.separatorChar, '.'); + + if (file instanceof BaseFileObject) { + return ((BaseFileObject) file).inferBinaryName(path); } else throw new IllegalArgumentException(file.getClass().getName()); - // System.err.println("inferBinaryName failed for " + file); - return null; } - // where - private static String removeExtension(String fileName) { - int lastDot = fileName.lastIndexOf("."); - return (lastDot == -1 ? fileName : fileName.substring(0, lastDot)); - } public boolean isSameFile(FileObject a, FileObject b) { nullCheck(a); @@ -1029,7 +905,7 @@ public class JavacFileManager implements StandardJavaFileManager { if (dir.isDirectory()) { File f = new File(dir, name.replace('/', File.separatorChar)); if (f.exists()) - return new RegularFileObject(f); + return new RegularFileObject(this, f); } else { Archive a = openArchive(dir); if (a.contains(name)) { @@ -1091,7 +967,7 @@ public class JavacFileManager implements StandardJavaFileManager { if (sibling != null && sibling instanceof RegularFileObject) { siblingDir = ((RegularFileObject)sibling).f.getParentFile(); } - return new RegularFileObject(new File(siblingDir, baseName(fileName))); + return new RegularFileObject(this, new File(siblingDir, baseName(fileName))); } } else if (location == SOURCE_OUTPUT) { dir = (getSourceOutDir() != null ? getSourceOutDir() : getClassOutDir()); @@ -1105,7 +981,7 @@ public class JavacFileManager implements StandardJavaFileManager { } File file = (dir == null ? new File(fileName) : new File(dir, fileName)); - return new RegularFileObject(file); + return new RegularFileObject(this, file); } @@ -1118,7 +994,7 @@ public class JavacFileManager implements StandardJavaFileManager { else result = new ArrayList(); for (File f: files) - result.add(new RegularFileObject(nullCheck(f))); + result.add(new RegularFileObject(this, nullCheck(f))); return result; } @@ -1268,452 +1144,4 @@ public class JavacFileManager implements StandardJavaFileManager { t.getClass(); // null check return it; } - - /** - * A subclass of JavaFileObject representing regular files. - */ - private class RegularFileObject extends BaseFileObject { - /** Have the parent directories been created? - */ - private boolean hasParents=false; - - /** The file's name. - */ - private String name; - - /** The underlying file. - */ - final File f; - - public RegularFileObject(File f) { - this(f.getName(), f); - } - - public RegularFileObject(String name, File f) { - if (f.isDirectory()) - throw new IllegalArgumentException("directories not supported"); - this.name = name; - this.f = f; - } - - public InputStream openInputStream() throws IOException { - return new FileInputStream(f); - } - - protected CharsetDecoder getDecoder(boolean ignoreEncodingErrors) { - return JavacFileManager.this.getDecoder(getEncodingName(), ignoreEncodingErrors); - } - - public OutputStream openOutputStream() throws IOException { - ensureParentDirectoriesExist(); - return new FileOutputStream(f); - } - - public Writer openWriter() throws IOException { - ensureParentDirectoriesExist(); - return new OutputStreamWriter(new FileOutputStream(f), getEncodingName()); - } - - private void ensureParentDirectoriesExist() throws IOException { - if (!hasParents) { - File parent = f.getParentFile(); - if (parent != null && !parent.exists()) { - if (!parent.mkdirs()) { - // if the mkdirs failed, it may be because another process concurrently - // created the directory, so check if the directory got created - // anyway before throwing an exception - if (!parent.exists() || !parent.isDirectory()) - throw new IOException("could not create parent directories"); - } - } - hasParents = true; - } - } - - /** @deprecated see bug 6410637 */ - @Deprecated - public String getName() { - return name; - } - - public boolean isNameCompatible(String cn, JavaFileObject.Kind kind) { - cn.getClass(); // null check - if (kind == Kind.OTHER && getKind() != kind) - return false; - String n = cn + kind.extension; - if (name.equals(n)) - return true; - if (name.equalsIgnoreCase(n)) { - try { - // allow for Windows - return (f.getCanonicalFile().getName().equals(n)); - } catch (IOException e) { - } - } - return false; - } - - /** @deprecated see bug 6410637 */ - @Deprecated - public String getPath() { - return f.getPath(); - } - - public long getLastModified() { - return f.lastModified(); - } - - public boolean delete() { - return f.delete(); - } - - public CharBuffer getCharContent(boolean ignoreEncodingErrors) throws IOException { - SoftReference r = contentCache.get(this); - CharBuffer cb = (r == null ? null : r.get()); - if (cb == null) { - InputStream in = new FileInputStream(f); - try { - ByteBuffer bb = makeByteBuffer(in); - JavaFileObject prev = log.useSource(this); - try { - cb = decode(bb, ignoreEncodingErrors); - } finally { - log.useSource(prev); - } - byteBufferCache.put(bb); // save for next time - if (!ignoreEncodingErrors) - contentCache.put(this, new SoftReference(cb)); - } finally { - in.close(); - } - } - return cb; - } - - @Override - public boolean equals(Object other) { - if (!(other instanceof RegularFileObject)) - return false; - RegularFileObject o = (RegularFileObject) other; - try { - return f.equals(o.f) - || f.getCanonicalFile().equals(o.f.getCanonicalFile()); - } catch (IOException e) { - return false; - } - } - - @Override - public int hashCode() { - return f.hashCode(); - } - - public URI toUri() { - try { - // Do no use File.toURI to avoid file system access - String path = f.getAbsolutePath().replace(File.separatorChar, '/'); - return new URI("file://" + path).normalize(); - } catch (URISyntaxException ex) { - return f.toURI(); - } - } - - } - - /** - * A subclass of JavaFileObject representing zip entries. - */ - public class ZipFileObject extends BaseFileObject { - - /** The entry's name. - */ - private String name; - - /** The zipfile containing the entry. - */ - ZipFile zdir; - - /** The underlying zip entry object. - */ - ZipEntry entry; - - public ZipFileObject(String name, ZipFile zdir, ZipEntry entry) { - this.name = name; - this.zdir = zdir; - this.entry = entry; - } - - public InputStream openInputStream() throws IOException { - return zdir.getInputStream(entry); - } - - public OutputStream openOutputStream() throws IOException { - throw new UnsupportedOperationException(); - } - - protected CharsetDecoder getDecoder(boolean ignoreEncodingErrors) { - return JavacFileManager.this.getDecoder(getEncodingName(), ignoreEncodingErrors); - } - - public Writer openWriter() throws IOException { - throw new UnsupportedOperationException(); - } - - /** @deprecated see bug 6410637 */ - @Deprecated - public String getName() { - return name; - } - - public boolean isNameCompatible(String cn, JavaFileObject.Kind k) { - cn.getClass(); // null check - if (k == Kind.OTHER && getKind() != k) - return false; - return name.equals(cn + k.extension); - } - - /** @deprecated see bug 6410637 */ - @Deprecated - public String getPath() { - return zdir.getName() + "(" + entry + ")"; - } - - public long getLastModified() { - return entry.getTime(); - } - - public boolean delete() { - throw new UnsupportedOperationException(); - } - - public CharBuffer getCharContent(boolean ignoreEncodingErrors) throws IOException { - SoftReference r = contentCache.get(this); - CharBuffer cb = (r == null ? null : r.get()); - if (cb == null) { - InputStream in = zdir.getInputStream(entry); - try { - ByteBuffer bb = makeByteBuffer(in); - JavaFileObject prev = log.useSource(this); - try { - cb = decode(bb, ignoreEncodingErrors); - } finally { - log.useSource(prev); - } - byteBufferCache.put(bb); // save for next time - if (!ignoreEncodingErrors) - contentCache.put(this, new SoftReference(cb)); - } finally { - in.close(); - } - } - return cb; - } - - @Override - public boolean equals(Object other) { - if (!(other instanceof ZipFileObject)) - return false; - ZipFileObject o = (ZipFileObject) other; - return zdir.equals(o.zdir) || name.equals(o.name); - } - - @Override - public int hashCode() { - return zdir.hashCode() + name.hashCode(); - } - - public String getZipName() { - return zdir.getName(); - } - - public String getZipEntryName() { - return entry.getName(); - } - - public URI toUri() { - String zipName = new File(getZipName()).toURI().normalize().getPath(); - String entryName = getZipEntryName(); - return URI.create("jar:" + zipName + "!" + entryName); - } - - } - - /** - * A subclass of JavaFileObject representing zip entries using the com.sun.tools.javac.zip.ZipFileIndex implementation. - */ - public class ZipFileIndexFileObject extends BaseFileObject { - - /** The entry's name. - */ - private String name; - - /** The zipfile containing the entry. - */ - ZipFileIndex zfIndex; - - /** The underlying zip entry object. - */ - ZipFileIndexEntry entry; - - /** The InputStream for this zip entry (file.) - */ - InputStream inputStream = null; - - /** The name of the zip file where this entry resides. - */ - String zipName; - - JavacFileManager defFileManager = null; - - public ZipFileIndexFileObject(JavacFileManager fileManager, ZipFileIndex zfIndex, ZipFileIndexEntry entry, String zipFileName) { - super(); - this.name = entry.getFileName(); - this.zfIndex = zfIndex; - this.entry = entry; - this.zipName = zipFileName; - defFileManager = fileManager; - } - - public InputStream openInputStream() throws IOException { - - if (inputStream == null) { - inputStream = new ByteArrayInputStream(read()); - } - return inputStream; - } - - protected CharsetDecoder getDecoder(boolean ignoreEncodingErrors) { - return JavacFileManager.this.getDecoder(getEncodingName(), ignoreEncodingErrors); - } - - public OutputStream openOutputStream() throws IOException { - throw new UnsupportedOperationException(); - } - - public Writer openWriter() throws IOException { - throw new UnsupportedOperationException(); - } - - /** @deprecated see bug 6410637 */ - @Deprecated - public String getName() { - return name; - } - - public boolean isNameCompatible(String cn, JavaFileObject.Kind k) { - cn.getClass(); // null check - if (k == Kind.OTHER && getKind() != k) - return false; - return name.equals(cn + k.extension); - } - - /** @deprecated see bug 6410637 */ - @Deprecated - public String getPath() { - return zipName + "(" + entry.getName() + ")"; - } - - public long getLastModified() { - return entry.getLastModified(); - } - - public boolean delete() { - throw new UnsupportedOperationException(); - } - - @Override - public boolean equals(Object other) { - if (!(other instanceof ZipFileIndexFileObject)) - return false; - ZipFileIndexFileObject o = (ZipFileIndexFileObject) other; - return entry.equals(o.entry); - } - - @Override - public int hashCode() { - return zipName.hashCode() + (name.hashCode() << 10); - } - - public String getZipName() { - return zipName; - } - - public String getZipEntryName() { - return entry.getName(); - } - - 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(); - } - return zfIndex.read(entry); - } - - public CharBuffer getCharContent(boolean ignoreEncodingErrors) throws IOException { - SoftReference r = defFileManager.contentCache.get(this); - CharBuffer cb = (r == null ? null : r.get()); - if (cb == null) { - InputStream in = new ByteArrayInputStream(zfIndex.read(entry)); - try { - ByteBuffer bb = makeByteBuffer(in); - JavaFileObject prev = log.useSource(this); - try { - cb = decode(bb, ignoreEncodingErrors); - } finally { - log.useSource(prev); - } - byteBufferCache.put(bb); // save for next time - if (!ignoreEncodingErrors) - defFileManager.contentCache.put(this, new SoftReference(cb)); - } finally { - in.close(); - } - } - return cb; - } - } - - public class ZipFileIndexArchive implements Archive { - private final ZipFileIndex zfIndex; - private JavacFileManager fileManager; - - public ZipFileIndexArchive(JavacFileManager fileManager, ZipFileIndex zdir) throws IOException { - this.fileManager = fileManager; - this.zfIndex = zdir; - } - - public boolean contains(String name) { - return zfIndex.contains(name); - } - - public com.sun.tools.javac.util.List getFiles(String subdirectory) { - return zfIndex.getFiles(((subdirectory.endsWith("/") || subdirectory.endsWith("\\"))? subdirectory.substring(0, subdirectory.length() - 1) : subdirectory)); - } - - public JavaFileObject getFileObject(String subdirectory, String file) { - String fullZipFileName = subdirectory + file; - ZipFileIndexEntry entry = zfIndex.getZipIndexEntry(fullZipFileName); - JavaFileObject ret = new ZipFileIndexFileObject(fileManager, zfIndex, entry, zfIndex.getZipFile().getPath()); - return ret; - } - - public Set getSubdirectories() { - return zfIndex.getAllDirectories(); - } - - public void close() throws IOException { - zfIndex.close(); - } - } } diff --git a/src/share/classes/com/sun/tools/javac/file/RegularFileObject.java b/src/share/classes/com/sun/tools/javac/file/RegularFileObject.java new file mode 100644 index 0000000000000000000000000000000000000000..a2a4b2bdc73c04e66215bba3ed225bb3c6adcd5c --- /dev/null +++ b/src/share/classes/com/sun/tools/javac/file/RegularFileObject.java @@ -0,0 +1,204 @@ +/* + * Copyright 2005-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.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.net.URI; +import java.net.URISyntaxException; +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.charset.CharsetDecoder; +import javax.tools.JavaFileObject; + +/** + * A subclass of JavaFileObject representing regular files. + */ +class RegularFileObject extends BaseFileObject { + + /** Have the parent directories been created? + */ + private boolean hasParents = false; + private String name; + final File f; + + public RegularFileObject(JavacFileManager fileManager, File f) { + this(fileManager, f.getName(), f); + } + + public RegularFileObject(JavacFileManager fileManager, String name, File f) { + super(fileManager); + if (f.isDirectory()) { + throw new IllegalArgumentException("directories not supported"); + } + this.name = name; + this.f = f; + } + + public InputStream openInputStream() throws IOException { + return new FileInputStream(f); + } + + protected CharsetDecoder getDecoder(boolean ignoreEncodingErrors) { + return fileManager.getDecoder(fileManager.getEncodingName(), ignoreEncodingErrors); + } + + public OutputStream openOutputStream() throws IOException { + ensureParentDirectoriesExist(); + return new FileOutputStream(f); + } + + public Writer openWriter() throws IOException { + ensureParentDirectoriesExist(); + return new OutputStreamWriter(new FileOutputStream(f), fileManager.getEncodingName()); + } + + @Override + protected String inferBinaryName(Iterable path) { + String fPath = f.getPath(); + //System.err.println("RegularFileObject " + file + " " +r.getPath()); + for (File dir: path) { + //System.err.println("dir: " + dir); + String dPath = dir.getPath(); + if (!dPath.endsWith(File.separator)) + dPath += File.separator; + if (fPath.regionMatches(true, 0, dPath, 0, dPath.length()) + && new File(fPath.substring(0, dPath.length())).equals(new File(dPath))) { + String relativeName = fPath.substring(dPath.length()); + return removeExtension(relativeName).replace(File.separatorChar, '.'); + } + } + return null; + } + + private void ensureParentDirectoriesExist() throws IOException { + if (!hasParents) { + File parent = f.getParentFile(); + if (parent != null && !parent.exists()) { + if (!parent.mkdirs()) { + if (!parent.exists() || !parent.isDirectory()) { + throw new IOException("could not create parent directories"); + } + } + } + hasParents = true; + } + } + + @Deprecated + public String getName() { + return name; + } + + public boolean isNameCompatible(String cn, JavaFileObject.Kind kind) { + cn.getClass(); + // null check + if (kind == Kind.OTHER && getKind() != kind) { + return false; + } + String n = cn + kind.extension; + if (name.equals(n)) { + return true; + } + if (name.equalsIgnoreCase(n)) { + try { + // allow for Windows + return f.getCanonicalFile().getName().equals(n); + } catch (IOException e) { + } + } + return false; + } + + @Deprecated + public String getPath() { + return f.getPath(); + } + + public long getLastModified() { + return f.lastModified(); + } + + public boolean delete() { + return f.delete(); + } + + public CharBuffer getCharContent(boolean ignoreEncodingErrors) throws IOException { + CharBuffer cb = fileManager.getCachedContent(this); + if (cb == null) { + InputStream in = new FileInputStream(f); + try { + ByteBuffer bb = fileManager.makeByteBuffer(in); + JavaFileObject prev = fileManager.log.useSource(this); + try { + cb = fileManager.decode(bb, ignoreEncodingErrors); + } finally { + fileManager.log.useSource(prev); + } + fileManager.recycleByteBuffer(bb); + if (!ignoreEncodingErrors) { + fileManager.cache(this, cb); + } + } finally { + in.close(); + } + } + return cb; + } + + @Override + public boolean equals(Object other) { + if (!(other instanceof RegularFileObject)) { + return false; + } + RegularFileObject o = (RegularFileObject) other; + try { + return f.equals(o.f) || f.getCanonicalFile().equals(o.f.getCanonicalFile()); + } catch (IOException e) { + return false; + } + } + + @Override + public int hashCode() { + return f.hashCode(); + } + + public URI toUri() { + try { + String path = f.getAbsolutePath().replace(File.separatorChar, '/'); + return new URI("file://" + path).normalize(); + } catch (URISyntaxException ex) { + return f.toURI(); + } + } +} diff --git a/src/share/classes/com/sun/tools/javac/file/SymbolArchive.java b/src/share/classes/com/sun/tools/javac/file/SymbolArchive.java new file mode 100644 index 0000000000000000000000000000000000000000..a4d44526e0a54fb0e13da57f6aa157c269e748aa --- /dev/null +++ b/src/share/classes/com/sun/tools/javac/file/SymbolArchive.java @@ -0,0 +1,71 @@ +/* + * Copyright 2005-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 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; + +public class SymbolArchive extends ZipArchive { + + final File origFile; + final String prefix; + + public SymbolArchive(JavacFileManager fileManager, File orig, ZipFile zdir, String prefix) throws IOException { + super(fileManager, zdir); + this.origFile = orig; + this.prefix = prefix; + } + + @Override + void addZipEntry(ZipEntry entry) { + String name = entry.getName(); + if (!name.startsWith(prefix)) { + return; + } + name = name.substring(prefix.length()); + int i = name.lastIndexOf('/'); + String dirname = name.substring(0, i + 1); + String basename = name.substring(i + 1); + if (basename.length() == 0) { + return; + } + List list = map.get(dirname); + if (list == null) { + list = List.nil(); + } + list = list.prepend(basename); + map.put(dirname, list); + } + + @Override + public JavaFileObject getFileObject(String subdirectory, String file) { + return super.getFileObject(prefix + subdirectory, file); + } +} diff --git a/src/share/classes/com/sun/tools/javac/file/ZipArchive.java b/src/share/classes/com/sun/tools/javac/file/ZipArchive.java new file mode 100644 index 0000000000000000000000000000000000000000..b59bdd4aa5eb98324a9151ac06658cb9dccec989 --- /dev/null +++ b/src/share/classes/com/sun/tools/javac/file/ZipArchive.java @@ -0,0 +1,234 @@ +/* + * Copyright 2005-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.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; +import java.net.URI; +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.charset.CharsetDecoder; + +public class ZipArchive implements Archive { + + public ZipArchive(JavacFileManager fm, ZipFile zdir) throws IOException { + this.fileManager = fm; + this.zdir = zdir; + this.map = new HashMap>(); + for (Enumeration e = zdir.entries(); e.hasMoreElements(); ) { + ZipEntry entry; + try { + entry = e.nextElement(); + } catch (InternalError ex) { + IOException io = new IOException(); + io.initCause(ex); // convenience constructors added in Mustang :-( + throw io; + } + addZipEntry(entry); + } + } + + void addZipEntry(ZipEntry entry) { + String name = entry.getName(); + int i = name.lastIndexOf('/'); + String dirname = name.substring(0, i+1); + String basename = name.substring(i+1); + if (basename.length() == 0) + return; + List list = map.get(dirname); + if (list == null) + list = List.nil(); + list = list.prepend(basename); + map.put(dirname, list); + } + + public boolean contains(String name) { + int i = name.lastIndexOf('/'); + String dirname = name.substring(0, i+1); + String basename = name.substring(i+1); + if (basename.length() == 0) + return false; + List list = map.get(dirname); + return (list != null && list.contains(basename)); + } + + public List getFiles(String subdirectory) { + return map.get(subdirectory); + } + + public JavaFileObject getFileObject(String subdirectory, String file) { + ZipEntry ze = zdir.getEntry(subdirectory + file); + return new ZipFileObject(this, file, ze); + } + + public Set getSubdirectories() { + return map.keySet(); + } + + public void close() throws IOException { + zdir.close(); + } + + protected JavacFileManager fileManager; + protected final Map> map; + protected final ZipFile zdir; + + /** + * A subclass of JavaFileObject representing zip entries. + */ + public static class ZipFileObject extends BaseFileObject { + + private String name; + ZipArchive zarch; + ZipEntry entry; + + public ZipFileObject(ZipArchive zarch, String name, ZipEntry entry) { + super(zarch.fileManager); + this.zarch = zarch; + this.name = name; + this.entry = entry; + } + + public InputStream openInputStream() throws IOException { + return zarch.zdir.getInputStream(entry); + } + + public OutputStream openOutputStream() throws IOException { + throw new UnsupportedOperationException(); + } + + protected CharsetDecoder getDecoder(boolean ignoreEncodingErrors) { + return fileManager.getDecoder(fileManager.getEncodingName(), ignoreEncodingErrors); + } + + public Writer openWriter() throws IOException { + throw new UnsupportedOperationException(); + } + + @Deprecated + public String getName() { + return name; + } + + public boolean isNameCompatible(String cn, JavaFileObject.Kind k) { + cn.getClass(); + // null check + if (k == Kind.OTHER && getKind() != k) { + return false; + } + return name.equals(cn + k.extension); + } + + @Deprecated + public String getPath() { + return zarch.zdir.getName() + "(" + entry + ")"; + } + + public long getLastModified() { + return entry.getTime(); + } + + public boolean delete() { + throw new UnsupportedOperationException(); + } + + public CharBuffer getCharContent(boolean ignoreEncodingErrors) throws IOException { + CharBuffer cb = fileManager.getCachedContent(this); + if (cb == null) { + InputStream in = zarch.zdir.getInputStream(entry); + try { + ByteBuffer bb = fileManager.makeByteBuffer(in); + JavaFileObject prev = fileManager.log.useSource(this); + try { + cb = fileManager.decode(bb, ignoreEncodingErrors); + } finally { + fileManager.log.useSource(prev); + } + fileManager.recycleByteBuffer(bb); + if (!ignoreEncodingErrors) { + fileManager.cache(this, cb); + } + } finally { + in.close(); + } + } + return cb; + } + + @Override + public boolean equals(Object other) { + if (!(other instanceof ZipFileObject)) { + return false; + } + ZipFileObject o = (ZipFileObject) other; + return zarch.zdir.equals(o.zarch.zdir) || name.equals(o.name); + } + + @Override + public int hashCode() { + return zarch.zdir.hashCode() + name.hashCode(); + } + + public String getZipName() { + return zarch.zdir.getName(); + } + + public String getZipEntryName() { + return entry.getName(); + } + + public URI toUri() { + String zipName = new File(getZipName()).toURI().normalize().getPath(); + String entryName = getZipEntryName(); + return URI.create("jar:" + zipName + "!" + entryName); + } + + @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 --git a/src/share/classes/com/sun/tools/javac/file/ZipFileIndex.java b/src/share/classes/com/sun/tools/javac/file/ZipFileIndex.java index 89e31523ec222cc0e2595683922f33c5a490f957..d677e2b603b6fe5e1b130ef81d1ea976fe502e44 100644 --- a/src/share/classes/com/sun/tools/javac/file/ZipFileIndex.java +++ b/src/share/classes/com/sun/tools/javac/file/ZipFileIndex.java @@ -81,11 +81,12 @@ public class ZipFileIndex { private File zipFile; private long zipFileLastModified = NOT_MODIFIED; private RandomAccessFile zipRandomFile; - private ZipFileIndexEntry[] entries; + private Entry[] entries; private boolean readFromIndex = false; private File zipIndexFile = null; private boolean triedToReadIndex = false; + final String symbolFilePrefix; private int symbolFilePrefixLength = 0; private boolean hasPopulatedData = false; private long lastReferenceTimeStamp = NOT_MODIFIED; @@ -141,14 +142,14 @@ public class ZipFileIndex { } } - public static ZipFileIndex getZipFileIndex(File zipFile, int symbolFilePrefixLen, boolean useCache, String cacheLocation, boolean writeIndex) throws IOException { + public static ZipFileIndex getZipFileIndex(File zipFile, String symbolFilePrefix, boolean useCache, String cacheLocation, boolean writeIndex) throws IOException { ZipFileIndex zi = null; lock.lock(); try { zi = getExistingZipIndex(zipFile); if (zi == null || (zi != null && zipFile.lastModified() != zi.zipFileLastModified)) { - zi = new ZipFileIndex(zipFile, symbolFilePrefixLen, writeIndex, + zi = new ZipFileIndex(zipFile, symbolFilePrefix, writeIndex, useCache, cacheLocation); zipFileIndexCache.put(zipFile, zi); } @@ -229,10 +230,12 @@ public class ZipFileIndex { } } - private ZipFileIndex(File zipFile, int symbolFilePrefixLen, boolean writeIndex, + private ZipFileIndex(File zipFile, String symbolFilePrefix, boolean writeIndex, boolean useCache, String cacheLocation) throws IOException { this.zipFile = zipFile; - this.symbolFilePrefixLength = symbolFilePrefixLen; + this.symbolFilePrefix = symbolFilePrefix; + this.symbolFilePrefixLength = (symbolFilePrefix == null ? 0 : + symbolFilePrefix.getBytes("UTF-8").length); this.writeIndex = writeIndex; this.usePreindexedCache = useCache; this.preindexedCacheLocation = cacheLocation; @@ -312,7 +315,7 @@ public class ZipFileIndex { private void cleanupState() { // Make sure there is a valid but empty index if the file doesn't exist - entries = ZipFileIndexEntry.EMPTY_ARRAY; + entries = Entry.EMPTY_ARRAY; directories = Collections.emptyMap(); zipFileLastModified = NOT_MODIFIED; allDirs = Collections.emptySet(); @@ -342,7 +345,7 @@ public class ZipFileIndex { /** * Returns the ZipFileIndexEntry for an absolute path, if there is one. */ - public ZipFileIndexEntry getZipIndexEntry(String path) { + Entry getZipIndexEntry(String path) { if (File.separatorChar != '/') { path = path.replace('/', File.separatorChar); } @@ -493,7 +496,7 @@ public class ZipFileIndex { public long getLastModified(String path) throws IOException { lock.lock(); try { - ZipFileIndexEntry entry = getZipIndexEntry(path); + Entry entry = getZipIndexEntry(path); if (entry == null) throw new FileNotFoundException(); return entry.getLastModified(); @@ -506,7 +509,7 @@ public class ZipFileIndex { public int length(String path) throws IOException { lock.lock(); try { - ZipFileIndexEntry entry = getZipIndexEntry(path); + Entry entry = getZipIndexEntry(path); if (entry == null) throw new FileNotFoundException(); @@ -530,7 +533,7 @@ public class ZipFileIndex { public byte[] read(String path) throws IOException { lock.lock(); try { - ZipFileIndexEntry entry = getZipIndexEntry(path); + Entry entry = getZipIndexEntry(path); if (entry == null) throw new FileNotFoundException(MessageFormat.format("Path not found in ZIP: {0}", path)); return read(entry); @@ -540,7 +543,7 @@ public class ZipFileIndex { } } - public byte[] read(ZipFileIndexEntry entry) throws IOException { + byte[] read(Entry entry) throws IOException { lock.lock(); try { openFile(); @@ -556,7 +559,7 @@ public class ZipFileIndex { public int read(String path, byte[] buffer) throws IOException { lock.lock(); try { - ZipFileIndexEntry entry = getZipIndexEntry(path); + Entry entry = getZipIndexEntry(path); if (entry == null) throw new FileNotFoundException(); return read(entry, buffer); @@ -566,7 +569,7 @@ public class ZipFileIndex { } } - public int read(ZipFileIndexEntry entry, byte[] buffer) + int read(Entry entry, byte[] buffer) throws IOException { lock.lock(); try { @@ -578,7 +581,7 @@ public class ZipFileIndex { } } - private byte[] readBytes(ZipFileIndexEntry entry) throws IOException { + private byte[] readBytes(Entry entry) throws IOException { byte[] header = getHeader(entry); int csize = entry.compressedSize; byte[] cbuf = new byte[csize]; @@ -600,7 +603,7 @@ public class ZipFileIndex { /** * */ - private int readBytes(ZipFileIndexEntry entry, byte[] buffer) throws IOException { + private int readBytes(Entry entry, byte[] buffer) throws IOException { byte[] header = getHeader(entry); // entry is not compressed? @@ -633,7 +636,7 @@ public class ZipFileIndex { // Zip utilities //---------------------------------------------------------------------------- - private byte[] getHeader(ZipFileIndexEntry entry) throws IOException { + private byte[] getHeader(Entry entry) throws IOException { zipRandomFile.seek(entry.offset); byte[] header = new byte[30]; zipRandomFile.readFully(header); @@ -746,11 +749,11 @@ public class ZipFileIndex { private void buildIndex() throws IOException { int entryCount = get2ByteLittleEndian(zipDir, 0); - entries = new ZipFileIndexEntry[entryCount]; + entries = new Entry[entryCount]; // Add each of the files if (entryCount > 0) { directories = new HashMap(); - ArrayList entryList = new ArrayList(); + ArrayList entryList = new ArrayList(); int pos = 2; for (int i = 0; i < entryCount; i++) { pos = readEntry(pos, entryList, directories); @@ -759,19 +762,19 @@ public class ZipFileIndex { // Add the accumulated dirs into the same list Iterator i = directories.keySet().iterator(); while (i.hasNext()) { - ZipFileIndexEntry zipFileIndexEntry = new ZipFileIndexEntry( (String) i.next()); + Entry zipFileIndexEntry = new Entry( (String) i.next()); zipFileIndexEntry.isDir = true; entryList.add(zipFileIndexEntry); } - entries = entryList.toArray(new ZipFileIndexEntry[entryList.size()]); + entries = entryList.toArray(new Entry[entryList.size()]); Arrays.sort(entries); } else { cleanupState(); } } - private int readEntry(int pos, List entryList, + private int readEntry(int pos, List entryList, Map directories) throws IOException { if (get4ByteLittleEndian(zipDir, pos) != 0x02014b50) { throw new ZipException("cannot read zip file entry"); @@ -838,7 +841,7 @@ public class ZipFileIndex { // For each dir create also a file if (fileStart != fileEnd) { - ZipFileIndexEntry entry = new ZipFileIndexEntry(directory, + Entry entry = new Entry(directory, new String(zipDir, fileStart, fileEnd - fileStart, "UTF-8")); entry.setNativeTime(get4ByteLittleEndian(zipDir, pos + 12)); @@ -873,6 +876,7 @@ public class ZipFileIndex { /** ------------------------------------------------------------------------ * DirectoryEntry class * -------------------------------------------------------------------------*/ + static class DirectoryEntry { private boolean filesInited; private boolean directoriesInited; @@ -885,9 +889,9 @@ public class ZipFileIndex { 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(); - private com.sun.tools.javac.util.List zipFileEntries = com.sun.tools.javac.util.List.nil(); + private com.sun.tools.javac.util.List zipFileEntries = com.sun.tools.javac.util.List.nil(); - private List entries = new ArrayList(); + private List entries = new ArrayList(); private ZipFileIndex zipFileIndex; @@ -916,7 +920,7 @@ public class ZipFileIndex { initEntries(); - for (ZipFileIndexEntry e : entries) { + for (Entry e : entries) { if (!e.isDir) { zipFileEntriesFiles = zipFileEntriesFiles.append(e.name); } @@ -932,7 +936,7 @@ public class ZipFileIndex { initEntries(); - for (ZipFileIndexEntry e : entries) { + for (Entry e : entries) { if (e.isDir) { zipFileEntriesDirectories = zipFileEntriesDirectories.append(e.name); } @@ -943,7 +947,7 @@ public class ZipFileIndex { return zipFileEntriesDirectories; } - private com.sun.tools.javac.util.List getEntries() { + private com.sun.tools.javac.util.List getEntries() { if (zipFileEntriesInited) { return zipFileEntries; } @@ -951,7 +955,7 @@ public class ZipFileIndex { initEntries(); zipFileEntries = com.sun.tools.javac.util.List.nil(); - for (ZipFileIndexEntry zfie : entries) { + for (Entry zfie : entries) { zipFileEntries = zipFileEntries.append(zfie); } @@ -960,9 +964,9 @@ public class ZipFileIndex { return zipFileEntries; } - private ZipFileIndexEntry getEntry(String rootName) { + private Entry getEntry(String rootName) { initEntries(); - int index = Collections.binarySearch(entries, new ZipFileIndexEntry(dirName, rootName)); + int index = Collections.binarySearch(entries, new Entry(dirName, rootName)); if (index < 0) { return null; } @@ -977,9 +981,9 @@ public class ZipFileIndex { if (!zipFileIndex.readFromIndex) { int from = -Arrays.binarySearch(zipFileIndex.entries, - new ZipFileIndexEntry(dirName, ZipFileIndex.MIN_CHAR)) - 1; + new Entry(dirName, ZipFileIndex.MIN_CHAR)) - 1; int to = -Arrays.binarySearch(zipFileIndex.entries, - new ZipFileIndexEntry(dirName, MAX_CHAR)) - 1; + new Entry(dirName, MAX_CHAR)) - 1; boolean emptyList = false; @@ -1016,7 +1020,7 @@ public class ZipFileIndex { // Read java time stamp of the file in the real Jar/Zip file long eJavaTimestamp = raf.readLong(); - ZipFileIndexEntry rfie = new ZipFileIndexEntry(dirName, eName); + Entry rfie = new Entry(dirName, eName); rfie.isDir = eIsDir; rfie.offset = eOffset; rfie.size = eSize; @@ -1041,7 +1045,7 @@ public class ZipFileIndex { entriesInited = true; } - List getEntriesAsCollection() { + List getEntriesAsCollection() { initEntries(); return entries; @@ -1173,8 +1177,8 @@ public class ZipFileIndex { raf.seek(currFP); // Now write each of the files in the DirectoryEntry - List entries = de.getEntriesAsCollection(); - for (ZipFileIndexEntry zfie : entries) { + List entries = de.getEntriesAsCollection(); + for (Entry zfie : entries) { // Write the name bytes byte [] zfieNameBytes = zfie.name.getBytes("UTF-8"); int zfieNameBytesLen = zfieNameBytes.length; @@ -1245,4 +1249,94 @@ public class ZipFileIndex { public File getZipFile() { return zipFile; } + + + static class Entry implements Comparable { + public static final Entry[] EMPTY_ARRAY = {}; + + // Directory related + String dir; + boolean isDir; + + // File related + String name; + + int offset; + int size; + int compressedSize; + long javatime; + + 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(String directory, String name) { + this.dir = directory.intern(); + 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(); + } + + public String getFileName() { + return name; + } + + public long getLastModified() { + if (javatime == 0) { + javatime = dosToJavaTime(nativetime); + } + return javatime; + } + + // From java.util.zip + private static long dosToJavaTime(int nativetime) { + // Bootstrap build problems prevent me from using the code directly + // Convert the raw/native time to a long for now + return (long)nativetime; + } + + void setNativeTime(int natTime) { + nativetime = natTime; + } + + public boolean isDirectory() { + return isDir; + } + + public int compareTo(Entry other) { + String otherD = other.dir; + if (dir != otherD) { + int c = dir.compareTo(otherD); + if (c != 0) + return c; + } + return name.compareTo(other.name); + } + + + public String toString() { + return isDir ? ("Dir:" + dir + " : " + name) : + (dir + ":" + name); + } + } + } diff --git a/src/share/classes/com/sun/tools/javac/file/ZipFileIndexArchive.java b/src/share/classes/com/sun/tools/javac/file/ZipFileIndexArchive.java new file mode 100644 index 0000000000000000000000000000000000000000..8fa789662ef5f1fefa69260e1fbd7ffa2b8690b5 --- /dev/null +++ b/src/share/classes/com/sun/tools/javac/file/ZipFileIndexArchive.java @@ -0,0 +1,233 @@ +/* + * Copyright 2005-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.IOException; +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; +import java.net.URI; +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.charset.CharsetDecoder; + +public class ZipFileIndexArchive implements Archive { + + private final ZipFileIndex zfIndex; + private JavacFileManager fileManager; + + public ZipFileIndexArchive(JavacFileManager fileManager, ZipFileIndex zdir) throws IOException { + super(); + this.fileManager = fileManager; + this.zfIndex = zdir; + } + + public boolean contains(String 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 JavaFileObject getFileObject(String subdirectory, String file) { + String fullZipFileName = subdirectory + file; + ZipFileIndex.Entry entry = zfIndex.getZipIndexEntry(fullZipFileName); + JavaFileObject ret = new ZipFileIndexFileObject(fileManager, zfIndex, entry, zfIndex.getZipFile().getPath()); + return ret; + } + + public Set getSubdirectories() { + return zfIndex.getAllDirectories(); + } + + public void close() throws IOException { + zfIndex.close(); + } + + /** + * A subclass of JavaFileObject representing zip entries using the com.sun.tools.javac.file.ZipFileIndex implementation. + */ + public static class ZipFileIndexFileObject extends BaseFileObject { + + /** The entry's name. + */ + private String name; + + /** The zipfile containing the entry. + */ + ZipFileIndex zfIndex; + + /** The underlying zip entry object. + */ + ZipFileIndex.Entry entry; + + /** The InputStream for this zip entry (file.) + */ + InputStream inputStream = null; + + /** The name of the zip file where this entry resides. + */ + String zipName; + + + ZipFileIndexFileObject(JavacFileManager fileManager, ZipFileIndex zfIndex, ZipFileIndex.Entry entry, String zipFileName) { + super(fileManager); + this.name = entry.getFileName(); + this.zfIndex = zfIndex; + this.entry = entry; + this.zipName = zipFileName; + } + + public InputStream openInputStream() throws IOException { + + if (inputStream == null) { + inputStream = new ByteArrayInputStream(read()); + } + return inputStream; + } + + protected CharsetDecoder getDecoder(boolean ignoreEncodingErrors) { + return fileManager.getDecoder(fileManager.getEncodingName(), ignoreEncodingErrors); + } + + public OutputStream openOutputStream() throws IOException { + throw new UnsupportedOperationException(); + } + + public Writer openWriter() throws IOException { + throw new UnsupportedOperationException(); + } + + /** @deprecated see bug 6410637 */ + @Deprecated + public String getName() { + return name; + } + + public boolean isNameCompatible(String cn, JavaFileObject.Kind k) { + cn.getClass(); // null check + if (k == Kind.OTHER && getKind() != k) + return false; + return name.equals(cn + k.extension); + } + + /** @deprecated see bug 6410637 */ + @Deprecated + public String getPath() { + return zipName + "(" + entry.getName() + ")"; + } + + public long getLastModified() { + return entry.getLastModified(); + } + + public boolean delete() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean equals(Object other) { + if (!(other instanceof ZipFileIndexFileObject)) + return false; + ZipFileIndexFileObject o = (ZipFileIndexFileObject) other; + return entry.equals(o.entry); + } + + @Override + public int hashCode() { + return zipName.hashCode() + (name.hashCode() << 10); + } + + public String getZipName() { + return zipName; + } + + public String getZipEntryName() { + return entry.getName(); + } + + 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(); + } + return zfIndex.read(entry); + } + + public CharBuffer getCharContent(boolean ignoreEncodingErrors) throws IOException { + CharBuffer cb = fileManager.getCachedContent(this); + if (cb == null) { + InputStream in = new ByteArrayInputStream(zfIndex.read(entry)); + try { + ByteBuffer bb = fileManager.makeByteBuffer(in); + JavaFileObject prev = fileManager.log.useSource(this); + try { + cb = fileManager.decode(bb, ignoreEncodingErrors); + } finally { + fileManager.log.useSource(prev); + } + fileManager.recycleByteBuffer(bb); // save for next time + if (!ignoreEncodingErrors) + fileManager.cache(this, cb); + } finally { + in.close(); + } + } + return cb; + } + + @Override + protected String inferBinaryName(Iterable path) { + String entryName = getZipEntryName(); + if (zfIndex.symbolFilePrefix != null) { + String prefix = zfIndex.symbolFilePrefix; + if (entryName.startsWith(prefix)) + entryName = entryName.substring(prefix.length()); + } + return removeExtension(entryName).replace(File.separatorChar, '.'); + } + } + +} diff --git a/src/share/classes/com/sun/tools/javac/file/ZipFileIndexEntry.java b/src/share/classes/com/sun/tools/javac/file/ZipFileIndexEntry.java deleted file mode 100644 index 17b851a8dcfb6a1f7aa47b09010449b8a19f52a6..0000000000000000000000000000000000000000 --- a/src/share/classes/com/sun/tools/javac/file/ZipFileIndexEntry.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright 2007-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; - -public final class ZipFileIndexEntry implements Comparable { - public static final ZipFileIndexEntry[] EMPTY_ARRAY = {}; - - // Directory related - String dir; - boolean isDir; - - // File related - String name; - - int offset; - int size; - int compressedSize; - long javatime; - - private int nativetime; - - public ZipFileIndexEntry(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 ZipFileIndexEntry(String directory, String name) { - this.dir = directory.intern(); - 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(); - } - - public String getFileName() { - return name; - } - - public long getLastModified() { - if (javatime == 0) { - javatime = dosToJavaTime(nativetime); - } - return javatime; - } - - // From java.util.zip - private static long dosToJavaTime(int nativetime) { - // Bootstrap build problems prevent me from using the code directly - // Convert the raw/native time to a long for now - return (long)nativetime; - } - - void setNativeTime(int natTime) { - nativetime = natTime; - } - - public boolean isDirectory() { - return isDir; - } - - public int compareTo(ZipFileIndexEntry other) { - String otherD = other.dir; - if (dir != otherD) { - int c = dir.compareTo(otherD); - if (c != 0) - return c; - } - return name.compareTo(other.name); - } - - - public String toString() { - return isDir ? ("Dir:" + dir + " : " + name) : - (dir + ":" + name); - } -} diff --git a/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java b/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java index 5d054d860bb8a71235abbb92559350d4f2056771..5bce482929ac5e5cacfa788cad5a1113238b2af2 100644 --- a/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java +++ b/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java @@ -1056,7 +1056,7 @@ public class ClassReader extends ClassFile implements Completer { void readClassAttr(ClassSymbol c, Name attrName, int attrLen) { if (attrName == names.SourceFile) { Name n = readName(nextChar()); - c.sourcefile = new SourceFileObject(n); + c.sourcefile = new SourceFileObject(n, c.flatname); } else if (attrName == names.InnerClasses) { readInnerClasses(c); } else if (allowGenerics && attrName == names.Signature) { @@ -2221,9 +2221,12 @@ public class ClassReader extends ClassFile implements Completer { /** The file's name. */ private Name name; + private Name flatname; - public SourceFileObject(Name name) { + public SourceFileObject(Name name, Name flatname) { + super(null); // no file manager; never referenced for this file object this.name = name; + this.flatname = flatname; } public InputStream openInputStream() { @@ -2285,5 +2288,9 @@ public class ClassReader extends ClassFile implements Completer { throw new UnsupportedOperationException(); } + @Override + protected String inferBinaryName(Iterable path) { + return flatname.toString(); + } } } diff --git a/src/share/classes/com/sun/tools/javadoc/JavadocClassReader.java b/src/share/classes/com/sun/tools/javadoc/JavadocClassReader.java index 1ce38332a933e95cceea977444c7db063cd7759c..13fc01b708079ea5aba0e0b0bee501536180da06 100644 --- a/src/share/classes/com/sun/tools/javadoc/JavadocClassReader.java +++ b/src/share/classes/com/sun/tools/javadoc/JavadocClassReader.java @@ -27,7 +27,9 @@ package com.sun.tools.javadoc; import com.sun.tools.javac.code.Symbol.PackageSymbol; import com.sun.tools.javac.file.JavacFileManager; +import com.sun.tools.javac.file.ZipArchive.ZipFileObject; import com.sun.tools.javac.file.Old199; +import com.sun.tools.javac.file.ZipFileIndexArchive; import com.sun.tools.javac.jvm.ClassReader; import com.sun.tools.javac.util.Context; @@ -82,16 +84,16 @@ class JavadocClassReader extends ClassReader { protected void extraFileActions(PackageSymbol pack, JavaFileObject fo) { CharSequence fileName = Old199.getName(fo); if (docenv != null && fileName.equals("package.html")) { - if (fo instanceof JavacFileManager.ZipFileObject) { - JavacFileManager.ZipFileObject zfo = (JavacFileManager.ZipFileObject) fo; + if (fo instanceof ZipFileObject) { + ZipFileObject zfo = (ZipFileObject) fo; String zipName = zfo.getZipName(); String entryName = zfo.getZipEntryName(); int lastSep = entryName.lastIndexOf("/"); String classPathName = entryName.substring(0, lastSep + 1); docenv.getPackageDoc(pack).setDocPath(zipName, classPathName); } - else if (fo instanceof JavacFileManager.ZipFileIndexFileObject) { - JavacFileManager.ZipFileIndexFileObject zfo = (JavacFileManager.ZipFileIndexFileObject) fo; + else if (fo instanceof ZipFileIndexArchive.ZipFileIndexFileObject) { + ZipFileIndexArchive.ZipFileIndexFileObject zfo = (ZipFileIndexArchive.ZipFileIndexFileObject) fo; String zipName = zfo.getZipName(); String entryName = zfo.getZipEntryName(); if (File.separatorChar != '/') {