37 import java.util.MissingResourceException;
38 import java.util.function.Predicate;
39 import jdk.internal.jimage.BasicImageReader;
40 import jdk.internal.jimage.ImageHeader;
41 import jdk.internal.jimage.ImageLocation;
42 import jdk.tools.jlink.internal.ImageResourcesTree;
43 import jdk.tools.jlink.internal.TaskHelper;
44 import jdk.tools.jlink.internal.TaskHelper.BadArgs;
45 import static jdk.tools.jlink.internal.TaskHelper.JIMAGE_BUNDLE;
46 import jdk.tools.jlink.internal.TaskHelper.Option;
47 import jdk.tools.jlink.internal.TaskHelper.OptionsHelper;
48 import jdk.tools.jlink.internal.Utils;
49
50 class JImageTask {
51 private static final Option<?>[] RECOGNIZED_OPTIONS = {
52 new Option<JImageTask>(true, (task, option, arg) -> {
53 task.options.directory = arg;
54 }, "--dir"),
55
56 new Option<JImageTask>(true, (task, option, arg) -> {
57 task.options.filters = arg;
58 }, "--filter"),
59
60 new Option<JImageTask>(false, (task, option, arg) -> {
61 task.options.fullVersion = true;
62 }, true, "--fullversion"),
63
64 new Option<JImageTask>(false, (task, option, arg) -> {
65 task.options.help = true;
66 }, "--help"),
67
68 new Option<JImageTask>(false, (task, option, arg) -> {
69 task.options.verbose = true;
70 }, "--verbose"),
71
72 new Option<JImageTask>(false, (task, option, arg) -> {
73 task.options.version = true;
74 }, "--version")
75 };
76 private static final TaskHelper TASK_HELPER
77 = new TaskHelper(JIMAGE_BUNDLE);
78 private static final OptionsHelper<JImageTask> OPTION_HELPER
79 = TASK_HELPER.newOptionsHelper(JImageTask.class, RECOGNIZED_OPTIONS);
80 private static final String PROGNAME = "jimage";
81 private static final FileSystem JRT_FILE_SYSTEM = Utils.jrtFileSystem();
82
83 private final OptionsValues options;
84 private final List<Predicate<String>> filterPredicates;
85 private PrintWriter log;
86
87 JImageTask() {
88 this.options = new OptionsValues();
89 this.filterPredicates = new ArrayList<>();
90 log = null;
91 }
92
93 void setLog(PrintWriter out) {
94 log = out;
95 TASK_HELPER.setLog(log);
96 }
97
98 static class OptionsValues {
99 Task task = Task.LIST;
100 String directory = ".";
101 String filters = "";
102 boolean fullVersion;
103 boolean help;
104 boolean verbose;
105 boolean version;
106 List<File> jimages = new LinkedList<>();
107 }
108
109 enum Task {
110 EXTRACT,
111 INFO,
112 LIST,
113 VERIFY
114 };
115
116 private String pad(String string, int width, boolean justifyRight) {
117 int length = string.length();
118
119 if (length == width) {
120 return string;
121 }
183 }
184 } else if (!options.help && !options.version && !options.fullVersion) {
185 throw TASK_HELPER.newBadArgs("err.invalid.task", "<unspecified>");
186 }
187
188 if (options.help) {
189 if (unhandled.isEmpty()) {
190 log.println(TASK_HELPER.getMessage("main.usage", PROGNAME));
191
192 for (Option<?> o : RECOGNIZED_OPTIONS) {
193 String name = o.aliases()[0];
194
195 if (name.startsWith("--")) {
196 name = name.substring(2);
197 } else if (name.startsWith("-")) {
198 name = name.substring(1);
199 }
200
201 log.println(TASK_HELPER.getMessage("main.opt." + name));
202 }
203 } else {
204 try {
205 log.println(TASK_HELPER.getMessage("main.usage." +
206 options.task.toString().toLowerCase()));
207 } catch (MissingResourceException ex) {
208 throw TASK_HELPER.newBadArgs("err.not.a.task", unhandled.get(0));
209 }
210 }
211 return EXIT_OK;
212 }
213
214 if (options.version || options.fullVersion) {
215 TASK_HELPER.showVersion(options.fullVersion);
216
217 if (unhandled.isEmpty()) {
218 return EXIT_OK;
219 }
220 }
221
222 processFilter(options.filters);
223
224 return run() ? EXIT_OK : EXIT_ERROR;
225 } catch (BadArgs e) {
226 TASK_HELPER.reportError(e.key, e.args);
227
228 if (e.showUsage) {
229 log.println(TASK_HELPER.getMessage("main.usage.summary", PROGNAME));
230 }
231
232 return EXIT_CMDERR;
233 } catch (Exception x) {
234 x.printStackTrace();
235
236 return EXIT_ABNORMAL;
237 } finally {
238 log.flush();
239 }
240 }
241
242 private void processFilter(String filters) {
243 if (filters.isEmpty()) {
244 return;
245 }
246
247 for (String filter : filters.split(",")) {
248 final PathMatcher matcher = Utils.getPathMatcher(JRT_FILE_SYSTEM, filter);
249 Predicate<String> predicate = (path) -> matcher.matches(JRT_FILE_SYSTEM.getPath(path));
250 filterPredicates.add(predicate);
251 }
252 }
253
254 private void listTitle(File file, BasicImageReader reader) {
255 log.println("jimage: " + file);
256 }
257
258 private interface JImageAction {
259 public void apply(File file, BasicImageReader reader) throws IOException, BadArgs;
260 }
261
262 private interface ModuleAction {
263 public void apply(BasicImageReader reader,
264 String oldModule, String newModule) throws IOException, BadArgs;
265 }
266
267 private interface ResourceAction {
268 public void apply(BasicImageReader reader, String name,
269 ImageLocation location) throws IOException, BadArgs;
270 }
371 ResourceAction resourceAction) throws IOException, BadArgs {
372 if (options.jimages.isEmpty()) {
373 throw TASK_HELPER.newBadArgs("err.no.jimage");
374 }
375
376 for (File file : options.jimages) {
377 if (!file.exists() || !file.isFile()) {
378 throw TASK_HELPER.newBadArgs("err.not.a.jimage", file.getName());
379 }
380
381 try (BasicImageReader reader = BasicImageReader.open(file.toPath())) {
382 if (jimageAction != null) {
383 jimageAction.apply(file, reader);
384 }
385
386 if (resourceAction != null) {
387 String[] entryNames = reader.getEntryNames();
388 String oldModule = "";
389
390 for (String name : entryNames) {
391 boolean match = filterPredicates.isEmpty();
392
393 for (Predicate<String> predicate : filterPredicates) {
394 if (predicate.test(name)) {
395 match = true;
396 break;
397 }
398 }
399
400 if (!match) {
401 continue;
402 }
403
404 if (!ImageResourcesTree.isTreeInfoResource(name)) {
405 if (moduleAction != null) {
406 int offset = name.indexOf('/', 1);
407
408 String newModule = offset != -1 ?
409 name.substring(1, offset) :
410 "<unknown>";
411
412 if (!oldModule.equals(newModule)) {
413 moduleAction.apply(reader, oldModule, newModule);
|
37 import java.util.MissingResourceException;
38 import java.util.function.Predicate;
39 import jdk.internal.jimage.BasicImageReader;
40 import jdk.internal.jimage.ImageHeader;
41 import jdk.internal.jimage.ImageLocation;
42 import jdk.tools.jlink.internal.ImageResourcesTree;
43 import jdk.tools.jlink.internal.TaskHelper;
44 import jdk.tools.jlink.internal.TaskHelper.BadArgs;
45 import static jdk.tools.jlink.internal.TaskHelper.JIMAGE_BUNDLE;
46 import jdk.tools.jlink.internal.TaskHelper.Option;
47 import jdk.tools.jlink.internal.TaskHelper.OptionsHelper;
48 import jdk.tools.jlink.internal.Utils;
49
50 class JImageTask {
51 private static final Option<?>[] RECOGNIZED_OPTIONS = {
52 new Option<JImageTask>(true, (task, option, arg) -> {
53 task.options.directory = arg;
54 }, "--dir"),
55
56 new Option<JImageTask>(true, (task, option, arg) -> {
57 task.options.include = arg;
58 }, "--include"),
59
60 new Option<JImageTask>(false, (task, option, arg) -> {
61 task.options.fullVersion = true;
62 }, true, "--fullversion"),
63
64 new Option<JImageTask>(false, (task, option, arg) -> {
65 task.options.help = true;
66 }, "--help"),
67
68 new Option<JImageTask>(false, (task, option, arg) -> {
69 task.options.verbose = true;
70 }, "--verbose"),
71
72 new Option<JImageTask>(false, (task, option, arg) -> {
73 task.options.version = true;
74 }, "--version")
75 };
76 private static final TaskHelper TASK_HELPER
77 = new TaskHelper(JIMAGE_BUNDLE);
78 private static final OptionsHelper<JImageTask> OPTION_HELPER
79 = TASK_HELPER.newOptionsHelper(JImageTask.class, RECOGNIZED_OPTIONS);
80 private static final String PROGNAME = "jimage";
81 private static final FileSystem JRT_FILE_SYSTEM = Utils.jrtFileSystem();
82
83 private final OptionsValues options;
84 private final List<Predicate<String>> includePredicates;
85 private PrintWriter log;
86
87 JImageTask() {
88 this.options = new OptionsValues();
89 this.includePredicates = new ArrayList<>();
90 log = null;
91 }
92
93 void setLog(PrintWriter out) {
94 log = out;
95 TASK_HELPER.setLog(log);
96 }
97
98 static class OptionsValues {
99 Task task = Task.LIST;
100 String directory = ".";
101 String include = "";
102 boolean fullVersion;
103 boolean help;
104 boolean verbose;
105 boolean version;
106 List<File> jimages = new LinkedList<>();
107 }
108
109 enum Task {
110 EXTRACT,
111 INFO,
112 LIST,
113 VERIFY
114 };
115
116 private String pad(String string, int width, boolean justifyRight) {
117 int length = string.length();
118
119 if (length == width) {
120 return string;
121 }
183 }
184 } else if (!options.help && !options.version && !options.fullVersion) {
185 throw TASK_HELPER.newBadArgs("err.invalid.task", "<unspecified>");
186 }
187
188 if (options.help) {
189 if (unhandled.isEmpty()) {
190 log.println(TASK_HELPER.getMessage("main.usage", PROGNAME));
191
192 for (Option<?> o : RECOGNIZED_OPTIONS) {
193 String name = o.aliases()[0];
194
195 if (name.startsWith("--")) {
196 name = name.substring(2);
197 } else if (name.startsWith("-")) {
198 name = name.substring(1);
199 }
200
201 log.println(TASK_HELPER.getMessage("main.opt." + name));
202 }
203
204 log.println(TASK_HELPER.getMessage("main.opt.footer"));
205 } else {
206 try {
207 log.println(TASK_HELPER.getMessage("main.usage." +
208 options.task.toString().toLowerCase()));
209 } catch (MissingResourceException ex) {
210 throw TASK_HELPER.newBadArgs("err.not.a.task", unhandled.get(0));
211 }
212 }
213 return EXIT_OK;
214 }
215
216 if (options.version || options.fullVersion) {
217 TASK_HELPER.showVersion(options.fullVersion);
218
219 if (unhandled.isEmpty()) {
220 return EXIT_OK;
221 }
222 }
223
224 processInclude(options.include);
225
226 return run() ? EXIT_OK : EXIT_ERROR;
227 } catch (BadArgs e) {
228 TASK_HELPER.reportError(e.key, e.args);
229
230 if (e.showUsage) {
231 log.println(TASK_HELPER.getMessage("main.usage.summary", PROGNAME));
232 }
233
234 return EXIT_CMDERR;
235 } catch (Exception x) {
236 x.printStackTrace();
237
238 return EXIT_ABNORMAL;
239 } finally {
240 log.flush();
241 }
242 }
243
244 private void processInclude(String include) {
245 if (include.isEmpty()) {
246 return;
247 }
248
249 for (String filter : include.split(",")) {
250 final PathMatcher matcher = Utils.getPathMatcher(JRT_FILE_SYSTEM, filter);
251 Predicate<String> predicate = (path) -> matcher.matches(JRT_FILE_SYSTEM.getPath(path));
252 includePredicates.add(predicate);
253 }
254 }
255
256 private void listTitle(File file, BasicImageReader reader) {
257 log.println("jimage: " + file);
258 }
259
260 private interface JImageAction {
261 public void apply(File file, BasicImageReader reader) throws IOException, BadArgs;
262 }
263
264 private interface ModuleAction {
265 public void apply(BasicImageReader reader,
266 String oldModule, String newModule) throws IOException, BadArgs;
267 }
268
269 private interface ResourceAction {
270 public void apply(BasicImageReader reader, String name,
271 ImageLocation location) throws IOException, BadArgs;
272 }
373 ResourceAction resourceAction) throws IOException, BadArgs {
374 if (options.jimages.isEmpty()) {
375 throw TASK_HELPER.newBadArgs("err.no.jimage");
376 }
377
378 for (File file : options.jimages) {
379 if (!file.exists() || !file.isFile()) {
380 throw TASK_HELPER.newBadArgs("err.not.a.jimage", file.getName());
381 }
382
383 try (BasicImageReader reader = BasicImageReader.open(file.toPath())) {
384 if (jimageAction != null) {
385 jimageAction.apply(file, reader);
386 }
387
388 if (resourceAction != null) {
389 String[] entryNames = reader.getEntryNames();
390 String oldModule = "";
391
392 for (String name : entryNames) {
393 boolean match = includePredicates.isEmpty();
394
395 for (Predicate<String> predicate : includePredicates) {
396 if (predicate.test(name)) {
397 match = true;
398 break;
399 }
400 }
401
402 if (!match) {
403 continue;
404 }
405
406 if (!ImageResourcesTree.isTreeInfoResource(name)) {
407 if (moduleAction != null) {
408 int offset = name.indexOf('/', 1);
409
410 String newModule = offset != -1 ?
411 name.substring(1, offset) :
412 "<unknown>";
413
414 if (!oldModule.equals(newModule)) {
415 moduleAction.apply(reader, oldModule, newModule);
|