--- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MacHelper.java Wed Oct 16 09:57:23 2019 -0400
+++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MacHelper.java Wed Oct 16 10:32:08 2019 -0400
@@ -22,11 +22,70 @@
*/
package jdk.jpackage.test;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
import java.nio.file.Path;
+import java.util.List;
import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathFactory;
+import jdk.jpackage.test.Functional.ThrowingConsumer;
+import jdk.jpackage.test.Functional.ThrowingSupplier;
+import org.xml.sax.SAXException;
public class MacHelper {
+ public static void withExplodedDmg(JPackageCommand cmd,
+ ThrowingConsumer<Path> consumer) {
+ cmd.verifyIsOfType(PackageType.MAC_DMG);
+
+ var plist = readPList(new Executor()
+ .setExecutable("/usr/bin/hdiutil")
+ .dumpOutput()
+ .addArguments("attach", cmd.outputBundle().toString(), "-plist")
+ .executeAndGetOutput());
+
+ final Path mountPoint = Path.of(plist.queryValue("mount-point"));
+ try {
+ Path dmgImage = mountPoint.resolve(cmd.name() + ".app");
+ TKit.trace(String.format("Exploded [%s] in [%s] directory",
+ cmd.outputBundle(), dmgImage));
+ ThrowingConsumer.toConsumer(consumer).accept(dmgImage);
+ } finally {
+ new Executor()
+ .setExecutable("/usr/bin/hdiutil")
+ .addArgument("detach").addArgument(mountPoint)
+ .execute().assertExitCodeIsZero();
+ }
+ }
+
+ public static PListWrapper readPListFromAppImage(Path appImage) {
+ return readPList(appImage.resolve("Contents/Info.plist"));
+ }
+
+ public static PListWrapper readPList(Path path) {
+ TKit.assertReadableFileExists(path);
+ return ThrowingSupplier.toSupplier(() -> readPList(Files.readAllLines(
+ path))).get();
+ }
+
+ public static PListWrapper readPList(List<String> lines) {
+ return readPList(lines.stream());
+ }
+
+ public static PListWrapper readPList(Stream<String> lines) {
+ return ThrowingSupplier.toSupplier(() -> new PListWrapper(lines.collect(
+ Collectors.joining()))).get();
+ }
+
static String getBundleName(JPackageCommand cmd) {
cmd.verifyIsOfType(PackageType.MAC);
return String.format("%s-%s%s", getPackageName(cmd), cmd.version(),
@@ -45,6 +104,35 @@
() -> cmd.name());
}
+ public static final class PListWrapper {
+ public String queryValue(String keyName) {
+ XPath xPath = XPathFactory.newInstance().newXPath();
+ // Query for the value of <string> element preceding <key> element
+ // with value equal to `keyName`
+ String query = String.format(
+ "//string[preceding-sibling::key = \"%s\"][1]", keyName);
+ return ThrowingSupplier.toSupplier(() -> (String) xPath.evaluate(
+ query, doc, XPathConstants.STRING)).get();
+ }
+
+ PListWrapper(String xml) throws ParserConfigurationException,
+ SAXException, IOException {
+ doc = createDocumentBuilder().parse(new ByteArrayInputStream(
+ xml.getBytes(StandardCharsets.UTF_8)));
+ }
+
+ private static DocumentBuilder createDocumentBuilder() throws
+ ParserConfigurationException {
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newDefaultInstance();
+ dbf.setFeature(
+ "http://apache.org/xml/features/nonvalidating/load-external-dtd",
+ false);
+ return dbf.newDocumentBuilder();
+ }
+
+ private final org.w3c.dom.Document doc;
+ }
+
static final Set<Path> CRITICAL_RUNTIME_FILES = Set.of(Path.of(
"Contents/Home/lib/server/libjvm.dylib"));