-
Notifications
You must be signed in to change notification settings - Fork 57
8287971: Throw exception for missing values in .jpackage.xml #9
Changes from 1 commit
daee617
c06af06
2199f4e
d489ee6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -64,20 +64,15 @@ public final class AppImageFile { | |
private final String launcherName; | ||
private final String mainClass; | ||
private final List<LauncherInfo> addLauncherInfos; | ||
private final boolean signed; | ||
private final boolean appStore; | ||
private final String signedStr; | ||
private final String appStoreStr; | ||
|
||
private static final String FILENAME = ".jpackage.xml"; | ||
|
||
private static final Map<Platform, String> PLATFORM_LABELS = Map.of( | ||
Platform.LINUX, "linux", Platform.WINDOWS, "windows", Platform.MAC, | ||
"macOS"); | ||
|
||
|
||
private AppImageFile() { | ||
this(null, null, null, null, null, null, null); | ||
} | ||
|
||
private AppImageFile(String launcherName, String mainClass, | ||
List<LauncherInfo> launcherInfos, String creatorVersion, | ||
String creatorPlatform, String signedStr, String appStoreStr) { | ||
|
@@ -86,8 +81,8 @@ private AppImageFile(String launcherName, String mainClass, | |
this.addLauncherInfos = launcherInfos; | ||
this.creatorVersion = creatorVersion; | ||
this.creatorPlatform = creatorPlatform; | ||
this.signed = "true".equals(signedStr); | ||
this.appStore = "true".equals(appStoreStr); | ||
this.signedStr = signedStr; | ||
this.appStoreStr = appStoreStr; | ||
} | ||
|
||
/** | ||
|
@@ -114,15 +109,11 @@ String getMainClass() { | |
} | ||
|
||
boolean isSigned() { | ||
return signed; | ||
return "true".equals(signedStr); | ||
} | ||
|
||
boolean isAppStore() { | ||
return appStore; | ||
} | ||
|
||
void verifyCompatible() throws ConfigException { | ||
// Just do nothing for now. | ||
return "true".equals(appStoreStr); | ||
} | ||
|
||
/** | ||
|
@@ -189,25 +180,17 @@ static void save(Path appImageDir, Map<String, Object> params) | |
* @return valid info about application image or null | ||
* @throws IOException | ||
*/ | ||
static AppImageFile load(Path appImageDir) throws IOException { | ||
static AppImageFile load(Path appImageDir) { | ||
try { | ||
Document doc = readXml(appImageDir); | ||
|
||
XPath xPath = XPathFactory.newInstance().newXPath(); | ||
|
||
String mainLauncher = xpathQueryNullable(xPath, | ||
"/jpackage-state/main-launcher/text()", doc); | ||
if (mainLauncher == null) { | ||
// No main launcher, this is fatal. | ||
return new AppImageFile(); | ||
} | ||
|
||
String mainClass = xpathQueryNullable(xPath, | ||
"/jpackage-state/main-class/text()", doc); | ||
if (mainClass == null) { | ||
// No main class, this is fatal. | ||
return new AppImageFile(); | ||
} | ||
|
||
List<LauncherInfo> launcherInfos = new ArrayList<>(); | ||
|
||
|
@@ -234,12 +217,19 @@ static AppImageFile load(Path appImageDir) throws IOException { | |
AppImageFile file = new AppImageFile(mainLauncher, mainClass, | ||
launcherInfos, version, platform, signedStr, appStoreStr); | ||
if (!file.isValid()) { | ||
file = new AppImageFile(); | ||
throw new RuntimeException(MessageFormat.format(I18N.getString( | ||
"error.invalid-app-image"), appImageDir)); | ||
} | ||
return file; | ||
} catch (XPathExpressionException ex) { | ||
// This should never happen as XPath expressions should be correct | ||
throw new RuntimeException(ex); | ||
} catch (NoSuchFileException nsfe) { | ||
// non jpackage generated app-image (no app/.jpackage.xml) | ||
throw new RuntimeException(MessageFormat.format(I18N.getString( | ||
"error.foreign-app-image"), appImageDir)); | ||
} catch (IOException ioe) { | ||
throw new RuntimeException(ioe); | ||
} | ||
} | ||
|
||
|
@@ -275,23 +265,11 @@ static List<LauncherInfo> getLaunchers(Path appImageDir, | |
Map<String, Object> params) { | ||
List<LauncherInfo> launchers = new ArrayList<>(); | ||
if (appImageDir != null) { | ||
try { | ||
AppImageFile appImageInfo = AppImageFile.load(appImageDir); | ||
if (appImageInfo != null) { | ||
launchers.add(new LauncherInfo( | ||
appImageInfo.getLauncherName(), params)); | ||
AppImageFile appImageInfo = AppImageFile.load(appImageDir); | ||
launchers.add(new LauncherInfo( | ||
appImageInfo.getLauncherName(), params)); | ||
launchers.addAll(appImageInfo.getAddLaunchers()); | ||
return launchers; | ||
} | ||
} catch (NoSuchFileException nsfe) { | ||
// non jpackage generated app-image (no app/.jpackage.xml) | ||
Log.info(MessageFormat.format(I18N.getString( | ||
"warning.foreign-app-image"), appImageDir)); | ||
} catch (IOException ioe) { | ||
Log.verbose(ioe); | ||
Log.info(MessageFormat.format(I18N.getString( | ||
"warning.invalid-app-image"), appImageDir)); | ||
} | ||
return launchers; | ||
} | ||
|
||
launchers.add(new LauncherInfo(params)); | ||
|
@@ -302,23 +280,11 @@ static List<LauncherInfo> getLaunchers(Path appImageDir, | |
} | ||
|
||
public static String extractAppName(Path appImageDir) { | ||
try { | ||
return AppImageFile.load(appImageDir).getLauncherName(); | ||
} catch (IOException ioe) { | ||
Log.verbose(MessageFormat.format(I18N.getString( | ||
"warning.foreign-app-image"), appImageDir)); | ||
return null; | ||
} | ||
return AppImageFile.load(appImageDir).getLauncherName(); | ||
} | ||
|
||
public static String extractMainClass(Path appImageDir) { | ||
try { | ||
return AppImageFile.load(appImageDir).getMainClass(); | ||
} catch (IOException ioe) { | ||
Log.verbose(MessageFormat.format(I18N.getString( | ||
"warning.foreign-app-image"), appImageDir)); | ||
return null; | ||
} | ||
return AppImageFile.load(appImageDir).getMainClass(); | ||
} | ||
|
||
private static String xpathQueryNullable(XPath xPath, String xpathExpr, | ||
|
@@ -332,29 +298,43 @@ private static String xpathQueryNullable(XPath xPath, String xpathExpr, | |
} | ||
|
||
static String getVersion() { | ||
return "1.0"; | ||
return System.getProperty("java.version"); | ||
} | ||
|
||
static String getPlatform() { | ||
return PLATFORM_LABELS.get(Platform.getPlatform()); | ||
} | ||
|
||
private boolean isValid() { | ||
if (!Objects.equals(getVersion(), creatorVersion)) { | ||
return false; | ||
} | ||
|
||
if (!Objects.equals(getPlatform(), creatorPlatform)) { | ||
return false; | ||
} | ||
|
||
if (launcherName == null || launcherName.length() == 0) { | ||
return false; | ||
} | ||
|
||
if (mainClass == null || mainClass.length() == 0) { | ||
return false; | ||
} | ||
|
||
for (var launcher : addLauncherInfos) { | ||
if ("".equals(launcher.getName())) { | ||
return false; | ||
} | ||
} | ||
|
||
if (!Objects.equals(getVersion(), creatorVersion)) { | ||
if (signedStr == null || | ||
!("true".equals(signedStr) || "false".equals(signedStr))) { | ||
return false; | ||
} | ||
|
||
if (!Objects.equals(getPlatform(), creatorPlatform)) { | ||
if (appStoreStr == null || | ||
!("true".equals(appStoreStr) || "false".equals(appStoreStr))) { | ||
return false; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It makes sense to unfold this function in the ctor as we don't allow empty AppImageFile instances. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -75,8 +75,9 @@ error.blocked.option=jlink-Option [{0}] ist in --jlink-options nicht zul\u00E4ss | |
error.no.name=Name nicht mit --name angegeben. Es kann auch kein Name aus app-image abgeleitet werden | ||
|
||
warning.no.jdk.modules.found=Warnung: Keine JDK-Module gefunden | ||
warning.foreign-app-image=Warnung: app-image-Verzeichnis ({0}) wurde von jpackage nicht generiert. | ||
warning.invalid-app-image=Warnung: .jpackage.xml kann in app-image-Verzeichnis ({0}) nicht geparst werden | ||
|
||
error.foreign-app-image=Error: app-image dir ({0}) not generated by jpackage. Missing .jpackage.xml. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This error message will be misleading in case app image was generated by jpackage and adjusted after. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
error.invalid-app-image=Error: app-image dir ({0}) generated by another jpackage version or malformed .jpackage.xml | ||
|
||
MSG_BundlerFailed=Fehler: Bundler "{1}" ({0}) konnte kein Package generieren | ||
MSG_BundlerConfigException=Bundler {0} aufgrund eines Konfigurationsproblems \u00FCbersprungen: {1} \nEmpfehlung zur Behebung: {2} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -233,6 +233,43 @@ public static void createTextFile(Path filename, Stream<String> lines) { | |
trace("Done"); | ||
} | ||
|
||
public static void createJPackageXMLFile(Path appImageDir, | ||
String mainLauncher, String mainClass) throws IOException { | ||
String version = System.getProperty("java.version"); | ||
String platform = ""; | ||
Path appDir = appImageDir; | ||
if (TKit.isWindows()) { | ||
platform = "windows"; | ||
appDir = Files.createDirectories( | ||
appImageDir.resolve("app")); | ||
} else if (TKit.isLinux()) { | ||
platform = "linux"; | ||
appDir = Files.createDirectories( | ||
appImageDir.resolve("lib").resolve("app")); | ||
} else if (TKit.isOSX()) { | ||
platform = "macOS"; | ||
appDir = Files.createDirectories( | ||
appImageDir.resolve("Contents").resolve("app")); | ||
} | ||
|
||
TKit.createTextFile(appDir.resolve(".jpackage.xml"), List.of( | ||
"<?xml version=\"1.0\" encoding=\"utf-8\"?>", | ||
String.format( | ||
"<jpackage-state platform=\"%s\" version=\"%s\">", | ||
platform, version), | ||
"<app-version>1.0</app-version>", | ||
String.format( | ||
"<main-launcher>%s</main-launcher>", | ||
mainLauncher), | ||
String.format( | ||
"<main-class>%s</main-class>", | ||
mainClass), | ||
"<signed>false</signed>", | ||
"<app-store>false</app-store>", | ||
"</jpackage-state>" | ||
)); | ||
} | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 1 and 2 done. I think you mistaken There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right! My bad, sorry for the confusion. |
||
public static void createPropertiesFile(Path propsFilename, | ||
Collection<Map.Entry<String, String>> props) { | ||
trace(String.format("Create [%s] properties file...", | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the idea of this change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To store string values, so it can be validated to make sure it is true or false only. I changed it back, since I moved validation to ctor.