< prev index next >

src/jdk.jlink/share/classes/jdk/tools/jmod/JmodTask.java

Print this page

        

@@ -136,10 +136,12 @@
     }
 
     private static final String PROGNAME = "jmod";
     private static final String MODULE_INFO = "module-info.class";
 
+    private static final Path CWD = Paths.get("");
+
     private Options options;
     private PrintWriter out = new PrintWriter(System.out, true);
     void setLog(PrintWriter out, PrintWriter err) {
         this.out = out;
     }

@@ -151,10 +153,11 @@
                      EXIT_SYSERR = 3, // System error or resource exhaustion.
                      EXIT_ABNORMAL = 4;// terminated abnormally
 
     enum Mode {
         CREATE,
+        EXTRACT,
         LIST,
         DESCRIBE,
         HASH
     };
 

@@ -176,10 +179,11 @@
         String osArch;
         String osVersion;
         Pattern modulesToHash;
         boolean dryrun;
         List<PathMatcher> excludes;
+        Path extractDir;
     }
 
     public int run(String[] args) {
 
         try {

@@ -200,10 +204,13 @@
             boolean ok;
             switch (options.mode) {
                 case CREATE:
                     ok = create();
                     break;
+                case EXTRACT:
+                    ok = extract();
+                    break;
                 case LIST:
                     ok = list();
                     break;
                 case DESCRIBE:
                     ok = describe();

@@ -246,10 +253,36 @@
             if (zip != null)
                 zip.close();
         }
     }
 
+    private boolean extract() throws IOException {
+        Path dir = options.extractDir != null ? options.extractDir : CWD;
+        try (JmodFile jf = new JmodFile(options.jmodFile)) {
+            jf.stream().forEach(e -> {
+                try {
+                    ZipEntry entry = e.zipEntry();
+                    String name = entry.getName();
+                    int index = name.lastIndexOf("/");
+                    if (index != -1) {
+                        Path p = dir.resolve(name.substring(0, index));
+                        if (Files.notExists(p))
+                            Files.createDirectories(p);
+                    }
+
+                    try (OutputStream os = Files.newOutputStream(dir.resolve(name))) {
+                        jf.getInputStream(e).transferTo(os);
+                    }
+                } catch (IOException x) {
+                    throw new UncheckedIOException(x);
+                }
+            });
+
+            return true;
+        }
+    }
+
     private boolean hashModules() {
         return new Hasher(options.moduleFinder).run();
     }
 
     private boolean describe() throws IOException {

@@ -1017,12 +1050,10 @@
     }
 
     static class ClassPathConverter implements ValueConverter<Path> {
         static final ValueConverter<Path> INSTANCE = new ClassPathConverter();
 
-        private static final Path CWD = Paths.get("");
-
         @Override
         public Path convert(String value) {
             try {
                 Path path = CWD.resolve(value);
                 if (Files.notExists(path))

@@ -1042,12 +1073,10 @@
     }
 
     static class DirPathConverter implements ValueConverter<Path> {
         static final ValueConverter<Path> INSTANCE = new DirPathConverter();
 
-        private static final Path CWD = Paths.get("");
-
         @Override
         public Path convert(String value) {
             try {
                 Path path = CWD.resolve(value);
                 if (Files.notExists(path))

@@ -1063,10 +1092,37 @@
         @Override  public Class<Path> valueType() { return Path.class; }
 
         @Override  public String valuePattern() { return "path"; }
     }
 
+    static class ExtractDirPathConverter implements ValueConverter<Path> {
+
+        @Override
+        public Path convert(String value) {
+            try {
+                Path path = CWD.resolve(value);
+                if (Files.exists(path)) {
+                    if (!Files.isDirectory(path))
+                        throw new CommandException("err.cannot.create.dir", path);
+                } else {
+                    try {
+                        Files.createDirectories(path);
+                    } catch (IOException ioe) {
+                        throw new CommandException("err.cannot.create.dir", path);
+                    }
+                }
+                return path;
+            } catch (InvalidPathException x) {
+                throw new CommandException("err.path.not.valid", value);
+            }
+        }
+
+        @Override  public Class<Path> valueType() { return Path.class; }
+
+        @Override  public String valuePattern() { return "path"; }
+    }
+
     static class ModuleVersionConverter implements ValueConverter<Version> {
         @Override
         public Version convert(String value) {
             try {
                 return Version.parse(value);

@@ -1156,10 +1212,11 @@
             String content = super.format(all);
             StringBuilder builder = new StringBuilder();
 
             builder.append(getMessage("main.opt.mode")).append("\n  ");
             builder.append(getMessage("main.opt.mode.create")).append("\n  ");
+            builder.append(getMessage("main.opt.mode.extract")).append("\n  ");
             builder.append(getMessage("main.opt.mode.list")).append("\n  ");
             builder.append(getMessage("main.opt.mode.describe")).append("\n  ");
             builder.append(getMessage("main.opt.mode.hash")).append("\n\n");
 
             String cmdfile = null;

@@ -1201,10 +1258,15 @@
                 = parser.accepts("config", getMessage("main.opt.config"))
                         .withRequiredArg()
                         .withValuesSeparatedBy(File.pathSeparatorChar)
                         .withValuesConvertedBy(DirPathConverter.INSTANCE);
 
+        OptionSpec<Path> dir
+                = parser.accepts("dir", getMessage("main.opt.extractDir"))
+                        .withRequiredArg()
+                        .withValuesConvertedBy(new ExtractDirPathConverter());
+
         OptionSpec<Void> dryrun
             = parser.accepts("dry-run", getMessage("main.opt.dry-run"));
 
         OptionSpec<PathMatcher> excludes
                 = parser.accepts("exclude", getMessage("main.opt.exclude"))

@@ -1301,10 +1363,12 @@
                 options.classpath = opts.valuesOf(classPath);
             if (opts.has(cmds))
                 options.cmds = opts.valuesOf(cmds);
             if (opts.has(config))
                 options.configs = opts.valuesOf(config);
+            if (opts.has(dir))
+                options.extractDir = opts.valueOf(dir);
             if (opts.has(dryrun))
                 options.dryrun = true;
             if (opts.has(excludes))
                 options.excludes = opts.valuesOf(excludes);
             if (opts.has(libs))

@@ -1345,11 +1409,12 @@
                 Path path = Paths.get(words.get(1));
 
                 if (options.mode.equals(Mode.CREATE) && Files.exists(path))
                     throw new CommandException("err.file.already.exists", path);
                 else if ((options.mode.equals(Mode.LIST) ||
-                            options.mode.equals(Mode.DESCRIBE))
+                            options.mode.equals(Mode.DESCRIBE) ||
+                            options.mode.equals((Mode.EXTRACT)))
                          && Files.notExists(path))
                     throw new CommandException("err.jmod.not.found", path);
 
                 if (options.dryrun) {
                     throw new CommandException("err.invalid.dryrun.option");
< prev index next >