src/jdk.jpackage/share/classes/jdk/jpackage/internal/AbstractAppImageBuilder.java
branchJDK-8200758-branch
changeset 58994 b09ba68c6a19
parent 58993 b5e1baa9d2c3
child 58995 de1413ae214c
equal deleted inserted replaced
58993:b5e1baa9d2c3 58994:b09ba68c6a19
     1 /*
       
     2  * Copyright (c) 2015, 2019, 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 
       
    26 package jdk.jpackage.internal;
       
    27 
       
    28 import java.io.ByteArrayOutputStream;
       
    29 import java.io.File;
       
    30 import java.io.FileInputStream;
       
    31 import java.io.IOException;
       
    32 import java.io.InputStream;
       
    33 import java.io.PrintStream;
       
    34 import java.nio.file.Files;
       
    35 import java.nio.file.Path;
       
    36 import java.text.MessageFormat;
       
    37 import java.util.List;
       
    38 import java.util.Map;
       
    39 import java.util.ResourceBundle;
       
    40 import java.util.ArrayList;
       
    41 
       
    42 import jdk.jpackage.internal.resources.ResourceLocator;
       
    43 
       
    44 import static jdk.jpackage.internal.StandardBundlerParam.*;
       
    45 
       
    46 /*
       
    47  * AbstractAppImageBuilder
       
    48  *     This is sub-classed by each of the platform dependent AppImageBuilder
       
    49  * classes, and contains resource processing code common to all platforms.
       
    50  */
       
    51 
       
    52 public abstract class AbstractAppImageBuilder {
       
    53 
       
    54     private static final ResourceBundle I18N = ResourceBundle.getBundle(
       
    55             "jdk.jpackage.internal.resources.MainResources");
       
    56 
       
    57     private final Path root;
       
    58 
       
    59     public AbstractAppImageBuilder(Map<String, Object> unused, Path root) {
       
    60         this.root = root;
       
    61     }
       
    62 
       
    63     public InputStream getResourceAsStream(String name) {
       
    64         return ResourceLocator.class.getResourceAsStream(name);
       
    65     }
       
    66 
       
    67     public abstract void prepareApplicationFiles(
       
    68             Map<String, ? super Object> params) throws IOException;
       
    69     public abstract void prepareJreFiles(
       
    70             Map<String, ? super Object> params) throws IOException;
       
    71     public abstract Path getAppDir();
       
    72     public abstract Path getAppModsDir();
       
    73 
       
    74     public Path getRuntimeRoot() {
       
    75         return this.root;
       
    76     }
       
    77 
       
    78     protected void copyEntry(Path appDir, File srcdir, String fname)
       
    79             throws IOException {
       
    80         Path dest = appDir.resolve(fname);
       
    81         Files.createDirectories(dest.getParent());
       
    82         File src = new File(srcdir, fname);
       
    83         if (src.isDirectory()) {
       
    84             IOUtils.copyRecursive(src.toPath(), dest);
       
    85         } else {
       
    86             Files.copy(src.toPath(), dest);
       
    87         }
       
    88     }
       
    89 
       
    90     public void writeCfgFile(Map<String, ? super Object> params,
       
    91             File cfgFileName) throws IOException {
       
    92         cfgFileName.getParentFile().mkdirs();
       
    93         cfgFileName.delete();
       
    94         File mainJar = JLinkBundlerHelper.getMainJar(params);
       
    95         ModFile.ModType mainJarType = ModFile.ModType.Unknown;
       
    96 
       
    97         if (mainJar != null) {
       
    98             mainJarType = new ModFile(mainJar).getModType();
       
    99         }
       
   100 
       
   101         String mainModule = StandardBundlerParam.MODULE.fetchFrom(params);
       
   102 
       
   103         try (PrintStream out = new PrintStream(cfgFileName)) {
       
   104 
       
   105             out.println("[Application]");
       
   106             out.println("app.name=" + APP_NAME.fetchFrom(params));
       
   107             out.println("app.version=" + VERSION.fetchFrom(params));
       
   108             out.println("app.runtime=" + getCfgRuntimeDir());
       
   109             out.println("app.identifier=" + IDENTIFIER.fetchFrom(params));
       
   110             out.println("app.classpath="
       
   111                     + getCfgClassPath(CLASSPATH.fetchFrom(params)));
       
   112 
       
   113             // The main app is required to be a jar, modular or unnamed.
       
   114             if (mainModule != null &&
       
   115                     (mainJarType == ModFile.ModType.Unknown ||
       
   116                     mainJarType == ModFile.ModType.ModularJar)) {
       
   117                 out.println("app.mainmodule=" + mainModule);
       
   118             } else {
       
   119                 String mainClass =
       
   120                         StandardBundlerParam.MAIN_CLASS.fetchFrom(params);
       
   121                 // If the app is contained in an unnamed jar then launch it the
       
   122                 // legacy way and the main class string must be
       
   123                 // of the format com/foo/Main
       
   124                 if (mainJar != null) {
       
   125                     out.println("app.mainjar=" + getCfgAppDir()
       
   126                             + mainJar.toPath().getFileName().toString());
       
   127                 }
       
   128                 if (mainClass != null) {
       
   129                     out.println("app.mainclass="
       
   130                             + mainClass.replace("\\", "/"));
       
   131                 }
       
   132             }
       
   133 
       
   134             out.println();
       
   135             out.println("[JavaOptions]");
       
   136             List<String> jvmargs = JAVA_OPTIONS.fetchFrom(params);
       
   137             for (String arg : jvmargs) {
       
   138                 out.println(arg);
       
   139             }
       
   140             Path modsDir = getAppModsDir();
       
   141 
       
   142             if (modsDir != null && modsDir.toFile().exists()) {
       
   143                 out.println("--module-path");
       
   144                 out.println(getCfgAppDir().replace("\\","/") + "mods");
       
   145             }
       
   146 
       
   147             out.println();
       
   148             out.println("[ArgOptions]");
       
   149             List<String> args = ARGUMENTS.fetchFrom(params);
       
   150             for (String arg : args) {
       
   151                 if (arg.endsWith("=") &&
       
   152                         (arg.indexOf("=") == arg.lastIndexOf("="))) {
       
   153                     out.print(arg.substring(0, arg.length() - 1));
       
   154                     out.println("\\=");
       
   155                 } else {
       
   156                     out.println(arg);
       
   157                 }
       
   158             }
       
   159         }
       
   160     }
       
   161 
       
   162     File getRuntimeImageDir(File runtimeImageTop) {
       
   163         return runtimeImageTop;
       
   164     }
       
   165 
       
   166     protected String getCfgAppDir() {
       
   167         return "$ROOTDIR" + File.separator
       
   168                 + getAppDir().getFileName() + File.separator;
       
   169     }
       
   170 
       
   171     protected String getCfgRuntimeDir() {
       
   172         return "$ROOTDIR" + File.separator + "runtime";
       
   173     }
       
   174 
       
   175     String getCfgClassPath(String classpath) {
       
   176         String cfgAppDir = getCfgAppDir();
       
   177 
       
   178         StringBuilder sb = new StringBuilder();
       
   179         for (String path : classpath.split("[:;]")) {
       
   180             if (path.length() > 0) {
       
   181                 sb.append(cfgAppDir);
       
   182                 sb.append(path);
       
   183                 sb.append(File.pathSeparator);
       
   184             }
       
   185         }
       
   186         if (sb.length() > 0) {
       
   187             sb.deleteCharAt(sb.length() - 1);
       
   188         }
       
   189         return sb.toString();
       
   190     }
       
   191 }