src/jdk.jlink/share/classes/jdk/tools/jmod/JmodTask.java
author chegar
Sat, 03 Mar 2018 20:21:35 +0000
branchhttp-client-branch
changeset 56235 6218673d7fa0
parent 48543 7067fe4e054e
child 50130 aefd3c7f5373
permissions -rw-r--r--
http-client-branch: 100-Continue 100-Continue
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
     1
/*
48543
7067fe4e054e 8189102: All tools should support -?, -h and --help
goetz
parents: 47216
diff changeset
     2
 * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
     4
 *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    10
 *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    15
 * accompanied this code).
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    16
 *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    20
 *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    23
 * questions.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    24
 */
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    25
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    26
package jdk.tools.jmod;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    27
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    28
import java.io.ByteArrayInputStream;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    29
import java.io.ByteArrayOutputStream;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    30
import java.io.File;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    31
import java.io.IOException;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    32
import java.io.InputStream;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    33
import java.io.OutputStream;
41484
834b7539ada3 8164689: Retrofit jar, jlink, jmod as a ToolProvider
mchung
parents: 41352
diff changeset
    34
import java.io.PrintWriter;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    35
import java.io.UncheckedIOException;
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
    36
import java.lang.module.Configuration;
43712
5dfd0950317c 8173393: Module system implementation refresh (2/2017)
alanb
parents: 43242
diff changeset
    37
import java.lang.module.FindException;
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
    38
import java.lang.module.ModuleReader;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    39
import java.lang.module.ModuleReference;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    40
import java.lang.module.ModuleFinder;
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
    41
import java.lang.module.ModuleDescriptor;
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
    42
import java.lang.module.ModuleDescriptor.Exports;
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
    43
import java.lang.module.ModuleDescriptor.Opens;
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
    44
import java.lang.module.ModuleDescriptor.Provides;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    45
import java.lang.module.ModuleDescriptor.Requires;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    46
import java.lang.module.ModuleDescriptor.Version;
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
    47
import java.lang.module.ResolutionException;
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
    48
import java.lang.module.ResolvedModule;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    49
import java.net.URI;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    50
import java.nio.file.FileSystems;
41916
eb4aa81c6c5f 8166286: jmod fails on symlink to directory
sundar
parents: 41817
diff changeset
    51
import java.nio.file.FileVisitOption;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    52
import java.nio.file.FileVisitResult;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    53
import java.nio.file.Files;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    54
import java.nio.file.InvalidPathException;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    55
import java.nio.file.Path;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    56
import java.nio.file.PathMatcher;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    57
import java.nio.file.Paths;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    58
import java.nio.file.SimpleFileVisitor;
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
    59
import java.nio.file.StandardCopyOption;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    60
import java.nio.file.attribute.BasicFileAttributes;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    61
import java.text.MessageFormat;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    62
import java.util.ArrayList;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    63
import java.util.Collection;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    64
import java.util.Collections;
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
    65
import java.util.Comparator;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    66
import java.util.HashSet;
42703
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
    67
import java.util.LinkedHashMap;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    68
import java.util.List;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    69
import java.util.Locale;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    70
import java.util.Map;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    71
import java.util.MissingResourceException;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    72
import java.util.Optional;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    73
import java.util.ResourceBundle;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    74
import java.util.Set;
42922
9111fb672357 8170618: jmod should validate if any exported or open package is missing
sundar
parents: 42704
diff changeset
    75
import java.util.TreeSet;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    76
import java.util.function.Consumer;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    77
import java.util.function.Predicate;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    78
import java.util.function.Supplier;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    79
import java.util.jar.JarEntry;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    80
import java.util.jar.JarFile;
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
    81
import java.util.jar.JarOutputStream;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    82
import java.util.stream.Collectors;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    83
import java.util.regex.Pattern;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    84
import java.util.regex.PatternSyntaxException;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    85
import java.util.zip.ZipEntry;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    86
import java.util.zip.ZipException;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    87
import java.util.zip.ZipFile;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    88
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
    89
import jdk.internal.jmod.JmodFile;
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
    90
import jdk.internal.jmod.JmodFile.Section;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    91
import jdk.internal.joptsimple.BuiltinHelpFormatter;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    92
import jdk.internal.joptsimple.NonOptionArgumentSpec;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    93
import jdk.internal.joptsimple.OptionDescriptor;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    94
import jdk.internal.joptsimple.OptionException;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    95
import jdk.internal.joptsimple.OptionParser;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    96
import jdk.internal.joptsimple.OptionSet;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    97
import jdk.internal.joptsimple.OptionSpec;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    98
import jdk.internal.joptsimple.ValueConverter;
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
    99
import jdk.internal.module.ModuleHashes;
43109
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   100
import jdk.internal.module.ModuleHashesBuilder;
42703
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
   101
import jdk.internal.module.ModuleInfo;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   102
import jdk.internal.module.ModuleInfoExtender;
42703
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
   103
import jdk.internal.module.ModulePath;
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
   104
import jdk.internal.module.ModuleResolution;
44359
c6761862ca0b 8174823: Module system implementation refresh (3/2017)
alanb
parents: 43712
diff changeset
   105
import jdk.internal.module.ModuleTarget;
c6761862ca0b 8174823: Module system implementation refresh (3/2017)
alanb
parents: 43712
diff changeset
   106
import jdk.internal.module.Resources;
39042
52db877f18db 8159206: All jlink or jmod tests failing
jlaskey
parents: 38871
diff changeset
   107
import jdk.tools.jlink.internal.Utils;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   108
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   109
import static java.util.stream.Collectors.joining;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   110
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   111
/**
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   112
 * Implementation for the jmod tool.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   113
 */
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   114
public class JmodTask {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   115
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   116
    static class CommandException extends RuntimeException {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   117
        private static final long serialVersionUID = 0L;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   118
        boolean showUsage;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   119
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   120
        CommandException(String key, Object... args) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   121
            super(getMessageOrKey(key, args));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   122
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   123
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   124
        CommandException showUsage(boolean b) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   125
            showUsage = b;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   126
            return this;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   127
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   128
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   129
        private static String getMessageOrKey(String key, Object... args) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   130
            try {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   131
                return MessageFormat.format(ResourceBundleHelper.bundle.getString(key), args);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   132
            } catch (MissingResourceException e) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   133
                return key;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   134
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   135
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   136
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   137
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   138
    private static final String PROGNAME = "jmod";
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   139
    private static final String MODULE_INFO = "module-info.class";
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   140
42468
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
   141
    private static final Path CWD = Paths.get("");
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
   142
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   143
    private Options options;
41484
834b7539ada3 8164689: Retrofit jar, jlink, jmod as a ToolProvider
mchung
parents: 41352
diff changeset
   144
    private PrintWriter out = new PrintWriter(System.out, true);
834b7539ada3 8164689: Retrofit jar, jlink, jmod as a ToolProvider
mchung
parents: 41352
diff changeset
   145
    void setLog(PrintWriter out, PrintWriter err) {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   146
        this.out = out;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   147
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   148
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   149
    /* Result codes. */
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   150
    static final int EXIT_OK = 0, // Completed with no errors.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   151
                     EXIT_ERROR = 1, // Completed but reported errors.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   152
                     EXIT_CMDERR = 2, // Bad command-line arguments
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   153
                     EXIT_SYSERR = 3, // System error or resource exhaustion.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   154
                     EXIT_ABNORMAL = 4;// terminated abnormally
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   155
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   156
    enum Mode {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   157
        CREATE,
42468
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
   158
        EXTRACT,
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   159
        LIST,
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   160
        DESCRIBE,
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   161
        HASH
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   162
    };
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   163
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   164
    static class Options {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   165
        Mode mode;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   166
        Path jmodFile;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   167
        boolean help;
42703
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
   168
        boolean helpExtra;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   169
        boolean version;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   170
        List<Path> classpath;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   171
        List<Path> cmds;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   172
        List<Path> configs;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   173
        List<Path> libs;
41561
0c6942d13f2e 8167558: Add new JMOD section for header files and man pages
mchung
parents: 41484
diff changeset
   174
        List<Path> headerFiles;
0c6942d13f2e 8167558: Add new JMOD section for header files and man pages
mchung
parents: 41484
diff changeset
   175
        List<Path> manPages;
42670
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
   176
        List<Path> legalNotices;;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   177
        ModuleFinder moduleFinder;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   178
        Version moduleVersion;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   179
        String mainClass;
45004
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   180
        String targetPlatform;
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   181
        Pattern modulesToHash;
42703
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
   182
        ModuleResolution moduleResolution;
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   183
        boolean dryrun;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   184
        List<PathMatcher> excludes;
42468
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
   185
        Path extractDir;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   186
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   187
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   188
    public int run(String[] args) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   189
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   190
        try {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   191
            handleOptions(args);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   192
            if (options == null) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   193
                showUsageSummary();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   194
                return EXIT_CMDERR;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   195
            }
42703
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
   196
            if (options.help || options.helpExtra) {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   197
                showHelp();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   198
                return EXIT_OK;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   199
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   200
            if (options.version) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   201
                showVersion();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   202
                return EXIT_OK;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   203
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   204
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   205
            boolean ok;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   206
            switch (options.mode) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   207
                case CREATE:
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   208
                    ok = create();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   209
                    break;
42468
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
   210
                case EXTRACT:
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
   211
                    ok = extract();
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
   212
                    break;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   213
                case LIST:
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   214
                    ok = list();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   215
                    break;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   216
                case DESCRIBE:
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   217
                    ok = describe();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   218
                    break;
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   219
                case HASH:
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   220
                    ok = hashModules();
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   221
                    break;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   222
                default:
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   223
                    throw new AssertionError("Unknown mode: " + options.mode.name());
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   224
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   225
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   226
            return ok ? EXIT_OK : EXIT_ERROR;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   227
        } catch (CommandException e) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   228
            reportError(e.getMessage());
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   229
            if (e.showUsage)
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   230
                showUsageSummary();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   231
            return EXIT_CMDERR;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   232
        } catch (Exception x) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   233
            reportError(x.getMessage());
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   234
            x.printStackTrace();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   235
            return EXIT_ABNORMAL;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   236
        } finally {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   237
            out.flush();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   238
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   239
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   240
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   241
    private boolean list() throws IOException {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   242
        ZipFile zip = null;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   243
        try {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   244
            try {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   245
                zip = new ZipFile(options.jmodFile.toFile());
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   246
            } catch (IOException x) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   247
                throw new IOException("error opening jmod file", x);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   248
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   249
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   250
            // Trivially print the archive entries for now, pending a more complete implementation
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   251
            zip.stream().forEach(e -> out.println(e.getName()));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   252
            return true;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   253
        } finally {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   254
            if (zip != null)
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   255
                zip.close();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   256
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   257
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   258
42468
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
   259
    private boolean extract() throws IOException {
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
   260
        Path dir = options.extractDir != null ? options.extractDir : CWD;
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
   261
        try (JmodFile jf = new JmodFile(options.jmodFile)) {
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
   262
            jf.stream().forEach(e -> {
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
   263
                try {
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
   264
                    ZipEntry entry = e.zipEntry();
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
   265
                    String name = entry.getName();
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
   266
                    int index = name.lastIndexOf("/");
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
   267
                    if (index != -1) {
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
   268
                        Path p = dir.resolve(name.substring(0, index));
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
   269
                        if (Files.notExists(p))
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
   270
                            Files.createDirectories(p);
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
   271
                    }
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
   272
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
   273
                    try (OutputStream os = Files.newOutputStream(dir.resolve(name))) {
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
   274
                        jf.getInputStream(e).transferTo(os);
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
   275
                    }
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
   276
                } catch (IOException x) {
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
   277
                    throw new UncheckedIOException(x);
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
   278
                }
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
   279
            });
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
   280
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
   281
            return true;
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
   282
        }
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
   283
    }
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
   284
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   285
    private boolean hashModules() {
43109
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   286
        if (options.dryrun) {
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   287
            out.println("Dry run:");
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   288
        }
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   289
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   290
        Hasher hasher = new Hasher(options.moduleFinder);
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   291
        hasher.computeHashes().forEach((mn, hashes) -> {
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   292
            if (options.dryrun) {
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   293
                out.format("%s%n", mn);
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   294
                hashes.names().stream()
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   295
                    .sorted()
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   296
                    .forEach(name -> out.format("  hashes %s %s %s%n",
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   297
                        name, hashes.algorithm(), toHex(hashes.hashFor(name))));
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   298
            } else {
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   299
                try {
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   300
                    hasher.updateModuleInfo(mn, hashes);
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   301
                } catch (IOException ex) {
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   302
                    throw new UncheckedIOException(ex);
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   303
                }
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   304
            }
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   305
        });
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   306
        return true;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   307
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   308
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   309
    private boolean describe() throws IOException {
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   310
        try (JmodFile jf = new JmodFile(options.jmodFile)) {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   311
            try (InputStream in = jf.getInputStream(Section.CLASSES, MODULE_INFO)) {
42703
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
   312
                ModuleInfo.Attributes attrs = ModuleInfo.read(in, null);
45004
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   313
                describeModule(attrs.descriptor(),
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   314
                               attrs.target(),
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   315
                               attrs.recordedHashes());
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   316
                return true;
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   317
            } catch (IOException e) {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   318
                throw new CommandException("err.module.descriptor.not.found");
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   319
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   320
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   321
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   322
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   323
    static <T> String toString(Collection<T> c) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   324
        if (c.isEmpty()) { return ""; }
45004
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   325
        return " " + c.stream().map(e -> e.toString().toLowerCase(Locale.ROOT))
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   326
                .sorted().collect(joining(" "));
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   327
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   328
45004
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   329
    private void describeModule(ModuleDescriptor md,
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   330
                                ModuleTarget target,
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   331
                                ModuleHashes hashes)
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   332
        throws IOException
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   333
    {
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   334
        StringBuilder sb = new StringBuilder();
45004
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   335
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   336
        sb.append(md.toNameAndVersion());
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   337
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   338
        if (md.isOpen())
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   339
            sb.append(" open");
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   340
        if (md.isAutomatic())
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   341
            sb.append(" automatic");
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   342
        sb.append("\n");
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   343
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   344
        // unqualified exports (sorted by package)
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   345
        md.exports().stream()
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   346
                .sorted(Comparator.comparing(Exports::source))
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   347
                .filter(e -> !e.isQualified())
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   348
                .forEach(e -> sb.append("exports ").append(e.source())
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   349
                                .append(toString(e.modifiers())).append("\n"));
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   350
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   351
        // dependences
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   352
        md.requires().stream().sorted()
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   353
                .forEach(r -> sb.append("requires ").append(r.name())
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   354
                                .append(toString(r.modifiers())).append("\n"));
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   355
45004
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   356
        // service use and provides
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   357
        md.uses().stream().sorted()
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   358
                .forEach(s -> sb.append("uses ").append(s).append("\n"));
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   359
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   360
        md.provides().stream()
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   361
                .sorted(Comparator.comparing(Provides::service))
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   362
                .forEach(p -> sb.append("provides ").append(p.service())
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   363
                                .append(" with")
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   364
                                .append(toString(p.providers()))
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   365
                                .append("\n"));
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   366
45004
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   367
        // qualified exports
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   368
        md.exports().stream()
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   369
                .sorted(Comparator.comparing(Exports::source))
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   370
                .filter(Exports::isQualified)
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   371
                .forEach(e -> sb.append("qualified exports ").append(e.source())
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   372
                                .append(" to").append(toString(e.targets()))
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   373
                                .append("\n"));
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   374
45004
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   375
        // open packages
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   376
        md.opens().stream()
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   377
                .sorted(Comparator.comparing(Opens::source))
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   378
                .filter(o -> !o.isQualified())
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   379
                .forEach(o -> sb.append("opens ").append(o.source())
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   380
                                 .append(toString(o.modifiers()))
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   381
                                 .append("\n"));
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   382
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   383
        md.opens().stream()
45004
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   384
                .sorted(Comparator.comparing(Opens::source))
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   385
                .filter(Opens::isQualified)
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   386
                .forEach(o -> sb.append("qualified opens ").append(o.source())
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   387
                                 .append(toString(o.modifiers()))
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   388
                                 .append(" to").append(toString(o.targets()))
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   389
                                 .append("\n"));
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   390
45004
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   391
        // non-exported/non-open packages
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   392
        Set<String> concealed = new TreeSet<>(md.packages());
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   393
        md.exports().stream().map(Exports::source).forEach(concealed::remove);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   394
        md.opens().stream().map(Opens::source).forEach(concealed::remove);
45004
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   395
        concealed.forEach(p -> sb.append("contains ").append(p).append("\n"));
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   396
45004
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   397
        md.mainClass().ifPresent(v -> sb.append("main-class ").append(v).append("\n"));
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   398
44359
c6761862ca0b 8174823: Module system implementation refresh (3/2017)
alanb
parents: 43712
diff changeset
   399
        if (target != null) {
45004
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   400
            String targetPlatform = target.targetPlatform();
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   401
            if (!targetPlatform.isEmpty())
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   402
                sb.append("platform ").append(targetPlatform).append("\n");
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   403
       }
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   404
45004
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   405
       if (hashes != null) {
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   406
           hashes.names().stream().sorted().forEach(
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   407
                   mod -> sb.append("hashes ").append(mod).append(" ")
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   408
                            .append(hashes.algorithm()).append(" ")
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   409
                            .append(toHex(hashes.hashFor(mod)))
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   410
                            .append("\n"));
42703
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
   411
        }
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   412
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   413
        out.println(sb.toString());
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   414
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   415
42703
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
   416
    private String toHex(byte[] ba) {
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
   417
        StringBuilder sb = new StringBuilder(ba.length);
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
   418
        for (byte b: ba) {
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
   419
            sb.append(String.format("%02x", b & 0xff));
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
   420
        }
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
   421
        return sb.toString();
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
   422
    }
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
   423
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   424
    private boolean create() throws IOException {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   425
        JmodFileWriter jmod = new JmodFileWriter();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   426
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   427
        // create jmod with temporary name to avoid it being examined
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   428
        // when scanning the module path
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   429
        Path target = options.jmodFile;
43242
6c33c81be927 8173096: jmod files are not world-readable
mchung
parents: 43109
diff changeset
   430
        Path tempTarget = jmodTempFilePath(target);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   431
        try {
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   432
            try (JmodOutputStream jos = JmodOutputStream.newOutputStream(tempTarget)) {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   433
                jmod.write(jos);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   434
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   435
            Files.move(tempTarget, target);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   436
        } catch (Exception e) {
43242
6c33c81be927 8173096: jmod files are not world-readable
mchung
parents: 43109
diff changeset
   437
            try {
6c33c81be927 8173096: jmod files are not world-readable
mchung
parents: 43109
diff changeset
   438
                Files.deleteIfExists(tempTarget);
6c33c81be927 8173096: jmod files are not world-readable
mchung
parents: 43109
diff changeset
   439
            } catch (IOException ioe) {
6c33c81be927 8173096: jmod files are not world-readable
mchung
parents: 43109
diff changeset
   440
                e.addSuppressed(ioe);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   441
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   442
            throw e;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   443
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   444
        return true;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   445
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   446
43242
6c33c81be927 8173096: jmod files are not world-readable
mchung
parents: 43109
diff changeset
   447
    /*
6c33c81be927 8173096: jmod files are not world-readable
mchung
parents: 43109
diff changeset
   448
     * Create a JMOD .tmp file for the given target JMOD file
6c33c81be927 8173096: jmod files are not world-readable
mchung
parents: 43109
diff changeset
   449
     */
6c33c81be927 8173096: jmod files are not world-readable
mchung
parents: 43109
diff changeset
   450
    private static Path jmodTempFilePath(Path target) throws IOException {
6c33c81be927 8173096: jmod files are not world-readable
mchung
parents: 43109
diff changeset
   451
        return target.resolveSibling("." + target.getFileName() + ".tmp");
6c33c81be927 8173096: jmod files are not world-readable
mchung
parents: 43109
diff changeset
   452
    }
6c33c81be927 8173096: jmod files are not world-readable
mchung
parents: 43109
diff changeset
   453
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   454
    private class JmodFileWriter {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   455
        final List<Path> cmds = options.cmds;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   456
        final List<Path> libs = options.libs;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   457
        final List<Path> configs = options.configs;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   458
        final List<Path> classpath = options.classpath;
41561
0c6942d13f2e 8167558: Add new JMOD section for header files and man pages
mchung
parents: 41484
diff changeset
   459
        final List<Path> headerFiles = options.headerFiles;
0c6942d13f2e 8167558: Add new JMOD section for header files and man pages
mchung
parents: 41484
diff changeset
   460
        final List<Path> manPages = options.manPages;
42670
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
   461
        final List<Path> legalNotices = options.legalNotices;
41561
0c6942d13f2e 8167558: Add new JMOD section for header files and man pages
mchung
parents: 41484
diff changeset
   462
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   463
        final Version moduleVersion = options.moduleVersion;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   464
        final String mainClass = options.mainClass;
45004
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   465
        final String targetPlatform = options.targetPlatform;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   466
        final List<PathMatcher> excludes = options.excludes;
42703
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
   467
        final ModuleResolution moduleResolution = options.moduleResolution;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   468
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   469
        JmodFileWriter() { }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   470
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   471
        /**
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   472
         * Writes the jmod to the given output stream.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   473
         */
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   474
        void write(JmodOutputStream out) throws IOException {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   475
            // module-info.class
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   476
            writeModuleInfo(out, findPackages(classpath));
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   477
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   478
            // classes
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   479
            processClasses(out, classpath);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   480
42670
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
   481
            processSection(out, Section.CONFIG, configs);
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
   482
            processSection(out, Section.HEADER_FILES, headerFiles);
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
   483
            processSection(out, Section.LEGAL_NOTICES, legalNotices);
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
   484
            processSection(out, Section.MAN_PAGES, manPages);
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   485
            processSection(out, Section.NATIVE_CMDS, cmds);
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   486
            processSection(out, Section.NATIVE_LIBS, libs);
41561
0c6942d13f2e 8167558: Add new JMOD section for header files and man pages
mchung
parents: 41484
diff changeset
   487
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   488
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   489
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   490
        /**
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   491
         * Returns a supplier of an input stream to the module-info.class
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   492
         * on the class path of directories and JAR files.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   493
         */
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   494
        Supplier<InputStream> newModuleInfoSupplier() throws IOException {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   495
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   496
            for (Path e: classpath) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   497
                if (Files.isDirectory(e)) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   498
                    Path mi = e.resolve(MODULE_INFO);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   499
                    if (Files.isRegularFile(mi)) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   500
                        Files.copy(mi, baos);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   501
                        break;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   502
                    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   503
                } else if (Files.isRegularFile(e) && e.toString().endsWith(".jar")) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   504
                    try (JarFile jf = new JarFile(e.toFile())) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   505
                        ZipEntry entry = jf.getEntry(MODULE_INFO);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   506
                        if (entry != null) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   507
                            jf.getInputStream(entry).transferTo(baos);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   508
                            break;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   509
                        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   510
                    } catch (ZipException x) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   511
                        // Skip. Do nothing. No packages will be added.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   512
                    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   513
                }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   514
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   515
            if (baos.size() == 0) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   516
                return null;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   517
            } else {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   518
                byte[] bytes = baos.toByteArray();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   519
                return () -> new ByteArrayInputStream(bytes);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   520
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   521
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   522
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   523
        /**
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   524
         * Writes the updated module-info.class to the ZIP output stream.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   525
         *
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   526
         * The updated module-info.class will have a Packages attribute
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   527
         * with the set of module-private/non-exported packages.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   528
         *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   529
         * If --module-version, --main-class, or other options were provided
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   530
         * then the corresponding class file attributes are added to the
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   531
         * module-info here.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   532
         */
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   533
        void writeModuleInfo(JmodOutputStream out, Set<String> packages)
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   534
            throws IOException
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   535
        {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   536
            Supplier<InputStream> miSupplier = newModuleInfoSupplier();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   537
            if (miSupplier == null) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   538
                throw new IOException(MODULE_INFO + " not found");
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   539
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   540
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   541
            ModuleDescriptor descriptor;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   542
            try (InputStream in = miSupplier.get()) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   543
                descriptor = ModuleDescriptor.read(in);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   544
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   545
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   546
            // copy the module-info.class into the jmod with the additional
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   547
            // attributes for the version, main class and other meta data
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   548
            try (InputStream in = miSupplier.get()) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   549
                ModuleInfoExtender extender = ModuleInfoExtender.newExtender(in);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   550
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   551
                // Add (or replace) the Packages attribute
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   552
                if (packages != null) {
42922
9111fb672357 8170618: jmod should validate if any exported or open package is missing
sundar
parents: 42704
diff changeset
   553
                    validatePackages(descriptor, packages);
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   554
                    extender.packages(packages);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   555
                }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   556
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   557
                // --main-class
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   558
                if (mainClass != null)
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   559
                    extender.mainClass(mainClass);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   560
45004
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   561
                // --target-platform
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   562
                if (targetPlatform != null) {
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   563
                    extender.targetPlatform(targetPlatform);
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   564
                }
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   565
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   566
                // --module-version
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   567
                if (moduleVersion != null)
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   568
                    extender.version(moduleVersion);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   569
43109
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   570
                // --hash-modules
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   571
                if (options.modulesToHash != null) {
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   572
                    // To compute hashes, it creates a Configuration to resolve
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   573
                    // a module graph.  The post-resolution check requires
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   574
                    // the packages in ModuleDescriptor be available for validation.
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   575
                    ModuleDescriptor md;
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   576
                    try (InputStream is = miSupplier.get()) {
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   577
                        md = ModuleDescriptor.read(is, () -> packages);
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   578
                    }
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   579
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   580
                    ModuleHashes moduleHashes = computeHashes(md);
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   581
                    if (moduleHashes != null) {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   582
                        extender.hashes(moduleHashes);
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   583
                    } else {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   584
                        warning("warn.no.module.hashes", descriptor.name());
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   585
                    }
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   586
                }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   587
42703
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
   588
                if (moduleResolution != null && moduleResolution.value() != 0) {
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
   589
                    extender.moduleResolution(moduleResolution);
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
   590
                }
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
   591
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   592
                // write the (possibly extended or modified) module-info.class
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   593
                out.writeEntry(extender.toByteArray(), Section.CLASSES, MODULE_INFO);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   594
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   595
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   596
42922
9111fb672357 8170618: jmod should validate if any exported or open package is missing
sundar
parents: 42704
diff changeset
   597
        private void validatePackages(ModuleDescriptor descriptor, Set<String> packages) {
9111fb672357 8170618: jmod should validate if any exported or open package is missing
sundar
parents: 42704
diff changeset
   598
            Set<String> nonExistPackages = new TreeSet<>();
9111fb672357 8170618: jmod should validate if any exported or open package is missing
sundar
parents: 42704
diff changeset
   599
            descriptor.exports().stream()
9111fb672357 8170618: jmod should validate if any exported or open package is missing
sundar
parents: 42704
diff changeset
   600
                .map(Exports::source)
9111fb672357 8170618: jmod should validate if any exported or open package is missing
sundar
parents: 42704
diff changeset
   601
                .filter(pn -> !packages.contains(pn))
9111fb672357 8170618: jmod should validate if any exported or open package is missing
sundar
parents: 42704
diff changeset
   602
                .forEach(nonExistPackages::add);
9111fb672357 8170618: jmod should validate if any exported or open package is missing
sundar
parents: 42704
diff changeset
   603
9111fb672357 8170618: jmod should validate if any exported or open package is missing
sundar
parents: 42704
diff changeset
   604
            descriptor.opens().stream()
9111fb672357 8170618: jmod should validate if any exported or open package is missing
sundar
parents: 42704
diff changeset
   605
                .map(Opens::source)
9111fb672357 8170618: jmod should validate if any exported or open package is missing
sundar
parents: 42704
diff changeset
   606
                .filter(pn -> !packages.contains(pn))
9111fb672357 8170618: jmod should validate if any exported or open package is missing
sundar
parents: 42704
diff changeset
   607
                .forEach(nonExistPackages::add);
9111fb672357 8170618: jmod should validate if any exported or open package is missing
sundar
parents: 42704
diff changeset
   608
9111fb672357 8170618: jmod should validate if any exported or open package is missing
sundar
parents: 42704
diff changeset
   609
            if (!nonExistPackages.isEmpty()) {
9111fb672357 8170618: jmod should validate if any exported or open package is missing
sundar
parents: 42704
diff changeset
   610
                throw new CommandException("err.missing.export.or.open.packages",
9111fb672357 8170618: jmod should validate if any exported or open package is missing
sundar
parents: 42704
diff changeset
   611
                    descriptor.name(), nonExistPackages);
9111fb672357 8170618: jmod should validate if any exported or open package is missing
sundar
parents: 42704
diff changeset
   612
            }
9111fb672357 8170618: jmod should validate if any exported or open package is missing
sundar
parents: 42704
diff changeset
   613
        }
9111fb672357 8170618: jmod should validate if any exported or open package is missing
sundar
parents: 42704
diff changeset
   614
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   615
        /*
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   616
         * Hasher resolves a module graph using the --hash-modules PATTERN
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   617
         * as the roots.
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   618
         *
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   619
         * The jmod file is being created and does not exist in the
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   620
         * given modulepath.
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   621
         */
43109
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   622
        private ModuleHashes computeHashes(ModuleDescriptor descriptor) {
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   623
            String mn = descriptor.name();
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   624
            URI uri = options.jmodFile.toUri();
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   625
            ModuleReference mref = new ModuleReference(descriptor, uri) {
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   626
                @Override
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   627
                public ModuleReader open() {
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   628
                    throw new UnsupportedOperationException("opening " + mn);
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   629
                }
43109
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   630
            };
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   631
43109
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   632
            // compose a module finder with the module path and also
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   633
            // a module finder that can find the jmod file being created
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   634
            ModuleFinder finder = ModuleFinder.compose(options.moduleFinder,
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   635
                new ModuleFinder() {
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   636
                    @Override
43109
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   637
                    public Optional<ModuleReference> find(String name) {
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   638
                        if (descriptor.name().equals(name))
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   639
                            return Optional.of(mref);
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   640
                        else return Optional.empty();
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   641
                    }
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   642
43109
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   643
                    @Override
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   644
                    public Set<ModuleReference> findAll() {
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   645
                        return Collections.singleton(mref);
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   646
                    }
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   647
                });
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   648
43109
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   649
            return new Hasher(mn, finder).computeHashes().get(mn);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   650
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   651
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   652
        /**
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   653
         * Returns the set of all packages on the given class path.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   654
         */
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   655
        Set<String> findPackages(List<Path> classpath) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   656
            Set<String> packages = new HashSet<>();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   657
            for (Path path : classpath) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   658
                if (Files.isDirectory(path)) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   659
                    packages.addAll(findPackages(path));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   660
                } else if (Files.isRegularFile(path) && path.toString().endsWith(".jar")) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   661
                    try (JarFile jf = new JarFile(path.toString())) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   662
                        packages.addAll(findPackages(jf));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   663
                    } catch (ZipException x) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   664
                        // Skip. Do nothing. No packages will be added.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   665
                    } catch (IOException ioe) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   666
                        throw new UncheckedIOException(ioe);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   667
                    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   668
                }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   669
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   670
            return packages;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   671
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   672
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   673
        /**
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   674
         * Returns the set of packages in the given directory tree.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   675
         */
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   676
        Set<String> findPackages(Path dir) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   677
            try {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   678
                return Files.find(dir, Integer.MAX_VALUE,
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   679
                                  ((path, attrs) -> attrs.isRegularFile()))
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   680
                        .map(dir::relativize)
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   681
                        .filter(path -> isResource(path.toString()))
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   682
                        .map(path -> toPackageName(path))
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   683
                        .filter(pkg -> pkg.length() > 0)
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   684
                        .distinct()
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   685
                        .collect(Collectors.toSet());
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   686
            } catch (IOException ioe) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   687
                throw new UncheckedIOException(ioe);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   688
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   689
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   690
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   691
        /**
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   692
         * Returns the set of packages in the given JAR file.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   693
         */
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   694
        Set<String> findPackages(JarFile jf) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   695
            return jf.stream()
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   696
                     .filter(e -> !e.isDirectory() && isResource(e.getName()))
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   697
                     .map(e -> toPackageName(e))
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   698
                     .filter(pkg -> pkg.length() > 0)
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   699
                     .distinct()
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   700
                     .collect(Collectors.toSet());
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   701
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   702
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   703
        /**
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   704
         * Returns true if it's a .class or a resource with an effective
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   705
         * package name.
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   706
         */
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   707
        boolean isResource(String name) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   708
            name = name.replace(File.separatorChar, '/');
44359
c6761862ca0b 8174823: Module system implementation refresh (3/2017)
alanb
parents: 43712
diff changeset
   709
            return name.endsWith(".class") || Resources.canEncapsulate(name);
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   710
        }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   711
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   712
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   713
        String toPackageName(Path path) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   714
            String name = path.toString();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   715
            int index = name.lastIndexOf(File.separatorChar);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   716
            if (index != -1)
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   717
                return name.substring(0, index).replace(File.separatorChar, '.');
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   718
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   719
            if (name.endsWith(".class") && !name.equals(MODULE_INFO)) {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   720
                IOException e = new IOException(name  + " in the unnamed package");
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   721
                throw new UncheckedIOException(e);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   722
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   723
            return "";
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   724
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   725
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   726
        String toPackageName(ZipEntry entry) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   727
            String name = entry.getName();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   728
            int index = name.lastIndexOf("/");
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   729
            if (index != -1)
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   730
                return name.substring(0, index).replace('/', '.');
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   731
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   732
            if (name.endsWith(".class") && !name.equals(MODULE_INFO)) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   733
                IOException e = new IOException(name  + " in the unnamed package");
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   734
                throw new UncheckedIOException(e);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   735
            }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   736
            return "";
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   737
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   738
41561
0c6942d13f2e 8167558: Add new JMOD section for header files and man pages
mchung
parents: 41484
diff changeset
   739
        void processClasses(JmodOutputStream out, List<Path> classpaths)
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   740
            throws IOException
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   741
        {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   742
            if (classpaths == null)
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   743
                return;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   744
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   745
            for (Path p : classpaths) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   746
                if (Files.isDirectory(p)) {
41561
0c6942d13f2e 8167558: Add new JMOD section for header files and man pages
mchung
parents: 41484
diff changeset
   747
                    processSection(out, Section.CLASSES, p);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   748
                } else if (Files.isRegularFile(p) && p.toString().endsWith(".jar")) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   749
                    try (JarFile jf = new JarFile(p.toFile())) {
41561
0c6942d13f2e 8167558: Add new JMOD section for header files and man pages
mchung
parents: 41484
diff changeset
   750
                        JarEntryConsumer jec = new JarEntryConsumer(out, jf);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   751
                        jf.stream().filter(jec).forEach(jec);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   752
                    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   753
                }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   754
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   755
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   756
41561
0c6942d13f2e 8167558: Add new JMOD section for header files and man pages
mchung
parents: 41484
diff changeset
   757
        void processSection(JmodOutputStream out, Section section, List<Path> paths)
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   758
            throws IOException
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   759
        {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   760
            if (paths == null)
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   761
                return;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   762
42670
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
   763
            for (Path p : paths) {
41561
0c6942d13f2e 8167558: Add new JMOD section for header files and man pages
mchung
parents: 41484
diff changeset
   764
                processSection(out, section, p);
42670
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
   765
            }
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   766
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   767
42670
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
   768
        void processSection(JmodOutputStream out, Section section, Path path)
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   769
            throws IOException
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   770
        {
42670
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
   771
            Files.walkFileTree(path, Set.of(FileVisitOption.FOLLOW_LINKS),
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
   772
                Integer.MAX_VALUE, new SimpleFileVisitor<Path>() {
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
   773
                    @Override
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
   774
                    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
   775
                        throws IOException
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
   776
                    {
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
   777
                        Path relPath = path.relativize(file);
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
   778
                        if (relPath.toString().equals(MODULE_INFO)
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
   779
                                && !Section.CLASSES.equals(section))
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
   780
                            warning("warn.ignore.entry", MODULE_INFO, section);
39882
2a5433a2eca5 8134779: (jmod) ZipException is thrown if there are duplicate resources
chegar
parents: 39150
diff changeset
   781
42670
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
   782
                        if (!relPath.toString().equals(MODULE_INFO)
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
   783
                                && !matches(relPath, excludes)) {
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
   784
                            try (InputStream in = Files.newInputStream(file)) {
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
   785
                                out.writeEntry(in, section, relPath.toString());
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
   786
                            } catch (IOException x) {
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
   787
                                if (x.getMessage().contains("duplicate entry")) {
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
   788
                                    warning("warn.ignore.duplicate.entry",
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
   789
                                            relPath.toString(), section);
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
   790
                                    return FileVisitResult.CONTINUE;
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
   791
                                }
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
   792
                                throw x;
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   793
                            }
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   794
                        }
42670
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
   795
                        return FileVisitResult.CONTINUE;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   796
                    }
42670
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
   797
                });
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   798
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   799
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   800
        boolean matches(Path path, List<PathMatcher> matchers) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   801
            if (matchers != null) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   802
                for (PathMatcher pm : matchers) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   803
                    if (pm.matches(path))
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   804
                        return true;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   805
                }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   806
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   807
            return false;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   808
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   809
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   810
        class JarEntryConsumer implements Consumer<JarEntry>, Predicate<JarEntry> {
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   811
            final JmodOutputStream out;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   812
            final JarFile jarfile;
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   813
            JarEntryConsumer(JmodOutputStream out, JarFile jarfile) {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   814
                this.out = out;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   815
                this.jarfile = jarfile;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   816
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   817
            @Override
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   818
            public void accept(JarEntry je) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   819
                try (InputStream in = jarfile.getInputStream(je)) {
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   820
                    out.writeEntry(in, Section.CLASSES, je.getName());
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   821
                } catch (IOException e) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   822
                    throw new UncheckedIOException(e);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   823
                }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   824
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   825
            @Override
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   826
            public boolean test(JarEntry je) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   827
                String name = je.getName();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   828
                // ## no support for excludes. Is it really needed?
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   829
                return !name.endsWith(MODULE_INFO) && !je.isDirectory();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   830
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   831
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   832
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   833
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   834
    /**
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   835
     * Compute and record hashes
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   836
     */
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   837
    private class Hasher {
43109
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   838
        final Configuration configuration;
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   839
        final ModuleHashesBuilder hashesBuilder;
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   840
        final Set<String> modules;
43109
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   841
        final String moduleName;  // a specific module to record hashes, if set
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   842
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   843
        /**
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   844
         * This constructor is for jmod hash command.
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   845
         *
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   846
         * This Hasher will determine which modules to record hashes, i.e.
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   847
         * the module in a subgraph of modules to be hashed and that
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   848
         * has no outgoing edges.  It will record in each of these modules,
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   849
         * say `M`, with the the hashes of modules that depend upon M
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   850
         * directly or indirectly matching the specified --hash-modules pattern.
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   851
         */
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   852
        Hasher(ModuleFinder finder) {
43109
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   853
            this(null, finder);
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   854
        }
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   855
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   856
        /**
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   857
         * Constructs a Hasher to compute hashes.
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   858
         *
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   859
         * If a module name `M` is specified, it will compute the hashes of
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   860
         * modules that depend upon M directly or indirectly matching the
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   861
         * specified --hash-modules pattern and record in the ModuleHashes
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   862
         * attribute in M's module-info.class.
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   863
         *
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   864
         * @param name    name of the module to record hashes
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   865
         * @param finder  module finder for the specified --module-path
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   866
         */
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   867
        Hasher(String name, ModuleFinder finder) {
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   868
            // Determine the modules that matches the pattern {@code modulesToHash}
43109
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   869
            Set<String> roots = finder.findAll().stream()
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   870
                .map(mref -> mref.descriptor().name())
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   871
                .filter(mn -> options.modulesToHash.matcher(mn).find())
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   872
                .collect(Collectors.toSet());
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   873
43109
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   874
            // use system module path unless it creates a JMOD file for
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   875
            // a module that is present in the system image e.g. upgradeable
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   876
            // module
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   877
            ModuleFinder system;
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   878
            if (name != null && ModuleFinder.ofSystem().find(name).isPresent()) {
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   879
                system = ModuleFinder.of();
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   880
            } else {
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   881
                system = ModuleFinder.ofSystem();
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   882
            }
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   883
            // get a resolved module graph
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   884
            Configuration config = null;
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   885
            try {
43712
5dfd0950317c 8173393: Module system implementation refresh (2/2017)
alanb
parents: 43242
diff changeset
   886
                config = Configuration.empty().resolve(system, finder, roots);
5dfd0950317c 8173393: Module system implementation refresh (2/2017)
alanb
parents: 43242
diff changeset
   887
            } catch (FindException | ResolutionException e) {
43109
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   888
                throw new CommandException("err.module.resolution.fail", e.getMessage());
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   889
            }
43109
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   890
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   891
            this.moduleName = name;
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   892
            this.configuration = config;
43109
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   893
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   894
            // filter modules resolved from the system module finder
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   895
            this.modules = config.modules().stream()
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   896
                .map(ResolvedModule::name)
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   897
                .filter(mn -> roots.contains(mn) && !system.find(mn).isPresent())
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   898
                .collect(Collectors.toSet());
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   899
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   900
            this.hashesBuilder = new ModuleHashesBuilder(config, modules);
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   901
        }
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   902
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   903
        /**
43109
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   904
         * Returns a map of a module M to record hashes of the modules
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   905
         * that depend upon M directly or indirectly.
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   906
         *
43109
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   907
         * For jmod hash command, the returned map contains one entry
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   908
         * for each module M that has no outgoing edges to any of the
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   909
         * modules matching the specified --hash-modules pattern.
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   910
         *
43109
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   911
         * Each entry represents a leaf node in a connected subgraph containing
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   912
         * M and other candidate modules from the module graph where M's outgoing
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   913
         * edges to any module other than the ones matching the specified
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   914
         * --hash-modules pattern are excluded.
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   915
         */
43109
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   916
        Map<String, ModuleHashes> computeHashes() {
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   917
            if (hashesBuilder == null)
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   918
                return null;
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   919
43109
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   920
            if (moduleName != null) {
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   921
                return hashesBuilder.computeHashes(Set.of(moduleName));
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   922
            } else {
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   923
                return hashesBuilder.computeHashes(modules);
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   924
            }
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   925
        }
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   926
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   927
        /**
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   928
         * Reads the given input stream of module-info.class and write
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   929
         * the extended module-info.class with the given ModuleHashes
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   930
         *
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   931
         * @param in       InputStream of module-info.class
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   932
         * @param out      OutputStream to write the extended module-info.class
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   933
         * @param hashes   ModuleHashes
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   934
         */
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   935
        private void recordHashes(InputStream in, OutputStream out, ModuleHashes hashes)
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   936
            throws IOException
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   937
        {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   938
            ModuleInfoExtender extender = ModuleInfoExtender.newExtender(in);
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   939
            extender.hashes(hashes);
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   940
            extender.write(out);
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   941
        }
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   942
43109
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   943
        void updateModuleInfo(String name, ModuleHashes moduleHashes)
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   944
            throws IOException
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   945
        {
43109
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   946
            Path target = moduleToPath(name);
43242
6c33c81be927 8173096: jmod files are not world-readable
mchung
parents: 43109
diff changeset
   947
            Path tempTarget = jmodTempFilePath(target);
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   948
            try {
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   949
                if (target.getFileName().toString().endsWith(".jmod")) {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   950
                    updateJmodFile(target, tempTarget, moduleHashes);
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   951
                } else {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   952
                    updateModularJar(target, tempTarget, moduleHashes);
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   953
                }
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   954
            } catch (IOException|RuntimeException e) {
43242
6c33c81be927 8173096: jmod files are not world-readable
mchung
parents: 43109
diff changeset
   955
                try {
6c33c81be927 8173096: jmod files are not world-readable
mchung
parents: 43109
diff changeset
   956
                    Files.deleteIfExists(tempTarget);
6c33c81be927 8173096: jmod files are not world-readable
mchung
parents: 43109
diff changeset
   957
                } catch (IOException ioe) {
6c33c81be927 8173096: jmod files are not world-readable
mchung
parents: 43109
diff changeset
   958
                    e.addSuppressed(ioe);
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   959
                }
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   960
                throw e;
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   961
            }
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   962
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   963
            out.println(getMessage("module.hashes.recorded", name));
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   964
            Files.move(tempTarget, target, StandardCopyOption.REPLACE_EXISTING);
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   965
        }
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   966
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   967
        private void updateModularJar(Path target, Path tempTarget,
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   968
                                      ModuleHashes moduleHashes)
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   969
            throws IOException
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   970
        {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   971
            try (JarFile jf = new JarFile(target.toFile());
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   972
                 OutputStream out = Files.newOutputStream(tempTarget);
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   973
                 JarOutputStream jos = new JarOutputStream(out))
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   974
            {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   975
                jf.stream().forEach(e -> {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   976
                    try (InputStream in = jf.getInputStream(e)) {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   977
                        if (e.getName().equals(MODULE_INFO)) {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   978
                            // what about module-info.class in versioned entries?
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   979
                            ZipEntry ze = new ZipEntry(e.getName());
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   980
                            ze.setTime(System.currentTimeMillis());
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   981
                            jos.putNextEntry(ze);
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   982
                            recordHashes(in, jos, moduleHashes);
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   983
                            jos.closeEntry();
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   984
                        } else {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   985
                            jos.putNextEntry(e);
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   986
                            jos.write(in.readAllBytes());
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   987
                            jos.closeEntry();
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   988
                        }
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   989
                    } catch (IOException x) {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   990
                        throw new UncheckedIOException(x);
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   991
                    }
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   992
                });
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   993
            }
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   994
        }
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   995
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   996
        private void updateJmodFile(Path target, Path tempTarget,
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   997
                                    ModuleHashes moduleHashes)
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   998
            throws IOException
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   999
        {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
  1000
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
  1001
            try (JmodFile jf = new JmodFile(target);
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
  1002
                 JmodOutputStream jos = JmodOutputStream.newOutputStream(tempTarget))
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
  1003
            {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
  1004
                jf.stream().forEach(e -> {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
  1005
                    try (InputStream in = jf.getInputStream(e.section(), e.name())) {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
  1006
                        if (e.name().equals(MODULE_INFO)) {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
  1007
                            // replace module-info.class
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
  1008
                            ModuleInfoExtender extender =
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
  1009
                                ModuleInfoExtender.newExtender(in);
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
  1010
                            extender.hashes(moduleHashes);
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
  1011
                            jos.writeEntry(extender.toByteArray(), e.section(), e.name());
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
  1012
                        } else {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
  1013
                            jos.writeEntry(in, e);
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
  1014
                        }
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
  1015
                    } catch (IOException x) {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
  1016
                        throw new UncheckedIOException(x);
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
  1017
                    }
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
  1018
                });
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
  1019
            }
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
  1020
        }
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
  1021
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1022
        private Path moduleToPath(String name) {
43109
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
  1023
            ResolvedModule rm = configuration.findModule(name).orElseThrow(
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1024
                () -> new InternalError("Selected module " + name + " not on module path"));
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1025
43109
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
  1026
            URI uri = rm.reference().location().get();
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1027
            Path path = Paths.get(uri);
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1028
            String fn = path.getFileName().toString();
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1029
            if (!fn.endsWith(".jar") && !fn.endsWith(".jmod")) {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1030
                throw new InternalError(path + " is not a modular JAR or jmod file");
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1031
            }
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1032
            return path;
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1033
        }
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1034
    }
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1035
43067
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1036
    /**
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1037
     * An abstract converter that given a string representing a list of paths,
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1038
     * separated by the File.pathSeparator, returns a List of java.nio.Path's.
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1039
     * Specific subclasses should do whatever validation is required on the
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1040
     * individual path elements, if any.
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1041
     */
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1042
    static abstract class AbstractPathConverter implements ValueConverter<List<Path>> {
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1043
        @Override
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1044
        public List<Path> convert(String value) {
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1045
            List<Path> paths = new ArrayList<>();
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1046
            String[] pathElements = value.split(File.pathSeparator);
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1047
            for (String pathElement : pathElements) {
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1048
                paths.add(toPath(pathElement));
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1049
            }
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1050
            return paths;
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1051
        }
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1052
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1053
        @SuppressWarnings("unchecked")
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1054
        @Override
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1055
        public Class<List<Path>> valueType() {
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1056
            return (Class<List<Path>>)(Object)List.class;
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1057
        }
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1058
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1059
        @Override public String valuePattern() { return "path"; }
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1060
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1061
        abstract Path toPath(String path);
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1062
    }
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1063
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1064
    static class ClassPathConverter extends AbstractPathConverter {
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1065
        static final ValueConverter<List<Path>> INSTANCE = new ClassPathConverter();
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1066
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1067
        @Override
43067
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1068
        public Path toPath(String value) {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1069
            try {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1070
                Path path = CWD.resolve(value);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1071
                if (Files.notExists(path))
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1072
                    throw new CommandException("err.path.not.found", path);
43067
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1073
                if (!(Files.isDirectory(path) ||
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1074
                        (Files.isRegularFile(path) && path.toString().endsWith(".jar"))))
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1075
                    throw new CommandException("err.invalid.class.path.entry", path);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1076
                return path;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1077
            } catch (InvalidPathException x) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1078
                throw new CommandException("err.path.not.valid", value);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1079
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1080
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1081
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1082
43067
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1083
    static class DirPathConverter extends AbstractPathConverter {
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1084
        static final ValueConverter<List<Path>> INSTANCE = new DirPathConverter();
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1085
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1086
        @Override
43067
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1087
        public Path toPath(String value) {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1088
            try {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1089
                Path path = CWD.resolve(value);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1090
                if (Files.notExists(path))
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1091
                    throw new CommandException("err.path.not.found", path);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1092
                if (!Files.isDirectory(path))
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1093
                    throw new CommandException("err.path.not.a.dir", path);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1094
                return path;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1095
            } catch (InvalidPathException x) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1096
                throw new CommandException("err.path.not.valid", value);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1097
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1098
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1099
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1100
42468
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
  1101
    static class ExtractDirPathConverter implements ValueConverter<Path> {
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
  1102
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
  1103
        @Override
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
  1104
        public Path convert(String value) {
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
  1105
            try {
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
  1106
                Path path = CWD.resolve(value);
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
  1107
                if (Files.exists(path)) {
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
  1108
                    if (!Files.isDirectory(path))
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
  1109
                        throw new CommandException("err.cannot.create.dir", path);
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
  1110
                }
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
  1111
                return path;
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
  1112
            } catch (InvalidPathException x) {
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
  1113
                throw new CommandException("err.path.not.valid", value);
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
  1114
            }
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
  1115
        }
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
  1116
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
  1117
        @Override  public Class<Path> valueType() { return Path.class; }
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
  1118
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
  1119
        @Override  public String valuePattern() { return "path"; }
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
  1120
    }
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
  1121
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1122
    static class ModuleVersionConverter implements ValueConverter<Version> {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1123
        @Override
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1124
        public Version convert(String value) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1125
            try {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1126
                return Version.parse(value);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1127
            } catch (IllegalArgumentException x) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1128
                throw new CommandException("err.invalid.version", x.getMessage());
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1129
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1130
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1131
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1132
        @Override public Class<Version> valueType() { return Version.class; }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1133
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1134
        @Override public String valuePattern() { return "module-version"; }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1135
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1136
42703
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1137
    static class WarnIfResolvedReasonConverter
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1138
        implements ValueConverter<ModuleResolution>
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1139
    {
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1140
        @Override
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1141
        public ModuleResolution convert(String value) {
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1142
            if (value.equals("deprecated"))
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1143
                return ModuleResolution.empty().withDeprecated();
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1144
            else if (value.equals("deprecated-for-removal"))
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1145
                return ModuleResolution.empty().withDeprecatedForRemoval();
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1146
            else if (value.equals("incubating"))
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1147
                return ModuleResolution.empty().withIncubating();
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1148
            else
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1149
                throw new CommandException("err.bad.WarnIfResolvedReason", value);
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1150
        }
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1151
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1152
        @Override public Class<ModuleResolution> valueType() {
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1153
            return ModuleResolution.class;
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1154
        }
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1155
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1156
        @Override public String valuePattern() { return "reason"; }
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1157
    }
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1158
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1159
    static class PatternConverter implements ValueConverter<Pattern> {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1160
        @Override
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1161
        public Pattern convert(String value) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1162
            try {
38871
ec08bf1979d4 8158402: jlink: should use regex for all pattern operations (--order-resources or --exclude-resources)
jlaskey
parents: 37779
diff changeset
  1163
                if (value.startsWith("regex:")) {
ec08bf1979d4 8158402: jlink: should use regex for all pattern operations (--order-resources or --exclude-resources)
jlaskey
parents: 37779
diff changeset
  1164
                    value = value.substring("regex:".length()).trim();
ec08bf1979d4 8158402: jlink: should use regex for all pattern operations (--order-resources or --exclude-resources)
jlaskey
parents: 37779
diff changeset
  1165
                }
ec08bf1979d4 8158402: jlink: should use regex for all pattern operations (--order-resources or --exclude-resources)
jlaskey
parents: 37779
diff changeset
  1166
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1167
                return Pattern.compile(value);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1168
            } catch (PatternSyntaxException e) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1169
                throw new CommandException("err.bad.pattern", value);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1170
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1171
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1172
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1173
        @Override public Class<Pattern> valueType() { return Pattern.class; }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1174
39150
cb99396625b4 8159172: Update usage of jlink/jimage/jmod to show option patterns
jlaskey
parents: 39042
diff changeset
  1175
        @Override public String valuePattern() { return "regex-pattern"; }
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1176
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1177
38871
ec08bf1979d4 8158402: jlink: should use regex for all pattern operations (--order-resources or --exclude-resources)
jlaskey
parents: 37779
diff changeset
  1178
    static class PathMatcherConverter implements ValueConverter<PathMatcher> {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1179
        @Override
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1180
        public PathMatcher convert(String pattern) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1181
            try {
39042
52db877f18db 8159206: All jlink or jmod tests failing
jlaskey
parents: 38871
diff changeset
  1182
                return Utils.getPathMatcher(FileSystems.getDefault(), pattern);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1183
            } catch (PatternSyntaxException e) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1184
                throw new CommandException("err.bad.pattern", pattern);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1185
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1186
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1187
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1188
        @Override public Class<PathMatcher> valueType() { return PathMatcher.class; }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1189
39150
cb99396625b4 8159172: Update usage of jlink/jimage/jmod to show option patterns
jlaskey
parents: 39042
diff changeset
  1190
        @Override public String valuePattern() { return "pattern-list"; }
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1191
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1192
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1193
    /* Support for @<file> in jmod help */
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1194
    private static final String CMD_FILENAME = "@<filename>";
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1195
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1196
    /**
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1197
     * This formatter is adding the @filename option and does the required
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1198
     * formatting.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1199
     */
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1200
    private static final class JmodHelpFormatter extends BuiltinHelpFormatter {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1201
42703
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1202
        private final Options opts;
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1203
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1204
        private JmodHelpFormatter(Options opts) {
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1205
            super(80, 2);
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1206
            this.opts = opts;
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1207
        }
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1208
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1209
        @Override
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1210
        public String format(Map<String, ? extends OptionDescriptor> options) {
42703
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1211
            Map<String, OptionDescriptor> all = new LinkedHashMap<>();
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1212
            all.putAll(options);
42703
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1213
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1214
            // extra options
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1215
            if (!opts.helpExtra) {
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1216
                all.remove("do-not-resolve-by-default");
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1217
                all.remove("warn-if-resolved");
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1218
            }
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1219
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1220
            all.put(CMD_FILENAME, new OptionDescriptor() {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1221
                @Override
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1222
                public Collection<String> options() {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1223
                    List<String> ret = new ArrayList<>();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1224
                    ret.add(CMD_FILENAME);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1225
                    return ret;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1226
                }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1227
                @Override
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1228
                public String description() { return getMessage("main.opt.cmdfile"); }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1229
                @Override
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1230
                public List<?> defaultValues() { return Collections.emptyList(); }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1231
                @Override
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1232
                public boolean isRequired() { return false; }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1233
                @Override
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1234
                public boolean acceptsArguments() { return false; }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1235
                @Override
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1236
                public boolean requiresArgument() { return false; }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1237
                @Override
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1238
                public String argumentDescription() { return null; }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1239
                @Override
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1240
                public String argumentTypeIndicator() { return null; }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1241
                @Override
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1242
                public boolean representsNonOptions() { return false; }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1243
            });
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1244
            String content = super.format(all);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1245
            StringBuilder builder = new StringBuilder();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1246
39150
cb99396625b4 8159172: Update usage of jlink/jimage/jmod to show option patterns
jlaskey
parents: 39042
diff changeset
  1247
            builder.append(getMessage("main.opt.mode")).append("\n  ");
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1248
            builder.append(getMessage("main.opt.mode.create")).append("\n  ");
42468
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
  1249
            builder.append(getMessage("main.opt.mode.extract")).append("\n  ");
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1250
            builder.append(getMessage("main.opt.mode.list")).append("\n  ");
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1251
            builder.append(getMessage("main.opt.mode.describe")).append("\n  ");
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1252
            builder.append(getMessage("main.opt.mode.hash")).append("\n\n");
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1253
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1254
            String cmdfile = null;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1255
            String[] lines = content.split("\n");
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1256
            for (String line : lines) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1257
                if (line.startsWith("--@")) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1258
                    cmdfile = line.replace("--" + CMD_FILENAME, CMD_FILENAME + "  ");
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1259
                } else if (line.startsWith("Option") || line.startsWith("------")) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1260
                    builder.append(" ").append(line).append("\n");
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1261
                } else if (!line.matches("Non-option arguments")){
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1262
                    builder.append("  ").append(line).append("\n");
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1263
                }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1264
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1265
            if (cmdfile != null) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1266
                builder.append("  ").append(cmdfile).append("\n");
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1267
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1268
            return builder.toString();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1269
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1270
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1271
40261
86a49ba76f52 8136930: Simplify use of module-system options by custom launchers
mchung
parents: 39882
diff changeset
  1272
    private final OptionParser parser = new OptionParser("hp");
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1273
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1274
    private void handleOptions(String[] args) {
42703
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1275
        options = new Options();
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1276
        parser.formatHelpWith(new JmodHelpFormatter(options));
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1277
43067
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1278
        OptionSpec<List<Path>> classPath
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1279
                = parser.accepts("class-path", getMessage("main.opt.class-path"))
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1280
                        .withRequiredArg()
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1281
                        .withValuesConvertedBy(ClassPathConverter.INSTANCE);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1282
43067
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1283
        OptionSpec<List<Path>> cmds
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1284
                = parser.accepts("cmds", getMessage("main.opt.cmds"))
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1285
                        .withRequiredArg()
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1286
                        .withValuesConvertedBy(DirPathConverter.INSTANCE);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1287
43067
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1288
        OptionSpec<List<Path>> config
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1289
                = parser.accepts("config", getMessage("main.opt.config"))
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1290
                        .withRequiredArg()
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1291
                        .withValuesConvertedBy(DirPathConverter.INSTANCE);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1292
42468
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
  1293
        OptionSpec<Path> dir
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
  1294
                = parser.accepts("dir", getMessage("main.opt.extractDir"))
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
  1295
                        .withRequiredArg()
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
  1296
                        .withValuesConvertedBy(new ExtractDirPathConverter());
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
  1297
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1298
        OptionSpec<Void> dryrun
42670
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
  1299
                = parser.accepts("dry-run", getMessage("main.opt.dry-run"));
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1300
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1301
        OptionSpec<PathMatcher> excludes
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1302
                = parser.accepts("exclude", getMessage("main.opt.exclude"))
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1303
                        .withRequiredArg()
38871
ec08bf1979d4 8158402: jlink: should use regex for all pattern operations (--order-resources or --exclude-resources)
jlaskey
parents: 37779
diff changeset
  1304
                        .withValuesConvertedBy(new PathMatcherConverter());
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1305
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1306
        OptionSpec<Pattern> hashModules
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1307
                = parser.accepts("hash-modules", getMessage("main.opt.hash-modules"))
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1308
                        .withRequiredArg()
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1309
                        .withValuesConvertedBy(new PatternConverter());
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1310
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1311
        OptionSpec<Void> help
48543
7067fe4e054e 8189102: All tools should support -?, -h and --help
goetz
parents: 47216
diff changeset
  1312
                = parser.acceptsAll(Set.of("h", "help", "?"), getMessage("main.opt.help"))
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1313
                        .forHelp();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1314
42703
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1315
        OptionSpec<Void> helpExtra
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1316
                = parser.accepts("help-extra", getMessage("main.opt.help-extra"));
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1317
43067
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1318
        OptionSpec<List<Path>> headerFiles
42670
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
  1319
                = parser.accepts("header-files", getMessage("main.opt.header-files"))
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
  1320
                        .withRequiredArg()
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
  1321
                        .withValuesConvertedBy(DirPathConverter.INSTANCE);
41561
0c6942d13f2e 8167558: Add new JMOD section for header files and man pages
mchung
parents: 41484
diff changeset
  1322
43067
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1323
        OptionSpec<List<Path>> libs
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1324
                = parser.accepts("libs", getMessage("main.opt.libs"))
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1325
                        .withRequiredArg()
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1326
                        .withValuesConvertedBy(DirPathConverter.INSTANCE);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1327
43067
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1328
        OptionSpec<List<Path>> legalNotices
42670
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
  1329
                = parser.accepts("legal-notices", getMessage("main.opt.legal-notices"))
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
  1330
                        .withRequiredArg()
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
  1331
                        .withValuesConvertedBy(DirPathConverter.INSTANCE);
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
  1332
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
  1333
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1334
        OptionSpec<String> mainClass
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1335
                = parser.accepts("main-class", getMessage("main.opt.main-class"))
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1336
                        .withRequiredArg()
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1337
                        .describedAs(getMessage("main.opt.main-class.arg"));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1338
43067
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1339
        OptionSpec<List<Path>> manPages
42670
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
  1340
                = parser.accepts("man-pages", getMessage("main.opt.man-pages"))
41561
0c6942d13f2e 8167558: Add new JMOD section for header files and man pages
mchung
parents: 41484
diff changeset
  1341
                        .withRequiredArg()
0c6942d13f2e 8167558: Add new JMOD section for header files and man pages
mchung
parents: 41484
diff changeset
  1342
                        .withValuesConvertedBy(DirPathConverter.INSTANCE);
0c6942d13f2e 8167558: Add new JMOD section for header files and man pages
mchung
parents: 41484
diff changeset
  1343
43067
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1344
        OptionSpec<List<Path>> modulePath
40261
86a49ba76f52 8136930: Simplify use of module-system options by custom launchers
mchung
parents: 39882
diff changeset
  1345
                = parser.acceptsAll(Set.of("p", "module-path"),
86a49ba76f52 8136930: Simplify use of module-system options by custom launchers
mchung
parents: 39882
diff changeset
  1346
                                    getMessage("main.opt.module-path"))
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1347
                        .withRequiredArg()
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1348
                        .withValuesConvertedBy(DirPathConverter.INSTANCE);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1349
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1350
        OptionSpec<Version> moduleVersion
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1351
                = parser.accepts("module-version", getMessage("main.opt.module-version"))
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1352
                        .withRequiredArg()
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1353
                        .withValuesConvertedBy(new ModuleVersionConverter());
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1354
45004
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
  1355
        OptionSpec<String> targetPlatform
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
  1356
                = parser.accepts("target-platform", getMessage("main.opt.target-platform"))
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1357
                        .withRequiredArg()
45004
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
  1358
                        .describedAs(getMessage("main.opt.target-platform.arg"));
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1359
42703
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1360
        OptionSpec<Void> doNotResolveByDefault
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1361
                = parser.accepts("do-not-resolve-by-default",
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1362
                                 getMessage("main.opt.do-not-resolve-by-default"));
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1363
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1364
        OptionSpec<ModuleResolution> warnIfResolved
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1365
                = parser.accepts("warn-if-resolved", getMessage("main.opt.warn-if-resolved"))
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1366
                        .withRequiredArg()
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1367
                        .withValuesConvertedBy(new WarnIfResolvedReasonConverter());
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1368
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1369
        OptionSpec<Void> version
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1370
                = parser.accepts("version", getMessage("main.opt.version"));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1371
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1372
        NonOptionArgumentSpec<String> nonOptions
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1373
                = parser.nonOptions();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1374
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1375
        try {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1376
            OptionSet opts = parser.parse(args);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1377
42703
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1378
            if (opts.has(help) || opts.has(helpExtra) || opts.has(version)) {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1379
                options.help = opts.has(help);
42703
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1380
                options.helpExtra = opts.has(helpExtra);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1381
                options.version = opts.has(version);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1382
                return;  // informational message will be shown
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1383
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1384
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1385
            List<String> words = opts.valuesOf(nonOptions);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1386
            if (words.isEmpty())
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1387
                throw new CommandException("err.missing.mode").showUsage(true);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1388
            String verb = words.get(0);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1389
            try {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1390
                options.mode = Enum.valueOf(Mode.class, verb.toUpperCase());
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1391
            } catch (IllegalArgumentException e) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1392
                throw new CommandException("err.invalid.mode", verb).showUsage(true);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1393
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1394
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1395
            if (opts.has(classPath))
43067
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1396
                options.classpath = getLastElement(opts.valuesOf(classPath));
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1397
            if (opts.has(cmds))
43067
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1398
                options.cmds = getLastElement(opts.valuesOf(cmds));
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1399
            if (opts.has(config))
43067
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1400
                options.configs = getLastElement(opts.valuesOf(config));
42468
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
  1401
            if (opts.has(dir))
43067
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1402
                options.extractDir = getLastElement(opts.valuesOf(dir));
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1403
            if (opts.has(dryrun))
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1404
                options.dryrun = true;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1405
            if (opts.has(excludes))
43067
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1406
                options.excludes = opts.valuesOf(excludes);  // excludes is repeatable
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1407
            if (opts.has(libs))
43067
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1408
                options.libs = getLastElement(opts.valuesOf(libs));
41561
0c6942d13f2e 8167558: Add new JMOD section for header files and man pages
mchung
parents: 41484
diff changeset
  1409
            if (opts.has(headerFiles))
43067
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1410
                options.headerFiles = getLastElement(opts.valuesOf(headerFiles));
41561
0c6942d13f2e 8167558: Add new JMOD section for header files and man pages
mchung
parents: 41484
diff changeset
  1411
            if (opts.has(manPages))
43067
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1412
                options.manPages = getLastElement(opts.valuesOf(manPages));
42670
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
  1413
            if (opts.has(legalNotices))
43067
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1414
                options.legalNotices = getLastElement(opts.valuesOf(legalNotices));
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1415
            if (opts.has(modulePath)) {
43067
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1416
                Path[] dirs = getLastElement(opts.valuesOf(modulePath)).toArray(new Path[0]);
43712
5dfd0950317c 8173393: Module system implementation refresh (2/2017)
alanb
parents: 43242
diff changeset
  1417
                options.moduleFinder = ModulePath.of(Runtime.version(), true, dirs);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1418
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1419
            if (opts.has(moduleVersion))
43067
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1420
                options.moduleVersion = getLastElement(opts.valuesOf(moduleVersion));
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1421
            if (opts.has(mainClass))
43067
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1422
                options.mainClass = getLastElement(opts.valuesOf(mainClass));
45004
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
  1423
            if (opts.has(targetPlatform))
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
  1424
                options.targetPlatform = getLastElement(opts.valuesOf(targetPlatform));
42703
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1425
            if (opts.has(warnIfResolved))
43067
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1426
                options.moduleResolution = getLastElement(opts.valuesOf(warnIfResolved));
42703
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1427
            if (opts.has(doNotResolveByDefault)) {
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1428
                if (options.moduleResolution == null)
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1429
                    options.moduleResolution = ModuleResolution.empty();
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1430
                options.moduleResolution = options.moduleResolution.withDoNotResolveByDefault();
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1431
            }
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1432
            if (opts.has(hashModules)) {
43067
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1433
                options.modulesToHash = getLastElement(opts.valuesOf(hashModules));
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1434
                // if storing hashes then the module path is required
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1435
                if (options.moduleFinder == null)
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1436
                    throw new CommandException("err.modulepath.must.be.specified")
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1437
                            .showUsage(true);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1438
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1439
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1440
            if (options.mode.equals(Mode.HASH)) {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1441
                if (options.moduleFinder == null || options.modulesToHash == null)
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1442
                    throw new CommandException("err.modulepath.must.be.specified")
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1443
                            .showUsage(true);
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1444
            } else {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1445
                if (words.size() <= 1)
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1446
                    throw new CommandException("err.jmod.must.be.specified").showUsage(true);
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1447
                Path path = Paths.get(words.get(1));
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1448
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1449
                if (options.mode.equals(Mode.CREATE) && Files.exists(path))
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1450
                    throw new CommandException("err.file.already.exists", path);
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1451
                else if ((options.mode.equals(Mode.LIST) ||
42468
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
  1452
                            options.mode.equals(Mode.DESCRIBE) ||
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
  1453
                            options.mode.equals((Mode.EXTRACT)))
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1454
                         && Files.notExists(path))
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1455
                    throw new CommandException("err.jmod.not.found", path);
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1456
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1457
                if (options.dryrun) {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1458
                    throw new CommandException("err.invalid.dryrun.option");
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1459
                }
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1460
                options.jmodFile = path;
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1461
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1462
                if (words.size() > 2)
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1463
                    throw new CommandException("err.unknown.option",
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1464
                            words.subList(2, words.size())).showUsage(true);
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1465
            }
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1466
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1467
            if (options.mode.equals(Mode.CREATE) && options.classpath == null)
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1468
                throw new CommandException("err.classpath.must.be.specified").showUsage(true);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1469
            if (options.mainClass != null && !isValidJavaIdentifier(options.mainClass))
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1470
                throw new CommandException("err.invalid.main-class", options.mainClass);
43067
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1471
            if (options.mode.equals(Mode.EXTRACT) && options.extractDir != null) {
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1472
                try {
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1473
                    Files.createDirectories(options.extractDir);
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1474
                } catch (IOException ioe) {
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1475
                    throw new CommandException("err.cannot.create.dir", options.extractDir);
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1476
                }
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1477
            }
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1478
        } catch (OptionException e) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1479
             throw new CommandException(e.getMessage());
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1480
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1481
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1482
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1483
    /**
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1484
     * Returns true if, and only if, the given main class is a legal.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1485
     */
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1486
    static boolean isValidJavaIdentifier(String mainClass) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1487
        if (mainClass.length() == 0)
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1488
            return false;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1489
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1490
        if (!Character.isJavaIdentifierStart(mainClass.charAt(0)))
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1491
            return false;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1492
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1493
        int n = mainClass.length();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1494
        for (int i=1; i < n; i++) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1495
            char c = mainClass.charAt(i);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1496
            if (!Character.isJavaIdentifierPart(c) && c != '.')
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1497
                return false;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1498
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1499
        if (mainClass.charAt(n-1) == '.')
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1500
            return false;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1501
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1502
        return true;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1503
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1504
43067
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1505
    static <E> E getLastElement(List<E> list) {
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1506
        if (list.size() == 0)
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1507
            throw new InternalError("Unexpected 0 list size");
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1508
        return list.get(list.size() - 1);
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1509
    }
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1510
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1511
    private void reportError(String message) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1512
        out.println(getMessage("error.prefix") + " " + message);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1513
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1514
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1515
    private void warning(String key, Object... args) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1516
        out.println(getMessage("warn.prefix") + " " + getMessage(key, args));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1517
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1518
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1519
    private void showUsageSummary() {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1520
        out.println(getMessage("main.usage.summary", PROGNAME));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1521
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1522
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1523
    private void showHelp() {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1524
        out.println(getMessage("main.usage", PROGNAME));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1525
        try {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1526
            parser.printHelpOn(out);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1527
        } catch (IOException x) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1528
            throw new AssertionError(x);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1529
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1530
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1531
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1532
    private void showVersion() {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1533
        out.println(version());
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1534
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1535
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1536
    private String version() {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1537
        return System.getProperty("java.version");
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1538
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1539
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1540
    private static String getMessage(String key, Object... args) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1541
        try {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1542
            return MessageFormat.format(ResourceBundleHelper.bundle.getString(key), args);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1543
        } catch (MissingResourceException e) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1544
            throw new InternalError("Missing message: " + key);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1545
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1546
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1547
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1548
    private static class ResourceBundleHelper {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1549
        static final ResourceBundle bundle;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1550
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1551
        static {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1552
            Locale locale = Locale.getDefault();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1553
            try {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1554
                bundle = ResourceBundle.getBundle("jdk.tools.jmod.resources.jmod", locale);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1555
            } catch (MissingResourceException e) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1556
                throw new InternalError("Cannot find jmod resource bundle for locale " + locale);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1557
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1558
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1559
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1560
}