1 /*
2 * Copyright (c) 2016, 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
42 /**
43 * Helper class to read JMOD file
44 */
45 public class JmodFile implements AutoCloseable {
46 // jmod magic number and version number
47 private static final int JMOD_MAJOR_VERSION = 0x01;
48 private static final int JMOD_MINOR_VERSION = 0x00;
49 private static final byte[] JMOD_MAGIC_NUMBER = {
50 0x4A, 0x4D, /* JM */
51 JMOD_MAJOR_VERSION, JMOD_MINOR_VERSION, /* version 1.0 */
52 };
53
54 public static void checkMagic(Path file) throws IOException {
55 try (InputStream in = Files.newInputStream(file);
56 BufferedInputStream bis = new BufferedInputStream(in)) {
57 // validate the header
58 byte[] magic = new byte[4];
59 bis.read(magic);
60 if (magic[0] != JMOD_MAGIC_NUMBER[0] ||
61 magic[1] != JMOD_MAGIC_NUMBER[1]) {
62 throw new IOException("Invalid jmod file: " + file.toString());
63 }
64 if (magic[2] > JMOD_MAJOR_VERSION ||
65 (magic[2] == JMOD_MAJOR_VERSION && magic[3] > JMOD_MINOR_VERSION)) {
66 throw new IOException("Unsupported jmod version: " +
67 magic[2] + "." + magic[3] + " in " + file.toString());
68 }
69 }
70 }
71
72 /**
73 * JMOD sections
74 */
75 public static enum Section {
76 CLASSES("classes"),
77 CONFIG("conf"),
78 HEADER_FILES("include"),
79 LEGAL_NOTICES("legal"),
80 MAN_PAGES("man"),
81 NATIVE_LIBS("lib"),
82 NATIVE_CMDS("bin");
114 this.zipEntry = e;
115 this.section = section(name.substring(0, i));
116 this.name = name.substring(i+1);
117 }
118
119 /**
120 * Returns the section of this entry.
121 */
122 public Section section() {
123 return section;
124 }
125
126 /**
127 * Returns the name of this entry.
128 */
129 public String name() {
130 return name;
131 }
132
133 /**
134 * Returns the size of this entry.
135 */
136 public long size() {
137 return zipEntry.getSize();
138 }
139
140 public ZipEntry zipEntry() {
141 return zipEntry;
142 }
143
144 @Override
145 public String toString() {
146 return section.jmodDir() + "/" + name;
147 }
148
149 /*
150 * A map from the jmodDir name to Section
151 */
152 static final Map<String, Section> NAME_TO_SECTION =
153 Arrays.stream(Section.values())
169 /**
170 * Constructs a {@code JmodFile} from a given path.
171 */
172 public JmodFile(Path file) throws IOException {
173 checkMagic(file);
174 this.file = file;
175 this.zipfile = new ZipFile(file.toFile());
176 }
177
178 public static void writeMagicNumber(OutputStream os) throws IOException {
179 os.write(JMOD_MAGIC_NUMBER);
180 }
181
182 /**
183 * Returns the {@code Entry} for a resource in a JMOD file section
184 * or {@code null} if not found.
185 */
186 public Entry getEntry(Section section, String name) {
187 String entry = section.jmodDir() + "/" + name;
188 ZipEntry ze = zipfile.getEntry(entry);
189 return (ze == null || ze.isDirectory()) ? null : new Entry(ze);
190 }
191
192 /**
193 * Opens an {@code InputStream} for reading the named entry of the given
194 * section in this jmod file.
195 *
196 * @throws IOException if the named entry is not found, or I/O error
197 * occurs when reading it
198 */
199 public InputStream getInputStream(Section section, String name)
200 throws IOException
201 {
202 String entry = section.jmodDir() + "/" + name;
203 ZipEntry e = zipfile.getEntry(entry);
204 if (e == null || e.isDirectory()) {
205 throw new IOException(name + " not found: " + file);
206 }
207 return zipfile.getInputStream(e);
208 }
209
210 /**
211 * Opens an {@code InputStream} for reading an entry in the JMOD file.
212 *
213 * @throws IOException if an I/O error occurs
214 */
215 public InputStream getInputStream(Entry entry) throws IOException {
216 return zipfile.getInputStream(entry.zipEntry());
217 }
218
219 /**
220 * Returns a stream of non-directory entries in this jmod file.
221 */
222 public Stream<Entry> stream() {
223 return zipfile.stream()
224 .filter(e -> !e.isDirectory())
225 .map(Entry::new);
226 }
227
228 @Override
229 public void close() throws IOException {
230 if (zipfile != null) {
231 zipfile.close();
232 }
233 }
234 }
|
1 /*
2 * Copyright (c) 2016, 2017, 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
42 /**
43 * Helper class to read JMOD file
44 */
45 public class JmodFile implements AutoCloseable {
46 // jmod magic number and version number
47 private static final int JMOD_MAJOR_VERSION = 0x01;
48 private static final int JMOD_MINOR_VERSION = 0x00;
49 private static final byte[] JMOD_MAGIC_NUMBER = {
50 0x4A, 0x4D, /* JM */
51 JMOD_MAJOR_VERSION, JMOD_MINOR_VERSION, /* version 1.0 */
52 };
53
54 public static void checkMagic(Path file) throws IOException {
55 try (InputStream in = Files.newInputStream(file);
56 BufferedInputStream bis = new BufferedInputStream(in)) {
57 // validate the header
58 byte[] magic = new byte[4];
59 bis.read(magic);
60 if (magic[0] != JMOD_MAGIC_NUMBER[0] ||
61 magic[1] != JMOD_MAGIC_NUMBER[1]) {
62 throw new IOException("Invalid JMOD file: " + file.toString());
63 }
64 if (magic[2] > JMOD_MAJOR_VERSION ||
65 (magic[2] == JMOD_MAJOR_VERSION && magic[3] > JMOD_MINOR_VERSION)) {
66 throw new IOException("Unsupported jmod version: " +
67 magic[2] + "." + magic[3] + " in " + file.toString());
68 }
69 }
70 }
71
72 /**
73 * JMOD sections
74 */
75 public static enum Section {
76 CLASSES("classes"),
77 CONFIG("conf"),
78 HEADER_FILES("include"),
79 LEGAL_NOTICES("legal"),
80 MAN_PAGES("man"),
81 NATIVE_LIBS("lib"),
82 NATIVE_CMDS("bin");
114 this.zipEntry = e;
115 this.section = section(name.substring(0, i));
116 this.name = name.substring(i+1);
117 }
118
119 /**
120 * Returns the section of this entry.
121 */
122 public Section section() {
123 return section;
124 }
125
126 /**
127 * Returns the name of this entry.
128 */
129 public String name() {
130 return name;
131 }
132
133 /**
134 * Returns true if the entry is a directory in the JMOD file.
135 */
136 public boolean isDirectory() {
137 return zipEntry.isDirectory();
138 }
139
140 /**
141 * Returns the size of this entry.
142 */
143 public long size() {
144 return zipEntry.getSize();
145 }
146
147 public ZipEntry zipEntry() {
148 return zipEntry;
149 }
150
151 @Override
152 public String toString() {
153 return section.jmodDir() + "/" + name;
154 }
155
156 /*
157 * A map from the jmodDir name to Section
158 */
159 static final Map<String, Section> NAME_TO_SECTION =
160 Arrays.stream(Section.values())
176 /**
177 * Constructs a {@code JmodFile} from a given path.
178 */
179 public JmodFile(Path file) throws IOException {
180 checkMagic(file);
181 this.file = file;
182 this.zipfile = new ZipFile(file.toFile());
183 }
184
185 public static void writeMagicNumber(OutputStream os) throws IOException {
186 os.write(JMOD_MAGIC_NUMBER);
187 }
188
189 /**
190 * Returns the {@code Entry} for a resource in a JMOD file section
191 * or {@code null} if not found.
192 */
193 public Entry getEntry(Section section, String name) {
194 String entry = section.jmodDir() + "/" + name;
195 ZipEntry ze = zipfile.getEntry(entry);
196 return (ze != null) ? new Entry(ze) : null;
197 }
198
199 /**
200 * Opens an {@code InputStream} for reading the named entry of the given
201 * section in this JMOD file.
202 *
203 * @throws IOException if the named entry is not found, or I/O error
204 * occurs when reading it
205 */
206 public InputStream getInputStream(Section section, String name)
207 throws IOException
208 {
209 String entry = section.jmodDir() + "/" + name;
210 ZipEntry e = zipfile.getEntry(entry);
211 if (e == null) {
212 throw new IOException(name + " not found: " + file);
213 }
214 return zipfile.getInputStream(e);
215 }
216
217 /**
218 * Opens an {@code InputStream} for reading an entry in the JMOD file.
219 *
220 * @throws IOException if an I/O error occurs
221 */
222 public InputStream getInputStream(Entry entry) throws IOException {
223 return zipfile.getInputStream(entry.zipEntry());
224 }
225
226 /**
227 * Returns a stream of entries in this JMOD file.
228 */
229 public Stream<Entry> stream() {
230 return zipfile.stream()
231 .map(Entry::new);
232 }
233
234 @Override
235 public void close() throws IOException {
236 if (zipfile != null) {
237 zipfile.close();
238 }
239 }
240 }
|