Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -265,9 +265,29 @@ private void writeEntry(InputStream in, Path dstFile) throws IOException {
@Override
public void prepareApplicationFiles(Map<String, ? super Object> params)
throws IOException {
// If predefine app image is provided, then just sign it and return.
if (PREDEFINED_APP_IMAGE.fetchFrom(params) != null) {
doSigning(params);
// If predefined app image is provided, then just sign it and return.
Path predefinedAppImage = PREDEFINED_APP_IMAGE.fetchFrom(params);
if (predefinedAppImage != null) {
// Mark app image as signed, before we signing it.
AppImageFile appImageFile =
AppImageFile.load(predefinedAppImage);
if (!appImageFile.isSigned()) {
appImageFile.copyAsSigned().save(predefinedAppImage);
} else {
appImageFile = null;
}

try {
doSigning(params);
} catch (Exception ex) {
// Restore original app image file if signing failed
if (appImageFile != null) {
appImageFile.save(predefinedAppImage);
}

throw ex;
}

return;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2022, 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
Expand Down
171 changes: 138 additions & 33 deletions src/jdk.jpackage/share/classes/jdk/jpackage/internal/AppImageFile.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
import java.util.List;
import java.util.Map;
import java.util.Objects;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
Expand All @@ -59,11 +61,12 @@
public final class AppImageFile {

// These values will be loaded from AppImage xml file.
private final String creatorVersion;
private final String creatorPlatform;
private final String appVersion;
private final String launcherName;
private final String mainClass;
private final List<LauncherInfo> addLauncherInfos;
private final String creatorVersion;
private final String creatorPlatform;
private final boolean signed;
private final boolean appStore;

Expand All @@ -73,15 +76,13 @@ public final class AppImageFile {
Platform.LINUX, "linux", Platform.WINDOWS, "windows", Platform.MAC,
"macOS");

private AppImageFile(Path appImageDir, String launcherName, String mainClass,
List<LauncherInfo> launcherInfos, String creatorVersion,
String creatorPlatform, String signedStr, String appStoreStr) {
private AppImageFile(Path appImageDir, String appVersion, String launcherName,
String mainClass, List<LauncherInfo> launcherInfos,
String creatorVersion, String creatorPlatform, String signedStr,
String appStoreStr) {
boolean isValid = true;
if (!Objects.equals(getVersion(), creatorVersion)) {
isValid = false;
}

if (!Objects.equals(getPlatform(), creatorPlatform)) {
if (appVersion == null || appVersion.length() == 0) {
isValid = false;
}

Expand All @@ -99,6 +100,14 @@ private AppImageFile(Path appImageDir, String launcherName, String mainClass,
}
}

if (!Objects.equals(getVersion(), creatorVersion)) {
isValid = false;
}

if (!Objects.equals(getPlatform(), creatorPlatform)) {
isValid = false;
}

if (signedStr == null ||
!("true".equals(signedStr) || "false".equals(signedStr))) {
isValid = false;
Expand All @@ -111,9 +120,11 @@ private AppImageFile(Path appImageDir, String launcherName, String mainClass,

if (!isValid) {
throw new RuntimeException(MessageFormat.format(I18N.getString(
"error.invalid-app-image"), appImageDir));
"error.invalid-app-image"), appImageDir,
AppImageFile.getPathInAppImage(appImageDir)));
}

this.appVersion = appVersion;
this.launcherName = launcherName;
this.mainClass = mainClass;
this.addLauncherInfos = launcherInfos;
Expand All @@ -132,6 +143,13 @@ List<LauncherInfo> getAddLaunchers() {
return addLauncherInfos;
}

/**
* Returns application version. Never returns null or empty value.
*/
String getAppVersion() {
return appVersion;
}

/**
* Returns main application launcher name. Never returns null or empty value.
*/
Expand All @@ -150,7 +168,7 @@ public boolean isSigned() {
return signed;
}

boolean isAppStore() {
public boolean isAppStore() {
return appStore;
}

Expand All @@ -165,53 +183,118 @@ public static Path getPathInAppImage(Path appImageDir) {
.resolve(FILENAME);
}

/**
* Saves file with application image info in application image using values
* from current instance.
* @param appImageDir - path to application image
* @throws IOException
*/
void save(Path appImageDir) throws IOException {
AppImageFile.save(appImageDir, null, this);
}

/**
* Saves file with application image info in application image.
* @param appImageDir - path to application image
* @param params - parameters used to generate application image
* @throws IOException
*/
static void save(Path appImageDir, Map<String, Object> params)
throws IOException {
AppImageFile.save(appImageDir, params, null);
}

/**
* Saves file with application image info in application image using params
* or appImage. Both params or appImage cannot be valid.
* @param appImageDir - path to application image
* @param params - parameters used to generate application image
* @param appImage - instance of already existing application image file
* @throws IOException
* @throws IllegalArgumentException - If both params and appImage are null or
* If both params and appImage are not null
*/
private static void save(Path appImageDir,
Map<String, Object> params,
AppImageFile appImage) throws IOException {
if ((params == null && appImage == null) ||
(params != null && appImage != null)) {
throw new IllegalArgumentException();
}

final String appVersionSave;
final String mainLauncherSave;
final String mainClassSave;
final String signedSave;
final String appStoreSave;
final List<LauncherInfo> addLauncherInfoSave;
if (params != null) {
appVersionSave = VERSION.fetchFrom(params);
mainLauncherSave = APP_NAME.fetchFrom(params);
mainClassSave = MAIN_CLASS.fetchFrom(params);
signedSave = SIGN_BUNDLE.fetchFrom(params).toString();
appStoreSave = APP_STORE.fetchFrom(params).toString();
addLauncherInfoSave = null;
} else {
appVersionSave = appImage.getAppVersion();
mainLauncherSave = appImage.getLauncherName();
mainClassSave = appImage.getMainClass();
signedSave = String.valueOf(appImage.isSigned());
appStoreSave = String.valueOf(appImage.isAppStore());
addLauncherInfoSave = appImage.getAddLaunchers();
}

IOUtils.createXml(getPathInAppImage(appImageDir), xml -> {
xml.writeStartElement("jpackage-state");
xml.writeAttribute("version", getVersion());
xml.writeAttribute("platform", getPlatform());

xml.writeStartElement("app-version");
xml.writeCharacters(VERSION.fetchFrom(params));
xml.writeCharacters(appVersionSave);
xml.writeEndElement();

xml.writeStartElement("main-launcher");
xml.writeCharacters(APP_NAME.fetchFrom(params));
xml.writeCharacters(mainLauncherSave);
xml.writeEndElement();

xml.writeStartElement("main-class");
xml.writeCharacters(MAIN_CLASS.fetchFrom(params));
xml.writeCharacters(mainClassSave);
xml.writeEndElement();

xml.writeStartElement("signed");
xml.writeCharacters(SIGN_BUNDLE.fetchFrom(params).toString());
xml.writeCharacters(signedSave);
xml.writeEndElement();

xml.writeStartElement("app-store");
xml.writeCharacters(APP_STORE.fetchFrom(params).toString());
xml.writeCharacters(appStoreSave);
xml.writeEndElement();

List<Map<String, ? super Object>> addLaunchers =
ADD_LAUNCHERS.fetchFrom(params);

for (var launcherParams : addLaunchers) {
var li = new LauncherInfo(launcherParams);
xml.writeStartElement("add-launcher");
xml.writeAttribute("name", li.getName());
xml.writeAttribute("shortcut", Boolean.toString(li.isShortcut()));
xml.writeAttribute("menu", Boolean.toString(li.isMenu()));
xml.writeAttribute("service", Boolean.toString(li.isService()));
xml.writeEndElement();
if (addLauncherInfoSave != null) {
for (var li : addLauncherInfoSave) {
addLauncherInfo(xml, li);
}
} else {
List<Map<String, ? super Object>> addLaunchers =
ADD_LAUNCHERS.fetchFrom(params);

for (var launcherParams : addLaunchers) {
var li = new LauncherInfo(launcherParams);
addLauncherInfo(xml, li);
}
}
});
}

static void addLauncherInfo(XMLStreamWriter xml, LauncherInfo li)
throws XMLStreamException {
xml.writeStartElement("add-launcher");
xml.writeAttribute("name", li.getName());
xml.writeAttribute("shortcut", Boolean.toString(li.isShortcut()));
xml.writeAttribute("menu", Boolean.toString(li.isMenu()));
xml.writeAttribute("service", Boolean.toString(li.isService()));
xml.writeEndElement();
}

/**
* Loads application image info from application image.
* @param appImageDir - path to application image
Expand All @@ -224,6 +307,9 @@ public static AppImageFile load(Path appImageDir) {

XPath xPath = XPathFactory.newInstance().newXPath();

String appVersion = xpathQueryNullable(xPath,
"/jpackage-state/app-version/text()", doc);

String mainLauncher = xpathQueryNullable(xPath,
"/jpackage-state/main-launcher/text()", doc);

Expand Down Expand Up @@ -252,8 +338,9 @@ public static AppImageFile load(Path appImageDir) {
launcherInfos.add(new LauncherInfo(launcherNodes.item(i)));
}

return new AppImageFile(appImageDir, mainLauncher, mainClass,
launcherInfos, version, platform, signedStr, appStoreStr);
return new AppImageFile(appImageDir, appVersion, mainLauncher,
mainClass, launcherInfos, version, platform, signedStr,
appStoreStr);
} catch (XPathExpressionException ex) {
// This should never happen as XPath expressions should be correct
throw new RuntimeException(ex);
Expand All @@ -266,10 +353,22 @@ public static AppImageFile load(Path appImageDir) {
}
}

private static String getAttribute(Node item, String attr) {
NamedNodeMap attrs = item.getAttributes();
Node attrNode = attrs.getNamedItem(attr);
return ((attrNode == null) ? null : attrNode.getNodeValue());
/**
* Returns copy of AppImageFile, but with signed set to true if AppImageFile
* is not marked as signed. If AppImageFile already signed it will return
* instance to itself.
*/
public AppImageFile copyAsSigned() {
if (isSigned()) {
return this;
}

// Pass null for appImageDir, it is used only to show location of
// .jpackage.xml in case of error. copyAsSigned() should not produce
// invalid app image file.
return new AppImageFile(null, getAppVersion(),
getLauncherName(), getMainClass(), getAddLaunchers(),
getVersion(), getPlatform(), "true", String.valueOf(isAppStore()));
}

public static Document readXml(Path appImageDir) throws IOException {
Expand Down Expand Up @@ -362,6 +461,12 @@ private LauncherInfo(Node node) {
this.service = !"false".equals(getAttribute(node, "service"));
}

private String getAttribute(Node item, String attr) {
NamedNodeMap attrs = item.getAttributes();
Node attrNode = attrs.getNamedItem(attr);
return ((attrNode == null) ? null : attrNode.getNodeValue());
}

public String getName() {
return name;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@ error.no.name=Name not specified with --name and cannot infer one from app-image

warning.no.jdk.modules.found=Warning: No JDK Modules found

error.foreign-app-image=Error: Missing .jpackage.xml file in app-image dir ({0})
error.invalid-app-image=Error: app-image dir ({0}) generated by another jpackage version or malformed .jpackage.xml
error.foreign-app-image=Error: Missing .jpackage.xml file in app-image dir "{0}"
error.invalid-app-image=Error: app-image dir "{0}" generated by another jpackage version or malformed "{1}"

MSG_BundlerFailed=Error: Bundler "{1}" ({0}) failed to produce a package
MSG_BundlerConfigException=Bundler {0} skipped because of a configuration problem: {1} \n\
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ error.no.name=Name nicht mit --name angegeben. Es kann auch kein Name aus app-im

warning.no.jdk.modules.found=Warnung: Keine JDK-Module gefunden

error.foreign-app-image=Error: Missing .jpackage.xml file in app-image dir ({0})
error.invalid-app-image=Error: app-image dir ({0}) generated by another jpackage version or malformed .jpackage.xml
error.foreign-app-image=Error: Missing .jpackage.xml file in app-image dir "{0}"
error.invalid-app-image=Error: app-image dir "{0}" generated by another jpackage version or malformed "{1}"

MSG_BundlerFailed=Fehler: Bundler "{1}" ({0}) konnte kein Package generieren
MSG_BundlerConfigException=Bundler {0} aufgrund eines Konfigurationsproblems \u00FCbersprungen: {1} \nEmpfehlung zur Behebung: {2}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ error.no.name=\u540D\u524D\u304C--name\u3067\u6307\u5B9A\u3055\u308C\u3066\u304A

warning.no.jdk.modules.found=\u8B66\u544A: JDK\u30E2\u30B8\u30E5\u30FC\u30EB\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093

error.foreign-app-image=Error: Missing .jpackage.xml file in app-image dir ({0})
error.invalid-app-image=Error: app-image dir ({0}) generated by another jpackage version or malformed .jpackage.xml
error.foreign-app-image=Error: Missing .jpackage.xml file in app-image dir "{0}"
error.invalid-app-image=Error: app-image dir "{0}" generated by another jpackage version or malformed "{1}"

MSG_BundlerFailed=\u30A8\u30E9\u30FC: \u30D0\u30F3\u30C9\u30E9"{1}" ({0})\u304C\u30D1\u30C3\u30B1\u30FC\u30B8\u306E\u751F\u6210\u306B\u5931\u6557\u3057\u307E\u3057\u305F
MSG_BundlerConfigException=\u69CB\u6210\u306E\u554F\u984C\u306E\u305F\u3081\u3001\u30D0\u30F3\u30C9\u30E9{0}\u304C\u30B9\u30AD\u30C3\u30D7\u3055\u308C\u307E\u3057\u305F: {1} \n\u6B21\u306E\u4FEE\u6B63\u3092\u884C\u3063\u3066\u304F\u3060\u3055\u3044: {2}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ error.no.name=\u672A\u4F7F\u7528 --name \u6307\u5B9A\u540D\u79F0\uFF0C\u65E0\u6C

warning.no.jdk.modules.found=\u8B66\u544A: \u672A\u627E\u5230 JDK \u6A21\u5757

error.foreign-app-image=Error: Missing .jpackage.xml file in app-image dir ({0})
error.invalid-app-image=Error: app-image dir ({0}) generated by another jpackage version or malformed .jpackage.xml
error.foreign-app-image=Error: Missing .jpackage.xml file in app-image dir "{0}"
error.invalid-app-image=Error: app-image dir "{0}" generated by another jpackage version or malformed "{1}"

MSG_BundlerFailed=\u9519\u8BEF\uFF1A\u6253\u5305\u7A0B\u5E8F "{1}" ({0}) \u65E0\u6CD5\u751F\u6210\u7A0B\u5E8F\u5305
MSG_BundlerConfigException=\u7531\u4E8E\u914D\u7F6E\u95EE\u9898, \u8DF3\u8FC7\u4E86\u6253\u5305\u7A0B\u5E8F{0}: {1} \n\u4FEE\u590D\u5EFA\u8BAE: {2}
Expand Down
Loading