1 /*
2 * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25 package com.sun.tools.javac.file;
26
27 import java.io.IOException;
28 import java.io.UncheckedIOException;
29 import java.lang.ref.SoftReference;
30 import java.net.URI;
31 import java.nio.file.DirectoryStream;
32 import java.nio.file.FileSystem;
33 import java.nio.file.FileSystems;
34 import java.nio.file.FileSystemNotFoundException;
35 import java.nio.file.Files;
36 import java.nio.file.Path;
37 import java.nio.file.ProviderNotFoundException;
38 import java.nio.file.spi.FileSystemProvider;
39 import java.util.Collections;
40 import java.util.HashMap;
41 import java.util.LinkedHashMap;
42 import java.util.LinkedHashSet;
43 import java.util.Map;
44 import java.util.MissingResourceException;
45 import java.util.ResourceBundle;
46 import java.util.Set;
47
48 import javax.tools.FileObject;
49
50 import com.sun.tools.javac.file.RelativePath.RelativeDirectory;
51 import com.sun.tools.javac.util.Context;
52
53 /**
54 * A package-oriented index into the jrt: filesystem.
55 */
56 public class JRTIndex {
57 /** Get a shared instance of the cache. */
58 private static JRTIndex sharedInstance;
78 throw new UncheckedIOException(e);
79 }
80 }
81
82 public static boolean isAvailable() {
83 try {
84 FileSystems.getFileSystem(URI.create("jrt:/"));
85 return true;
86 } catch (ProviderNotFoundException | FileSystemNotFoundException e) {
87 return false;
88 }
89 }
90
91
92 /**
93 * The jrt: file system.
94 */
95 private final FileSystem jrtfs;
96
97 /**
98 * The set of module directories within the jrt: file system.
99 */
100 private final Set<Path> jrtModules;
101
102 /**
103 * A lazily evaluated set of entries about the contents of the jrt: file system.
104 */
105 private final Map<RelativeDirectory, SoftReference<Entry>> entries;
106
107 /**
108 * An entry provides cached info about a specific package directory within jrt:.
109 */
110 class Entry {
111 /**
112 * The regular files for this package.
113 * For now, assume just one instance of each file across all modules.
114 */
115 final Map<String, Path> files;
116
117 /**
118 * The set of subdirectories in jrt: for this package.
119 */
120 final Set<RelativeDirectory> subdirs;
121
122 /**
166 if (needSep) sb.append(",");
167 sb.append("proprietary");
168 needSep = true;
169 }
170 if (minProfile != null) {
171 if (needSep) sb.append(",");
172 sb.append(minProfile);
173 }
174 sb.append("]");
175 return sb.toString();
176 }
177
178 static final CtSym EMPTY = new CtSym(false, false, null);
179 }
180
181 /**
182 * Create and initialize the index.
183 */
184 private JRTIndex() throws IOException {
185 jrtfs = FileSystems.getFileSystem(URI.create("jrt:/"));
186 jrtModules = new LinkedHashSet<>();
187 Path root = jrtfs.getPath("/");
188 try (DirectoryStream<Path> stream = Files.newDirectoryStream(root)) {
189 for (Path entry: stream) {
190 if (Files.isDirectory(entry))
191 jrtModules.add(entry);
192 }
193 }
194 entries = new HashMap<>();
195 }
196
197 public CtSym getCtSym(CharSequence packageName) throws IOException {
198 return getEntry(RelativeDirectory.forPackage(packageName)).ctSym;
199 }
200
201 synchronized Entry getEntry(RelativeDirectory rd) throws IOException {
202 SoftReference<Entry> ref = entries.get(rd);
203 Entry e = (ref == null) ? null : ref.get();
204 if (e == null) {
205 Map<String, Path> files = new LinkedHashMap<>();
206 Set<RelativeDirectory> subdirs = new LinkedHashSet<>();
207 for (Path module: jrtModules) {
208 Path p = rd.getFile(module);
209 if (!Files.exists(p))
210 continue;
211 try (DirectoryStream<Path> stream = Files.newDirectoryStream(p)) {
212 for (Path entry: stream) {
213 String name = entry.getFileName().toString();
214 if (Files.isRegularFile(entry)) {
215 // TODO: consider issue of files with same name in different modules
216 files.put(name, entry);
217 } else if (Files.isDirectory(entry)) {
218 subdirs.add(new RelativeDirectory(rd, name));
219 }
220 }
221 }
222 }
223 e = new Entry(Collections.unmodifiableMap(files),
224 Collections.unmodifiableSet(subdirs),
225 getCtInfo(rd));
226 entries.put(rd, new SoftReference<>(e));
227 }
228 return e;
229 }
230
231 public boolean isInJRT(FileObject fo) {
232 if (fo instanceof PathFileObject) {
233 Path path = ((PathFileObject) fo).getPath();
234 return (path.getFileSystem() == jrtfs);
235 } else {
236 return false;
237 }
238 }
239
240 private CtSym getCtInfo(RelativeDirectory dir) {
241 if (dir.path.isEmpty())
242 return CtSym.EMPTY;
|
1 /*
2 * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25 package com.sun.tools.javac.file;
26
27 import java.io.IOException;
28 import java.io.UncheckedIOException;
29 import java.lang.ref.SoftReference;
30 import java.net.URI;
31 import java.nio.file.DirectoryStream;
32 import java.nio.file.FileSystem;
33 import java.nio.file.FileSystems;
34 import java.nio.file.FileSystemNotFoundException;
35 import java.nio.file.Files;
36 import java.nio.file.Path;
37 import java.nio.file.ProviderNotFoundException;
38 import java.util.Collections;
39 import java.util.HashMap;
40 import java.util.LinkedHashMap;
41 import java.util.LinkedHashSet;
42 import java.util.Map;
43 import java.util.MissingResourceException;
44 import java.util.ResourceBundle;
45 import java.util.Set;
46
47 import javax.tools.FileObject;
48
49 import com.sun.tools.javac.file.RelativePath.RelativeDirectory;
50 import com.sun.tools.javac.util.Context;
51
52 /**
53 * A package-oriented index into the jrt: filesystem.
54 */
55 public class JRTIndex {
56 /** Get a shared instance of the cache. */
57 private static JRTIndex sharedInstance;
77 throw new UncheckedIOException(e);
78 }
79 }
80
81 public static boolean isAvailable() {
82 try {
83 FileSystems.getFileSystem(URI.create("jrt:/"));
84 return true;
85 } catch (ProviderNotFoundException | FileSystemNotFoundException e) {
86 return false;
87 }
88 }
89
90
91 /**
92 * The jrt: file system.
93 */
94 private final FileSystem jrtfs;
95
96 /**
97 * A lazily evaluated set of entries about the contents of the jrt: file system.
98 */
99 private final Map<RelativeDirectory, SoftReference<Entry>> entries;
100
101 /**
102 * An entry provides cached info about a specific package directory within jrt:.
103 */
104 class Entry {
105 /**
106 * The regular files for this package.
107 * For now, assume just one instance of each file across all modules.
108 */
109 final Map<String, Path> files;
110
111 /**
112 * The set of subdirectories in jrt: for this package.
113 */
114 final Set<RelativeDirectory> subdirs;
115
116 /**
160 if (needSep) sb.append(",");
161 sb.append("proprietary");
162 needSep = true;
163 }
164 if (minProfile != null) {
165 if (needSep) sb.append(",");
166 sb.append(minProfile);
167 }
168 sb.append("]");
169 return sb.toString();
170 }
171
172 static final CtSym EMPTY = new CtSym(false, false, null);
173 }
174
175 /**
176 * Create and initialize the index.
177 */
178 private JRTIndex() throws IOException {
179 jrtfs = FileSystems.getFileSystem(URI.create("jrt:/"));
180 entries = new HashMap<>();
181 }
182
183 public CtSym getCtSym(CharSequence packageName) throws IOException {
184 return getEntry(RelativeDirectory.forPackage(packageName)).ctSym;
185 }
186
187 synchronized Entry getEntry(RelativeDirectory rd) throws IOException {
188 SoftReference<Entry> ref = entries.get(rd);
189 Entry e = (ref == null) ? null : ref.get();
190 if (e == null) {
191 Map<String, Path> files = new LinkedHashMap<>();
192 Set<RelativeDirectory> subdirs = new LinkedHashSet<>();
193 Path dir;
194 if (rd.path.isEmpty()) {
195 dir = jrtfs.getPath("/modules");
196 } else {
197 Path pkgs = jrtfs.getPath("/packages");
198 dir = pkgs.resolve(rd.getPath().replaceAll("/$", "").replace("/", "."));
199 }
200 if (Files.exists(dir)) {
201 try (DirectoryStream<Path> modules = Files.newDirectoryStream(dir)) {
202 for (Path module: modules) {
203 Path p = rd.getFile(module);
204 if (!Files.exists(p))
205 continue;
206 try (DirectoryStream<Path> stream = Files.newDirectoryStream(p)) {
207 for (Path entry: stream) {
208 String name = entry.getFileName().toString();
209 if (Files.isRegularFile(entry)) {
210 // TODO: consider issue of files with same name in different modules
211 files.put(name, entry);
212 } else if (Files.isDirectory(entry)) {
213 subdirs.add(new RelativeDirectory(rd, name));
214 }
215 }
216 }
217 }
218 }
219 }
220 e = new Entry(Collections.unmodifiableMap(files),
221 Collections.unmodifiableSet(subdirs),
222 getCtInfo(rd));
223 entries.put(rd, new SoftReference<>(e));
224 }
225 return e;
226 }
227
228 public boolean isInJRT(FileObject fo) {
229 if (fo instanceof PathFileObject) {
230 Path path = ((PathFileObject) fo).getPath();
231 return (path.getFileSystem() == jrtfs);
232 } else {
233 return false;
234 }
235 }
236
237 private CtSym getCtInfo(RelativeDirectory dir) {
238 if (dir.path.isEmpty())
239 return CtSym.EMPTY;
|