1/*
2 * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package jdk.tools.jlink.internal.packager;
27
28
29import jdk.tools.jlink.builder.DefaultImageBuilder;
30import jdk.tools.jlink.internal.Jlink;
31import jdk.tools.jlink.internal.JlinkTask;
32import jdk.tools.jlink.plugin.Plugin;
33
34import java.io.File;
35import java.io.IOException;
36import java.lang.module.ModuleFinder;
37import java.nio.ByteOrder;
38import java.nio.file.Path;
39import java.util.ArrayList;
40import java.util.Collections;
41import java.util.List;
42import java.util.Map;
43import java.util.Set;
44
45/**
46 * AppRuntimeImageBuilder is a private API used only by the Java Packager to generate
47 * a Java runtime image using jlink. AppRuntimeImageBuilder encapsulates the
48 * arguments that jlink requires to generate this image. To create the image call the
49 * build() method.
50 */
51public final class AppRuntimeImageBuilder {
52    private Path outputDir = null;
53    private Map<String, String> launchers = Collections.emptyMap();
54    private List<Path> modulePath = null;
55    private Set<String> addModules = null;
56    private Set<String> limitModules = null;
57    private String excludeFileList = null;
58    private Map<String, String> userArguments = null;
59    private Boolean stripNativeCommands = null;
60
61    public AppRuntimeImageBuilder() {}
62
63    public void setOutputDir(Path value) {
64        outputDir = value;
65    }
66
67    public void setLaunchers(Map<String, String> value) {
68        launchers = value;
69    }
70
71    public void setModulePath(List<Path> value) {
72        modulePath = value;
73    }
74
75    public void setAddModules(Set<String> value) {
76        addModules = value;
77    }
78
79    public void setLimitModules(Set<String> value) {
80        limitModules = value;
81    }
82
83    public void setExcludeFileList(String value) {
84        excludeFileList = value;
85    }
86
87    public void setStripNativeCommands(boolean value) {
88        stripNativeCommands = value;
89    }
90
91    public void setUserArguments(Map<String, String> value) {
92        userArguments = value;
93    }
94
95    public void build() throws IOException {
96        // jlink main arguments
97        Jlink.JlinkConfiguration jlinkConfig =
98            new Jlink.JlinkConfiguration(new File("").toPath(), // Unused
99                                         modulePath,
100                                         addModules,
101                                         limitModules,
102                                         ByteOrder.nativeOrder());
103
104        // plugin configuration
105        List<Plugin> plugins = new ArrayList<Plugin>();
106
107        if (stripNativeCommands) {
108            plugins.add(Jlink.newPlugin(
109                        "strip-native-commands",
110                        Collections.singletonMap("strip-native-commands", "on"),
111                        null));
112        }
113
114        if (excludeFileList != null && !excludeFileList.isEmpty()) {
115            plugins.add(Jlink.newPlugin(
116                        "exclude-files",
117                        Collections.singletonMap("exclude-files", excludeFileList),
118                        null));
119        }
120
121        // add user supplied jlink arguments
122        for (Map.Entry<String, String> entry : userArguments.entrySet()) {
123            String key = entry.getKey();
124            String value = entry.getValue();
125            plugins.add(Jlink.newPlugin(key,
126                                        Collections.singletonMap(key, value),
127                                        null));
128        }
129
130        // build the image
131        Jlink.PluginsConfiguration pluginConfig = new Jlink.PluginsConfiguration(
132            plugins, new DefaultImageBuilder(outputDir, launchers), null);
133        Jlink jlink = new Jlink();
134        jlink.build(jlinkConfig, pluginConfig);
135    }
136
137    /*
138     * Returns a ModuleFinder that limits observability to the given root
139     * modules, their transitive dependences, plus a set of other modules.
140     */
141    public static ModuleFinder moduleFinder(List<Path> modulepaths,
142                                            Set<String> roots,
143                                            Set<String> otherModules) {
144        return JlinkTask.newModuleFinder(modulepaths, roots, otherModules);
145    }
146}
147