8269387: jpackage --add-launcher should have option to not create shortcuts for additional launchers
Reviewed-by: asemenyuk, almatvee
This commit is contained in:
parent
746fe5dc68
commit
057992f206
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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(),
|
||||
|
@ -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\
|
||||
|
@ -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\
|
||||
|
@ -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\
|
||||
|
@ -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;
|
||||
|
@ -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("");
|
||||
}
|
||||
|
@ -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 {
|
||||
|
114
test/jdk/tools/jpackage/share/AddLShortcutTest.java
Normal file
114
test/jdk/tools/jpackage/share/AddLShortcutTest.java
Normal 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));
|
||||
}
|
Loading…
Reference in New Issue
Block a user