8061876: replace java.io.File with java.nio.file.Path (again)

Reviewed-by: ksrini, jlahoda
This commit is contained in:
Jonathan Gibbons 2014-11-21 10:38:43 -08:00
parent 8bf55955df
commit bdf693fcc5
38 changed files with 678 additions and 385 deletions

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2005, 2009, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,20 +25,19 @@
package com.sun.tools.javac.file; package com.sun.tools.javac.file;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.Reader; import java.io.Reader;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.nio.charset.CharsetDecoder; import java.nio.charset.CharsetDecoder;
import java.nio.file.Path;
import javax.lang.model.element.Modifier; import javax.lang.model.element.Modifier;
import javax.lang.model.element.NestingKind; import javax.lang.model.element.NestingKind;
import javax.tools.FileObject; import javax.tools.FileObject;
import javax.tools.JavaFileObject; import javax.tools.JavaFileObject;
import static javax.tools.JavaFileObject.Kind.*;
import com.sun.tools.javac.util.BaseFileManager; import com.sun.tools.javac.util.BaseFileManager;
import com.sun.tools.javac.util.DefinedBy; import com.sun.tools.javac.util.DefinedBy;
import com.sun.tools.javac.util.DefinedBy.Api; import com.sun.tools.javac.util.DefinedBy.Api;
@ -78,7 +77,7 @@ public abstract class BaseFileObject implements JavaFileObject {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
protected abstract String inferBinaryName(Iterable<? extends File> path); protected abstract String inferBinaryName(Iterable<? extends Path> path);
protected static JavaFileObject.Kind getKind(String filename) { protected static JavaFileObject.Kind getKind(String filename) {
return BaseFileManager.getKind(filename); return BaseFileManager.getKind(filename);
@ -89,8 +88,8 @@ public abstract class BaseFileObject implements JavaFileObject {
return (lastDot == -1 ? fileName : fileName.substring(0, lastDot)); return (lastDot == -1 ? fileName : fileName.substring(0, lastDot));
} }
protected static URI createJarUri(File jarFile, String entryName) { protected static URI createJarUri(Path jarFile, String entryName) {
URI jarURI = jarFile.toURI().normalize(); URI jarURI = jarFile.toUri().normalize();
String separator = entryName.startsWith("/") ? "!" : "!/"; String separator = entryName.startsWith("/") ? "!" : "!/";
try { try {
// The jar URI convention appears to be not to re-encode the jarURI // The jar URI convention appears to be not to re-encode the jarURI

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,8 +25,8 @@
package com.sun.tools.javac.file; package com.sun.tools.javac.file;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Path;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
@ -61,31 +61,31 @@ public class CacheFSInfo extends FSInfo {
} }
@Override @Override
public File getCanonicalFile(File file) { public Path getCanonicalFile(Path file) {
Entry e = getEntry(file); Entry e = getEntry(file);
return e.canonicalFile; return e.canonicalFile;
} }
@Override @Override
public boolean exists(File file) { public boolean exists(Path file) {
Entry e = getEntry(file); Entry e = getEntry(file);
return e.exists; return e.exists;
} }
@Override @Override
public boolean isDirectory(File file) { public boolean isDirectory(Path file) {
Entry e = getEntry(file); Entry e = getEntry(file);
return e.isDirectory; return e.isDirectory;
} }
@Override @Override
public boolean isFile(File file) { public boolean isFile(Path file) {
Entry e = getEntry(file); Entry e = getEntry(file);
return e.isFile; return e.isFile;
} }
@Override @Override
public List<File> getJarClassPath(File file) throws IOException { public List<Path> getJarClassPath(Path file) throws IOException {
// don't bother to lock the cache, because it is thread-safe, and // don't bother to lock the cache, because it is thread-safe, and
// because the worst that can happen would be to create two identical // because the worst that can happen would be to create two identical
// jar class paths together and have one overwrite the other. // jar class paths together and have one overwrite the other.
@ -95,7 +95,7 @@ public class CacheFSInfo extends FSInfo {
return e.jarClassPath; return e.jarClassPath;
} }
private Entry getEntry(File file) { private Entry getEntry(Path file) {
// don't bother to lock the cache, because it is thread-safe, and // don't bother to lock the cache, because it is thread-safe, and
// because the worst that can happen would be to create two identical // because the worst that can happen would be to create two identical
// entries together and have one overwrite the other. // entries together and have one overwrite the other.
@ -112,13 +112,13 @@ public class CacheFSInfo extends FSInfo {
} }
// could also be a Map<File,SoftReference<Entry>> ? // could also be a Map<File,SoftReference<Entry>> ?
private Map<File,Entry> cache = new ConcurrentHashMap<>(); private final Map<Path,Entry> cache = new ConcurrentHashMap<>();
private static class Entry { private static class Entry {
File canonicalFile; Path canonicalFile;
boolean exists; boolean exists;
boolean isFile; boolean isFile;
boolean isDirectory; boolean isDirectory;
List<File> jarClassPath; List<Path> jarClassPath;
} }
} }

View file

@ -1,8 +1,10 @@
package com.sun.tools.javac.file; package com.sun.tools.javac.file;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@ -42,29 +44,29 @@ public class FSInfo {
context.put(FSInfo.class, this); context.put(FSInfo.class, this);
} }
public File getCanonicalFile(File file) { public Path getCanonicalFile(Path file) {
try { try {
return file.getCanonicalFile(); return file.toRealPath();
} catch (IOException e) { } catch (IOException e) {
return file.getAbsoluteFile(); return file.toAbsolutePath();
} }
} }
public boolean exists(File file) { public boolean exists(Path file) {
return file.exists(); return Files.exists(file);
} }
public boolean isDirectory(File file) { public boolean isDirectory(Path file) {
return file.isDirectory(); return Files.isDirectory(file);
} }
public boolean isFile(File file) { public boolean isFile(Path file) {
return file.isFile(); return Files.isRegularFile(file);
} }
public List<File> getJarClassPath(File file) throws IOException { public List<Path> getJarClassPath(Path file) throws IOException {
String parent = file.getParent(); Path parent = file.getParent();
try (JarFile jarFile = new JarFile(file)) { try (JarFile jarFile = new JarFile(file.toFile())) {
Manifest man = jarFile.getManifest(); Manifest man = jarFile.getManifest();
if (man == null) if (man == null)
return Collections.emptyList(); return Collections.emptyList();
@ -77,14 +79,14 @@ public class FSInfo {
if (path == null) if (path == null)
return Collections.emptyList(); return Collections.emptyList();
List<File> list = new ArrayList<>(); List<Path> list = new ArrayList<>();
for (StringTokenizer st = new StringTokenizer(path); for (StringTokenizer st = new StringTokenizer(path);
st.hasMoreTokens(); ) { st.hasMoreTokens(); ) {
String elt = st.nextToken(); String elt = st.nextToken();
File f = new File(elt); Path f = Paths.get(elt);
if (!f.isAbsolute() && parent != null) if (!f.isAbsolute() && parent != null)
f = new File(parent,elt).getAbsoluteFile(); f = parent.resolve(f).toAbsolutePath();
list.add(f); list.add(f);
} }

View file

@ -25,17 +25,21 @@
package com.sun.tools.javac.file; package com.sun.tools.javac.file;
import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.net.URL; import java.net.URL;
import java.nio.CharBuffer; import java.nio.CharBuffer;
import java.nio.charset.Charset; import java.nio.charset.Charset;
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.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
@ -46,6 +50,8 @@ import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.zip.ZipFile; import java.util.zip.ZipFile;
import javax.lang.model.SourceVersion; import javax.lang.model.SourceVersion;
@ -54,8 +60,8 @@ import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject; import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager; import javax.tools.StandardJavaFileManager;
import com.sun.tools.javac.file.RelativePath.RelativeFile;
import com.sun.tools.javac.file.RelativePath.RelativeDirectory; import com.sun.tools.javac.file.RelativePath.RelativeDirectory;
import com.sun.tools.javac.file.RelativePath.RelativeFile;
import com.sun.tools.javac.util.BaseFileManager; import com.sun.tools.javac.util.BaseFileManager;
import com.sun.tools.javac.util.Context; import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.DefinedBy; import com.sun.tools.javac.util.DefinedBy;
@ -95,15 +101,15 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
protected boolean mmappedIO; protected boolean mmappedIO;
protected boolean symbolFileEnabled; protected boolean symbolFileEnabled;
protected enum SortFiles implements Comparator<File> { protected enum SortFiles implements Comparator<Path> {
FORWARD { FORWARD {
public int compare(File f1, File f2) { public int compare(Path f1, Path f2) {
return f1.getName().compareTo(f2.getName()); return f1.getFileName().compareTo(f2.getFileName());
} }
}, },
REVERSE { REVERSE {
public int compare(File f1, File f2) { public int compare(Path f1, Path f2) {
return -f1.getName().compareTo(f2.getName()); return -f1.getFileName().compareTo(f2.getFileName());
} }
} }
} }
@ -162,10 +168,10 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
} }
public JavaFileObject getFileForInput(String name) { public JavaFileObject getFileForInput(String name) {
return getRegularFile(new File(name)); return getRegularFile(Paths.get(name));
} }
public JavaFileObject getRegularFile(File file) { public JavaFileObject getRegularFile(Path file) {
return new RegularFileObject(this, file); return new RegularFileObject(this, file);
} }
@ -255,25 +261,36 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
* Insert all files in subdirectory subdirectory of directory directory * Insert all files in subdirectory subdirectory of directory directory
* which match fileKinds into resultList * which match fileKinds into resultList
*/ */
private void listDirectory(File directory, private void listDirectory(Path directory,
RelativeDirectory subdirectory, RelativeDirectory subdirectory,
Set<JavaFileObject.Kind> fileKinds, Set<JavaFileObject.Kind> fileKinds,
boolean recurse, boolean recurse,
ListBuffer<JavaFileObject> resultList) { ListBuffer<JavaFileObject> resultList) {
File d = subdirectory.getFile(directory); Path d;
if (!caseMapCheck(d, subdirectory)) try {
d = subdirectory.getFile(directory);
} catch (InvalidPathException ignore) {
return; return;
}
File[] files = d.listFiles(); if (!Files.exists(d)) {
if (files == null) return;
}
if (!caseMapCheck(d, subdirectory)) {
return; return;
}
if (sortFiles != null) java.util.List<Path> files;
Arrays.sort(files, sortFiles); try (Stream<Path> s = Files.list(d)) {
files = (sortFiles == null ? s : s.sorted(sortFiles)).collect(Collectors.toList());
} catch (IOException ignore) {
return;
}
for (File f: files) { for (Path f: files) {
String fname = f.getName(); String fname = f.getFileName().toString();
if (f.isDirectory()) { if (Files.isDirectory(f)) {
if (recurse && SourceVersion.isIdentifier(fname)) { if (recurse && SourceVersion.isIdentifier(fname)) {
listDirectory(directory, listDirectory(directory,
new RelativeDirectory(subdirectory, fname), new RelativeDirectory(subdirectory, fname),
@ -284,7 +301,7 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
} else { } else {
if (isValidFile(fname, fileKinds)) { if (isValidFile(fname, fileKinds)) {
JavaFileObject fe = JavaFileObject fe =
new RegularFileObject(this, fname, new File(d, fname)); new RegularFileObject(this, fname, d.resolve(fname));
resultList.append(fe); resultList.append(fe);
} }
} }
@ -327,7 +344,7 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
* Insert all files in subdirectory subdirectory of container which * Insert all files in subdirectory subdirectory of container which
* match fileKinds into resultList * match fileKinds into resultList
*/ */
private void listContainer(File container, private void listContainer(Path container,
RelativeDirectory subdirectory, RelativeDirectory subdirectory,
Set<JavaFileObject.Kind> fileKinds, Set<JavaFileObject.Kind> fileKinds,
boolean recurse, boolean recurse,
@ -372,13 +389,15 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
* ends in a string of characters with the same case as given name. * ends in a string of characters with the same case as given name.
* Ignore file separators in both path and name. * Ignore file separators in both path and name.
*/ */
private boolean caseMapCheck(File f, RelativePath name) { private boolean caseMapCheck(Path f, RelativePath name) {
if (fileSystemIsCaseSensitive) return true; if (fileSystemIsCaseSensitive) return true;
// Note that getCanonicalPath() returns the case-sensitive // Note that toRealPath() returns the case-sensitive
// spelled file name. // spelled file name.
String path; String path;
char sep;
try { try {
path = f.getCanonicalPath(); path = f.toRealPath(LinkOption.NOFOLLOW_LINKS).toString();
sep = f.getFileSystem().getSeparator().charAt(0);
} catch (IOException ex) { } catch (IOException ex) {
return false; return false;
} }
@ -387,7 +406,7 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
int i = pcs.length - 1; int i = pcs.length - 1;
int j = ncs.length - 1; int j = ncs.length - 1;
while (i >= 0 && j >= 0) { while (i >= 0 && j >= 0) {
while (i >= 0 && pcs[i] == File.separatorChar) i--; while (i >= 0 && pcs[i] == sep) i--;
while (j >= 0 && ncs[j] == '/') j--; while (j >= 0 && ncs[j] == '/') j--;
if (i >= 0 && j >= 0) { if (i >= 0 && j >= 0) {
if (pcs[i] != ncs[j]) return false; if (pcs[i] != ncs[j]) return false;
@ -415,8 +434,8 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
} }
public class MissingArchive implements Archive { public class MissingArchive implements Archive {
final File zipFileName; final Path zipFileName;
public MissingArchive(File name) { public MissingArchive(Path name) {
zipFileName = name; zipFileName = name;
} }
public boolean contains(RelativePath name) { public boolean contains(RelativePath name) {
@ -446,7 +465,7 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
/** A directory of zip files already opened. /** A directory of zip files already opened.
*/ */
Map<File, Archive> archives = new HashMap<>(); Map<Path, Archive> archives = new HashMap<>();
private static final String[] symbolFileLocation = { "lib", "ct.sym" }; private static final String[] symbolFileLocation = { "lib", "ct.sym" };
private static final RelativeDirectory symbolFilePrefix private static final RelativeDirectory symbolFilePrefix
@ -458,7 +477,7 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
* fail over to the platform zip, and allow it to deal with a potentially * fail over to the platform zip, and allow it to deal with a potentially
* non compliant zip file. * non compliant zip file.
*/ */
protected Archive openArchive(File zipFilename) throws IOException { protected Archive openArchive(Path zipFilename) throws IOException {
try { try {
return openArchive(zipFilename, contextUseOptimizedZip); return openArchive(zipFilename, contextUseOptimizedZip);
} catch (IOException ioe) { } catch (IOException ioe) {
@ -472,17 +491,17 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
/** Open a new zip file directory, and cache it. /** Open a new zip file directory, and cache it.
*/ */
private Archive openArchive(File zipFileName, boolean useOptimizedZip) throws IOException { private Archive openArchive(Path zipFileName, boolean useOptimizedZip) throws IOException {
File origZipFileName = zipFileName; Path origZipFileName = zipFileName;
if (symbolFileEnabled && locations.isDefaultBootClassPathRtJar(zipFileName)) { if (symbolFileEnabled && locations.isDefaultBootClassPathRtJar(zipFileName)) {
File file = zipFileName.getParentFile().getParentFile(); // ${java.home} Path file = zipFileName.getParent().getParent(); // ${java.home}
if (new File(file.getName()).equals(new File("jre"))) if (file.getFileName().equals(Paths.get("jre")))
file = file.getParentFile(); file = file.getParent();
// file == ${jdk.home} // file == ${jdk.home}
for (String name : symbolFileLocation) for (String name : symbolFileLocation)
file = new File(file, name); file = file.resolve(name);
// file == ${jdk.home}/lib/ct.sym // file == ${jdk.home}/lib/ct.sym
if (file.exists()) if (Files.exists(file))
zipFileName = file; zipFileName = file;
} }
@ -495,7 +514,7 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
String preindexCacheLocation = null; String preindexCacheLocation = null;
if (!useOptimizedZip) { if (!useOptimizedZip) {
zdir = new ZipFile(zipFileName); zdir = new ZipFile(zipFileName.toFile());
} else { } else {
usePreindexedCache = options.isSet("usezipindex"); usePreindexedCache = options.isSet("usezipindex");
preindexCacheLocation = options.get("java.io.tmpdir"); preindexCacheLocation = options.get("java.io.tmpdir");
@ -545,12 +564,12 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
options.isSet("writezipindexfiles"))); options.isSet("writezipindexfiles")));
} }
} }
} catch (FileNotFoundException ex) { } catch (FileNotFoundException | NoSuchFileException ex) {
archive = new MissingArchive(zipFileName); archive = new MissingArchive(zipFileName);
} catch (ZipFileIndex.ZipFormatException zfe) { } catch (ZipFileIndex.ZipFormatException zfe) {
throw zfe; throw zfe;
} catch (IOException ex) { } catch (IOException ex) {
if (zipFileName.exists()) if (Files.exists(zipFileName))
log.error("error.reading.file", zipFileName, getMessage(ex)); log.error("error.reading.file", zipFileName, getMessage(ex));
archive = new MissingArchive(zipFileName); archive = new MissingArchive(zipFileName);
} }
@ -610,13 +629,13 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
nullCheck(packageName); nullCheck(packageName);
nullCheck(kinds); nullCheck(kinds);
Iterable<? extends File> path = getLocation(location); Iterable<? extends Path> path = asPaths(getLocation(location));
if (path == null) if (path == null)
return List.nil(); return List.nil();
RelativeDirectory subdirectory = RelativeDirectory.forPackage(packageName); RelativeDirectory subdirectory = RelativeDirectory.forPackage(packageName);
ListBuffer<JavaFileObject> results = new ListBuffer<>(); ListBuffer<JavaFileObject> results = new ListBuffer<>();
for (File directory : path) for (Path directory : path)
listContainer(directory, subdirectory, kinds, recurse, results); listContainer(directory, subdirectory, kinds, recurse, results);
return results.toList(); return results.toList();
} }
@ -626,7 +645,7 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
file.getClass(); // null check file.getClass(); // null check
location.getClass(); // null check location.getClass(); // null check
// Need to match the path semantics of list(location, ...) // Need to match the path semantics of list(location, ...)
Iterable<? extends File> path = getLocation(location); Iterable<? extends Path> path = getLocationAsPaths(location);
if (path == null) { if (path == null) {
return null; return null;
} }
@ -686,17 +705,20 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
} }
private JavaFileObject getFileForInput(Location location, RelativeFile name) throws IOException { private JavaFileObject getFileForInput(Location location, RelativeFile name) throws IOException {
Iterable<? extends File> path = getLocation(location); Iterable<? extends Path> path = asPaths(getLocation(location));
if (path == null) if (path == null)
return null; return null;
for (File dir: path) { for (Path dir: path) {
Archive a = archives.get(dir); Archive a = archives.get(dir);
if (a == null) { if (a == null) {
if (fsInfo.isDirectory(dir)) { if (fsInfo.isDirectory(dir)) {
File f = name.getFile(dir); try {
if (f.exists()) Path f = name.getFile(dir);
return new RegularFileObject(this, f); if (Files.exists(f))
return new RegularFileObject(this, f);
} catch (InvalidPathException ignore) {
}
continue; continue;
} }
// Not a directory, create the archive // Not a directory, create the archive
@ -749,31 +771,37 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
FileObject sibling) FileObject sibling)
throws IOException throws IOException
{ {
File dir; Path dir;
if (location == CLASS_OUTPUT) { if (location == CLASS_OUTPUT) {
if (getClassOutDir() != null) { if (getClassOutDir() != null) {
dir = getClassOutDir(); dir = getClassOutDir();
} else { } else {
File siblingDir = null; Path siblingDir = null;
if (sibling != null && sibling instanceof RegularFileObject) { if (sibling != null && sibling instanceof RegularFileObject) {
siblingDir = ((RegularFileObject)sibling).file.getParentFile(); siblingDir = ((RegularFileObject)sibling).file.getParent();
} }
return new RegularFileObject(this, new File(siblingDir, fileName.basename())); 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) { } else if (location == SOURCE_OUTPUT) {
dir = (getSourceOutDir() != null ? getSourceOutDir() : getClassOutDir()); dir = (getSourceOutDir() != null ? getSourceOutDir() : getClassOutDir());
} else { } else {
Iterable<? extends File> path = locations.getLocation(location); Iterable<? extends Path> path = locations.getLocation(location);
dir = null; dir = null;
for (File f: path) { for (Path f: path) {
dir = f; dir = f;
break; break;
} }
} }
File file = fileName.getFile(dir); // null-safe try {
return new RegularFileObject(this, file); Path file = fileName.getFile(dir); // null-safe
return new RegularFileObject(this, file);
} catch (InvalidPathException e) {
throw new IOException("bad filename " + fileName, e);
}
} }
@DefinedBy(Api.COMPILER) @DefinedBy(Api.COMPILER)
@ -786,7 +814,7 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
else else
result = new ArrayList<>(); result = new ArrayList<>();
for (File f: files) for (File f: files)
result.add(new RegularFileObject(this, nullCheck(f))); result.add(new RegularFileObject(this, nullCheck(f).toPath()));
return result; return result;
} }
@ -797,24 +825,29 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
@DefinedBy(Api.COMPILER) @DefinedBy(Api.COMPILER)
public void setLocation(Location location, public void setLocation(Location location,
Iterable<? extends File> path) Iterable<? extends File> searchpath)
throws IOException throws IOException
{ {
nullCheck(location); nullCheck(location);
locations.setLocation(location, path); locations.setLocation(location, asPaths(searchpath));
} }
@DefinedBy(Api.COMPILER) @DefinedBy(Api.COMPILER)
public Iterable<? extends File> getLocation(Location location) { public Iterable<? extends File> getLocation(Location location) {
nullCheck(location);
return asFiles(locations.getLocation(location));
}
private Iterable<? extends Path> getLocationAsPaths(Location location) {
nullCheck(location); nullCheck(location);
return locations.getLocation(location); return locations.getLocation(location);
} }
private File getClassOutDir() { private Path getClassOutDir() {
return locations.getOutputLocation(CLASS_OUTPUT); return locations.getOutputLocation(CLASS_OUTPUT);
} }
private File getSourceOutDir() { private Path getSourceOutDir() {
return locations.getOutputLocation(SOURCE_OUTPUT); return locations.getOutputLocation(SOURCE_OUTPUT);
} }
@ -885,4 +918,50 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
return s; return s;
return e.toString(); return e.toString();
} }
/* Converters between files and paths.
* These are temporary until we can update the StandardJavaFileManager API.
*/
static Iterable<Path> asPaths(final Iterable<? extends File> files) {
if (files == null)
return null;
return () -> new Iterator<Path>() {
Iterator<? extends File> iter = files.iterator();
@Override
public boolean hasNext() {
return iter.hasNext();
}
@Override
public Path next() {
return iter.next().toPath();
}
};
}
static Iterable<File> asFiles(final Iterable<? extends Path> paths) {
if (paths == null)
return null;
return () -> new Iterator<File>() {
Iterator<? extends Path> iter = paths.iterator();
@Override
public boolean hasNext() {
return iter.hasNext();
}
@Override
public File next() {
return iter.next().toFile();
}
};
}
static File asFile(Path path) {
return path == null ? null : path.toFile();
}
} }

View file

@ -29,6 +29,10 @@ import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
@ -40,7 +44,8 @@ import java.util.Iterator;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.StringTokenizer; import java.util.regex.Pattern;
import java.util.stream.Stream;
import java.util.zip.ZipFile; import java.util.zip.ZipFile;
import javax.tools.JavaFileManager; import javax.tools.JavaFileManager;
@ -105,7 +110,7 @@ public class Locations {
this.fsInfo = fsInfo; this.fsInfo = fsInfo;
} }
public Collection<File> bootClassPath() { public Collection<Path> bootClassPath() {
return getLocation(PLATFORM_CLASS_PATH); return getLocation(PLATFORM_CLASS_PATH);
} }
@ -115,56 +120,52 @@ public class Locations {
return h.isDefault(); return h.isDefault();
} }
boolean isDefaultBootClassPathRtJar(File file) { boolean isDefaultBootClassPathRtJar(Path file) {
BootClassPathLocationHandler h BootClassPathLocationHandler h
= (BootClassPathLocationHandler) getHandler(PLATFORM_CLASS_PATH); = (BootClassPathLocationHandler) getHandler(PLATFORM_CLASS_PATH);
return h.isDefaultRtJar(file); return h.isDefaultRtJar(file);
} }
public Collection<File> userClassPath() { public Collection<Path> userClassPath() {
return getLocation(CLASS_PATH); return getLocation(CLASS_PATH);
} }
public Collection<File> sourcePath() { public Collection<Path> sourcePath() {
Collection<File> p = getLocation(SOURCE_PATH); Collection<Path> p = getLocation(SOURCE_PATH);
// TODO: this should be handled by the LocationHandler // TODO: this should be handled by the LocationHandler
return p == null || p.isEmpty() ? null : p; return p == null || p.isEmpty() ? null : p;
} }
/** /**
* Split a path into its elements. Empty path elements will be ignored. * Split a search path into its elements. Empty path elements will be ignored.
* *
* @param path The path to be split * @param searchPath The search path to be split
* @return The elements of the path * @return The elements of the path
*/ */
private static Iterable<File> getPathEntries(String path) { private static Iterable<Path> getPathEntries(String searchPath) {
return getPathEntries(path, null); return getPathEntries(searchPath, null);
} }
/** /**
* Split a path into its elements. If emptyPathDefault is not null, all empty elements in the * Split a search path into its elements. If emptyPathDefault is not null, all empty elements in the
* path, including empty elements at either end of the path, will be replaced with the value of * path, including empty elements at either end of the path, will be replaced with the value of
* emptyPathDefault. * emptyPathDefault.
* *
* @param path The path to be split * @param searchPath The search path to be split
* @param emptyPathDefault The value to substitute for empty path elements, or null, to ignore * @param emptyPathDefault The value to substitute for empty path elements, or null, to ignore
* empty path elements * empty path elements
* @return The elements of the path * @return The elements of the path
*/ */
private static Iterable<File> getPathEntries(String path, File emptyPathDefault) { private static Iterable<Path> getPathEntries(String searchPath, Path emptyPathDefault) {
ListBuffer<File> entries = new ListBuffer<>(); ListBuffer<Path> entries = new ListBuffer<>();
int start = 0; for (String s: searchPath.split(Pattern.quote(File.pathSeparator), -1)) {
while (start <= path.length()) { if (s.isEmpty()) {
int sep = path.indexOf(File.pathSeparatorChar, start); if (emptyPathDefault != null) {
if (sep == -1) { entries.add(emptyPathDefault);
sep = path.length(); }
} else {
entries.add(Paths.get(s));
} }
if (start < sep) {
entries.add(new File(path.substring(start, sep)));
} else if (emptyPathDefault != null) {
entries.add(emptyPathDefault);
}
start = sep + 1;
} }
return entries; return entries;
} }
@ -173,12 +174,12 @@ public class Locations {
* Utility class to help evaluate a path option. Duplicate entries are ignored, jar class paths * Utility class to help evaluate a path option. Duplicate entries are ignored, jar class paths
* can be expanded. * can be expanded.
*/ */
private class SearchPath extends LinkedHashSet<File> { private class SearchPath extends LinkedHashSet<Path> {
private static final long serialVersionUID = 0; private static final long serialVersionUID = 0;
private boolean expandJarClassPaths = false; private boolean expandJarClassPaths = false;
private final Set<File> canonicalValues = new HashSet<>(); private final Set<Path> canonicalValues = new HashSet<>();
public SearchPath expandJarClassPaths(boolean x) { public SearchPath expandJarClassPaths(boolean x) {
expandJarClassPaths = x; expandJarClassPaths = x;
@ -188,9 +189,9 @@ public class Locations {
/** /**
* What to use when path element is the empty string * What to use when path element is the empty string
*/ */
private File emptyPathDefault = null; private Path emptyPathDefault = null;
public SearchPath emptyPathDefault(File x) { public SearchPath emptyPathDefault(Path x) {
emptyPathDefault = x; emptyPathDefault = x;
return this; return this;
} }
@ -200,7 +201,7 @@ public class Locations {
expandJarClassPaths = true; expandJarClassPaths = true;
try { try {
if (dirs != null) { if (dirs != null) {
for (File dir : getPathEntries(dirs)) { for (Path dir : getPathEntries(dirs)) {
addDirectory(dir, warn); addDirectory(dir, warn);
} }
} }
@ -214,8 +215,8 @@ public class Locations {
return addDirectories(dirs, warn); return addDirectories(dirs, warn);
} }
private void addDirectory(File dir, boolean warn) { private void addDirectory(Path dir, boolean warn) {
if (!dir.isDirectory()) { if (!Files.isDirectory(dir)) {
if (warn) { if (warn) {
log.warning(Lint.LintCategory.PATH, log.warning(Lint.LintCategory.PATH,
"dir.path.element.not.found", dir); "dir.path.element.not.found", dir);
@ -223,15 +224,10 @@ public class Locations {
return; return;
} }
File[] files = dir.listFiles(); try (Stream<Path> s = Files.list(dir)) {
if (files == null) { s.filter(dirEntry -> isArchive(dirEntry))
return; .forEach(dirEntry -> addFile(dirEntry, warn));
} } catch (IOException ignore) {
for (File direntry : files) {
if (isArchive(direntry)) {
addFile(direntry, warn);
}
} }
} }
@ -246,20 +242,20 @@ public class Locations {
return addFiles(files, warn); return addFiles(files, warn);
} }
public SearchPath addFiles(Iterable<? extends File> files, boolean warn) { public SearchPath addFiles(Iterable<? extends Path> files, boolean warn) {
if (files != null) { if (files != null) {
for (File file : files) { for (Path file : files) {
addFile(file, warn); addFile(file, warn);
} }
} }
return this; return this;
} }
public SearchPath addFiles(Iterable<? extends File> files) { public SearchPath addFiles(Iterable<? extends Path> files) {
return addFiles(files, warn); return addFiles(files, warn);
} }
public void addFile(File file, boolean warn) { public void addFile(Path file, boolean warn) {
if (contains(file)) { if (contains(file)) {
// discard duplicates // discard duplicates
return; return;
@ -275,7 +271,7 @@ public class Locations {
return; return;
} }
File canonFile = fsInfo.getCanonicalFile(file); Path canonFile = fsInfo.getCanonicalFile(file);
if (canonicalValues.contains(canonFile)) { if (canonicalValues.contains(canonFile)) {
/* Discard duplicates and avoid infinite recursion */ /* Discard duplicates and avoid infinite recursion */
return; return;
@ -287,7 +283,7 @@ public class Locations {
/* Not a recognized extension; open it to see if /* Not a recognized extension; open it to see if
it looks like a valid zip file. */ it looks like a valid zip file. */
try { try {
ZipFile z = new ZipFile(file); ZipFile z = new ZipFile(file.toFile());
z.close(); z.close();
if (warn) { if (warn) {
log.warning(Lint.LintCategory.PATH, log.warning(Lint.LintCategory.PATH,
@ -318,9 +314,9 @@ public class Locations {
// Manifest entry. In some future release, we may want to // Manifest entry. In some future release, we may want to
// update this code to recognize URLs rather than simple // update this code to recognize URLs rather than simple
// filenames, but if we do, we should redo all path-related code. // filenames, but if we do, we should redo all path-related code.
private void addJarClassPath(File jarFile, boolean warn) { private void addJarClassPath(Path jarFile, boolean warn) {
try { try {
for (File f : fsInfo.getJarClassPath(jarFile)) { for (Path f : fsInfo.getJarClassPath(jarFile)) {
addFile(f, warn); addFile(f, warn);
} }
} catch (IOException e) { } catch (IOException e) {
@ -365,12 +361,12 @@ public class Locations {
/** /**
* @see StandardJavaFileManager#getLocation * @see StandardJavaFileManager#getLocation
*/ */
abstract Collection<File> getLocation(); abstract Collection<Path> getLocation();
/** /**
* @see StandardJavaFileManager#setLocation * @see StandardJavaFileManager#setLocation
*/ */
abstract void setLocation(Iterable<? extends File> files) throws IOException; abstract void setLocation(Iterable<? extends Path> files) throws IOException;
} }
/** /**
@ -380,7 +376,7 @@ public class Locations {
*/ */
private class OutputLocationHandler extends LocationHandler { private class OutputLocationHandler extends LocationHandler {
private File outputDir; private Path outputDir;
OutputLocationHandler(Location location, Option... options) { OutputLocationHandler(Location location, Option... options) {
super(location, options); super(location, options);
@ -396,31 +392,31 @@ public class Locations {
// need to decide how best to report issue for benefit of // need to decide how best to report issue for benefit of
// direct API call on JavaFileManager.handleOption(specifies IAE) // direct API call on JavaFileManager.handleOption(specifies IAE)
// vs. command line decoding. // vs. command line decoding.
outputDir = (value == null) ? null : new File(value); outputDir = (value == null) ? null : Paths.get(value);
return true; return true;
} }
@Override @Override
Collection<File> getLocation() { Collection<Path> getLocation() {
return (outputDir == null) ? null : Collections.singleton(outputDir); return (outputDir == null) ? null : Collections.singleton(outputDir);
} }
@Override @Override
void setLocation(Iterable<? extends File> files) throws IOException { void setLocation(Iterable<? extends Path> files) throws IOException {
if (files == null) { if (files == null) {
outputDir = null; outputDir = null;
} else { } else {
Iterator<? extends File> pathIter = files.iterator(); Iterator<? extends Path> pathIter = files.iterator();
if (!pathIter.hasNext()) { if (!pathIter.hasNext()) {
throw new IllegalArgumentException("empty path for directory"); throw new IllegalArgumentException("empty path for directory");
} }
File dir = pathIter.next(); Path dir = pathIter.next();
if (pathIter.hasNext()) { if (pathIter.hasNext()) {
throw new IllegalArgumentException("path too long for directory"); throw new IllegalArgumentException("path too long for directory");
} }
if (!dir.exists()) { if (!Files.exists(dir)) {
throw new FileNotFoundException(dir + ": does not exist"); throw new FileNotFoundException(dir + ": does not exist");
} else if (!dir.isDirectory()) { } else if (!Files.isDirectory(dir)) {
throw new IOException(dir + ": not a directory"); throw new IOException(dir + ": not a directory");
} }
outputDir = dir; outputDir = dir;
@ -435,7 +431,7 @@ public class Locations {
*/ */
private class SimpleLocationHandler extends LocationHandler { private class SimpleLocationHandler extends LocationHandler {
protected Collection<File> searchPath; protected Collection<Path> searchPath;
SimpleLocationHandler(Location location, Option... options) { SimpleLocationHandler(Location location, Option... options) {
super(location, options); super(location, options);
@ -452,12 +448,12 @@ public class Locations {
} }
@Override @Override
Collection<File> getLocation() { Collection<Path> getLocation() {
return searchPath; return searchPath;
} }
@Override @Override
void setLocation(Iterable<? extends File> files) { void setLocation(Iterable<? extends Path> files) {
SearchPath p; SearchPath p;
if (files == null) { if (files == null) {
p = computePath(null); p = computePath(null);
@ -488,7 +484,7 @@ public class Locations {
} }
@Override @Override
Collection<File> getLocation() { Collection<Path> getLocation() {
lazy(); lazy();
return searchPath; return searchPath;
} }
@ -520,7 +516,7 @@ public class Locations {
protected SearchPath createPath() { protected SearchPath createPath() {
return new SearchPath() return new SearchPath()
.expandJarClassPaths(true) // Only search user jars for Class-Paths .expandJarClassPaths(true) // Only search user jars for Class-Paths
.emptyPathDefault(new File(".")); // Empty path elt ==> current directory .emptyPathDefault(Paths.get(".")); // Empty path elt ==> current directory
} }
private void lazy() { private void lazy() {
@ -539,14 +535,14 @@ public class Locations {
*/ */
private class BootClassPathLocationHandler extends LocationHandler { private class BootClassPathLocationHandler extends LocationHandler {
private Collection<File> searchPath; private Collection<Path> searchPath;
final Map<Option, String> optionValues = new EnumMap<>(Option.class); final Map<Option, String> optionValues = new EnumMap<>(Option.class);
/** /**
* rt.jar as found on the default bootclasspath. If the user specified a bootclasspath, null * rt.jar as found on the default bootclasspath. If the user specified a bootclasspath, null
* is used. * is used.
*/ */
private File defaultBootClassPathRtJar = null; private Path defaultBootClassPathRtJar = null;
/** /**
* Is bootclasspath the default? * Is bootclasspath the default?
@ -567,7 +563,7 @@ public class Locations {
return isDefaultBootClassPath; return isDefaultBootClassPath;
} }
boolean isDefaultRtJar(File file) { boolean isDefaultRtJar(Path file) {
lazy(); lazy();
return file.equals(defaultBootClassPathRtJar); return file.equals(defaultBootClassPathRtJar);
} }
@ -604,13 +600,13 @@ public class Locations {
} }
@Override @Override
Collection<File> getLocation() { Collection<Path> getLocation() {
lazy(); lazy();
return searchPath; return searchPath;
} }
@Override @Override
void setLocation(Iterable<? extends File> files) { void setLocation(Iterable<? extends Path> files) {
if (files == null) { if (files == null) {
searchPath = null; // reset to "uninitialized" searchPath = null; // reset to "uninitialized"
} else { } else {
@ -645,9 +641,9 @@ public class Locations {
// Standard system classes for this compiler's release. // Standard system classes for this compiler's release.
String files = System.getProperty("sun.boot.class.path"); String files = System.getProperty("sun.boot.class.path");
path.addFiles(files, false); path.addFiles(files, false);
File rt_jar = new File("rt.jar"); Path rt_jar = Paths.get("rt.jar");
for (File file : getPathEntries(files)) { for (Path file : getPathEntries(files)) {
if (new File(file.getName()).equals(rt_jar)) { if (file.getFileName().equals(rt_jar)) {
defaultBootClassPathRtJar = file; defaultBootClassPathRtJar = file;
} }
} }
@ -709,12 +705,12 @@ public class Locations {
return (h == null ? false : h.handleOption(option, value)); return (h == null ? false : h.handleOption(option, value));
} }
Collection<File> getLocation(Location location) { Collection<Path> getLocation(Location location) {
LocationHandler h = getHandler(location); LocationHandler h = getHandler(location);
return (h == null ? null : h.getLocation()); return (h == null ? null : h.getLocation());
} }
File getOutputLocation(Location location) { Path getOutputLocation(Location location) {
if (!location.isOutputLocation()) { if (!location.isOutputLocation()) {
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }
@ -722,7 +718,7 @@ public class Locations {
return ((OutputLocationHandler) h).outputDir; return ((OutputLocationHandler) h).outputDir;
} }
void setLocation(Location location, Iterable<? extends File> files) throws IOException { void setLocation(Location location, Iterable<? extends Path> files) throws IOException {
LocationHandler h = getHandler(location); LocationHandler h = getHandler(location);
if (h == null) { if (h == null) {
if (location.isOutputLocation()) { if (location.isOutputLocation()) {
@ -743,8 +739,8 @@ public class Locations {
/** /**
* Is this the name of an archive file? * Is this the name of an archive file?
*/ */
private boolean isArchive(File file) { private boolean isArchive(Path file) {
String n = StringUtils.toLowerCase(file.getName()); String n = StringUtils.toLowerCase(file.getFileName().toString());
return fsInfo.isFile(file) return fsInfo.isFile(file)
&& (n.endsWith(".jar") || n.endsWith(".zip")); && (n.endsWith(".jar") || n.endsWith(".zip"));
} }
@ -753,50 +749,41 @@ public class Locations {
* Utility method for converting a search path string to an array of directory and JAR file * Utility method for converting a search path string to an array of directory and JAR file
* URLs. * URLs.
* *
* Note that this method is called by apt and the DocletInvoker. * Note that this method is called by the DocletInvoker.
* *
* @param path the search path string * @param path the search path string
* @return the resulting array of directory and JAR file URLs * @return the resulting array of directory and JAR file URLs
*/ */
public static URL[] pathToURLs(String path) { public static URL[] pathToURLs(String path) {
StringTokenizer st = new StringTokenizer(path, File.pathSeparator); java.util.List<URL> urls = new ArrayList<>();
URL[] urls = new URL[st.countTokens()]; for (String s: path.split(Pattern.quote(File.pathSeparator))) {
int count = 0; if (!s.isEmpty()) {
while (st.hasMoreTokens()) { URL url = fileToURL(Paths.get(s));
URL url = fileToURL(new File(st.nextToken())); if (url != null) {
if (url != null) { urls.add(url);
urls[count++] = url; }
} }
} }
urls = Arrays.copyOf(urls, count); return urls.toArray(new URL[urls.size()]);
return urls;
} }
/** /**
* Returns the directory or JAR file URL corresponding to the specified local file name. * Returns the directory or JAR file URL corresponding to the specified local file name.
* *
* @param file the File object * @param file the Path object
* @return the resulting directory or JAR file URL, or null if unknown * @return the resulting directory or JAR file URL, or null if unknown
*/ */
private static URL fileToURL(File file) { private static URL fileToURL(Path file) {
String name; Path p;
try { try {
name = file.getCanonicalPath(); p = file.toRealPath();
} catch (IOException e) { } catch (IOException e) {
name = file.getAbsolutePath(); p = file.toAbsolutePath();
}
name = name.replace(File.separatorChar, '/');
if (!name.startsWith("/")) {
name = "/" + name;
}
// If the file does not exist, then assume that it's a directory
if (!file.isFile()) {
name = name + "/";
} }
try { try {
return new URL("file", "", name); return p.normalize().toUri().toURL();
} catch (MalformedURLException e) { } catch (MalformedURLException e) {
throw new IllegalArgumentException(file.toString()); return null;
} }
} }
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,9 +25,6 @@
package com.sun.tools.javac.file; package com.sun.tools.javac.file;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
@ -39,9 +36,13 @@ import java.net.URI;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.CharBuffer; import java.nio.CharBuffer;
import java.nio.charset.CharsetDecoder; import java.nio.charset.CharsetDecoder;
import javax.tools.JavaFileObject; import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.Normalizer; import java.text.Normalizer;
import javax.tools.JavaFileObject;
import com.sun.tools.javac.util.DefinedBy; import com.sun.tools.javac.util.DefinedBy;
import com.sun.tools.javac.util.DefinedBy.Api; import com.sun.tools.javac.util.DefinedBy.Api;
@ -59,33 +60,33 @@ class RegularFileObject extends BaseFileObject {
*/ */
private boolean hasParents = false; private boolean hasParents = false;
private String name; private String name;
final File file; final Path file;
private Reference<File> absFileRef; private Reference<Path> absFileRef;
final static boolean isMacOS = System.getProperty("os.name", "").contains("OS X"); final static boolean isMacOS = System.getProperty("os.name", "").contains("OS X");
public RegularFileObject(JavacFileManager fileManager, File f) { public RegularFileObject(JavacFileManager fileManager, Path f) {
this(fileManager, f.getName(), f); this(fileManager, f.getFileName().toString(), f);
} }
public RegularFileObject(JavacFileManager fileManager, String name, File f) { public RegularFileObject(JavacFileManager fileManager, String name, Path f) {
super(fileManager); super(fileManager);
if (f.isDirectory()) { if (Files.isDirectory(f)) {
throw new IllegalArgumentException("directories not supported"); throw new IllegalArgumentException("directories not supported");
} }
this.name = name; this.name = name;
this.file = f; this.file = f;
if (f.lastModified() > System.currentTimeMillis()) if (getLastModified() > System.currentTimeMillis())
fileManager.log.warning("file.from.future", f); fileManager.log.warning("file.from.future", f);
} }
@Override @DefinedBy(Api.COMPILER) @Override @DefinedBy(Api.COMPILER)
public URI toUri() { public URI toUri() {
return file.toURI().normalize(); return file.toUri().normalize();
} }
@Override @DefinedBy(Api.COMPILER) @Override @DefinedBy(Api.COMPILER)
public String getName() { public String getName() {
return file.getPath(); return file.toString();
} }
@Override @Override
@ -100,21 +101,21 @@ class RegularFileObject extends BaseFileObject {
@Override @DefinedBy(Api.COMPILER) @Override @DefinedBy(Api.COMPILER)
public InputStream openInputStream() throws IOException { public InputStream openInputStream() throws IOException {
return new FileInputStream(file); return Files.newInputStream(file);
} }
@Override @DefinedBy(Api.COMPILER) @Override @DefinedBy(Api.COMPILER)
public OutputStream openOutputStream() throws IOException { public OutputStream openOutputStream() throws IOException {
fileManager.flushCache(this); fileManager.flushCache(this);
ensureParentDirectoriesExist(); ensureParentDirectoriesExist();
return new FileOutputStream(file); return Files.newOutputStream(file);
} }
@Override @DefinedBy(Api.COMPILER) @Override @DefinedBy(Api.COMPILER)
public CharBuffer getCharContent(boolean ignoreEncodingErrors) throws IOException { public CharBuffer getCharContent(boolean ignoreEncodingErrors) throws IOException {
CharBuffer cb = fileManager.getCachedContent(this); CharBuffer cb = fileManager.getCachedContent(this);
if (cb == null) { if (cb == null) {
try (InputStream in = new FileInputStream(file)) { try (InputStream in = Files.newInputStream(file)) {
ByteBuffer bb = fileManager.makeByteBuffer(in); ByteBuffer bb = fileManager.makeByteBuffer(in);
JavaFileObject prev = fileManager.log.useSource(this); JavaFileObject prev = fileManager.log.useSource(this);
try { try {
@ -135,17 +136,26 @@ class RegularFileObject extends BaseFileObject {
public Writer openWriter() throws IOException { public Writer openWriter() throws IOException {
fileManager.flushCache(this); fileManager.flushCache(this);
ensureParentDirectoriesExist(); ensureParentDirectoriesExist();
return new OutputStreamWriter(new FileOutputStream(file), fileManager.getEncodingName()); return new OutputStreamWriter(Files.newOutputStream(file), fileManager.getEncodingName());
} }
@Override @DefinedBy(Api.COMPILER) @Override @DefinedBy(Api.COMPILER)
public long getLastModified() { public long getLastModified() {
return file.lastModified(); try {
return Files.getLastModifiedTime(file).toMillis();
} catch (IOException e) {
return 0;
}
} }
@Override @DefinedBy(Api.COMPILER) @Override @DefinedBy(Api.COMPILER)
public boolean delete() { public boolean delete() {
return file.delete(); try {
Files.delete(file);
return true;
} catch (IOException e) {
return false;
}
} }
@Override @Override
@ -154,20 +164,21 @@ class RegularFileObject extends BaseFileObject {
} }
@Override @Override
protected String inferBinaryName(Iterable<? extends File> path) { protected String inferBinaryName(Iterable<? extends Path> path) {
String fPath = file.getPath(); String fPath = file.toString();
//System.err.println("RegularFileObject " + file + " " +r.getPath()); //System.err.println("RegularFileObject " + file + " " +r.getPath());
for (File dir: path) { for (Path dir: path) {
//System.err.println("dir: " + dir); //System.err.println("dir: " + dir);
String dPath = dir.getPath(); String sep = dir.getFileSystem().getSeparator();
String dPath = dir.toString();
if (dPath.length() == 0) if (dPath.length() == 0)
dPath = System.getProperty("user.dir"); dPath = System.getProperty("user.dir");
if (!dPath.endsWith(File.separator)) if (!dPath.endsWith(sep))
dPath += File.separator; dPath += sep;
if (fPath.regionMatches(true, 0, dPath, 0, dPath.length()) if (fPath.regionMatches(true, 0, dPath, 0, dPath.length())
&& new File(fPath.substring(0, dPath.length())).equals(new File(dPath))) { && Paths.get(fPath.substring(0, dPath.length())).equals(Paths.get(dPath))) {
String relativeName = fPath.substring(dPath.length()); String relativeName = fPath.substring(dPath.length());
return removeExtension(relativeName).replace(File.separatorChar, '.'); return removeExtension(relativeName).replace(sep, ".");
} }
} }
return null; return null;
@ -199,7 +210,7 @@ class RegularFileObject extends BaseFileObject {
if (name.equalsIgnoreCase(n)) { if (name.equalsIgnoreCase(n)) {
try { try {
// allow for Windows // allow for Windows
return file.getCanonicalFile().getName().equals(n); return file.toRealPath().getFileName().toString().equals(n);
} catch (IOException e) { } catch (IOException e) {
} }
} }
@ -208,12 +219,12 @@ class RegularFileObject extends BaseFileObject {
private void ensureParentDirectoriesExist() throws IOException { private void ensureParentDirectoriesExist() throws IOException {
if (!hasParents) { if (!hasParents) {
File parent = file.getParentFile(); Path parent = file.getParent();
if (parent != null && !parent.exists()) { if (parent != null && !Files.isDirectory(parent)) {
if (!parent.mkdirs()) { try {
if (!parent.exists() || !parent.isDirectory()) { Files.createDirectories(parent);
throw new IOException("could not create parent directories"); } catch (IOException e) {
} throw new IOException("could not create parent directories", e);
} }
} }
hasParents = true; hasParents = true;
@ -242,10 +253,10 @@ class RegularFileObject extends BaseFileObject {
return getAbsoluteFile().hashCode(); return getAbsoluteFile().hashCode();
} }
private File getAbsoluteFile() { private Path getAbsoluteFile() {
File absFile = (absFileRef == null ? null : absFileRef.get()); Path absFile = (absFileRef == null ? null : absFileRef.get());
if (absFile == null) { if (absFile == null) {
absFile = file.getAbsoluteFile(); absFile = file.toAbsolutePath();
absFileRef = new SoftReference<>(absFile); absFileRef = new SoftReference<>(absFile);
} }
return absFile; return absFile;

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,9 +25,13 @@
package com.sun.tools.javac.file; package com.sun.tools.javac.file;
import java.io.File; import java.nio.file.FileSystems;
import java.nio.file.InvalidPathException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
import java.util.zip.ZipFile; import java.util.zip.ZipFile;
import javax.tools.JavaFileObject; import javax.tools.JavaFileObject;
/** /**
@ -52,12 +56,17 @@ public abstract class RelativePath implements Comparable<RelativePath> {
public abstract String basename(); public abstract String basename();
public File getFile(File directory) { public Path getFile(Path directory) throws /*unchecked*/ InvalidPathException {
if (path.length() == 0) if (directory == null) {
return directory; String sep = FileSystems.getDefault().getSeparator();
return new File(directory, path.replace('/', File.separatorChar)); return Paths.get(path.replace("/", sep));
} else {
String sep = directory.getFileSystem().getSeparator();
return directory.resolve(path.replace("/", sep));
}
} }
@Override
public int compareTo(RelativePath other) { public int compareTo(RelativePath other) {
return path.compareTo(other.path); return path.compareTo(other.path);
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2005, 2009, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,10 +25,11 @@
package com.sun.tools.javac.file; package com.sun.tools.javac.file;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Path;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
import java.util.zip.ZipFile; import java.util.zip.ZipFile;
import javax.tools.JavaFileObject; import javax.tools.JavaFileObject;
import com.sun.tools.javac.file.RelativePath.RelativeDirectory; import com.sun.tools.javac.file.RelativePath.RelativeDirectory;
@ -43,10 +44,10 @@ import com.sun.tools.javac.util.List;
*/ */
public class SymbolArchive extends ZipArchive { public class SymbolArchive extends ZipArchive {
final File origFile; final Path origFile;
final RelativeDirectory prefix; final RelativeDirectory prefix;
public SymbolArchive(JavacFileManager fileManager, File orig, ZipFile zdir, RelativeDirectory prefix) throws IOException { public SymbolArchive(JavacFileManager fileManager, Path orig, ZipFile zdir, RelativeDirectory prefix) throws IOException {
super(fileManager, zdir, false); super(fileManager, zdir, false);
this.origFile = orig; this.origFile = orig;
this.prefix = prefix; this.prefix = prefix;
@ -94,7 +95,7 @@ public class SymbolArchive extends ZipArchive {
} }
@Override @Override
protected String inferBinaryName(Iterable<? extends File> path) { protected String inferBinaryName(Iterable<? extends Path> path) {
String entryName = entry.getName(); String entryName = entry.getName();
String prefix = ((SymbolArchive) zarch).prefix.path; String prefix = ((SymbolArchive) zarch).prefix.path;
if (entryName.startsWith(prefix)) if (entryName.startsWith(prefix))

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2005, 2009, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,15 +25,18 @@
package com.sun.tools.javac.file; package com.sun.tools.javac.file;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.Writer; import java.io.Writer;
import java.lang.ref.Reference;
import java.lang.ref.SoftReference;
import java.net.URI; import java.net.URI;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.CharBuffer; import java.nio.CharBuffer;
import java.nio.charset.CharsetDecoder; import java.nio.charset.CharsetDecoder;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -49,8 +52,6 @@ import com.sun.tools.javac.file.RelativePath.RelativeFile;
import com.sun.tools.javac.util.DefinedBy; import com.sun.tools.javac.util.DefinedBy;
import com.sun.tools.javac.util.DefinedBy.Api; import com.sun.tools.javac.util.DefinedBy.Api;
import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.List;
import java.lang.ref.Reference;
import java.lang.ref.SoftReference;
/** /**
* <p><b>This is NOT part of any supported API. * <p><b>This is NOT part of any supported API.
@ -131,10 +132,10 @@ public class ZipArchive implements Archive {
return "ZipArchive[" + zfile.getName() + "]"; return "ZipArchive[" + zfile.getName() + "]";
} }
private File getAbsoluteFile() { private Path getAbsoluteFile() {
File absFile = (absFileRef == null ? null : absFileRef.get()); Path absFile = (absFileRef == null ? null : absFileRef.get());
if (absFile == null) { if (absFile == null) {
absFile = new File(zfile.getName()).getAbsoluteFile(); absFile = Paths.get(zfile.getName()).toAbsolutePath();
absFileRef = new SoftReference<>(absFile); absFileRef = new SoftReference<>(absFile);
} }
return absFile; return absFile;
@ -155,7 +156,7 @@ public class ZipArchive implements Archive {
/** /**
* A reference to the absolute filename for the zip file for the archive. * A reference to the absolute filename for the zip file for the archive.
*/ */
protected Reference<File> absFileRef; protected Reference<Path> absFileRef;
/** /**
* A subclass of JavaFileObject representing zip entries. * A subclass of JavaFileObject representing zip entries.
@ -175,7 +176,7 @@ public class ZipArchive implements Archive {
@DefinedBy(Api.COMPILER) @DefinedBy(Api.COMPILER)
public URI toUri() { public URI toUri() {
File zipFile = new File(zarch.zfile.getName()); Path zipFile = Paths.get(zarch.zfile.getName());
return createJarUri(zipFile, entry.getName()); return createJarUri(zipFile, entry.getName());
} }
@ -186,7 +187,7 @@ public class ZipArchive implements Archive {
@Override @Override
public String getShortName() { public String getShortName() {
return new File(zarch.zfile.getName()).getName() + "(" + entry + ")"; return Paths.get(zarch.zfile.getName()).getFileName() + "(" + entry + ")";
} }
@Override @DefinedBy(Api.COMPILER) @Override @DefinedBy(Api.COMPILER)
@ -246,7 +247,7 @@ public class ZipArchive implements Archive {
} }
@Override @Override
protected String inferBinaryName(Iterable<? extends File> path) { protected String inferBinaryName(Iterable<? extends Path> path) {
String entryName = entry.getName(); String entryName = entry.getName();
return removeExtension(entryName).replace('/', '.'); return removeExtension(entryName).replace('/', '.');
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -26,18 +26,20 @@
package com.sun.tools.javac.file; package com.sun.tools.javac.file;
import java.io.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.io.RandomAccessFile; import java.io.RandomAccessFile;
import java.lang.ref.Reference; import java.lang.ref.Reference;
import java.lang.ref.SoftReference; import java.lang.ref.SoftReference;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Calendar; import java.util.Calendar;
import java.util.Collections; import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -91,14 +93,14 @@ public class ZipFileIndex {
Collections.<RelativeDirectory>emptySet(); Collections.<RelativeDirectory>emptySet();
// ZipFileIndex data entries // ZipFileIndex data entries
final File zipFile; final Path zipFile;
private Reference<File> absFileRef; private Reference<Path> absFileRef;
long zipFileLastModified = NOT_MODIFIED; long zipFileLastModified = NOT_MODIFIED;
private RandomAccessFile zipRandomFile; private RandomAccessFile zipRandomFile;
private Entry[] entries; private Entry[] entries;
private boolean readFromIndex = false; private boolean readFromIndex = false;
private File zipIndexFile = null; private Path zipIndexFile = null;
private boolean triedToReadIndex = false; private boolean triedToReadIndex = false;
final RelativeDirectory symbolFilePrefix; final RelativeDirectory symbolFilePrefix;
private final int symbolFilePrefixLength; private final int symbolFilePrefixLength;
@ -117,7 +119,7 @@ public class ZipFileIndex {
return (zipRandomFile != null); return (zipRandomFile != null);
} }
ZipFileIndex(File zipFile, RelativeDirectory symbolFilePrefix, boolean writeIndex, ZipFileIndex(Path zipFile, RelativeDirectory symbolFilePrefix, boolean writeIndex,
boolean useCache, String cacheLocation) throws IOException { boolean useCache, String cacheLocation) throws IOException {
this.zipFile = zipFile; this.zipFile = zipFile;
this.symbolFilePrefix = symbolFilePrefix; this.symbolFilePrefix = symbolFilePrefix;
@ -128,7 +130,7 @@ public class ZipFileIndex {
this.preindexedCacheLocation = cacheLocation; this.preindexedCacheLocation = cacheLocation;
if (zipFile != null) { if (zipFile != null) {
this.zipFileLastModified = zipFile.lastModified(); this.zipFileLastModified = Files.getLastModifiedTime(zipFile).toMillis();
} }
// Validate integrity of the zip file // Validate integrity of the zip file
@ -148,10 +150,11 @@ public class ZipFileIndex {
} }
private boolean isUpToDate() { private boolean isUpToDate() {
if (zipFile != null try {
&& ((!NON_BATCH_MODE) || zipFileLastModified == zipFile.lastModified()) return (zipFile != null
&& hasPopulatedData) { && ((!NON_BATCH_MODE) || zipFileLastModified == Files.getLastModifiedTime(zipFile).toMillis())
return true; && hasPopulatedData);
} catch (IOException ignore) {
} }
return false; return false;
@ -199,7 +202,7 @@ public class ZipFileIndex {
private void openFile() throws FileNotFoundException { private void openFile() throws FileNotFoundException {
if (zipRandomFile == null && zipFile != null) { if (zipRandomFile == null && zipFile != null) {
zipRandomFile = new RandomAccessFile(zipFile, "r"); zipRandomFile = new RandomAccessFile(zipFile.toFile(), "r");
} }
} }
@ -785,11 +788,11 @@ public class ZipFileIndex {
entries.add(zipFileIndex.entries[i]); entries.add(zipFileIndex.entries[i]);
} }
} else { } else {
File indexFile = zipFileIndex.getIndexFile(); Path indexFile = zipFileIndex.getIndexFile();
if (indexFile != null) { if (indexFile != null) {
RandomAccessFile raf = null; RandomAccessFile raf = null;
try { try {
raf = new RandomAccessFile(indexFile, "r"); raf = new RandomAccessFile(indexFile.toFile(), "r");
raf.seek(writtenOffsetOffset); raf.seek(writtenOffsetOffset);
for (int nFiles = 0; nFiles < numEntries; nFiles++) { for (int nFiles = 0; nFiles < numEntries; nFiles++) {
@ -856,11 +859,11 @@ public class ZipFileIndex {
triedToReadIndex = true; triedToReadIndex = true;
RandomAccessFile raf = null; RandomAccessFile raf = null;
try { try {
File indexFileName = getIndexFile(); Path indexFileName = getIndexFile();
raf = new RandomAccessFile(indexFileName, "r"); raf = new RandomAccessFile(indexFileName.toFile(), "r");
long fileStamp = raf.readLong(); long fileStamp = raf.readLong();
if (zipFile.lastModified() != fileStamp) { if (Files.getLastModifiedTime(zipFile).toMillis() != fileStamp) {
ret = false; ret = false;
} else { } else {
directories = new LinkedHashMap<>(); directories = new LinkedHashMap<>();
@ -908,7 +911,7 @@ public class ZipFileIndex {
return true; return true;
} }
File indexFile = getIndexFile(); Path indexFile = getIndexFile();
if (indexFile == null) { if (indexFile == null) {
return false; return false;
} }
@ -916,7 +919,7 @@ public class ZipFileIndex {
RandomAccessFile raf = null; RandomAccessFile raf = null;
long writtenSoFar = 0; long writtenSoFar = 0;
try { try {
raf = new RandomAccessFile(indexFile, "rw"); raf = new RandomAccessFile(indexFile.toFile(), "rw");
raf.writeLong(zipFileLastModified); raf.writeLong(zipFileLastModified);
writtenSoFar += 8; writtenSoFar += 8;
@ -1016,27 +1019,27 @@ public class ZipFileIndex {
} }
} }
private File getIndexFile() { private Path getIndexFile() {
if (zipIndexFile == null) { if (zipIndexFile == null) {
if (zipFile == null) { if (zipFile == null) {
return null; return null;
} }
zipIndexFile = new File((preindexedCacheLocation == null ? "" : preindexedCacheLocation) + zipIndexFile = Paths.get((preindexedCacheLocation == null ? "" : preindexedCacheLocation) +
zipFile.getName() + ".index"); zipFile.getFileName() + ".index");
} }
return zipIndexFile; return zipIndexFile;
} }
public File getZipFile() { public Path getZipFile() {
return zipFile; return zipFile;
} }
File getAbsoluteFile() { Path getAbsoluteFile() {
File absFile = (absFileRef == null ? null : absFileRef.get()); Path absFile = (absFileRef == null ? null : absFileRef.get());
if (absFile == null) { if (absFile == null) {
absFile = zipFile.getAbsoluteFile(); absFile = zipFile.toAbsolutePath();
absFileRef = new SoftReference<>(absFile); absFileRef = new SoftReference<>(absFile);
} }
return absFile; return absFile;

View file

@ -25,12 +25,8 @@
package com.sun.tools.javac.file; package com.sun.tools.javac.file;
import java.io.IOException;
import java.util.Set;
import javax.tools.JavaFileObject;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.File; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.Writer; import java.io.Writer;
@ -38,6 +34,10 @@ import java.net.URI;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.CharBuffer; import java.nio.CharBuffer;
import java.nio.charset.CharsetDecoder; import java.nio.charset.CharsetDecoder;
import java.nio.file.Path;
import java.util.Set;
import javax.tools.JavaFileObject;
import com.sun.tools.javac.file.JavacFileManager.Archive; import com.sun.tools.javac.file.JavacFileManager.Archive;
import com.sun.tools.javac.file.RelativePath.RelativeDirectory; import com.sun.tools.javac.file.RelativePath.RelativeDirectory;
@ -56,7 +56,7 @@ import com.sun.tools.javac.util.List;
public class ZipFileIndexArchive implements Archive { public class ZipFileIndexArchive implements Archive {
private final ZipFileIndex zfIndex; private final ZipFileIndex zfIndex;
private JavacFileManager fileManager; private final JavacFileManager fileManager;
public ZipFileIndexArchive(JavacFileManager fileManager, ZipFileIndex zdir) throws IOException { public ZipFileIndexArchive(JavacFileManager fileManager, ZipFileIndex zdir) throws IOException {
super(); super();
@ -111,10 +111,10 @@ public class ZipFileIndexArchive implements Archive {
/** The name of the zip file where this entry resides. /** The name of the zip file where this entry resides.
*/ */
File zipName; Path zipName;
ZipFileIndexFileObject(JavacFileManager fileManager, ZipFileIndex zfIndex, ZipFileIndex.Entry entry, File zipFileName) { ZipFileIndexFileObject(JavacFileManager fileManager, ZipFileIndex zfIndex, ZipFileIndex.Entry entry, Path zipFileName) {
super(fileManager); super(fileManager);
this.name = entry.getFileName(); this.name = entry.getFileName();
this.zfIndex = zfIndex; this.zfIndex = zfIndex;
@ -134,7 +134,7 @@ public class ZipFileIndexArchive implements Archive {
@Override @Override
public String getShortName() { public String getShortName() {
return zipName.getName() + "(" + entry.getName() + ")"; return zipName.getFileName() + "(" + entry.getName() + ")";
} }
@Override @DefinedBy(Api.COMPILER) @Override @DefinedBy(Api.COMPILER)
@ -194,7 +194,7 @@ public class ZipFileIndexArchive implements Archive {
} }
@Override @Override
protected String inferBinaryName(Iterable<? extends File> path) { protected String inferBinaryName(Iterable<? extends Path> path) {
String entryName = entry.getName(); String entryName = entry.getName();
if (zfIndex.symbolFilePrefix != null) { if (zfIndex.symbolFilePrefix != null) {
String prefix = zfIndex.symbolFilePrefix.path; String prefix = zfIndex.symbolFilePrefix.path;

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,21 +25,22 @@
package com.sun.tools.javac.file; package com.sun.tools.javac.file;
import com.sun.tools.javac.file.RelativePath.RelativeDirectory;
import com.sun.tools.javac.util.Context;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import com.sun.tools.javac.file.RelativePath.RelativeDirectory;
import com.sun.tools.javac.util.Context;
/** A cache for ZipFileIndex objects. */ /** A cache for ZipFileIndex objects. */
public class ZipFileIndexCache { public class ZipFileIndexCache {
private final Map<File, ZipFileIndex> map = new HashMap<>(); private final Map<Path, ZipFileIndex> map = new HashMap<>();
/** Get a shared instance of the cache. */ /** Get a shared instance of the cache. */
private static ZipFileIndexCache sharedInstance; private static ZipFileIndexCache sharedInstance;
@ -89,13 +90,13 @@ public class ZipFileIndexCache {
return zipFileIndexes; return zipFileIndexes;
} }
public synchronized ZipFileIndex getZipFileIndex(File zipFile, public synchronized ZipFileIndex getZipFileIndex(Path zipFile,
RelativeDirectory symbolFilePrefix, RelativeDirectory symbolFilePrefix,
boolean useCache, String cacheLocation, boolean useCache, String cacheLocation,
boolean writeIndex) throws IOException { boolean writeIndex) throws IOException {
ZipFileIndex zi = getExistingZipIndex(zipFile); ZipFileIndex zi = getExistingZipIndex(zipFile);
if (zi == null || (zi != null && zipFile.lastModified() != zi.zipFileLastModified)) { if (zi == null || (zi != null && Files.getLastModifiedTime(zipFile).toMillis() != zi.zipFileLastModified)) {
zi = new ZipFileIndex(zipFile, symbolFilePrefix, writeIndex, zi = new ZipFileIndex(zipFile, symbolFilePrefix, writeIndex,
useCache, cacheLocation); useCache, cacheLocation);
map.put(zipFile, zi); map.put(zipFile, zi);
@ -103,7 +104,7 @@ public class ZipFileIndexCache {
return zi; return zi;
} }
public synchronized ZipFileIndex getExistingZipIndex(File zipFile) { public synchronized ZipFileIndex getExistingZipIndex(Path zipFile) {
return map.get(zipFile); return map.get(zipFile);
} }
@ -112,7 +113,7 @@ public class ZipFileIndexCache {
} }
public synchronized void clearCache(long timeNotUsed) { public synchronized void clearCache(long timeNotUsed) {
for (File cachedFile : map.keySet()) { for (Path cachedFile : map.keySet()) {
ZipFileIndex cachedZipIndex = map.get(cachedFile); ZipFileIndex cachedZipIndex = map.get(cachedFile);
if (cachedZipIndex != null) { if (cachedZipIndex != null) {
long timeToTest = cachedZipIndex.lastReferenceTimeStamp + timeNotUsed; long timeToTest = cachedZipIndex.lastReferenceTimeStamp + timeNotUsed;
@ -124,7 +125,7 @@ public class ZipFileIndexCache {
} }
} }
public synchronized void removeFromCache(File file) { public synchronized void removeFromCache(Path file) {
map.remove(file); map.remove(file);
} }

View file

@ -29,23 +29,27 @@ import java.io.*;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.nio.CharBuffer; import java.nio.CharBuffer;
import java.nio.file.Path;
import java.util.Arrays; import java.util.Arrays;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import javax.tools.JavaFileObject;
import javax.tools.JavaFileManager;
import com.sun.tools.javac.comp.Annotate; import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
import com.sun.tools.javac.code.*; import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Lint.LintCategory; import com.sun.tools.javac.code.Lint.LintCategory;
import com.sun.tools.javac.code.Type.*;
import com.sun.tools.javac.code.Scope.WriteableScope; import com.sun.tools.javac.code.Scope.WriteableScope;
import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.code.Symtab; import com.sun.tools.javac.code.Symtab;
import com.sun.tools.javac.code.Type.*;
import com.sun.tools.javac.comp.Annotate;
import com.sun.tools.javac.file.BaseFileObject; import com.sun.tools.javac.file.BaseFileObject;
import com.sun.tools.javac.jvm.ClassFile.NameAndType;
import com.sun.tools.javac.jvm.ClassFile.Version;
import com.sun.tools.javac.util.*; import com.sun.tools.javac.util.*;
import com.sun.tools.javac.util.DefinedBy.Api; import com.sun.tools.javac.util.DefinedBy.Api;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
@ -2481,7 +2485,7 @@ public class ClassReader {
} }
@Override @Override
protected String inferBinaryName(Iterable<? extends File> path) { protected String inferBinaryName(Iterable<? extends Path> path) {
return flatname.toString(); return flatname.toString();
} }

View file

@ -29,10 +29,10 @@ import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.net.URL; import java.net.URL;
import java.nio.file.NoSuchFileException;
import java.security.DigestInputStream; import java.security.DigestInputStream;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.util.Set; import java.util.Set;
import javax.tools.JavaFileManager; import javax.tools.JavaFileManager;
@ -168,7 +168,7 @@ public class Main {
try { try {
argv = CommandLine.parse(argv); argv = CommandLine.parse(argv);
} catch (FileNotFoundException e) { } catch (FileNotFoundException | NoSuchFileException e) {
warning("err.file.not.found", e.getMessage()); warning("err.file.not.found", e.getMessage());
return Result.SYSERR; return Result.SYSERR;
} catch (IOException ex) { } catch (IOException ex) {

View file

@ -30,12 +30,13 @@ import java.io.IOException;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.FileSystem; import java.nio.file.FileSystem;
import java.nio.file.FileSystems; import java.nio.file.FileSystems;
import java.nio.file.FileVisitOption; import java.nio.file.FileVisitOption;
import java.nio.file.FileVisitResult; import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor; import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes; import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList; import java.util.ArrayList;
@ -48,6 +49,7 @@ import java.util.Iterator;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import javax.lang.model.SourceVersion; import javax.lang.model.SourceVersion;
import javax.tools.FileObject; import javax.tools.FileObject;
import javax.tools.JavaFileManager; import javax.tools.JavaFileManager;
@ -55,9 +57,6 @@ import javax.tools.JavaFileObject;
import javax.tools.JavaFileObject.Kind; import javax.tools.JavaFileObject.Kind;
import javax.tools.StandardLocation; import javax.tools.StandardLocation;
import static java.nio.file.FileVisitOption.*;
import static javax.tools.StandardLocation.*;
import com.sun.tools.javac.util.BaseFileManager; import com.sun.tools.javac.util.BaseFileManager;
import com.sun.tools.javac.util.Context; import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.DefinedBy; import com.sun.tools.javac.util.DefinedBy;
@ -65,6 +64,10 @@ import com.sun.tools.javac.util.DefinedBy.Api;
import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.ListBuffer; import com.sun.tools.javac.util.ListBuffer;
import static java.nio.file.FileVisitOption.*;
import static javax.tools.StandardLocation.*;
import static com.sun.tools.javac.main.Option.*; import static com.sun.tools.javac.main.Option.*;
@ -221,7 +224,7 @@ public class JavacPathFileManager extends BaseFileManager implements PathFileMan
} }
private void setDefaultForLocation(Location locn) { private void setDefaultForLocation(Location locn) {
Collection<File> files = null; Collection<Path> files = null;
if (locn instanceof StandardLocation) { if (locn instanceof StandardLocation) {
switch ((StandardLocation) locn) { switch ((StandardLocation) locn) {
case CLASS_PATH: case CLASS_PATH:
@ -235,12 +238,12 @@ public class JavacPathFileManager extends BaseFileManager implements PathFileMan
break; break;
case CLASS_OUTPUT: { case CLASS_OUTPUT: {
String arg = options.get(D); String arg = options.get(D);
files = (arg == null ? null : Collections.singleton(new File(arg))); files = (arg == null ? null : Collections.singleton(Paths.get(arg)));
break; break;
} }
case SOURCE_OUTPUT: { case SOURCE_OUTPUT: {
String arg = options.get(S); String arg = options.get(S);
files = (arg == null ? null : Collections.singleton(new File(arg))); files = (arg == null ? null : Collections.singleton(Paths.get(arg)));
break; break;
} }
} }
@ -248,8 +251,8 @@ public class JavacPathFileManager extends BaseFileManager implements PathFileMan
PathsForLocation pl = new PathsForLocation(); PathsForLocation pl = new PathsForLocation();
if (files != null) { if (files != null) {
for (File f: files) for (Path f: files)
pl.add(f.toPath()); pl.add(f);
} }
if (!pl.isEmpty()) if (!pl.isEmpty())
pathsForLocation.put(locn, pl); pathsForLocation.put(locn, pl);

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -24,6 +24,7 @@
*/ */
package com.sun.tools.javac.util; package com.sun.tools.javac.util;
import java.nio.file.Path;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.EnumSet; import java.util.EnumSet;
@ -48,6 +49,7 @@ import com.sun.tools.javac.file.BaseFileObject;
import com.sun.tools.javac.jvm.Profile; import com.sun.tools.javac.jvm.Profile;
import com.sun.tools.javac.tree.JCTree.*; import com.sun.tools.javac.tree.JCTree.*;
import com.sun.tools.javac.tree.Pretty; import com.sun.tools.javac.tree.Pretty;
import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticType.*; import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticType.*;
/** /**
@ -186,7 +188,7 @@ public abstract class AbstractDiagnosticFormatter implements DiagnosticFormatter
else if (arg instanceof JCExpression) { else if (arg instanceof JCExpression) {
return expr2String((JCExpression)arg); return expr2String((JCExpression)arg);
} }
else if (arg instanceof Iterable<?>) { else if (arg instanceof Iterable<?> && !(arg instanceof Path)) {
return formatIterable(d, (Iterable<?>)arg, l); return formatIterable(d, (Iterable<?>)arg, l);
} }
else if (arg instanceof Type) { else if (arg instanceof Type) {

View file

@ -24,6 +24,7 @@
*/ */
package com.sun.tools.javac.util; package com.sun.tools.javac.util;
import java.nio.file.Path;
import java.util.EnumMap; import java.util.EnumMap;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.HashMap; import java.util.HashMap;
@ -39,8 +40,8 @@ import com.sun.tools.javac.code.Type;
import com.sun.tools.javac.code.Type.*; import com.sun.tools.javac.code.Type.*;
import com.sun.tools.javac.code.Types; import com.sun.tools.javac.code.Types;
import static com.sun.tools.javac.code.TypeTag.*;
import static com.sun.tools.javac.code.Flags.*; import static com.sun.tools.javac.code.Flags.*;
import static com.sun.tools.javac.code.TypeTag.*;
import static com.sun.tools.javac.code.Kinds.*; import static com.sun.tools.javac.code.Kinds.*;
import static com.sun.tools.javac.code.Kinds.Kind.*; import static com.sun.tools.javac.code.Kinds.Kind.*;
import static com.sun.tools.javac.util.LayoutCharacters.*; import static com.sun.tools.javac.util.LayoutCharacters.*;
@ -186,7 +187,7 @@ public class RichDiagnosticFormatter extends
else if (arg instanceof JCDiagnostic) { else if (arg instanceof JCDiagnostic) {
preprocessDiagnostic((JCDiagnostic)arg); preprocessDiagnostic((JCDiagnostic)arg);
} }
else if (arg instanceof Iterable<?>) { else if (arg instanceof Iterable<?> && !(arg instanceof Path)) {
for (Object o : (Iterable<?>)arg) { for (Object o : (Iterable<?>)arg) {
preprocessArgument(o); preprocessArgument(o);
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,7 +25,6 @@
package com.sun.tools.javah; package com.sun.tools.javah;
import java.io.UnsupportedEncodingException;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
@ -33,6 +32,8 @@ import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.OutputStreamWriter; import java.io.OutputStreamWriter;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.nio.file.NoSuchFileException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
@ -40,7 +41,6 @@ import java.util.Set;
import java.util.Stack; import java.util.Stack;
import javax.annotation.processing.ProcessingEnvironment; import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Modifier; import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement; import javax.lang.model.element.TypeElement;
@ -48,7 +48,6 @@ import javax.lang.model.element.VariableElement;
import javax.lang.model.util.ElementFilter; import javax.lang.model.util.ElementFilter;
import javax.lang.model.util.Elements; import javax.lang.model.util.Elements;
import javax.lang.model.util.Types; import javax.lang.model.util.Types;
import javax.tools.FileObject; import javax.tools.FileObject;
import javax.tools.JavaFileManager; import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject; import javax.tools.JavaFileObject;
@ -204,7 +203,7 @@ public abstract class Gen {
event = "[Overwriting file "; event = "[Overwriting file ";
} }
} catch (FileNotFoundException e) { } catch (FileNotFoundException | NoSuchFileException e) {
mustWrite = true; mustWrite = true;
event = "[Creating file "; event = "[Creating file ";
} }

View file

@ -31,6 +31,7 @@ import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.io.Writer; import java.io.Writer;
import java.nio.file.NoSuchFileException;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -50,7 +51,6 @@ import javax.annotation.processing.Messager;
import javax.annotation.processing.ProcessingEnvironment; import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.RoundEnvironment; import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes; import javax.annotation.processing.SupportedAnnotationTypes;
import javax.lang.model.SourceVersion; import javax.lang.model.SourceVersion;
import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement; import javax.lang.model.element.TypeElement;
@ -62,7 +62,6 @@ import javax.lang.model.type.TypeVisitor;
import javax.lang.model.util.ElementFilter; import javax.lang.model.util.ElementFilter;
import javax.lang.model.util.SimpleTypeVisitor9; import javax.lang.model.util.SimpleTypeVisitor9;
import javax.lang.model.util.Types; import javax.lang.model.util.Types;
import javax.tools.Diagnostic; import javax.tools.Diagnostic;
import javax.tools.DiagnosticListener; import javax.tools.DiagnosticListener;
import javax.tools.JavaCompiler; import javax.tools.JavaCompiler;
@ -72,13 +71,15 @@ import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager; import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation; import javax.tools.StandardLocation;
import javax.tools.ToolProvider; import javax.tools.ToolProvider;
import static javax.tools.Diagnostic.Kind.*;
import com.sun.tools.javac.code.Symbol.CompletionFailure; import com.sun.tools.javac.code.Symbol.CompletionFailure;
import com.sun.tools.javac.main.CommandLine; import com.sun.tools.javac.main.CommandLine;
import com.sun.tools.javac.util.DefinedBy; import com.sun.tools.javac.util.DefinedBy;
import com.sun.tools.javac.util.DefinedBy.Api; import com.sun.tools.javac.util.DefinedBy.Api;
import static javax.tools.Diagnostic.Kind.*;
/** /**
* Javah generates support files for native methods. * Javah generates support files for native methods.
* Parse commandline options and invokes javadoc to execute those commands. * Parse commandline options and invokes javadoc to execute those commands.
@ -420,7 +421,7 @@ public class JavahTask implements NativeHeaderTool.NativeHeaderTask {
List<String> l = new ArrayList<>(); List<String> l = new ArrayList<>();
for (String arg: args) l.add(arg); for (String arg: args) l.add(arg);
return Arrays.asList(CommandLine.parse(l.toArray(new String[l.size()]))); return Arrays.asList(CommandLine.parse(l.toArray(new String[l.size()])));
} catch (FileNotFoundException e) { } catch (FileNotFoundException | NoSuchFileException e) {
throw new BadArgs("at.args.file.not.found", e.getLocalizedMessage()); throw new BadArgs("at.args.file.not.found", e.getLocalizedMessage());
} catch (IOException e) { } catch (IOException e) {
throw new BadArgs("at.args.io.exception", e.getLocalizedMessage()); throw new BadArgs("at.args.io.exception", e.getLocalizedMessage());

View file

@ -36,6 +36,10 @@ import java.io.Reader;
import java.io.StringWriter; import java.io.StringWriter;
import java.io.Writer; import java.io.Writer;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLConnection;
import java.nio.file.NoSuchFileException;
import java.security.DigestInputStream; import java.security.DigestInputStream;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
@ -61,10 +65,6 @@ import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation; import javax.tools.StandardLocation;
import com.sun.tools.classfile.*; import com.sun.tools.classfile.*;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLConnection;
import com.sun.tools.javac.util.DefinedBy; import com.sun.tools.javac.util.DefinedBy;
import com.sun.tools.javac.util.DefinedBy.Api; import com.sun.tools.javac.util.DefinedBy.Api;
@ -568,7 +568,7 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages {
} catch (EOFException e) { } catch (EOFException e) {
reportError("err.end.of.file", className); reportError("err.end.of.file", className);
result = EXIT_ERROR; result = EXIT_ERROR;
} catch (FileNotFoundException e) { } catch (FileNotFoundException | NoSuchFileException e) {
reportError("err.file.not.found", e.getLocalizedMessage()); reportError("err.file.not.found", e.getLocalizedMessage());
result = EXIT_ERROR; result = EXIT_ERROR;
} catch (IOException e) { } catch (IOException e) {
@ -668,9 +668,12 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages {
if (fileManager instanceof StandardJavaFileManager) { if (fileManager instanceof StandardJavaFileManager) {
StandardJavaFileManager sfm = (StandardJavaFileManager) fileManager; StandardJavaFileManager sfm = (StandardJavaFileManager) fileManager;
fo = sfm.getJavaFileObjects(className).iterator().next(); try {
if (fo != null && fo.getLastModified() != 0) { fo = sfm.getJavaFileObjects(className).iterator().next();
return fo; if (fo != null && fo.getLastModified() != 0) {
return fo;
}
} catch (IllegalArgumentException ignore) {
} }
} }
@ -859,11 +862,15 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages {
} }
private JavaFileObject getClassFileObject(String className) throws IOException { private JavaFileObject getClassFileObject(String className) throws IOException {
JavaFileObject fo; try {
fo = fileManager.getJavaFileForInput(StandardLocation.PLATFORM_CLASS_PATH, className, JavaFileObject.Kind.CLASS); JavaFileObject fo;
if (fo == null) fo = fileManager.getJavaFileForInput(StandardLocation.PLATFORM_CLASS_PATH, className, JavaFileObject.Kind.CLASS);
fo = fileManager.getJavaFileForInput(StandardLocation.CLASS_PATH, className, JavaFileObject.Kind.CLASS); if (fo == null)
return fo; fo = fileManager.getJavaFileForInput(StandardLocation.CLASS_PATH, className, JavaFileObject.Kind.CLASS);
return fo;
} catch (IllegalArgumentException e) {
return null;
}
} }
private void showHelp() { private void showHelp() {

View file

@ -26,16 +26,17 @@
package com.sun.tools.sjavac; package com.sun.tools.sjavac;
import java.io.*; import java.io.*;
import java.net.URI;
import java.nio.file.NoSuchFileException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.Collections; import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.Set; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.HashMap; import java.util.Set;
import java.text.SimpleDateFormat;
import java.net.URI;
import java.util.*;
import com.sun.tools.sjavac.options.Options; import com.sun.tools.sjavac.options.Options;
import com.sun.tools.sjavac.server.Sjavac; import com.sun.tools.sjavac.server.Sjavac;
@ -364,7 +365,7 @@ public class JavacState {
} }
} }
} }
} catch (FileNotFoundException e) { } catch (FileNotFoundException | NoSuchFileException e) {
// Silently create a new javac_state file. // Silently create a new javac_state file.
noFileFound = true; noFileFound = true;
} catch (IOException e) { } catch (IOException e) {
@ -841,7 +842,7 @@ public class JavacState {
} }
listedSources.add(l); listedSources.add(l);
} }
} catch (FileNotFoundException e) { } catch (FileNotFoundException | NoSuchFileException e) {
throw new ProblemException("Could not open "+makefileSourceList.getPath()+" since it does not exist!"); throw new ProblemException("Could not open "+makefileSourceList.getPath()+" since it does not exist!");
} catch (IOException e) { } catch (IOException e) {
throw new ProblemException("Could not read "+makefileSourceList.getPath()); throw new ProblemException("Could not read "+makefileSourceList.getPath());

View file

@ -27,6 +27,8 @@ package com.sun.tools.sjavac.comp;
import java.io.*; import java.io.*;
import java.net.URI; import java.net.URI;
import java.nio.file.NoSuchFileException;
import javax.lang.model.element.Modifier; import javax.lang.model.element.Modifier;
import javax.lang.model.element.NestingKind; import javax.lang.model.element.NestingKind;
import javax.tools.JavaFileObject; import javax.tools.JavaFileObject;
@ -108,7 +110,7 @@ public class SmartFileObject implements JavaFileObject {
while (r.ready()) { while (r.ready()) {
s.append(r.readLine()+lineseparator); s.append(r.readLine()+lineseparator);
} }
} catch (FileNotFoundException e) { } catch (FileNotFoundException | NoSuchFileException e) {
// Perfectly ok. // Perfectly ok.
} }
return new SmartWriter(file, s.toString(), file.getName(), stdout); return new SmartWriter(file, s.toString(), file.getName(), stdout);

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -59,7 +59,7 @@ public class T6725036 {
long jarEntryTime = je.getTime(); long jarEntryTime = je.getTime();
ZipFileIndexCache zfic = ZipFileIndexCache.getSharedInstance(); ZipFileIndexCache zfic = ZipFileIndexCache.getSharedInstance();
ZipFileIndex zfi = zfic.getZipFileIndex(rt_jar, null, false, null, false); ZipFileIndex zfi = zfic.getZipFileIndex(rt_jar.toPath(), null, false, null, false);
long zfiTime = zfi.getLastModified(TEST_ENTRY_NAME); long zfiTime = zfi.getLastModified(TEST_ENTRY_NAME);
check(je, jarEntryTime, zfi + ":" + TEST_ENTRY_NAME.getPath(), zfiTime); check(je, jarEntryTime, zfi + ":" + TEST_ENTRY_NAME.getPath(), zfiTime);

View file

@ -34,6 +34,7 @@
import java.io.File; import java.io.File;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.nio.file.Path;
import java.util.Arrays; import java.util.Arrays;
import static javax.tools.StandardLocation.CLASS_OUTPUT; import static javax.tools.StandardLocation.CLASS_OUTPUT;
import javax.tools.*; import javax.tools.*;
@ -59,10 +60,10 @@ public class T6440528 extends ToolTester {
System.err.println("Got: " + got); System.err.println("Got: " + got);
} }
private File getUnderlyingFile(Object o) throws Exception { private File getUnderlyingFile(FileObject o) throws Exception {
Field file = o.getClass().getDeclaredField("file"); Field file = o.getClass().getDeclaredField("file"); // assumes RegularFileObject
file.setAccessible(true); file.setAccessible(true);
return (File)file.get(o); return ((Path)file.get(o)).toFile();
} }
public static void main(String... args) throws Exception { public static void main(String... args) throws Exception {

View file

@ -61,7 +61,10 @@ public class TestJavacTask {
try { try {
getTask(testFile); getTask(testFile);
} catch (IllegalArgumentException iae) { } catch (IllegalArgumentException iae) {
if (!iae.getMessage().contains("\"" + testFile.getName() + "\"")) { // The following check is somewhat fragile, since the content of the ILA is not
// formally specified. If we want to fix this, we should catch/rewrap ILA coming
// from use of java.nio.file.Path inside javac's impl of JavaFileManager.
if (!iae.getMessage().contains(testFile.getName())) {
System.err.println("Got message: " + iae.getMessage()); System.err.println("Got message: " + iae.getMessage());
throw new RuntimeException("Error: expected string not found"); throw new RuntimeException("Error: expected string not found");
} }

View file

@ -321,12 +321,17 @@ class Example implements Comparable<Example> {
first = opts.get(0); first = opts.get(0);
rest = opts.subList(1, opts.size()).toArray(new String[opts.size() - 1]); rest = opts.subList(1, opts.size()).toArray(new String[opts.size() - 1]);
} }
// For more details on the different compilers,
// see their respective class doc comments.
// See also README.examples.txt in this directory.
if (first == null || first.equals("jsr199")) if (first == null || first.equals("jsr199"))
return new Jsr199Compiler(verbose, rest); return new Jsr199Compiler(verbose, rest);
else if (first.equals("simple")) else if (first.equals("simple"))
return new SimpleCompiler(verbose); return new SimpleCompiler(verbose);
else if (first.equals("backdoor")) else if (first.equals("backdoor"))
return new BackdoorCompiler(verbose); return new BackdoorCompiler(verbose);
else if (first.equals("exec"))
return new ExecCompiler(verbose);
else else
throw new IllegalArgumentException(first); throw new IllegalArgumentException(first);
} }
@ -506,6 +511,84 @@ class Example implements Comparable<Example> {
} }
} }
/**
* Run the test in a separate process.
*/
static class ExecCompiler extends Compiler {
ExecCompiler(boolean verbose) {
super(verbose);
}
@Override
boolean run(PrintWriter out, Set<String> keys, boolean raw, List<String> opts, List<File> files) {
if (out != null && keys != null)
throw new IllegalArgumentException();
if (verbose)
System.err.println("run_exec: " + opts + " " + files);
List<String> args = new ArrayList<String>();
File javaHome = new File(System.getProperty("java.home"));
if (javaHome.getName().equals("jre"))
javaHome = javaHome.getParentFile();
File javaExe = new File(new File(javaHome, "bin"), "java");
args.add(javaExe.getPath());
File toolsJar = new File(new File(javaHome, "lib"), "tools.jar");
if (toolsJar.exists()) {
args.add("-classpath");
args.add(toolsJar.getPath());
}
addOpts(args, "test.vm.opts");
addOpts(args, "test.java.opts");
args.add(com.sun.tools.javac.Main.class.getName());
if (keys != null || raw)
args.add("-XDrawDiagnostics");
args.addAll(opts);
for (File f: files)
args.add(f.getPath());
try {
ProcessBuilder pb = new ProcessBuilder(args);
pb.redirectErrorStream(true);
Process p = pb.start();
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
if (keys != null)
scanForKeys(line, keys);
}
int rc = p.waitFor();
return (rc == 0);
} catch (IOException | InterruptedException e) {
System.err.println("Exception execing javac" + e);
System.err.println("Command line: " + opts);
return false;
}
}
private static void scanForKeys(String text, Set<String> keys) {
StringTokenizer st = new StringTokenizer(text, " ,\r\n():");
while (st.hasMoreElements()) {
String t = st.nextToken();
if (t.startsWith("compiler."))
keys.add(t);
}
}
private static void addOpts(List<String> args, String propName) {
String propValue = System.getProperty(propName);
if (propValue == null || propValue.isEmpty())
return;
args.addAll(Arrays.asList(propValue.split(" +", 0)));
}
}
static class BackdoorCompiler extends Compiler { static class BackdoorCompiler extends Compiler {
BackdoorCompiler(boolean verbose) { BackdoorCompiler(boolean verbose) {
super(verbose); super(verbose);

View file

@ -123,6 +123,9 @@ different types of information may be given:
is required to detect and track messages that bypass the normal is required to detect and track messages that bypass the normal
diagnostic mechanisms, such as output generated by the -verbose diagnostic mechanisms, such as output generated by the -verbose
option. option.
exec -- The example will be run in a subprocess. This mode is useful when
the example will leave files open, such that the only way to close
them is to exit the process.
The "jsr199" run mode accepts the following options: The "jsr199" run mode accepts the following options:
-cantRead:pattern -cantRead:pattern

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -23,5 +23,6 @@
// key: compiler.warn.proc.unclosed.type.files // key: compiler.warn.proc.unclosed.type.files
// options: -Xlint:processing -processor AnnoProc // options: -Xlint:processing -processor AnnoProc
// run: exec
class ProcUnclosedTypeFiles { } class ProcUnclosedTypeFiles { }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -99,7 +99,7 @@ public class T7018098 extends JavacTestingAbstractProcessor {
round++; round++;
if (round == 1) { if (round == 1) {
boolean expect = Boolean.valueOf(options.get("expect")); boolean expect = Boolean.valueOf(options.get("expect"));
checkEqual("cache result", fsInfo.isDirectory(testDir), expect); checkEqual("cache result", fsInfo.isDirectory(testDir.toPath()), expect);
initialFSInfo = fsInfo; initialFSInfo = fsInfo;
} else { } else {
checkEqual("fsInfo", fsInfo, initialFSInfo); checkEqual("fsInfo", fsInfo, initialFSInfo);

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -30,6 +30,7 @@
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.io.Writer; import java.io.Writer;
import java.nio.file.NoSuchFileException;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.Map; import java.util.Map;
@ -104,7 +105,7 @@ public class T7068437 {
messager.printMessage(Kind.NOTE, "found previous content of length " + messager.printMessage(Kind.NOTE, "found previous content of length " +
filer.getResource(StandardLocation.SOURCE_OUTPUT, "p", "C.java").getCharContent(false).length()); filer.getResource(StandardLocation.SOURCE_OUTPUT, "p", "C.java").getCharContent(false).length());
found = true; found = true;
} catch (FileNotFoundException x) { } catch (FileNotFoundException | NoSuchFileException x) {
messager.printMessage(Kind.NOTE, "not previously there"); messager.printMessage(Kind.NOTE, "not previously there");
found = false; found = false;
} catch (IOException x) { } catch (IOException x) {

View file

@ -33,6 +33,7 @@ import java.io.FileNotFoundException;
import java.io.FileWriter; import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import java.io.Writer; import java.io.Writer;
import java.nio.file.NoSuchFileException;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@ -143,7 +144,7 @@ public class T7068451 {
try { try {
int len = filer.getResource(StandardLocation.SOURCE_OUTPUT, "p", "C.java").getCharContent(false).length(); int len = filer.getResource(StandardLocation.SOURCE_OUTPUT, "p", "C.java").getCharContent(false).length();
messager.printMessage(Kind.NOTE, "C.java: found previous content of length " + len); messager.printMessage(Kind.NOTE, "C.java: found previous content of length " + len);
} catch (FileNotFoundException x) { } catch (FileNotFoundException | NoSuchFileException x) {
messager.printMessage(Kind.NOTE, "C.java: not previously there"); messager.printMessage(Kind.NOTE, "C.java: not previously there");
} catch (IOException x) { } catch (IOException x) {
messager.printMessage(Kind.ERROR, "while reading: " + x); messager.printMessage(Kind.ERROR, "while reading: " + x);

View file

@ -30,6 +30,7 @@
* @run main LinksTest * @run main LinksTest
*/ */
import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Paths; import java.nio.file.Paths;
@ -48,17 +49,24 @@ public class LinksTest {
ToolBox tb = new ToolBox(); ToolBox tb = new ToolBox();
tb.writeFile("tmp/B.java", BSrc); tb.writeFile("tmp/B.java", BSrc);
// Try to set up a symbolic link for the test.
try { try {
Files.createSymbolicLink(Paths.get("a"), Paths.get("tmp")); Files.createSymbolicLink(Paths.get("a"), Paths.get("tmp"));
System.err.println("Created symbolic link");
tb.new JavacTask() } catch (UnsupportedOperationException | IOException e) {
.sourcepath(".") System.err.println("Problem creating symbolic link: " + e);
.outdir(".") System.err.println("Test cannot continue; test passed by default");
.sources(TSrc) return;
.run();
} catch (UnsupportedOperationException e) {
System.err.println("Symbolic links not supported on this system. The test can't finish");
} }
// If symbolic link was successfully created,
// try a compilation that will use it.
tb.new JavacTask()
.sourcepath(".")
.outdir(".")
.sources(TSrc)
.run()
.writeAll();
} }
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * 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"); if (!testFile.canRead()) throw new IllegalStateException("Cannot read the test source");
JavacTool compiler = JavacTool.create(); JavacTool compiler = JavacTool.create();
JavacFileManager fm = compiler.getStandardFileManager(null, null, null); JavacFileManager fm = compiler.getStandardFileManager(null, null, null);
testContent = fm.getRegularFile(testFile).getCharContent(true).toString(); testContent = fm.getRegularFile(testFile.toPath()).getCharContent(true).toString();
JavaFileObject testFileObject = new TestFO(new URI("mem://" + args[0]), testContent); JavaFileObject testFileObject = new TestFO(new URI("mem://" + args[0]), testContent);
TestFM testFileManager = new TestFM(fm); TestFM testFileManager = new TestFM(fm);
JavacTask task = compiler.getTask(null, JavacTask task = compiler.getTask(null,

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * 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]); File inp = new File(sp, args[0]);
if (inp.canRead()) { if (inp.canRead()) {
testContent = fm.getRegularFile(inp).getCharContent(true).toString(); testContent = fm.getRegularFile(inp.toPath()).getCharContent(true).toString();
} }
} }
if (testContent == null) throw new IllegalStateException(); if (testContent == null) throw new IllegalStateException();
@ -167,4 +167,4 @@ public class Processor extends AbstractProcessor {
} }
} }
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -26,7 +26,8 @@
* @bug 4914724 4973116 5014511 * @bug 4914724 4973116 5014511
* @summary Ensure that a supplementary character can be used as part/whole of a * @summary Ensure that a supplementary character can be used as part/whole of a
* class name on platforms that have Unicode aware filesystems. * class name on platforms that have Unicode aware filesystems.
* @run main SupplementaryJavaID6 * @build Wrapper
* @run main Wrapper SupplementaryJavaID6
*/ */
public class SupplementaryJavaID6 { public class SupplementaryJavaID6 {

View file

@ -0,0 +1,78 @@
/*
* Copyright (c) 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.
*/
import java.io.File;
import java.lang.reflect.Method;
import java.nio.file.InvalidPathException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
public class Wrapper {
public static void main(String... args) throws Exception {
if (!isSupplementaryCharactersSupported()) {
System.out.println("Unicode supplementary characters in filenames not supported: pass by default");
return;
}
String testClassName = args[0];
String[] testArgs = Arrays.copyOfRange(args, 1, args.length);
File srcDir = new File(System.getProperty("test.src"));
File clsDir = new File(System.getProperty("test.classes"));
File src = new File(srcDir, testClassName + ".java");
File cls = new File(clsDir, testClassName + ".class");
if (cls.lastModified() < src.lastModified()) {
System.err.println("Recompiling test class...");
String[] javacArgs = { "-d", clsDir.getPath(), src.getPath() };
int rc = com.sun.tools.javac.Main.compile(javacArgs);
if (rc != 0)
throw new Exception("compilation failed");
}
Class<?> mainClass = Class.forName(testClassName);
Method main = mainClass.getMethod("main", String[].class);
main.invoke(null, new Object[] { testArgs });
}
private static boolean isSupplementaryCharactersSupported() {
try {
String s = "p--\ud801\udc00--";
System.err.println("Trying: Paths.get(" + s + ")");
Path p1 = Paths.get(s);
System.err.println("Found: " + p1);
System.err.println("Trying: p1.resolve(" + s + ")");
Path p2 = p1.resolve(s);
System.err.println("Found: " + p2);
return p1.toString().equals(s) && p2.toString().equals(s + java.io.File.separator + s);
} catch (InvalidPathException e) {
System.err.println(e);
return false;
}
}
}

View file

@ -74,7 +74,7 @@ public class VerifySuppressWarnings {
File inp = new File(sp, args[0]); File inp = new File(sp, args[0]);
if (inp.canRead()) { if (inp.canRead()) {
testContent = fm.getRegularFile(inp).getCharContent(true).toString(); testContent = fm.getRegularFile(inp.toPath()).getCharContent(true).toString();
} }
} }
if (testContent == null) throw new IllegalStateException(); if (testContent == null) throw new IllegalStateException();

View file

@ -57,7 +57,7 @@ public class WhitespaceTest {
if (line.endsWith(" ")) if (line.endsWith(" "))
error("line has trailing whitespace: " + line); error("line has trailing whitespace: " + line);
int comment = line.indexOf(doubleSlash); int comment = line.indexOf(doubleSlash);
if (comment > 0 && line.charAt(comment - 1) != ' ') if (comment > 0 && line.charAt(comment - 1) != ' ' && !line.contains("file:///"))
error("no space before comment: " + line); error("no space before comment: " + line);
if (line.matches(" +}")) if (line.matches(" +}"))
error("bad indentation: " + line); error("bad indentation: " + line);