113 public class Locations {
114
115 /**
116 * The log to use for warning output
117 */
118 private Log log;
119
120 /**
121 * Access to (possibly cached) file info
122 */
123 private FSInfo fsInfo;
124
125 private ModuleNameReader moduleNameReader;
126
127 private PathFactory pathFactory = Paths::get;
128
129 static final Path javaHome = FileSystems.getDefault().getPath(System.getProperty("java.home"));
130 static final Path thisSystemModules = javaHome.resolve("lib").resolve("modules");
131
132 Map<Path, FileSystem> fileSystems = new LinkedHashMap<>();
133 List<Closeable> closeables = new ArrayList<>();
134 private String releaseVersion = null;
135
136 Locations() {
137 initHandlers();
138 }
139
140 Path getPath(String first, String... more) {
141 try {
142 return pathFactory.getPath(first, more);
143 } catch (InvalidPathException ipe) {
144 throw new IllegalArgumentException(ipe);
145 }
146 }
147
148 public void close() throws IOException {
149 ListBuffer<IOException> list = new ListBuffer<>();
150 closeables.forEach(closeable -> {
151 try {
152 closeable.close();
153 } catch (IOException ex) {
154 list.add(ex);
155 }
156 });
157 if (list.nonEmpty()) {
158 IOException ex = new IOException();
159 for (IOException e: list)
160 ex.addSuppressed(e);
161 throw ex;
162 }
163 }
164
165 void update(Log log, FSInfo fsInfo) {
166 this.log = log;
167 this.fsInfo = fsInfo;
168 }
169
170 void setPathFactory(PathFactory f) {
171 pathFactory = f;
172 }
173
174 boolean isDefaultBootClassPath() {
175 BootClassPathLocationHandler h
176 = (BootClassPathLocationHandler) getHandler(PLATFORM_CLASS_PATH);
209 if (s.isEmpty()) {
210 if (emptyPathDefault != null) {
211 entries.add(emptyPathDefault);
212 }
213 } else {
214 try {
215 entries.add(getPath(s));
216 } catch (IllegalArgumentException e) {
217 log.warning(LintWarnings.InvalidPath(s));
218 }
219 }
220 }
221 return entries;
222 }
223
224 public void setMultiReleaseValue(String multiReleaseValue) {
225 // Null is implicitly allowed and unsets the value.
226 this.releaseVersion = multiReleaseValue;
227 }
228
229 private boolean contains(Collection<Path> searchPath, Path file) throws IOException {
230
231 if (searchPath == null) {
232 return false;
233 }
234
235 Path enclosingJar = null;
236 if (file.getFileSystem().provider() == fsInfo.getJarFSProvider()) {
237 URI uri = file.toUri();
238 if (uri.getScheme().equals("jar")) {
239 String ssp = uri.getSchemeSpecificPart();
240 int sep = ssp.lastIndexOf("!");
241 if (ssp.startsWith("file:") && sep > 0) {
242 enclosingJar = Paths.get(URI.create(ssp.substring(0, sep)));
243 }
244 }
245 }
246
247 Path nf = normalize(file);
248 for (Path p : searchPath) {
1442 if (p.getFileName().toString().endsWith(".jmod")) {
1443 try {
1444 // check if the JMOD file is valid
1445 JmodFile.checkMagic(p);
1446
1447 // No JMOD file system. Use JarFileSystem to
1448 // workaround for now
1449 FileSystem fs = fileSystems.get(p);
1450 if (fs == null) {
1451 FileSystemProvider jarFSProvider = fsInfo.getJarFSProvider();
1452 if (jarFSProvider == null) {
1453 log.error(Errors.LocnCantReadFile(p));
1454 return null;
1455 }
1456 fs = jarFSProvider.newFileSystem(p, fsInfo.readOnlyJarFSEnv(null));
1457 try {
1458 Path moduleInfoClass = fs.getPath("classes/module-info.class");
1459 String moduleName = readModuleName(moduleInfoClass);
1460 Path modulePath = fs.getPath("classes");
1461 fileSystems.put(p, fs);
1462 closeables.add(fs);
1463 fs = null; // prevent fs being closed in the finally clause
1464 return new Pair<>(moduleName, modulePath);
1465 } finally {
1466 if (fs != null)
1467 fs.close();
1468 }
1469 }
1470 } catch (ModuleNameReader.BadClassFile e) {
1471 log.error(Errors.LocnBadModuleInfo(p));
1472 } catch (IOException e) {
1473 log.error(Errors.LocnCantReadFile(p));
1474 return null;
1475 }
1476 }
1477
1478 if (false) { // temp disable, when enabled, massage examples.not-yet.txt suitably.
1479 log.warning(LintWarnings.LocnUnknownFileOnModulePath(p));
1480 }
1481 return null;
1482 }
1933 boolean contains(Path file) throws IOException {
1934 initSystemModules();
1935 return moduleTable.contains(file);
1936 }
1937
1938 private void initSystemModules() throws IOException {
1939 if (moduleTable != null)
1940 return;
1941
1942 if (systemJavaHome == null) {
1943 moduleTable = new ModuleTable();
1944 return;
1945 }
1946
1947 if (modules == null) {
1948 try {
1949 URI jrtURI = URI.create("jrt:/");
1950 FileSystem jrtfs;
1951
1952 if (isCurrentPlatform(systemJavaHome)) {
1953 jrtfs = FileSystems.getFileSystem(jrtURI);
1954 } else {
1955 try {
1956 Map<String, String> attrMap =
1957 Collections.singletonMap("java.home", systemJavaHome.toString());
1958 jrtfs = FileSystems.newFileSystem(jrtURI, attrMap);
1959 } catch (ProviderNotFoundException ex) {
1960 URL jfsJar = resolveInJavaHomeLib(systemJavaHome, "jrt-fs.jar").toUri().toURL();
1961 ClassLoader currentLoader = Locations.class.getClassLoader();
1962 URLClassLoader fsLoader =
1963 new URLClassLoader(new URL[] {jfsJar}, currentLoader);
1964
1965 jrtfs = FileSystems.newFileSystem(jrtURI, Collections.emptyMap(), fsLoader);
1966
1967 closeables.add(fsLoader);
1968 }
1969
1970 closeables.add(jrtfs);
1971 }
1972
1973 modules = jrtfs.getPath("/modules");
1974 } catch (FileSystemNotFoundException | ProviderNotFoundException e) {
1975 modules = resolveInJavaHomeLib(systemJavaHome, "modules");
1976 if (!Files.exists(modules))
1977 throw new IOException("can't find system classes", e);
1978 }
1979 }
1980
1981 moduleTable = new ModuleTable();
1982 try (DirectoryStream<Path> stream = Files.newDirectoryStream(modules, Files::isDirectory)) {
1983 for (Path entry : stream) {
1984 String moduleName = entry.getFileName().toString();
1985 String name = location.getName() + "[" + moduleName + "]";
1986 ModuleLocationHandler h = new ModuleLocationHandler(this,
1987 name, moduleName, Collections.singletonList(entry), false);
1988 moduleTable.add(h);
1989 }
1990 }
|
113 public class Locations {
114
115 /**
116 * The log to use for warning output
117 */
118 private Log log;
119
120 /**
121 * Access to (possibly cached) file info
122 */
123 private FSInfo fsInfo;
124
125 private ModuleNameReader moduleNameReader;
126
127 private PathFactory pathFactory = Paths::get;
128
129 static final Path javaHome = FileSystems.getDefault().getPath(System.getProperty("java.home"));
130 static final Path thisSystemModules = javaHome.resolve("lib").resolve("modules");
131
132 Map<Path, FileSystem> fileSystems = new LinkedHashMap<>();
133 // List of resources to be closed (self-sychronized).
134 private final List<Closeable> closeables = new ArrayList<>();
135 private String releaseVersion = null;
136 private boolean previewMode = false;
137
138 Locations() {
139 initHandlers();
140 }
141
142 Path getPath(String first, String... more) {
143 try {
144 return pathFactory.getPath(first, more);
145 } catch (InvalidPathException ipe) {
146 throw new IllegalArgumentException(ipe);
147 }
148 }
149
150 private void addCloseable(Closeable c) {
151 synchronized (closeables) {
152 closeables.add(c);
153 }
154 }
155
156 public void close() throws IOException {
157 ListBuffer<IOException> list = new ListBuffer<>();
158 Closeable[] arr;
159 synchronized (closeables) {
160 arr = closeables.toArray(Closeable[]::new);
161 closeables.clear();
162 }
163 for (Closeable closeable : arr) {
164 try {
165 closeable.close();
166 } catch (IOException ex) {
167 list.add(ex);
168 }
169 }
170 if (list.nonEmpty()) {
171 IOException ex = new IOException();
172 for (IOException e: list)
173 ex.addSuppressed(e);
174 throw ex;
175 }
176 }
177
178 void update(Log log, FSInfo fsInfo) {
179 this.log = log;
180 this.fsInfo = fsInfo;
181 }
182
183 void setPathFactory(PathFactory f) {
184 pathFactory = f;
185 }
186
187 boolean isDefaultBootClassPath() {
188 BootClassPathLocationHandler h
189 = (BootClassPathLocationHandler) getHandler(PLATFORM_CLASS_PATH);
222 if (s.isEmpty()) {
223 if (emptyPathDefault != null) {
224 entries.add(emptyPathDefault);
225 }
226 } else {
227 try {
228 entries.add(getPath(s));
229 } catch (IllegalArgumentException e) {
230 log.warning(LintWarnings.InvalidPath(s));
231 }
232 }
233 }
234 return entries;
235 }
236
237 public void setMultiReleaseValue(String multiReleaseValue) {
238 // Null is implicitly allowed and unsets the value.
239 this.releaseVersion = multiReleaseValue;
240 }
241
242 public void setPreviewMode(boolean previewMode) {
243 // Null is implicitly allowed and unsets the value.
244 this.previewMode = previewMode;
245 }
246
247 private boolean contains(Collection<Path> searchPath, Path file) throws IOException {
248
249 if (searchPath == null) {
250 return false;
251 }
252
253 Path enclosingJar = null;
254 if (file.getFileSystem().provider() == fsInfo.getJarFSProvider()) {
255 URI uri = file.toUri();
256 if (uri.getScheme().equals("jar")) {
257 String ssp = uri.getSchemeSpecificPart();
258 int sep = ssp.lastIndexOf("!");
259 if (ssp.startsWith("file:") && sep > 0) {
260 enclosingJar = Paths.get(URI.create(ssp.substring(0, sep)));
261 }
262 }
263 }
264
265 Path nf = normalize(file);
266 for (Path p : searchPath) {
1460 if (p.getFileName().toString().endsWith(".jmod")) {
1461 try {
1462 // check if the JMOD file is valid
1463 JmodFile.checkMagic(p);
1464
1465 // No JMOD file system. Use JarFileSystem to
1466 // workaround for now
1467 FileSystem fs = fileSystems.get(p);
1468 if (fs == null) {
1469 FileSystemProvider jarFSProvider = fsInfo.getJarFSProvider();
1470 if (jarFSProvider == null) {
1471 log.error(Errors.LocnCantReadFile(p));
1472 return null;
1473 }
1474 fs = jarFSProvider.newFileSystem(p, fsInfo.readOnlyJarFSEnv(null));
1475 try {
1476 Path moduleInfoClass = fs.getPath("classes/module-info.class");
1477 String moduleName = readModuleName(moduleInfoClass);
1478 Path modulePath = fs.getPath("classes");
1479 fileSystems.put(p, fs);
1480 addCloseable(fs);
1481 fs = null; // prevent fs being closed in the finally clause
1482 return new Pair<>(moduleName, modulePath);
1483 } finally {
1484 if (fs != null)
1485 fs.close();
1486 }
1487 }
1488 } catch (ModuleNameReader.BadClassFile e) {
1489 log.error(Errors.LocnBadModuleInfo(p));
1490 } catch (IOException e) {
1491 log.error(Errors.LocnCantReadFile(p));
1492 return null;
1493 }
1494 }
1495
1496 if (false) { // temp disable, when enabled, massage examples.not-yet.txt suitably.
1497 log.warning(LintWarnings.LocnUnknownFileOnModulePath(p));
1498 }
1499 return null;
1500 }
1951 boolean contains(Path file) throws IOException {
1952 initSystemModules();
1953 return moduleTable.contains(file);
1954 }
1955
1956 private void initSystemModules() throws IOException {
1957 if (moduleTable != null)
1958 return;
1959
1960 if (systemJavaHome == null) {
1961 moduleTable = new ModuleTable();
1962 return;
1963 }
1964
1965 if (modules == null) {
1966 try {
1967 URI jrtURI = URI.create("jrt:/");
1968 FileSystem jrtfs;
1969
1970 if (isCurrentPlatform(systemJavaHome)) {
1971 JRTIndex jrtIndex = JRTIndex.instance(previewMode);
1972 addCloseable(jrtIndex);
1973 jrtfs = jrtIndex.getFileSystem();
1974 } else {
1975 try {
1976 Map<String, String> attrMap =
1977 Map.of("java.home", systemJavaHome.toString(),
1978 "previewMode", String.valueOf(previewMode));
1979 jrtfs = FileSystems.newFileSystem(jrtURI, attrMap);
1980 } catch (ProviderNotFoundException ex) {
1981 URL jfsJar = resolveInJavaHomeLib(systemJavaHome, "jrt-fs.jar").toUri().toURL();
1982 ClassLoader currentLoader = Locations.class.getClassLoader();
1983 URLClassLoader fsLoader =
1984 new URLClassLoader(new URL[] {jfsJar}, currentLoader);
1985
1986 jrtfs = FileSystems.newFileSystem(jrtURI, Collections.emptyMap(), fsLoader);
1987
1988 addCloseable(fsLoader);
1989 }
1990
1991 addCloseable(jrtfs);
1992 }
1993
1994 modules = jrtfs.getPath("/modules");
1995 } catch (FileSystemNotFoundException | ProviderNotFoundException e) {
1996 modules = resolveInJavaHomeLib(systemJavaHome, "modules");
1997 if (!Files.exists(modules))
1998 throw new IOException("can't find system classes", e);
1999 }
2000 }
2001
2002 moduleTable = new ModuleTable();
2003 try (DirectoryStream<Path> stream = Files.newDirectoryStream(modules, Files::isDirectory)) {
2004 for (Path entry : stream) {
2005 String moduleName = entry.getFileName().toString();
2006 String name = location.getName() + "[" + moduleName + "]";
2007 ModuleLocationHandler h = new ModuleLocationHandler(this,
2008 name, moduleName, Collections.singletonList(entry), false);
2009 moduleTable.add(h);
2010 }
2011 }
|