27 |
27 |
28 import java.io.File; |
28 import java.io.File; |
29 import java.io.IOException; |
29 import java.io.IOException; |
30 import java.io.PrintWriter; |
30 import java.io.PrintWriter; |
31 import java.nio.file.Files; |
31 import java.nio.file.Files; |
|
32 import java.util.ArrayList; |
32 import java.util.LinkedList; |
33 import java.util.LinkedList; |
33 import java.util.List; |
34 import java.util.List; |
34 import java.util.MissingResourceException; |
35 import java.util.MissingResourceException; |
|
36 import java.util.function.Predicate; |
35 import jdk.internal.jimage.BasicImageReader; |
37 import jdk.internal.jimage.BasicImageReader; |
36 import jdk.internal.jimage.ImageHeader; |
38 import jdk.internal.jimage.ImageHeader; |
37 import jdk.internal.jimage.ImageLocation; |
39 import jdk.internal.jimage.ImageLocation; |
38 import jdk.tools.jlink.internal.ImageResourcesTree; |
40 import jdk.tools.jlink.internal.ImageResourcesTree; |
39 import jdk.tools.jlink.internal.TaskHelper; |
41 import jdk.tools.jlink.internal.TaskHelper; |
41 import static jdk.tools.jlink.internal.TaskHelper.JIMAGE_BUNDLE; |
43 import static jdk.tools.jlink.internal.TaskHelper.JIMAGE_BUNDLE; |
42 import jdk.tools.jlink.internal.TaskHelper.Option; |
44 import jdk.tools.jlink.internal.TaskHelper.Option; |
43 import jdk.tools.jlink.internal.TaskHelper.OptionsHelper; |
45 import jdk.tools.jlink.internal.TaskHelper.OptionsHelper; |
44 |
46 |
45 class JImageTask { |
47 class JImageTask { |
46 |
|
47 static final Option<?>[] recognizedOptions = { |
48 static final Option<?>[] recognizedOptions = { |
48 new Option<JImageTask>(true, (task, option, arg) -> { |
49 new Option<JImageTask>(true, (task, option, arg) -> { |
49 task.options.directory = arg; |
50 task.options.directory = arg; |
50 }, "--dir"), |
51 }, "--dir"), |
|
52 |
|
53 new Option<JImageTask>(true, (task, option, arg) -> { |
|
54 task.options.filters = arg; |
|
55 }, "--filter"), |
|
56 |
51 new Option<JImageTask>(false, (task, option, arg) -> { |
57 new Option<JImageTask>(false, (task, option, arg) -> { |
52 task.options.fullVersion = true; |
58 task.options.fullVersion = true; |
53 }, true, "--fullversion"), |
59 }, true, "--fullversion"), |
|
60 |
54 new Option<JImageTask>(false, (task, option, arg) -> { |
61 new Option<JImageTask>(false, (task, option, arg) -> { |
55 task.options.help = true; |
62 task.options.help = true; |
56 }, "--help"), |
63 }, "--help"), |
|
64 |
57 new Option<JImageTask>(false, (task, option, arg) -> { |
65 new Option<JImageTask>(false, (task, option, arg) -> { |
58 task.options.verbose = true; |
66 task.options.verbose = true; |
59 }, "--verbose"), |
67 }, "--verbose"), |
|
68 |
60 new Option<JImageTask>(false, (task, option, arg) -> { |
69 new Option<JImageTask>(false, (task, option, arg) -> { |
61 task.options.version = true; |
70 task.options.version = true; |
62 }, "--version") |
71 }, "--version") |
63 }; |
72 }; |
64 private static final TaskHelper taskHelper |
73 private static final TaskHelper taskHelper |
65 = new TaskHelper(JIMAGE_BUNDLE); |
74 = new TaskHelper(JIMAGE_BUNDLE); |
66 private static final OptionsHelper<JImageTask> optionsHelper |
75 private static final OptionsHelper<JImageTask> optionsHelper |
67 = taskHelper.newOptionsHelper(JImageTask.class, recognizedOptions); |
76 = taskHelper.newOptionsHelper(JImageTask.class, recognizedOptions); |
|
77 private static final String PROGNAME = "jimage"; |
|
78 |
|
79 private final OptionsValues options; |
|
80 private final List<Predicate<String>> filterPredicates; |
|
81 private PrintWriter log = null; |
|
82 |
|
83 JImageTask() { |
|
84 this.options = new OptionsValues(); |
|
85 this.filterPredicates = new ArrayList<>(); |
|
86 log = null; |
|
87 } |
|
88 |
|
89 void setLog(PrintWriter out) { |
|
90 log = out; |
|
91 taskHelper.setLog(log); |
|
92 } |
68 |
93 |
69 static class OptionsValues { |
94 static class OptionsValues { |
70 Task task = Task.LIST; |
95 Task task = Task.LIST; |
71 String directory = "."; |
96 String directory = "."; |
|
97 String filters = ""; |
72 boolean fullVersion; |
98 boolean fullVersion; |
73 boolean help; |
99 boolean help; |
74 boolean verbose; |
100 boolean verbose; |
75 boolean version; |
101 boolean version; |
76 List<File> jimages = new LinkedList<>(); |
102 List<File> jimages = new LinkedList<>(); |
77 } |
103 } |
78 |
|
79 private static final String PROGNAME = "jimage"; |
|
80 private final OptionsValues options = new OptionsValues(); |
|
81 |
104 |
82 enum Task { |
105 enum Task { |
83 EXTRACT, |
106 EXTRACT, |
84 INFO, |
107 INFO, |
85 LIST, |
108 LIST, |
133 |
156 |
134 int run(String[] args) { |
157 int run(String[] args) { |
135 if (log == null) { |
158 if (log == null) { |
136 setLog(new PrintWriter(System.out, true)); |
159 setLog(new PrintWriter(System.out, true)); |
137 } |
160 } |
|
161 |
138 if (args.length == 0) { |
162 if (args.length == 0) { |
139 log.println(taskHelper.getMessage("main.usage.summary", PROGNAME)); |
163 log.println(taskHelper.getMessage("main.usage.summary", PROGNAME)); |
140 return EXIT_ABNORMAL; |
164 return EXIT_ABNORMAL; |
141 } |
165 } |
|
166 |
142 try { |
167 try { |
143 List<String> unhandled = optionsHelper.handleOptions(this, args); |
168 List<String> unhandled = optionsHelper.handleOptions(this, args); |
|
169 |
144 if(!unhandled.isEmpty()) { |
170 if(!unhandled.isEmpty()) { |
145 try { |
171 try { |
146 options.task = Enum.valueOf(Task.class, unhandled.get(0).toUpperCase()); |
172 options.task = Enum.valueOf(Task.class, unhandled.get(0).toUpperCase()); |
147 } catch (IllegalArgumentException ex) { |
173 } catch (IllegalArgumentException ex) { |
148 throw taskHelper.newBadArgs("err.not.a.task", unhandled.get(0)); |
174 throw taskHelper.newBadArgs("err.not.a.task", unhandled.get(0)); |
149 } |
175 } |
|
176 |
150 for(int i = 1; i < unhandled.size(); i++) { |
177 for(int i = 1; i < unhandled.size(); i++) { |
151 options.jimages.add(new File(unhandled.get(i))); |
178 options.jimages.add(new File(unhandled.get(i))); |
152 } |
179 } |
153 } else if (!options.help && !options.version && !options.fullVersion) { |
180 } else if (!options.help && !options.version && !options.fullVersion) { |
154 throw taskHelper.newBadArgs("err.invalid.task", "<unspecified>"); |
181 throw taskHelper.newBadArgs("err.invalid.task", "<unspecified>"); |
155 } |
182 } |
|
183 |
156 if (options.help) { |
184 if (options.help) { |
157 if (unhandled.isEmpty()) { |
185 if (unhandled.isEmpty()) { |
158 log.println(taskHelper.getMessage("main.usage", PROGNAME)); |
186 log.println(taskHelper.getMessage("main.usage", PROGNAME)); |
|
187 |
159 for (Option<?> o : recognizedOptions) { |
188 for (Option<?> o : recognizedOptions) { |
160 String name = o.aliases()[0]; |
189 String name = o.aliases()[0]; |
|
190 |
161 if (name.startsWith("--")) { |
191 if (name.startsWith("--")) { |
162 name = name.substring(2); |
192 name = name.substring(2); |
163 } else if (name.startsWith("-")) { |
193 } else if (name.startsWith("-")) { |
164 name = name.substring(1); |
194 name = name.substring(1); |
165 } |
195 } |
|
196 |
166 log.println(taskHelper.getMessage("main.opt." + name)); |
197 log.println(taskHelper.getMessage("main.opt." + name)); |
167 } |
198 } |
168 } else { |
199 } else { |
169 try { |
200 try { |
170 log.println(taskHelper.getMessage("main.usage." + options.task.toString().toLowerCase())); |
201 log.println(taskHelper.getMessage("main.usage." + |
|
202 options.task.toString().toLowerCase())); |
171 } catch (MissingResourceException ex) { |
203 } catch (MissingResourceException ex) { |
172 throw taskHelper.newBadArgs("err.not.a.task", unhandled.get(0)); |
204 throw taskHelper.newBadArgs("err.not.a.task", unhandled.get(0)); |
173 } |
205 } |
174 } |
206 } |
175 return EXIT_OK; |
207 return EXIT_OK; |
176 } |
208 } |
|
209 |
177 if (options.version || options.fullVersion) { |
210 if (options.version || options.fullVersion) { |
178 taskHelper.showVersion(options.fullVersion); |
211 taskHelper.showVersion(options.fullVersion); |
179 |
212 |
180 if (unhandled.isEmpty()) { |
213 if (unhandled.isEmpty()) { |
181 return EXIT_OK; |
214 return EXIT_OK; |
182 } |
215 } |
183 } |
216 } |
|
217 |
|
218 processFilter(options.filters); |
|
219 |
184 return run() ? EXIT_OK : EXIT_ERROR; |
220 return run() ? EXIT_OK : EXIT_ERROR; |
185 } catch (BadArgs e) { |
221 } catch (BadArgs e) { |
186 taskHelper.reportError(e.key, e.args); |
222 taskHelper.reportError(e.key, e.args); |
|
223 |
187 if (e.showUsage) { |
224 if (e.showUsage) { |
188 log.println(taskHelper.getMessage("main.usage.summary", PROGNAME)); |
225 log.println(taskHelper.getMessage("main.usage.summary", PROGNAME)); |
189 } |
226 } |
|
227 |
190 return EXIT_CMDERR; |
228 return EXIT_CMDERR; |
191 } catch (Exception x) { |
229 } catch (Exception x) { |
192 x.printStackTrace(); |
230 x.printStackTrace(); |
|
231 |
193 return EXIT_ABNORMAL; |
232 return EXIT_ABNORMAL; |
194 } finally { |
233 } finally { |
195 log.flush(); |
234 log.flush(); |
|
235 } |
|
236 } |
|
237 |
|
238 private void processFilter(String filters) { |
|
239 if (filters.isEmpty()) { |
|
240 return; |
|
241 } |
|
242 |
|
243 for (String filter : filters.split(",")) { |
|
244 boolean endsWith = filter.startsWith("*"); |
|
245 boolean startsWith = filter.endsWith("*"); |
|
246 Predicate<String> function; |
|
247 |
|
248 if (startsWith && endsWith) { |
|
249 final String string = filter.substring(1, filter.length() - 1); |
|
250 function = (path) -> path.contains(string); |
|
251 } else if (startsWith) { |
|
252 final String string = filter.substring(0, filter.length() - 1); |
|
253 function = (path) -> path.startsWith(string); |
|
254 } else if (endsWith) { |
|
255 final String string = filter.substring(1); |
|
256 function = (path) -> path.endsWith(string); |
|
257 } else { |
|
258 final String string = filter; |
|
259 function = (path) -> path.equals(string); |
|
260 } |
|
261 |
|
262 filterPredicates.add(function); |
196 } |
263 } |
197 } |
264 } |
198 |
265 |
199 private void listTitle(File file, BasicImageReader reader) { |
266 private void listTitle(File file, BasicImageReader reader) { |
200 log.println("jimage: " + file); |
267 log.println("jimage: " + file); |
221 File resource = new File(directory, name); |
288 File resource = new File(directory, name); |
222 File parent = resource.getParentFile(); |
289 File parent = resource.getParentFile(); |
223 |
290 |
224 if (parent.exists()) { |
291 if (parent.exists()) { |
225 if (!parent.isDirectory()) { |
292 if (!parent.isDirectory()) { |
226 throw taskHelper.newBadArgs("err.cannot.create.dir", parent.getAbsolutePath()); |
293 throw taskHelper.newBadArgs("err.cannot.create.dir", |
|
294 parent.getAbsolutePath()); |
227 } |
295 } |
228 } else if (!parent.mkdirs()) { |
296 } else if (!parent.mkdirs()) { |
229 throw taskHelper.newBadArgs("err.cannot.create.dir", parent.getAbsolutePath()); |
297 throw taskHelper.newBadArgs("err.cannot.create.dir", |
|
298 parent.getAbsolutePath()); |
230 } |
299 } |
231 |
300 |
232 if (!ImageResourcesTree.isTreeInfoResource(name)) { |
301 if (!ImageResourcesTree.isTreeInfoResource(name)) { |
233 Files.write(resource.toPath(), bytes); |
302 Files.write(resource.toPath(), bytes); |
234 } |
303 } |