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 org.openjdk.jigsaw.cli;
27
28 import java.lang.module.*;
29 import java.io.*;
30 import java.net.*;
31 import java.nio.file.Files;
32 import java.nio.file.Path;
33 import java.security.*;
34 import java.util.*;
35 import java.util.regex.*;
36
37 import static java.lang.System.out;
38 import static java.lang.System.err;
39
40 import org.openjdk.jigsaw.*;
41 import org.openjdk.jigsaw.SimpleLibrary.StorageOption;
42 import org.openjdk.internal.joptsimple.*;
43
44
45 public class Librarian {
46
47 private static JigsawModuleSystem jms
48 = JigsawModuleSystem.instance();
49
50 static class Create extends Command<SimpleLibrary> {
51 protected void go(SimpleLibrary lib)
52 throws Command.Exception
53 {
54 noDry();
55 finishArgs();
56 }
57 }
58
59 static class DumpClass extends Command<SimpleLibrary> {
60 protected void go(SimpleLibrary lib)
61 throws Command.Exception
62 {
63 noDry();
64 String mids = takeArg();
65 ModuleId mid = null;
66 try {
67 mid = jms.parseModuleId(mids);
68 } catch (IllegalArgumentException x) {
69 throw new Command.Exception(x.getMessage());
70 }
71 String cn = takeArg();
72 String ops = takeArg();
73 finishArgs();
74 byte[] bs = null;
75 try {
76 bs = lib.readClass(mid, cn);
77 if (bs == null)
78 throw new Command.Exception("%s: No such class in module %s",
102 noDry();
103 finishArgs();
104 out.format("path %s%n", lib.root());
105 out.format("version %d.%d%n",
106 lib.majorVersion(), lib.minorVersion());
107 SimpleLibrary plib = lib.parent();
108 while (plib != null) {
109 out.format("parent %s%n", plib.root());
110 plib = plib.parent();
111 }
112 }
113 }
114
115 static class Extract extends Command<SimpleLibrary> {
116 protected void go(SimpleLibrary lib)
117 throws Command.Exception
118 {
119 noDry();
120 while (hasArg()) {
121 File module = new File(takeArg());
122 File classes = null;
123 try (FileInputStream fis = new FileInputStream(module);
124 DataInputStream dis = new DataInputStream(fis);
125 ModuleFile.Reader reader = new ModuleFile.Reader(dis)) {
126
127 ModuleInfo mi = jms.parseModuleInfo(reader.readStart());
128 classes = new File(mi.id().name());
129 Path path = classes.toPath();
130 Files.deleteIfExists(path);
131 Files.createDirectory(path);
132 reader.readRest(classes, false);
133 }
134 catch (IOException x) {
135 // Try to cleanup if an exception is thrown
136 if (classes != null && classes.exists())
137 try {
138 FilePaths.deleteTree(classes.toPath());
139 }
140 catch (IOException y) {
141 throw (Command.Exception)
142 new Command.Exception(y).initCause(x);
143 }
144 throw new Command.Exception(x);
145 }
146 }
147 finishArgs();
148 }
149 }
150
151 static class Install extends Command<SimpleLibrary> {
152 protected void go(SimpleLibrary lib)
153 throws Command.Exception
154 {
155 String key = takeArg();
156 File kf = new File(key);
157 boolean verifySignature = !opts.has("noverify");
158 boolean strip = opts.has("G");
456 commands.put("config", Config.class);
457 commands.put("create", Create.class);
458 commands.put("del-repo", DelRepo.class);
459 commands.put("dump-class", DumpClass.class);
460 commands.put("dump-config", DumpConfig.class);
461 commands.put("extract", Extract.class);
462 commands.put("id", Identify.class);
463 commands.put("identify", Identify.class);
464 commands.put("install", Install.class);
465 commands.put("list", Commands.ListLibrary.class);
466 commands.put("ls", Commands.ListLibrary.class);
467 commands.put("preinstall", PreInstall.class);
468 commands.put("refresh", Refresh.class);
469 commands.put("reindex", ReIndex.class);
470 commands.put("repos", Repos.class);
471 }
472
473 private OptionParser parser;
474
475 private static OptionSpec<Integer> repoIndex; // ##
476
477 private void usage() {
478 out.format("%n");
479 out.format("usage: jmod add-repo [-i <index>] URL%n");
480 out.format(" jmod extract <module-file> ...%n");
481 out.format(" jmod config [<module-id> ...]%n");
482 out.format(" jmod create [-L <library>] [-P <parent>]%n");
483 out.format(" jmod del-repo URL%n");
484 out.format(" jmod dump-class <module-id> <class-name> <output-file>%n");
485 out.format(" jmod dump-config <module-id>%n");
486 out.format(" jmod identify%n");
487 out.format(" jmod install [--noverify] [-n] <module-id-query> ...%n");
488 out.format(" jmod install [--noverify] <module-file> ...%n");
489 out.format(" jmod install <classes-dir> <module-name> ...%n");
490 out.format(" jmod list [-v] [-p] [-R] [<module-id-query>]%n");
491 out.format(" jmod preinstall <classes-dir> <dst-dir> <module-name> ...%n");
492 out.format(" jmod refresh [-f] [-n] [-v]%n");
493 out.format(" jmod reindex [<module-id> ...]%n");
494 out.format(" jmod repos [-v]%n");
495 out.format("%n");
496 try {
497 parser.printHelpOn(out);
498 } catch (IOException x) {
499 throw new AssertionError(x);
500 }
501 out.format("%n");
502 System.exit(0);
503 }
504
505 public static void run(String [] args) throws OptionException, Command.Exception {
506 new Librarian().exec(args);
507 }
508
509 private void exec(String[] args) throws OptionException, Command.Exception {
510 parser = new OptionParser();
511
512 // ## Need subcommand-specific option parsing
513 OptionSpec<File> libPath
514 = (parser.acceptsAll(Arrays.asList("L", "library"),
515 "Module-library location"
516 + " (default $JAVA_MODULES)")
517 .withRequiredArg()
518 .describedAs("path")
519 .ofType(File.class));
520 OptionSpec<File> parentPath
521 = (parser.acceptsAll(Arrays.asList("P", "parent-path"),
522 "Parent module-library location")
523 .withRequiredArg()
524 .describedAs("path")
525 .ofType(File.class));
526 parser.acceptsAll(Arrays.asList("N", "no-parent"),
527 "Use no parent library when creating");
528 parser.acceptsAll(Arrays.asList("v", "verbose"),
529 "Enable verbose output");
530 parser.acceptsAll(Arrays.asList("h", "?", "help"),
531 "Show this help message");
532 parser.acceptsAll(Arrays.asList("p", "parent"),
533 "Apply operation to parent library, if any");
534 parser.acceptsAll(Arrays.asList("z", "enable-compression"),
535 "Enable compression of module contents");
536 repoIndex
537 = (parser.acceptsAll(Arrays.asList("i"),
538 "Repository-list index")
539 .withRequiredArg()
540 .describedAs("index")
541 .ofType(Integer.class));
542 parser.acceptsAll(Arrays.asList("f", "force"),
543 "Force the requested operation");
544 parser.acceptsAll(Arrays.asList("n", "dry-run"),
545 "Dry-run the requested operation");
546 parser.acceptsAll(Arrays.asList("R", "repos"),
547 "List contents of associated repositories");
548 parser.acceptsAll(Arrays.asList("noverify"),
549 "Do not verify module signatures. "
550 + "Treat as unsigned.");
551 parser.acceptsAll(Arrays.asList("G", "strip-debug"),
552 "Strip debug attributes during installation");
553
554 if (args.length == 0)
555 usage();
556
557 File homeLibrary = new File(System.getProperty("java.home"),
558 "lib/modules");
559
560 OptionSet opts = parser.parse(args);
561 if (opts.has("h"))
562 usage();
563 List<String> words = opts.nonOptionArguments();
564 if (words.isEmpty())
565 usage();
566 String verb = words.get(0);
567 Class<? extends Command<SimpleLibrary>> cmd = commands.get(verb);
568 if (cmd == null)
569 throw new Command.Exception("%s: unknown command", verb);
570 File lp = null;
571 if (opts.has(libPath)) {
572 lp = opts.valueOf(libPath);
573 } else {
574 String jm = System.getenv("JAVA_MODULES");
575 if (jm != null)
576 lp = new File(jm);
577 else
578 lp = homeLibrary;
579 }
580 File pp = null;
581 if (opts.has(parentPath)) {
582 pp = opts.valueOf(parentPath);
583 } else if (!opts.has("N")) {
584 pp = homeLibrary;
585 }
586 SimpleLibrary lib = null;
587 try {
588 if (verb.equals("create")) {
589 Set<StorageOption> createOpts = new HashSet<>();
590 if (opts.has("z"))
591 createOpts.add(StorageOption.DEFLATED);
592 lib = SimpleLibrary.create(lp, pp, createOpts);
593 } else {
594 lib = SimpleLibrary.open(lp);
595 }
596 } catch (FileNotFoundException x) {
597 String msg = null;
598 File f = new File(x.getMessage());
599 try {
600 f = f.getCanonicalFile();
601 if (lp.getCanonicalFile().equals(f))
602 msg = "No such library";
603 else
604 msg = "Cannot open parent library " + f;
605 } catch (IOException y) {
606 throw new Command.Exception(y);
607 }
608 throw new Command.Exception("%s: %s", lp, msg);
609 } catch (IOException x) {
610 throw new Command.Exception(x);
611 }
612 try {
613 cmd.newInstance().run(lib, opts);
614 } catch (InstantiationException x) {
615 throw new AssertionError(x);
616 } catch (IllegalAccessException x) {
617 throw new AssertionError(x);
618 }
619 }
620
621 private Librarian() { }
622
623 public static void main(String[] args) {
624 try {
625 run(args);
626 } catch (OptionException x) {
627 err.println(x.getMessage());
628 System.exit(1);
629 } catch (Command.Exception x) {
630 err.println(x.getMessage());
631 x.printStackTrace();
632 System.exit(1);
633 }
634 }
635
636 }
|
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 org.openjdk.jigsaw.cli;
27
28 import java.lang.module.*;
29 import java.io.*;
30 import java.net.*;
31 import java.nio.file.Files;
32 import java.nio.file.Path;
33 import java.security.*;
34 import java.util.*;
35
36 import static java.lang.System.out;
37 import static java.lang.System.err;
38
39 import org.openjdk.jigsaw.*;
40 import org.openjdk.jigsaw.SimpleLibrary.StorageOption;
41 import org.openjdk.internal.joptsimple.*;
42
43
44 public class Librarian {
45
46 private static JigsawModuleSystem jms
47 = JigsawModuleSystem.instance();
48
49 private static final File homeLibrary = Library.systemLibraryPath();
50
51 static class Create extends Command<SimpleLibrary> {
52 protected void go(SimpleLibrary lib)
53 throws Command.Exception
54 {
55 noDry();
56 finishArgs();
57 File lp = libPath(opts);
58 File pp = null;
59 if (opts.has(parentPath)) {
60 pp = opts.valueOf(parentPath);
61 } else if (!opts.has("N")) {
62 pp = homeLibrary;
63 }
64 File natlibs = null;
65 if (opts.has(nativeLibs)) {
66 natlibs = opts.valueOf(nativeLibs);
67 }
68 File natcmds = null;
69 if (opts.has(nativeCmds)) {
70 natcmds = opts.valueOf(nativeCmds);
71 }
72 File configs = null;
73 if (opts.has(configFiles)) {
74 configs = opts.valueOf(configFiles);
75 }
76
77 Set<StorageOption> createOpts = new HashSet<>();
78 if (opts.has("z"))
79 createOpts.add(StorageOption.DEFLATED);
80
81 try {
82 lib = SimpleLibrary.create(lp, pp, natlibs, natcmds,
83 configs, createOpts);
84 } catch (IOException x) {
85 throw new Command.Exception(x);
86 }
87 }
88 }
89
90 static class DumpClass extends Command<SimpleLibrary> {
91 protected void go(SimpleLibrary lib)
92 throws Command.Exception
93 {
94 noDry();
95 String mids = takeArg();
96 ModuleId mid = null;
97 try {
98 mid = jms.parseModuleId(mids);
99 } catch (IllegalArgumentException x) {
100 throw new Command.Exception(x.getMessage());
101 }
102 String cn = takeArg();
103 String ops = takeArg();
104 finishArgs();
105 byte[] bs = null;
106 try {
107 bs = lib.readClass(mid, cn);
108 if (bs == null)
109 throw new Command.Exception("%s: No such class in module %s",
133 noDry();
134 finishArgs();
135 out.format("path %s%n", lib.root());
136 out.format("version %d.%d%n",
137 lib.majorVersion(), lib.minorVersion());
138 SimpleLibrary plib = lib.parent();
139 while (plib != null) {
140 out.format("parent %s%n", plib.root());
141 plib = plib.parent();
142 }
143 }
144 }
145
146 static class Extract extends Command<SimpleLibrary> {
147 protected void go(SimpleLibrary lib)
148 throws Command.Exception
149 {
150 noDry();
151 while (hasArg()) {
152 File module = new File(takeArg());
153 File destination = null;
154 try (FileInputStream fis = new FileInputStream(module);
155 DataInputStream dis = new DataInputStream(fis);
156 ModuleFile.Reader reader = new ModuleFile.Reader(dis)) {
157
158 ModuleInfo mi = jms.parseModuleInfo(reader.readStart());
159 destination = new File(mi.id().name());
160 Path path = destination.toPath();
161 Files.deleteIfExists(path);
162 Files.createDirectory(path);
163 reader.readRest(destination, false);
164 }
165 catch (IOException x) {
166 // Try to cleanup if an exception is thrown
167 if (destination != null && destination.exists())
168 try {
169 FilePaths.deleteTree(destination.toPath());
170 }
171 catch (IOException y) {
172 throw (Command.Exception)
173 new Command.Exception(y).initCause(x);
174 }
175 throw new Command.Exception(x);
176 }
177 }
178 finishArgs();
179 }
180 }
181
182 static class Install extends Command<SimpleLibrary> {
183 protected void go(SimpleLibrary lib)
184 throws Command.Exception
185 {
186 String key = takeArg();
187 File kf = new File(key);
188 boolean verifySignature = !opts.has("noverify");
189 boolean strip = opts.has("G");
487 commands.put("config", Config.class);
488 commands.put("create", Create.class);
489 commands.put("del-repo", DelRepo.class);
490 commands.put("dump-class", DumpClass.class);
491 commands.put("dump-config", DumpConfig.class);
492 commands.put("extract", Extract.class);
493 commands.put("id", Identify.class);
494 commands.put("identify", Identify.class);
495 commands.put("install", Install.class);
496 commands.put("list", Commands.ListLibrary.class);
497 commands.put("ls", Commands.ListLibrary.class);
498 commands.put("preinstall", PreInstall.class);
499 commands.put("refresh", Refresh.class);
500 commands.put("reindex", ReIndex.class);
501 commands.put("repos", Repos.class);
502 }
503
504 private OptionParser parser;
505
506 private static OptionSpec<Integer> repoIndex; // ##
507 private static OptionSpec<File> libPath;
508 private static OptionSpec<File> parentPath;
509 private static OptionSpec<File> nativeLibs;
510 private static OptionSpec<File> nativeCmds;
511 private static OptionSpec<File> configFiles;
512
513 private void usage() {
514 out.format("%n");
515 out.format("usage: jmod add-repo [-i <index>] URL%n");
516 out.format(" jmod extract <module-file> ...%n");
517 out.format(" jmod config [<module-id> ...]%n");
518 out.format(" jmod create [-L <library>] [-P <parent>]" +
519 " [--natlib <natlib>] [--natcmd <natcmd>] [--config <config>]%n");
520 out.format(" jmod del-repo URL%n");
521 out.format(" jmod dump-class <module-id> <class-name> <output-file>%n");
522 out.format(" jmod dump-config <module-id>%n");
523 out.format(" jmod identify%n");
524 out.format(" jmod install [--noverify] [-n] <module-id-query> ...%n");
525 out.format(" jmod install [--noverify] <module-file> ...%n");
526 out.format(" jmod install <classes-dir> <module-name> ...%n");
527 out.format(" jmod list [-v] [-p] [-R] [<module-id-query>]%n");
528 out.format(" jmod preinstall <classes-dir> <dst-dir> <module-name> ...%n");
529 out.format(" jmod refresh [-f] [-n] [-v]%n");
530 out.format(" jmod reindex [<module-id> ...]%n");
531 out.format(" jmod repos [-v]%n");
532 out.format("%n");
533 try {
534 parser.printHelpOn(out);
535 } catch (IOException x) {
536 throw new AssertionError(x);
537 }
538 out.format("%n");
539 System.exit(0);
540 }
541
542 public static void run(String [] args) throws OptionException, Command.Exception {
543 new Librarian().exec(args);
544 }
545
546 private void exec(String[] args) throws OptionException, Command.Exception {
547 parser = new OptionParser();
548
549 // ## Need subcommand-specific option parsing
550 libPath
551 = (parser.acceptsAll(Arrays.asList("L", "library"),
552 "Module-library location"
553 + " (default $JAVA_MODULES)")
554 .withRequiredArg()
555 .describedAs("path")
556 .ofType(File.class));
557 parentPath
558 = (parser.acceptsAll(Arrays.asList("P", "parent-path"),
559 "Parent module-library location")
560 .withRequiredArg()
561 .describedAs("path")
562 .ofType(File.class));
563 nativeLibs
564 = (parser.accepts("natlib", "Directory to store native libs")
565 .withRequiredArg()
566 .describedAs("dir")
567 .ofType(File.class));
568 nativeCmds
569 = (parser.accepts("natcmd", "Directory to store native launchers")
570 .withRequiredArg()
571 .describedAs("dir")
572 .ofType(File.class));
573 configFiles
574 = (parser.accepts("config", "Directory to store config files")
575 .withRequiredArg()
576 .describedAs("dir")
577 .ofType(File.class));
578 parser.acceptsAll(Arrays.asList("N", "no-parent"),
579 "Use no parent library when creating");
580 parser.acceptsAll(Arrays.asList("v", "verbose"),
581 "Enable verbose output");
582 parser.acceptsAll(Arrays.asList("h", "?", "help"),
583 "Show this help message");
584 parser.acceptsAll(Arrays.asList("p", "parent"),
585 "Apply operation to parent library, if any");
586 parser.acceptsAll(Arrays.asList("z", "enable-compression"),
587 "Enable compression of module contents");
588 repoIndex
589 = (parser.acceptsAll(Arrays.asList("i"),
590 "Repository-list index")
591 .withRequiredArg()
592 .describedAs("index")
593 .ofType(Integer.class));
594 parser.acceptsAll(Arrays.asList("f", "force"),
595 "Force the requested operation");
596 parser.acceptsAll(Arrays.asList("n", "dry-run"),
597 "Dry-run the requested operation");
598 parser.acceptsAll(Arrays.asList("R", "repos"),
599 "List contents of associated repositories");
600 parser.acceptsAll(Arrays.asList("noverify"),
601 "Do not verify module signatures. "
602 + "Treat as unsigned.");
603 parser.acceptsAll(Arrays.asList("G", "strip-debug"),
604 "Strip debug attributes during installation");
605
606 if (args.length == 0)
607 usage();
608
609 OptionSet opts = parser.parse(args);
610 if (opts.has("h"))
611 usage();
612 List<String> words = opts.nonOptionArguments();
613 if (words.isEmpty())
614 usage();
615 String verb = words.get(0);
616 Class<? extends Command<SimpleLibrary>> cmd = commands.get(verb);
617 if (cmd == null)
618 throw new Command.Exception("%s: unknown command", verb);
619
620 // Every command, except 'create' and 'extract', needs
621 // to have a valid reference to the library
622 SimpleLibrary lib = null;
623 if (!(verb.equals("create") || verb.equals("extract"))) {
624 File lp = libPath(opts);
625 try {
626 lib = SimpleLibrary.open(lp);
627 } catch (FileNotFoundException x) {
628 String msg = null;
629 File f = new File(x.getMessage());
630 try {
631 f = f.getCanonicalFile();
632 if (lp.getCanonicalFile().equals(f))
633 msg = "No such library";
634 else
635 msg = "Cannot open parent library " + f;
636 } catch (IOException y) {
637 throw new Command.Exception(y);
638 }
639 throw new Command.Exception("%s: %s", lp, msg);
640 } catch (IOException x) {
641 throw new Command.Exception(x);
642 }
643 }
644 try {
645 cmd.newInstance().run(lib, opts);
646 } catch (InstantiationException x) {
647 throw new AssertionError(x);
648 } catch (IllegalAccessException x) {
649 throw new AssertionError(x);
650 }
651 }
652
653 private static File libPath(OptionSet opts) {
654 if (opts.has(libPath)) {
655 return opts.valueOf(libPath);
656 } else {
657 String jm = System.getenv("JAVA_MODULES");
658 if (jm != null)
659 return new File(jm);
660 else
661 return homeLibrary;
662 }
663 }
664
665 private Librarian() { }
666
667 public static void main(String[] args) {
668 try {
669 run(args);
670 } catch (OptionException x) {
671 err.println(x.getMessage());
672 System.exit(1);
673 } catch (Command.Exception x) {
674 err.println(x.getMessage());
675 x.printStackTrace();
676 System.exit(1);
677 }
678 }
679
680 }
|