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<WinAppBundler> APP_BUNDLER |
|
126 44 = new WindowsBundlerParam<>( |
|
127 45 "win.app.bundler", |
|
128 46 WinAppBundler.class, |
|
129 47 params -> new WinAppBundler(), |
|
130 48 null); |
|
131 49 |
|
132 50 public static final BundlerParamInfo<File> EXE_IMAGE_DIR |
|
133 51 = new WindowsBundlerParam<>( |
|
134 52 "win.exe.imageDir", |
|
135 53 File.class, |
|
136 54 params -> { |
|
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) -> 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<BundlerParamInfo<?>> getBundleParameters() { |
|
169 87 return new WinMsiBundler().getBundleParameters(); |
|
170 88 } |
|
171 89 |
|
172 90 @Override |
|
173 91 public File execute(Map<String, ? super Object> 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<String, ? super Object> params) |
|
185 103 throws UnsupportedPlatformException, ConfigException { |
|
186 104 return new WinMsiBundler().validate(params); |
|
187 105 } |
|
188 106 |
|
189 107 public File bundle(Map<String, ? super Object> 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> |
|