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
26 package jdk.tools.jimage;
27
28 import java.io.File;
29 import java.io.IOException;
30 import java.io.PrintWriter;
31 import java.nio.file.FileSystem;
32 import java.nio.file.Files;
33 import java.nio.file.PathMatcher;
34 import java.util.ArrayList;
35 import java.util.Arrays;
36 import java.util.LinkedList;
37 import java.util.List;
38 import java.util.MissingResourceException;
39 import java.util.function.Predicate;
40 import jdk.internal.jimage.BasicImageReader;
41 import jdk.internal.jimage.ImageHeader;
42 import jdk.internal.jimage.ImageLocation;
43 import jdk.internal.org.objectweb.asm.ClassReader;
44 import jdk.internal.org.objectweb.asm.tree.ClassNode;
45 import jdk.tools.jlink.internal.ImageResourcesTree;
46 import jdk.tools.jlink.internal.TaskHelper;
47 import jdk.tools.jlink.internal.TaskHelper.BadArgs;
48 import static jdk.tools.jlink.internal.TaskHelper.JIMAGE_BUNDLE;
49 import jdk.tools.jlink.internal.TaskHelper.Option;
50 import jdk.tools.jlink.internal.TaskHelper.OptionsHelper;
51 import jdk.tools.jlink.internal.Utils;
52
53 class JImageTask {
54 private static final Option<?>[] RECOGNIZED_OPTIONS = {
55 new Option<JImageTask>(true, (task, option, arg) -> {
56 task.options.directory = arg;
57 }, "--dir"),
58
59 new Option<JImageTask>(true, (task, option, arg) -> {
82 = TASK_HELPER.newOptionsHelper(JImageTask.class, RECOGNIZED_OPTIONS);
83 private static final String PROGNAME = "jimage";
84 private static final FileSystem JRT_FILE_SYSTEM = Utils.jrtFileSystem();
85
86 private final OptionsValues options;
87 private final List<Predicate<String>> includePredicates;
88 private PrintWriter log;
89
90 JImageTask() {
91 this.options = new OptionsValues();
92 this.includePredicates = new ArrayList<>();
93 log = null;
94 }
95
96 void setLog(PrintWriter out) {
97 log = out;
98 TASK_HELPER.setLog(log);
99 }
100
101 static class OptionsValues {
102 Task task = Task.LIST;
103 String directory = ".";
104 String include = "";
105 boolean fullVersion;
106 boolean help;
107 boolean verbose;
108 boolean version;
109 List<File> jimages = new LinkedList<>();
110 }
111
112 enum Task {
113 EXTRACT,
114 INFO,
115 LIST,
116 VERIFY
117 };
118
119 private String pad(String string, int width, boolean justifyRight) {
120 int length = string.length();
121
122 if (length == width) {
155 return pad(Long.toString(value), width, true);
156 }
157
158 private static final int EXIT_OK = 0; // No errors.
159 private static final int EXIT_ERROR = 1; // Completed but reported errors.
160 private static final int EXIT_CMDERR = 2; // Bad command-line arguments and/or switches.
161 private static final int EXIT_SYSERR = 3; // System error or resource exhaustion.
162 private static final int EXIT_ABNORMAL = 4; // Terminated abnormally.
163
164 int run(String[] args) {
165 if (log == null) {
166 setLog(new PrintWriter(System.out, true));
167 }
168
169 if (args.length == 0) {
170 log.println(TASK_HELPER.getMessage("main.usage.summary", PROGNAME));
171 return EXIT_ABNORMAL;
172 }
173
174 try {
175 List<String> unhandled = OPTION_HELPER.handleOptions(this, args);
176
177 if(!unhandled.isEmpty()) {
178 try {
179 options.task = Enum.valueOf(Task.class, unhandled.get(0).toUpperCase());
180 } catch (IllegalArgumentException ex) {
181 throw TASK_HELPER.newBadArgs("err.not.a.task", unhandled.get(0));
182 }
183
184 for(int i = 1; i < unhandled.size(); i++) {
185 options.jimages.add(new File(unhandled.get(i)));
186 }
187 } else if (!options.help && !options.version && !options.fullVersion) {
188 throw TASK_HELPER.newBadArgs("err.invalid.task", "<unspecified>");
189 }
190
191 if (options.help) {
192 if (unhandled.isEmpty()) {
193 log.println(TASK_HELPER.getMessage("main.usage", PROGNAME));
194 Arrays.asList(RECOGNIZED_OPTIONS).stream()
195 .filter(option -> !option.isHidden())
196 .sorted()
197 .forEach(option -> {
198 log.println(TASK_HELPER.getMessage(option.resourceName()));
199 });
200 log.println(TASK_HELPER.getMessage("main.opt.footer"));
201 } else {
202 try {
203 log.println(TASK_HELPER.getMessage("main.usage." +
204 options.task.toString().toLowerCase()));
205 } catch (MissingResourceException ex) {
206 throw TASK_HELPER.newBadArgs("err.not.a.task", unhandled.get(0));
207 }
208 }
209 return EXIT_OK;
210 }
211
212 if (options.version || options.fullVersion) {
213 TASK_HELPER.showVersion(options.fullVersion);
214
215 if (unhandled.isEmpty()) {
216 return EXIT_OK;
217 }
218 }
219
220 processInclude(options.include);
221
222 return run() ? EXIT_OK : EXIT_ERROR;
223 } catch (BadArgs e) {
224 TASK_HELPER.reportError(e.key, e.args);
225
226 if (e.showUsage) {
227 log.println(TASK_HELPER.getMessage("main.usage.summary", PROGNAME));
228 }
229
230 return EXIT_CMDERR;
231 } catch (Exception x) {
232 x.printStackTrace();
233
234 return EXIT_ABNORMAL;
418 }
419 }
420 }
421 }
422
423 private boolean run() throws Exception, BadArgs {
424 switch (options.task) {
425 case EXTRACT:
426 iterate(null, null, this::extract);
427 break;
428 case INFO:
429 iterate(this::info, null, null);
430 break;
431 case LIST:
432 iterate(this::listTitle, this::listModule, this::list);
433 break;
434 case VERIFY:
435 iterate(this::listTitle, null, this::verify);
436 break;
437 default:
438 throw TASK_HELPER.newBadArgs("err.invalid.task",
439 options.task.name()).showUsage(true);
440 }
441 return true;
442 }
443 }
|
1 /*
2 * Copyright (c) 2014, 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
23 * questions.
24 */
25
26 package jdk.tools.jimage;
27
28 import java.io.File;
29 import java.io.IOException;
30 import java.io.PrintWriter;
31 import java.nio.file.FileSystem;
32 import java.nio.file.Files;
33 import java.nio.file.PathMatcher;
34 import java.util.ArrayList;
35 import java.util.Arrays;
36 import java.util.LinkedList;
37 import java.util.List;
38 import java.util.Locale;
39 import java.util.MissingResourceException;
40 import java.util.function.Predicate;
41 import java.util.stream.Collectors;
42 import java.util.stream.Stream;
43
44 import jdk.internal.jimage.BasicImageReader;
45 import jdk.internal.jimage.ImageHeader;
46 import jdk.internal.jimage.ImageLocation;
47 import jdk.internal.org.objectweb.asm.ClassReader;
48 import jdk.internal.org.objectweb.asm.tree.ClassNode;
49 import jdk.tools.jlink.internal.ImageResourcesTree;
50 import jdk.tools.jlink.internal.TaskHelper;
51 import jdk.tools.jlink.internal.TaskHelper.BadArgs;
52 import static jdk.tools.jlink.internal.TaskHelper.JIMAGE_BUNDLE;
53 import jdk.tools.jlink.internal.TaskHelper.Option;
54 import jdk.tools.jlink.internal.TaskHelper.OptionsHelper;
55 import jdk.tools.jlink.internal.Utils;
56
57 class JImageTask {
58 private static final Option<?>[] RECOGNIZED_OPTIONS = {
59 new Option<JImageTask>(true, (task, option, arg) -> {
60 task.options.directory = arg;
61 }, "--dir"),
62
63 new Option<JImageTask>(true, (task, option, arg) -> {
86 = TASK_HELPER.newOptionsHelper(JImageTask.class, RECOGNIZED_OPTIONS);
87 private static final String PROGNAME = "jimage";
88 private static final FileSystem JRT_FILE_SYSTEM = Utils.jrtFileSystem();
89
90 private final OptionsValues options;
91 private final List<Predicate<String>> includePredicates;
92 private PrintWriter log;
93
94 JImageTask() {
95 this.options = new OptionsValues();
96 this.includePredicates = new ArrayList<>();
97 log = null;
98 }
99
100 void setLog(PrintWriter out) {
101 log = out;
102 TASK_HELPER.setLog(log);
103 }
104
105 static class OptionsValues {
106 Task task = null;
107 String directory = ".";
108 String include = "";
109 boolean fullVersion;
110 boolean help;
111 boolean verbose;
112 boolean version;
113 List<File> jimages = new LinkedList<>();
114 }
115
116 enum Task {
117 EXTRACT,
118 INFO,
119 LIST,
120 VERIFY
121 };
122
123 private String pad(String string, int width, boolean justifyRight) {
124 int length = string.length();
125
126 if (length == width) {
159 return pad(Long.toString(value), width, true);
160 }
161
162 private static final int EXIT_OK = 0; // No errors.
163 private static final int EXIT_ERROR = 1; // Completed but reported errors.
164 private static final int EXIT_CMDERR = 2; // Bad command-line arguments and/or switches.
165 private static final int EXIT_SYSERR = 3; // System error or resource exhaustion.
166 private static final int EXIT_ABNORMAL = 4; // Terminated abnormally.
167
168 int run(String[] args) {
169 if (log == null) {
170 setLog(new PrintWriter(System.out, true));
171 }
172
173 if (args.length == 0) {
174 log.println(TASK_HELPER.getMessage("main.usage.summary", PROGNAME));
175 return EXIT_ABNORMAL;
176 }
177
178 try {
179 String command;
180 String[] remaining = args;
181 try {
182 command = args[0];
183 options.task = Enum.valueOf(Task.class, args[0].toUpperCase(Locale.ENGLISH));
184 remaining = args.length > 1 ? Arrays.copyOfRange(args, 1, args.length)
185 : new String[0];
186 } catch (IllegalArgumentException ex) {
187 command = null;
188 options.task = null;
189 }
190
191 // process arguments
192 List<String> unhandled = OPTION_HELPER.handleOptions(this, remaining);
193 for (String f : unhandled) {
194 options.jimages.add(new File(f));
195 }
196
197 if (options.task == null && !options.help && !options.version && !options.fullVersion) {
198 throw TASK_HELPER.newBadArgs("err.not.a.task",
199 command != null ? command : "<unspecified>");
200 }
201
202 if (options.help) {
203 if (options.task == null) {
204 log.println(TASK_HELPER.getMessage("main.usage", PROGNAME));
205 Arrays.asList(RECOGNIZED_OPTIONS).stream()
206 .filter(option -> !option.isHidden())
207 .sorted()
208 .forEach(option -> {
209 log.println(TASK_HELPER.getMessage(option.resourceName()));
210 });
211 log.println(TASK_HELPER.getMessage("main.opt.footer"));
212 } else {
213 try {
214 log.println(TASK_HELPER.getMessage("main.usage." +
215 options.task.toString().toLowerCase()));
216 } catch (MissingResourceException ex) {
217 throw TASK_HELPER.newBadArgs("err.not.a.task", command);
218 }
219 }
220 return EXIT_OK;
221 }
222
223 if (options.version || options.fullVersion) {
224 if (options.task == null && !unhandled.isEmpty()) {
225 throw TASK_HELPER.newBadArgs("err.not.a.task",
226 Stream.of(args).collect(Collectors.joining(" ")));
227 }
228
229 TASK_HELPER.showVersion(options.fullVersion);
230 if (unhandled.isEmpty()) {
231 return EXIT_OK;
232 }
233 }
234
235 processInclude(options.include);
236
237 return run() ? EXIT_OK : EXIT_ERROR;
238 } catch (BadArgs e) {
239 TASK_HELPER.reportError(e.key, e.args);
240
241 if (e.showUsage) {
242 log.println(TASK_HELPER.getMessage("main.usage.summary", PROGNAME));
243 }
244
245 return EXIT_CMDERR;
246 } catch (Exception x) {
247 x.printStackTrace();
248
249 return EXIT_ABNORMAL;
433 }
434 }
435 }
436 }
437
438 private boolean run() throws Exception, BadArgs {
439 switch (options.task) {
440 case EXTRACT:
441 iterate(null, null, this::extract);
442 break;
443 case INFO:
444 iterate(this::info, null, null);
445 break;
446 case LIST:
447 iterate(this::listTitle, this::listModule, this::list);
448 break;
449 case VERIFY:
450 iterate(this::listTitle, null, this::verify);
451 break;
452 default:
453 throw TASK_HELPER.newBadArgs("err.not.a.task",
454 options.task.name()).showUsage(true);
455 }
456 return true;
457 }
458 }
|