1
1
/*
2
- * Copyright (c) 2019, 2020 , Oracle and/or its affiliates. All rights reserved.
2
+ * Copyright (c) 2019, 2021 , Oracle and/or its affiliates. All rights reserved.
3
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
4
*
5
5
* This code is free software; you can redistribute it and/or modify it
40
40
import javax .xml .xpath .XPathExpressionException ;
41
41
import javax .xml .xpath .XPathFactory ;
42
42
import org .w3c .dom .Document ;
43
+ import org .w3c .dom .Node ;
43
44
import org .w3c .dom .NodeList ;
45
+ import org .w3c .dom .NamedNodeMap ;
44
46
import org .xml .sax .SAXException ;
45
47
46
48
import static jdk .jpackage .internal .StandardBundlerParam .VERSION ;
47
49
import static jdk .jpackage .internal .StandardBundlerParam .ADD_LAUNCHERS ;
48
50
import static jdk .jpackage .internal .StandardBundlerParam .APP_NAME ;
51
+ import static jdk .jpackage .internal .StandardBundlerParam .SHORTCUT_HINT ;
52
+ import static jdk .jpackage .internal .StandardBundlerParam .MENU_HINT ;
49
53
50
54
public class AppImageFile {
51
55
52
56
// These values will be loaded from AppImage xml file.
53
57
private final String creatorVersion ;
54
58
private final String creatorPlatform ;
55
59
private final String launcherName ;
56
- private final List <String > addLauncherNames ;
60
+ private final List <LauncherInfo > addLauncherInfos ;
57
61
58
62
private static final String FILENAME = ".jpackage.xml" ;
59
63
@@ -66,10 +70,10 @@ private AppImageFile() {
66
70
this (null , null , null , null );
67
71
}
68
72
69
- private AppImageFile (String launcherName , List <String > addLauncherNames ,
73
+ private AppImageFile (String launcherName , List <LauncherInfo > launcherInfos ,
70
74
String creatorVersion , String creatorPlatform ) {
71
75
this .launcherName = launcherName ;
72
- this .addLauncherNames = addLauncherNames ;
76
+ this .addLauncherInfos = launcherInfos ;
73
77
this .creatorVersion = creatorVersion ;
74
78
this .creatorPlatform = creatorPlatform ;
75
79
}
@@ -79,8 +83,8 @@ private AppImageFile(String launcherName, List<String> addLauncherNames,
79
83
* Each item in the list is not null or empty string.
80
84
* Returns empty list for application without additional launchers.
81
85
*/
82
- List <String > getAddLauncherNames () {
83
- return addLauncherNames ;
86
+ List <LauncherInfo > getAddLaunchers () {
87
+ return addLauncherInfos ;
84
88
}
85
89
86
90
/**
@@ -131,7 +135,10 @@ static void save(Path appImageDir, Map<String, Object> params)
131
135
for (int i = 0 ; i < addLaunchers .size (); i ++) {
132
136
Map <String , ? super Object > sl = addLaunchers .get (i );
133
137
xml .writeStartElement ("add-launcher" );
134
- xml .writeCharacters (APP_NAME .fetchFrom (sl ));
138
+ xml .writeAttribute ("name" , APP_NAME .fetchFrom (sl ));
139
+ xml .writeAttribute ("shortcut" ,
140
+ SHORTCUT_HINT .fetchFrom (sl ).toString ());
141
+ xml .writeAttribute ("menu" , MENU_HINT .fetchFrom (sl ).toString ());
135
142
xml .writeEndElement ();
136
143
}
137
144
});
@@ -156,24 +163,31 @@ static AppImageFile load(Path appImageDir) throws IOException {
156
163
return new AppImageFile ();
157
164
}
158
165
159
- List <String > addLaunchers = new ArrayList <>();
166
+ List <LauncherInfo > launcherInfos = new ArrayList <>();
160
167
161
168
String platform = xpathQueryNullable (xPath ,
162
169
"/jpackage-state/@platform" , doc );
163
170
164
171
String version = xpathQueryNullable (xPath ,
165
172
"/jpackage-state/@version" , doc );
166
173
167
- NodeList launcherNameNodes = (NodeList ) xPath .evaluate (
168
- "/jpackage-state/add-launcher/text() " , doc ,
174
+ NodeList launcherNodes = (NodeList ) xPath .evaluate (
175
+ "/jpackage-state/add-launcher" , doc ,
169
176
XPathConstants .NODESET );
170
177
171
- for (int i = 0 ; i != launcherNameNodes .getLength (); i ++) {
172
- addLaunchers .add (launcherNameNodes .item (i ).getNodeValue ());
178
+ for (int i = 0 ; i != launcherNodes .getLength (); i ++) {
179
+ Node item = launcherNodes .item (i );
180
+ String name = getAttribute (item , "name" );
181
+ String shortcut = getAttribute (item , "shortcut" );
182
+ String menu = getAttribute (item , "menu" );
183
+
184
+ launcherInfos .add (new LauncherInfo (name ,
185
+ !("false" .equals (shortcut )),
186
+ !("false" .equals (menu ))));
173
187
}
174
188
175
189
AppImageFile file = new AppImageFile (
176
- mainLauncher , addLaunchers , version , platform );
190
+ mainLauncher , launcherInfos , version , platform );
177
191
if (!file .isValid ()) {
178
192
file = new AppImageFile ();
179
193
}
@@ -184,6 +198,12 @@ static AppImageFile load(Path appImageDir) throws IOException {
184
198
}
185
199
}
186
200
201
+ private static String getAttribute (Node item , String attr ) {
202
+ NamedNodeMap attrs = item .getAttributes ();
203
+ Node attrNode = attrs .getNamedItem (attr );
204
+ return ((attrNode == null ) ? null : attrNode .getNodeValue ());
205
+ }
206
+
187
207
public static Document readXml (Path appImageDir ) throws IOException {
188
208
try {
189
209
Path path = getPathInAppImage (appImageDir );
@@ -202,18 +222,19 @@ public static Document readXml(Path appImageDir) throws IOException {
202
222
}
203
223
204
224
/**
205
- * Returns list of launcher names configured for the application.
206
- * The first item in the returned list is main launcher name .
225
+ * Returns list of LauncherInfo objects configured for the application.
226
+ * The first item in the returned list is main launcher.
207
227
* Following items in the list are names of additional launchers.
208
228
*/
209
- static List <String > getLauncherNames (Path appImageDir ,
229
+ static List <LauncherInfo > getLaunchers (Path appImageDir ,
210
230
Map <String , ? super Object > params ) {
211
- List <String > launchers = new ArrayList <>();
231
+ List <LauncherInfo > launchers = new ArrayList <>();
212
232
try {
213
233
AppImageFile appImageInfo = AppImageFile .load (appImageDir );
214
234
if (appImageInfo != null ) {
215
- launchers .add (appImageInfo .getLauncherName ());
216
- launchers .addAll (appImageInfo .getAddLauncherNames ());
235
+ launchers .add (new LauncherInfo (
236
+ appImageInfo .getLauncherName (), true , true ));
237
+ launchers .addAll (appImageInfo .getAddLaunchers ());
217
238
return launchers ;
218
239
}
219
240
} catch (NoSuchFileException nsfe ) {
@@ -226,10 +247,11 @@ static List<String> getLauncherNames(Path appImageDir,
226
247
"warning.invalid-app-image" ), appImageDir ));
227
248
228
249
}
250
+ // this should never be the case, but maintaining behavior of
251
+ // creating default launchers without AppImageFile present
229
252
230
- launchers .add (APP_NAME .fetchFrom (params ));
231
- ADD_LAUNCHERS .fetchFrom (params ).stream ().map (APP_NAME ::fetchFrom ).forEach (
232
- launchers ::add );
253
+ ADD_LAUNCHERS .fetchFrom (params ).stream ().map (APP_NAME ::fetchFrom ).map (
254
+ name -> new LauncherInfo (name , true , true )).forEach (launchers ::add );
233
255
return launchers ;
234
256
}
235
257
@@ -262,15 +284,37 @@ private static String getPlatform() {
262
284
}
263
285
264
286
private boolean isValid () {
265
- if (launcherName == null || launcherName .length () == 0 ||
266
- addLauncherNames .indexOf ("" ) != -1 ) {
267
- // Some launchers have empty names. This is invalid.
287
+ if (launcherName == null || launcherName .length () == 0 ) {
268
288
return false ;
269
289
}
270
-
271
- // Add more validation.
290
+ for (var launcher : addLauncherInfos ) {
291
+ if ("" .equals (launcher .getName ())) {
292
+ return false ;
293
+ }
294
+ }
272
295
273
296
return true ;
274
297
}
275
298
299
+ static class LauncherInfo {
300
+ private String name ;
301
+ private boolean shortcut ;
302
+ private boolean menu ;
303
+
304
+ public LauncherInfo (String name , boolean shortcut , boolean menu ) {
305
+ this .name = name ;
306
+ this .shortcut = shortcut ;
307
+ this .menu = menu ;
308
+ }
309
+ public String getName () {
310
+ return name ;
311
+ }
312
+ public boolean isShortcut () {
313
+ return shortcut ;
314
+ }
315
+ public boolean isMenu () {
316
+ return menu ;
317
+ }
318
+ }
319
+
276
320
}
0 commit comments