72 private static final String FA_DESCRIPTION = "description"; |
72 private static final String FA_DESCRIPTION = "description"; |
73 private static final String FA_ICON = "icon"; |
73 private static final String FA_ICON = "icon"; |
74 |
74 |
75 public static final BundlerParamInfo<Boolean> CREATE_IMAGE = |
75 public static final BundlerParamInfo<Boolean> CREATE_IMAGE = |
76 new StandardBundlerParam<>( |
76 new StandardBundlerParam<>( |
77 I18N.getString("param.create-image.name"), |
|
78 I18N.getString("param.create-image.description"), |
|
79 IMAGE_MODE, |
77 IMAGE_MODE, |
80 Boolean.class, |
78 Boolean.class, |
81 p -> Boolean.FALSE, |
79 p -> Boolean.FALSE, |
82 (s, p) -> (s == null || "null".equalsIgnoreCase(s)) ? |
80 (s, p) -> (s == null || "null".equalsIgnoreCase(s)) ? |
83 true : Boolean.valueOf(s)); |
81 true : Boolean.valueOf(s)); |
84 |
82 |
85 public static final BundlerParamInfo<Boolean> CREATE_INSTALLER = |
83 public static final BundlerParamInfo<Boolean> CREATE_INSTALLER = |
86 new StandardBundlerParam<>( |
84 new StandardBundlerParam<>( |
87 I18N.getString("param.create-installer.name"), |
|
88 I18N.getString("param.create-installer.description"), |
|
89 INSTALLER_MODE, |
85 INSTALLER_MODE, |
90 Boolean.class, |
86 Boolean.class, |
91 p -> Boolean.FALSE, |
87 p -> Boolean.FALSE, |
92 (s, p) -> (s == null || "null".equalsIgnoreCase(s)) ? |
88 (s, p) -> (s == null || "null".equalsIgnoreCase(s)) ? |
93 true : Boolean.valueOf(s)); |
89 true : Boolean.valueOf(s)); |
94 |
90 |
95 // regexp for parsing args (for example, for secondary launchers) |
91 // regexp for parsing args (for example, for additional launchers) |
96 private static Pattern pattern = Pattern.compile( |
92 private static Pattern pattern = Pattern.compile( |
97 "(?:(?:([\"'])(?:\\\\\\1|.)*?(?:\\1|$))|(?:\\\\[\"'\\s]|[^\\s]))++"); |
93 "(?:(?:([\"'])(?:\\\\\\1|.)*?(?:\\1|$))|(?:\\\\[\"'\\s]|[^\\s]))++"); |
98 |
94 |
99 private DeployParams deployParams = null; |
95 private DeployParams deployParams = null; |
100 private BundlerType bundleType = null; |
96 private BundlerType bundleType = null; |
121 |
117 |
122 private static boolean runtimeInstaller = false; |
118 private static boolean runtimeInstaller = false; |
123 |
119 |
124 private List<jdk.jpackage.internal.Bundler> platformBundlers = null; |
120 private List<jdk.jpackage.internal.Bundler> platformBundlers = null; |
125 |
121 |
126 private List<SecondaryLauncherArguments> secondaryLaunchers = null; |
122 private List<AddLauncherArguments> addLaunchers = null; |
127 |
123 |
128 private static Map<String, CLIOptions> argIds = new HashMap<>(); |
124 private static Map<String, CLIOptions> argIds = new HashMap<>(); |
129 private static Map<String, CLIOptions> argShortIds = new HashMap<>(); |
125 private static Map<String, CLIOptions> argShortIds = new HashMap<>(); |
130 |
126 |
131 { |
127 { |
157 context().bundleType = BundlerType.INSTALLER; |
153 context().bundleType = BundlerType.INSTALLER; |
158 String format = "installer"; |
154 String format = "installer"; |
159 context().deployParams.setTargetFormat(format); |
155 context().deployParams.setTargetFormat(format); |
160 }), |
156 }), |
161 |
157 |
162 RUNTIME_INSTALLER("runtime-installer", |
|
163 OptionCategories.PROPERTY, () -> { |
|
164 runtimeInstaller = true; |
|
165 setOptionValue("runtime-installer", true); |
|
166 }), |
|
167 |
|
168 INSTALLER_TYPE("installer-type", OptionCategories.PROPERTY, () -> { |
158 INSTALLER_TYPE("installer-type", OptionCategories.PROPERTY, () -> { |
169 String type = popArg(); |
159 String type = popArg(); |
170 if (BundlerType.INSTALLER.equals(context().bundleType)) { |
160 if (BundlerType.INSTALLER.equals(context().bundleType)) { |
171 context().deployParams.setTargetFormat(type); |
161 context().deployParams.setTargetFormat(type); |
172 context().hasTargetFormat = true; |
162 context().hasTargetFormat = true; |
186 |
176 |
187 DESCRIPTION ("description", "d", OptionCategories.PROPERTY), |
177 DESCRIPTION ("description", "d", OptionCategories.PROPERTY), |
188 |
178 |
189 VENDOR ("vendor", OptionCategories.PROPERTY), |
179 VENDOR ("vendor", OptionCategories.PROPERTY), |
190 |
180 |
191 APPCLASS ("main-class", "c", OptionCategories.PROPERTY, () -> { |
181 APPCLASS ("main-class", OptionCategories.PROPERTY, () -> { |
192 context().hasMainClass = true; |
182 context().hasMainClass = true; |
193 setOptionValue("main-class", popArg()); |
183 setOptionValue("main-class", popArg()); |
194 }), |
184 }), |
195 |
185 |
196 NAME ("name", "n", OptionCategories.PROPERTY), |
186 NAME ("name", "n", OptionCategories.PROPERTY), |
198 IDENTIFIER ("identifier", OptionCategories.PROPERTY), |
188 IDENTIFIER ("identifier", OptionCategories.PROPERTY), |
199 |
189 |
200 VERBOSE ("verbose", OptionCategories.PROPERTY, () -> { |
190 VERBOSE ("verbose", OptionCategories.PROPERTY, () -> { |
201 setOptionValue("verbose", true); |
191 setOptionValue("verbose", true); |
202 Log.setVerbose(true); |
192 Log.setVerbose(true); |
203 }), |
|
204 |
|
205 OVERWRITE ("overwrite", OptionCategories.PROPERTY, () -> { |
|
206 setOptionValue("overwrite", true); |
|
207 }), |
193 }), |
208 |
194 |
209 RESOURCE_DIR("resource-dir", |
195 RESOURCE_DIR("resource-dir", |
210 OptionCategories.PROPERTY, () -> { |
196 OptionCategories.PROPERTY, () -> { |
211 String resourceDir = popArg(); |
197 String resourceDir = popArg(); |
217 String files = popArg(); |
203 String files = popArg(); |
218 context().files.addAll( |
204 context().files.addAll( |
219 Arrays.asList(files.split(File.pathSeparator))); |
205 Arrays.asList(files.split(File.pathSeparator))); |
220 }), |
206 }), |
221 |
207 |
222 ARGUMENTS ("arguments", "a", OptionCategories.PROPERTY, () -> { |
208 ARGUMENTS ("arguments", OptionCategories.PROPERTY, () -> { |
223 List<String> arguments = getArgumentList(popArg()); |
209 List<String> arguments = getArgumentList(popArg()); |
224 setOptionValue("arguments", arguments); |
210 setOptionValue("arguments", arguments); |
225 }), |
211 }), |
226 |
212 |
227 STRIP_NATIVE_COMMANDS ("strip-native-commands", |
|
228 OptionCategories.PROPERTY, () -> { |
|
229 setOptionValue("strip-native-commands", true); |
|
230 }), |
|
231 |
|
232 ICON ("icon", OptionCategories.PROPERTY), |
213 ICON ("icon", OptionCategories.PROPERTY), |
233 CATEGORY ("category", OptionCategories.PROPERTY), |
214 |
234 COPYRIGHT ("copyright", OptionCategories.PROPERTY), |
215 COPYRIGHT ("copyright", OptionCategories.PROPERTY), |
235 |
216 |
236 LICENSE_FILE ("license-file", OptionCategories.PROPERTY), |
217 LICENSE_FILE ("license-file", OptionCategories.PROPERTY), |
237 |
218 |
238 VERSION ("app-version", OptionCategories.PROPERTY), |
219 VERSION ("app-version", OptionCategories.PROPERTY), |
277 // check that we really add _another_ value to the list |
258 // check that we really add _another_ value to the list |
278 setOptionValue("file-associations", associationList); |
259 setOptionValue("file-associations", associationList); |
279 |
260 |
280 }), |
261 }), |
281 |
262 |
282 SECONDARY_LAUNCHER ("secondary-launcher", |
263 ADD_LAUNCHER ("add-launcher", |
283 OptionCategories.PROPERTY, () -> { |
264 OptionCategories.PROPERTY, () -> { |
284 context().secondaryLaunchers.add( |
265 context().addLaunchers.add( |
285 new SecondaryLauncherArguments(popArg())); |
266 new AddLauncherArguments(popArg())); |
286 }), |
267 }), |
287 |
268 |
288 BUILD_ROOT ("build-root", OptionCategories.PROPERTY, () -> { |
269 TEMP_ROOT ("temp-root", OptionCategories.PROPERTY, () -> { |
289 context().buildRoot = popArg(); |
270 context().buildRoot = popArg(); |
290 context().userProvidedBuildRoot = true; |
271 context().userProvidedBuildRoot = true; |
291 setOptionValue("build-root", context().buildRoot); |
272 setOptionValue("temp-root", context().buildRoot); |
292 }), |
273 }), |
293 |
274 |
294 INSTALL_DIR ("install-dir", OptionCategories.PROPERTY), |
275 INSTALL_DIR ("install-dir", OptionCategories.PROPERTY), |
295 |
276 |
296 PREDEFINED_APP_IMAGE ("app-image", OptionCategories.PROPERTY, ()-> { |
277 PREDEFINED_APP_IMAGE ("app-image", OptionCategories.PROPERTY, ()-> { |
298 context().hasAppImage = true; |
279 context().hasAppImage = true; |
299 }), |
280 }), |
300 |
281 |
301 PREDEFINED_RUNTIME_IMAGE ("runtime-image", OptionCategories.PROPERTY), |
282 PREDEFINED_RUNTIME_IMAGE ("runtime-image", OptionCategories.PROPERTY), |
302 |
283 |
303 MAIN_JAR ("main-jar", "j", OptionCategories.PROPERTY, () -> { |
284 MAIN_JAR ("main-jar", OptionCategories.PROPERTY, () -> { |
304 context().mainJarPath = popArg(); |
285 context().mainJarPath = popArg(); |
305 context().hasMainJar = true; |
286 context().hasMainJar = true; |
306 setOptionValue("main-jar", context().mainJarPath); |
287 setOptionValue("main-jar", context().mainJarPath); |
307 }), |
288 }), |
308 |
289 |
377 |
358 |
378 LINUX_RPM_LICENSE_TYPE ("linux-rpm-license-type", |
359 LINUX_RPM_LICENSE_TYPE ("linux-rpm-license-type", |
379 OptionCategories.PLATFORM_LINUX), |
360 OptionCategories.PLATFORM_LINUX), |
380 |
361 |
381 LINUX_PACKAGE_DEPENDENCIES ("linux-package-deps", |
362 LINUX_PACKAGE_DEPENDENCIES ("linux-package-deps", |
382 OptionCategories.PLATFORM_LINUX); |
363 OptionCategories.PLATFORM_LINUX), |
|
364 |
|
365 LINUX_MENU_GROUP ("linux-menu-group", OptionCategories.PLATFORM_LINUX); |
383 |
366 |
384 private final String id; |
367 private final String id; |
385 private final String shortId; |
368 private final String shortId; |
386 private final OptionCategories category; |
369 private final OptionCategories category; |
387 private final ArgAction action; |
370 private final ArgAction action; |
502 deployParams = new DeployParams(); |
485 deployParams = new DeployParams(); |
503 bundleType = BundlerType.NONE; |
486 bundleType = BundlerType.NONE; |
504 |
487 |
505 allOptions = new ArrayList<>(); |
488 allOptions = new ArrayList<>(); |
506 |
489 |
507 secondaryLaunchers = new ArrayList<>(); |
490 addLaunchers = new ArrayList<>(); |
508 } |
491 } |
509 |
492 |
510 public boolean processArguments() throws Exception { |
493 public boolean processArguments() throws Exception { |
511 try { |
494 try { |
512 |
495 |
551 deployParams.setBundleType(bundleType); |
534 deployParams.setBundleType(bundleType); |
552 |
535 |
553 List<Map<String, ? super Object>> launchersAsMap = |
536 List<Map<String, ? super Object>> launchersAsMap = |
554 new ArrayList<>(); |
537 new ArrayList<>(); |
555 |
538 |
556 for (SecondaryLauncherArguments sl : secondaryLaunchers) { |
539 for (AddLauncherArguments sl : addLaunchers) { |
557 launchersAsMap.add(sl.getLauncherMap()); |
540 launchersAsMap.add(sl.getLauncherMap()); |
558 } |
541 } |
559 |
542 |
560 deployParams.addBundleArgument( |
543 deployParams.addBundleArgument( |
561 StandardBundlerParam.SECONDARY_LAUNCHERS.getID(), |
544 StandardBundlerParam.ADD_LAUNCHERS.getID(), |
562 launchersAsMap); |
545 launchersAsMap); |
563 |
546 |
564 // at this point deployParams should be already configured |
547 // at this point deployParams should be already configured |
565 |
548 |
566 deployParams.validate(); |
549 deployParams.validate(); |
569 |
552 |
570 // validate name(s) |
553 // validate name(s) |
571 ArrayList<String> usedNames = new ArrayList<String>(); |
554 ArrayList<String> usedNames = new ArrayList<String>(); |
572 usedNames.add(bp.getName()); // add main app name |
555 usedNames.add(bp.getName()); // add main app name |
573 |
556 |
574 for (SecondaryLauncherArguments sl : secondaryLaunchers) { |
557 for (AddLauncherArguments sl : addLaunchers) { |
575 Map<String, ? super Object> slMap = sl.getLauncherMap(); |
558 Map<String, ? super Object> slMap = sl.getLauncherMap(); |
576 String slName = |
559 String slName = |
577 (String) slMap.get(Arguments.CLIOptions.NAME.getId()); |
560 (String) slMap.get(Arguments.CLIOptions.NAME.getId()); |
578 if (slName == null) { |
561 if (slName == null) { |
579 throw new PackagerException("ERR_NoSecondaryLauncherName"); |
562 throw new PackagerException("ERR_NoAddLauncherName"); |
580 } |
563 } |
581 // same rules apply to secondary launcher names as app name |
564 // same rules apply to additional launcher names as app name |
582 DeployParams.validateName(slName, false); |
565 DeployParams.validateName(slName, false); |
583 for (String usedName : usedNames) { |
566 for (String usedName : usedNames) { |
584 if (slName.equals(usedName)) { |
567 if (slName.equals(usedName)) { |
585 throw new PackagerException("ERR_NoUniqueName"); |
568 throw new PackagerException("ERR_NoUniqueName"); |
586 } |
569 } |
603 return false; |
586 return false; |
604 } |
587 } |
605 } |
588 } |
606 } |
589 } |
607 |
590 |
608 private void validateArguments() { |
591 private void validateArguments() throws PackagerException { |
609 CLIOptions mode = allOptions.get(0); |
592 CLIOptions mode = allOptions.get(0); |
|
593 boolean imageOnly = (mode == CLIOptions.CREATE_IMAGE); |
|
594 boolean hasAppImage = allOptions.contains( |
|
595 CLIOptions.PREDEFINED_APP_IMAGE); |
|
596 boolean hasRuntime = allOptions.contains( |
|
597 CLIOptions.PREDEFINED_RUNTIME_IMAGE); |
|
598 boolean installerOnly = !imageOnly && hasAppImage; |
|
599 boolean runtimeInstall = !imageOnly && hasRuntime && !hasAppImage && |
|
600 !hasMainModule && !hasMainJar; |
|
601 |
610 for (CLIOptions option : allOptions) { |
602 for (CLIOptions option : allOptions) { |
611 if(!ValidOptions.checkIfSupported(mode, option)) { |
603 if (!ValidOptions.checkIfSupported(option)) { |
612 String key = "warning.unsupported.option"; |
604 // includes option valid only on different platform |
613 if (ValidOptions.checkIfOtherSupported(mode, option)) { |
605 throw new PackagerException("ERR_UnsupportedOption", |
614 key = "warning.unsupported.mode.option"; |
606 option.getIdWithPrefix()); |
615 } |
607 } |
616 Log.info(MessageFormat.format(I18N.getString(key), |
608 if (imageOnly) { |
617 option.getId(), mode)); |
609 if (!ValidOptions.checkIfImageSupported(option)) { |
618 } |
610 throw new PackagerException("ERR_NotImageOption", |
|
611 option.getIdWithPrefix()); |
|
612 } |
|
613 } else if (installerOnly || runtimeInstall) { |
|
614 if (!ValidOptions.checkIfInstallerSupported(option)) { |
|
615 String key = runtimeInstaller ? |
|
616 "ERR_NoInstallerEntryPoint" : "ERR_NotInstallerOption"; |
|
617 throw new PackagerException(key, option.getIdWithPrefix()); |
|
618 } |
|
619 } |
|
620 } |
|
621 if (installerOnly && hasRuntime) { |
|
622 // note --runtime-image is only for image or runtime installer. |
|
623 throw new PackagerException("ERR_NotInstallerOption", |
|
624 CLIOptions.PREDEFINED_RUNTIME_IMAGE.getIdWithPrefix()); |
|
625 } |
|
626 if (hasMainJar && hasMainModule) { |
|
627 throw new PackagerException("ERR_BothMainJarAndModule"); |
|
628 } |
|
629 if (imageOnly && !hasMainJar && !hasMainModule) { |
|
630 throw new PackagerException("ERR_NoEntryPoint"); |
619 } |
631 } |
620 } |
632 } |
621 |
633 |
622 private List<jdk.jpackage.internal.Bundler> getPlatformBundlers() { |
634 private List<jdk.jpackage.internal.Bundler> getPlatformBundlers() { |
623 |
635 |
645 private boolean generateBundle(Map<String,? super Object> params) |
657 private boolean generateBundle(Map<String,? super Object> params) |
646 throws PackagerException { |
658 throws PackagerException { |
647 |
659 |
648 boolean bundleCreated = false; |
660 boolean bundleCreated = false; |
649 |
661 |
650 // the build-root needs to be fetched from the params early, |
662 // the temp-root needs to be fetched from the params early, |
651 // to prevent each copy of the params (such as may be used for |
663 // to prevent each copy of the params (such as may be used for |
652 // secondary launchers) from generating a separate build-root when |
664 // additional launchers) from generating a separate temp-root when |
653 // the default is used (the default is a new temp directory) |
665 // the default is used (the default is a new temp directory) |
654 // The bundler.cleanup() below would not otherwise be able to |
666 // The bundler.cleanup() below would not otherwise be able to |
655 // clean these extra (and unneeded) temp directories. |
667 // clean these extra (and unneeded) temp directories. |
656 StandardBundlerParam.BUILD_ROOT.fetchFrom(params); |
668 StandardBundlerParam.TEMP_ROOT.fetchFrom(params); |
657 |
669 List<jdk.jpackage.internal.Bundler> bundlers = getPlatformBundlers(); |
658 for (jdk.jpackage.internal.Bundler bundler : getPlatformBundlers()) { |
670 if (bundlers.isEmpty()) { |
|
671 throw new PackagerException("ERR_InvalidInstallerType", |
|
672 deployParams.getTargetFormat()); |
|
673 } |
|
674 for (jdk.jpackage.internal.Bundler bundler : bundlers) { |
659 Map<String, ? super Object> localParams = new HashMap<>(params); |
675 Map<String, ? super Object> localParams = new HashMap<>(params); |
660 try { |
676 try { |
661 if (bundler.validate(localParams)) { |
677 if (bundler.validate(localParams)) { |
662 File result = |
678 File result = |
663 bundler.execute(localParams, deployParams.outdir); |
679 bundler.execute(localParams, deployParams.outdir); |