jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/JmodTask.java
author alanb
Thu, 01 Dec 2016 08:57:53 +0000
changeset 42338 a60f280f803c
parent 41916 eb4aa81c6c5f
child 42468 7a9555a7e080
permissions -rw-r--r--
8169069: Module system implementation refresh (11/2016) Reviewed-by: plevart, chegar, psandoz, mchung, alanb, dfuchs, naoto, coffeys, weijun Contributed-by: alan.bateman@oracle.com, mandy.chung@oracle.com, claes.redestad@oracle.com, mark.reinhold@oracle.com
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
     1
/*
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
     2
 * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
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;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    34
import java.io.PrintStream;
41484
834b7539ada3 8164689: Retrofit jar, jlink, jmod as a ToolProvider
mchung
parents: 41352
diff changeset
    35
import java.io.PrintWriter;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    36
import java.io.UncheckedIOException;
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
    37
import java.lang.module.Configuration;
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;
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
    62
import java.util.ArrayDeque;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    63
import java.util.ArrayList;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    64
import java.util.Collection;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    65
import java.util.Collections;
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
    66
import java.util.Comparator;
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
    67
import java.util.Deque;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    68
import java.util.HashMap;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    69
import java.util.HashSet;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    70
import java.util.List;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    71
import java.util.Locale;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    72
import java.util.Map;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    73
import java.util.MissingResourceException;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    74
import java.util.Optional;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    75
import java.util.ResourceBundle;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    76
import java.util.Set;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    77
import java.util.function.Consumer;
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
    78
import java.util.function.Function;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    79
import java.util.function.Predicate;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    80
import java.util.function.Supplier;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    81
import java.util.jar.JarEntry;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    82
import java.util.jar.JarFile;
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
    83
import java.util.jar.JarOutputStream;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    84
import java.util.stream.Collectors;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    85
import java.util.regex.Pattern;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    86
import java.util.regex.PatternSyntaxException;
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
    87
import java.util.stream.Stream;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    88
import java.util.zip.ZipEntry;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    89
import java.util.zip.ZipException;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    90
import java.util.zip.ZipFile;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    91
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
    92
import jdk.internal.jmod.JmodFile;
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
    93
import jdk.internal.jmod.JmodFile.Section;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    94
import jdk.internal.joptsimple.BuiltinHelpFormatter;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    95
import jdk.internal.joptsimple.NonOptionArgumentSpec;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    96
import jdk.internal.joptsimple.OptionDescriptor;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    97
import jdk.internal.joptsimple.OptionException;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    98
import jdk.internal.joptsimple.OptionParser;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    99
import jdk.internal.joptsimple.OptionSet;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   100
import jdk.internal.joptsimple.OptionSpec;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   101
import jdk.internal.joptsimple.ValueConverter;
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   102
import jdk.internal.loader.ResourceHelper;
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   103
import jdk.internal.misc.JavaLangModuleAccess;
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   104
import jdk.internal.misc.SharedSecrets;
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   105
import jdk.internal.module.ModuleHashes;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   106
import jdk.internal.module.ModuleInfoExtender;
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
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   141
    private Options options;
41484
834b7539ada3 8164689: Retrofit jar, jlink, jmod as a ToolProvider
mchung
parents: 41352
diff changeset
   142
    private PrintWriter out = new PrintWriter(System.out, true);
834b7539ada3 8164689: Retrofit jar, jlink, jmod as a ToolProvider
mchung
parents: 41352
diff changeset
   143
    void setLog(PrintWriter out, PrintWriter err) {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   144
        this.out = out;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   145
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   146
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   147
    /* Result codes. */
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   148
    static final int EXIT_OK = 0, // Completed with no errors.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   149
                     EXIT_ERROR = 1, // Completed but reported errors.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   150
                     EXIT_CMDERR = 2, // Bad command-line arguments
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   151
                     EXIT_SYSERR = 3, // System error or resource exhaustion.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   152
                     EXIT_ABNORMAL = 4;// terminated abnormally
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   153
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   154
    enum Mode {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   155
        CREATE,
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   156
        LIST,
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   157
        DESCRIBE,
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   158
        HASH
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   159
    };
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   160
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   161
    static class Options {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   162
        Mode mode;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   163
        Path jmodFile;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   164
        boolean help;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   165
        boolean version;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   166
        List<Path> classpath;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   167
        List<Path> cmds;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   168
        List<Path> configs;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   169
        List<Path> libs;
41561
0c6942d13f2e 8167558: Add new JMOD section for header files and man pages
mchung
parents: 41484
diff changeset
   170
        List<Path> headerFiles;
0c6942d13f2e 8167558: Add new JMOD section for header files and man pages
mchung
parents: 41484
diff changeset
   171
        List<Path> manPages;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   172
        ModuleFinder moduleFinder;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   173
        Version moduleVersion;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   174
        String mainClass;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   175
        String osName;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   176
        String osArch;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   177
        String osVersion;
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   178
        Pattern modulesToHash;
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   179
        boolean dryrun;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   180
        List<PathMatcher> excludes;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   181
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   182
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   183
    public int run(String[] args) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   184
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   185
        try {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   186
            handleOptions(args);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   187
            if (options == null) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   188
                showUsageSummary();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   189
                return EXIT_CMDERR;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   190
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   191
            if (options.help) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   192
                showHelp();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   193
                return EXIT_OK;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   194
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   195
            if (options.version) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   196
                showVersion();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   197
                return EXIT_OK;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   198
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   199
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   200
            boolean ok;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   201
            switch (options.mode) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   202
                case CREATE:
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   203
                    ok = create();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   204
                    break;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   205
                case LIST:
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   206
                    ok = list();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   207
                    break;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   208
                case DESCRIBE:
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   209
                    ok = describe();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   210
                    break;
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   211
                case HASH:
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   212
                    ok = hashModules();
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   213
                    break;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   214
                default:
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   215
                    throw new AssertionError("Unknown mode: " + options.mode.name());
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   216
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   217
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   218
            return ok ? EXIT_OK : EXIT_ERROR;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   219
        } catch (CommandException e) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   220
            reportError(e.getMessage());
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   221
            if (e.showUsage)
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   222
                showUsageSummary();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   223
            return EXIT_CMDERR;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   224
        } catch (Exception x) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   225
            reportError(x.getMessage());
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   226
            x.printStackTrace();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   227
            return EXIT_ABNORMAL;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   228
        } finally {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   229
            out.flush();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   230
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   231
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   232
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   233
    private boolean list() throws IOException {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   234
        ZipFile zip = null;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   235
        try {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   236
            try {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   237
                zip = new ZipFile(options.jmodFile.toFile());
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   238
            } catch (IOException x) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   239
                throw new IOException("error opening jmod file", x);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   240
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   241
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   242
            // Trivially print the archive entries for now, pending a more complete implementation
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   243
            zip.stream().forEach(e -> out.println(e.getName()));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   244
            return true;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   245
        } finally {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   246
            if (zip != null)
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   247
                zip.close();
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
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   251
    private boolean hashModules() {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   252
        return new Hasher(options.moduleFinder).run();
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   253
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   254
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   255
    private boolean describe() throws IOException {
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   256
        try (JmodFile jf = new JmodFile(options.jmodFile)) {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   257
            try (InputStream in = jf.getInputStream(Section.CLASSES, MODULE_INFO)) {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   258
                ModuleDescriptor md = ModuleDescriptor.read(in);
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   259
                printModuleDescriptor(md);
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   260
                return true;
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   261
            } catch (IOException e) {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   262
                throw new CommandException("err.module.descriptor.not.found");
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   263
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   264
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   265
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   266
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   267
    static <T> String toString(Collection<T> c) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   268
        if (c.isEmpty()) { return ""; }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   269
        return c.stream().map(e -> e.toString().toLowerCase(Locale.ROOT))
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   270
                  .collect(joining(" "));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   271
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   272
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   273
    private static final JavaLangModuleAccess JLMA = SharedSecrets.getJavaLangModuleAccess();
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   274
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   275
    private void printModuleDescriptor(ModuleDescriptor md)
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   276
        throws IOException
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   277
    {
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   278
        StringBuilder sb = new StringBuilder();
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   279
        sb.append("\n").append(md.toNameAndVersion());
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   280
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   281
        md.requires().stream()
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   282
            .sorted(Comparator.comparing(Requires::name))
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   283
            .forEach(r -> {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   284
                sb.append("\n  requires ");
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   285
                if (!r.modifiers().isEmpty())
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   286
                    sb.append(toString(r.modifiers())).append(" ");
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   287
                sb.append(r.name());
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   288
            });
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   289
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   290
        md.uses().stream().sorted()
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   291
            .forEach(s -> sb.append("\n  uses ").append(s));
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   292
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   293
        md.exports().stream()
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   294
            .sorted(Comparator.comparing(Exports::source))
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   295
            .forEach(p -> sb.append("\n  exports ").append(p));
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   296
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   297
        md.opens().stream()
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   298
            .sorted(Comparator.comparing(Opens::source))
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   299
            .forEach(p -> sb.append("\n  opens ").append(p));
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   300
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   301
        Set<String> concealed = new HashSet<>(md.packages());
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   302
        md.exports().stream().map(Exports::source).forEach(concealed::remove);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   303
        md.opens().stream().map(Opens::source).forEach(concealed::remove);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   304
        concealed.stream().sorted()
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   305
                 .forEach(p -> sb.append("\n  contains ").append(p));
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   306
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   307
        md.provides().stream()
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   308
            .sorted(Comparator.comparing(Provides::service))
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   309
            .forEach(p -> sb.append("\n  provides ").append(p.service())
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   310
                            .append(" with ")
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   311
                            .append(toString(p.providers())));
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   312
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   313
        md.mainClass().ifPresent(v -> sb.append("\n  main-class " + v));
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   314
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   315
        md.osName().ifPresent(v -> sb.append("\n  operating-system-name " + v));
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   316
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   317
        md.osArch().ifPresent(v -> sb.append("\n  operating-system-architecture " + v));
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   318
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   319
        md.osVersion().ifPresent(v -> sb.append("\n  operating-system-version " + v));
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   320
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   321
        JLMA.hashes(md).ifPresent(
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   322
            hashes -> hashes.names().stream().sorted().forEach(
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   323
                mod -> sb.append("\n  hashes ").append(mod).append(" ")
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   324
                         .append(hashes.algorithm()).append(" ")
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   325
                         .append(hashes.hashFor(mod))));
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   326
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   327
        out.println(sb.toString());
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   328
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   329
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   330
    private boolean create() throws IOException {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   331
        JmodFileWriter jmod = new JmodFileWriter();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   332
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   333
        // create jmod with temporary name to avoid it being examined
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   334
        // when scanning the module path
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   335
        Path target = options.jmodFile;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   336
        Path tempTarget = target.resolveSibling(target.getFileName() + ".tmp");
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   337
        try {
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   338
            try (JmodOutputStream jos = JmodOutputStream.newOutputStream(tempTarget)) {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   339
                jmod.write(jos);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   340
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   341
            Files.move(tempTarget, target);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   342
        } catch (Exception e) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   343
            if (Files.exists(tempTarget)) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   344
                try {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   345
                    Files.delete(tempTarget);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   346
                } catch (IOException ioe) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   347
                    e.addSuppressed(ioe);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   348
                }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   349
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   350
            throw e;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   351
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   352
        return true;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   353
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   354
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   355
    private class JmodFileWriter {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   356
        final List<Path> cmds = options.cmds;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   357
        final List<Path> libs = options.libs;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   358
        final List<Path> configs = options.configs;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   359
        final List<Path> classpath = options.classpath;
41561
0c6942d13f2e 8167558: Add new JMOD section for header files and man pages
mchung
parents: 41484
diff changeset
   360
        final List<Path> headerFiles = options.headerFiles;
0c6942d13f2e 8167558: Add new JMOD section for header files and man pages
mchung
parents: 41484
diff changeset
   361
        final List<Path> manPages = options.manPages;
0c6942d13f2e 8167558: Add new JMOD section for header files and man pages
mchung
parents: 41484
diff changeset
   362
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   363
        final Version moduleVersion = options.moduleVersion;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   364
        final String mainClass = options.mainClass;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   365
        final String osName = options.osName;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   366
        final String osArch = options.osArch;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   367
        final String osVersion = options.osVersion;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   368
        final List<PathMatcher> excludes = options.excludes;
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   369
        final Hasher hasher = hasher();
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   370
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   371
        JmodFileWriter() { }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   372
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   373
        /**
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   374
         * Writes the jmod to the given output stream.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   375
         */
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   376
        void write(JmodOutputStream out) throws IOException {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   377
            // module-info.class
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   378
            writeModuleInfo(out, findPackages(classpath));
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   379
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   380
            // classes
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   381
            processClasses(out, classpath);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   382
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   383
            processSection(out, Section.NATIVE_CMDS, cmds);
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   384
            processSection(out, Section.NATIVE_LIBS, libs);
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   385
            processSection(out, Section.CONFIG, configs);
41561
0c6942d13f2e 8167558: Add new JMOD section for header files and man pages
mchung
parents: 41484
diff changeset
   386
            processSection(out, Section.HEADER_FILES, headerFiles);
0c6942d13f2e 8167558: Add new JMOD section for header files and man pages
mchung
parents: 41484
diff changeset
   387
            processSection(out, Section.MAN_PAGES, manPages);
0c6942d13f2e 8167558: Add new JMOD section for header files and man pages
mchung
parents: 41484
diff changeset
   388
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   389
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   390
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   391
        /**
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   392
         * Returns a supplier of an input stream to the module-info.class
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   393
         * on the class path of directories and JAR files.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   394
         */
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   395
        Supplier<InputStream> newModuleInfoSupplier() throws IOException {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   396
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   397
            for (Path e: classpath) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   398
                if (Files.isDirectory(e)) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   399
                    Path mi = e.resolve(MODULE_INFO);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   400
                    if (Files.isRegularFile(mi)) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   401
                        Files.copy(mi, baos);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   402
                        break;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   403
                    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   404
                } else if (Files.isRegularFile(e) && e.toString().endsWith(".jar")) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   405
                    try (JarFile jf = new JarFile(e.toFile())) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   406
                        ZipEntry entry = jf.getEntry(MODULE_INFO);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   407
                        if (entry != null) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   408
                            jf.getInputStream(entry).transferTo(baos);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   409
                            break;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   410
                        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   411
                    } catch (ZipException x) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   412
                        // Skip. Do nothing. No packages will be added.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   413
                    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   414
                }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   415
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   416
            if (baos.size() == 0) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   417
                return null;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   418
            } else {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   419
                byte[] bytes = baos.toByteArray();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   420
                return () -> new ByteArrayInputStream(bytes);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   421
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   422
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   423
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   424
        /**
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   425
         * Writes the updated module-info.class to the ZIP output stream.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   426
         *
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   427
         * The updated module-info.class will have a Packages attribute
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   428
         * with the set of module-private/non-exported packages.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   429
         *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   430
         * If --module-version, --main-class, or other options were provided
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   431
         * then the corresponding class file attributes are added to the
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   432
         * module-info here.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   433
         */
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   434
        void writeModuleInfo(JmodOutputStream out, Set<String> packages)
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   435
            throws IOException
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   436
        {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   437
            Supplier<InputStream> miSupplier = newModuleInfoSupplier();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   438
            if (miSupplier == null) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   439
                throw new IOException(MODULE_INFO + " not found");
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   440
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   441
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   442
            ModuleDescriptor descriptor;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   443
            try (InputStream in = miSupplier.get()) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   444
                descriptor = ModuleDescriptor.read(in);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   445
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   446
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   447
            // copy the module-info.class into the jmod with the additional
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   448
            // attributes for the version, main class and other meta data
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   449
            try (InputStream in = miSupplier.get()) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   450
                ModuleInfoExtender extender = ModuleInfoExtender.newExtender(in);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   451
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   452
                // Add (or replace) the Packages attribute
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   453
                if (packages != null) {
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   454
                    extender.packages(packages);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   455
                }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   456
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   457
                // --main-class
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   458
                if (mainClass != null)
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   459
                    extender.mainClass(mainClass);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   460
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   461
                // --os-name, --os-arch, --os-version
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   462
                if (osName != null || osArch != null || osVersion != null)
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   463
                    extender.targetPlatform(osName, osArch, osVersion);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   464
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   465
                // --module-version
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   466
                if (moduleVersion != null)
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   467
                    extender.version(moduleVersion);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   468
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   469
                if (hasher != null) {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   470
                    ModuleHashes moduleHashes = hasher.computeHashes(descriptor.name());
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   471
                    if (moduleHashes != null) {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   472
                        extender.hashes(moduleHashes);
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   473
                    } else {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   474
                        warning("warn.no.module.hashes", descriptor.name());
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   475
                    }
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   476
                }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   477
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   478
                // write the (possibly extended or modified) module-info.class
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   479
                out.writeEntry(extender.toByteArray(), Section.CLASSES, MODULE_INFO);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   480
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   481
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   482
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   483
        /*
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   484
         * Hasher resolves a module graph using the --hash-modules PATTERN
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   485
         * as the roots.
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   486
         *
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   487
         * 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
   488
         * given modulepath.
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   489
         */
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   490
        private Hasher hasher() {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   491
            if (options.modulesToHash == null)
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   492
                return null;
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   493
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   494
            try {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   495
                Supplier<InputStream> miSupplier = newModuleInfoSupplier();
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   496
                if (miSupplier == null) {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   497
                    throw new IOException(MODULE_INFO + " not found");
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   498
                }
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   499
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   500
                ModuleDescriptor descriptor;
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   501
                try (InputStream in = miSupplier.get()) {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   502
                    descriptor = ModuleDescriptor.read(in);
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   503
                }
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   504
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   505
                URI uri = options.jmodFile.toUri();
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   506
                ModuleReference mref = new ModuleReference(descriptor, uri, new Supplier<>() {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   507
                    @Override
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   508
                    public ModuleReader get() {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   509
                        throw new UnsupportedOperationException();
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   510
                    }
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   511
                });
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   512
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   513
                // compose a module finder with the module path and also
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   514
                // a module finder that can find the jmod file being created
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   515
                ModuleFinder finder = ModuleFinder.compose(options.moduleFinder,
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   516
                    new ModuleFinder() {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   517
                        @Override
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   518
                        public Optional<ModuleReference> find(String name) {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   519
                            if (descriptor.name().equals(name))
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   520
                                return Optional.of(mref);
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   521
                            else return Optional.empty();
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   522
                        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   523
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   524
                        @Override
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   525
                        public Set<ModuleReference> findAll() {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   526
                            return Collections.singleton(mref);
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   527
                        }
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   528
                    });
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   529
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   530
                return new Hasher(finder);
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   531
            } catch (IOException e) {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   532
                throw new UncheckedIOException(e);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   533
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   534
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   535
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   536
        /**
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   537
         * Returns the set of all packages on the given class path.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   538
         */
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   539
        Set<String> findPackages(List<Path> classpath) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   540
            Set<String> packages = new HashSet<>();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   541
            for (Path path : classpath) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   542
                if (Files.isDirectory(path)) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   543
                    packages.addAll(findPackages(path));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   544
                } else if (Files.isRegularFile(path) && path.toString().endsWith(".jar")) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   545
                    try (JarFile jf = new JarFile(path.toString())) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   546
                        packages.addAll(findPackages(jf));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   547
                    } catch (ZipException x) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   548
                        // Skip. Do nothing. No packages will be added.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   549
                    } catch (IOException ioe) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   550
                        throw new UncheckedIOException(ioe);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   551
                    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   552
                }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   553
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   554
            return packages;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   555
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   556
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   557
        /**
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   558
         * Returns the set of packages in the given directory tree.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   559
         */
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   560
        Set<String> findPackages(Path dir) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   561
            try {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   562
                return Files.find(dir, Integer.MAX_VALUE,
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   563
                                  ((path, attrs) -> attrs.isRegularFile()))
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   564
                        .map(dir::relativize)
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   565
                        .filter(path -> isResource(path.toString()))
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   566
                        .map(path -> toPackageName(path))
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   567
                        .filter(pkg -> pkg.length() > 0)
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   568
                        .distinct()
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   569
                        .collect(Collectors.toSet());
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   570
            } catch (IOException ioe) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   571
                throw new UncheckedIOException(ioe);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   572
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   573
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   574
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   575
        /**
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   576
         * Returns the set of packages in the given JAR file.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   577
         */
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   578
        Set<String> findPackages(JarFile jf) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   579
            return jf.stream()
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   580
                     .filter(e -> !e.isDirectory() && isResource(e.getName()))
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   581
                     .map(e -> toPackageName(e))
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   582
                     .filter(pkg -> pkg.length() > 0)
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   583
                     .distinct()
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   584
                     .collect(Collectors.toSet());
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   585
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   586
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   587
        /**
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   588
         * 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
   589
         * package name.
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   590
         */
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   591
        boolean isResource(String name) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   592
            name = name.replace(File.separatorChar, '/');
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   593
            return name.endsWith(".class") || !ResourceHelper.isSimpleResource(name);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   594
        }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   595
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   596
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   597
        String toPackageName(Path path) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   598
            String name = path.toString();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   599
            int index = name.lastIndexOf(File.separatorChar);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   600
            if (index != -1)
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   601
                return name.substring(0, index).replace(File.separatorChar, '.');
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   602
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   603
            if (name.endsWith(".class") && !name.equals(MODULE_INFO)) {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   604
                IOException e = new IOException(name  + " in the unnamed package");
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   605
                throw new UncheckedIOException(e);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   606
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   607
            return "";
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   608
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   609
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   610
        String toPackageName(ZipEntry entry) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   611
            String name = entry.getName();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   612
            int index = name.lastIndexOf("/");
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   613
            if (index != -1)
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   614
                return name.substring(0, index).replace('/', '.');
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   615
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   616
            if (name.endsWith(".class") && !name.equals(MODULE_INFO)) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   617
                IOException e = new IOException(name  + " in the unnamed package");
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   618
                throw new UncheckedIOException(e);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   619
            }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 41916
diff changeset
   620
            return "";
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   621
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   622
41561
0c6942d13f2e 8167558: Add new JMOD section for header files and man pages
mchung
parents: 41484
diff changeset
   623
        void processClasses(JmodOutputStream out, List<Path> classpaths)
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   624
            throws IOException
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   625
        {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   626
            if (classpaths == null)
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   627
                return;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   628
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   629
            for (Path p : classpaths) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   630
                if (Files.isDirectory(p)) {
41561
0c6942d13f2e 8167558: Add new JMOD section for header files and man pages
mchung
parents: 41484
diff changeset
   631
                    processSection(out, Section.CLASSES, p);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   632
                } else if (Files.isRegularFile(p) && p.toString().endsWith(".jar")) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   633
                    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
   634
                        JarEntryConsumer jec = new JarEntryConsumer(out, jf);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   635
                        jf.stream().filter(jec).forEach(jec);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   636
                    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   637
                }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   638
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   639
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   640
41561
0c6942d13f2e 8167558: Add new JMOD section for header files and man pages
mchung
parents: 41484
diff changeset
   641
        void processSection(JmodOutputStream out, Section section, List<Path> paths)
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   642
            throws IOException
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   643
        {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   644
            if (paths == null)
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   645
                return;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   646
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   647
            for (Path p : paths)
41561
0c6942d13f2e 8167558: Add new JMOD section for header files and man pages
mchung
parents: 41484
diff changeset
   648
                processSection(out, section, p);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   649
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   650
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   651
        void processSection(JmodOutputStream out, Section section, Path top)
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   652
            throws IOException
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   653
        {
41916
eb4aa81c6c5f 8166286: jmod fails on symlink to directory
sundar
parents: 41817
diff changeset
   654
            Files.walkFileTree(top, Set.of(FileVisitOption.FOLLOW_LINKS),
eb4aa81c6c5f 8166286: jmod fails on symlink to directory
sundar
parents: 41817
diff changeset
   655
                    Integer.MAX_VALUE, new SimpleFileVisitor<Path>() {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   656
                @Override
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   657
                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   658
                    throws IOException
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   659
                {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   660
                    Path relPath = top.relativize(file);
39882
2a5433a2eca5 8134779: (jmod) ZipException is thrown if there are duplicate resources
chegar
parents: 39150
diff changeset
   661
                    if (relPath.toString().equals(MODULE_INFO)
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   662
                        && !Section.CLASSES.equals(section))
39882
2a5433a2eca5 8134779: (jmod) ZipException is thrown if there are duplicate resources
chegar
parents: 39150
diff changeset
   663
                        warning("warn.ignore.entry", MODULE_INFO, section);
2a5433a2eca5 8134779: (jmod) ZipException is thrown if there are duplicate resources
chegar
parents: 39150
diff changeset
   664
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   665
                    if (!relPath.toString().equals(MODULE_INFO)
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   666
                        && !matches(relPath, excludes)) {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   667
                        try (InputStream in = Files.newInputStream(file)) {
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   668
                            out.writeEntry(in, section, relPath.toString());
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   669
                        } catch (IOException x) {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   670
                            if (x.getMessage().contains("duplicate entry")) {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   671
                                warning("warn.ignore.duplicate.entry", relPath.toString(), section);
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   672
                                return FileVisitResult.CONTINUE;
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   673
                            }
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   674
                            throw x;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   675
                        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   676
                    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   677
                    return FileVisitResult.CONTINUE;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   678
                }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   679
            });
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   680
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   681
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   682
        boolean matches(Path path, List<PathMatcher> matchers) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   683
            if (matchers != null) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   684
                for (PathMatcher pm : matchers) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   685
                    if (pm.matches(path))
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   686
                        return true;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   687
                }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   688
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   689
            return false;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   690
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   691
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   692
        class JarEntryConsumer implements Consumer<JarEntry>, Predicate<JarEntry> {
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   693
            final JmodOutputStream out;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   694
            final JarFile jarfile;
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   695
            JarEntryConsumer(JmodOutputStream out, JarFile jarfile) {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   696
                this.out = out;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   697
                this.jarfile = jarfile;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   698
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   699
            @Override
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   700
            public void accept(JarEntry je) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   701
                try (InputStream in = jarfile.getInputStream(je)) {
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   702
                    out.writeEntry(in, Section.CLASSES, je.getName());
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   703
                } catch (IOException e) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   704
                    throw new UncheckedIOException(e);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   705
                }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   706
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   707
            @Override
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   708
            public boolean test(JarEntry je) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   709
                String name = je.getName();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   710
                // ## no support for excludes. Is it really needed?
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   711
                return !name.endsWith(MODULE_INFO) && !je.isDirectory();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   712
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   713
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   714
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   715
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   716
    /**
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   717
     * Compute and record hashes
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   718
     */
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   719
    private class Hasher {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   720
        final ModuleFinder moduleFinder;
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   721
        final Map<String, Path> moduleNameToPath;
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   722
        final Set<String> modules;
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   723
        final Configuration configuration;
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   724
        final boolean dryrun = options.dryrun;
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   725
        Hasher(ModuleFinder finder) {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   726
            this.moduleFinder = finder;
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   727
            // Determine the modules that matches the pattern {@code modulesToHash}
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   728
            this.modules = moduleFinder.findAll().stream()
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   729
                .map(mref -> mref.descriptor().name())
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   730
                .filter(mn -> options.modulesToHash.matcher(mn).find())
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   731
                .collect(Collectors.toSet());
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   732
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   733
            // a map from a module name to Path of the packaged module
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   734
            this.moduleNameToPath = moduleFinder.findAll().stream()
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   735
                .map(mref -> mref.descriptor().name())
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   736
                .collect(Collectors.toMap(Function.identity(), mn -> moduleToPath(mn)));
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   737
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   738
            // get a resolved module graph
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   739
            Configuration config = null;
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   740
            try {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   741
                config = Configuration.empty()
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   742
                    .resolveRequires(ModuleFinder.ofSystem(), moduleFinder, modules);
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   743
            } catch (ResolutionException e) {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   744
                warning("warn.module.resolution.fail", e.getMessage());
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   745
            }
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   746
            this.configuration = config;
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   747
        }
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   748
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   749
        /**
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   750
         * This method is for jmod hash command.
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   751
         *
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   752
         * Identify the base modules in the module graph, i.e. no outgoing edge
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   753
         * to any of the modules to be hashed.
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   754
         *
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   755
         * For each base module M, compute the hashes of all modules that depend
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   756
         * upon M directly or indirectly.  Then update M's module-info.class
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   757
         * to record the hashes.
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   758
         */
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   759
        boolean run() {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   760
            if (configuration == null)
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   761
                return false;
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   762
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   763
            // transposed graph containing the the packaged modules and
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   764
            // its transitive dependences matching --hash-modules
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   765
            Map<String, Set<String>> graph = new HashMap<>();
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   766
            for (String root : modules) {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   767
                Deque<String> deque = new ArrayDeque<>();
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   768
                deque.add(root);
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   769
                Set<String> visited = new HashSet<>();
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   770
                while (!deque.isEmpty()) {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   771
                    String mn = deque.pop();
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   772
                    if (!visited.contains(mn)) {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   773
                        visited.add(mn);
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   774
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   775
                        if (modules.contains(mn))
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   776
                            graph.computeIfAbsent(mn, _k -> new HashSet<>());
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   777
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   778
                        ResolvedModule resolvedModule = configuration.findModule(mn).get();
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   779
                        for (ResolvedModule dm : resolvedModule.reads()) {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   780
                            String name = dm.name();
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   781
                            if (!visited.contains(name)) {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   782
                                deque.push(name);
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   783
                            }
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   784
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   785
                            // reverse edge
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   786
                            if (modules.contains(name) && modules.contains(mn)) {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   787
                                graph.computeIfAbsent(name, _k -> new HashSet<>()).add(mn);
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   788
                            }
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   789
                        }
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   790
                    }
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   791
                }
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   792
            }
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   793
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   794
            if (dryrun)
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   795
                out.println("Dry run:");
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   796
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   797
            // each node in a transposed graph is a matching packaged module
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   798
            // in which the hash of the modules that depend upon it is recorded
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   799
            graph.entrySet().stream()
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   800
                .filter(e -> !e.getValue().isEmpty())
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   801
                .forEach(e -> {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   802
                    String mn = e.getKey();
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   803
                    Map<String, Path> modulesForHash = e.getValue().stream()
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   804
                            .collect(Collectors.toMap(Function.identity(),
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   805
                                                      moduleNameToPath::get));
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   806
                    ModuleHashes hashes = ModuleHashes.generate(modulesForHash, "SHA-256");
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   807
                    if (dryrun) {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   808
                        out.format("%s%n", mn);
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   809
                        hashes.names().stream()
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   810
                              .sorted()
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   811
                              .forEach(name -> out.format("  hashes %s %s %s%n",
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   812
                                  name, hashes.algorithm(), hashes.hashFor(name)));
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   813
                    } else {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   814
                        try {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   815
                            updateModuleInfo(mn, hashes);
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   816
                        } catch (IOException ex) {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   817
                            throw new UncheckedIOException(ex);
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   818
                        }
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   819
                    }
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   820
                });
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   821
            return true;
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   822
        }
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   823
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   824
        /**
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   825
         * Compute hashes of the specified module.
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   826
         *
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   827
         * It records the hashing modules that depend upon the specified
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   828
         * module directly or indirectly.
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   829
         */
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   830
        ModuleHashes computeHashes(String name) {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   831
            if (configuration == null)
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   832
                return null;
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   833
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   834
            // the transposed graph includes all modules in the resolved graph
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   835
            Map<String, Set<String>> graph = transpose();
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   836
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   837
            // find the modules that transitively depend upon the specified name
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   838
            Deque<String> deque = new ArrayDeque<>();
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   839
            deque.add(name);
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   840
            Set<String> mods = visitNodes(graph, deque);
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
            // filter modules matching the pattern specified --hash-modules
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   843
            // as well as itself as the jmod file is being generated
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   844
            Map<String, Path> modulesForHash = mods.stream()
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   845
                .filter(mn -> !mn.equals(name) && modules.contains(mn))
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   846
                .collect(Collectors.toMap(Function.identity(), moduleNameToPath::get));
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   847
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   848
            if (modulesForHash.isEmpty())
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   849
                return null;
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   850
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   851
           return ModuleHashes.generate(modulesForHash, "SHA-256");
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   852
        }
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   853
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   854
        /**
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   855
         * Returns all nodes traversed from the given roots.
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   856
         */
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   857
        private Set<String> visitNodes(Map<String, Set<String>> graph,
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   858
                                       Deque<String> roots) {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   859
            Set<String> visited = new HashSet<>();
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   860
            while (!roots.isEmpty()) {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   861
                String mn = roots.pop();
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   862
                if (!visited.contains(mn)) {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   863
                    visited.add(mn);
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   864
                    // the given roots may not be part of the graph
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   865
                    if (graph.containsKey(mn)) {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   866
                        for (String dm : graph.get(mn)) {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   867
                            if (!visited.contains(dm)) {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   868
                                roots.push(dm);
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   869
                            }
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   870
                        }
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   871
                    }
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   872
                }
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   873
            }
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   874
            return visited;
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   875
        }
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   876
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   877
        /**
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   878
         * Returns a transposed graph from the resolved module graph.
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   879
         */
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   880
        private Map<String, Set<String>> transpose() {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   881
            Map<String, Set<String>> transposedGraph = new HashMap<>();
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   882
            Deque<String> deque = new ArrayDeque<>(modules);
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   883
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   884
            Set<String> visited = new HashSet<>();
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   885
            while (!deque.isEmpty()) {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   886
                String mn = deque.pop();
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   887
                if (!visited.contains(mn)) {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   888
                    visited.add(mn);
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   889
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   890
                    transposedGraph.computeIfAbsent(mn, _k -> new HashSet<>());
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   891
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   892
                    ResolvedModule resolvedModule = configuration.findModule(mn).get();
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   893
                    for (ResolvedModule dm : resolvedModule.reads()) {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   894
                        String name = dm.name();
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   895
                        if (!visited.contains(name)) {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   896
                            deque.push(name);
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   897
                        }
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   898
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   899
                        // reverse edge
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   900
                        transposedGraph.computeIfAbsent(name, _k -> new HashSet<>())
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   901
                                .add(mn);
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   902
                    }
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   903
                }
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   904
            }
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   905
            return transposedGraph;
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
        /**
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   909
         * Reads the given input stream of module-info.class and write
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   910
         * the extended module-info.class with the given ModuleHashes
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   911
         *
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   912
         * @param in       InputStream of module-info.class
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   913
         * @param out      OutputStream to write the extended module-info.class
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   914
         * @param hashes   ModuleHashes
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   915
         */
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   916
        private void recordHashes(InputStream in, OutputStream out, ModuleHashes hashes)
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   917
            throws IOException
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   918
        {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   919
            ModuleInfoExtender extender = ModuleInfoExtender.newExtender(in);
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   920
            extender.hashes(hashes);
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   921
            extender.write(out);
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   922
        }
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   923
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   924
        private void updateModuleInfo(String name, ModuleHashes moduleHashes)
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   925
            throws IOException
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   926
        {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   927
            Path target = moduleNameToPath.get(name);
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   928
            Path tempTarget = target.resolveSibling(target.getFileName() + ".tmp");
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   929
            try {
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   930
                if (target.getFileName().toString().endsWith(".jmod")) {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   931
                    updateJmodFile(target, tempTarget, moduleHashes);
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   932
                } else {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   933
                    updateModularJar(target, tempTarget, moduleHashes);
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   934
                }
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   935
            } catch (IOException|RuntimeException e) {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   936
                if (Files.exists(tempTarget)) {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   937
                    try {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   938
                        Files.delete(tempTarget);
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   939
                    } catch (IOException ioe) {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   940
                        e.addSuppressed(ioe);
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   941
                    }
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   942
                }
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   943
                throw e;
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   944
            }
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   945
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   946
            out.println(getMessage("module.hashes.recorded", name));
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   947
            Files.move(tempTarget, target, StandardCopyOption.REPLACE_EXISTING);
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   948
        }
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
   949
41352
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   950
        private void updateModularJar(Path target, Path tempTarget,
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   951
                                      ModuleHashes moduleHashes)
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   952
            throws IOException
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   953
        {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   954
            try (JarFile jf = new JarFile(target.toFile());
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   955
                 OutputStream out = Files.newOutputStream(tempTarget);
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   956
                 JarOutputStream jos = new JarOutputStream(out))
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   957
            {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   958
                jf.stream().forEach(e -> {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   959
                    try (InputStream in = jf.getInputStream(e)) {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   960
                        if (e.getName().equals(MODULE_INFO)) {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   961
                            // what about module-info.class in versioned entries?
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   962
                            ZipEntry ze = new ZipEntry(e.getName());
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   963
                            ze.setTime(System.currentTimeMillis());
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   964
                            jos.putNextEntry(ze);
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   965
                            recordHashes(in, jos, moduleHashes);
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   966
                            jos.closeEntry();
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   967
                        } else {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   968
                            jos.putNextEntry(e);
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   969
                            jos.write(in.readAllBytes());
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   970
                            jos.closeEntry();
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   971
                        }
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   972
                    } catch (IOException x) {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   973
                        throw new UncheckedIOException(x);
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   974
                    }
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   975
                });
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   976
            }
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   977
        }
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   978
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   979
        private void updateJmodFile(Path target, Path tempTarget,
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   980
                                    ModuleHashes moduleHashes)
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   981
            throws IOException
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   982
        {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   983
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   984
            try (JmodFile jf = new JmodFile(target);
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   985
                 JmodOutputStream jos = JmodOutputStream.newOutputStream(tempTarget))
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   986
            {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   987
                jf.stream().forEach(e -> {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   988
                    try (InputStream in = jf.getInputStream(e.section(), e.name())) {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   989
                        if (e.name().equals(MODULE_INFO)) {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   990
                            // replace module-info.class
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   991
                            ModuleInfoExtender extender =
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   992
                                ModuleInfoExtender.newExtender(in);
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   993
                            extender.hashes(moduleHashes);
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   994
                            jos.writeEntry(extender.toByteArray(), e.section(), e.name());
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   995
                        } else {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   996
                            jos.writeEntry(in, e);
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
                    } catch (IOException x) {
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
   999
                        throw new UncheckedIOException(x);
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
                });
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
  1002
            }
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
  1003
        }
f9844bad9052 8166860: Add magic number to jmod file
mchung
parents: 40261
diff changeset
  1004
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1005
        private Path moduleToPath(String name) {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1006
            ModuleReference mref = moduleFinder.find(name).orElseThrow(
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1007
                () -> new InternalError("Selected module " + name + " not on module path"));
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1008
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1009
            URI uri = mref.location().get();
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1010
            Path path = Paths.get(uri);
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1011
            String fn = path.getFileName().toString();
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1012
            if (!fn.endsWith(".jar") && !fn.endsWith(".jmod")) {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1013
                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
  1014
            }
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1015
            return path;
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1016
        }
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1017
    }
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1018
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1019
    static class ClassPathConverter implements ValueConverter<Path> {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1020
        static final ValueConverter<Path> INSTANCE = new ClassPathConverter();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1021
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1022
        private static final Path CWD = Paths.get("");
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1023
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1024
        @Override
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1025
        public Path convert(String value) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1026
            try {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1027
                Path path = CWD.resolve(value);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1028
                if (Files.notExists(path))
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1029
                    throw new CommandException("err.path.not.found", path);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1030
                if (! (Files.isDirectory(path) ||
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1031
                       (Files.isRegularFile(path) && path.toString().endsWith(".jar"))))
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1032
                    throw new CommandException("err.invalid.class.path.entry", path);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1033
                return path;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1034
            } catch (InvalidPathException x) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1035
                throw new CommandException("err.path.not.valid", value);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1036
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1037
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1038
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1039
        @Override  public Class<Path> valueType() { return Path.class; }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1040
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1041
        @Override  public String valuePattern() { return "path"; }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1042
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1043
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1044
    static class DirPathConverter implements ValueConverter<Path> {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1045
        static final ValueConverter<Path> INSTANCE = new DirPathConverter();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1046
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1047
        private static final Path CWD = Paths.get("");
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1048
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1049
        @Override
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1050
        public Path convert(String value) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1051
            try {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1052
                Path path = CWD.resolve(value);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1053
                if (Files.notExists(path))
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1054
                    throw new CommandException("err.path.not.found", path);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1055
                if (!Files.isDirectory(path))
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1056
                    throw new CommandException("err.path.not.a.dir", path);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1057
                return path;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1058
            } catch (InvalidPathException x) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1059
                throw new CommandException("err.path.not.valid", value);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1060
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1061
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1062
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1063
        @Override  public Class<Path> valueType() { return Path.class; }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1064
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1065
        @Override  public String valuePattern() { return "path"; }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1066
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1067
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1068
    static class ModuleVersionConverter implements ValueConverter<Version> {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1069
        @Override
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1070
        public Version convert(String value) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1071
            try {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1072
                return Version.parse(value);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1073
            } catch (IllegalArgumentException x) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1074
                throw new CommandException("err.invalid.version", x.getMessage());
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1075
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1076
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1077
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1078
        @Override public Class<Version> valueType() { return Version.class; }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1079
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1080
        @Override public String valuePattern() { return "module-version"; }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1081
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1082
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1083
    static class PatternConverter implements ValueConverter<Pattern> {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1084
        @Override
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1085
        public Pattern convert(String value) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1086
            try {
38871
ec08bf1979d4 8158402: jlink: should use regex for all pattern operations (--order-resources or --exclude-resources)
jlaskey
parents: 37779
diff changeset
  1087
                if (value.startsWith("regex:")) {
ec08bf1979d4 8158402: jlink: should use regex for all pattern operations (--order-resources or --exclude-resources)
jlaskey
parents: 37779
diff changeset
  1088
                    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
  1089
                }
ec08bf1979d4 8158402: jlink: should use regex for all pattern operations (--order-resources or --exclude-resources)
jlaskey
parents: 37779
diff changeset
  1090
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1091
                return Pattern.compile(value);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1092
            } catch (PatternSyntaxException e) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1093
                throw new CommandException("err.bad.pattern", value);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1094
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1095
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1096
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1097
        @Override public Class<Pattern> valueType() { return Pattern.class; }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1098
39150
cb99396625b4 8159172: Update usage of jlink/jimage/jmod to show option patterns
jlaskey
parents: 39042
diff changeset
  1099
        @Override public String valuePattern() { return "regex-pattern"; }
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1100
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1101
38871
ec08bf1979d4 8158402: jlink: should use regex for all pattern operations (--order-resources or --exclude-resources)
jlaskey
parents: 37779
diff changeset
  1102
    static class PathMatcherConverter implements ValueConverter<PathMatcher> {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1103
        @Override
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1104
        public PathMatcher convert(String pattern) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1105
            try {
39042
52db877f18db 8159206: All jlink or jmod tests failing
jlaskey
parents: 38871
diff changeset
  1106
                return Utils.getPathMatcher(FileSystems.getDefault(), pattern);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1107
            } catch (PatternSyntaxException e) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1108
                throw new CommandException("err.bad.pattern", pattern);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1109
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1110
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1111
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1112
        @Override public Class<PathMatcher> valueType() { return PathMatcher.class; }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1113
39150
cb99396625b4 8159172: Update usage of jlink/jimage/jmod to show option patterns
jlaskey
parents: 39042
diff changeset
  1114
        @Override public String valuePattern() { return "pattern-list"; }
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1115
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1116
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1117
    /* Support for @<file> in jmod help */
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1118
    private static final String CMD_FILENAME = "@<filename>";
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1119
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1120
    /**
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1121
     * This formatter is adding the @filename option and does the required
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1122
     * formatting.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1123
     */
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1124
    private static final class JmodHelpFormatter extends BuiltinHelpFormatter {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1125
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1126
        private JmodHelpFormatter() { super(80, 2); }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1127
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1128
        @Override
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1129
        public String format(Map<String, ? extends OptionDescriptor> options) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1130
            Map<String, OptionDescriptor> all = new HashMap<>();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1131
            all.putAll(options);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1132
            all.put(CMD_FILENAME, new OptionDescriptor() {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1133
                @Override
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1134
                public Collection<String> options() {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1135
                    List<String> ret = new ArrayList<>();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1136
                    ret.add(CMD_FILENAME);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1137
                    return ret;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1138
                }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1139
                @Override
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1140
                public String description() { return getMessage("main.opt.cmdfile"); }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1141
                @Override
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1142
                public List<?> defaultValues() { return Collections.emptyList(); }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1143
                @Override
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1144
                public boolean isRequired() { return false; }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1145
                @Override
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1146
                public boolean acceptsArguments() { return false; }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1147
                @Override
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1148
                public boolean requiresArgument() { return false; }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1149
                @Override
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1150
                public String argumentDescription() { return null; }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1151
                @Override
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1152
                public String argumentTypeIndicator() { return null; }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1153
                @Override
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1154
                public boolean representsNonOptions() { return false; }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1155
            });
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1156
            String content = super.format(all);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1157
            StringBuilder builder = new StringBuilder();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1158
39150
cb99396625b4 8159172: Update usage of jlink/jimage/jmod to show option patterns
jlaskey
parents: 39042
diff changeset
  1159
            builder.append(getMessage("main.opt.mode")).append("\n  ");
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1160
            builder.append(getMessage("main.opt.mode.create")).append("\n  ");
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1161
            builder.append(getMessage("main.opt.mode.list")).append("\n  ");
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1162
            builder.append(getMessage("main.opt.mode.describe")).append("\n  ");
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1163
            builder.append(getMessage("main.opt.mode.hash")).append("\n\n");
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1164
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1165
            String cmdfile = null;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1166
            String[] lines = content.split("\n");
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1167
            for (String line : lines) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1168
                if (line.startsWith("--@")) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1169
                    cmdfile = line.replace("--" + CMD_FILENAME, CMD_FILENAME + "  ");
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1170
                } else if (line.startsWith("Option") || line.startsWith("------")) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1171
                    builder.append(" ").append(line).append("\n");
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1172
                } else if (!line.matches("Non-option arguments")){
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1173
                    builder.append("  ").append(line).append("\n");
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1174
                }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1175
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1176
            if (cmdfile != null) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1177
                builder.append("  ").append(cmdfile).append("\n");
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1178
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1179
            return builder.toString();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1180
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1181
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1182
40261
86a49ba76f52 8136930: Simplify use of module-system options by custom launchers
mchung
parents: 39882
diff changeset
  1183
    private final OptionParser parser = new OptionParser("hp");
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1184
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1185
    private void handleOptions(String[] args) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1186
        parser.formatHelpWith(new JmodHelpFormatter());
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1187
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1188
        OptionSpec<Path> classPath
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1189
                = parser.accepts("class-path", getMessage("main.opt.class-path"))
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1190
                        .withRequiredArg()
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1191
                        .withValuesSeparatedBy(File.pathSeparatorChar)
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1192
                        .withValuesConvertedBy(ClassPathConverter.INSTANCE);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1193
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1194
        OptionSpec<Path> cmds
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1195
                = parser.accepts("cmds", getMessage("main.opt.cmds"))
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1196
                        .withRequiredArg()
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1197
                        .withValuesSeparatedBy(File.pathSeparatorChar)
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1198
                        .withValuesConvertedBy(DirPathConverter.INSTANCE);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1199
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1200
        OptionSpec<Path> config
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1201
                = parser.accepts("config", getMessage("main.opt.config"))
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1202
                        .withRequiredArg()
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1203
                        .withValuesSeparatedBy(File.pathSeparatorChar)
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1204
                        .withValuesConvertedBy(DirPathConverter.INSTANCE);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1205
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1206
        OptionSpec<Void> dryrun
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1207
            = parser.accepts("dry-run", getMessage("main.opt.dry-run"));
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1208
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1209
        OptionSpec<PathMatcher> excludes
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1210
                = parser.accepts("exclude", getMessage("main.opt.exclude"))
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1211
                        .withRequiredArg()
38871
ec08bf1979d4 8158402: jlink: should use regex for all pattern operations (--order-resources or --exclude-resources)
jlaskey
parents: 37779
diff changeset
  1212
                        .withValuesConvertedBy(new PathMatcherConverter());
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1213
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1214
        OptionSpec<Pattern> hashModules
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1215
                = parser.accepts("hash-modules", getMessage("main.opt.hash-modules"))
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1216
                        .withRequiredArg()
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1217
                        .withValuesConvertedBy(new PatternConverter());
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1218
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1219
        OptionSpec<Void> help
40261
86a49ba76f52 8136930: Simplify use of module-system options by custom launchers
mchung
parents: 39882
diff changeset
  1220
                = parser.acceptsAll(Set.of("h", "help"), getMessage("main.opt.help"))
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1221
                        .forHelp();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1222
41561
0c6942d13f2e 8167558: Add new JMOD section for header files and man pages
mchung
parents: 41484
diff changeset
  1223
        OptionSpec<Path> headerFiles
0c6942d13f2e 8167558: Add new JMOD section for header files and man pages
mchung
parents: 41484
diff changeset
  1224
            = parser.accepts("header-files", getMessage("main.opt.header-files"))
0c6942d13f2e 8167558: Add new JMOD section for header files and man pages
mchung
parents: 41484
diff changeset
  1225
                    .withRequiredArg()
0c6942d13f2e 8167558: Add new JMOD section for header files and man pages
mchung
parents: 41484
diff changeset
  1226
                    .withValuesSeparatedBy(File.pathSeparatorChar)
0c6942d13f2e 8167558: Add new JMOD section for header files and man pages
mchung
parents: 41484
diff changeset
  1227
                    .withValuesConvertedBy(DirPathConverter.INSTANCE);
0c6942d13f2e 8167558: Add new JMOD section for header files and man pages
mchung
parents: 41484
diff changeset
  1228
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1229
        OptionSpec<Path> libs
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1230
                = parser.accepts("libs", getMessage("main.opt.libs"))
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1231
                        .withRequiredArg()
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1232
                        .withValuesSeparatedBy(File.pathSeparatorChar)
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1233
                        .withValuesConvertedBy(DirPathConverter.INSTANCE);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1234
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1235
        OptionSpec<String> mainClass
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1236
                = parser.accepts("main-class", getMessage("main.opt.main-class"))
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1237
                        .withRequiredArg()
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1238
                        .describedAs(getMessage("main.opt.main-class.arg"));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1239
41561
0c6942d13f2e 8167558: Add new JMOD section for header files and man pages
mchung
parents: 41484
diff changeset
  1240
        OptionSpec<Path> manPages
0c6942d13f2e 8167558: Add new JMOD section for header files and man pages
mchung
parents: 41484
diff changeset
  1241
            = parser.accepts("man-pages", getMessage("main.opt.man-pages"))
0c6942d13f2e 8167558: Add new JMOD section for header files and man pages
mchung
parents: 41484
diff changeset
  1242
                        .withRequiredArg()
0c6942d13f2e 8167558: Add new JMOD section for header files and man pages
mchung
parents: 41484
diff changeset
  1243
                        .withValuesSeparatedBy(File.pathSeparatorChar)
0c6942d13f2e 8167558: Add new JMOD section for header files and man pages
mchung
parents: 41484
diff changeset
  1244
                        .withValuesConvertedBy(DirPathConverter.INSTANCE);
0c6942d13f2e 8167558: Add new JMOD section for header files and man pages
mchung
parents: 41484
diff changeset
  1245
40261
86a49ba76f52 8136930: Simplify use of module-system options by custom launchers
mchung
parents: 39882
diff changeset
  1246
        OptionSpec<Path> modulePath
86a49ba76f52 8136930: Simplify use of module-system options by custom launchers
mchung
parents: 39882
diff changeset
  1247
                = parser.acceptsAll(Set.of("p", "module-path"),
86a49ba76f52 8136930: Simplify use of module-system options by custom launchers
mchung
parents: 39882
diff changeset
  1248
                                    getMessage("main.opt.module-path"))
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1249
                        .withRequiredArg()
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1250
                        .withValuesSeparatedBy(File.pathSeparatorChar)
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1251
                        .withValuesConvertedBy(DirPathConverter.INSTANCE);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1252
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1253
        OptionSpec<Version> moduleVersion
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1254
                = parser.accepts("module-version", getMessage("main.opt.module-version"))
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1255
                        .withRequiredArg()
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1256
                        .withValuesConvertedBy(new ModuleVersionConverter());
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1257
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1258
        OptionSpec<String> osName
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1259
                = parser.accepts("os-name", getMessage("main.opt.os-name"))
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1260
                        .withRequiredArg()
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1261
                        .describedAs(getMessage("main.opt.os-name.arg"));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1262
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1263
        OptionSpec<String> osArch
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1264
                = parser.accepts("os-arch", getMessage("main.opt.os-arch"))
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1265
                        .withRequiredArg()
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1266
                        .describedAs(getMessage("main.opt.os-arch.arg"));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1267
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1268
        OptionSpec<String> osVersion
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1269
                = parser.accepts("os-version", getMessage("main.opt.os-version"))
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1270
                        .withRequiredArg()
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1271
                        .describedAs(getMessage("main.opt.os-version.arg"));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1272
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1273
        OptionSpec<Void> version
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1274
                = parser.accepts("version", getMessage("main.opt.version"));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1275
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1276
        NonOptionArgumentSpec<String> nonOptions
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1277
                = parser.nonOptions();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1278
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1279
        try {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1280
            OptionSet opts = parser.parse(args);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1281
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1282
            if (opts.has(help) || opts.has(version)) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1283
                options = new Options();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1284
                options.help = opts.has(help);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1285
                options.version = opts.has(version);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1286
                return;  // informational message will be shown
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1287
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1288
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1289
            List<String> words = opts.valuesOf(nonOptions);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1290
            if (words.isEmpty())
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1291
                throw new CommandException("err.missing.mode").showUsage(true);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1292
            String verb = words.get(0);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1293
            options = new Options();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1294
            try {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1295
                options.mode = Enum.valueOf(Mode.class, verb.toUpperCase());
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1296
            } catch (IllegalArgumentException e) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1297
                throw new CommandException("err.invalid.mode", verb).showUsage(true);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1298
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1299
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1300
            if (opts.has(classPath))
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1301
                options.classpath = opts.valuesOf(classPath);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1302
            if (opts.has(cmds))
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1303
                options.cmds = opts.valuesOf(cmds);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1304
            if (opts.has(config))
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1305
                options.configs = opts.valuesOf(config);
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1306
            if (opts.has(dryrun))
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1307
                options.dryrun = true;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1308
            if (opts.has(excludes))
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1309
                options.excludes = opts.valuesOf(excludes);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1310
            if (opts.has(libs))
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1311
                options.libs = opts.valuesOf(libs);
41561
0c6942d13f2e 8167558: Add new JMOD section for header files and man pages
mchung
parents: 41484
diff changeset
  1312
            if (opts.has(headerFiles))
0c6942d13f2e 8167558: Add new JMOD section for header files and man pages
mchung
parents: 41484
diff changeset
  1313
                options.headerFiles = opts.valuesOf(headerFiles);
0c6942d13f2e 8167558: Add new JMOD section for header files and man pages
mchung
parents: 41484
diff changeset
  1314
            if (opts.has(manPages))
0c6942d13f2e 8167558: Add new JMOD section for header files and man pages
mchung
parents: 41484
diff changeset
  1315
                options.manPages = opts.valuesOf(manPages);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1316
            if (opts.has(modulePath)) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1317
                Path[] dirs = opts.valuesOf(modulePath).toArray(new Path[0]);
41817
b90ad1de93ea 8168789: ModuleReader.list and ModuleFinder.of update
alanb
parents: 41561
diff changeset
  1318
                options.moduleFinder = JLMA.newModulePath(Runtime.version(), true, dirs);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1319
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1320
            if (opts.has(moduleVersion))
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1321
                options.moduleVersion = opts.valueOf(moduleVersion);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1322
            if (opts.has(mainClass))
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1323
                options.mainClass = opts.valueOf(mainClass);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1324
            if (opts.has(osName))
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1325
                options.osName = opts.valueOf(osName);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1326
            if (opts.has(osArch))
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1327
                options.osArch = opts.valueOf(osArch);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1328
            if (opts.has(osVersion))
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1329
                options.osVersion = opts.valueOf(osVersion);
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1330
            if (opts.has(hashModules)) {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1331
                options.modulesToHash = opts.valueOf(hashModules);
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1332
                // if storing hashes then the module path is required
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1333
                if (options.moduleFinder == null)
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1334
                    throw new CommandException("err.modulepath.must.be.specified")
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1335
                            .showUsage(true);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1336
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1337
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1338
            if (options.mode.equals(Mode.HASH)) {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1339
                if (options.moduleFinder == null || options.modulesToHash == null)
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1340
                    throw new CommandException("err.modulepath.must.be.specified")
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1341
                            .showUsage(true);
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1342
            } else {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1343
                if (words.size() <= 1)
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1344
                    throw new CommandException("err.jmod.must.be.specified").showUsage(true);
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1345
                Path path = Paths.get(words.get(1));
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1346
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1347
                if (options.mode.equals(Mode.CREATE) && Files.exists(path))
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1348
                    throw new CommandException("err.file.already.exists", path);
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1349
                else if ((options.mode.equals(Mode.LIST) ||
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1350
                            options.mode.equals(Mode.DESCRIBE))
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1351
                         && Files.notExists(path))
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1352
                    throw new CommandException("err.jmod.not.found", path);
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1353
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1354
                if (options.dryrun) {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1355
                    throw new CommandException("err.invalid.dryrun.option");
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1356
                }
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1357
                options.jmodFile = path;
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1358
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1359
                if (words.size() > 2)
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1360
                    throw new CommandException("err.unknown.option",
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1361
                            words.subList(2, words.size())).showUsage(true);
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 36511
diff changeset
  1362
            }
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1363
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1364
            if (options.mode.equals(Mode.CREATE) && options.classpath == null)
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1365
                throw new CommandException("err.classpath.must.be.specified").showUsage(true);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1366
            if (options.mainClass != null && !isValidJavaIdentifier(options.mainClass))
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1367
                throw new CommandException("err.invalid.main-class", options.mainClass);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1368
        } catch (OptionException e) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1369
             throw new CommandException(e.getMessage());
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1370
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1371
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1372
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1373
    /**
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1374
     * Returns true if, and only if, the given main class is a legal.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1375
     */
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1376
    static boolean isValidJavaIdentifier(String mainClass) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1377
        if (mainClass.length() == 0)
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1378
            return false;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1379
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1380
        if (!Character.isJavaIdentifierStart(mainClass.charAt(0)))
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1381
            return false;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1382
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1383
        int n = mainClass.length();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1384
        for (int i=1; i < n; i++) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1385
            char c = mainClass.charAt(i);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1386
            if (!Character.isJavaIdentifierPart(c) && c != '.')
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1387
                return false;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1388
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1389
        if (mainClass.charAt(n-1) == '.')
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1390
            return false;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1391
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1392
        return true;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1393
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1394
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1395
    private void reportError(String message) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1396
        out.println(getMessage("error.prefix") + " " + message);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1397
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1398
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1399
    private void warning(String key, Object... args) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1400
        out.println(getMessage("warn.prefix") + " " + getMessage(key, args));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1401
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1402
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1403
    private void showUsageSummary() {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1404
        out.println(getMessage("main.usage.summary", PROGNAME));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1405
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1406
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1407
    private void showHelp() {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1408
        out.println(getMessage("main.usage", PROGNAME));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1409
        try {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1410
            parser.printHelpOn(out);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1411
        } catch (IOException x) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1412
            throw new AssertionError(x);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1413
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1414
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1415
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1416
    private void showVersion() {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1417
        out.println(version());
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1418
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1419
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1420
    private String version() {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1421
        return System.getProperty("java.version");
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1422
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1423
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1424
    private static String getMessage(String key, Object... args) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1425
        try {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1426
            return MessageFormat.format(ResourceBundleHelper.bundle.getString(key), args);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1427
        } catch (MissingResourceException e) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1428
            throw new InternalError("Missing message: " + key);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1429
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1430
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1431
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1432
    private static class ResourceBundleHelper {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1433
        static final ResourceBundle bundle;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1434
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1435
        static {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1436
            Locale locale = Locale.getDefault();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1437
            try {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1438
                bundle = ResourceBundle.getBundle("jdk.tools.jmod.resources.jmod", locale);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1439
            } catch (MissingResourceException e) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1440
                throw new InternalError("Cannot find jmod resource bundle for locale " + locale);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1441
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1442
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1443
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1444
}