20 * or visit www.oracle.com if you need additional information or have any |
20 * or visit www.oracle.com if you need additional information or have any |
21 * questions. |
21 * questions. |
22 */ |
22 */ |
23 package jdk.jpackage.test; |
23 package jdk.jpackage.test; |
24 |
24 |
|
25 import java.io.ByteArrayInputStream; |
|
26 import java.io.IOException; |
|
27 import java.nio.charset.StandardCharsets; |
|
28 import java.nio.file.Files; |
25 import java.nio.file.Path; |
29 import java.nio.file.Path; |
|
30 import java.util.List; |
26 import java.util.Set; |
31 import java.util.Set; |
|
32 import java.util.stream.Collectors; |
|
33 import java.util.stream.Stream; |
|
34 import javax.xml.parsers.DocumentBuilder; |
|
35 import javax.xml.parsers.DocumentBuilderFactory; |
|
36 import javax.xml.parsers.ParserConfigurationException; |
|
37 import javax.xml.xpath.XPath; |
|
38 import javax.xml.xpath.XPathConstants; |
|
39 import javax.xml.xpath.XPathFactory; |
|
40 import jdk.jpackage.test.Functional.ThrowingConsumer; |
|
41 import jdk.jpackage.test.Functional.ThrowingSupplier; |
|
42 import org.xml.sax.SAXException; |
27 |
43 |
28 public class MacHelper { |
44 public class MacHelper { |
|
45 |
|
46 public static void withExplodedDmg(JPackageCommand cmd, |
|
47 ThrowingConsumer<Path> consumer) { |
|
48 cmd.verifyIsOfType(PackageType.MAC_DMG); |
|
49 |
|
50 var plist = readPList(new Executor() |
|
51 .setExecutable("/usr/bin/hdiutil") |
|
52 .dumpOutput() |
|
53 .addArguments("attach", cmd.outputBundle().toString(), "-plist") |
|
54 .executeAndGetOutput()); |
|
55 |
|
56 final Path mountPoint = Path.of(plist.queryValue("mount-point")); |
|
57 try { |
|
58 Path dmgImage = mountPoint.resolve(cmd.name() + ".app"); |
|
59 TKit.trace(String.format("Exploded [%s] in [%s] directory", |
|
60 cmd.outputBundle(), dmgImage)); |
|
61 ThrowingConsumer.toConsumer(consumer).accept(dmgImage); |
|
62 } finally { |
|
63 new Executor() |
|
64 .setExecutable("/usr/bin/hdiutil") |
|
65 .addArgument("detach").addArgument(mountPoint) |
|
66 .execute().assertExitCodeIsZero(); |
|
67 } |
|
68 } |
|
69 |
|
70 public static PListWrapper readPListFromAppImage(Path appImage) { |
|
71 return readPList(appImage.resolve("Contents/Info.plist")); |
|
72 } |
|
73 |
|
74 public static PListWrapper readPList(Path path) { |
|
75 TKit.assertReadableFileExists(path); |
|
76 return ThrowingSupplier.toSupplier(() -> readPList(Files.readAllLines( |
|
77 path))).get(); |
|
78 } |
|
79 |
|
80 public static PListWrapper readPList(List<String> lines) { |
|
81 return readPList(lines.stream()); |
|
82 } |
|
83 |
|
84 public static PListWrapper readPList(Stream<String> lines) { |
|
85 return ThrowingSupplier.toSupplier(() -> new PListWrapper(lines.collect( |
|
86 Collectors.joining()))).get(); |
|
87 } |
29 |
88 |
30 static String getBundleName(JPackageCommand cmd) { |
89 static String getBundleName(JPackageCommand cmd) { |
31 cmd.verifyIsOfType(PackageType.MAC); |
90 cmd.verifyIsOfType(PackageType.MAC); |
32 return String.format("%s-%s%s", getPackageName(cmd), cmd.version(), |
91 return String.format("%s-%s%s", getPackageName(cmd), cmd.version(), |
33 cmd.packageType().getSuffix()); |
92 cmd.packageType().getSuffix()); |
43 private static String getPackageName(JPackageCommand cmd) { |
102 private static String getPackageName(JPackageCommand cmd) { |
44 return cmd.getArgumentValue("--mac-package-name", |
103 return cmd.getArgumentValue("--mac-package-name", |
45 () -> cmd.name()); |
104 () -> cmd.name()); |
46 } |
105 } |
47 |
106 |
|
107 public static final class PListWrapper { |
|
108 public String queryValue(String keyName) { |
|
109 XPath xPath = XPathFactory.newInstance().newXPath(); |
|
110 // Query for the value of <string> element preceding <key> element |
|
111 // with value equal to `keyName` |
|
112 String query = String.format( |
|
113 "//string[preceding-sibling::key = \"%s\"][1]", keyName); |
|
114 return ThrowingSupplier.toSupplier(() -> (String) xPath.evaluate( |
|
115 query, doc, XPathConstants.STRING)).get(); |
|
116 } |
|
117 |
|
118 PListWrapper(String xml) throws ParserConfigurationException, |
|
119 SAXException, IOException { |
|
120 doc = createDocumentBuilder().parse(new ByteArrayInputStream( |
|
121 xml.getBytes(StandardCharsets.UTF_8))); |
|
122 } |
|
123 |
|
124 private static DocumentBuilder createDocumentBuilder() throws |
|
125 ParserConfigurationException { |
|
126 DocumentBuilderFactory dbf = DocumentBuilderFactory.newDefaultInstance(); |
|
127 dbf.setFeature( |
|
128 "http://apache.org/xml/features/nonvalidating/load-external-dtd", |
|
129 false); |
|
130 return dbf.newDocumentBuilder(); |
|
131 } |
|
132 |
|
133 private final org.w3c.dom.Document doc; |
|
134 } |
|
135 |
48 static final Set<Path> CRITICAL_RUNTIME_FILES = Set.of(Path.of( |
136 static final Set<Path> CRITICAL_RUNTIME_FILES = Set.of(Path.of( |
49 "Contents/Home/lib/server/libjvm.dylib")); |
137 "Contents/Home/lib/server/libjvm.dylib")); |
50 |
138 |
51 } |
139 } |