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