# HG changeset patch # User jjg # Date 1463078168 25200 # Node ID 1153fab98d25d90491ff6a905bb6737b82a53515 # Parent 2efb75c09230d066be9228856bc052ae51d2772e 8149843: StandardJavaFileManager should provide a way to get paths from strings 8150111: Need to change signature of StandardJavaFileManager.setLocationFromPaths Reviewed-by: vromero, jlahoda diff -r 2efb75c09230 -r 1153fab98d25 langtools/src/java.compiler/share/classes/javax/tools/StandardJavaFileManager.java --- a/langtools/src/java.compiler/share/classes/javax/tools/StandardJavaFileManager.java Wed May 11 20:28:22 2016 +0000 +++ b/langtools/src/java.compiler/share/classes/javax/tools/StandardJavaFileManager.java Thu May 12 11:36:08 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2016, 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 @@ -29,6 +29,7 @@ import java.io.IOException; import java.nio.file.Path; import java.util.Arrays; +import java.util.Collection; import static javax.tools.FileManagerUtils.*; @@ -176,7 +177,8 @@ /** * Returns file objects representing the given paths. * - *

The default implementation converts each path to a file and calls + * @implSpec + * The default implementation converts each path to a file and calls * {@link #getJavaFileObjectsFromFiles getJavaObjectsFromFiles}. * IllegalArgumentException will be thrown if any of the paths * cannot be converted to a file. @@ -280,10 +282,21 @@ * Associates the given search path with the given location. Any * previous value will be discarded. * - *

The default implementation converts each path to a file and calls + * @apiNote + * The type of the {@code paths} parameter is a {@code Collection} + * and not {@code Iterable}. This is to prevent the possibility of + * accidentally calling the method with a single {@code Path} as + * the second argument, because although {@code Path} implements + * {@code Iterable}, it would almost never be correct to call + * this method with a single {@code Path} and have it be treated as + * an {@code Iterable} of its components. + * + * + * @implSpec + * The default implementation converts each path to a file and calls * {@link #getJavaFileObjectsFromFiles getJavaObjectsFromFiles}. * IllegalArgumentException will be thrown if any of the paths - * cannot be converted to a file.

+ * cannot be converted to a file. * * @param location a location * @param paths a list of paths, if {@code null} use the default @@ -297,8 +310,8 @@ * * @since 9 */ - default void setLocationFromPaths(Location location, Iterable paths) - throws IOException { + default void setLocationFromPaths(Location location, Collection paths) + throws IOException { setLocation(location, asFiles(paths)); } @@ -319,6 +332,11 @@ /** * Returns the search path associated with the given location. * + * @implSpec + * The default implementation calls {@link #getLocation getLocation} + * and then returns an {@code Iterable} formed by calling {@code toPath()} + * on each {@code File} returned from {@code getLocation}. + * * @param location a location * @return a list of paths or {@code null} if this location has no * associated search path @@ -337,8 +355,9 @@ * {@link java.nio.file.Path Path} object. In such cases, this method may be * used to access that object. * - *

The default implementation throws {@link UnsupportedOperationException} - * for all files.

+ * @implSpec + * The default implementation throws {@link UnsupportedOperationException} + * for all files. * * @param file a file object * @return a path representing the same underlying file system artifact @@ -351,4 +370,36 @@ throw new UnsupportedOperationException(); } + /** + * Factory to create {@code Path} objects from strings. + * + * @since 9 + */ + interface PathFactory { + /** + * Converts a path string, or a sequence of strings that when joined form a path string, to a Path. + * + * @param first the path string or initial part of the path string + * @param more additional strings to be joined to form the path string + * @return the resulting {@code Path} + */ + Path getPath(String first, String... more); + } + + /** + * Specify a factory that can be used to generate a path from a string, or series of strings. + * + * If this method is not called, a factory whose {@code getPath} method is + * equivalent to calling + * {@link java.nio.file.Paths#get(String, String...) java.nio.file.Paths.get(first, more)} + * will be used. + * + * @implSpec + * The default implementation of this method ignores the factory that is provided. + * + * @param f the factory + * + * @since 9 + */ + default void setPathFactory(PathFactory f) { } } diff -r 2efb75c09230 -r 1153fab98d25 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/ClientCodeWrapper.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/ClientCodeWrapper.java Wed May 11 20:28:22 2016 +0000 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/ClientCodeWrapper.java Thu May 12 11:36:08 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2016, 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 @@ -492,7 +492,7 @@ } @Override @DefinedBy(Api.COMPILER) - public void setLocationFromPaths(Location location, Iterable paths) throws IOException { + public void setLocationFromPaths(Location location, Collection paths) throws IOException { try { ((StandardJavaFileManager)clientJavaFileManager).setLocationFromPaths(location, paths); } catch (ClientCodeException e) { @@ -534,6 +534,17 @@ throw new ClientCodeException(e); } } + + @Override @DefinedBy(Api.COMPILER) + public void setPathFactory(PathFactory f) { + try { + ((StandardJavaFileManager)clientJavaFileManager).setPathFactory(f); + } catch (ClientCodeException e) { + throw e; + } catch (RuntimeException | Error e) { + throw new ClientCodeException(e); + } + } } protected class WrappedFileObject implements FileObject { diff -r 2efb75c09230 -r 1153fab98d25 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/FSInfo.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/FSInfo.java Wed May 11 20:28:22 2016 +0000 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/FSInfo.java Thu May 12 11:36:08 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,7 @@ package com.sun.tools.javac.file; import java.io.IOException; +import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -108,7 +109,7 @@ for (StringTokenizer st = new StringTokenizer(path); st.hasMoreTokens(); ) { String elt = st.nextToken(); - Path f = Paths.get(elt); + Path f = FileSystems.getDefault().getPath(elt); if (!f.isAbsolute() && parent != null) f = parent.resolve(f).toAbsolutePath(); list.add(f); diff -r 2efb75c09230 -r 1153fab98d25 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java Wed May 11 20:28:22 2016 +0000 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java Thu May 12 11:36:08 2016 -0700 @@ -109,6 +109,8 @@ protected boolean symbolFileEnabled; + private PathFactory pathFactory = Paths::get; + protected enum SortFiles implements Comparator { FORWARD { @Override @@ -166,6 +168,16 @@ } } + @Override @DefinedBy(DefinedBy.Api.COMPILER) + public void setPathFactory(PathFactory f) { + pathFactory = Objects.requireNonNull(f); + locations.setPathFactory(f); + } + + private Path getPath(String first, String... more) { + return pathFactory.getPath(first, more); + } + /** * Set whether or not to use ct.sym as an alternate to rt.jar. */ @@ -199,7 +211,7 @@ public Iterable getJavaFileObjectsFromStrings(Iterable names) { ListBuffer paths = new ListBuffer<>(); for (String name : names) - paths.append(Paths.get(nullCheck(name))); + paths.append(getPath(nullCheck(name))); return getJavaFileObjectsFromPaths(paths.toList()); } @@ -837,7 +849,7 @@ if (sibling != null && sibling instanceof PathFileObject) { return ((PathFileObject) sibling).getSibling(baseName); } else { - Path p = Paths.get(baseName); + Path p = getPath(baseName); Path real = fsInfo.getCanonicalFile(p); return PathFileObject.forSimplePath(this, real, p); } @@ -855,7 +867,7 @@ try { if (dir == null) { - dir = Paths.get(System.getProperty("user.dir")); + dir = getPath(System.getProperty("user.dir")); } Path path = fileName.resolveAgainst(fsInfo.getCanonicalFile(dir)); return PathFileObject.forDirectoryPath(this, path, dir, fileName); @@ -918,7 +930,7 @@ @Override @DefinedBy(Api.COMPILER) public void setLocationFromPaths(Location location, - Iterable searchpath) + Collection searchpath) throws IOException { nullCheck(location); diff -r 2efb75c09230 -r 1153fab98d25 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java Wed May 11 20:28:22 2016 +0000 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java Thu May 12 11:36:08 2016 -0700 @@ -68,6 +68,7 @@ import javax.tools.JavaFileManager; import javax.tools.JavaFileManager.Location; import javax.tools.StandardJavaFileManager; +import javax.tools.StandardJavaFileManager.PathFactory; import javax.tools.StandardLocation; import com.sun.tools.javac.code.Lint; @@ -121,7 +122,9 @@ private ModuleNameReader moduleNameReader; - static final Path javaHome = Paths.get(System.getProperty("java.home")); + private PathFactory pathFactory = Paths::get; + + static final Path javaHome = FileSystems.getDefault().getPath(System.getProperty("java.home")); static final Path thisSystemModules = javaHome.resolve("lib").resolve("modules"); Map fileSystems = new LinkedHashMap<>(); @@ -131,6 +134,10 @@ initHandlers(); } + Path getPath(String first, String... more) { + return pathFactory.getPath(first, more); + } + public void close() throws IOException { ListBuffer list = new ListBuffer<>(); closeables.forEach(closeable -> { @@ -155,6 +162,10 @@ this.fsInfo = fsInfo; } + void setPathFactory(PathFactory f) { + pathFactory = f; + } + boolean isDefaultBootClassPath() { BootClassPathLocationHandler h = (BootClassPathLocationHandler) getHandler(PLATFORM_CLASS_PATH); @@ -167,7 +178,7 @@ * @param searchPath The search path to be split * @return The elements of the path */ - private static Iterable getPathEntries(String searchPath) { + private Iterable getPathEntries(String searchPath) { return getPathEntries(searchPath, null); } @@ -181,7 +192,7 @@ * empty path elements * @return The elements of the path */ - private static Iterable getPathEntries(String searchPath, Path emptyPathDefault) { + private Iterable getPathEntries(String searchPath, Path emptyPathDefault) { ListBuffer entries = new ListBuffer<>(); for (String s: searchPath.split(Pattern.quote(File.pathSeparator), -1)) { if (s.isEmpty()) { @@ -189,7 +200,7 @@ entries.add(emptyPathDefault); } } else { - entries.add(Paths.get(s)); + entries.add(getPath(s)); } } return entries; @@ -465,7 +476,7 @@ // need to decide how best to report issue for benefit of // direct API call on JavaFileManager.handleOption(specifies IAE) // vs. command line decoding. - outputDir = (value == null) ? null : Paths.get(value); + outputDir = (value == null) ? null : getPath(value); return true; } @@ -606,7 +617,7 @@ protected SearchPath createPath() { return new SearchPath() .expandJarClassPaths(true) // Only search user jars for Class-Paths - .emptyPathDefault(Paths.get(".")); // Empty path elt ==> current directory + .emptyPathDefault(getPath(".")); // Empty path elt ==> current directory } private void lazy() { @@ -791,7 +802,7 @@ paths.addAll(modules); for (String s : files.split(Pattern.quote(File.pathSeparator))) { - paths.add(Paths.get(s)); + paths.add(getPath(s)); } return paths; @@ -1170,12 +1181,12 @@ for (String seg: segments) { int markStart = seg.indexOf(MARKER); if (markStart == -1) { - add(map, Paths.get(seg), null); + add(map, getPath(seg), null); } else { if (markStart == 0 || !isSeparator(seg.charAt(markStart - 1))) { throw new IllegalArgumentException("illegal use of " + MARKER + " in " + seg); } - Path prefix = Paths.get(seg.substring(0, markStart - 1)); + Path prefix = getPath(seg.substring(0, markStart - 1)); Path suffix; int markEnd = markStart + MARKER.length(); if (markEnd == seg.length()) { @@ -1184,7 +1195,7 @@ || seg.indexOf(MARKER, markEnd) != -1) { throw new IllegalArgumentException("illegal use of " + MARKER + " in " + seg); } else { - suffix = Paths.get(seg.substring(markEnd + 1)); + suffix = getPath(seg.substring(markEnd + 1)); } add(map, prefix, suffix); } @@ -1331,13 +1342,13 @@ } private class SystemModulesLocationHandler extends BasicLocationHandler { - private Path javaHome; + private Path systemJavaHome; private Path modules; private Map systemModules; SystemModulesLocationHandler() { super(StandardLocation.SYSTEM_MODULES, Option.SYSTEM); - javaHome = Paths.get(System.getProperty("java.home")); + systemJavaHome = Locations.javaHome; } @Override @@ -1347,11 +1358,11 @@ } if (value == null) { - javaHome = Paths.get(System.getProperty("java.home")); + systemJavaHome = Locations.javaHome; } else if (value.equals("none")) { - javaHome = null; + systemJavaHome = null; } else { - update(Paths.get(value)); + update(getPath(value)); } modules = null; @@ -1360,13 +1371,13 @@ @Override Collection getPaths() { - return (javaHome == null) ? null : Collections.singleton(javaHome); + return (systemJavaHome == null) ? null : Collections.singleton(systemJavaHome); } @Override void setPaths(Iterable files) throws IOException { if (files == null) { - javaHome = null; + systemJavaHome = null; } else { Iterator pathIter = files.iterator(); if (!pathIter.hasNext()) { @@ -1386,16 +1397,15 @@ } private void update(Path p) { - if (!isCurrentPlatform(p) && !Files.exists(p.resolve("jrt-fs.jar")) && !Files.exists(javaHome.resolve("modules"))) + if (!isCurrentPlatform(p) && !Files.exists(p.resolve("jrt-fs.jar")) && !Files.exists(systemJavaHome.resolve("modules"))) throw new IllegalArgumentException(p.toString()); - javaHome = p; + systemJavaHome = p; modules = null; } private boolean isCurrentPlatform(Path p) { - Path jh = Paths.get(System.getProperty("java.home")); try { - return Files.isSameFile(p, jh); + return Files.isSameFile(p, Locations.javaHome); } catch (IOException ex) { throw new IllegalArgumentException(p.toString(), ex); } @@ -1421,7 +1431,7 @@ return; } - if (javaHome == null) { + if (systemJavaHome == null) { systemModules = Collections.emptyMap(); return; } @@ -1431,15 +1441,15 @@ URI jrtURI = URI.create("jrt:/"); FileSystem jrtfs; - if (isCurrentPlatform(javaHome)) { + if (isCurrentPlatform(systemJavaHome)) { jrtfs = FileSystems.getFileSystem(jrtURI); } else { try { Map attrMap = - Collections.singletonMap("java.home", javaHome.toString()); + Collections.singletonMap("java.home", systemJavaHome.toString()); jrtfs = FileSystems.newFileSystem(jrtURI, attrMap); } catch (ProviderNotFoundException ex) { - URL javaHomeURL = javaHome.resolve("jrt-fs.jar").toUri().toURL(); + URL javaHomeURL = systemJavaHome.resolve("jrt-fs.jar").toUri().toURL(); ClassLoader currentLoader = Locations.class.getClassLoader(); URLClassLoader fsLoader = new URLClassLoader(new URL[] {javaHomeURL}, currentLoader); @@ -1454,7 +1464,7 @@ modules = jrtfs.getPath("/modules"); } catch (FileSystemNotFoundException | ProviderNotFoundException e) { - modules = javaHome.resolve("modules"); + modules = systemJavaHome.resolve("modules"); if (!Files.exists(modules)) throw new IOException("can't find system classes", e); } diff -r 2efb75c09230 -r 1153fab98d25 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/PathFileObject.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/PathFileObject.java Wed May 11 20:28:22 2016 +0000 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/PathFileObject.java Thu May 12 11:36:08 2016 -0700 @@ -109,7 +109,7 @@ private DirectoryFileObject(BaseFileManager fileManager, Path path, Path userPackageRootDir, RelativePath relativePath) { super(fileManager, path); - this.userPackageRootDir = userPackageRootDir; + this.userPackageRootDir = Objects.requireNonNull(userPackageRootDir); this.relativePath = relativePath; } diff -r 2efb75c09230 -r 1153fab98d25 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/RelativePath.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/RelativePath.java Wed May 11 20:28:22 2016 +0000 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/RelativePath.java Thu May 12 11:36:08 2016 -0700 @@ -26,10 +26,8 @@ package com.sun.tools.javac.file; import java.nio.file.FileSystem; -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.ZipFile; @@ -58,13 +56,8 @@ public abstract String basename(); public Path resolveAgainst(Path directory) throws /*unchecked*/ InvalidPathException { - if (directory == null) { - String sep = FileSystems.getDefault().getSeparator(); - return Paths.get(path.replace("/", sep)); - } else { - String sep = directory.getFileSystem().getSeparator(); - return directory.resolve(path.replace("/", sep)); - } + String sep = directory.getFileSystem().getSeparator(); + return directory.resolve(path.replace("/", sep)); } public Path resolveAgainst(FileSystem fs) throws /*unchecked*/ InvalidPathException { diff -r 2efb75c09230 -r 1153fab98d25 langtools/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java --- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java Wed May 11 20:28:22 2016 +0000 +++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java Thu May 12 11:36:08 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2016, 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 @@ -1045,7 +1045,7 @@ public SourceCache(AnalyzeTask originalTask) { this.originalTask = originalTask; - Iterable sources = findSources(); + List sources = findSources(); if (sources.iterator().hasNext()) { StandardJavaFileManager fm = compiler.getStandardFileManager(null, null, null); try { @@ -1145,9 +1145,9 @@ } } - private Iterable availableSources; + private List availableSources; - private Iterable findSources() { + private List findSources() { if (availableSources != null) { return availableSources; }