langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java
changeset 37944 1153fab98d25
parent 37848 3c8ff4204d2d
child 38519 d70d50ec27bb
equal deleted inserted replaced
37943:2efb75c09230 37944:1153fab98d25
    66 
    66 
    67 import javax.lang.model.SourceVersion;
    67 import javax.lang.model.SourceVersion;
    68 import javax.tools.JavaFileManager;
    68 import javax.tools.JavaFileManager;
    69 import javax.tools.JavaFileManager.Location;
    69 import javax.tools.JavaFileManager.Location;
    70 import javax.tools.StandardJavaFileManager;
    70 import javax.tools.StandardJavaFileManager;
       
    71 import javax.tools.StandardJavaFileManager.PathFactory;
    71 import javax.tools.StandardLocation;
    72 import javax.tools.StandardLocation;
    72 
    73 
    73 import com.sun.tools.javac.code.Lint;
    74 import com.sun.tools.javac.code.Lint;
    74 import com.sun.tools.javac.main.Option;
    75 import com.sun.tools.javac.main.Option;
    75 import com.sun.tools.javac.resources.CompilerProperties.Errors;
    76 import com.sun.tools.javac.resources.CompilerProperties.Errors;
   119      */
   120      */
   120     private boolean warn;
   121     private boolean warn;
   121 
   122 
   122     private ModuleNameReader moduleNameReader;
   123     private ModuleNameReader moduleNameReader;
   123 
   124 
   124     static final Path javaHome = Paths.get(System.getProperty("java.home"));
   125     private PathFactory pathFactory = Paths::get;
       
   126 
       
   127     static final Path javaHome = FileSystems.getDefault().getPath(System.getProperty("java.home"));
   125     static final Path thisSystemModules = javaHome.resolve("lib").resolve("modules");
   128     static final Path thisSystemModules = javaHome.resolve("lib").resolve("modules");
   126 
   129 
   127     Map<Path, FileSystem> fileSystems = new LinkedHashMap<>();
   130     Map<Path, FileSystem> fileSystems = new LinkedHashMap<>();
   128     List<Closeable> closeables = new ArrayList<>();
   131     List<Closeable> closeables = new ArrayList<>();
   129 
   132 
   130     Locations() {
   133     Locations() {
   131         initHandlers();
   134         initHandlers();
       
   135     }
       
   136 
       
   137     Path getPath(String first, String... more) {
       
   138         return pathFactory.getPath(first, more);
   132     }
   139     }
   133 
   140 
   134     public void close() throws IOException {
   141     public void close() throws IOException {
   135         ListBuffer<IOException> list = new ListBuffer<>();
   142         ListBuffer<IOException> list = new ListBuffer<>();
   136         closeables.forEach(closeable -> {
   143         closeables.forEach(closeable -> {
   153         this.log = log;
   160         this.log = log;
   154         warn = lint.isEnabled(Lint.LintCategory.PATH);
   161         warn = lint.isEnabled(Lint.LintCategory.PATH);
   155         this.fsInfo = fsInfo;
   162         this.fsInfo = fsInfo;
   156     }
   163     }
   157 
   164 
       
   165     void setPathFactory(PathFactory f) {
       
   166         pathFactory = f;
       
   167     }
       
   168 
   158     boolean isDefaultBootClassPath() {
   169     boolean isDefaultBootClassPath() {
   159         BootClassPathLocationHandler h
   170         BootClassPathLocationHandler h
   160                 = (BootClassPathLocationHandler) getHandler(PLATFORM_CLASS_PATH);
   171                 = (BootClassPathLocationHandler) getHandler(PLATFORM_CLASS_PATH);
   161         return h.isDefault();
   172         return h.isDefault();
   162     }
   173     }
   165      * Split a search path into its elements. Empty path elements will be ignored.
   176      * Split a search path into its elements. Empty path elements will be ignored.
   166      *
   177      *
   167      * @param searchPath The search path to be split
   178      * @param searchPath The search path to be split
   168      * @return The elements of the path
   179      * @return The elements of the path
   169      */
   180      */
   170     private static Iterable<Path> getPathEntries(String searchPath) {
   181     private Iterable<Path> getPathEntries(String searchPath) {
   171         return getPathEntries(searchPath, null);
   182         return getPathEntries(searchPath, null);
   172     }
   183     }
   173 
   184 
   174     /**
   185     /**
   175      * Split a search path into its elements. If emptyPathDefault is not null, all empty elements in the
   186      * Split a search path into its elements. If emptyPathDefault is not null, all empty elements in the
   179      * @param searchPath The search path to be split
   190      * @param searchPath The search path to be split
   180      * @param emptyPathDefault The value to substitute for empty path elements, or null, to ignore
   191      * @param emptyPathDefault The value to substitute for empty path elements, or null, to ignore
   181      * empty path elements
   192      * empty path elements
   182      * @return The elements of the path
   193      * @return The elements of the path
   183      */
   194      */
   184     private static Iterable<Path> getPathEntries(String searchPath, Path emptyPathDefault) {
   195     private Iterable<Path> getPathEntries(String searchPath, Path emptyPathDefault) {
   185         ListBuffer<Path> entries = new ListBuffer<>();
   196         ListBuffer<Path> entries = new ListBuffer<>();
   186         for (String s: searchPath.split(Pattern.quote(File.pathSeparator), -1)) {
   197         for (String s: searchPath.split(Pattern.quote(File.pathSeparator), -1)) {
   187             if (s.isEmpty()) {
   198             if (s.isEmpty()) {
   188                 if (emptyPathDefault != null) {
   199                 if (emptyPathDefault != null) {
   189                     entries.add(emptyPathDefault);
   200                     entries.add(emptyPathDefault);
   190                 }
   201                 }
   191             } else {
   202             } else {
   192                 entries.add(Paths.get(s));
   203                 entries.add(getPath(s));
   193             }
   204             }
   194         }
   205         }
   195         return entries;
   206         return entries;
   196     }
   207     }
   197 
   208 
   463 
   474 
   464             // TODO: could/should validate outputDir exists and is a directory
   475             // TODO: could/should validate outputDir exists and is a directory
   465             // need to decide how best to report issue for benefit of
   476             // need to decide how best to report issue for benefit of
   466             // direct API call on JavaFileManager.handleOption(specifies IAE)
   477             // direct API call on JavaFileManager.handleOption(specifies IAE)
   467             // vs. command line decoding.
   478             // vs. command line decoding.
   468             outputDir = (value == null) ? null : Paths.get(value);
   479             outputDir = (value == null) ? null : getPath(value);
   469             return true;
   480             return true;
   470         }
   481         }
   471 
   482 
   472         @Override
   483         @Override
   473         Collection<Path> getPaths() {
   484         Collection<Path> getPaths() {
   604 
   615 
   605         @Override
   616         @Override
   606         protected SearchPath createPath() {
   617         protected SearchPath createPath() {
   607             return new SearchPath()
   618             return new SearchPath()
   608                     .expandJarClassPaths(true) // Only search user jars for Class-Paths
   619                     .expandJarClassPaths(true) // Only search user jars for Class-Paths
   609                     .emptyPathDefault(Paths.get("."));  // Empty path elt ==> current directory
   620                     .emptyPathDefault(getPath("."));  // Empty path elt ==> current directory
   610         }
   621         }
   611 
   622 
   612         private void lazy() {
   623         private void lazy() {
   613             if (searchPath == null) {
   624             if (searchPath == null) {
   614                 setPaths(null);
   625                 setPaths(null);
   789             // entries should be appended to the set of modules.
   800             // entries should be appended to the set of modules.
   790 
   801 
   791             paths.addAll(modules);
   802             paths.addAll(modules);
   792 
   803 
   793             for (String s : files.split(Pattern.quote(File.pathSeparator))) {
   804             for (String s : files.split(Pattern.quote(File.pathSeparator))) {
   794                 paths.add(Paths.get(s));
   805                 paths.add(getPath(s));
   795             }
   806             }
   796 
   807 
   797             return paths;
   808             return paths;
   798         }
   809         }
   799 
   810 
  1168             Map<String, Collection<Path>> map = new LinkedHashMap<>();
  1179             Map<String, Collection<Path>> map = new LinkedHashMap<>();
  1169             final String MARKER = "*";
  1180             final String MARKER = "*";
  1170             for (String seg: segments) {
  1181             for (String seg: segments) {
  1171                 int markStart = seg.indexOf(MARKER);
  1182                 int markStart = seg.indexOf(MARKER);
  1172                 if (markStart == -1) {
  1183                 if (markStart == -1) {
  1173                     add(map, Paths.get(seg), null);
  1184                     add(map, getPath(seg), null);
  1174                 } else {
  1185                 } else {
  1175                     if (markStart == 0 || !isSeparator(seg.charAt(markStart - 1))) {
  1186                     if (markStart == 0 || !isSeparator(seg.charAt(markStart - 1))) {
  1176                         throw new IllegalArgumentException("illegal use of " + MARKER + " in " + seg);
  1187                         throw new IllegalArgumentException("illegal use of " + MARKER + " in " + seg);
  1177                     }
  1188                     }
  1178                     Path prefix = Paths.get(seg.substring(0, markStart - 1));
  1189                     Path prefix = getPath(seg.substring(0, markStart - 1));
  1179                     Path suffix;
  1190                     Path suffix;
  1180                     int markEnd = markStart + MARKER.length();
  1191                     int markEnd = markStart + MARKER.length();
  1181                     if (markEnd == seg.length()) {
  1192                     if (markEnd == seg.length()) {
  1182                         suffix = null;
  1193                         suffix = null;
  1183                     } else if (!isSeparator(seg.charAt(markEnd))
  1194                     } else if (!isSeparator(seg.charAt(markEnd))
  1184                             || seg.indexOf(MARKER, markEnd) != -1) {
  1195                             || seg.indexOf(MARKER, markEnd) != -1) {
  1185                         throw new IllegalArgumentException("illegal use of " + MARKER + " in " + seg);
  1196                         throw new IllegalArgumentException("illegal use of " + MARKER + " in " + seg);
  1186                     } else {
  1197                     } else {
  1187                         suffix = Paths.get(seg.substring(markEnd + 1));
  1198                         suffix = getPath(seg.substring(markEnd + 1));
  1188                     }
  1199                     }
  1189                     add(map, prefix, suffix);
  1200                     add(map, prefix, suffix);
  1190                 }
  1201                 }
  1191             }
  1202             }
  1192 
  1203 
  1329         }
  1340         }
  1330 
  1341 
  1331     }
  1342     }
  1332 
  1343 
  1333     private class SystemModulesLocationHandler extends BasicLocationHandler {
  1344     private class SystemModulesLocationHandler extends BasicLocationHandler {
  1334         private Path javaHome;
  1345         private Path systemJavaHome;
  1335         private Path modules;
  1346         private Path modules;
  1336         private Map<String, ModuleLocationHandler> systemModules;
  1347         private Map<String, ModuleLocationHandler> systemModules;
  1337 
  1348 
  1338         SystemModulesLocationHandler() {
  1349         SystemModulesLocationHandler() {
  1339             super(StandardLocation.SYSTEM_MODULES, Option.SYSTEM);
  1350             super(StandardLocation.SYSTEM_MODULES, Option.SYSTEM);
  1340             javaHome = Paths.get(System.getProperty("java.home"));
  1351             systemJavaHome = Locations.javaHome;
  1341         }
  1352         }
  1342 
  1353 
  1343         @Override
  1354         @Override
  1344         boolean handleOption(Option option, String value) {
  1355         boolean handleOption(Option option, String value) {
  1345             if (!options.contains(option)) {
  1356             if (!options.contains(option)) {
  1346                 return false;
  1357                 return false;
  1347             }
  1358             }
  1348 
  1359 
  1349             if (value == null) {
  1360             if (value == null) {
  1350                 javaHome = Paths.get(System.getProperty("java.home"));
  1361                 systemJavaHome = Locations.javaHome;
  1351             } else if (value.equals("none")) {
  1362             } else if (value.equals("none")) {
  1352                 javaHome = null;
  1363                 systemJavaHome = null;
  1353             } else {
  1364             } else {
  1354                 update(Paths.get(value));
  1365                 update(getPath(value));
  1355             }
  1366             }
  1356 
  1367 
  1357             modules = null;
  1368             modules = null;
  1358             return true;
  1369             return true;
  1359         }
  1370         }
  1360 
  1371 
  1361         @Override
  1372         @Override
  1362         Collection<Path> getPaths() {
  1373         Collection<Path> getPaths() {
  1363             return (javaHome == null) ? null : Collections.singleton(javaHome);
  1374             return (systemJavaHome == null) ? null : Collections.singleton(systemJavaHome);
  1364         }
  1375         }
  1365 
  1376 
  1366         @Override
  1377         @Override
  1367         void setPaths(Iterable<? extends Path> files) throws IOException {
  1378         void setPaths(Iterable<? extends Path> files) throws IOException {
  1368             if (files == null) {
  1379             if (files == null) {
  1369                 javaHome = null;
  1380                 systemJavaHome = null;
  1370             } else {
  1381             } else {
  1371                 Iterator<? extends Path> pathIter = files.iterator();
  1382                 Iterator<? extends Path> pathIter = files.iterator();
  1372                 if (!pathIter.hasNext()) {
  1383                 if (!pathIter.hasNext()) {
  1373                     throw new IllegalArgumentException("empty path for directory"); // TODO: FIXME
  1384                     throw new IllegalArgumentException("empty path for directory"); // TODO: FIXME
  1374                 }
  1385                 }
  1384                 update(dir);
  1395                 update(dir);
  1385             }
  1396             }
  1386         }
  1397         }
  1387 
  1398 
  1388         private void update(Path p) {
  1399         private void update(Path p) {
  1389             if (!isCurrentPlatform(p) && !Files.exists(p.resolve("jrt-fs.jar")) && !Files.exists(javaHome.resolve("modules")))
  1400             if (!isCurrentPlatform(p) && !Files.exists(p.resolve("jrt-fs.jar")) && !Files.exists(systemJavaHome.resolve("modules")))
  1390                 throw new IllegalArgumentException(p.toString());
  1401                 throw new IllegalArgumentException(p.toString());
  1391             javaHome = p;
  1402             systemJavaHome = p;
  1392             modules = null;
  1403             modules = null;
  1393         }
  1404         }
  1394 
  1405 
  1395         private boolean isCurrentPlatform(Path p) {
  1406         private boolean isCurrentPlatform(Path p) {
  1396             Path jh = Paths.get(System.getProperty("java.home"));
       
  1397             try {
  1407             try {
  1398                 return Files.isSameFile(p, jh);
  1408                 return Files.isSameFile(p, Locations.javaHome);
  1399             } catch (IOException ex) {
  1409             } catch (IOException ex) {
  1400                 throw new IllegalArgumentException(p.toString(), ex);
  1410                 throw new IllegalArgumentException(p.toString(), ex);
  1401             }
  1411             }
  1402         }
  1412         }
  1403 
  1413 
  1419         private void initSystemModules() throws IOException {
  1429         private void initSystemModules() throws IOException {
  1420             if (systemModules != null) {
  1430             if (systemModules != null) {
  1421                 return;
  1431                 return;
  1422             }
  1432             }
  1423 
  1433 
  1424             if (javaHome == null) {
  1434             if (systemJavaHome == null) {
  1425                 systemModules = Collections.emptyMap();
  1435                 systemModules = Collections.emptyMap();
  1426                 return;
  1436                 return;
  1427             }
  1437             }
  1428 
  1438 
  1429             if (modules == null) {
  1439             if (modules == null) {
  1430                 try {
  1440                 try {
  1431                     URI jrtURI = URI.create("jrt:/");
  1441                     URI jrtURI = URI.create("jrt:/");
  1432                     FileSystem jrtfs;
  1442                     FileSystem jrtfs;
  1433 
  1443 
  1434                     if (isCurrentPlatform(javaHome)) {
  1444                     if (isCurrentPlatform(systemJavaHome)) {
  1435                         jrtfs = FileSystems.getFileSystem(jrtURI);
  1445                         jrtfs = FileSystems.getFileSystem(jrtURI);
  1436                     } else {
  1446                     } else {
  1437                         try {
  1447                         try {
  1438                             Map<String, String> attrMap =
  1448                             Map<String, String> attrMap =
  1439                                     Collections.singletonMap("java.home", javaHome.toString());
  1449                                     Collections.singletonMap("java.home", systemJavaHome.toString());
  1440                             jrtfs = FileSystems.newFileSystem(jrtURI, attrMap);
  1450                             jrtfs = FileSystems.newFileSystem(jrtURI, attrMap);
  1441                         } catch (ProviderNotFoundException ex) {
  1451                         } catch (ProviderNotFoundException ex) {
  1442                             URL javaHomeURL = javaHome.resolve("jrt-fs.jar").toUri().toURL();
  1452                             URL javaHomeURL = systemJavaHome.resolve("jrt-fs.jar").toUri().toURL();
  1443                             ClassLoader currentLoader = Locations.class.getClassLoader();
  1453                             ClassLoader currentLoader = Locations.class.getClassLoader();
  1444                             URLClassLoader fsLoader =
  1454                             URLClassLoader fsLoader =
  1445                                     new URLClassLoader(new URL[] {javaHomeURL}, currentLoader);
  1455                                     new URLClassLoader(new URL[] {javaHomeURL}, currentLoader);
  1446 
  1456 
  1447                             jrtfs = FileSystems.newFileSystem(jrtURI, Collections.emptyMap(), fsLoader);
  1457                             jrtfs = FileSystems.newFileSystem(jrtURI, Collections.emptyMap(), fsLoader);
  1452                         closeables.add(jrtfs);
  1462                         closeables.add(jrtfs);
  1453                     }
  1463                     }
  1454 
  1464 
  1455                     modules = jrtfs.getPath("/modules");
  1465                     modules = jrtfs.getPath("/modules");
  1456                 } catch (FileSystemNotFoundException | ProviderNotFoundException e) {
  1466                 } catch (FileSystemNotFoundException | ProviderNotFoundException e) {
  1457                     modules = javaHome.resolve("modules");
  1467                     modules = systemJavaHome.resolve("modules");
  1458                     if (!Files.exists(modules))
  1468                     if (!Files.exists(modules))
  1459                         throw new IOException("can't find system classes", e);
  1469                         throw new IOException("can't find system classes", e);
  1460                 }
  1470                 }
  1461             }
  1471             }
  1462 
  1472