42 import java.util.Map;
43 import java.util.Objects;
44 import java.util.Set;
45 import java.util.function.Consumer;
46
47 /**
48 * @implNote This class needs to maintain JDK 8 source compatibility.
49 *
50 * It is used internally in the JDK to implement jimage/jrtfs access,
51 * but also compiled and delivered as part of the jrtfs.jar to support access
52 * to the jimage file provided by the shipped JDK by tools running on JDK 8.
53 */
54 public final class ImageReader implements AutoCloseable {
55 private SharedImageReader reader;
56
57 private ImageReader(SharedImageReader reader) {
58 this.reader = reader;
59 }
60
61 public static ImageReader open(Path imagePath, ByteOrder byteOrder) throws IOException {
62 return SharedImageReader.open(imagePath, byteOrder);
63 }
64
65 public static ImageReader open(Path imagePath) throws IOException {
66 return open(imagePath, ByteOrder.nativeOrder());
67 }
68
69 @Override
70 public void close() throws IOException {
71 if (reader == null) {
72 throw new IOException("image file already closed");
73 }
74
75 reader.close(this);
76 reader = null;
77 }
78
79 // directory management interface
80 public Directory getRootDirectory() throws IOException {
81 if (reader == null) {
201 // attributes of the .jimage file. jimage file does not contain
202 // attributes for the individual resources (yet). We use attributes
203 // of the jimage file itself (creation, modification, access times).
204 // Iniitalized lazily, see {@link #imageFileAttributes()}.
205 BasicFileAttributes imageFileAttributes;
206
207 // directory management implementation
208 final HashMap<String, Node> nodes;
209 volatile Directory rootDir;
210
211 Directory packagesDir;
212 Directory modulesDir;
213
214 private SharedImageReader(Path imagePath, ByteOrder byteOrder) throws IOException {
215 super(imagePath, byteOrder);
216 this.openers = new HashSet<>();
217 this.nodes = new HashMap<>();
218 }
219
220 public static ImageReader open(Path imagePath, ByteOrder byteOrder) throws IOException {
221 synchronized (OPEN_FILES) {
222 SharedImageReader reader = OPEN_FILES.get(imagePath);
223
224 if (reader == null) {
225 // Will fail with an IOException if wrong byteOrder.
226 reader = new SharedImageReader(imagePath, byteOrder);
227 OPEN_FILES.put(imagePath, reader);
228 } else if (reader.getByteOrder() != byteOrder) {
229 throw new IOException("\"" + reader.getName() + "\" is not an image file");
230 }
231
232 ImageReader image = new ImageReader(reader);
233 reader.openers.add(image);
234
235 return image;
236 }
237 }
238
239 public void close(ImageReader image) throws IOException {
240 synchronized (OPEN_FILES) {
241 if (!openers.remove(image)) {
242 throw new IOException("image file already closed");
243 }
244
245 if (openers.isEmpty()) {
246 close();
247 nodes.clear();
248 rootDir = null;
249
250 if (!OPEN_FILES.remove(this.getImagePath(), this)) {
251 throw new IOException("image file not found in open list");
252 }
253 }
254 }
255 }
256
257 void addOpener(ImageReader reader) {
258 synchronized (OPEN_FILES) {
259 openers.add(reader);
|
42 import java.util.Map;
43 import java.util.Objects;
44 import java.util.Set;
45 import java.util.function.Consumer;
46
47 /**
48 * @implNote This class needs to maintain JDK 8 source compatibility.
49 *
50 * It is used internally in the JDK to implement jimage/jrtfs access,
51 * but also compiled and delivered as part of the jrtfs.jar to support access
52 * to the jimage file provided by the shipped JDK by tools running on JDK 8.
53 */
54 public final class ImageReader implements AutoCloseable {
55 private SharedImageReader reader;
56
57 private ImageReader(SharedImageReader reader) {
58 this.reader = reader;
59 }
60
61 public static ImageReader open(Path imagePath, ByteOrder byteOrder) throws IOException {
62 Objects.requireNonNull(imagePath);
63 Objects.requireNonNull(byteOrder);
64
65 return SharedImageReader.open(imagePath, byteOrder);
66 }
67
68 public static ImageReader open(Path imagePath) throws IOException {
69 return open(imagePath, ByteOrder.nativeOrder());
70 }
71
72 @Override
73 public void close() throws IOException {
74 if (reader == null) {
75 throw new IOException("image file already closed");
76 }
77
78 reader.close(this);
79 reader = null;
80 }
81
82 // directory management interface
83 public Directory getRootDirectory() throws IOException {
84 if (reader == null) {
204 // attributes of the .jimage file. jimage file does not contain
205 // attributes for the individual resources (yet). We use attributes
206 // of the jimage file itself (creation, modification, access times).
207 // Iniitalized lazily, see {@link #imageFileAttributes()}.
208 BasicFileAttributes imageFileAttributes;
209
210 // directory management implementation
211 final HashMap<String, Node> nodes;
212 volatile Directory rootDir;
213
214 Directory packagesDir;
215 Directory modulesDir;
216
217 private SharedImageReader(Path imagePath, ByteOrder byteOrder) throws IOException {
218 super(imagePath, byteOrder);
219 this.openers = new HashSet<>();
220 this.nodes = new HashMap<>();
221 }
222
223 public static ImageReader open(Path imagePath, ByteOrder byteOrder) throws IOException {
224 Objects.requireNonNull(imagePath);
225 Objects.requireNonNull(byteOrder);
226
227 synchronized (OPEN_FILES) {
228 SharedImageReader reader = OPEN_FILES.get(imagePath);
229
230 if (reader == null) {
231 // Will fail with an IOException if wrong byteOrder.
232 reader = new SharedImageReader(imagePath, byteOrder);
233 OPEN_FILES.put(imagePath, reader);
234 } else if (reader.getByteOrder() != byteOrder) {
235 throw new IOException("\"" + reader.getName() + "\" is not an image file");
236 }
237
238 ImageReader image = new ImageReader(reader);
239 reader.openers.add(image);
240
241 return image;
242 }
243 }
244
245 public void close(ImageReader image) throws IOException {
246 Objects.requireNonNull(image);
247
248 synchronized (OPEN_FILES) {
249 if (!openers.remove(image)) {
250 throw new IOException("image file already closed");
251 }
252
253 if (openers.isEmpty()) {
254 close();
255 nodes.clear();
256 rootDir = null;
257
258 if (!OPEN_FILES.remove(this.getImagePath(), this)) {
259 throw new IOException("image file not found in open list");
260 }
261 }
262 }
263 }
264
265 void addOpener(ImageReader reader) {
266 synchronized (OPEN_FILES) {
267 openers.add(reader);
|