langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java
changeset 27858 443efec4bf09
parent 27579 d1a63c99cdd5
parent 27852 2e6ad0e4fe20
child 28332 cd3ea1087d2b
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java	Wed Jul 05 20:08:43 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java	Wed Dec 03 19:28:40 2014 +0000
@@ -34,7 +34,12 @@
 import java.net.URL;
 import java.nio.CharBuffer;
 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.Arrays;
 import java.util.Collection;
@@ -45,6 +50,8 @@
 import java.util.Iterator;
 import java.util.Map;
 import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 import java.util.zip.ZipFile;
 
 import javax.lang.model.SourceVersion;
@@ -97,17 +104,17 @@
     protected boolean mmappedIO;
     protected boolean symbolFileEnabled;
 
-    protected enum SortFiles implements Comparator<File> {
+    protected enum SortFiles implements Comparator<Path> {
         FORWARD {
             @Override
-            public int compare(File f1, File f2) {
-                return f1.getName().compareTo(f2.getName());
+            public int compare(Path f1, Path f2) {
+                return f1.getFileName().compareTo(f2.getFileName());
             }
         },
         REVERSE {
             @Override
-            public int compare(File f1, File f2) {
-                return -f1.getName().compareTo(f2.getName());
+            public int compare(Path f1, Path f2) {
+                return -f1.getFileName().compareTo(f2.getFileName());
             }
         }
     }
@@ -171,10 +178,10 @@
     }
 
     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);
     }
 
@@ -298,25 +305,36 @@
      * Insert all files in subdirectory subdirectory of directory directory
      * which match fileKinds into resultList
      */
-    private void listDirectory(File directory,
+    private void listDirectory(Path directory,
                                RelativeDirectory subdirectory,
                                Set<JavaFileObject.Kind> fileKinds,
                                boolean recurse,
                                ListBuffer<JavaFileObject> resultList) {
-        File d = subdirectory.getFile(directory);
-        if (!caseMapCheck(d, subdirectory))
+        Path d;
+        try {
+            d = subdirectory.getFile(directory);
+        } catch (InvalidPathException ignore) {
             return;
+        }
 
-        File[] files = d.listFiles();
-        if (files == null)
+        if (!Files.exists(d)) {
+           return;
+        }
+
+        if (!caseMapCheck(d, subdirectory)) {
             return;
-
-        if (sortFiles != null)
-            Arrays.sort(files, sortFiles);
+        }
 
-        for (File f: files) {
-            String fname = f.getName();
-            if (f.isDirectory()) {
+        java.util.List<Path> files;
+        try (Stream<Path> s = Files.list(d)) {
+            files = (sortFiles == null ? s : s.sorted(sortFiles)).collect(Collectors.toList());
+        } catch (IOException ignore) {
+            return;
+        }
+
+        for (Path f: files) {
+            String fname = f.getFileName().toString();
+            if (Files.isDirectory(f)) {
                 if (recurse && SourceVersion.isIdentifier(fname)) {
                     listDirectory(directory,
                                   new RelativeDirectory(subdirectory, fname),
@@ -327,7 +345,7 @@
             } else {
                 if (isValidFile(fname, fileKinds)) {
                     JavaFileObject fe =
-                        new RegularFileObject(this, fname, new File(d, fname));
+                        new RegularFileObject(this, fname, d.resolve(fname));
                     resultList.append(fe);
                 }
             }
@@ -370,7 +388,7 @@
      * Insert all files in subdirectory subdirectory of container which
      * match fileKinds into resultList
      */
-    private void listContainer(File container,
+    private void listContainer(Path container,
                                RelativeDirectory subdirectory,
                                Set<JavaFileObject.Kind> fileKinds,
                                boolean recurse,
@@ -378,10 +396,10 @@
         Archive archive = archives.get(container);
         if (archive == null) {
             // Very temporary and obnoxious interim hack
-            if (container.getName().equals("bootmodules.jimage")) {
+            if (container.endsWith("bootmodules.jimage")) {
                 System.err.println("Warning: reference to bootmodules.jimage replaced by jrt:");
                 container = Locations.JRT_MARKER_FILE;
-            } else if (container.getName().endsWith(".jimage")) {
+            } else if (container.getFileName().toString().endsWith(".jimage")) {
                 System.err.println("Warning: reference to " + container + " ignored");
                 return;
             }
@@ -436,13 +454,15 @@
      *  ends in a string of characters with the same case as given name.
      *  Ignore file separators in both path and name.
      */
-    private boolean caseMapCheck(File f, RelativePath name) {
+    private boolean caseMapCheck(Path f, RelativePath name) {
         if (fileSystemIsCaseSensitive) return true;
-        // Note that getCanonicalPath() returns the case-sensitive
+        // Note that toRealPath() returns the case-sensitive
         // spelled file name.
         String path;
+        char sep;
         try {
-            path = f.getCanonicalPath();
+            path = f.toRealPath(LinkOption.NOFOLLOW_LINKS).toString();
+            sep = f.getFileSystem().getSeparator().charAt(0);
         } catch (IOException ex) {
             return false;
         }
@@ -451,7 +471,7 @@
         int i = pcs.length - 1;
         int j = ncs.length - 1;
         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--;
             if (i >= 0 && j >= 0) {
                 if (pcs[i] != ncs[j]) return false;
@@ -479,8 +499,8 @@
     }
 
     public class MissingArchive implements Archive {
-        final File zipFileName;
-        public MissingArchive(File name) {
+        final Path zipFileName;
+        public MissingArchive(Path name) {
             zipFileName = name;
         }
         @Override
@@ -515,7 +535,7 @@
 
     /** A directory of zip files already opened.
      */
-    Map<File, Archive> archives = new HashMap<>();
+    Map<Path, Archive> archives = new HashMap<>();
 
     /*
      * This method looks for a ZipFormatException and takes appropriate
@@ -523,7 +543,7 @@
      * fail over to the platform zip, and allow it to deal with a potentially
      * non compliant zip file.
      */
-    protected Archive openArchive(File zipFilename) throws IOException {
+    protected Archive openArchive(Path zipFilename) throws IOException {
         try {
             return openArchive(zipFilename, contextUseOptimizedZip);
         } catch (IOException ioe) {
@@ -537,7 +557,7 @@
 
     /** 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 {
         Archive archive;
         try {
 
@@ -547,7 +567,7 @@
             String preindexCacheLocation = null;
 
             if (!useOptimizedZip) {
-                zdir = new ZipFile(zipFileName);
+                zdir = new ZipFile(zipFileName.toFile());
             } else {
                 usePreindexedCache = options.isSet("usezipindex");
                 preindexCacheLocation = options.get("java.io.tmpdir");
@@ -584,12 +604,12 @@
                                     preindexCacheLocation,
                                     options.isSet("writezipindexfiles")));
                 }
-        } catch (FileNotFoundException ex) {
+        } catch (FileNotFoundException | NoSuchFileException ex) {
             archive = new MissingArchive(zipFileName);
         } catch (ZipFileIndex.ZipFormatException zfe) {
             throw zfe;
         } catch (IOException ex) {
-            if (zipFileName.exists())
+            if (Files.exists(zipFileName))
                 log.error("error.reading.file", zipFileName, getMessage(ex));
             archive = new MissingArchive(zipFileName);
         }
@@ -649,13 +669,13 @@
         nullCheck(packageName);
         nullCheck(kinds);
 
-        Iterable<? extends File> path = getLocation(location);
+        Iterable<? extends Path> path = getLocationAsPaths(location);
         if (path == null)
             return List.nil();
         RelativeDirectory subdirectory = RelativeDirectory.forPackage(packageName);
         ListBuffer<JavaFileObject> results = new ListBuffer<>();
 
-        for (File directory : path)
+        for (Path directory : path)
             listContainer(directory, subdirectory, kinds, recurse, results);
         return results.toList();
     }
@@ -665,7 +685,7 @@
         file.getClass(); // null check
         location.getClass(); // null check
         // Need to match the path semantics of list(location, ...)
-        Iterable<? extends File> path = getLocation(location);
+        Iterable<? extends Path> path = getLocationAsPaths(location);
         if (path == null) {
             return null;
         }
@@ -730,11 +750,11 @@
     }
 
     private JavaFileObject getFileForInput(Location location, RelativeFile name) throws IOException {
-        Iterable<? extends File> path = getLocation(location);
+        Iterable<? extends Path> path = getLocationAsPaths(location);
         if (path == null)
             return null;
 
-        for (File file: path) {
+        for (Path file: path) {
             Archive a = archives.get(file);
             if (a == null) {
                 // archives are not created for directories or jrt: images
@@ -747,9 +767,12 @@
                         return PathFileObject.createJRTPathFileObject(this, p);
                     continue;
                 } else if (fsInfo.isDirectory(file)) {
-                    File f = name.getFile(file);
-                    if (f.exists())
-                        return new RegularFileObject(this, f);
+                    try {
+                        Path f = name.getFile(file);
+                        if (Files.exists(f))
+                            return new RegularFileObject(this, f);
+                    } catch (InvalidPathException ignore) {
+                    }
                     continue;
                 }
                 // Not a directory, create the archive
@@ -802,31 +825,37 @@
                                             FileObject sibling)
         throws IOException
     {
-        File dir;
+        Path dir;
         if (location == CLASS_OUTPUT) {
             if (getClassOutDir() != null) {
                 dir = getClassOutDir();
             } else {
-                File siblingDir = null;
+                Path siblingDir = null;
                 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) {
             dir = (getSourceOutDir() != null ? getSourceOutDir() : getClassOutDir());
         } else {
-            Iterable<? extends File> path = locations.getLocation(location);
+            Iterable<? extends Path> path = locations.getLocation(location);
             dir = null;
-            for (File f: path) {
+            for (Path f: path) {
                 dir = f;
                 break;
             }
         }
 
-        File file = fileName.getFile(dir); // null-safe
-        return new RegularFileObject(this, file);
-
+        try {
+            Path file = fileName.getFile(dir); // null-safe
+            return new RegularFileObject(this, file);
+        } catch (InvalidPathException e) {
+            throw new IOException("bad filename " + fileName, e);
+        }
     }
 
     @Override @DefinedBy(Api.COMPILER)
@@ -839,7 +868,7 @@
         else
             result = new ArrayList<>();
         for (File f: files)
-            result.add(new RegularFileObject(this, nullCheck(f)));
+            result.add(new RegularFileObject(this, nullCheck(f).toPath()));
         return result;
     }
 
@@ -850,24 +879,29 @@
 
     @Override @DefinedBy(Api.COMPILER)
     public void setLocation(Location location,
-                            Iterable<? extends File> path)
+                            Iterable<? extends File> searchpath)
         throws IOException
     {
         nullCheck(location);
-        locations.setLocation(location, path);
+        locations.setLocation(location, asPaths(searchpath));
     }
 
     @Override @DefinedBy(Api.COMPILER)
     public Iterable<? extends File> getLocation(Location location) {
         nullCheck(location);
+        return asFiles(locations.getLocation(location));
+    }
+
+    private Iterable<? extends Path> getLocationAsPaths(Location location) {
+        nullCheck(location);
         return locations.getLocation(location);
     }
 
-    private File getClassOutDir() {
+    private Path getClassOutDir() {
         return locations.getOutputLocation(CLASS_OUTPUT);
     }
 
-    private File getSourceOutDir() {
+    private Path getSourceOutDir() {
         return locations.getOutputLocation(SOURCE_OUTPUT);
     }
 
@@ -938,4 +972,50 @@
             return s;
         return e.toString();
     }
+
+    /* Converters between files and paths.
+     * These are temporary until we can update the StandardJavaFileManager API.
+     */
+
+    private 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();
+            }
+        };
+    }
+
+    private 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();
+            }
+        };
+    }
+
+    private static File asFile(Path path) {
+        return path == null ? null : path.toFile();
+    }
 }