< 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 >