8059976: Convert JavacFileManager to use java.nio.file internally

Reviewed-by: jlahoda
This commit is contained in:
Jonathan Gibbons 2015-12-07 14:02:55 -08:00
parent 4297432f73
commit 31cdc1ad3d
34 changed files with 688 additions and 2902 deletions

View File

@ -343,7 +343,7 @@ public class ClassFinder {
}
currentClassFile = classfile;
if (verbose) {
log.printVerbose("loading", currentClassFile.toString());
log.printVerbose("loading", currentClassFile.getName());
}
if (classfile.getKind() == JavaFileObject.Kind.CLASS ||
classfile.getKind() == JavaFileObject.Kind.OTHER) {

View File

@ -1,131 +0,0 @@
/*
* Copyright (c) 2005, 2014, Oracle and/or its affiliates. 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.javac.file;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.CharsetDecoder;
import java.nio.file.Path;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.NestingKind;
import javax.tools.FileObject;
import javax.tools.JavaFileObject;
import com.sun.tools.javac.util.DefinedBy;
import com.sun.tools.javac.util.DefinedBy.Api;
/**
* <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own risk.
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*/
public abstract class BaseFileObject implements JavaFileObject {
protected BaseFileObject(JavacFileManager fileManager) {
this.fileManager = fileManager;
}
/** Return a short name for the object, such as for use in raw diagnostics
*/
public abstract String getShortName();
@Override
public String toString() {
return getClass().getSimpleName() + "[" + getName() + "]";
}
@DefinedBy(Api.COMPILER)
public NestingKind getNestingKind() { return null; }
@DefinedBy(Api.COMPILER)
public Modifier getAccessLevel() { return null; }
@DefinedBy(Api.COMPILER)
public Reader openReader(boolean ignoreEncodingErrors) throws IOException {
return new InputStreamReader(openInputStream(), getDecoder(ignoreEncodingErrors));
}
protected CharsetDecoder getDecoder(boolean ignoreEncodingErrors) {
throw new UnsupportedOperationException();
}
protected abstract String inferBinaryName(Iterable<? extends Path> path);
protected static JavaFileObject.Kind getKind(String filename) {
return BaseFileManager.getKind(filename);
}
protected static String removeExtension(String fileName) {
int lastDot = fileName.lastIndexOf(".");
return (lastDot == -1 ? fileName : fileName.substring(0, lastDot));
}
protected static URI createJarUri(Path jarFile, String entryName) {
URI jarURI = jarFile.toUri().normalize();
String separator = entryName.startsWith("/") ? "!" : "!/";
try {
// The jar URI convention appears to be not to re-encode the jarURI
return new URI("jar:" + jarURI + separator + entryName);
} catch (URISyntaxException e) {
throw new CannotCreateUriError(jarURI + separator + entryName, e);
}
}
/** Used when URLSyntaxException is thrown unexpectedly during
* implementations of (Base)FileObject.toURI(). */
protected static class CannotCreateUriError extends Error {
private static final long serialVersionUID = 9101708840997613546L;
public CannotCreateUriError(String value, Throwable cause) {
super(value, cause);
}
}
/** Return the last component of a presumed hierarchical URI.
* From the scheme specific part of the URI, it returns the substring
* after the last "/" if any, or everything if no "/" is found.
*/
public static String getSimpleName(FileObject fo) {
URI uri = fo.toUri();
String s = uri.getSchemeSpecificPart();
return s.substring(s.lastIndexOf("/") + 1); // safe when / not found
}
// force subtypes to define equals
@Override
public abstract boolean equals(Object other);
// force subtypes to define hashCode
@Override
public abstract int hashCode();
/** The file manager that created this JavaFileObject. */
protected final JavacFileManager fileManager;
}

View File

@ -48,7 +48,7 @@ public class FSInfo {
try {
return file.toRealPath();
} catch (IOException e) {
return file.toAbsolutePath();
return file.toAbsolutePath().normalize();
}
}

View File

@ -200,7 +200,7 @@ public class JRTIndex {
if (Files.exists(dir)) {
try (DirectoryStream<Path> modules = Files.newDirectoryStream(dir)) {
for (Path module: modules) {
Path p = rd.getFile(module);
Path p = rd.resolveAgainst(module);
if (!Files.exists(p))
continue;
try (DirectoryStream<Path> stream = Files.newDirectoryStream(p)) {

View File

@ -26,7 +26,6 @@
package com.sun.tools.javac.file;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI;
@ -34,16 +33,20 @@ import java.net.URISyntaxException;
import java.net.URL;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.FileVisitOption;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import java.nio.file.LinkOption;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.EnumSet;
import java.util.HashMap;
@ -53,7 +56,6 @@ import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.zip.ZipFile;
import javax.lang.model.SourceVersion;
import javax.tools.FileObject;
@ -69,6 +71,8 @@ import com.sun.tools.javac.util.DefinedBy.Api;
import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.ListBuffer;
import static java.nio.file.FileVisitOption.FOLLOW_LINKS;
import static javax.tools.StandardLocation.*;
/**
@ -92,9 +96,6 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
private FSInfo fsInfo;
private boolean contextUseOptimizedZip;
private ZipFileIndexCache zipFileIndexCache;
private final Set<JavaFileObject.Kind> sourceOrClass =
EnumSet.of(JavaFileObject.Kind.SOURCE, JavaFileObject.Kind.CLASS);
@ -149,10 +150,6 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
fsInfo = FSInfo.instance(context);
contextUseOptimizedZip = options.getBoolean("useOptimizedZip", true);
if (contextUseOptimizedZip)
zipFileIndexCache = ZipFileIndexCache.getSharedInstance();
symbolFileEnabled = !options.isSet("ignore.symbol.file");
String sf = options.get("sortFiles");
@ -173,13 +170,13 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
}
// used by tests
public JavaFileObject getFileForInput(String name) {
return getRegularFile(Paths.get(name));
public JavaFileObject getJavaFileObject(String name) {
return getJavaFileObjects(name).iterator().next();
}
// used by tests
public JavaFileObject getRegularFile(Path file) {
return new RegularFileObject(this, file);
public JavaFileObject getJavaFileObject(Path file) {
return getJavaFileObjects(file).iterator().next();
}
public JavaFileObject getFileForOutput(String classname,
@ -277,7 +274,7 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
for (Path file: e.files.values()) {
if (fileKinds.contains(getKind(file))) {
JavaFileObject fe
= PathFileObject.createJRTPathFileObject(JavacFileManager.this, file);
= PathFileObject.forJRTPath(JavacFileManager.this, file);
resultList.append(fe);
}
}
@ -302,14 +299,14 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
* Insert all files in subdirectory subdirectory of directory directory
* which match fileKinds into resultList
*/
private void listDirectory(Path directory,
private void listDirectory(Path directory, Path realDirectory,
RelativeDirectory subdirectory,
Set<JavaFileObject.Kind> fileKinds,
boolean recurse,
ListBuffer<JavaFileObject> resultList) {
Path d;
try {
d = subdirectory.getFile(directory);
d = subdirectory.resolveAgainst(directory);
} catch (InvalidPathException ignore) {
return;
}
@ -329,13 +326,16 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
return;
}
if (realDirectory == null)
realDirectory = fsInfo.getCanonicalFile(directory);
for (Path f: files) {
String fname = f.getFileName().toString();
if (fname.endsWith("/"))
fname = fname.substring(0, fname.length() - 1);
if (Files.isDirectory(f)) {
if (recurse && SourceVersion.isIdentifier(fname)) {
listDirectory(directory,
listDirectory(directory, realDirectory,
new RelativeDirectory(subdirectory, fname),
fileKinds,
recurse,
@ -343,8 +343,9 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
}
} else {
if (isValidFile(fname, fileKinds)) {
JavaFileObject fe =
new RegularFileObject(this, fname, d.resolve(fname));
RelativeFile file = new RelativeFile(subdirectory, fname);
JavaFileObject fe = PathFileObject.forDirectoryPath(this,
file.resolveAgainst(realDirectory), directory, file);
resultList.append(fe);
}
}
@ -352,34 +353,61 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
}
/**
* Insert all files in subdirectory subdirectory of archive archive
* Insert all files in subdirectory subdirectory of archive archivePath
* which match fileKinds into resultList
*/
private void listArchive(Archive archive,
RelativeDirectory subdirectory,
Set<JavaFileObject.Kind> fileKinds,
boolean recurse,
ListBuffer<JavaFileObject> resultList) {
// Get the files directly in the subdir
List<String> files = archive.getFiles(subdirectory);
if (files != null) {
for (; !files.isEmpty(); files = files.tail) {
String file = files.head;
if (isValidFile(file, fileKinds)) {
resultList.append(archive.getFileObject(subdirectory, file));
}
}
private void listArchive(Path archivePath,
RelativeDirectory subdirectory,
Set<JavaFileObject.Kind> fileKinds,
boolean recurse,
ListBuffer<JavaFileObject> resultList)
throws IOException {
FileSystem fs = getFileSystem(archivePath);
if (fs == null) {
return;
}
if (recurse) {
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.
listArchive(archive, s, fileKinds, false, resultList);
}
}
Path containerSubdir = subdirectory.resolveAgainst(fs);
if (!Files.exists(containerSubdir)) {
return;
}
int maxDepth = (recurse ? Integer.MAX_VALUE : 1);
Set<FileVisitOption> opts = EnumSet.of(FOLLOW_LINKS);
Files.walkFileTree(containerSubdir, opts, maxDepth,
new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
if (isValid(dir.getFileName())) {
return FileVisitResult.CONTINUE;
} else {
return FileVisitResult.SKIP_SUBTREE;
}
}
boolean isValid(Path fileName) {
if (fileName == null) {
return true;
} else {
String name = fileName.toString();
if (name.endsWith("/")) {
name = name.substring(0, name.length() - 1);
}
return SourceVersion.isIdentifier(name);
}
}
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
if (attrs.isRegularFile() && fileKinds.contains(getKind(file.getFileName().toString()))) {
JavaFileObject fe = PathFileObject.forJarPath(
JavacFileManager.this, file, archivePath);
resultList.append(fe);
}
return FileVisitResult.CONTINUE;
}
});
}
/**
@ -391,54 +419,46 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
RelativeDirectory subdirectory,
Set<JavaFileObject.Kind> fileKinds,
boolean recurse,
ListBuffer<JavaFileObject> resultList) {
Archive archive = archives.get(container);
if (archive == null) {
// Very temporary and obnoxious interim hack
if (container.endsWith("bootmodules.jimage")) {
System.err.println("Warning: reference to bootmodules.jimage replaced by jrt:");
container = Locations.JRT_MARKER_FILE;
} else if (container.getFileName().toString().endsWith(".jimage")) {
System.err.println("Warning: reference to " + container + " ignored");
return;
}
// archives are not created for directories or jrt: images
if (container == Locations.JRT_MARKER_FILE) {
try {
listJRTImage(subdirectory,
fileKinds,
recurse,
resultList);
} catch (IOException ex) {
ex.printStackTrace(System.err);
log.error("error.reading.file", container, getMessage(ex));
}
return;
}
if (fsInfo.isDirectory(container)) {
listDirectory(container,
subdirectory,
fileKinds,
recurse,
resultList);
return;
}
// Not a directory; either a file or non-existant, create the archive
try {
archive = openArchive(container);
} catch (IOException ex) {
log.error("error.reading.file", container, getMessage(ex));
return;
}
ListBuffer<JavaFileObject> resultList)
throws IOException {
// Very temporary and obnoxious interim hack
if (container.endsWith("bootmodules.jimage")) {
System.err.println("Warning: reference to bootmodules.jimage replaced by jrt:");
container = Locations.JRT_MARKER_FILE;
} else if (container.getFileName().toString().endsWith(".jimage")) {
System.err.println("Warning: reference to " + container + " ignored");
return;
}
listArchive(archive,
if (container == Locations.JRT_MARKER_FILE) {
try {
listJRTImage(subdirectory,
fileKinds,
recurse,
resultList);
} catch (IOException ex) {
ex.printStackTrace(System.err);
log.error("error.reading.file", container, getMessage(ex));
}
return;
}
if (fsInfo.isDirectory(container)) {
listDirectory(container, null,
subdirectory,
fileKinds,
recurse,
resultList);
return;
}
if (Files.exists(container)) {
listArchive(container,
subdirectory,
fileKinds,
recurse,
resultList);
}
}
private boolean isValidFile(String s, Set<JavaFileObject.Kind> fileKinds) {
@ -481,141 +501,17 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
return j < 0;
}
/**
* An archive provides a flat directory structure of a ZipFile by
* mapping directory names to lists of files (basenames).
*/
public interface Archive {
void close() throws IOException;
boolean contains(RelativePath name);
JavaFileObject getFileObject(RelativeDirectory subdirectory, String file);
List<String> getFiles(RelativeDirectory subdirectory);
Set<RelativeDirectory> getSubdirectories();
private FileSystem getFileSystem(Path path) throws IOException {
Path realPath = fsInfo.getCanonicalFile(path);
FileSystem fs = fileSystems.get(realPath);
if (fs == null) {
fileSystems.put(realPath, fs = FileSystems.newFileSystem(realPath, null));
}
return fs;
}
public class MissingArchive implements Archive {
final Path zipFileName;
public MissingArchive(Path name) {
zipFileName = name;
}
@Override
public boolean contains(RelativePath name) {
return false;
}
private final Map<Path,FileSystem> fileSystems = new HashMap<>();
@Override
public void close() {
}
@Override
public JavaFileObject getFileObject(RelativeDirectory subdirectory, String file) {
return null;
}
@Override
public List<String> getFiles(RelativeDirectory subdirectory) {
return List.nil();
}
@Override
public Set<RelativeDirectory> getSubdirectories() {
return Collections.emptySet();
}
@Override
public String toString() {
return "MissingArchive[" + zipFileName + "]";
}
}
/** A directory of zip files already opened.
*/
Map<Path, Archive> archives = new HashMap<>();
/*
* This method looks for a ZipFormatException and takes appropriate
* evasive action. If there is a failure in the fast mode then we
* fail over to the platform zip, and allow it to deal with a potentially
* non compliant zip file.
*/
protected Archive openArchive(Path zipFilename) throws IOException {
try {
return openArchive(zipFilename, contextUseOptimizedZip);
} catch (IOException ioe) {
if (ioe instanceof ZipFileIndex.ZipFormatException) {
return openArchive(zipFilename, false);
} else {
throw ioe;
}
}
}
/** Open a new zip file directory, and cache it.
*/
private Archive openArchive(Path zipFileName, boolean useOptimizedZip) throws IOException {
Archive archive;
try {
ZipFile zdir = null;
boolean usePreindexedCache = false;
String preindexCacheLocation = null;
if (!useOptimizedZip) {
zdir = new ZipFile(zipFileName.toFile());
} else {
usePreindexedCache = options.isSet("usezipindex");
preindexCacheLocation = options.get("java.io.tmpdir");
String optCacheLoc = options.get("cachezipindexdir");
if (optCacheLoc != null && optCacheLoc.length() != 0) {
if (optCacheLoc.startsWith("\"")) {
if (optCacheLoc.endsWith("\"")) {
optCacheLoc = optCacheLoc.substring(1, optCacheLoc.length() - 1);
}
else {
optCacheLoc = optCacheLoc.substring(1);
}
}
File cacheDir = new File(optCacheLoc);
if (cacheDir.exists() && cacheDir.canWrite()) {
preindexCacheLocation = optCacheLoc;
if (!preindexCacheLocation.endsWith("/") &&
!preindexCacheLocation.endsWith(File.separator)) {
preindexCacheLocation += File.separator;
}
}
}
}
if (!useOptimizedZip) {
archive = new ZipArchive(this, zdir);
} else {
archive = new ZipFileIndexArchive(this,
zipFileIndexCache.getZipFileIndex(zipFileName,
null,
usePreindexedCache,
preindexCacheLocation,
options.isSet("writezipindexfiles")));
}
} catch (FileNotFoundException | NoSuchFileException ex) {
archive = new MissingArchive(zipFileName);
} catch (ZipFileIndex.ZipFormatException zfe) {
throw zfe;
} catch (IOException ex) {
if (Files.exists(zipFileName))
log.error("error.reading.file", zipFileName, getMessage(ex));
archive = new MissingArchive(zipFileName);
}
archives.put(zipFileName, archive);
return archive;
}
/** Flush any output resources.
*/
@ -628,15 +524,9 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
* Close the JavaFileManager, releasing resources.
*/
@Override @DefinedBy(Api.COMPILER)
public void close() {
for (Iterator<Archive> i = archives.values().iterator(); i.hasNext(); ) {
Archive a = i.next();
i.remove();
try {
a.close();
} catch (IOException ignore) {
}
}
public void close() throws IOException {
for (FileSystem fs: fileSystems.values())
fs.close();
}
@Override @DefinedBy(Api.COMPILER)
@ -689,10 +579,8 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
return null;
}
if (file instanceof BaseFileObject) {
return ((BaseFileObject) file).inferBinaryName(path);
} else if (file instanceof PathFileObject) {
return ((PathFileObject) file).inferBinaryName(null);
if (file instanceof PathFileObject) {
return ((PathFileObject) file).inferBinaryName(path);
} else
throw new IllegalArgumentException(file.getClass().getName());
}
@ -703,11 +591,6 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
nullCheck(b);
if (a instanceof PathFileObject && b instanceof PathFileObject)
return ((PathFileObject) a).isSameFile((PathFileObject) b);
// In time, we should phase out BaseFileObject in favor of PathFileObject
if (!(a instanceof BaseFileObject || a instanceof PathFileObject))
throw new IllegalArgumentException("Not supported: " + a);
if (!(b instanceof BaseFileObject || b instanceof PathFileObject))
throw new IllegalArgumentException("Not supported: " + b);
return a.equals(b);
}
@ -754,32 +637,29 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
return null;
for (Path file: path) {
Archive a = archives.get(file);
if (a == null) {
// archives are not created for directories or jrt: images
if (file == Locations.JRT_MARKER_FILE) {
JRTIndex.Entry e = getJRTIndex().getEntry(name.dirname());
if (symbolFileEnabled && e.ctSym.hidden)
continue;
Path p = e.files.get(name.basename());
if (p != null)
return PathFileObject.createJRTPathFileObject(this, p);
continue;
} else if (fsInfo.isDirectory(file)) {
try {
Path f = name.getFile(file);
if (Files.exists(f))
return new RegularFileObject(this, f);
} catch (InvalidPathException ignore) {
}
if (file == Locations.JRT_MARKER_FILE) {
JRTIndex.Entry e = getJRTIndex().getEntry(name.dirname());
if (symbolFileEnabled && e.ctSym.hidden)
continue;
Path p = e.files.get(name.basename());
if (p != null)
return PathFileObject.forJRTPath(this, p);
} else if (fsInfo.isDirectory(file)) {
try {
Path f = name.resolveAgainst(file);
if (Files.exists(f))
return PathFileObject.forSimplePath(this,
fsInfo.getCanonicalFile(f), f);
} catch (InvalidPathException ignore) {
}
} else if (Files.exists(file)) {
FileSystem fs = getFileSystem(file);
if (fs != null) {
Path fsRoot = fs.getRootDirectories().iterator().next();
Path f = name.resolveAgainst(fsRoot);
if (Files.exists(f))
return PathFileObject.forJarPath(this, f, file);
}
// Not a directory, create the archive
a = openArchive(file);
}
// Process the archive
if (a.contains(name)) {
return a.getFileObject(name.dirname(), name.basename());
}
}
return null;
@ -829,14 +709,14 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
if (getClassOutDir() != null) {
dir = getClassOutDir();
} else {
Path siblingDir = null;
if (sibling != null && sibling instanceof RegularFileObject) {
siblingDir = ((RegularFileObject)sibling).file.getParent();
String baseName = fileName.basename();
if (sibling != null && sibling instanceof PathFileObject) {
return ((PathFileObject) sibling).getSibling(baseName);
} else {
Path p = Paths.get(baseName);
Path real = fsInfo.getCanonicalFile(p);
return PathFileObject.forSimplePath(this, real, p);
}
if (siblingDir == null)
return new RegularFileObject(this, Paths.get(fileName.basename()));
else
return new RegularFileObject(this, siblingDir.resolve(fileName.basename()));
}
} else if (location == SOURCE_OUTPUT) {
dir = (getSourceOutDir() != null ? getSourceOutDir() : getClassOutDir());
@ -850,8 +730,11 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
}
try {
Path file = fileName.getFile(dir); // null-safe
return new RegularFileObject(this, file);
if (dir == null) {
dir = Paths.get(System.getProperty("user.dir"));
}
Path path = fileName.resolveAgainst(fsInfo.getCanonicalFile(dir));
return PathFileObject.forDirectoryPath(this, path, dir, fileName);
} catch (InvalidPathException e) {
throw new IOException("bad filename " + fileName, e);
}
@ -861,13 +744,17 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
public Iterable<? extends JavaFileObject> getJavaFileObjectsFromFiles(
Iterable<? extends File> files)
{
ArrayList<RegularFileObject> result;
ArrayList<PathFileObject> result;
if (files instanceof Collection<?>)
result = new ArrayList<>(((Collection<?>)files).size());
else
result = new ArrayList<>();
for (File f: files)
result.add(new RegularFileObject(this, nullCheck(f).toPath()));
for (File f: files) {
Objects.requireNonNull(f);
Path p = f.toPath();
result.add(PathFileObject.forSimplePath(this,
fsInfo.getCanonicalFile(p), p));
}
return result;
}
@ -875,13 +762,14 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
public Iterable<? extends JavaFileObject> getJavaFileObjectsFromPaths(
Iterable<? extends Path> paths)
{
ArrayList<RegularFileObject> result;
ArrayList<PathFileObject> result;
if (paths instanceof Collection<?>)
result = new ArrayList<>(((Collection<?>)paths).size());
else
result = new ArrayList<>();
for (Path p: paths)
result.add(new RegularFileObject(this, nullCheck(p)));
result.add(PathFileObject.forSimplePath(this,
fsInfo.getCanonicalFile(p), p));
return result;
}
@ -935,8 +823,8 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
@Override @DefinedBy(Api.COMPILER)
public Path asPath(FileObject file) {
if (file instanceof RegularFileObject) {
return ((RegularFileObject) file).file;
if (file instanceof PathFileObject) {
return ((PathFileObject) file).path;
} else
throw new IllegalArgumentException(file.getName());
}

View File

@ -33,18 +33,24 @@ import java.io.OutputStreamWriter;
import java.io.Reader;
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 java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.Path;
import java.text.Normalizer;
import java.util.Objects;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.NestingKind;
import javax.tools.FileObject;
import javax.tools.JavaFileObject;
import com.sun.tools.javac.file.RelativePath.RelativeFile;
import com.sun.tools.javac.util.DefinedBy;
import com.sun.tools.javac.util.DefinedBy.Api;
@ -53,10 +59,16 @@ import com.sun.tools.javac.util.DefinedBy.Api;
* Implementation of JavaFileObject using java.nio.file API.
*
* <p>PathFileObjects are, for the most part, straightforward wrappers around
* Path objects. The primary complexity is the support for "inferBinaryName".
* This is left as an abstract method, implemented by each of a number of
* different factory methods, which compute the binary name based on
* information available at the time the file object is created.
* immutable absolute Path objects. Different subtypes are used to provide
* specialized implementations of "inferBinaryName" and "getName" that capture
* additional information available at the time the object is created.
*
* <p>In general, {@link JavaFileManager#isSameFile} should be used to
* determine whether two file objects refer to the same file on disk.
* PathFileObject also supports the standard {@code equals} and {@code hashCode}
* methods, primarily for convenience when working with collections.
* All of these operations delegate to the equivalent operations on the
* underlying Path object.
*
* <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own risk.
@ -64,108 +76,297 @@ import com.sun.tools.javac.util.DefinedBy.Api;
* deletion without notice.</b>
*/
public abstract class PathFileObject implements JavaFileObject {
private final BaseFileManager fileManager;
private final Path path;
private static final FileSystem defaultFileSystem = FileSystems.getDefault();
private static final boolean isMacOS = System.getProperty("os.name", "").contains("OS X");
protected final BaseFileManager fileManager;
protected final Path path;
private boolean hasParents;
/**
* Create a PathFileObject within a directory, such that the binary name
* can be inferred from the relationship to the parent directory.
* Create a PathFileObject for a file within a directory, such that the
* binary name can be inferred from the relationship to an enclosing directory.
*
* The binary name is derived from {@code relativePath}.
* The name is derived from the composition of {@code userPackageRootDir}
* and {@code relativePath}.
*
* @param fileManager the file manager creating this file object
* @param path the absolute path referred to by this file object
* @param userPackageRootDir the path of the directory containing the
* root of the package hierarchy
* @param relativePath the path of this file relative to {@code userPackageRootDir}
*/
static PathFileObject createDirectoryPathFileObject(BaseFileManager fileManager,
final Path path, final Path dir) {
return new PathFileObject(fileManager, path) {
@Override
public String inferBinaryName(Iterable<? extends Path> paths) {
return toBinaryName(dir.relativize(path));
}
};
static PathFileObject forDirectoryPath(BaseFileManager fileManager, Path path,
Path userPackageRootDir, RelativePath relativePath) {
return new DirectoryFileObject(fileManager, path, userPackageRootDir, relativePath);
}
private static class DirectoryFileObject extends PathFileObject {
private final Path userPackageRootDir;
private final RelativePath relativePath;
private DirectoryFileObject(BaseFileManager fileManager, Path path,
Path userPackageRootDir, RelativePath relativePath) {
super(fileManager, path);
this.userPackageRootDir = userPackageRootDir;
this.relativePath = relativePath;
}
@Override @DefinedBy(Api.COMPILER)
public String getName() {
return relativePath.resolveAgainst(userPackageRootDir).toString();
}
@Override
public String inferBinaryName(Iterable<? extends Path> paths) {
return toBinaryName(relativePath);
}
@Override
public String toString() {
return "DirectoryFileObject[" + userPackageRootDir + ":" + relativePath.path + "]";
}
@Override
PathFileObject getSibling(String baseName) {
return new DirectoryFileObject(fileManager,
path.resolveSibling(baseName),
userPackageRootDir,
new RelativeFile(relativePath.dirname(), baseName)
);
}
}
/**
* Create a PathFileObject in a file system such as a jar file, such that
* the binary name can be inferred from its position within the filesystem.
* Create a PathFileObject for a file in a file system such as a jar file,
* such that the binary name can be inferred from its position within the
* file system.
*
* The binary name is derived from {@code path}.
* The name is derived from the composition of {@code userJarPath}
* and {@code path}.
*
* @param fileManager the file manager creating this file object
* @param path the path referred to by this file object
* @param userJarPath the path of the jar file containing the file system.
*/
public static PathFileObject createJarPathFileObject(BaseFileManager fileManager,
public static PathFileObject forJarPath(BaseFileManager fileManager,
Path path, Path userJarPath) {
return new JarFileObject(fileManager, path, userJarPath);
}
private static class JarFileObject extends PathFileObject {
private final Path userJarPath;
private JarFileObject(BaseFileManager fileManager, Path path, Path userJarPath) {
super(fileManager, path);
this.userJarPath = userJarPath;
}
@Override @DefinedBy(Api.COMPILER)
public String getName() {
// The use of ( ) to delimit the entry name is not ideal
// but it does match earlier behavior
return userJarPath + "(" + path + ")";
}
@Override
public String inferBinaryName(Iterable<? extends Path> paths) {
Path root = path.getFileSystem().getRootDirectories().iterator().next();
return toBinaryName(root.relativize(path));
}
@Override @DefinedBy(Api.COMPILER)
public URI toUri() {
// Work around bug JDK-8134451:
// path.toUri() returns double-encoded URIs, that cannot be opened by URLConnection
return createJarUri(userJarPath, path.toString());
}
@Override
public String toString() {
return "JarFileObject[" + userJarPath + ":" + path + "]";
}
@Override
PathFileObject getSibling(String baseName) {
return new JarFileObject(fileManager,
path.resolveSibling(baseName),
userJarPath
);
}
private static URI createJarUri(Path jarFile, String entryName) {
URI jarURI = jarFile.toUri().normalize();
String separator = entryName.startsWith("/") ? "!" : "!/";
try {
// The jar URI convention appears to be not to re-encode the jarURI
return new URI("jar:" + jarURI + separator + entryName);
} catch (URISyntaxException e) {
throw new CannotCreateUriError(jarURI + separator + entryName, e);
}
}
}
/**
* Create a PathFileObject for a file in a modular file system, such as jrt:,
* such that the binary name can be inferred from its position within the
* filesystem.
*
* The binary name is derived from {@code path}, ignoring the first two
* elements of the name (which are "modules" and a module name).
* The name is derived from {@code path}.
*
* @param fileManager the file manager creating this file object
* @param path the path referred to by this file object
*/
public static PathFileObject forJRTPath(BaseFileManager fileManager,
final Path path) {
return new PathFileObject(fileManager, path) {
@Override
public String inferBinaryName(Iterable<? extends Path> paths) {
return toBinaryName(path);
}
};
return new JRTFileObject(fileManager, path);
}
private static class JRTFileObject extends PathFileObject {
// private final Path javaHome;
private JRTFileObject(BaseFileManager fileManager, Path path) {
super(fileManager, path);
}
@Override @DefinedBy(Api.COMPILER)
public String getName() {
return path.toString();
}
@Override
public String inferBinaryName(Iterable<? extends Path> paths) {
// use subpath to ignore the leading /modules/MODULE-NAME
return toBinaryName(path.subpath(2, path.getNameCount()));
}
@Override
public String toString() {
return "JRTFileObject[" + path + "]";
}
@Override
PathFileObject getSibling(String baseName) {
return new JRTFileObject(fileManager,
path.resolveSibling(baseName)
);
}
}
/**
* Create a PathFileObject in a modular file system, such as jrt:, such that
* the binary name can be inferred from its position within the filesystem.
* Create a PathFileObject for a file whose binary name must be inferred
* from its position on a search path.
*
* The binary name is inferred by finding an enclosing directory in
* the sequence of paths associated with the location given to
* {@link JavaFileManager#inferBinaryName).
* The name is derived from {@code userPath}.
*
* @param fileManager the file manager creating this file object
* @param path the path referred to by this file object
* @param userPath the "user-friendly" name for this path.
*/
public static PathFileObject createJRTPathFileObject(BaseFileManager fileManager,
final Path path) {
return new PathFileObject(fileManager, path) {
@Override
public String inferBinaryName(Iterable<? extends Path> paths) {
// use subpath to ignore the leading /modules/MODULE-NAME
return toBinaryName(path.subpath(2, path.getNameCount()));
}
};
static PathFileObject forSimplePath(BaseFileManager fileManager,
Path path, Path userPath) {
return new SimpleFileObject(fileManager, path, userPath);
}
/**
* Create a PathFileObject whose binary name can be inferred from the
* relative path to a sibling.
*/
static PathFileObject createSiblingPathFileObject(BaseFileManager fileManager,
final Path path, final String relativePath) {
return new PathFileObject(fileManager, path) {
@Override
public String inferBinaryName(Iterable<? extends Path> paths) {
return toBinaryName(relativePath, "/");
}
};
}
private static class SimpleFileObject extends PathFileObject {
private final Path userPath;
private SimpleFileObject(BaseFileManager fileManager, Path path, Path userPath) {
super(fileManager, path);
this.userPath = userPath;
}
/**
* Create a PathFileObject whose binary name might be inferred from its
* position on a search path.
*/
static PathFileObject createSimplePathFileObject(BaseFileManager fileManager,
final Path path) {
return new PathFileObject(fileManager, path) {
@Override
public String inferBinaryName(Iterable<? extends Path> paths) {
Path absPath = path.toAbsolutePath();
for (Path p: paths) {
Path ap = p.toAbsolutePath();
if (absPath.startsWith(ap)) {
try {
Path rp = ap.relativize(absPath);
if (rp != null) // maybe null if absPath same as ap
return toBinaryName(rp);
} catch (IllegalArgumentException e) {
// ignore this p if cannot relativize path to p
}
@Override @DefinedBy(Api.COMPILER)
public String getName() {
return userPath.toString();
}
@Override
public String inferBinaryName(Iterable<? extends Path> paths) {
Path absPath = path.toAbsolutePath();
for (Path p: paths) {
Path ap = p.toAbsolutePath();
if (absPath.startsWith(ap)) {
try {
Path rp = ap.relativize(absPath);
if (rp != null) // maybe null if absPath same as ap
return toBinaryName(rp);
} catch (IllegalArgumentException e) {
// ignore this p if cannot relativize path to p
}
}
return null;
}
};
return null;
}
@Override
PathFileObject getSibling(String baseName) {
return new SimpleFileObject(fileManager,
path.resolveSibling(baseName),
userPath.resolveSibling(baseName)
);
}
}
/**
* Create a PathFileObject, for a specified path, in the context of
* a given file manager.
*
* In general, this path should be an
* {@link Path#toAbsolutePath absolute path}, if not a
* {@link Path#toRealPath} real path.
* It will be used as the basis of {@code equals}, {@code hashCode}
* and {@code isSameFile} methods on this file object.
*
* A PathFileObject should also have a "friendly name" per the
* specification for {@link FileObject#getName}. The friendly name
* is provided by the various subtypes of {@code PathFileObject}.
*
* @param fileManager the file manager creating this file object
* @param path the path contained in this file object.
*/
protected PathFileObject(BaseFileManager fileManager, Path path) {
this.fileManager = Objects.requireNonNull(fileManager);
this.path = Objects.requireNonNull(path);
if (Files.isDirectory(path)) {
throw new IllegalArgumentException("directories not supported");
}
this.path = path;
}
public abstract String inferBinaryName(Iterable<? extends Path> paths);
/**
* See {@link JavacFileManager#inferBinaryName}.
*/
abstract String inferBinaryName(Iterable<? extends Path> paths);
/**
* Return the file object for a sibling file with a given file name.
* See {@link JavacFileManager#getFileForOutput} and
* {@link JavacFileManager#getJavaFileForOutput}.
*/
abstract PathFileObject getSibling(String basename);
/**
* Return the Path for this object.
* @return the Path for this object.
* @see StandardJavaFileManager#asPath
*/
public Path getPath() {
return path;
}
/**
* The short name is used when generating raw diagnostics.
* @return the last component of the path
*/
public String getShortName() {
return path.getFileName().toString();
}
@Override @DefinedBy(Api.COMPILER)
public Kind getKind() {
return BaseFileManager.getKind(path.getFileName().toString());
@ -174,22 +375,43 @@ public abstract class PathFileObject implements JavaFileObject {
@Override @DefinedBy(Api.COMPILER)
public boolean isNameCompatible(String simpleName, Kind kind) {
Objects.requireNonNull(simpleName);
// null check
Objects.requireNonNull(kind);
if (kind == Kind.OTHER && getKind() != kind) {
return false;
}
String sn = simpleName + kind.extension;
String pn = path.getFileName().toString();
if (pn.equals(sn)) {
return true;
}
if (pn.equalsIgnoreCase(sn)) {
try {
// allow for Windows
return path.toRealPath(LinkOption.NOFOLLOW_LINKS).getFileName().toString().equals(sn);
} catch (IOException e) {
if (path.getFileSystem() == defaultFileSystem) {
if (isMacOS) {
String name = path.getFileName().toString();
if (Normalizer.isNormalized(name, Normalizer.Form.NFD)
&& Normalizer.isNormalized(sn, Normalizer.Form.NFC)) {
// On Mac OS X it is quite possible to have the file name and the
// given simple name normalized in different ways.
// In that case we have to normalize file name to the
// Normal Form Composed (NFC).
String normName = Normalizer.normalize(name, Normalizer.Form.NFC);
if (normName.equals(sn)) {
return true;
}
}
}
if (pn.equalsIgnoreCase(sn)) {
try {
// allow for Windows
return path.toRealPath(LinkOption.NOFOLLOW_LINKS).getFileName().toString().equals(sn);
} catch (IOException e) {
}
}
}
return false;
}
@ -208,11 +430,6 @@ public abstract class PathFileObject implements JavaFileObject {
return path.toUri();
}
@Override @DefinedBy(Api.COMPILER)
public String getName() {
return path.toString();
}
@Override @DefinedBy(Api.COMPILER)
public InputStream openInputStream() throws IOException {
return Files.newInputStream(path);
@ -264,7 +481,7 @@ public abstract class PathFileObject implements JavaFileObject {
try {
return Files.getLastModifiedTime(path).toMillis();
} catch (IOException e) {
return -1;
return 0;
}
}
@ -278,7 +495,7 @@ public abstract class PathFileObject implements JavaFileObject {
}
}
public boolean isSameFile(PathFileObject other) {
boolean isSameFile(PathFileObject other) {
try {
return Files.isSameFile(path, other.path);
} catch (IOException e) {
@ -302,17 +519,21 @@ public abstract class PathFileObject implements JavaFileObject {
}
private void ensureParentDirectoriesExist() throws IOException {
Path parent = path.getParent();
if (parent != null)
Files.createDirectories(parent);
if (!hasParents) {
Path parent = path.getParent();
if (parent != null && !Files.isDirectory(parent)) {
try {
Files.createDirectories(parent);
} catch (IOException e) {
throw new IOException("could not create parent directories", e);
}
}
hasParents = true;
}
}
private long size() {
try {
return Files.size(path);
} catch (IOException e) {
return -1;
}
protected static String toBinaryName(RelativePath relativePath) {
return toBinaryName(relativePath.path, "/");
}
protected static String toBinaryName(Path relativePath) {
@ -320,12 +541,32 @@ public abstract class PathFileObject implements JavaFileObject {
relativePath.getFileSystem().getSeparator());
}
protected static String toBinaryName(String relativePath, String sep) {
private static String toBinaryName(String relativePath, String sep) {
return removeExtension(relativePath).replace(sep, ".");
}
protected static String removeExtension(String fileName) {
private static String removeExtension(String fileName) {
int lastDot = fileName.lastIndexOf(".");
return (lastDot == -1 ? fileName : fileName.substring(0, lastDot));
}
/** Return the last component of a presumed hierarchical URI.
* From the scheme specific part of the URI, it returns the substring
* after the last "/" if any, or everything if no "/" is found.
*/
public static String getSimpleName(FileObject fo) {
URI uri = fo.toUri();
String s = uri.getSchemeSpecificPart();
return s.substring(s.lastIndexOf("/") + 1); // safe when / not found
}
/** Used when URLSyntaxException is thrown unexpectedly during
* implementations of FileObject.toURI(). */
public static class CannotCreateUriError extends Error {
private static final long serialVersionUID = 9101708840997613546L;
public CannotCreateUriError(String value, Throwable cause) {
super(value, cause);
}
}
}

View File

@ -1,265 +0,0 @@
/*
* Copyright (c) 2005, 2014, Oracle and/or its affiliates. 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.javac.file;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.lang.ref.Reference;
import java.lang.ref.SoftReference;
import java.net.URI;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.CharsetDecoder;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.Normalizer;
import java.util.Objects;
import javax.tools.JavaFileObject;
import com.sun.tools.javac.util.DefinedBy;
import com.sun.tools.javac.util.DefinedBy.Api;
/**
* A subclass of JavaFileObject representing regular files.
*
* <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own risk.
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*/
class RegularFileObject extends BaseFileObject {
/** Have the parent directories been created?
*/
private boolean hasParents = false;
private String name;
final Path file;
private Reference<Path> absFileRef;
final static boolean isMacOS = System.getProperty("os.name", "").contains("OS X");
public RegularFileObject(JavacFileManager fileManager, Path f) {
this(fileManager, f.getFileName().toString(), f);
}
public RegularFileObject(JavacFileManager fileManager, String name, Path f) {
super(fileManager);
if (Files.isDirectory(f)) {
throw new IllegalArgumentException("directories not supported");
}
this.name = name;
this.file = f;
if (getLastModified() > System.currentTimeMillis())
fileManager.log.warning("file.from.future", f);
}
@Override @DefinedBy(Api.COMPILER)
public URI toUri() {
return file.toUri().normalize();
}
@Override @DefinedBy(Api.COMPILER)
public String getName() {
return file.toString();
}
@Override
public String getShortName() {
return name;
}
@Override @DefinedBy(Api.COMPILER)
public JavaFileObject.Kind getKind() {
return getKind(name);
}
@Override @DefinedBy(Api.COMPILER)
public InputStream openInputStream() throws IOException {
return Files.newInputStream(file);
}
@Override @DefinedBy(Api.COMPILER)
public OutputStream openOutputStream() throws IOException {
fileManager.flushCache(this);
ensureParentDirectoriesExist();
return Files.newOutputStream(file);
}
@Override @DefinedBy(Api.COMPILER)
public CharBuffer getCharContent(boolean ignoreEncodingErrors) throws IOException {
CharBuffer cb = fileManager.getCachedContent(this);
if (cb == null) {
try (InputStream in = Files.newInputStream(file)) {
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);
}
}
}
return cb;
}
@Override @DefinedBy(Api.COMPILER)
public Writer openWriter() throws IOException {
fileManager.flushCache(this);
ensureParentDirectoriesExist();
return new OutputStreamWriter(Files.newOutputStream(file), fileManager.getEncodingName());
}
@Override @DefinedBy(Api.COMPILER)
public long getLastModified() {
try {
return Files.getLastModifiedTime(file).toMillis();
} catch (IOException e) {
return 0;
}
}
@Override @DefinedBy(Api.COMPILER)
public boolean delete() {
try {
Files.delete(file);
return true;
} catch (IOException e) {
return false;
}
}
@Override
protected CharsetDecoder getDecoder(boolean ignoreEncodingErrors) {
return fileManager.getDecoder(fileManager.getEncodingName(), ignoreEncodingErrors);
}
@Override
protected String inferBinaryName(Iterable<? extends Path> path) {
String fPath = file.toString();
//System.err.println("RegularFileObject " + file + " " +r.getPath());
for (Path dir: path) {
//System.err.println("dir: " + dir);
String sep = dir.getFileSystem().getSeparator();
String dPath = dir.toString();
if (dPath.length() == 0)
dPath = System.getProperty("user.dir");
if (!dPath.endsWith(sep))
dPath += sep;
if (fPath.regionMatches(true, 0, dPath, 0, dPath.length())
&& Paths.get(fPath.substring(0, dPath.length())).equals(Paths.get(dPath))) {
String relativeName = fPath.substring(dPath.length());
return removeExtension(relativeName).replace(sep, ".");
}
}
return null;
}
@Override @DefinedBy(Api.COMPILER)
public boolean isNameCompatible(String cn, JavaFileObject.Kind kind) {
Objects.requireNonNull(cn);
// null check
if (kind == Kind.OTHER && getKind() != kind) {
return false;
}
String n = cn + kind.extension;
if (name.equals(n)) {
return true;
}
if (isMacOS && Normalizer.isNormalized(name, Normalizer.Form.NFD)
&& Normalizer.isNormalized(n, Normalizer.Form.NFC)) {
// On Mac OS X it is quite possible to file name and class
// name normalized in a different way - in that case we have to normalize file name
// to the Normal Form Compised (NFC)
String normName = Normalizer.normalize(name, Normalizer.Form.NFC);
if (normName.equals(n)) {
this.name = normName;
return true;
}
}
if (name.equalsIgnoreCase(n)) {
try {
// allow for Windows
return file.toRealPath().getFileName().toString().equals(n);
} catch (IOException e) {
}
}
return false;
}
private void ensureParentDirectoriesExist() throws IOException {
if (!hasParents) {
Path parent = file.getParent();
if (parent != null && !Files.isDirectory(parent)) {
try {
Files.createDirectories(parent);
} catch (IOException e) {
throw new IOException("could not create parent directories", e);
}
}
hasParents = true;
}
}
/**
* Check if two file objects are equal.
* Two RegularFileObjects are equal if the absolute paths of the underlying
* files are equal.
*/
@Override
public boolean equals(Object other) {
if (this == other)
return true;
if (!(other instanceof RegularFileObject))
return false;
RegularFileObject o = (RegularFileObject) other;
return getAbsoluteFile().equals(o.getAbsoluteFile());
}
@Override
public int hashCode() {
return getAbsoluteFile().hashCode();
}
private Path getAbsoluteFile() {
Path absFile = (absFileRef == null ? null : absFileRef.get());
if (absFile == null) {
absFile = file.toAbsolutePath();
absFileRef = new SoftReference<>(absFile);
}
return absFile;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2015, Oracle and/or its affiliates. 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
@ -26,6 +26,7 @@
package com.sun.tools.javac.file;
import java.io.File;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.InvalidPathException;
import java.nio.file.Path;
@ -57,7 +58,7 @@ public abstract class RelativePath implements Comparable<RelativePath> {
public abstract String basename();
public Path getFile(Path directory) throws /*unchecked*/ InvalidPathException {
public Path resolveAgainst(Path directory) throws /*unchecked*/ InvalidPathException {
if (directory == null) {
String sep = FileSystems.getDefault().getSeparator();
return Paths.get(path.replace("/", sep));
@ -67,6 +68,12 @@ public abstract class RelativePath implements Comparable<RelativePath> {
}
}
public Path resolveAgainst(FileSystem fs) throws /*unchecked*/ InvalidPathException {
String sep = fs.getSeparator();
Path root = fs.getRootDirectories().iterator().next();
return root.resolve(path.replace("/", sep));
}
@Override
public int compareTo(RelativePath other) {
return path.compareTo(other.path);

View File

@ -1,290 +0,0 @@
/*
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.javac.file;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Writer;
import java.lang.ref.Reference;
import java.lang.ref.SoftReference;
import java.net.URI;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.CharsetDecoder;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
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.DefinedBy;
import com.sun.tools.javac.util.DefinedBy.Api;
import com.sun.tools.javac.util.List;
/**
* <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own risk.
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*/
public class ZipArchive implements Archive {
public ZipArchive(JavacFileManager fm, ZipFile zfile) throws IOException {
this(fm, zfile, true);
}
protected ZipArchive(JavacFileManager fm, ZipFile zfile, boolean initMap) throws IOException {
this.fileManager = fm;
this.zfile = zfile;
this.map = new HashMap<>();
if (initMap)
initMap();
}
protected void initMap() throws IOException {
for (Enumeration<? extends ZipEntry> e = zfile.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('/');
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)
list = List.nil();
list = list.prepend(basename);
map.put(dirname, list);
}
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(RelativeDirectory subdirectory) {
return map.get(subdirectory);
}
public JavaFileObject getFileObject(RelativeDirectory subdirectory, String file) {
ZipEntry ze = new RelativeFile(subdirectory, file).getZipEntry(zfile);
return new ZipFileObject(this, file, ze);
}
public Set<RelativeDirectory> getSubdirectories() {
return map.keySet();
}
public void close() throws IOException {
zfile.close();
}
@Override
public String toString() {
return "ZipArchive[" + zfile.getName() + "]";
}
private Path getAbsoluteFile() {
Path absFile = (absFileRef == null ? null : absFileRef.get());
if (absFile == null) {
absFile = Paths.get(zfile.getName()).toAbsolutePath();
absFileRef = new SoftReference<>(absFile);
}
return absFile;
}
/**
* The file manager that created this archive.
*/
protected JavacFileManager fileManager;
/**
* The index for the contents of this archive.
*/
protected final Map<RelativeDirectory,List<String>> map;
/**
* The zip file for the archive.
*/
protected final ZipFile zfile;
/**
* A reference to the absolute filename for the zip file for the archive.
*/
protected Reference<Path> absFileRef;
/**
* A subclass of JavaFileObject representing zip entries.
*/
public static class ZipFileObject extends BaseFileObject {
private String name;
ZipArchive zarch;
ZipEntry entry;
protected ZipFileObject(ZipArchive zarch, String name, ZipEntry entry) {
super(zarch.fileManager);
this.zarch = zarch;
this.name = name;
this.entry = entry;
}
@DefinedBy(Api.COMPILER)
public URI toUri() {
Path zipFile = Paths.get(zarch.zfile.getName());
return createJarUri(zipFile, entry.getName());
}
@Override @DefinedBy(Api.COMPILER)
public String getName() {
return zarch.zfile.getName() + "(" + entry.getName() + ")";
}
@Override
public String getShortName() {
return Paths.get(zarch.zfile.getName()).getFileName() + "(" + entry + ")";
}
@Override @DefinedBy(Api.COMPILER)
public JavaFileObject.Kind getKind() {
return getKind(entry.getName());
}
@Override @DefinedBy(Api.COMPILER)
public InputStream openInputStream() throws IOException {
return zarch.zfile.getInputStream(entry);
}
@Override @DefinedBy(Api.COMPILER)
public OutputStream openOutputStream() throws IOException {
throw new UnsupportedOperationException();
}
@Override @DefinedBy(Api.COMPILER)
public CharBuffer getCharContent(boolean ignoreEncodingErrors) throws IOException {
CharBuffer cb = fileManager.getCachedContent(this);
if (cb == null) {
try (InputStream in = zarch.zfile.getInputStream(entry)) {
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);
}
}
}
return cb;
}
@Override @DefinedBy(Api.COMPILER)
public Writer openWriter() throws IOException {
throw new UnsupportedOperationException();
}
@Override @DefinedBy(Api.COMPILER)
public long getLastModified() {
return entry.getTime();
}
@Override @DefinedBy(Api.COMPILER)
public boolean delete() {
throw new UnsupportedOperationException();
}
@Override
protected CharsetDecoder getDecoder(boolean ignoreEncodingErrors) {
return fileManager.getDecoder(fileManager.getEncodingName(), ignoreEncodingErrors);
}
@Override
protected String inferBinaryName(Iterable<? extends Path> path) {
String entryName = entry.getName();
return removeExtension(entryName).replace('/', '.');
}
@Override @DefinedBy(Api.COMPILER)
public boolean isNameCompatible(String cn, JavaFileObject.Kind k) {
Objects.requireNonNull(cn);
// null check
if (k == Kind.OTHER && getKind() != k) {
return false;
}
return name.equals(cn + k.extension);
}
/**
* Check if two file objects are equal.
* Two ZipFileObjects are equal if the absolute paths of the underlying
* zip files are equal and if the paths within those zip files are equal.
*/
@Override
public boolean equals(Object other) {
if (this == other)
return true;
if (!(other instanceof ZipFileObject))
return false;
ZipFileObject o = (ZipFileObject) other;
return zarch.getAbsoluteFile().equals(o.zarch.getAbsoluteFile())
&& entry.getName().equals(o.entry.getName());
}
@Override
public int hashCode() {
return zarch.getAbsoluteFile().hashCode() + entry.getName().hashCode();
}
}
}

View File

@ -1,247 +0,0 @@
/*
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.javac.file;
import java.io.ByteArrayInputStream;
import java.io.IOException;
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;
import java.nio.file.Path;
import java.util.Objects;
import java.util.Set;
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.Assert;
import com.sun.tools.javac.util.DefinedBy;
import com.sun.tools.javac.util.DefinedBy.Api;
import com.sun.tools.javac.util.List;
/**
* <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own risk.
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*/
public class ZipFileIndexArchive implements Archive {
private final ZipFileIndex zfIndex;
private final JavacFileManager fileManager;
public ZipFileIndexArchive(JavacFileManager fileManager, ZipFileIndex zdir) throws IOException {
super();
this.fileManager = fileManager;
this.zfIndex = zdir;
}
public boolean contains(RelativePath name) {
return zfIndex.contains(name);
}
public List<String> getFiles(RelativeDirectory subdirectory) {
return zfIndex.getFiles(subdirectory);
}
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());
return ret;
}
public Set<RelativeDirectory> getSubdirectories() {
return zfIndex.getAllDirectories();
}
public void close() throws IOException {
zfIndex.close();
}
@Override
public String toString() {
return "ZipFileIndexArchive[" + zfIndex + "]";
}
/**
* 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 name of the zip file where this entry resides.
*/
Path zipName;
ZipFileIndexFileObject(JavacFileManager fileManager, ZipFileIndex zfIndex, ZipFileIndex.Entry entry, Path zipFileName) {
super(fileManager);
this.name = entry.getFileName();
this.zfIndex = zfIndex;
this.entry = entry;
this.zipName = zipFileName;
}
@Override @DefinedBy(Api.COMPILER)
public URI toUri() {
return createJarUri(zipName, getPrefixedEntryName());
}
@Override @DefinedBy(Api.COMPILER)
public String getName() {
return zipName + "(" + getPrefixedEntryName() + ")";
}
@Override
public String getShortName() {
return zipName.getFileName() + "(" + entry.getName() + ")";
}
@Override @DefinedBy(Api.COMPILER)
public JavaFileObject.Kind getKind() {
return getKind(entry.getName());
}
@Override @DefinedBy(Api.COMPILER)
public InputStream openInputStream() throws IOException {
Assert.checkNonNull(entry); // see constructor
return new ByteArrayInputStream(zfIndex.read(entry));
}
@Override @DefinedBy(Api.COMPILER)
public OutputStream openOutputStream() throws IOException {
throw new UnsupportedOperationException();
}
@Override @DefinedBy(Api.COMPILER)
public CharBuffer getCharContent(boolean ignoreEncodingErrors) throws IOException {
CharBuffer cb = fileManager.getCachedContent(this);
if (cb == null) {
try (InputStream in = new ByteArrayInputStream(zfIndex.read(entry))) {
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);
}
}
return cb;
}
@Override @DefinedBy(Api.COMPILER)
public Writer openWriter() throws IOException {
throw new UnsupportedOperationException();
}
@Override @DefinedBy(Api.COMPILER)
public long getLastModified() {
return entry.getLastModified();
}
@Override @DefinedBy(Api.COMPILER)
public boolean delete() {
throw new UnsupportedOperationException();
}
@Override
protected CharsetDecoder getDecoder(boolean ignoreEncodingErrors) {
return fileManager.getDecoder(fileManager.getEncodingName(), ignoreEncodingErrors);
}
@Override
protected String inferBinaryName(Iterable<? extends Path> path) {
String entryName = entry.getName();
if (zfIndex.symbolFilePrefix != null) {
String prefix = zfIndex.symbolFilePrefix.path;
if (entryName.startsWith(prefix))
entryName = entryName.substring(prefix.length());
}
return removeExtension(entryName).replace('/', '.');
}
@Override @DefinedBy(Api.COMPILER)
public boolean isNameCompatible(String cn, JavaFileObject.Kind k) {
Objects.requireNonNull(cn);
if (k == Kind.OTHER && getKind() != k)
return false;
return name.equals(cn + k.extension);
}
/**
* Check if two file objects are equal.
* Two ZipFileIndexFileObjects are equal if the absolute paths of the underlying
* zip files are equal and if the paths within those zip files are equal.
*/
@Override
public boolean equals(Object other) {
if (this == other)
return true;
if (!(other instanceof ZipFileIndexFileObject))
return false;
ZipFileIndexFileObject o = (ZipFileIndexFileObject) other;
return zfIndex.getAbsoluteFile().equals(o.zfIndex.getAbsoluteFile())
&& entry.equals(o.entry);
}
@Override
public int hashCode() {
return zfIndex.getAbsoluteFile().hashCode() + entry.hashCode();
}
private String getPrefixedEntryName() {
if (zfIndex.symbolFilePrefix != null)
return zfIndex.symbolFilePrefix.path + entry.getName();
else
return entry.getName();
}
}
}

View File

@ -1,147 +0,0 @@
/*
* Copyright (c) 2007, 2014, Oracle and/or its affiliates. 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.javac.file;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.sun.tools.javac.file.RelativePath.RelativeDirectory;
import com.sun.tools.javac.util.Context;
/** A cache for ZipFileIndex objects. */
public class ZipFileIndexCache {
private final Map<Path, ZipFileIndex> map = new HashMap<>();
/** Get a shared instance of the cache. */
private static ZipFileIndexCache sharedInstance;
public synchronized static ZipFileIndexCache getSharedInstance() {
if (sharedInstance == null)
sharedInstance = new ZipFileIndexCache();
return sharedInstance;
}
/** Get a context-specific instance of a cache. */
public static ZipFileIndexCache instance(Context context) {
ZipFileIndexCache instance = context.get(ZipFileIndexCache.class);
if (instance == null)
context.put(ZipFileIndexCache.class, instance = new ZipFileIndexCache());
return instance;
}
/**
* Returns a list of all ZipFileIndex entries
*
* @return A list of ZipFileIndex entries, or an empty list
*/
public List<ZipFileIndex> getZipFileIndexes() {
return getZipFileIndexes(false);
}
/**
* Returns a list of all ZipFileIndex entries
*
* @param openedOnly If true it returns a list of only opened ZipFileIndex entries, otherwise
* all ZipFileEntry(s) are included into the list.
* @return A list of ZipFileIndex entries, or an empty list
*/
public synchronized List<ZipFileIndex> getZipFileIndexes(boolean openedOnly) {
List<ZipFileIndex> zipFileIndexes = new ArrayList<>();
zipFileIndexes.addAll(map.values());
if (openedOnly) {
for(ZipFileIndex elem : zipFileIndexes) {
if (!elem.isOpen()) {
zipFileIndexes.remove(elem);
}
}
}
return zipFileIndexes;
}
public synchronized ZipFileIndex getZipFileIndex(Path zipFile,
RelativeDirectory symbolFilePrefix,
boolean useCache, String cacheLocation,
boolean writeIndex) throws IOException {
ZipFileIndex zi = getExistingZipIndex(zipFile);
if (zi == null || (zi != null && Files.getLastModifiedTime(zipFile).toMillis() != zi.zipFileLastModified)) {
zi = new ZipFileIndex(zipFile, symbolFilePrefix, writeIndex,
useCache, cacheLocation);
map.put(zipFile, zi);
}
return zi;
}
public synchronized ZipFileIndex getExistingZipIndex(Path zipFile) {
return map.get(zipFile);
}
public synchronized void clearCache() {
map.clear();
}
public synchronized void clearCache(long timeNotUsed) {
for (Path cachedFile : map.keySet()) {
ZipFileIndex cachedZipIndex = map.get(cachedFile);
if (cachedZipIndex != null) {
long timeToTest = cachedZipIndex.lastReferenceTimeStamp + timeNotUsed;
if (timeToTest < cachedZipIndex.lastReferenceTimeStamp || // Overflow...
System.currentTimeMillis() > timeToTest) {
map.remove(cachedFile);
}
}
}
}
public synchronized void removeFromCache(Path file) {
map.remove(file);
}
/** Sets already opened list of ZipFileIndexes from an outside client
* of the compiler. This functionality should be used in a non-batch clients of the compiler.
*/
public synchronized void setOpenedIndexes(List<ZipFileIndex>indexes) throws IllegalStateException {
if (map.isEmpty()) {
String msg =
"Setting opened indexes should be called only when the ZipFileCache is empty. "
+ "Call JavacFileManager.flush() before calling this method.";
throw new IllegalStateException(msg);
}
for (ZipFileIndex zfi : indexes) {
map.put(zfi.zipFile, zfi);
}
}
}

View File

@ -29,15 +29,18 @@ import java.io.*;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.CharBuffer;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.NestingKind;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
import com.sun.tools.javac.comp.Annotate;
import com.sun.tools.javac.comp.Annotate.AnnotationTypeCompleter;
import com.sun.tools.javac.code.*;
@ -47,7 +50,8 @@ import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.code.Symtab;
import com.sun.tools.javac.code.Type.*;
import com.sun.tools.javac.comp.Annotate.AnnotationTypeMetadata;
import com.sun.tools.javac.file.BaseFileObject;
import com.sun.tools.javac.file.BaseFileManager;
import com.sun.tools.javac.file.PathFileObject;
import com.sun.tools.javac.jvm.ClassFile.NameAndType;
import com.sun.tools.javac.jvm.ClassFile.Version;
import com.sun.tools.javac.util.*;
@ -2465,15 +2469,14 @@ public class ClassReader {
* to be valid as is, so operations other than those to access the name throw
* UnsupportedOperationException
*/
private static class SourceFileObject extends BaseFileObject {
private static class SourceFileObject implements JavaFileObject {
/** The file's name.
*/
private Name name;
private Name flatname;
private final Name name;
private final Name flatname;
public SourceFileObject(Name name, Name flatname) {
super(null); // no file manager; never referenced for this file object
this.name = name;
this.flatname = flatname;
}
@ -2483,7 +2486,7 @@ public class ClassReader {
try {
return new URI(null, name.toString(), null);
} catch (URISyntaxException e) {
throw new CannotCreateUriError(name.toString(), e);
throw new PathFileObject.CannotCreateUriError(name.toString(), e);
}
}
@ -2492,14 +2495,9 @@ public class ClassReader {
return name.toString();
}
@Override
public String getShortName() {
return getName();
}
@Override @DefinedBy(Api.COMPILER)
public JavaFileObject.Kind getKind() {
return getKind(getName());
return BaseFileManager.getKind(getName());
}
@Override @DefinedBy(Api.COMPILER)
@ -2537,16 +2535,21 @@ public class ClassReader {
throw new UnsupportedOperationException();
}
@Override
protected String inferBinaryName(Iterable<? extends Path> path) {
return flatname.toString();
}
@Override @DefinedBy(Api.COMPILER)
public boolean isNameCompatible(String simpleName, JavaFileObject.Kind kind) {
return true; // fail-safe mode
}
@Override @DefinedBy(Api.COMPILER)
public NestingKind getNestingKind() {
return null;
}
@Override @DefinedBy(Api.COMPILER)
public Modifier getAccessLevel() {
return null;
}
/**
* Check if two file objects are equal.
* SourceFileObjects are just placeholder objects for the value of a

View File

@ -40,7 +40,7 @@ import com.sun.tools.javac.code.Attribute.RetentionPolicy;
import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.code.Type.*;
import com.sun.tools.javac.code.Types.UniqueType;
import com.sun.tools.javac.file.BaseFileObject;
import com.sun.tools.javac.file.PathFileObject;
import com.sun.tools.javac.jvm.Pool.DynamicMethod;
import com.sun.tools.javac.jvm.Pool.Method;
import com.sun.tools.javac.jvm.Pool.MethodHandle;
@ -52,6 +52,7 @@ import static com.sun.tools.javac.code.Kinds.Kind.*;
import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
import static com.sun.tools.javac.code.TypeTag.*;
import static com.sun.tools.javac.main.Option.*;
import static javax.tools.StandardLocation.CLASS_OUTPUT;
/** This class provides operations to map an internal symbol table graph
@ -1699,7 +1700,7 @@ public class ClassWriter extends ClassFile {
// the last possible moment because the sourcefile may be used
// elsewhere in error diagnostics. Fixes 4241573.
//databuf.appendChar(c.pool.put(c.sourcefile));
String simpleName = BaseFileObject.getSimpleName(c.sourcefile);
String simpleName = PathFileObject.getSimpleName(c.sourcefile);
databuf.appendChar(c.pool.put(names.fromString(simpleName)));
endAttr(alenIdx);
acount++;

View File

@ -141,8 +141,11 @@ public class Main {
JavacFileManager.preRegister(context); // can't create it until Log has been set up
Result result = compile(args, context);
if (fileManager instanceof JavacFileManager) {
// A fresh context was created above, so jfm must be a JavacFileManager
((JavacFileManager)fileManager).close();
try {
// A fresh context was created above, so jfm must be a JavacFileManager
((JavacFileManager)fileManager).close();
} catch (IOException ignore) {
}
}
return result;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2015, Oracle and/or its affiliates. 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
@ -45,7 +45,7 @@ import com.sun.tools.javac.code.Printer;
import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.Type;
import com.sun.tools.javac.code.Type.CapturedType;
import com.sun.tools.javac.file.BaseFileObject;
import com.sun.tools.javac.file.PathFileObject;
import com.sun.tools.javac.jvm.Profile;
import com.sun.tools.javac.tree.JCTree.*;
import com.sun.tools.javac.tree.Pretty;
@ -144,10 +144,10 @@ public abstract class AbstractDiagnosticFormatter implements DiagnosticFormatter
throw new IllegalArgumentException(); // d should have source set
if (fullname)
return fo.getName();
else if (fo instanceof BaseFileObject)
return ((BaseFileObject) fo).getShortName();
else if (fo instanceof PathFileObject)
return ((PathFileObject) fo).getShortName();
else
return BaseFileObject.getSimpleName(fo);
return PathFileObject.getSimpleName(fo);
}
/**

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2015, Oracle and/or its affiliates. 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
@ -31,7 +31,7 @@ import javax.tools.JavaFileObject;
import com.sun.tools.javac.api.DiagnosticFormatter.Configuration.*;
import com.sun.tools.javac.api.Formattable;
import com.sun.tools.javac.file.BaseFileObject;
import com.sun.tools.javac.file.PathFileObject;
import com.sun.tools.javac.tree.JCTree.*;
import com.sun.tools.javac.util.AbstractDiagnosticFormatter.SimpleConfiguration;
@ -123,8 +123,8 @@ public final class RawDiagnosticFormatter extends AbstractDiagnosticFormatter {
} else if (arg instanceof JCExpression) {
JCExpression tree = (JCExpression)arg;
s = "@" + tree.getStartPosition();
} else if (arg instanceof BaseFileObject) {
s = ((BaseFileObject) arg).getShortName();
} else if (arg instanceof PathFileObject) {
s = ((PathFileObject) arg).getShortName();
} else {
s = super.formatArgument(diag, arg, null);
}

View File

@ -115,7 +115,11 @@ public class SjavacImpl implements Sjavac {
// Clean up
JavaFileManager fileManager = context.get(JavaFileManager.class);
if (fileManager instanceof JavacFileManager) {
((JavacFileManager) fileManager).close();
try {
((JavacFileManager) fileManager).close();
} catch (IOException e) {
return RC_FATAL;
}
}
return result.exitCode;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2015, Oracle and/or its affiliates. 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
@ -103,10 +103,14 @@ public class SourcePositionImpl implements SourcePosition {
String fn = filename.getName();
if (fn.endsWith(")")) {
int paren = fn.lastIndexOf("(");
if (paren != -1)
if (paren != -1) {
int i = paren+1;
if (fn.charAt(i) == '/')
i++;
fn = fn.substring(0, paren)
+ File.separatorChar
+ fn.substring(paren + 1, fn.length() - 1);
+ fn.substring(i, fn.length() - 1);
}
}
if (position == Position.NOPOS)

View File

@ -53,9 +53,6 @@ import static javax.tools.StandardLocation.*;
* the impl of inferBinaryName for that file object.
*/
public class TestInferBinaryName {
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();
}
@ -64,10 +61,7 @@ public class TestInferBinaryName {
testDirectory();
File testJar = createJar();
testZipArchive(testJar);
testZipFileIndexArchive(testJar);
testZipFileIndexArchive2(testJar);
if (errors > 0)
throw new Exception(errors + " error found");
@ -87,40 +81,18 @@ public class TestInferBinaryName {
void testDirectory() throws IOException {
String testClassName = "p.A";
List<File> testClasses = Arrays.asList(new File(System.getProperty("test.classes")));
try (JavaFileManager fm =
getFileManager(testClasses, USE_ZIP_FILE_INDEX)) {
try (JavaFileManager fm = getFileManager(testClasses)) {
test("testDirectory",
fm, testClassName, "com.sun.tools.javac.file.RegularFileObject");
fm, testClassName, "SimpleFileObject");
}
}
void testZipArchive(File testJar) throws IOException {
String testClassName = "java.lang.String";
List<File> path = Arrays.asList(testJar);
try (JavaFileManager fm =
getFileManager(path, DONT_USE_ZIP_FILE_INDEX)) {
try (JavaFileManager fm = getFileManager(path)) {
test("testZipArchive",
fm, testClassName, "com.sun.tools.javac.file.ZipArchive$ZipFileObject");
}
}
void testZipFileIndexArchive(File testJar) throws IOException {
String testClassName = "java.lang.String";
List<File> path = Arrays.asList(testJar);
try (JavaFileManager fm =
getFileManager(path, USE_ZIP_FILE_INDEX)) {
test("testZipFileIndexArchive",
fm, testClassName, "com.sun.tools.javac.file.ZipFileIndexArchive$ZipFileIndexFileObject");
}
}
void testZipFileIndexArchive2(File testJar) throws IOException {
String testClassName = "java.lang.String";
List<File> path = Arrays.asList(testJar);
try (JavaFileManager fm =
getFileManager(path, USE_ZIP_FILE_INDEX)) {
test("testZipFileIndexArchive2",
fm, testClassName, "com.sun.tools.javac.file.ZipFileIndexArchive$ZipFileIndexFileObject");
fm, testClassName, "JarFileObject");
}
}
@ -141,21 +113,17 @@ public class TestInferBinaryName {
return;
}
String cn = fo.getClass().getName();
String cn = fo.getClass().getSimpleName();
String bn = fm.inferBinaryName(CLASS_PATH, fo);
System.err.println(testName + " " + cn + " " + bn);
check(cn, implClassName);
check(bn, testClassName);
checkEqual(cn, implClassName);
checkEqual(bn, testClassName);
System.err.println("OK");
}
JavaFileManager getFileManager(List<File> path,
boolean zipFileIndexKind)
JavaFileManager getFileManager(List<File> path)
throws IOException {
Context ctx = new Context();
Options options = Options.instance(ctx);
options.put("useOptimizedZip",
Boolean.toString(zipFileIndexKind == USE_ZIP_FILE_INDEX));
JavacFileManager fm = new JavacFileManager(ctx, false, null);
fm.setLocation(CLASS_PATH, path);
@ -163,7 +131,7 @@ public class TestInferBinaryName {
}
List<File> getPath(String s) {
List<File> path = new ArrayList<File>();
List<File> path = new ArrayList<>();
for (String f: s.split(File.pathSeparator)) {
if (f.length() > 0)
path.add(new File(f));
@ -172,7 +140,7 @@ public class TestInferBinaryName {
return path;
}
void check(String found, String expect) {
void checkEqual(String found, String expect) {
if (!found.equals(expect)) {
System.err.println("Expected: " + expect);
System.err.println(" Found: " + found);

View File

@ -53,7 +53,7 @@ public class T6358024 extends AbstractProcessor {
String testSrc = System.getProperty("test.src");
fm = new JavacFileManager(new Context(), false, null);
JavaFileObject f = fm.getFileForInput(testSrc + File.separatorChar + self + ".java");
JavaFileObject f = fm.getJavaFileObject(testSrc + File.separatorChar + self + ".java");
test(fm, f,
new Option[] { new Option("-d", ".")},

View File

@ -54,7 +54,7 @@ public class T6358166 extends AbstractProcessor {
String testSrc = System.getProperty("test.src");
JavacFileManager fm = new JavacFileManager(new Context(), false, null);
JavaFileObject f = fm.getFileForInput(testSrc + File.separatorChar + self + ".java");
JavaFileObject f = fm.getJavaFileObject(testSrc + File.separatorChar + self + ".java");
test(fm, f, "-verbose", "-d", ".");

View File

@ -1,99 +0,0 @@
/*
* Copyright (c) 2008, 2015, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 6705935
* @summary javac reports path name of entry in ZipFileIndex incorectly
* @modules jdk.compiler/com.sun.tools.javac.file
*/
import java.io.*;
import java.util.*;
import javax.tools.*;
import com.sun.tools.javac.file.*;
import com.sun.tools.javac.file.ZipArchive.ZipFileObject;
import com.sun.tools.javac.file.ZipFileIndexArchive.ZipFileIndexFileObject;
public class T6705935 {
public static void main(String... args) throws Exception {
new T6705935().run();
}
public void run() throws Exception {
File java_home = new File(System.getProperty("java.home"));
JavaCompiler c = ToolProvider.getSystemJavaCompiler();
try (StandardJavaFileManager fm = c.getStandardFileManager(null, null, null)) {
//System.err.println("platform class path: " + asList(fm.getLocation(StandardLocation.PLATFORM_CLASS_PATH)));
for (JavaFileObject fo: fm.list(StandardLocation.PLATFORM_CLASS_PATH,
"java.lang",
Collections.singleton(JavaFileObject.Kind.CLASS),
false)) {
test++;
if (!(fo instanceof ZipFileObject || fo instanceof ZipFileIndexFileObject)) {
System.out.println("Skip " + fo.getClass().getSimpleName() + " " + fo.getName());
skip++;
continue;
}
//System.err.println(fo.getName());
String p = fo.getName();
int bra = p.indexOf("(");
int ket = p.indexOf(")");
//System.err.println(bra + "," + ket + "," + p.length());
if (bra == -1 || ket != p.length() -1)
throw new Exception("unexpected path: " + p + "[" + bra + "," + ket + "," + p.length());
String part1 = p.substring(0, bra);
String part2 = p.substring(bra + 1, ket);
//System.err.println("[" + part1 + "|" + part2 + "]" + " " + java_home);
if (part1.equals(part2) || !part1.startsWith(java_home.getPath()))
throw new Exception("bad path: " + p);
}
if (test == 0)
throw new Exception("no files found");
if (skip == 0)
System.out.println(test + " files found");
else
System.out.println(test + " files found, " + skip + " files skipped");
if (test == skip)
System.out.println("Warning: all files skipped; no platform classes found in zip files.");
}
}
private <T> List<T> asList(Iterable<? extends T> items) {
List<T> list = new ArrayList<T>();
for (T item: items)
list.add(item);
return list;
}
private int skip;
private int test;
}

View File

@ -37,16 +37,15 @@
import java.io.File;
import java.io.IOException;
import java.util.Collections;
import java.util.Date;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import javax.tools.*;
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.file.ZipFileIndexCache;
import com.sun.tools.javac.util.Context;
public class T6725036 {
@ -63,21 +62,14 @@ public class T6725036 {
JarEntry je = j.getJarEntry(TEST_ENTRY_NAME.getPath());
long jarEntryTime = je.getTime();
ZipFileIndexCache zfic = ZipFileIndexCache.getSharedInstance();
ZipFileIndex zfi = zfic.getZipFileIndex(testJar.toPath(), null, false, null, false);
long zfiTime = zfi.getLastModified(TEST_ENTRY_NAME);
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);
JavaFileObject jfo =
zfia.getFileObject(TEST_ENTRY_NAME.dirname(),
TEST_ENTRY_NAME.basename());
long jfoTime = jfo.getLastModified();
fm.setLocation(StandardLocation.CLASS_PATH, Collections.singletonList(testJar));
FileObject fo =
fm.getFileForInput(StandardLocation.CLASS_PATH, "", TEST_ENTRY_NAME.getPath());
long jfoTime = fo.getLastModified();
check(je, jarEntryTime, jfo, jfoTime);
check(je, jarEntryTime, fo, jfoTime);
if (errors > 0)
throw new Exception(errors + " occurred");

View File

@ -55,19 +55,13 @@ public class T6440528 extends ToolTester {
"package-info.class",
src);
File expect = new File(test_src, "package-info.class");
File got = getUnderlyingFile(cls);
File got = fm.asPath(cls).toFile();
if (!got.equals(expect))
throw new AssertionError(String.format("Expected: %s; got: %s", expect, got));
System.err.println("Expected: " + expect);
System.err.println("Got: " + got);
}
private File getUnderlyingFile(FileObject o) throws Exception {
Field file = o.getClass().getDeclaredField("file"); // assumes RegularFileObject
file.setAccessible(true);
return ((Path)file.get(o)).toFile();
}
public static void main(String... args) throws Exception {
try (T6440528 t = new T6440528()) {
t.test(args);

View File

@ -24,7 +24,7 @@
/*
* @test
* @bug 6358955
* @summary JavacFileManager.getFileForInput(dir) shuld throw IAE
* @summary JavacFileManager.getFileForInput(dir) should throw IAE
* @modules java.compiler
* jdk.compiler
*/

View File

@ -32,18 +32,18 @@
import java.io.*;
import java.util.*;
import java.util.zip.*;
import javax.tools.*;
import javax.tools.JavaFileManager.Location;
import com.sun.tools.javac.file.JavacFileManager;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.Options;
public class T6838467 {
boolean fileSystemIsCaseSignificant = !new File("a").equals(new File("A"));
enum FileKind {
DIR("dir"),
ZIP("zip"),
ZIPFILEINDEX("zip");
ZIP("zip");
FileKind(String path) {
file = new File(path);
}
@ -52,15 +52,19 @@ public class T6838467 {
enum CompareKind {
SAME {
@Override
File other(File f) { return f; }
},
ABSOLUTE {
@Override
File other(File f) { return f.getAbsoluteFile(); }
},
DIFFERENT {
@Override
File other(File f) { return new File("not_" + f.getPath()); }
},
CASEEQUIV {
@Override
File other(File f) { return new File(f.getPath().toUpperCase()); }
};
abstract File other(File f);
@ -73,10 +77,17 @@ public class T6838467 {
}
void run() throws Exception {
boolean fileNameIsCaseSignificant = isFileNameCaseSignificant();
boolean fileLookupIsCaseSignificant = isFileLookupCaseSignificant();
String osName = System.getProperty("os.name");
System.err.println("OS: " + osName);
System.err.println("fileNameIsCaseSignificant:" + fileNameIsCaseSignificant);
System.err.println("fileLookupIsCaseSignificant:" + fileLookupIsCaseSignificant);
// on Windows, verify file system is not case significant
if (System.getProperty("os.name").toLowerCase().startsWith("windows")
&& fileSystemIsCaseSignificant) {
error("fileSystemIsCaseSignificant is set on Windows.");
if ((osName.startsWith("windows")) && fileNameIsCaseSignificant) {
error("fileNameIsCaseSignificant is set on " + osName + ".");
}
// create a set of directories and zip files to compare
@ -84,7 +95,7 @@ public class T6838467 {
createTestDir(new File("not_dir"), paths);
createTestZip(new File("zip"), paths);
createTestZip(new File("not_zip"), paths);
if (fileSystemIsCaseSignificant) {
if (fileNameIsCaseSignificant || fileLookupIsCaseSignificant) {
createTestDir(new File("DIR"), paths);
createTestZip(new File("ZIP"), paths);
}
@ -99,8 +110,9 @@ public class T6838467 {
// verify that the various different types of file object were all
// tested
Set<String> expectClasses = new HashSet<String>(Arrays.asList(
"RegularFileObject", "ZipFileObject", "ZipFileIndexFileObject" ));
Set<String> expectClasses = new HashSet<>(Arrays.asList(
"DirectoryFileObject",
"JarFileObject" ));
if (!foundClasses.equals(expectClasses)) {
error("expected fileobject classes not found\n"
+ "expected: " + expectClasses + "\n"
@ -112,26 +124,22 @@ public class T6838467 {
}
void test(FileKind fk, CompareKind ck) throws IOException {
File f1 = fk.file;
JavaFileManager fm1 = createFileManager(fk, f1);
try (StandardJavaFileManager fm = createFileManager()) {
File f1 = fk.file;
Location l1 = createLocation(fm, "l1", f1);
File f2 = ck.other(fk.file);
JavaFileManager fm2 = createFileManager(fk, f2);
File f2 = ck.other(fk.file);
Location l2 = createLocation(fm, "l2", f2);
try {
// If the directories or zip files match, we expect "n" matches in
// the "n-squared" comparisons to come, where "n" is the number of
// entries in the the directories or zip files.
// If the directories or zip files don't themselves match,
// we obviously don't expect any of their contents to match either.
int expect = (f1.getAbsoluteFile().equals(f2.getAbsoluteFile()) ? paths.length : 0);
int expectEqualCount = (f1.getCanonicalFile().equals(f2.getCanonicalFile()) ? paths.length : 0);
System.err.println("test " + (++count) + " " + fk + " " + ck + " " + f1 + " " + f2);
test(fm1, fm2, expect);
} finally {
fm1.close();
fm2.close();
test(fm, l1, l2, expectEqualCount);
}
}
@ -140,17 +148,17 @@ public class T6838467 {
// returned from the other. For each pair of files, verify that if they
// are equal, the hashcode is equal as well, and finally verify that the
// expected number of matches was found.
void test(JavaFileManager fm1, JavaFileManager fm2, int expectEqualCount) throws IOException {
void test(JavaFileManager fm, Location l1, Location l2, int expectEqualCount) throws IOException {
boolean foundFiles1 = false;
boolean foundFiles2 = false;
int foundEqualCount = 0;
Set<JavaFileObject.Kind> kinds = EnumSet.allOf(JavaFileObject.Kind.class);
for (FileObject fo1: fm1.list(StandardLocation.CLASS_PATH, "p", kinds, false)) {
for (FileObject fo1: fm.list(l1, "p", kinds, false)) {
foundFiles1 = true;
foundClasses.add(fo1.getClass().getSimpleName());
for (FileObject fo2: fm2.list(StandardLocation.CLASS_PATH, "p", kinds, false)) {
for (FileObject fo2: fm.list(l2, "p", kinds, false)) {
foundFiles2 = true;
foundClasses.add(fo1.getClass().getSimpleName());
foundClasses.add(fo2.getClass().getSimpleName());
System.err.println("compare " + fo1 + " " + fo2);
if (fo1.equals(fo2)) {
foundEqualCount++;
@ -163,26 +171,35 @@ public class T6838467 {
}
}
if (!foundFiles1)
error("no files found for file manager 1");
error("no files found for location " + l1);
if (!foundFiles2)
error("no files found for file manager 2");
error("no files found for location " + l2);
// verify the expected number of matches were found
if (foundEqualCount != expectEqualCount)
error("expected matches not found: expected " + expectEqualCount + ", found " + foundEqualCount);
}
// create a file manager to test a FileKind, with a given directory
// or zip file placed on the classpath
JavaFileManager createFileManager(FileKind fk, File classpath) throws IOException {
StandardJavaFileManager fm = createFileManager(fk == FileKind.ZIP);
fm.setLocation(StandardLocation.CLASS_PATH, Arrays.asList(classpath));
return fm;
// create and initialize a location to test a FileKind, with a given directory
// or zip file placed on the path
Location createLocation(StandardJavaFileManager fm, String name, File classpath) throws IOException {
Location l = new Location() {
@Override
public String getName() {
return name;
}
@Override
public boolean isOutputLocation() {
return false;
}
};
fm.setLocation(l, Arrays.asList(classpath));
return l;
}
JavacFileManager createFileManager(boolean useOptimizedZip) {
JavacFileManager createFileManager() {
Context ctx = new Context();
Options options = Options.instance(ctx);
options.put("useOptimizedZip", Boolean.toString(useOptimizedZip));
return new JavacFileManager(ctx, false, null);
}
@ -191,21 +208,17 @@ public class T6838467 {
for (String p: paths) {
File file = new File(dir, p);
file.getParentFile().mkdirs();
FileWriter out = new FileWriter(file);
try {
try (FileWriter out = new FileWriter(file)) {
out.write(p);
} finally {
out.close();
}
}
}
// create a sip file containing a given set of entries
// create a zip file containing a given set of entries
void createTestZip(File zip, String[] paths) throws IOException {
if (zip.getParentFile() != null)
zip.getParentFile().mkdirs();
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zip));
try {
try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zip))) {
for (String p: paths) {
ZipEntry ze = new ZipEntry(p);
zos.putNextEntry(ze);
@ -213,8 +226,6 @@ public class T6838467 {
zos.write(bytes, 0, bytes.length);
zos.closeEntry();
}
} finally {
zos.close();
}
}
@ -223,8 +234,24 @@ public class T6838467 {
errors++;
}
boolean isFileNameCaseSignificant() {
File lower = new File("test.txt");
File upper = new File(lower.getPath().toUpperCase());
return !lower.equals(upper);
}
boolean isFileLookupCaseSignificant() throws IOException {
File lower = new File("test.txt");
File upper = new File(lower.getPath().toUpperCase());
if (upper.exists()) {
upper.delete();
}
try (FileWriter out = new FileWriter(lower)) { }
return !upper.exists();
}
int count;
int errors;
Set<String> foundClasses = new HashSet<String>();
Set<String> foundClasses = new HashSet<>();
}

View File

@ -62,15 +62,12 @@ public class T6877206 {
test(createFileManager(), createDir("dir", entries), "p", entries.length);
test(createFileManager(), createDir("a b/dir", entries), "p", entries.length);
for (boolean useOptimizedZip: new boolean[] { false, true }) {
test(createFileManager(useOptimizedZip), createJar("jar", entries), "p", entries.length);
test(createFileManager(useOptimizedZip), createJar("jar jar", entries), "p", entries.length);
}
test(createFileManager(), createJar("jar", entries), "p", entries.length);
test(createFileManager(), createJar("jar jar", entries), "p", entries.length);
// Verify that we hit the files we intended
checkCoverage("classes", foundClasses,
"RegularFileObject", "ZipFileIndexFileObject", "ZipFileObject");
"DirectoryFileObject", "JarFileObject");
// Verify that we hit the jar files we intended
checkCoverage("jar files", foundJars, "jar", "jar jar");
@ -153,17 +150,12 @@ public class T6877206 {
}
JavacFileManager createFileManager() {
return createFileManager(false, false);
return createFileManager(false);
}
JavacFileManager createFileManager(boolean useOptimizedZip) {
return createFileManager(useOptimizedZip, false);
}
JavacFileManager createFileManager(boolean useOptimizedZip, boolean useSymbolFile) {
JavacFileManager createFileManager(boolean useSymbolFile) {
Context ctx = new Context();
Options options = Options.instance(ctx);
options.put("useOptimizedZip", Boolean.toString(useOptimizedZip));
if (!useSymbolFile) {
options.put("ignore.symbol.file", "true");
}

View File

@ -60,7 +60,6 @@ public class T8076104 extends AbstractProcessor {
void run() throws Exception {
File testJar = createJar();
doTest(testJar);
doTest(testJar, "-XDuseOptimizedZip=false");
}
File createJar() throws Exception {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2015, Oracle and/or its affiliates. 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
@ -136,8 +136,11 @@ public class Tester {
} catch (IllegalArgumentException | IllegalStateException | IOException e) {
tr.setThrown(e);
} finally {
((JavacFileManager) context.get(JavaFileManager.class)).close();
tr.setLogs(sw.toString(), sysOut.close(), sysErr.close());
try {
((JavacFileManager) context.get(JavaFileManager.class)).close();
tr.setLogs(sw.toString(), sysOut.close(), sysErr.close());
} catch (IOException e) {
}
}
tr.setContext(context);
tr.show();
@ -149,6 +152,7 @@ public class Tester {
class TestResult {
final List<String> args;
Throwable thrown;
List<Throwable> suppressed = new ArrayList<>();
Object rc; // Number or Boolean
Map<Log, String> logs;
Context context;
@ -172,6 +176,10 @@ public class Tester {
this.rc = ok ? 0 : 1;
}
void setSuppressed(Throwable thrown) {
this.suppressed.add(thrown);
}
void setThrown(Throwable thrown) {
this.thrown = thrown;
}
@ -199,6 +207,11 @@ public class Tester {
out.print("thrown:" + thrown);
needSep = true;
}
if (!suppressed.isEmpty()) {
if (needSep) out.print("; ");
out.print("suppressed:" + suppressed);
needSep = true;
}
if (needSep)
out.println();
logs.forEach((k, v) -> {

View File

@ -49,7 +49,7 @@ public class T4910483 {
String testSrc = System.getProperty("test.src");
JavacFileManager fm = new JavacFileManager(new Context(), false, null);
JavaFileObject f = fm.getFileForInput(testSrc + File.separatorChar + "T4910483.java");
JavaFileObject f = fm.getJavaFileObject(testSrc + File.separatorChar + "T4910483.java");
JCTree.JCCompilationUnit cu = compiler.parse(f);
JCTree classDef = cu.getTypeDecls().head;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2015, Oracle and/or its affiliates. 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
@ -88,7 +88,7 @@ public class Processor extends AbstractProcessor {
if (!testFile.canRead()) throw new IllegalStateException("Cannot read the test source");
JavacTool compiler = JavacTool.create();
JavacFileManager fm = compiler.getStandardFileManager(null, null, null);
testContent = fm.getRegularFile(testFile.toPath()).getCharContent(true).toString();
testContent = fm.getJavaFileObject(testFile.toPath()).getCharContent(true).toString();
JavaFileObject testFileObject = new TestFO(new URI("mem://" + args[0]), testContent);
TestFM testFileManager = new TestFM(fm);
JavacTask task = compiler.getTask(null,

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2015, Oracle and/or its affiliates. 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
@ -71,7 +71,7 @@ public class Processor extends AbstractProcessor {
File inp = new File(sp, args[0]);
if (inp.canRead()) {
testContent = fm.getRegularFile(inp.toPath()).getCharContent(true).toString();
testContent = fm.getJavaFileObject(inp.toPath()).getCharContent(true).toString();
}
}
if (testContent == null) throw new IllegalStateException();

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2015, Oracle and/or its affiliates. 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
@ -74,7 +74,7 @@ public class VerifySuppressWarnings {
File inp = new File(sp, args[0]);
if (inp.canRead()) {
testContent = fm.getRegularFile(inp.toPath()).getCharContent(true).toString();
testContent = fm.getJavaFileObject(inp.toPath()).getCharContent(true).toString();
}
}
if (testContent == null) throw new IllegalStateException();