8269387: jpackage --add-launcher should have option to not create shortcuts for additional launchers

Reviewed-by: asemenyuk, almatvee
This commit is contained in:
Andy Herrick 2021-07-15 17:04:54 +00:00
parent 746fe5dc68
commit 057992f206
11 changed files with 328 additions and 83 deletions

View File

@ -56,6 +56,7 @@ import static jdk.jpackage.internal.StandardBundlerParam.DESCRIPTION;
import static jdk.jpackage.internal.StandardBundlerParam.FILE_ASSOCIATIONS;
import static jdk.jpackage.internal.StandardBundlerParam.ICON;
import static jdk.jpackage.internal.StandardBundlerParam.PREDEFINED_APP_IMAGE;
import static jdk.jpackage.internal.StandardBundlerParam.SHORTCUT_HINT;;
/**
* Helper to create files for desktop integration.
@ -82,7 +83,7 @@ final class DesktopIntegration {
// Need desktop and icon files if one of conditions is met:
// - there are file associations configured
// - user explicitely requested to create a shortcut
boolean withDesktopFile = !associations.isEmpty() || SHORTCUT_HINT.fetchFrom(params);
boolean withDesktopFile = !associations.isEmpty() || LINUX_SHORTCUT_HINT.fetchFrom(params);
var curIconResource = LinuxAppImageBuilder.createIconResource(DEFAULT_ICON,
ICON_PNG, params, mainParams);
@ -138,28 +139,34 @@ final class DesktopIntegration {
// Read launchers information from predefine app image
if (launchers.isEmpty() &&
PREDEFINED_APP_IMAGE.fetchFrom(params) != null) {
List<String> launcherPaths = AppImageFile.getLauncherNames(
List<AppImageFile.LauncherInfo> launcherInfos =
AppImageFile.getLaunchers(
PREDEFINED_APP_IMAGE.fetchFrom(params), params);
if (!launcherPaths.isEmpty()) {
launcherPaths.remove(0); // Remove main launcher
if (!launcherInfos.isEmpty()) {
launcherInfos.remove(0); // Remove main launcher
}
for (var launcherPath : launcherPaths) {
for (var launcherInfo : launcherInfos) {
Map<String, ? super Object> launcherParams = new HashMap<>();
Arguments.putUnlessNull(launcherParams, CLIOptions.NAME.getId(),
launcherPath);
launcherParams = AddLauncherArguments.merge(params, launcherParams,
ICON.getID(), ICON_PNG.getID(), ADD_LAUNCHERS.getID(),
FILE_ASSOCIATIONS.getID(), PREDEFINED_APP_IMAGE.getID());
nestedIntegrations.add(new DesktopIntegration(thePackage,
launcherParams, params));
launcherInfo.getName());
launcherParams = AddLauncherArguments.merge(params,
launcherParams, ICON.getID(), ICON_PNG.getID(),
ADD_LAUNCHERS.getID(), FILE_ASSOCIATIONS.getID(),
PREDEFINED_APP_IMAGE.getID());
if (launcherInfo.isShortcut()) {
nestedIntegrations.add(new DesktopIntegration(thePackage,
launcherParams, params));
}
}
} else {
for (var launcherParams : launchers) {
launcherParams = AddLauncherArguments.merge(params, launcherParams,
ICON.getID(), ICON_PNG.getID(), ADD_LAUNCHERS.getID(),
FILE_ASSOCIATIONS.getID());
nestedIntegrations.add(new DesktopIntegration(thePackage,
launcherParams, params));
launcherParams = AddLauncherArguments.merge(params,
launcherParams, ICON.getID(), ICON_PNG.getID(),
ADD_LAUNCHERS.getID(), FILE_ASSOCIATIONS.getID());
if (SHORTCUT_HINT.fetchFrom(launcherParams)) {
nestedIntegrations.add(new DesktopIntegration(thePackage,
launcherParams, params));
}
}
}
}
@ -567,7 +574,7 @@ final class DesktopIntegration {
(s, p) -> s
);
private static final StandardBundlerParam<Boolean> SHORTCUT_HINT =
private static final StandardBundlerParam<Boolean> LINUX_SHORTCUT_HINT =
new StandardBundlerParam<>(
Arguments.CLIOptions.LINUX_SHORTCUT_HINT.getId(),
Boolean.class,

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -32,6 +32,8 @@ import java.util.List;
import jdk.jpackage.internal.Arguments.CLIOptions;
import static jdk.jpackage.internal.StandardBundlerParam.LAUNCHER_DATA;
import static jdk.jpackage.internal.StandardBundlerParam.APP_NAME;
import static jdk.jpackage.internal.StandardBundlerParam.MENU_HINT;
import static jdk.jpackage.internal.StandardBundlerParam.SHORTCUT_HINT;
/*
* AddLauncherArguments
@ -59,7 +61,10 @@ import static jdk.jpackage.internal.StandardBundlerParam.APP_NAME;
* arguments
* java-options
* win-console
* win-shortcut
* win-menu
* linux-app-category
* linux-shortcut
*
*/
class AddLauncherArguments {
@ -109,17 +114,27 @@ class AddLauncherArguments {
Arguments.putUnlessNull(bundleParams, CLIOptions.RELEASE.getId(),
getOptionValue(CLIOptions.RELEASE));
Arguments.putUnlessNull(bundleParams, CLIOptions.LINUX_CATEGORY.getId(),
getOptionValue(CLIOptions.LINUX_CATEGORY));
Arguments.putUnlessNull(bundleParams,
CLIOptions.WIN_CONSOLE_HINT.getId(),
getOptionValue(CLIOptions.WIN_CONSOLE_HINT));
String value = getOptionValue(CLIOptions.ICON);
Arguments.putUnlessNull(bundleParams, CLIOptions.ICON.getId(),
(value == null) ? null : Path.of(value));
if (Platform.isWindows()) {
Arguments.putUnlessNull(bundleParams,
CLIOptions.WIN_CONSOLE_HINT.getId(),
getOptionValue(CLIOptions.WIN_CONSOLE_HINT));
Arguments.putUnlessNull(bundleParams, SHORTCUT_HINT.getID(),
getOptionValue(CLIOptions.WIN_SHORTCUT_HINT));
Arguments.putUnlessNull(bundleParams, MENU_HINT.getID(),
getOptionValue(CLIOptions.WIN_MENU_HINT));
}
if (Platform.isLinux()) {
Arguments.putUnlessNull(bundleParams, CLIOptions.LINUX_CATEGORY.getId(),
getOptionValue(CLIOptions.LINUX_CATEGORY));
Arguments.putUnlessNull(bundleParams, SHORTCUT_HINT.getID(),
getOptionValue(CLIOptions.LINUX_SHORTCUT_HINT));
}
// "arguments" and "java-options" even if value is null:
if (allArgs.containsKey(CLIOptions.ARGUMENTS.getId())) {
String argumentStr = getOptionValue(CLIOptions.ARGUMENTS);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -40,12 +40,16 @@ import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.NamedNodeMap;
import org.xml.sax.SAXException;
import static jdk.jpackage.internal.StandardBundlerParam.VERSION;
import static jdk.jpackage.internal.StandardBundlerParam.ADD_LAUNCHERS;
import static jdk.jpackage.internal.StandardBundlerParam.APP_NAME;
import static jdk.jpackage.internal.StandardBundlerParam.SHORTCUT_HINT;
import static jdk.jpackage.internal.StandardBundlerParam.MENU_HINT;
public class AppImageFile {
@ -53,7 +57,7 @@ public class AppImageFile {
private final String creatorVersion;
private final String creatorPlatform;
private final String launcherName;
private final List<String> addLauncherNames;
private final List<LauncherInfo> addLauncherInfos;
private static final String FILENAME = ".jpackage.xml";
@ -66,10 +70,10 @@ public class AppImageFile {
this(null, null, null, null);
}
private AppImageFile(String launcherName, List<String> addLauncherNames,
private AppImageFile(String launcherName, List<LauncherInfo> launcherInfos,
String creatorVersion, String creatorPlatform) {
this.launcherName = launcherName;
this.addLauncherNames = addLauncherNames;
this.addLauncherInfos = launcherInfos;
this.creatorVersion = creatorVersion;
this.creatorPlatform = creatorPlatform;
}
@ -79,8 +83,8 @@ public class AppImageFile {
* Each item in the list is not null or empty string.
* Returns empty list for application without additional launchers.
*/
List<String> getAddLauncherNames() {
return addLauncherNames;
List<LauncherInfo> getAddLaunchers() {
return addLauncherInfos;
}
/**
@ -131,7 +135,10 @@ public class AppImageFile {
for (int i = 0; i < addLaunchers.size(); i++) {
Map<String, ? super Object> sl = addLaunchers.get(i);
xml.writeStartElement("add-launcher");
xml.writeCharacters(APP_NAME.fetchFrom(sl));
xml.writeAttribute("name", APP_NAME.fetchFrom(sl));
xml.writeAttribute("shortcut",
SHORTCUT_HINT.fetchFrom(sl).toString());
xml.writeAttribute("menu", MENU_HINT.fetchFrom(sl).toString());
xml.writeEndElement();
}
});
@ -156,7 +163,7 @@ public class AppImageFile {
return new AppImageFile();
}
List<String> addLaunchers = new ArrayList<>();
List<LauncherInfo> launcherInfos = new ArrayList<>();
String platform = xpathQueryNullable(xPath,
"/jpackage-state/@platform", doc);
@ -164,16 +171,23 @@ public class AppImageFile {
String version = xpathQueryNullable(xPath,
"/jpackage-state/@version", doc);
NodeList launcherNameNodes = (NodeList) xPath.evaluate(
"/jpackage-state/add-launcher/text()", doc,
NodeList launcherNodes = (NodeList) xPath.evaluate(
"/jpackage-state/add-launcher", doc,
XPathConstants.NODESET);
for (int i = 0; i != launcherNameNodes.getLength(); i++) {
addLaunchers.add(launcherNameNodes.item(i).getNodeValue());
for (int i = 0; i != launcherNodes.getLength(); i++) {
Node item = launcherNodes.item(i);
String name = getAttribute(item, "name");
String shortcut = getAttribute(item, "shortcut");
String menu = getAttribute(item, "menu");
launcherInfos.add(new LauncherInfo(name,
!("false".equals(shortcut)),
!("false".equals(menu))));
}
AppImageFile file = new AppImageFile(
mainLauncher, addLaunchers, version, platform);
mainLauncher, launcherInfos, version, platform);
if (!file.isValid()) {
file = new AppImageFile();
}
@ -184,6 +198,12 @@ public class AppImageFile {
}
}
private static String getAttribute(Node item, String attr) {
NamedNodeMap attrs = item.getAttributes();
Node attrNode = attrs.getNamedItem(attr);
return ((attrNode == null) ? null : attrNode.getNodeValue());
}
public static Document readXml(Path appImageDir) throws IOException {
try {
Path path = getPathInAppImage(appImageDir);
@ -202,18 +222,19 @@ public class AppImageFile {
}
/**
* Returns list of launcher names configured for the application.
* The first item in the returned list is main launcher name.
* Returns list of LauncherInfo objects configured for the application.
* The first item in the returned list is main launcher.
* Following items in the list are names of additional launchers.
*/
static List<String> getLauncherNames(Path appImageDir,
static List<LauncherInfo> getLaunchers(Path appImageDir,
Map<String, ? super Object> params) {
List<String> launchers = new ArrayList<>();
List<LauncherInfo> launchers = new ArrayList<>();
try {
AppImageFile appImageInfo = AppImageFile.load(appImageDir);
if (appImageInfo != null) {
launchers.add(appImageInfo.getLauncherName());
launchers.addAll(appImageInfo.getAddLauncherNames());
launchers.add(new LauncherInfo(
appImageInfo.getLauncherName(), true, true));
launchers.addAll(appImageInfo.getAddLaunchers());
return launchers;
}
} catch (NoSuchFileException nsfe) {
@ -226,10 +247,11 @@ public class AppImageFile {
"warning.invalid-app-image"), appImageDir));
}
// this should never be the case, but maintaining behavior of
// creating default launchers without AppImageFile present
launchers.add(APP_NAME.fetchFrom(params));
ADD_LAUNCHERS.fetchFrom(params).stream().map(APP_NAME::fetchFrom).forEach(
launchers::add);
ADD_LAUNCHERS.fetchFrom(params).stream().map(APP_NAME::fetchFrom).map(
name -> new LauncherInfo(name, true, true)).forEach(launchers::add);
return launchers;
}
@ -262,15 +284,37 @@ public class AppImageFile {
}
private boolean isValid() {
if (launcherName == null || launcherName.length() == 0 ||
addLauncherNames.indexOf("") != -1) {
// Some launchers have empty names. This is invalid.
if (launcherName == null || launcherName.length() == 0) {
return false;
}
// Add more validation.
for (var launcher : addLauncherInfos) {
if ("".equals(launcher.getName())) {
return false;
}
}
return true;
}
static class LauncherInfo {
private String name;
private boolean shortcut;
private boolean menu;
public LauncherInfo(String name, boolean shortcut, boolean menu) {
this.name = name;
this.shortcut = shortcut;
this.menu = menu;
}
public String getName() {
return name;
}
public boolean isShortcut() {
return shortcut;
}
public boolean isMenu() {
return menu;
}
}
}

View File

@ -311,6 +311,24 @@ class StandardBundlerParam<T> extends BundlerParamInfo<T> {
true : Boolean.valueOf(s)
);
static final StandardBundlerParam<Boolean> SHORTCUT_HINT =
new StandardBundlerParam<>(
"shortcut-hint", // not directly related to a CLI option
Boolean.class,
params -> true, // defaults to true
(s, p) -> (s == null || "null".equalsIgnoreCase(s)) ?
true : Boolean.valueOf(s)
);
static final StandardBundlerParam<Boolean> MENU_HINT =
new StandardBundlerParam<>(
"menu-hint", // not directly related to a CLI option
Boolean.class,
params -> true, // defaults to true
(s, p) -> (s == null || "null".equalsIgnoreCase(s)) ?
true : Boolean.valueOf(s)
);
static final StandardBundlerParam<Path> RESOURCE_DIR =
new StandardBundlerParam<>(
Arguments.CLIOptions.RESOURCE_DIR.getId(),

View File

@ -135,8 +135,9 @@ Generic Options:\n\
\ a list of key, value pairs\n\
\ (absolute path or relative to the current directory)\n\
\ The keys "module", "main-jar", "main-class",\n\
\ "arguments", "java-options", "app-version", "icon", and\n\
\ "win-console" can be used.\n\
\ "arguments", "java-options", "app-version", "icon",\n\
\ "win-console", "win-shortcut", "win-menu",\n\
\ "linux-app-category", and "linux-shortcut" can be used.\n\
\ These options are added to, or used to overwrite, the original\n\
\ command line options to build an additional alternative launcher.\n\
\ The main application launcher will be built from the command line\n\

View File

@ -135,8 +135,9 @@ Generic Options:\n\
\ a list of key, value pairs\n\
\ (absolute path or relative to the current directory)\n\
\ The keys "module", "main-jar", "main-class",\n\
\ "arguments", "java-options", "app-version", "icon", and\n\
\ "win-console" can be used.\n\
\ "arguments", "java-options", "app-version", "icon",\n\
\ "win-console", "win-shortcut", "win-menu",\n\
\ "linux-app-category", and "linux-shortcut" can be used.\n\
\ These options are added to, or used to overwrite, the original\n\
\ command line options to build an additional alternative launcher.\n\
\ The main application launcher will be built from the command line\n\

View File

@ -135,8 +135,9 @@ Generic Options:\n\
\ a list of key, value pairs\n\
\ (absolute path or relative to the current directory)\n\
\ The keys "module", "main-jar", "main-class",\n\
\ "arguments", "java-options", "app-version", "icon", and\n\
\ "win-console" can be used.\n\
\ "arguments", "java-options", "app-version", "icon",\n\
\ "win-console", "win-shortcut", "win-menu",\n\
\ "linux-app-category", and "linux-shortcut" can be used.\n\
\ These options are added to, or used to overwrite, the original\n\
\ command line options to build an additional alternative launcher.\n\
\ The main application launcher will be built from the command line\n\

View File

@ -107,12 +107,9 @@ class WixAppImageFragmentBuilder extends WixFragmentBuilder {
Collectors.toSet());
if (StandardBundlerParam.isRuntimeInstaller(params)) {
launcherPaths = Collections.emptyList();
launchers = Collections.emptyList();
} else {
launcherPaths = AppImageFile.getLauncherNames(appImageRoot, params).stream()
.map(name -> installedAppImage.launchersDirectory().resolve(name))
.map(WixAppImageFragmentBuilder::addExeSuffixToPath)
.toList();
launchers = AppImageFile.getLaunchers(appImageRoot, params);
}
programMenuFolderName = MENU_GROUP.fetchFrom(params);
@ -411,13 +408,23 @@ class WixAppImageFragmentBuilder extends WixFragmentBuilder {
XMLStreamException, IOException {
List<String> componentIds = new ArrayList<>();
Set<ShortcutsFolder> defineShortcutFolders = new HashSet<>();
for (var launcherPath : launcherPaths) {
for (var launcher : launchers) {
for (var folder : shortcutFolders) {
String componentId = addShortcutComponent(xml, launcherPath,
folder);
if (componentId != null) {
defineShortcutFolders.add(folder);
componentIds.add(componentId);
Path launcherPath = addExeSuffixToPath(installedAppImage
.launchersDirectory().resolve(launcher.getName()));
if ((launcher.isMenu() &&
(folder.equals(ShortcutsFolder.ProgramMenu))) ||
(launcher.isShortcut() &&
(folder.equals(ShortcutsFolder.Desktop)))) {
String componentId = addShortcutComponent(xml, launcherPath,
folder);
if (componentId != null) {
defineShortcutFolders.add(folder);
componentIds.add(componentId);
}
}
}
}
@ -824,7 +831,7 @@ class WixAppImageFragmentBuilder extends WixFragmentBuilder {
private Set<ShortcutsFolder> shortcutFolders;
private List<Path> launcherPaths;
private List<AppImageFile.LauncherInfo> launchers;
private ApplicationLayout appImage;
private ApplicationLayout installedAppImage;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -81,6 +81,12 @@ public final class AdditionalLauncher {
return this;
}
public AdditionalLauncher setShortcuts(boolean menu, boolean shortcut) {
withMenuShortcut = menu;
withShortcut = shortcut;
return this;
}
public AdditionalLauncher setIcon(Path iconPath) {
if (iconPath == NO_ICON) {
throw new IllegalArgumentException();
@ -143,6 +149,18 @@ public final class AdditionalLauncher {
properties.add(Map.entry("icon", iconPath));
}
if (withShortcut != null) {
if (TKit.isLinux()) {
properties.add(Map.entry("linux-shortcut", withShortcut.toString()));
} else if (TKit.isWindows()) {
properties.add(Map.entry("win-shortcut", withShortcut.toString()));
}
}
if (TKit.isWindows() && withMenuShortcut != null) {
properties.add(Map.entry("win-menu", withMenuShortcut.toString()));
}
properties.addAll(rawProperties);
createFileHandler.accept(propsFile, properties);
@ -178,7 +196,7 @@ public final class AdditionalLauncher {
() -> iconInResourceDir(cmd, name));
while (effectiveIcon != NO_ICON) {
if (effectiveIcon != null) {
withLinuxDesktopFile = true;
withLinuxDesktopFile = Boolean.FALSE != withShortcut;
verifier.setExpectedIcon(effectiveIcon);
break;
}
@ -186,7 +204,7 @@ public final class AdditionalLauncher {
Path customMainLauncherIcon = cmd.getArgumentValue("--icon",
() -> iconInResourceDir(cmd, null), Path::of);
if (customMainLauncherIcon != null) {
withLinuxDesktopFile = true;
withLinuxDesktopFile = Boolean.FALSE != withShortcut;
verifier.setExpectedIcon(customMainLauncherIcon);
break;
}
@ -197,8 +215,8 @@ public final class AdditionalLauncher {
if (TKit.isLinux() && !cmd.isImagePackageType()) {
if (effectiveIcon != NO_ICON && !withLinuxDesktopFile) {
withLinuxDesktopFile = Stream.of("--linux-shortcut").anyMatch(
cmd::hasArgument);
withLinuxDesktopFile = (Boolean.FALSE != withShortcut) &&
Stream.of("--linux-shortcut").anyMatch(cmd::hasArgument);
verifier.setExpectedDefaultIcon();
}
Path desktopFile = LinuxHelper.getDesktopFile(cmd, name);
@ -212,8 +230,21 @@ public final class AdditionalLauncher {
verifier.applyTo(cmd);
}
private void verifyShortcuts(JPackageCommand cmd) throws IOException {
if (TKit.isLinux() && !cmd.isImagePackageType()
&& withShortcut != null) {
Path desktopFile = LinuxHelper.getDesktopFile(cmd, name);
if (withShortcut) {
TKit.assertFileExists(desktopFile);
} else {
TKit.assertPathExists(desktopFile, false);
}
}
}
private void verify(JPackageCommand cmd) throws IOException {
verifyIcon(cmd);
verifyShortcuts(cmd);
Path launcherPath = cmd.appLauncherPath(name);
@ -240,6 +271,8 @@ public final class AdditionalLauncher {
private final String name;
private final List<Map.Entry<String, String>> rawProperties;
private BiConsumer<Path, List<Map.Entry<String, String>>> createFileHandler;
private Boolean withMenuShortcut;
private Boolean withShortcut;
private final static Path NO_ICON = Path.of("");
}

View File

@ -104,8 +104,8 @@ public class AppImageFileTest {
"<launcher></launcher>",
"</jpackage-state>");
Assert.assertEquals("Foo", file.getLauncherName());
Assert.assertArrayEquals(new String[0],
file.getAddLauncherNames().toArray(String[]::new));
Assert.assertEquals(0, file.getAddLaunchers().size());
}
@Test
@ -119,7 +119,7 @@ public class AppImageFileTest {
}
@Test
public void testAddLauncherNames() throws IOException {
public void testAddLaunchers() throws IOException {
Map<String, ? super Object> params = new LinkedHashMap<>();
List<Map<String, ? super Object>> launchersAsMap = new ArrayList<>();
@ -136,10 +136,14 @@ public class AppImageFileTest {
params.put("add-launcher", launchersAsMap);
AppImageFile aif = create(params);
List<String> addLauncherNames = aif.getAddLauncherNames();
Assert.assertEquals(2, addLauncherNames.size());
Assert.assertTrue(addLauncherNames.contains("Launcher2Name"));
Assert.assertTrue(addLauncherNames.contains("Launcher3Name"));
List<AppImageFile.LauncherInfo> addLaunchers = aif.getAddLaunchers();
Assert.assertEquals(2, addLaunchers.size());
List<String> names = new ArrayList<String>();
names.add(addLaunchers.get(0).getName());
names.add(addLaunchers.get(1).getName());
Assert.assertTrue(names.contains("Launcher2Name"));
Assert.assertTrue(names.contains("Launcher3Name"));
}
@ -150,7 +154,7 @@ public class AppImageFileTest {
private void assertInvalid(AppImageFile file) {
Assert.assertNull(file.getLauncherName());
Assert.assertNull(file.getAddLauncherNames());
Assert.assertNull(file.getAddLaunchers());
}
private AppImageFile createFromXml(String... xmlData) throws IOException {

View File

@ -0,0 +1,114 @@
/*
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.nio.file.Path;
import java.io.File;
import java.util.Map;
import java.lang.invoke.MethodHandles;
import jdk.jpackage.test.PackageTest;
import jdk.jpackage.test.FileAssociations;
import jdk.jpackage.test.AdditionalLauncher;
import jdk.jpackage.test.TKit;
import jdk.jpackage.test.Annotations.Test;
/**
* Test --add-launcher parameter with shortcuts (platform permitting).
* Output of the test should be AddLShortcutTest*.* installer.
* The output installer should provide the same functionality as the
* default installer (see description of the default installer in
* SimplePackageTest.java) plus install extra application launchers with and
* without various shortcuts to be tested manually.
*/
/*
* @test
* @summary jpackage with --add-launcher
* @key jpackagePlatformPackage
* @library ../helpers
* @build jdk.jpackage.test.*
* @modules jdk.jpackage/jdk.jpackage.internal
* @compile AddLShortcutTest.java
* @run main/othervm/timeout=540 -Xmx512m jdk.jpackage.test.Main
* --jpt-run=AddLShortcutTest
*/
public class AddLShortcutTest {
@Test
public void test() {
// Configure several additional launchers with each combination of
// possible shortcut hints in add-launcher property file.
// default is true so Foo (no property), and Bar (properties set to "true")
// will have shortcuts while other launchers with some properties set
// to "false" will have none.
PackageTest packageTest = new PackageTest().configureHelloApp();
packageTest.addInitializer(cmd -> {
cmd.addArguments("--arguments", "Duke", "--arguments", "is",
"--arguments", "the", "--arguments", "King");
if (TKit.isWindows()) {
cmd.addArguments("--win-shortcut", "--win-menu");
} else if (TKit.isLinux()) {
cmd.addArguments("--linux-shortcut");
}
});
new FileAssociations(
MethodHandles.lookup().lookupClass().getSimpleName()).applyTo(
packageTest);
new AdditionalLauncher("Foo")
.setDefaultArguments("yep!")
.setIcon(GOLDEN_ICON)
.applyTo(packageTest);
new AdditionalLauncher("Bar")
.setDefaultArguments("one", "two", "three")
.setIcon(GOLDEN_ICON)
.setShortcuts(true, true)
.applyTo(packageTest);
new AdditionalLauncher("Launcher3")
.setDefaultArguments()
.setIcon(GOLDEN_ICON)
.setShortcuts(false, false)
.applyTo(packageTest);
new AdditionalLauncher("Launcher4")
.setDefaultArguments()
.setIcon(GOLDEN_ICON)
.setShortcuts(true, false)
.applyTo(packageTest);
new AdditionalLauncher("Launcher5")
.setDefaultArguments()
.setIcon(GOLDEN_ICON)
.setShortcuts(false, true)
.applyTo(packageTest);
packageTest.run();
}
private final static Path GOLDEN_ICON = TKit.TEST_SRC_ROOT.resolve(Path.of(
"resources", "icon" + TKit.ICON_SUFFIX));
}