src/jdk.jlink/share/classes/jdk/tools/jmod/JmodTask.java
author jlahoda
Wed, 06 Jun 2018 15:36:29 +0200
changeset 50428 8c88df2e8a78
parent 50130 aefd3c7f5373
permissions -rw-r--r--
8203891: Upgrade JOpt Simple to 5.0.4 Reviewed-by: alanb, chegar, mchung
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
50130
aefd3c7f5373 8191533: jar --describe-module prints service provider class names in lower case
sherman
parents: 48543
diff changeset
   323
    static <T> String toLowerCaseString(Collection<T> c) {
42338
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
50130
aefd3c7f5373 8191533: jar --describe-module prints service provider class names in lower case
sherman
parents: 48543
diff changeset
   329
    static <T> String toString(Collection<T> c) {
aefd3c7f5373 8191533: jar --describe-module prints service provider class names in lower case
sherman
parents: 48543
diff changeset
   330
        if (c.isEmpty()) { return ""; }
aefd3c7f5373 8191533: jar --describe-module prints service provider class names in lower case
sherman
parents: 48543
diff changeset
   331
        return " " + c.stream().map(e -> e.toString()).sorted().collect(joining(" "));
aefd3c7f5373 8191533: jar --describe-module prints service provider class names in lower case
sherman
parents: 48543
diff changeset
   332
    }
aefd3c7f5373 8191533: jar --describe-module prints service provider class names in lower case
sherman
parents: 48543
diff changeset
   333
45004
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   334
    private void describeModule(ModuleDescriptor md,
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   335
                                ModuleTarget target,
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   336
                                ModuleHashes hashes)
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   337
        throws IOException
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   338
    {
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   339
        StringBuilder sb = new StringBuilder();
45004
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   340
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   341
        sb.append(md.toNameAndVersion());
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   342
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   343
        if (md.isOpen())
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   344
            sb.append(" open");
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   345
        if (md.isAutomatic())
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   346
            sb.append(" automatic");
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   347
        sb.append("\n");
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   348
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   349
        // unqualified exports (sorted by package)
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   350
        md.exports().stream()
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   351
                .sorted(Comparator.comparing(Exports::source))
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   352
                .filter(e -> !e.isQualified())
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   353
                .forEach(e -> sb.append("exports ").append(e.source())
50130
aefd3c7f5373 8191533: jar --describe-module prints service provider class names in lower case
sherman
parents: 48543
diff changeset
   354
                                .append(toLowerCaseString(e.modifiers())).append("\n"));
45004
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   355
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   356
        // dependences
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   357
        md.requires().stream().sorted()
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   358
                .forEach(r -> sb.append("requires ").append(r.name())
50130
aefd3c7f5373 8191533: jar --describe-module prints service provider class names in lower case
sherman
parents: 48543
diff changeset
   359
                                .append(toLowerCaseString(r.modifiers())).append("\n"));
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   360
45004
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   361
        // service use and provides
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   362
        md.uses().stream().sorted()
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   363
                .forEach(s -> sb.append("uses ").append(s).append("\n"));
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   364
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   365
        md.provides().stream()
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   366
                .sorted(Comparator.comparing(Provides::service))
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   367
                .forEach(p -> sb.append("provides ").append(p.service())
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   368
                                .append(" with")
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   369
                                .append(toString(p.providers()))
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   370
                                .append("\n"));
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   371
45004
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   372
        // qualified exports
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   373
        md.exports().stream()
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   374
                .sorted(Comparator.comparing(Exports::source))
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   375
                .filter(Exports::isQualified)
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   376
                .forEach(e -> sb.append("qualified exports ").append(e.source())
50130
aefd3c7f5373 8191533: jar --describe-module prints service provider class names in lower case
sherman
parents: 48543
diff changeset
   377
                                .append(" to").append(toLowerCaseString(e.targets()))
45004
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   378
                                .append("\n"));
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   379
45004
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   380
        // open packages
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   381
        md.opens().stream()
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   382
                .sorted(Comparator.comparing(Opens::source))
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   383
                .filter(o -> !o.isQualified())
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   384
                .forEach(o -> sb.append("opens ").append(o.source())
50130
aefd3c7f5373 8191533: jar --describe-module prints service provider class names in lower case
sherman
parents: 48543
diff changeset
   385
                                 .append(toLowerCaseString(o.modifiers()))
45004
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   386
                                 .append("\n"));
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   387
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   388
        md.opens().stream()
45004
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   389
                .sorted(Comparator.comparing(Opens::source))
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   390
                .filter(Opens::isQualified)
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   391
                .forEach(o -> sb.append("qualified opens ").append(o.source())
50130
aefd3c7f5373 8191533: jar --describe-module prints service provider class names in lower case
sherman
parents: 48543
diff changeset
   392
                                 .append(toLowerCaseString(o.modifiers()))
aefd3c7f5373 8191533: jar --describe-module prints service provider class names in lower case
sherman
parents: 48543
diff changeset
   393
                                 .append(" to").append(toLowerCaseString(o.targets()))
45004
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   394
                                 .append("\n"));
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   395
45004
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   396
        // non-exported/non-open packages
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   397
        Set<String> concealed = new TreeSet<>(md.packages());
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   398
        md.exports().stream().map(Exports::source).forEach(concealed::remove);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   399
        md.opens().stream().map(Opens::source).forEach(concealed::remove);
45004
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   400
        concealed.forEach(p -> sb.append("contains ").append(p).append("\n"));
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   401
45004
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   402
        md.mainClass().ifPresent(v -> sb.append("main-class ").append(v).append("\n"));
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   403
44359
c6761862ca0b 8174823: Module system implementation refresh (3/2017)
alanb
parents: 43712
diff changeset
   404
        if (target != null) {
45004
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   405
            String targetPlatform = target.targetPlatform();
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   406
            if (!targetPlatform.isEmpty())
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   407
                sb.append("platform ").append(targetPlatform).append("\n");
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   408
       }
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   409
45004
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   410
       if (hashes != null) {
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   411
           hashes.names().stream().sorted().forEach(
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   412
                   mod -> sb.append("hashes ").append(mod).append(" ")
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   413
                            .append(hashes.algorithm()).append(" ")
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   414
                            .append(toHex(hashes.hashFor(mod)))
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   415
                            .append("\n"));
42703
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
   416
        }
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   417
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   418
        out.println(sb.toString());
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   419
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   420
42703
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
   421
    private String toHex(byte[] ba) {
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
   422
        StringBuilder sb = new StringBuilder(ba.length);
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
   423
        for (byte b: ba) {
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
   424
            sb.append(String.format("%02x", b & 0xff));
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
   425
        }
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
   426
        return sb.toString();
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
   427
    }
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
   428
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   429
    private boolean create() throws IOException {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   430
        JmodFileWriter jmod = new JmodFileWriter();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   431
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   432
        // create jmod with temporary name to avoid it being examined
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   433
        // when scanning the module path
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   434
        Path target = options.jmodFile;
43242
6c33c81be927 8173096: jmod files are not world-readable
mchung
parents: 43109
diff changeset
   435
        Path tempTarget = jmodTempFilePath(target);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   436
        try {
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   437
            try (JmodOutputStream jos = JmodOutputStream.newOutputStream(tempTarget)) {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   438
                jmod.write(jos);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   439
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   440
            Files.move(tempTarget, target);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   441
        } catch (Exception e) {
43242
6c33c81be927 8173096: jmod files are not world-readable
mchung
parents: 43109
diff changeset
   442
            try {
6c33c81be927 8173096: jmod files are not world-readable
mchung
parents: 43109
diff changeset
   443
                Files.deleteIfExists(tempTarget);
6c33c81be927 8173096: jmod files are not world-readable
mchung
parents: 43109
diff changeset
   444
            } catch (IOException ioe) {
6c33c81be927 8173096: jmod files are not world-readable
mchung
parents: 43109
diff changeset
   445
                e.addSuppressed(ioe);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   446
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   447
            throw e;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   448
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   449
        return true;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   450
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   451
43242
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
     * Create a JMOD .tmp file for the given target JMOD file
6c33c81be927 8173096: jmod files are not world-readable
mchung
parents: 43109
diff changeset
   454
     */
6c33c81be927 8173096: jmod files are not world-readable
mchung
parents: 43109
diff changeset
   455
    private static Path jmodTempFilePath(Path target) throws IOException {
6c33c81be927 8173096: jmod files are not world-readable
mchung
parents: 43109
diff changeset
   456
        return target.resolveSibling("." + target.getFileName() + ".tmp");
6c33c81be927 8173096: jmod files are not world-readable
mchung
parents: 43109
diff changeset
   457
    }
6c33c81be927 8173096: jmod files are not world-readable
mchung
parents: 43109
diff changeset
   458
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   459
    private class JmodFileWriter {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   460
        final List<Path> cmds = options.cmds;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   461
        final List<Path> libs = options.libs;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   462
        final List<Path> configs = options.configs;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   463
        final List<Path> classpath = options.classpath;
41561
0c6942d13f2e 8167558: Add new JMOD section for header files and man pages
mchung
parents: 41484
diff changeset
   464
        final List<Path> headerFiles = options.headerFiles;
0c6942d13f2e 8167558: Add new JMOD section for header files and man pages
mchung
parents: 41484
diff changeset
   465
        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
   466
        final List<Path> legalNotices = options.legalNotices;
41561
0c6942d13f2e 8167558: Add new JMOD section for header files and man pages
mchung
parents: 41484
diff changeset
   467
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   468
        final Version moduleVersion = options.moduleVersion;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   469
        final String mainClass = options.mainClass;
45004
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   470
        final String targetPlatform = options.targetPlatform;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   471
        final List<PathMatcher> excludes = options.excludes;
42703
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
   472
        final ModuleResolution moduleResolution = options.moduleResolution;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   473
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   474
        JmodFileWriter() { }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   475
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   476
        /**
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   477
         * Writes the jmod to the given output stream.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   478
         */
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   479
        void write(JmodOutputStream out) throws IOException {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   480
            // module-info.class
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   481
            writeModuleInfo(out, findPackages(classpath));
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   482
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   483
            // classes
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   484
            processClasses(out, classpath);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   485
42670
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
   486
            processSection(out, Section.CONFIG, configs);
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
   487
            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
   488
            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
   489
            processSection(out, Section.MAN_PAGES, manPages);
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   490
            processSection(out, Section.NATIVE_CMDS, cmds);
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   491
            processSection(out, Section.NATIVE_LIBS, libs);
41561
0c6942d13f2e 8167558: Add new JMOD section for header files and man pages
mchung
parents: 41484
diff changeset
   492
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   493
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   494
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   495
        /**
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   496
         * Returns a supplier of an input stream to the module-info.class
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   497
         * on the class path of directories and JAR files.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   498
         */
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   499
        Supplier<InputStream> newModuleInfoSupplier() throws IOException {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   500
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   501
            for (Path e: classpath) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   502
                if (Files.isDirectory(e)) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   503
                    Path mi = e.resolve(MODULE_INFO);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   504
                    if (Files.isRegularFile(mi)) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   505
                        Files.copy(mi, baos);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   506
                        break;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   507
                    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   508
                } else if (Files.isRegularFile(e) && e.toString().endsWith(".jar")) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   509
                    try (JarFile jf = new JarFile(e.toFile())) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   510
                        ZipEntry entry = jf.getEntry(MODULE_INFO);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   511
                        if (entry != null) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   512
                            jf.getInputStream(entry).transferTo(baos);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   513
                            break;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   514
                        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   515
                    } catch (ZipException x) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   516
                        // Skip. Do nothing. No packages will be added.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   517
                    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   518
                }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   519
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   520
            if (baos.size() == 0) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   521
                return null;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   522
            } else {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   523
                byte[] bytes = baos.toByteArray();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   524
                return () -> new ByteArrayInputStream(bytes);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   525
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   526
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   527
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   528
        /**
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   529
         * Writes the updated module-info.class to the ZIP output stream.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   530
         *
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   531
         * The updated module-info.class will have a Packages attribute
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   532
         * with the set of module-private/non-exported packages.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   533
         *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   534
         * If --module-version, --main-class, or other options were provided
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   535
         * then the corresponding class file attributes are added to the
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   536
         * module-info here.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   537
         */
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   538
        void writeModuleInfo(JmodOutputStream out, Set<String> packages)
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   539
            throws IOException
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   540
        {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   541
            Supplier<InputStream> miSupplier = newModuleInfoSupplier();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   542
            if (miSupplier == null) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   543
                throw new IOException(MODULE_INFO + " not found");
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
            ModuleDescriptor descriptor;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   547
            try (InputStream in = miSupplier.get()) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   548
                descriptor = ModuleDescriptor.read(in);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   549
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   550
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   551
            // copy the module-info.class into the jmod with the additional
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   552
            // attributes for the version, main class and other meta data
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   553
            try (InputStream in = miSupplier.get()) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   554
                ModuleInfoExtender extender = ModuleInfoExtender.newExtender(in);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   555
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   556
                // Add (or replace) the Packages attribute
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   557
                if (packages != null) {
42922
9111fb672357 8170618: jmod should validate if any exported or open package is missing
sundar
parents: 42704
diff changeset
   558
                    validatePackages(descriptor, packages);
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   559
                    extender.packages(packages);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   560
                }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   561
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   562
                // --main-class
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   563
                if (mainClass != null)
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   564
                    extender.mainClass(mainClass);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   565
45004
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   566
                // --target-platform
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   567
                if (targetPlatform != null) {
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   568
                    extender.targetPlatform(targetPlatform);
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
   569
                }
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   570
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   571
                // --module-version
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   572
                if (moduleVersion != null)
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   573
                    extender.version(moduleVersion);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   574
43109
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   575
                // --hash-modules
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   576
                if (options.modulesToHash != null) {
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   577
                    // To compute hashes, it creates a Configuration to resolve
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   578
                    // a module graph.  The post-resolution check requires
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   579
                    // the packages in ModuleDescriptor be available for validation.
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   580
                    ModuleDescriptor md;
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   581
                    try (InputStream is = miSupplier.get()) {
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   582
                        md = ModuleDescriptor.read(is, () -> packages);
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   583
                    }
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   584
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   585
                    ModuleHashes moduleHashes = computeHashes(md);
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   586
                    if (moduleHashes != null) {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   587
                        extender.hashes(moduleHashes);
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   588
                    } else {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   589
                        warning("warn.no.module.hashes", descriptor.name());
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   590
                    }
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   591
                }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   592
42703
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
   593
                if (moduleResolution != null && moduleResolution.value() != 0) {
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
   594
                    extender.moduleResolution(moduleResolution);
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
   595
                }
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
   596
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   597
                // write the (possibly extended or modified) module-info.class
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   598
                out.writeEntry(extender.toByteArray(), Section.CLASSES, MODULE_INFO);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   599
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   600
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   601
42922
9111fb672357 8170618: jmod should validate if any exported or open package is missing
sundar
parents: 42704
diff changeset
   602
        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
   603
            Set<String> nonExistPackages = new TreeSet<>();
9111fb672357 8170618: jmod should validate if any exported or open package is missing
sundar
parents: 42704
diff changeset
   604
            descriptor.exports().stream()
9111fb672357 8170618: jmod should validate if any exported or open package is missing
sundar
parents: 42704
diff changeset
   605
                .map(Exports::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
            descriptor.opens().stream()
9111fb672357 8170618: jmod should validate if any exported or open package is missing
sundar
parents: 42704
diff changeset
   610
                .map(Opens::source)
9111fb672357 8170618: jmod should validate if any exported or open package is missing
sundar
parents: 42704
diff changeset
   611
                .filter(pn -> !packages.contains(pn))
9111fb672357 8170618: jmod should validate if any exported or open package is missing
sundar
parents: 42704
diff changeset
   612
                .forEach(nonExistPackages::add);
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
            if (!nonExistPackages.isEmpty()) {
9111fb672357 8170618: jmod should validate if any exported or open package is missing
sundar
parents: 42704
diff changeset
   615
                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
   616
                    descriptor.name(), nonExistPackages);
9111fb672357 8170618: jmod should validate if any exported or open package is missing
sundar
parents: 42704
diff changeset
   617
            }
9111fb672357 8170618: jmod should validate if any exported or open package is missing
sundar
parents: 42704
diff changeset
   618
        }
9111fb672357 8170618: jmod should validate if any exported or open package is missing
sundar
parents: 42704
diff changeset
   619
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   620
        /*
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   621
         * Hasher resolves a module graph using the --hash-modules PATTERN
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   622
         * as the roots.
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   623
         *
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   624
         * 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
   625
         * given modulepath.
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   626
         */
43109
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   627
        private ModuleHashes computeHashes(ModuleDescriptor descriptor) {
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   628
            String mn = descriptor.name();
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   629
            URI uri = options.jmodFile.toUri();
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   630
            ModuleReference mref = new ModuleReference(descriptor, uri) {
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   631
                @Override
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   632
                public ModuleReader open() {
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   633
                    throw new UnsupportedOperationException("opening " + mn);
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   634
                }
43109
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   635
            };
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   636
43109
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   637
            // compose a module finder with the module path and also
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   638
            // a module finder that can find the jmod file being created
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   639
            ModuleFinder finder = ModuleFinder.compose(options.moduleFinder,
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   640
                new ModuleFinder() {
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   641
                    @Override
43109
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   642
                    public Optional<ModuleReference> find(String name) {
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   643
                        if (descriptor.name().equals(name))
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   644
                            return Optional.of(mref);
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   645
                        else return Optional.empty();
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   646
                    }
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   647
43109
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   648
                    @Override
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   649
                    public Set<ModuleReference> findAll() {
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   650
                        return Collections.singleton(mref);
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   651
                    }
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   652
                });
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   653
43109
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   654
            return new Hasher(mn, finder).computeHashes().get(mn);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   655
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   656
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   657
        /**
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   658
         * Returns the set of all packages on the given class path.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   659
         */
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   660
        Set<String> findPackages(List<Path> classpath) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   661
            Set<String> packages = new HashSet<>();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   662
            for (Path path : classpath) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   663
                if (Files.isDirectory(path)) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   664
                    packages.addAll(findPackages(path));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   665
                } else if (Files.isRegularFile(path) && path.toString().endsWith(".jar")) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   666
                    try (JarFile jf = new JarFile(path.toString())) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   667
                        packages.addAll(findPackages(jf));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   668
                    } catch (ZipException x) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   669
                        // Skip. Do nothing. No packages will be added.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   670
                    } catch (IOException ioe) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   671
                        throw new UncheckedIOException(ioe);
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
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   675
            return packages;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   676
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   677
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   678
        /**
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   679
         * Returns the set of packages in the given directory tree.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   680
         */
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   681
        Set<String> findPackages(Path dir) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   682
            try {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   683
                return Files.find(dir, Integer.MAX_VALUE,
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   684
                                  ((path, attrs) -> attrs.isRegularFile()))
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   685
                        .map(dir::relativize)
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   686
                        .filter(path -> isResource(path.toString()))
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   687
                        .map(path -> toPackageName(path))
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   688
                        .filter(pkg -> pkg.length() > 0)
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   689
                        .distinct()
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   690
                        .collect(Collectors.toSet());
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   691
            } catch (IOException ioe) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   692
                throw new UncheckedIOException(ioe);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   693
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   694
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   695
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   696
        /**
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   697
         * Returns the set of packages in the given JAR file.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   698
         */
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   699
        Set<String> findPackages(JarFile jf) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   700
            return jf.stream()
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   701
                     .filter(e -> !e.isDirectory() && isResource(e.getName()))
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   702
                     .map(e -> toPackageName(e))
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   703
                     .filter(pkg -> pkg.length() > 0)
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   704
                     .distinct()
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   705
                     .collect(Collectors.toSet());
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   706
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   707
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   708
        /**
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   709
         * 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
   710
         * package name.
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
        boolean isResource(String name) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   713
            name = name.replace(File.separatorChar, '/');
44359
c6761862ca0b 8174823: Module system implementation refresh (3/2017)
alanb
parents: 43712
diff changeset
   714
            return name.endsWith(".class") || Resources.canEncapsulate(name);
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   715
        }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   716
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   717
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   718
        String toPackageName(Path path) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   719
            String name = path.toString();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   720
            int index = name.lastIndexOf(File.separatorChar);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   721
            if (index != -1)
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   722
                return name.substring(0, index).replace(File.separatorChar, '.');
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   723
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   724
            if (name.endsWith(".class") && !name.equals(MODULE_INFO)) {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   725
                IOException e = new IOException(name  + " in the unnamed package");
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   726
                throw new UncheckedIOException(e);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   727
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   728
            return "";
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   729
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   730
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   731
        String toPackageName(ZipEntry entry) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   732
            String name = entry.getName();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   733
            int index = name.lastIndexOf("/");
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   734
            if (index != -1)
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   735
                return name.substring(0, index).replace('/', '.');
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   736
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   737
            if (name.endsWith(".class") && !name.equals(MODULE_INFO)) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   738
                IOException e = new IOException(name  + " in the unnamed package");
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   739
                throw new UncheckedIOException(e);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   740
            }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   741
            return "";
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   742
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   743
41561
0c6942d13f2e 8167558: Add new JMOD section for header files and man pages
mchung
parents: 41484
diff changeset
   744
        void processClasses(JmodOutputStream out, List<Path> classpaths)
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   745
            throws IOException
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   746
        {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   747
            if (classpaths == null)
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   748
                return;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   749
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   750
            for (Path p : classpaths) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   751
                if (Files.isDirectory(p)) {
41561
0c6942d13f2e 8167558: Add new JMOD section for header files and man pages
mchung
parents: 41484
diff changeset
   752
                    processSection(out, Section.CLASSES, p);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   753
                } else if (Files.isRegularFile(p) && p.toString().endsWith(".jar")) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   754
                    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
   755
                        JarEntryConsumer jec = new JarEntryConsumer(out, jf);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   756
                        jf.stream().filter(jec).forEach(jec);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   757
                    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   758
                }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   759
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   760
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   761
41561
0c6942d13f2e 8167558: Add new JMOD section for header files and man pages
mchung
parents: 41484
diff changeset
   762
        void processSection(JmodOutputStream out, Section section, List<Path> paths)
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   763
            throws IOException
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   764
        {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   765
            if (paths == null)
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   766
                return;
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
            for (Path p : paths) {
41561
0c6942d13f2e 8167558: Add new JMOD section for header files and man pages
mchung
parents: 41484
diff changeset
   769
                processSection(out, section, p);
42670
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
   770
            }
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   771
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   772
42670
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
   773
        void processSection(JmodOutputStream out, Section section, Path path)
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   774
            throws IOException
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   775
        {
42670
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
   776
            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
   777
                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
   778
                    @Override
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
   779
                    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
   780
                        throws IOException
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
   781
                    {
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
   782
                        Path relPath = path.relativize(file);
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
   783
                        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
   784
                                && !Section.CLASSES.equals(section))
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
   785
                            warning("warn.ignore.entry", MODULE_INFO, section);
39882
2a5433a2eca5 8134779: (jmod) ZipException is thrown if there are duplicate resources
chegar
parents: 39150
diff changeset
   786
42670
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
   787
                        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
   788
                                && !matches(relPath, excludes)) {
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
   789
                            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
   790
                                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
   791
                            } catch (IOException x) {
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
   792
                                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
   793
                                    warning("warn.ignore.duplicate.entry",
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
   794
                                            relPath.toString(), section);
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
   795
                                    return FileVisitResult.CONTINUE;
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
   796
                                }
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
   797
                                throw x;
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   798
                            }
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   799
                        }
42670
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
   800
                        return FileVisitResult.CONTINUE;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   801
                    }
42670
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
   802
                });
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   803
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   804
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   805
        boolean matches(Path path, List<PathMatcher> matchers) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   806
            if (matchers != null) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   807
                for (PathMatcher pm : matchers) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   808
                    if (pm.matches(path))
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   809
                        return true;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   810
                }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   811
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   812
            return false;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   813
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   814
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   815
        class JarEntryConsumer implements Consumer<JarEntry>, Predicate<JarEntry> {
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   816
            final JmodOutputStream out;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   817
            final JarFile jarfile;
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   818
            JarEntryConsumer(JmodOutputStream out, JarFile jarfile) {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   819
                this.out = out;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   820
                this.jarfile = jarfile;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   821
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   822
            @Override
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   823
            public void accept(JarEntry je) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   824
                try (InputStream in = jarfile.getInputStream(je)) {
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   825
                    out.writeEntry(in, Section.CLASSES, je.getName());
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   826
                } catch (IOException e) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   827
                    throw new UncheckedIOException(e);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   828
                }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   829
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   830
            @Override
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   831
            public boolean test(JarEntry je) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   832
                String name = je.getName();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   833
                // ## no support for excludes. Is it really needed?
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   834
                return !name.endsWith(MODULE_INFO) && !je.isDirectory();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   835
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   836
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   837
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   838
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   839
    /**
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   840
     * Compute and record hashes
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   841
     */
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   842
    private class Hasher {
43109
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   843
        final Configuration configuration;
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   844
        final ModuleHashesBuilder hashesBuilder;
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   845
        final Set<String> modules;
43109
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   846
        final String moduleName;  // a specific module to record hashes, if set
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   847
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   848
        /**
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   849
         * This constructor is for jmod hash command.
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   850
         *
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   851
         * This Hasher will determine which modules to record hashes, i.e.
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   852
         * 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
   853
         * 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
   854
         * 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
   855
         * directly or indirectly matching the specified --hash-modules pattern.
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   856
         */
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   857
        Hasher(ModuleFinder finder) {
43109
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   858
            this(null, finder);
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   859
        }
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   860
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   861
        /**
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   862
         * Constructs a Hasher to compute hashes.
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
         * 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
   865
         * modules that depend upon M directly or indirectly matching the
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   866
         * specified --hash-modules pattern and record in the ModuleHashes
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   867
         * attribute in M's module-info.class.
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   868
         *
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   869
         * @param name    name of the module to record hashes
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   870
         * @param finder  module finder for the specified --module-path
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   871
         */
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   872
        Hasher(String name, ModuleFinder finder) {
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   873
            // Determine the modules that matches the pattern {@code modulesToHash}
43109
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   874
            Set<String> roots = finder.findAll().stream()
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   875
                .map(mref -> mref.descriptor().name())
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   876
                .filter(mn -> options.modulesToHash.matcher(mn).find())
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   877
                .collect(Collectors.toSet());
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   878
43109
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   879
            // use system module path unless it creates a JMOD file for
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   880
            // 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
   881
            // module
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   882
            ModuleFinder system;
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   883
            if (name != null && ModuleFinder.ofSystem().find(name).isPresent()) {
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   884
                system = ModuleFinder.of();
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   885
            } else {
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   886
                system = ModuleFinder.ofSystem();
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   887
            }
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   888
            // get a resolved module graph
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   889
            Configuration config = null;
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   890
            try {
43712
5dfd0950317c 8173393: Module system implementation refresh (2/2017)
alanb
parents: 43242
diff changeset
   891
                config = Configuration.empty().resolve(system, finder, roots);
5dfd0950317c 8173393: Module system implementation refresh (2/2017)
alanb
parents: 43242
diff changeset
   892
            } catch (FindException | ResolutionException e) {
43109
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   893
                throw new CommandException("err.module.resolution.fail", e.getMessage());
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   894
            }
43109
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   895
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   896
            this.moduleName = name;
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   897
            this.configuration = config;
43109
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   898
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   899
            // filter modules resolved from the system module finder
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   900
            this.modules = config.modules().stream()
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   901
                .map(ResolvedModule::name)
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   902
                .filter(mn -> roots.contains(mn) && !system.find(mn).isPresent())
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   903
                .collect(Collectors.toSet());
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   904
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   905
            this.hashesBuilder = new ModuleHashesBuilder(config, modules);
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   906
        }
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   907
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   908
        /**
43109
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   909
         * 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
   910
         * that depend upon M directly or indirectly.
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   911
         *
43109
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   912
         * For jmod hash command, the returned map contains one entry
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   913
         * 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
   914
         * modules matching the specified --hash-modules pattern.
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
         * Each entry represents a leaf node in a connected subgraph containing
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   917
         * 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
   918
         * edges to any module other than the ones matching the specified
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   919
         * --hash-modules pattern are excluded.
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   920
         */
43109
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   921
        Map<String, ModuleHashes> computeHashes() {
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   922
            if (hashesBuilder == null)
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   923
                return null;
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   924
43109
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   925
            if (moduleName != null) {
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   926
                return hashesBuilder.computeHashes(Set.of(moduleName));
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   927
            } else {
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   928
                return hashesBuilder.computeHashes(modules);
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   929
            }
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
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   932
        /**
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   933
         * Reads the given input stream of module-info.class and write
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   934
         * the extended module-info.class with the given ModuleHashes
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   935
         *
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   936
         * @param in       InputStream of module-info.class
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   937
         * @param out      OutputStream to write the extended module-info.class
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   938
         * @param hashes   ModuleHashes
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   939
         */
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   940
        private void recordHashes(InputStream in, OutputStream out, ModuleHashes hashes)
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   941
            throws IOException
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   942
        {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   943
            ModuleInfoExtender extender = ModuleInfoExtender.newExtender(in);
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   944
            extender.hashes(hashes);
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   945
            extender.write(out);
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   946
        }
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   947
43109
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   948
        void updateModuleInfo(String name, ModuleHashes moduleHashes)
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   949
            throws IOException
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   950
        {
43109
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
   951
            Path target = moduleToPath(name);
43242
6c33c81be927 8173096: jmod files are not world-readable
mchung
parents: 43109
diff changeset
   952
            Path tempTarget = jmodTempFilePath(target);
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   953
            try {
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   954
                if (target.getFileName().toString().endsWith(".jmod")) {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   955
                    updateJmodFile(target, tempTarget, moduleHashes);
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   956
                } else {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   957
                    updateModularJar(target, tempTarget, moduleHashes);
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   958
                }
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   959
            } catch (IOException|RuntimeException e) {
43242
6c33c81be927 8173096: jmod files are not world-readable
mchung
parents: 43109
diff changeset
   960
                try {
6c33c81be927 8173096: jmod files are not world-readable
mchung
parents: 43109
diff changeset
   961
                    Files.deleteIfExists(tempTarget);
6c33c81be927 8173096: jmod files are not world-readable
mchung
parents: 43109
diff changeset
   962
                } catch (IOException ioe) {
6c33c81be927 8173096: jmod files are not world-readable
mchung
parents: 43109
diff changeset
   963
                    e.addSuppressed(ioe);
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   964
                }
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   965
                throw e;
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
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   968
            out.println(getMessage("module.hashes.recorded", name));
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   969
            Files.move(tempTarget, target, StandardCopyOption.REPLACE_EXISTING);
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   970
        }
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   971
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   972
        private void updateModularJar(Path target, Path tempTarget,
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   973
                                      ModuleHashes moduleHashes)
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   974
            throws IOException
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   975
        {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   976
            try (JarFile jf = new JarFile(target.toFile());
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   977
                 OutputStream out = Files.newOutputStream(tempTarget);
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   978
                 JarOutputStream jos = new JarOutputStream(out))
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   979
            {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   980
                jf.stream().forEach(e -> {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   981
                    try (InputStream in = jf.getInputStream(e)) {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   982
                        if (e.getName().equals(MODULE_INFO)) {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   983
                            // what about module-info.class in versioned entries?
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   984
                            ZipEntry ze = new ZipEntry(e.getName());
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   985
                            ze.setTime(System.currentTimeMillis());
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   986
                            jos.putNextEntry(ze);
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   987
                            recordHashes(in, jos, moduleHashes);
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   988
                            jos.closeEntry();
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   989
                        } else {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   990
                            jos.putNextEntry(e);
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   991
                            jos.write(in.readAllBytes());
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   992
                            jos.closeEntry();
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
                    } catch (IOException x) {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   995
                        throw new UncheckedIOException(x);
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   996
                    }
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   997
                });
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   998
            }
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
        private void updateJmodFile(Path target, Path tempTarget,
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
  1002
                                    ModuleHashes moduleHashes)
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
  1003
            throws IOException
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
  1004
        {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
  1005
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
  1006
            try (JmodFile jf = new JmodFile(target);
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
  1007
                 JmodOutputStream jos = JmodOutputStream.newOutputStream(tempTarget))
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
  1008
            {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
  1009
                jf.stream().forEach(e -> {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
  1010
                    try (InputStream in = jf.getInputStream(e.section(), e.name())) {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
  1011
                        if (e.name().equals(MODULE_INFO)) {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
  1012
                            // replace module-info.class
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
  1013
                            ModuleInfoExtender extender =
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
  1014
                                ModuleInfoExtender.newExtender(in);
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
  1015
                            extender.hashes(moduleHashes);
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
  1016
                            jos.writeEntry(extender.toByteArray(), e.section(), e.name());
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
  1017
                        } else {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
  1018
                            jos.writeEntry(in, e);
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
                    } catch (IOException x) {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
  1021
                        throw new UncheckedIOException(x);
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
  1022
                    }
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
  1023
                });
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
  1024
            }
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
  1025
        }
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
  1026
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1027
        private Path moduleToPath(String name) {
43109
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
  1028
            ResolvedModule rm = configuration.findModule(name).orElseThrow(
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1029
                () -> new InternalError("Selected module " + name + " not on module path"));
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1030
43109
fe275140c3f1 8160286: jmod hash is creating unlinkable modules
mchung
parents: 43067
diff changeset
  1031
            URI uri = rm.reference().location().get();
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1032
            Path path = Paths.get(uri);
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1033
            String fn = path.getFileName().toString();
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1034
            if (!fn.endsWith(".jar") && !fn.endsWith(".jmod")) {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1035
                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
  1036
            }
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1037
            return path;
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1038
        }
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1039
    }
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1040
43067
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
     * 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
  1043
     * 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
  1044
     * 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
  1045
     * 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
  1046
     */
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1047
    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
  1048
        @Override
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1049
        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
  1050
            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
  1051
            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
  1052
            for (String pathElement : pathElements) {
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1053
                paths.add(toPath(pathElement));
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1054
            }
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1055
            return paths;
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1056
        }
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
        @SuppressWarnings("unchecked")
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1059
        @Override
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1060
        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
  1061
            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
  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
        @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
  1065
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1066
        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
  1067
    }
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1068
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1069
    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
  1070
        static final ValueConverter<List<Path>> INSTANCE = new ClassPathConverter();
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1071
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1072
        @Override
43067
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1073
        public Path toPath(String value) {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1074
            try {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1075
                Path path = CWD.resolve(value);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1076
                if (Files.notExists(path))
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1077
                    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
  1078
                if (!(Files.isDirectory(path) ||
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1079
                        (Files.isRegularFile(path) && path.toString().endsWith(".jar"))))
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1080
                    throw new CommandException("err.invalid.class.path.entry", path);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1081
                return path;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1082
            } catch (InvalidPathException x) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1083
                throw new CommandException("err.path.not.valid", value);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1084
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1085
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1086
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1087
43067
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1088
    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
  1089
        static final ValueConverter<List<Path>> INSTANCE = new DirPathConverter();
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1090
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1091
        @Override
43067
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1092
        public Path toPath(String value) {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1093
            try {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1094
                Path path = CWD.resolve(value);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1095
                if (Files.notExists(path))
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1096
                    throw new CommandException("err.path.not.found", path);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1097
                if (!Files.isDirectory(path))
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1098
                    throw new CommandException("err.path.not.a.dir", path);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1099
                return path;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1100
            } catch (InvalidPathException x) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1101
                throw new CommandException("err.path.not.valid", value);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1102
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1103
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1104
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1105
42468
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
  1106
    static class ExtractDirPathConverter implements ValueConverter<Path> {
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
  1107
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
  1108
        @Override
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
  1109
        public Path convert(String value) {
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
  1110
            try {
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
  1111
                Path path = CWD.resolve(value);
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
  1112
                if (Files.exists(path)) {
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
  1113
                    if (!Files.isDirectory(path))
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
  1114
                        throw new CommandException("err.cannot.create.dir", path);
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
  1115
                }
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
  1116
                return path;
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
  1117
            } catch (InvalidPathException x) {
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
  1118
                throw new CommandException("err.path.not.valid", value);
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
  1119
            }
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
  1120
        }
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
  1121
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
  1122
        @Override  public Class<Path> valueType() { return Path.class; }
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
  1123
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
  1124
        @Override  public String valuePattern() { return "path"; }
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
  1125
    }
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
  1126
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1127
    static class ModuleVersionConverter implements ValueConverter<Version> {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1128
        @Override
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1129
        public Version convert(String value) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1130
            try {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1131
                return Version.parse(value);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1132
            } catch (IllegalArgumentException x) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1133
                throw new CommandException("err.invalid.version", x.getMessage());
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1134
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1135
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1136
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1137
        @Override public Class<Version> valueType() { return Version.class; }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1138
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1139
        @Override public String valuePattern() { return "module-version"; }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1140
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1141
42703
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1142
    static class WarnIfResolvedReasonConverter
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1143
        implements ValueConverter<ModuleResolution>
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1144
    {
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1145
        @Override
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1146
        public ModuleResolution convert(String value) {
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1147
            if (value.equals("deprecated"))
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1148
                return ModuleResolution.empty().withDeprecated();
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1149
            else if (value.equals("deprecated-for-removal"))
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1150
                return ModuleResolution.empty().withDeprecatedForRemoval();
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1151
            else if (value.equals("incubating"))
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1152
                return ModuleResolution.empty().withIncubating();
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1153
            else
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1154
                throw new CommandException("err.bad.WarnIfResolvedReason", value);
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
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1157
        @Override public Class<ModuleResolution> valueType() {
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1158
            return ModuleResolution.class;
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1159
        }
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1160
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1161
        @Override public String valuePattern() { return "reason"; }
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1162
    }
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1163
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1164
    static class PatternConverter implements ValueConverter<Pattern> {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1165
        @Override
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1166
        public Pattern convert(String value) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1167
            try {
38871
ec08bf1979d4 8158402: jlink: should use regex for all pattern operations (--order-resources or --exclude-resources)
jlaskey
parents: 37779
diff changeset
  1168
                if (value.startsWith("regex:")) {
ec08bf1979d4 8158402: jlink: should use regex for all pattern operations (--order-resources or --exclude-resources)
jlaskey
parents: 37779
diff changeset
  1169
                    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
  1170
                }
ec08bf1979d4 8158402: jlink: should use regex for all pattern operations (--order-resources or --exclude-resources)
jlaskey
parents: 37779
diff changeset
  1171
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1172
                return Pattern.compile(value);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1173
            } catch (PatternSyntaxException e) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1174
                throw new CommandException("err.bad.pattern", value);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1175
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1176
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1177
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1178
        @Override public Class<Pattern> valueType() { return Pattern.class; }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1179
39150
cb99396625b4 8159172: Update usage of jlink/jimage/jmod to show option patterns
jlaskey
parents: 39042
diff changeset
  1180
        @Override public String valuePattern() { return "regex-pattern"; }
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1181
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1182
38871
ec08bf1979d4 8158402: jlink: should use regex for all pattern operations (--order-resources or --exclude-resources)
jlaskey
parents: 37779
diff changeset
  1183
    static class PathMatcherConverter implements ValueConverter<PathMatcher> {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1184
        @Override
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1185
        public PathMatcher convert(String pattern) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1186
            try {
39042
52db877f18db 8159206: All jlink or jmod tests failing
jlaskey
parents: 38871
diff changeset
  1187
                return Utils.getPathMatcher(FileSystems.getDefault(), pattern);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1188
            } catch (PatternSyntaxException e) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1189
                throw new CommandException("err.bad.pattern", pattern);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1190
            }
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
        @Override public Class<PathMatcher> valueType() { return PathMatcher.class; }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1194
39150
cb99396625b4 8159172: Update usage of jlink/jimage/jmod to show option patterns
jlaskey
parents: 39042
diff changeset
  1195
        @Override public String valuePattern() { return "pattern-list"; }
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1196
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1197
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1198
    /* Support for @<file> in jmod help */
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1199
    private static final String CMD_FILENAME = "@<filename>";
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1200
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1201
    /**
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1202
     * This formatter is adding the @filename option and does the required
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1203
     * formatting.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1204
     */
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1205
    private static final class JmodHelpFormatter extends BuiltinHelpFormatter {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1206
42703
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1207
        private final Options opts;
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1208
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1209
        private JmodHelpFormatter(Options opts) {
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1210
            super(80, 2);
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1211
            this.opts = opts;
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1212
        }
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1213
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1214
        @Override
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1215
        public String format(Map<String, ? extends OptionDescriptor> options) {
42703
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1216
            Map<String, OptionDescriptor> all = new LinkedHashMap<>();
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1217
            all.putAll(options);
42703
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
            // extra options
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1220
            if (!opts.helpExtra) {
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1221
                all.remove("do-not-resolve-by-default");
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1222
                all.remove("warn-if-resolved");
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1223
            }
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1224
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1225
            all.put(CMD_FILENAME, new OptionDescriptor() {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1226
                @Override
50428
8c88df2e8a78 8203891: Upgrade JOpt Simple to 5.0.4
jlahoda
parents: 50130
diff changeset
  1227
                public List<String> options() {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1228
                    List<String> ret = new ArrayList<>();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1229
                    ret.add(CMD_FILENAME);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1230
                    return ret;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1231
                }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1232
                @Override
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1233
                public String description() { return getMessage("main.opt.cmdfile"); }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1234
                @Override
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1235
                public List<?> defaultValues() { return Collections.emptyList(); }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1236
                @Override
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1237
                public boolean isRequired() { return false; }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1238
                @Override
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1239
                public boolean acceptsArguments() { return false; }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1240
                @Override
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1241
                public boolean requiresArgument() { return false; }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1242
                @Override
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1243
                public String argumentDescription() { return null; }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1244
                @Override
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1245
                public String argumentTypeIndicator() { return null; }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1246
                @Override
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1247
                public boolean representsNonOptions() { return false; }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1248
            });
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1249
            String content = super.format(all);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1250
            StringBuilder builder = new StringBuilder();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1251
39150
cb99396625b4 8159172: Update usage of jlink/jimage/jmod to show option patterns
jlaskey
parents: 39042
diff changeset
  1252
            builder.append(getMessage("main.opt.mode")).append("\n  ");
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1253
            builder.append(getMessage("main.opt.mode.create")).append("\n  ");
42468
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
  1254
            builder.append(getMessage("main.opt.mode.extract")).append("\n  ");
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1255
            builder.append(getMessage("main.opt.mode.list")).append("\n  ");
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1256
            builder.append(getMessage("main.opt.mode.describe")).append("\n  ");
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1257
            builder.append(getMessage("main.opt.mode.hash")).append("\n\n");
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1258
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1259
            String cmdfile = null;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1260
            String[] lines = content.split("\n");
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1261
            for (String line : lines) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1262
                if (line.startsWith("--@")) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1263
                    cmdfile = line.replace("--" + CMD_FILENAME, CMD_FILENAME + "  ");
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1264
                } else if (line.startsWith("Option") || line.startsWith("------")) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1265
                    builder.append(" ").append(line).append("\n");
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1266
                } else if (!line.matches("Non-option arguments")){
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1267
                    builder.append("  ").append(line).append("\n");
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1268
                }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1269
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1270
            if (cmdfile != null) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1271
                builder.append("  ").append(cmdfile).append("\n");
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1272
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1273
            return builder.toString();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1274
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1275
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1276
40261
86a49ba76f52 8136930: Simplify use of module-system options by custom launchers
mchung
parents: 39882
diff changeset
  1277
    private final OptionParser parser = new OptionParser("hp");
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1278
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1279
    private void handleOptions(String[] args) {
42703
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1280
        options = new Options();
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1281
        parser.formatHelpWith(new JmodHelpFormatter(options));
36511
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>> classPath
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1284
                = parser.accepts("class-path", getMessage("main.opt.class-path"))
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1285
                        .withRequiredArg()
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1286
                        .withValuesConvertedBy(ClassPathConverter.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>> cmds
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1289
                = parser.accepts("cmds", getMessage("main.opt.cmds"))
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
43067
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1293
        OptionSpec<List<Path>> config
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1294
                = parser.accepts("config", getMessage("main.opt.config"))
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1295
                        .withRequiredArg()
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1296
                        .withValuesConvertedBy(DirPathConverter.INSTANCE);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1297
42468
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
  1298
        OptionSpec<Path> dir
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
  1299
                = parser.accepts("dir", getMessage("main.opt.extractDir"))
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
  1300
                        .withRequiredArg()
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
  1301
                        .withValuesConvertedBy(new ExtractDirPathConverter());
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
  1302
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1303
        OptionSpec<Void> dryrun
42670
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
  1304
                = parser.accepts("dry-run", getMessage("main.opt.dry-run"));
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1305
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1306
        OptionSpec<PathMatcher> excludes
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1307
                = parser.accepts("exclude", getMessage("main.opt.exclude"))
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1308
                        .withRequiredArg()
38871
ec08bf1979d4 8158402: jlink: should use regex for all pattern operations (--order-resources or --exclude-resources)
jlaskey
parents: 37779
diff changeset
  1309
                        .withValuesConvertedBy(new PathMatcherConverter());
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1310
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1311
        OptionSpec<Pattern> hashModules
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1312
                = parser.accepts("hash-modules", getMessage("main.opt.hash-modules"))
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1313
                        .withRequiredArg()
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1314
                        .withValuesConvertedBy(new PatternConverter());
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1315
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1316
        OptionSpec<Void> help
50428
8c88df2e8a78 8203891: Upgrade JOpt Simple to 5.0.4
jlahoda
parents: 50130
diff changeset
  1317
                = parser.acceptsAll(List.of("h", "help", "?"), getMessage("main.opt.help"))
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1318
                        .forHelp();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1319
42703
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1320
        OptionSpec<Void> helpExtra
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1321
                = parser.accepts("help-extra", getMessage("main.opt.help-extra"));
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
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>> headerFiles
42670
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
  1324
                = 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
  1325
                        .withRequiredArg()
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
  1326
                        .withValuesConvertedBy(DirPathConverter.INSTANCE);
41561
0c6942d13f2e 8167558: Add new JMOD section for header files and man pages
mchung
parents: 41484
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>> libs
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1329
                = parser.accepts("libs", getMessage("main.opt.libs"))
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1330
                        .withRequiredArg()
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1331
                        .withValuesConvertedBy(DirPathConverter.INSTANCE);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1332
43067
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1333
        OptionSpec<List<Path>> legalNotices
42670
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
  1334
                = 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
  1335
                        .withRequiredArg()
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
  1336
                        .withValuesConvertedBy(DirPathConverter.INSTANCE);
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
  1337
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
  1338
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1339
        OptionSpec<String> mainClass
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1340
                = parser.accepts("main-class", getMessage("main.opt.main-class"))
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1341
                        .withRequiredArg()
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1342
                        .describedAs(getMessage("main.opt.main-class.arg"));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
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>> manPages
42670
d833113eb7d7 8169925: Organize licenses by module in source, JMOD file, and run-time image
mchung
parents: 42468
diff changeset
  1345
                = 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
  1346
                        .withRequiredArg()
0c6942d13f2e 8167558: Add new JMOD section for header files and man pages
mchung
parents: 41484
diff changeset
  1347
                        .withValuesConvertedBy(DirPathConverter.INSTANCE);
0c6942d13f2e 8167558: Add new JMOD section for header files and man pages
mchung
parents: 41484
diff changeset
  1348
43067
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1349
        OptionSpec<List<Path>> modulePath
50428
8c88df2e8a78 8203891: Upgrade JOpt Simple to 5.0.4
jlahoda
parents: 50130
diff changeset
  1350
                = parser.acceptsAll(List.of("p", "module-path"),
40261
86a49ba76f52 8136930: Simplify use of module-system options by custom launchers
mchung
parents: 39882
diff changeset
  1351
                                    getMessage("main.opt.module-path"))
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1352
                        .withRequiredArg()
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1353
                        .withValuesConvertedBy(DirPathConverter.INSTANCE);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1354
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1355
        OptionSpec<Version> moduleVersion
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1356
                = parser.accepts("module-version", getMessage("main.opt.module-version"))
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1357
                        .withRequiredArg()
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1358
                        .withValuesConvertedBy(new ModuleVersionConverter());
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1359
45004
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
  1360
        OptionSpec<String> targetPlatform
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
  1361
                = parser.accepts("target-platform", getMessage("main.opt.target-platform"))
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1362
                        .withRequiredArg()
45004
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
  1363
                        .describedAs(getMessage("main.opt.target-platform.arg"));
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1364
42703
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1365
        OptionSpec<Void> doNotResolveByDefault
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1366
                = parser.accepts("do-not-resolve-by-default",
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1367
                                 getMessage("main.opt.do-not-resolve-by-default"));
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1368
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1369
        OptionSpec<ModuleResolution> warnIfResolved
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1370
                = parser.accepts("warn-if-resolved", getMessage("main.opt.warn-if-resolved"))
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1371
                        .withRequiredArg()
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1372
                        .withValuesConvertedBy(new WarnIfResolvedReasonConverter());
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1373
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1374
        OptionSpec<Void> version
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1375
                = parser.accepts("version", getMessage("main.opt.version"));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1376
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1377
        NonOptionArgumentSpec<String> nonOptions
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1378
                = parser.nonOptions();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1379
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1380
        try {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1381
            OptionSet opts = parser.parse(args);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1382
42703
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1383
            if (opts.has(help) || opts.has(helpExtra) || opts.has(version)) {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1384
                options.help = opts.has(help);
42703
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1385
                options.helpExtra = opts.has(helpExtra);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1386
                options.version = opts.has(version);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1387
                return;  // informational message will be shown
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1388
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1389
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1390
            List<String> words = opts.valuesOf(nonOptions);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1391
            if (words.isEmpty())
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1392
                throw new CommandException("err.missing.mode").showUsage(true);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1393
            String verb = words.get(0);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1394
            try {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1395
                options.mode = Enum.valueOf(Mode.class, verb.toUpperCase());
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1396
            } catch (IllegalArgumentException e) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1397
                throw new CommandException("err.invalid.mode", verb).showUsage(true);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1398
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1399
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1400
            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
  1401
                options.classpath = getLastElement(opts.valuesOf(classPath));
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1402
            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
  1403
                options.cmds = getLastElement(opts.valuesOf(cmds));
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1404
            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
  1405
                options.configs = getLastElement(opts.valuesOf(config));
42468
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
  1406
            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
  1407
                options.extractDir = getLastElement(opts.valuesOf(dir));
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1408
            if (opts.has(dryrun))
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1409
                options.dryrun = true;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1410
            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
  1411
                options.excludes = opts.valuesOf(excludes);  // excludes is repeatable
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1412
            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
  1413
                options.libs = getLastElement(opts.valuesOf(libs));
41561
0c6942d13f2e 8167558: Add new JMOD section for header files and man pages
mchung
parents: 41484
diff changeset
  1414
            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
  1415
                options.headerFiles = getLastElement(opts.valuesOf(headerFiles));
41561
0c6942d13f2e 8167558: Add new JMOD section for header files and man pages
mchung
parents: 41484
diff changeset
  1416
            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
  1417
                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
  1418
            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
  1419
                options.legalNotices = getLastElement(opts.valuesOf(legalNotices));
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1420
            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
  1421
                Path[] dirs = getLastElement(opts.valuesOf(modulePath)).toArray(new Path[0]);
43712
5dfd0950317c 8173393: Module system implementation refresh (2/2017)
alanb
parents: 43242
diff changeset
  1422
                options.moduleFinder = ModulePath.of(Runtime.version(), true, dirs);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1423
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1424
            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
  1425
                options.moduleVersion = getLastElement(opts.valuesOf(moduleVersion));
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1426
            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
  1427
                options.mainClass = getLastElement(opts.valuesOf(mainClass));
45004
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
  1428
            if (opts.has(targetPlatform))
ea3137042a61 8178380: Module system implementation refresh (5/2017)
alanb
parents: 44359
diff changeset
  1429
                options.targetPlatform = getLastElement(opts.valuesOf(targetPlatform));
42703
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1430
            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
  1431
                options.moduleResolution = getLastElement(opts.valuesOf(warnIfResolved));
42703
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1432
            if (opts.has(doNotResolveByDefault)) {
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1433
                if (options.moduleResolution == null)
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1434
                    options.moduleResolution = ModuleResolution.empty();
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1435
                options.moduleResolution = options.moduleResolution.withDoNotResolveByDefault();
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42468
diff changeset
  1436
            }
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1437
            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
  1438
                options.modulesToHash = getLastElement(opts.valuesOf(hashModules));
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1439
                // if storing hashes then the module path is required
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1440
                if (options.moduleFinder == null)
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1441
                    throw new CommandException("err.modulepath.must.be.specified")
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1442
                            .showUsage(true);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1443
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1444
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1445
            if (options.mode.equals(Mode.HASH)) {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1446
                if (options.moduleFinder == null || options.modulesToHash == null)
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1447
                    throw new CommandException("err.modulepath.must.be.specified")
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1448
                            .showUsage(true);
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1449
            } else {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1450
                if (words.size() <= 1)
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1451
                    throw new CommandException("err.jmod.must.be.specified").showUsage(true);
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1452
                Path path = Paths.get(words.get(1));
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1453
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1454
                if (options.mode.equals(Mode.CREATE) && Files.exists(path))
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1455
                    throw new CommandException("err.file.already.exists", path);
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1456
                else if ((options.mode.equals(Mode.LIST) ||
42468
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
  1457
                            options.mode.equals(Mode.DESCRIBE) ||
7a9555a7e080 8166568: Add jmod extract subcommand
chegar
parents: 42338
diff changeset
  1458
                            options.mode.equals((Mode.EXTRACT)))
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1459
                         && Files.notExists(path))
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1460
                    throw new CommandException("err.jmod.not.found", 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 (options.dryrun) {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1463
                    throw new CommandException("err.invalid.dryrun.option");
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1464
                }
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1465
                options.jmodFile = path;
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1466
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1467
                if (words.size() > 2)
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1468
                    throw new CommandException("err.unknown.option",
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1469
                            words.subList(2, words.size())).showUsage(true);
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1470
            }
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1471
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1472
            if (options.mode.equals(Mode.CREATE) && options.classpath == null)
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1473
                throw new CommandException("err.classpath.must.be.specified").showUsage(true);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1474
            if (options.mainClass != null && !isValidJavaIdentifier(options.mainClass))
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1475
                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
  1476
            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
  1477
                try {
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1478
                    Files.createDirectories(options.extractDir);
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1479
                } catch (IOException ioe) {
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1480
                    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
  1481
                }
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1482
            }
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1483
        } catch (OptionException e) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1484
             throw new CommandException(e.getMessage());
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1485
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1486
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1487
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1488
    /**
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1489
     * Returns true if, and only if, the given main class is a legal.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1490
     */
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1491
    static boolean isValidJavaIdentifier(String mainClass) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1492
        if (mainClass.length() == 0)
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1493
            return false;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1494
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1495
        if (!Character.isJavaIdentifierStart(mainClass.charAt(0)))
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1496
            return false;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1497
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1498
        int n = mainClass.length();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1499
        for (int i=1; i < n; i++) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1500
            char c = mainClass.charAt(i);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1501
            if (!Character.isJavaIdentifierPart(c) && c != '.')
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1502
                return false;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1503
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1504
        if (mainClass.charAt(n-1) == '.')
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1505
            return false;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1506
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1507
        return true;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1508
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1509
43067
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1510
    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
  1511
        if (list.size() == 0)
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1512
            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
  1513
        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
  1514
    }
3f011a470ce2 8168149: Examine the behavior of jmod command-line options - repeating vs last one wins
chegar
parents: 42922
diff changeset
  1515
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1516
    private void reportError(String message) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1517
        out.println(getMessage("error.prefix") + " " + message);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1518
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1519
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1520
    private void warning(String key, Object... args) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1521
        out.println(getMessage("warn.prefix") + " " + getMessage(key, args));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1522
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1523
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1524
    private void showUsageSummary() {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1525
        out.println(getMessage("main.usage.summary", PROGNAME));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1526
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1527
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1528
    private void showHelp() {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1529
        out.println(getMessage("main.usage", PROGNAME));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1530
        try {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1531
            parser.printHelpOn(out);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1532
        } catch (IOException x) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1533
            throw new AssertionError(x);
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
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1537
    private void showVersion() {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1538
        out.println(version());
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1539
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1540
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1541
    private String version() {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1542
        return System.getProperty("java.version");
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1543
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1544
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1545
    private static String getMessage(String key, Object... args) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1546
        try {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1547
            return MessageFormat.format(ResourceBundleHelper.bundle.getString(key), args);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1548
        } catch (MissingResourceException e) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1549
            throw new InternalError("Missing message: " + key);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1550
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1551
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1552
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1553
    private static class ResourceBundleHelper {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1554
        static final ResourceBundle bundle;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1555
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1556
        static {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1557
            Locale locale = Locale.getDefault();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1558
            try {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1559
                bundle = ResourceBundle.getBundle("jdk.tools.jmod.resources.jmod", locale);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1560
            } catch (MissingResourceException e) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1561
                throw new InternalError("Cannot find jmod resource bundle for locale " + locale);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1562
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1563
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1564
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1565
}