30 import java.io.File;
31 import java.io.IOException;
32 import java.io.InputStream;
33 import java.io.OutputStream;
34 import java.io.PrintStream;
35 import java.io.PrintWriter;
36 import java.io.UncheckedIOException;
37 import java.lang.module.Configuration;
38 import java.lang.module.ModuleReader;
39 import java.lang.module.ModuleReference;
40 import java.lang.module.ModuleFinder;
41 import java.lang.module.ModuleDescriptor;
42 import java.lang.module.ModuleDescriptor.Exports;
43 import java.lang.module.ModuleDescriptor.Opens;
44 import java.lang.module.ModuleDescriptor.Provides;
45 import java.lang.module.ModuleDescriptor.Requires;
46 import java.lang.module.ModuleDescriptor.Version;
47 import java.lang.module.ResolutionException;
48 import java.lang.module.ResolvedModule;
49 import java.net.URI;
50 import java.nio.file.FileSystems;
51 import java.nio.file.FileVisitOption;
52 import java.nio.file.FileVisitResult;
53 import java.nio.file.Files;
54 import java.nio.file.InvalidPathException;
55 import java.nio.file.Path;
56 import java.nio.file.PathMatcher;
57 import java.nio.file.Paths;
58 import java.nio.file.SimpleFileVisitor;
59 import java.nio.file.StandardCopyOption;
60 import java.nio.file.attribute.BasicFileAttributes;
61 import java.text.MessageFormat;
62 import java.util.ArrayDeque;
63 import java.util.ArrayList;
64 import java.util.Collection;
65 import java.util.Collections;
66 import java.util.Comparator;
67 import java.util.Deque;
68 import java.util.HashMap;
69 import java.util.HashSet;
136 }
137
138 private static final String PROGNAME = "jmod";
139 private static final String MODULE_INFO = "module-info.class";
140
141 private Options options;
142 private PrintWriter out = new PrintWriter(System.out, true);
143 void setLog(PrintWriter out, PrintWriter err) {
144 this.out = out;
145 }
146
147 /* Result codes. */
148 static final int EXIT_OK = 0, // Completed with no errors.
149 EXIT_ERROR = 1, // Completed but reported errors.
150 EXIT_CMDERR = 2, // Bad command-line arguments
151 EXIT_SYSERR = 3, // System error or resource exhaustion.
152 EXIT_ABNORMAL = 4;// terminated abnormally
153
154 enum Mode {
155 CREATE,
156 LIST,
157 DESCRIBE,
158 HASH
159 };
160
161 static class Options {
162 Mode mode;
163 Path jmodFile;
164 boolean help;
165 boolean version;
166 List<Path> classpath;
167 List<Path> cmds;
168 List<Path> configs;
169 List<Path> libs;
170 List<Path> headerFiles;
171 List<Path> manPages;
172 ModuleFinder moduleFinder;
173 Version moduleVersion;
174 String mainClass;
175 String osName;
185 try {
186 handleOptions(args);
187 if (options == null) {
188 showUsageSummary();
189 return EXIT_CMDERR;
190 }
191 if (options.help) {
192 showHelp();
193 return EXIT_OK;
194 }
195 if (options.version) {
196 showVersion();
197 return EXIT_OK;
198 }
199
200 boolean ok;
201 switch (options.mode) {
202 case CREATE:
203 ok = create();
204 break;
205 case LIST:
206 ok = list();
207 break;
208 case DESCRIBE:
209 ok = describe();
210 break;
211 case HASH:
212 ok = hashModules();
213 break;
214 default:
215 throw new AssertionError("Unknown mode: " + options.mode.name());
216 }
217
218 return ok ? EXIT_OK : EXIT_ERROR;
219 } catch (CommandException e) {
220 reportError(e.getMessage());
221 if (e.showUsage)
222 showUsageSummary();
223 return EXIT_CMDERR;
224 } catch (Exception x) {
231 }
232
233 private boolean list() throws IOException {
234 ZipFile zip = null;
235 try {
236 try {
237 zip = new ZipFile(options.jmodFile.toFile());
238 } catch (IOException x) {
239 throw new IOException("error opening jmod file", x);
240 }
241
242 // Trivially print the archive entries for now, pending a more complete implementation
243 zip.stream().forEach(e -> out.println(e.getName()));
244 return true;
245 } finally {
246 if (zip != null)
247 zip.close();
248 }
249 }
250
251 private boolean hashModules() {
252 return new Hasher(options.moduleFinder).run();
253 }
254
255 private boolean describe() throws IOException {
256 try (JmodFile jf = new JmodFile(options.jmodFile)) {
257 try (InputStream in = jf.getInputStream(Section.CLASSES, MODULE_INFO)) {
258 ModuleDescriptor md = ModuleDescriptor.read(in);
259 printModuleDescriptor(md);
260 return true;
261 } catch (IOException e) {
262 throw new CommandException("err.module.descriptor.not.found");
263 }
264 }
265 }
266
267 static <T> String toString(Collection<T> c) {
268 if (c.isEmpty()) { return ""; }
269 return c.stream().map(e -> e.toString().toLowerCase(Locale.ROOT))
270 .collect(joining(" "));
1141 @Override
1142 public List<?> defaultValues() { return Collections.emptyList(); }
1143 @Override
1144 public boolean isRequired() { return false; }
1145 @Override
1146 public boolean acceptsArguments() { return false; }
1147 @Override
1148 public boolean requiresArgument() { return false; }
1149 @Override
1150 public String argumentDescription() { return null; }
1151 @Override
1152 public String argumentTypeIndicator() { return null; }
1153 @Override
1154 public boolean representsNonOptions() { return false; }
1155 });
1156 String content = super.format(all);
1157 StringBuilder builder = new StringBuilder();
1158
1159 builder.append(getMessage("main.opt.mode")).append("\n ");
1160 builder.append(getMessage("main.opt.mode.create")).append("\n ");
1161 builder.append(getMessage("main.opt.mode.list")).append("\n ");
1162 builder.append(getMessage("main.opt.mode.describe")).append("\n ");
1163 builder.append(getMessage("main.opt.mode.hash")).append("\n\n");
1164
1165 String cmdfile = null;
1166 String[] lines = content.split("\n");
1167 for (String line : lines) {
1168 if (line.startsWith("--@")) {
1169 cmdfile = line.replace("--" + CMD_FILENAME, CMD_FILENAME + " ");
1170 } else if (line.startsWith("Option") || line.startsWith("------")) {
1171 builder.append(" ").append(line).append("\n");
1172 } else if (!line.matches("Non-option arguments")){
1173 builder.append(" ").append(line).append("\n");
1174 }
1175 }
1176 if (cmdfile != null) {
1177 builder.append(" ").append(cmdfile).append("\n");
1178 }
1179 return builder.toString();
1180 }
|
30 import java.io.File;
31 import java.io.IOException;
32 import java.io.InputStream;
33 import java.io.OutputStream;
34 import java.io.PrintStream;
35 import java.io.PrintWriter;
36 import java.io.UncheckedIOException;
37 import java.lang.module.Configuration;
38 import java.lang.module.ModuleReader;
39 import java.lang.module.ModuleReference;
40 import java.lang.module.ModuleFinder;
41 import java.lang.module.ModuleDescriptor;
42 import java.lang.module.ModuleDescriptor.Exports;
43 import java.lang.module.ModuleDescriptor.Opens;
44 import java.lang.module.ModuleDescriptor.Provides;
45 import java.lang.module.ModuleDescriptor.Requires;
46 import java.lang.module.ModuleDescriptor.Version;
47 import java.lang.module.ResolutionException;
48 import java.lang.module.ResolvedModule;
49 import java.net.URI;
50 import java.nio.file.CopyOption;
51 import java.nio.file.FileSystems;
52 import java.nio.file.FileVisitOption;
53 import java.nio.file.FileVisitResult;
54 import java.nio.file.Files;
55 import java.nio.file.InvalidPathException;
56 import java.nio.file.Path;
57 import java.nio.file.PathMatcher;
58 import java.nio.file.Paths;
59 import java.nio.file.SimpleFileVisitor;
60 import java.nio.file.StandardCopyOption;
61 import java.nio.file.attribute.BasicFileAttributes;
62 import java.text.MessageFormat;
63 import java.util.ArrayDeque;
64 import java.util.ArrayList;
65 import java.util.Collection;
66 import java.util.Collections;
67 import java.util.Comparator;
68 import java.util.Deque;
69 import java.util.HashMap;
70 import java.util.HashSet;
137 }
138
139 private static final String PROGNAME = "jmod";
140 private static final String MODULE_INFO = "module-info.class";
141
142 private Options options;
143 private PrintWriter out = new PrintWriter(System.out, true);
144 void setLog(PrintWriter out, PrintWriter err) {
145 this.out = out;
146 }
147
148 /* Result codes. */
149 static final int EXIT_OK = 0, // Completed with no errors.
150 EXIT_ERROR = 1, // Completed but reported errors.
151 EXIT_CMDERR = 2, // Bad command-line arguments
152 EXIT_SYSERR = 3, // System error or resource exhaustion.
153 EXIT_ABNORMAL = 4;// terminated abnormally
154
155 enum Mode {
156 CREATE,
157 EXTRACT,
158 LIST,
159 DESCRIBE,
160 HASH
161 };
162
163 static class Options {
164 Mode mode;
165 Path jmodFile;
166 boolean help;
167 boolean version;
168 List<Path> classpath;
169 List<Path> cmds;
170 List<Path> configs;
171 List<Path> libs;
172 List<Path> headerFiles;
173 List<Path> manPages;
174 ModuleFinder moduleFinder;
175 Version moduleVersion;
176 String mainClass;
177 String osName;
187 try {
188 handleOptions(args);
189 if (options == null) {
190 showUsageSummary();
191 return EXIT_CMDERR;
192 }
193 if (options.help) {
194 showHelp();
195 return EXIT_OK;
196 }
197 if (options.version) {
198 showVersion();
199 return EXIT_OK;
200 }
201
202 boolean ok;
203 switch (options.mode) {
204 case CREATE:
205 ok = create();
206 break;
207 case EXTRACT:
208 ok = extract();
209 break;
210 case LIST:
211 ok = list();
212 break;
213 case DESCRIBE:
214 ok = describe();
215 break;
216 case HASH:
217 ok = hashModules();
218 break;
219 default:
220 throw new AssertionError("Unknown mode: " + options.mode.name());
221 }
222
223 return ok ? EXIT_OK : EXIT_ERROR;
224 } catch (CommandException e) {
225 reportError(e.getMessage());
226 if (e.showUsage)
227 showUsageSummary();
228 return EXIT_CMDERR;
229 } catch (Exception x) {
236 }
237
238 private boolean list() throws IOException {
239 ZipFile zip = null;
240 try {
241 try {
242 zip = new ZipFile(options.jmodFile.toFile());
243 } catch (IOException x) {
244 throw new IOException("error opening jmod file", x);
245 }
246
247 // Trivially print the archive entries for now, pending a more complete implementation
248 zip.stream().forEach(e -> out.println(e.getName()));
249 return true;
250 } finally {
251 if (zip != null)
252 zip.close();
253 }
254 }
255
256 private boolean extract() throws IOException {
257 try (JmodFile jf = new JmodFile(options.jmodFile)) {
258 jf.stream().forEach(e -> {
259 try {
260 ZipEntry entry = e.zipEntry();
261 String name = entry.getName();
262 int index = name.lastIndexOf("/");
263 if (index != -1) {
264 Path p = Paths.get(name.substring(0, index));
265 if (Files.notExists(p))
266 Files.createDirectories(p);
267 }
268
269 try (OutputStream os = Files.newOutputStream(Paths.get(name))) {
270 jf.getInputStream(e).transferTo(os);
271 }
272 } catch (IOException x) {
273 throw new UncheckedIOException(x);
274 }
275 });
276
277 return true;
278 }
279 }
280
281 private boolean hashModules() {
282 return new Hasher(options.moduleFinder).run();
283 }
284
285 private boolean describe() throws IOException {
286 try (JmodFile jf = new JmodFile(options.jmodFile)) {
287 try (InputStream in = jf.getInputStream(Section.CLASSES, MODULE_INFO)) {
288 ModuleDescriptor md = ModuleDescriptor.read(in);
289 printModuleDescriptor(md);
290 return true;
291 } catch (IOException e) {
292 throw new CommandException("err.module.descriptor.not.found");
293 }
294 }
295 }
296
297 static <T> String toString(Collection<T> c) {
298 if (c.isEmpty()) { return ""; }
299 return c.stream().map(e -> e.toString().toLowerCase(Locale.ROOT))
300 .collect(joining(" "));
1171 @Override
1172 public List<?> defaultValues() { return Collections.emptyList(); }
1173 @Override
1174 public boolean isRequired() { return false; }
1175 @Override
1176 public boolean acceptsArguments() { return false; }
1177 @Override
1178 public boolean requiresArgument() { return false; }
1179 @Override
1180 public String argumentDescription() { return null; }
1181 @Override
1182 public String argumentTypeIndicator() { return null; }
1183 @Override
1184 public boolean representsNonOptions() { return false; }
1185 });
1186 String content = super.format(all);
1187 StringBuilder builder = new StringBuilder();
1188
1189 builder.append(getMessage("main.opt.mode")).append("\n ");
1190 builder.append(getMessage("main.opt.mode.create")).append("\n ");
1191 builder.append(getMessage("main.opt.mode.extract")).append("\n ");
1192 builder.append(getMessage("main.opt.mode.list")).append("\n ");
1193 builder.append(getMessage("main.opt.mode.describe")).append("\n ");
1194 builder.append(getMessage("main.opt.mode.hash")).append("\n\n");
1195
1196 String cmdfile = null;
1197 String[] lines = content.split("\n");
1198 for (String line : lines) {
1199 if (line.startsWith("--@")) {
1200 cmdfile = line.replace("--" + CMD_FILENAME, CMD_FILENAME + " ");
1201 } else if (line.startsWith("Option") || line.startsWith("------")) {
1202 builder.append(" ").append(line).append("\n");
1203 } else if (!line.matches("Non-option arguments")){
1204 builder.append(" ").append(line).append("\n");
1205 }
1206 }
1207 if (cmdfile != null) {
1208 builder.append(" ").append(cmdfile).append("\n");
1209 }
1210 return builder.toString();
1211 }
|