src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinExeBundler.java.html
branchJDK-8200758-branch
changeset 57414 6eda749d3117
parent 57413 45c74e654794
child 57415 50ac38fbd874
equal deleted inserted replaced
57413:45c74e654794 57414:6eda749d3117
     1 <?xml version="1.0"?>
       
     2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
       
     3     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
       
     4 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
       
     5 <head><meta charset="utf-8">
       
     6 <meta http-equiv="cache-control" content="no-cache" />
       
     7 <meta http-equiv="Pragma" content="no-cache" />
       
     8 <meta http-equiv="Expires" content="-1" />
       
     9 <!--
       
    10    Note to customizers: the body of the webrev is IDed as SUNWwebrev
       
    11    to allow easy overriding by users of webrev via the userContent.css
       
    12    mechanism available in some browsers.
       
    13 
       
    14    For example, to have all "removed" information be red instead of
       
    15    brown, set a rule in your userContent.css file like:
       
    16 
       
    17        body#SUNWwebrev span.removed { color: red ! important; }
       
    18 -->
       
    19 <style type="text/css" media="screen">
       
    20 body {
       
    21     background-color: #eeeeee;
       
    22 }
       
    23 hr {
       
    24     border: none 0;
       
    25     border-top: 1px solid #aaa;
       
    26     height: 1px;
       
    27 }
       
    28 div.summary {
       
    29     font-size: .8em;
       
    30     border-bottom: 1px solid #aaa;
       
    31     padding-left: 1em;
       
    32     padding-right: 1em;
       
    33 }
       
    34 div.summary h2 {
       
    35     margin-bottom: 0.3em;
       
    36 }
       
    37 div.summary table th {
       
    38     text-align: right;
       
    39     vertical-align: top;
       
    40     white-space: nowrap;
       
    41 }
       
    42 span.lineschanged {
       
    43     font-size: 0.7em;
       
    44 }
       
    45 span.oldmarker {
       
    46     color: red;
       
    47     font-size: large;
       
    48     font-weight: bold;
       
    49 }
       
    50 span.newmarker {
       
    51     color: green;
       
    52     font-size: large;
       
    53     font-weight: bold;
       
    54 }
       
    55 span.removed {
       
    56     color: brown;
       
    57 }
       
    58 span.changed {
       
    59     color: blue;
       
    60 }
       
    61 span.new {
       
    62     color: blue;
       
    63     font-weight: bold;
       
    64 }
       
    65 a.print { font-size: x-small; }
       
    66 
       
    67 </style>
       
    68 
       
    69 <style type="text/css" media="print">
       
    70 pre { font-size: 0.8em; font-family: courier, monospace; }
       
    71 span.removed { color: #444; font-style: italic }
       
    72 span.changed { font-weight: bold; }
       
    73 span.new { font-weight: bold; }
       
    74 span.newmarker { font-size: 1.2em; font-weight: bold; }
       
    75 span.oldmarker { font-size: 1.2em; font-weight: bold; }
       
    76 a.print {display: none}
       
    77 hr { border: none 0; border-top: 1px solid #aaa; height: 1px; }
       
    78 </style>
       
    79 
       
    80 <title>New src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinExeBundler.java</title>
       
    81 <body id="SUNWwebrev">
       
    82 <pre>
       
    83    1 /*
       
    84    2  * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
       
    85    3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
    86    4  *
       
    87    5  * This code is free software; you can redistribute it and/or modify it
       
    88    6  * under the terms of the GNU General Public License version 2 only, as
       
    89    7  * published by the Free Software Foundation.  Oracle designates this
       
    90    8  * particular file as subject to the "Classpath" exception as provided
       
    91    9  * by Oracle in the LICENSE file that accompanied this code.
       
    92   10  *
       
    93   11  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    94   12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    95   13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    96   14  * version 2 for more details (a copy is included in the LICENSE file that
       
    97   15  * accompanied this code).
       
    98   16  *
       
    99   17  * You should have received a copy of the GNU General Public License version
       
   100   18  * 2 along with this work; if not, write to the Free Software Foundation,
       
   101   19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
   102   20  *
       
   103   21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
   104   22  * or visit www.oracle.com if you need additional information or have any
       
   105   23  * questions.
       
   106   24  */
       
   107   25 package jdk.jpackage.internal;
       
   108   26 
       
   109   27 import java.io.*;
       
   110   28 import java.nio.file.Files;
       
   111   29 import java.nio.file.Path;
       
   112   30 import java.nio.file.Paths;
       
   113   31 import java.text.MessageFormat;
       
   114   32 import java.util.*;
       
   115   33 
       
   116   34 public class WinExeBundler extends AbstractBundler {
       
   117   35 
       
   118   36     static {
       
   119   37         System.loadLibrary("jpackage");
       
   120   38     }
       
   121   39 
       
   122   40     private static final ResourceBundle I18N = ResourceBundle.getBundle(
       
   123   41             "jdk.jpackage.internal.resources.WinResources");
       
   124   42 
       
   125   43     public static final BundlerParamInfo&lt;WinAppBundler&gt; APP_BUNDLER
       
   126   44             = new WindowsBundlerParam&lt;&gt;(
       
   127   45                     "win.app.bundler",
       
   128   46                     WinAppBundler.class,
       
   129   47                     params -&gt; new WinAppBundler(),
       
   130   48                     null);
       
   131   49 
       
   132   50     public static final BundlerParamInfo&lt;File&gt; EXE_IMAGE_DIR
       
   133   51             = new WindowsBundlerParam&lt;&gt;(
       
   134   52                     "win.exe.imageDir",
       
   135   53                     File.class,
       
   136   54                     params -&gt; {
       
   137   55                         File imagesRoot = IMAGES_ROOT.fetchFrom(params);
       
   138   56                         if (!imagesRoot.exists()) {
       
   139   57                             imagesRoot.mkdirs();
       
   140   58                         }
       
   141   59                         return new File(imagesRoot, "win-exe.image");
       
   142   60                     },
       
   143   61                     (s, p) -&gt; null);
       
   144   62 
       
   145   63     private final static String EXE_WRAPPER_NAME = "msiwrapper.exe";
       
   146   64 
       
   147   65     @Override
       
   148   66     public String getName() {
       
   149   67         return getString("exe.bundler.name");
       
   150   68     }
       
   151   69 
       
   152   70     @Override
       
   153   71     public String getDescription() {
       
   154   72         return getString("exe.bundler.description");
       
   155   73     }
       
   156   74 
       
   157   75     @Override
       
   158   76     public String getID() {
       
   159   77         return "exe";
       
   160   78     }
       
   161   79 
       
   162   80     @Override
       
   163   81     public String getBundleType() {
       
   164   82         return "INSTALLER";
       
   165   83     }
       
   166   84 
       
   167   85     @Override
       
   168   86     public Collection&lt;BundlerParamInfo&lt;?&gt;&gt; getBundleParameters() {
       
   169   87         return new WinMsiBundler().getBundleParameters();
       
   170   88     }
       
   171   89 
       
   172   90     @Override
       
   173   91     public File execute(Map&lt;String, ? super Object&gt; params,
       
   174   92             File outputParentDir) throws PackagerException {
       
   175   93         return bundle(params, outputParentDir);
       
   176   94     }
       
   177   95 
       
   178   96     @Override
       
   179   97     public boolean supported(boolean platformInstaller) {
       
   180   98         return (Platform.getPlatform() == Platform.WINDOWS);
       
   181   99     }
       
   182  100 
       
   183  101     @Override
       
   184  102     public boolean validate(Map&lt;String, ? super Object&gt; params)
       
   185  103             throws UnsupportedPlatformException, ConfigException {
       
   186  104         return new WinMsiBundler().validate(params);
       
   187  105     }
       
   188  106 
       
   189  107     public File bundle(Map&lt;String, ? super Object&gt; params, File outdir)
       
   190  108             throws PackagerException {
       
   191  109 
       
   192  110         File exeImageDir = EXE_IMAGE_DIR.fetchFrom(params);
       
   193  111 
       
   194  112         // Write msi to temporary directory.
       
   195  113         File msi = new WinMsiBundler().bundle(params, exeImageDir);
       
   196  114 
       
   197  115         try {
       
   198  116             return buildEXE(msi, outdir);
       
   199  117         } catch (IOException ex) {
       
   200  118             Log.verbose(ex);
       
   201  119             throw new PackagerException(ex);
       
   202  120         }
       
   203  121     }
       
   204  122 
       
   205  123     private File buildEXE(File msi, File outdir)
       
   206  124             throws IOException {
       
   207  125 
       
   208  126         Log.verbose(MessageFormat.format(
       
   209  127                 getString("message.outputting-to-location"),
       
   210  128                 outdir.getAbsolutePath()));
       
   211  129 
       
   212  130         // Copy template msi wrapper next to msi file
       
   213  131         String exePath = msi.getAbsolutePath();
       
   214  132         exePath = exePath.substring(0, exePath.lastIndexOf('.')) + ".exe";
       
   215  133         try (InputStream is = getResourceAsStream(EXE_WRAPPER_NAME)) {
       
   216  134             Files.copy(is, Path.of(exePath));
       
   217  135         }
       
   218  136         // Embed msi in msi wrapper exe.
       
   219  137         embedMSI(exePath, msi.getAbsolutePath());
       
   220  138 
       
   221  139         Path dstExePath = Paths.get(outdir.getAbsolutePath(), Path.of(exePath).getFileName().toString());
       
   222  140         Files.deleteIfExists(dstExePath);
       
   223  141 
       
   224  142         Files.copy(Path.of(exePath), dstExePath);
       
   225  143 
       
   226  144         Log.verbose(MessageFormat.format(
       
   227  145                 getString("message.output-location"),
       
   228  146                 outdir.getAbsolutePath()));
       
   229  147 
       
   230  148         return dstExePath.toFile();
       
   231  149     }
       
   232  150 
       
   233  151     private static String getString(String key)
       
   234  152             throws MissingResourceException {
       
   235  153         return I18N.getString(key);
       
   236  154     }
       
   237  155 
       
   238  156     private static native int embedMSI(String exePath, String msiPath);
       
   239  157 }
       
   240 </pre></body></html>