changeset 59844:eca07183e531

8246244: BasicShortcutHintTest shortcut can not be found Reviewed-by: herrick, almatvee
author asemenyuk
date Tue, 16 Jun 2020 16:23:32 -0400
parents 031fac263083
children fcefe78af1f5
files src/jdk.incubator.jpackage/linux/classes/jdk/incubator/jpackage/internal/DesktopIntegration.java test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LinuxHelper.java test/jdk/tools/jpackage/linux/ShortcutHintTest.java
diffstat 3 files changed, 79 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/jdk.incubator.jpackage/linux/classes/jdk/incubator/jpackage/internal/DesktopIntegration.java	Thu Jun 18 11:23:19 2020 +0200
+++ b/src/jdk.incubator.jpackage/linux/classes/jdk/incubator/jpackage/internal/DesktopIntegration.java	Tue Jun 16 16:23:32 2020 -0400
@@ -40,6 +40,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 import javax.imageio.ImageIO;
@@ -250,9 +251,14 @@
         data.put("APPLICATION_ICON",
                 iconFile != null ? iconFile.installPath().toString() : null);
         data.put("DEPLOY_BUNDLE_CATEGORY", MENU_GROUP.fetchFrom(params));
-        data.put("APPLICATION_LAUNCHER",
-                thePackage.installedApplicationLayout().launchersDirectory().resolve(
-                        LinuxAppImageBuilder.getLauncherName(params)).toString());
+
+        String appLauncher = thePackage.installedApplicationLayout().launchersDirectory().resolve(
+                LinuxAppImageBuilder.getLauncherName(params)).toString();
+        if (Pattern.compile("\\s").matcher(appLauncher).find()) {
+            // Path contains whitespace(s). Enclose in double quotes.
+            appLauncher = "\"" + appLauncher + "\"";
+        }
+        data.put("APPLICATION_LAUNCHER", appLauncher);
 
         return data;
     }
--- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LinuxHelper.java	Thu Jun 18 11:23:19 2020 +0200
+++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LinuxHelper.java	Tue Jun 16 16:23:32 2020 -0400
@@ -28,6 +28,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
@@ -332,6 +333,73 @@
                 }
             });
         });
+
+        test.addInstallVerifier(cmd -> {
+            // Verify .desktop files.
+            try (var files = Files.walk(cmd.appLayout().destktopIntegrationDirectory(), 1)) {
+                List<Path> desktopFiles = files
+                        .filter(path -> path.getFileName().toString().endsWith(".desktop"))
+                        .collect(Collectors.toList());
+                if (!integrated) {
+                    TKit.assertStringListEquals(List.of(),
+                            desktopFiles.stream().map(Path::toString).collect(
+                                    Collectors.toList()),
+                            "Check there are no .desktop files in the package");
+                }
+                for (var desktopFile : desktopFiles) {
+                    verifyDesktopFile(cmd, desktopFile);
+                }
+            }
+        });
+    }
+
+    private static void verifyDesktopFile(JPackageCommand cmd, Path desktopFile)
+            throws IOException {
+        TKit.trace(String.format("Check [%s] file BEGIN", desktopFile));
+        List<String> lines = Files.readAllLines(desktopFile);
+        TKit.assertEquals("[Desktop Entry]", lines.get(0), "Check file header");
+
+        Map<String, String> data = lines.stream()
+        .skip(1)
+        .peek(str -> TKit.assertTextStream("=").predicate(String::contains).apply(Stream.of(str)))
+        .map(str -> {
+            String components[] = str.split("=(?=.+)");
+            if (components.length == 1) {
+                return Map.entry(str.substring(0, str.length() - 1), "");
+            }
+            return Map.entry(components[0], components[1]);
+        }).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a, b) -> {
+            TKit.assertUnexpected("Multiple values of the same key");
+            return null;
+        }));
+
+        final Set<String> mandatoryKeys = new HashSet(Set.of("Name", "Comment",
+                "Exec", "Icon", "Terminal", "Type", "Categories"));
+        mandatoryKeys.removeAll(data.keySet());
+        TKit.assertTrue(mandatoryKeys.isEmpty(), String.format(
+                "Check for missing %s keys in the file", mandatoryKeys));
+
+        for (var e : Map.of("Type", "Application", "Terminal", "false").entrySet()) {
+            String key = e.getKey();
+            TKit.assertEquals(e.getValue(), data.get(key), String.format(
+                    "Check value of [%s] key", key));
+        }
+
+        // Verify value of `Exec` property in .desktop files are escaped if required
+        String launcherPath = data.get("Exec");
+        if (Pattern.compile("\\s").matcher(launcherPath).find()) {
+            TKit.assertTrue(launcherPath.startsWith("\"")
+                    && launcherPath.endsWith("\""),
+                    "Check path to the launcher is enclosed in double quotes");
+            launcherPath = launcherPath.substring(1, launcherPath.length() - 1);
+        }
+
+        Stream.of(launcherPath, data.get("Icon"))
+                .map(Path::of)
+                .map(cmd::pathToUnpackedPackageFile)
+                .forEach(TKit::assertFileExists);
+
+        TKit.trace(String.format("Check [%s] file END", desktopFile));
     }
 
     static void initFileAssociationsTestFile(Path testFile) {
--- a/test/jdk/tools/jpackage/linux/ShortcutHintTest.java	Thu Jun 18 11:23:19 2020 +0200
+++ b/test/jdk/tools/jpackage/linux/ShortcutHintTest.java	Tue Jun 16 16:23:32 2020 -0400
@@ -166,6 +166,8 @@
                             "Exec=APPLICATION_LAUNCHER",
                             "Terminal=false",
                             "Type=Application",
+                            "Comment=",
+                            "Icon=APPLICATION_ICON",
                             "Categories=DEPLOY_BUNDLE_CATEGORY",
                             expectedVersionString
                     ));