KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > pde > internal > build > tasks > JNLPGenerator


1 /*******************************************************************************
2  * Copyright (c) 2005, 2007 IBM Corporation and others. All rights reserved.
3  * This program and the accompanying materials are made available under the
4  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
5  * and is available at http://www.eclipse.org/legal/epl-v10.html
6  *
7  * Contributors:
8  * IBM Corporation - initial API and implementation
9  * G&H Softwareentwicklung GmbH - internationalization implementation (bug 150933)
10  * Michael Seele - remove offline-allowed (bug 153403)
11  ******************************************************************************/

12
13 package org.eclipse.pde.internal.build.tasks;
14
15 import java.io.*;
16 import java.util.*;
17 import java.util.zip.ZipEntry JavaDoc;
18 import java.util.zip.ZipFile JavaDoc;
19 import javax.xml.parsers.*;
20 import org.xml.sax.*;
21 import org.xml.sax.helpers.DefaultHandler JavaDoc;
22
23 /**
24  *
25  * @since 3.1
26  */

27 public class JNLPGenerator extends DefaultHandler JavaDoc {
28
29     private SAXParser parser;
30     private File JavaDoc featureRoot;
31
32     private String JavaDoc codebase;
33     private String JavaDoc j2se;
34
35     /**
36      * id = ???
37      * version = jnlp.version
38      * label = information.title
39      * provider-name = information.vendor
40      * image = information.icon
41      * feature.description = information.description
42      * feature.includes = extension
43      * feature.plugin = jar
44      */

45     private final static SAXParserFactory parserFactory = SAXParserFactory.newInstance();
46     private PrintWriter out;
47     private String JavaDoc destination;
48     private String JavaDoc provider;
49     private String JavaDoc label;
50     private String JavaDoc version;
51     private String JavaDoc id;
52     private String JavaDoc description;
53     private boolean resourceWritten = false;
54     private String JavaDoc currentOS = null;
55     private String JavaDoc currentArch = null;
56     private Locale locale = null;
57     private PropertyResourceBundle nlsBundle = null;
58     private boolean generateOfflineAllowed;
59     private Config[] configs;
60
61     /**
62      * For testing purposes only.
63      */

64     public static void main(String JavaDoc[] args) {
65         JNLPGenerator generator = new JNLPGenerator(args[0], args[1], args[2], args[3]);
66         generator.process();
67     }
68
69     /**
70      * Constructs a feature parser.
71      */

72     public JNLPGenerator(String JavaDoc feature, String JavaDoc destination, String JavaDoc codebase, String JavaDoc j2se) {
73         this(feature, destination, codebase, j2se, Locale.getDefault(), true, null);
74     }
75
76     /**
77      * Constructs a feature parser.
78      */

79     public JNLPGenerator(String JavaDoc feature, String JavaDoc destination, String JavaDoc codebase, String JavaDoc j2se, Locale locale, boolean generateOfflineAllowed, String JavaDoc configs) {
80         super();
81         this.featureRoot = new File JavaDoc(feature);
82         this.destination = destination;
83         this.codebase = codebase;
84         this.j2se = j2se;
85         this.locale = locale;
86         this.generateOfflineAllowed = generateOfflineAllowed;
87         try {
88             parserFactory.setNamespaceAware(true);
89             parser = parserFactory.newSAXParser();
90         } catch (ParserConfigurationException e) {
91             System.out.println(e);
92         } catch (SAXException e) {
93             System.out.println(e);
94         }
95         setConfigInfo(configs);
96     }
97
98     /**
99      * Parses the specified url and constructs a feature
100      */

101     public void process() {
102         InputStream in = null;
103         final String JavaDoc FEATURE_XML = "feature.xml"; //$NON-NLS-1$
104

105         try {
106             ZipFile JavaDoc featureArchive = null;
107             InputStream nlsStream = null;
108             if (featureRoot.isFile()) {
109                 featureArchive = new ZipFile JavaDoc(featureRoot);
110                 nlsStream = getNLSStream(featureArchive);
111                 ZipEntry JavaDoc featureXML = featureArchive.getEntry(FEATURE_XML);
112                 in = featureArchive.getInputStream(featureXML);
113             } else {
114                 nlsStream = getNLSStream(this.featureRoot);
115                 in = new BufferedInputStream(new FileInputStream(new File JavaDoc(featureRoot, FEATURE_XML)));
116             }
117             try {
118                 if (nlsStream != null) {
119                     nlsBundle = new PropertyResourceBundle(nlsStream);
120                     nlsStream.close();
121                 }
122             } catch (IOException e) {
123                 // do nothing
124
}
125             try {
126                 parser.parse(new InputSource(in), this);
127                 writeResourceEpilogue();
128                 writeEpilogue();
129             } catch (SAXException e) {
130                 //Ignore the exception
131
} finally {
132                 in.close();
133                 if (out != null)
134                     out.close();
135                 if (featureArchive != null)
136                     featureArchive.close();
137             }
138         } catch (IOException e) {
139             //Ignore the exception
140
}
141     }
142
143     /**
144      * Search for nls properties files and return the stream if files are found.
145      * First try to load the default properties file, then one with the default
146      * locale settings and if nothing matches, return the stream of the first
147      * properties file found.
148      */

149     private InputStream getNLSStream(File JavaDoc root) {
150         String JavaDoc appendix = ".properties"; //$NON-NLS-1$
151
String JavaDoc[] potentials = createNLSPotentials();
152
153         Map validEntries = new HashMap();
154         File JavaDoc[] files = root.listFiles();
155         for (int i = 0; i < files.length; i++) {
156             String JavaDoc filename = files[i].getName();
157             if (filename.endsWith(appendix)) {
158                 validEntries.put(filename, files[i]);
159             }
160         }
161         InputStream stream = null;
162         if (validEntries.size() > 0) {
163             for (int i = 0; i < potentials.length; i++) {
164                 File JavaDoc file = (File JavaDoc) validEntries.get(potentials[i]);
165                 if (file != null) {
166                     try {
167                         stream = new BufferedInputStream(new FileInputStream(file));
168                         break;
169                     } catch (IOException e) {
170                         // do nothing
171
}
172                 }
173             }
174             if (stream == null) {
175                 File JavaDoc file = (File JavaDoc) validEntries.values().iterator().next();
176                 try {
177                     stream = new BufferedInputStream(new FileInputStream(file));
178                 } catch (IOException e) {
179                     // do nothing
180
}
181             }
182         }
183         return stream;
184     }
185
186     /**
187      * Search for nls properties files and return the stream if files are found.
188      * First try to load the default properties file, then one with the default
189      * locale settings and if nothing matches, return the stream of the first
190      * founded properties file.
191      */

192     private InputStream getNLSStream(ZipFile JavaDoc featureArchive) {
193         String JavaDoc appendix = ".properties"; //$NON-NLS-1$
194
String JavaDoc[] potentials = createNLSPotentials();
195
196         Map validEntries = new HashMap();
197         for (Enumeration enumeration = featureArchive.entries(); enumeration.hasMoreElements();) {
198             ZipEntry JavaDoc entry = (ZipEntry JavaDoc) enumeration.nextElement();
199             String JavaDoc entryName = entry.getName();
200             if (entryName.endsWith(appendix)) {
201                 validEntries.put(entryName, entry);
202             }
203         }
204         InputStream stream = null;
205         if (validEntries.size() > 0) {
206             for (int i = 0; i < potentials.length; i++) {
207                 ZipEntry JavaDoc entry = (ZipEntry JavaDoc) validEntries.get(potentials[i]);
208                 if (entry != null) {
209                     try {
210                         stream = featureArchive.getInputStream(entry);
211                         break;
212                     } catch (IOException e) {
213                         // do nothing
214
}
215                 }
216             }
217             if (stream == null) {
218                 ZipEntry JavaDoc entry = (ZipEntry JavaDoc) validEntries.values().iterator().next();
219                 try {
220                     stream = featureArchive.getInputStream(entry);
221                 } catch (IOException e) {
222                     // do nothing
223
}
224             }
225         }
226         return stream;
227     }
228
229     private String JavaDoc[] createNLSPotentials() {
230         String JavaDoc suffix = "feature"; //$NON-NLS-1$
231
String JavaDoc appendix = ".properties"; //$NON-NLS-1$
232

233         String JavaDoc language = locale.getLanguage();
234         String JavaDoc country = locale.getCountry();
235         String JavaDoc variant = locale.getVariant();
236
237         String JavaDoc potential1 = '_' + language + '_' + country + '_' + variant;
238         String JavaDoc potential2 = '_' + language + '_' + country;
239         String JavaDoc potential3 = '_' + language;
240         String JavaDoc potential4 = ""; //$NON-NLS-1$
241

242         String JavaDoc[] potentials = new String JavaDoc[] {potential1, potential2, potential3, potential4};
243         for (int i = 0; i < potentials.length; i++) {
244             potentials[i] = suffix + potentials[i] + appendix;
245         }
246         return potentials;
247     }
248
249     public void startElement(String JavaDoc uri, String JavaDoc localName, String JavaDoc qName, Attributes attributes) throws SAXException {
250         try {
251             if ("feature".equals(localName)) { //$NON-NLS-1$
252
processFeature(attributes);
253             } else if ("includes".equals(localName)) { //$NON-NLS-1$
254
processIncludes(attributes);
255             } else if ("description".equals(localName)) { //$NON-NLS-1$
256
processDescription(attributes);
257             } else if ("plugin".equals(localName)) { //$NON-NLS-1$
258
processPlugin(attributes);
259             }
260         } catch (IOException e) {
261             throw new SAXException(e);
262         }
263     }
264
265     private void processPlugin(Attributes attributes) throws IOException {
266         writePrologue();
267         String JavaDoc pluginId = attributes.getValue("id"); //$NON-NLS-1$
268
String JavaDoc pluginVersion = attributes.getValue("version"); //$NON-NLS-1$
269
String JavaDoc os = attributes.getValue("os"); //$NON-NLS-1$
270
String JavaDoc ws = attributes.getValue("ws"); //$NON-NLS-1$
271
String JavaDoc arch = attributes.getValue("arch"); //$NON-NLS-1$
272
if (isValidEnvironment(os, ws, arch)) {
273             writeResourcePrologue(os, ws, arch);
274             out.println("\t\t<jar HREF=\"plugins/" + pluginId + "_" + pluginVersion + ".jar\"/>"); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
275
}
276     }
277
278     private void writeResourceEpilogue() {
279         if (!resourceWritten)
280             return;
281         out.println("\t</resources>"); //$NON-NLS-1$
282
resourceWritten = false;
283         currentOS = null;
284     }
285
286     private void writeResourcePrologue(String JavaDoc os, String JavaDoc ws, String JavaDoc arch) {
287         if (os == null)
288             os = ws;
289         os = convertOS(os);
290         arch = convertArch(arch);
291         if (resourceWritten && osMatch(os) && archMatch(arch))
292             return;
293         if (resourceWritten)
294             writeResourceEpilogue();
295         out.println("\t<resources" + (os == null ? "" : " os=\"" + os + "\"") + (arch == null ? "" : " arch=\"" + arch + "\"") + ">"); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$//$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$//$NON-NLS-7$ //$NON-NLS-8$
296
resourceWritten = true;
297         currentOS = os;
298         currentArch = arch;
299     }
300
301     private String JavaDoc convertOS(String JavaDoc os) {
302         if (os == null)
303             return null;
304         if ("win32".equalsIgnoreCase(os)) //$NON-NLS-1$
305
return "Windows"; //$NON-NLS-1$
306
if ("macosx".equalsIgnoreCase(os)) //$NON-NLS-1$
307
return "Mac"; //$NON-NLS-1$
308
if ("linux".equalsIgnoreCase(os)) //$NON-NLS-1$
309
return "Linux"; //$NON-NLS-1$
310
if ("solaris".equalsIgnoreCase(os)) //$NON-NLS-1$
311
return "Solaris"; //$NON-NLS-1$
312
if ("hpux".equalsIgnoreCase(os)) //$NON-NLS-1$
313
return "HP-UX"; //$NON-NLS-1$
314
if ("aix".equalsIgnoreCase(os)) //$NON-NLS-1$
315
return "AIX"; //$NON-NLS-1$
316
return os;
317     }
318
319     private boolean osMatch(String JavaDoc os) {
320         if (os == currentOS)
321             return true;
322         if (os == null)
323             return false;
324         return os.equals(currentOS);
325     }
326
327     private String JavaDoc convertArch(String JavaDoc arch) {
328         if (arch == null)
329             return null;
330
331         if ("x86".equals(arch)) //$NON-NLS-1$
332
return "x86"; //$NON-NLS-1$
333

334         if ("PA_RISC".equals(arch)) //$NON-NLS-1$
335
return "PA_RISC"; //$NON-NLS-1$
336

337         if ("ppc".equals(arch)) //$NON-NLS-1$
338
return "ppc"; //$NON-NLS-1$
339

340         if ("sparc".equals(arch)) //$NON-NLS-1$
341
return "sparc"; //$NON-NLS-1$
342

343         if ("x86_64".equals(arch))//$NON-NLS-1$
344
return "x86_64"; //$NON-NLS-1$
345

346         if ("ia64".equals(arch)) //$NON-NLS-1$
347
return "ia64"; //$NON-NLS-1$
348

349         if ("ia64_32".equals(arch)) //$NON-NLS-1$
350
return "ia64_32"; //$NON-NLS-1$
351

352         return arch;
353     }
354
355     private boolean archMatch(String JavaDoc arch) {
356         if (arch == currentOS)
357             return true;
358         if (arch == null)
359             return false;
360         return arch.equals(currentArch);
361     }
362
363     private void processDescription(Attributes attributes) {
364     }
365
366     private void processIncludes(Attributes attributes) throws IOException {
367         writePrologue();
368         String JavaDoc inclusionId = attributes.getValue("id"); //$NON-NLS-1$
369
String JavaDoc inclusionVersion = attributes.getValue("version"); //$NON-NLS-1$
370
String JavaDoc name = attributes.getValue("name"); //$NON-NLS-1$
371
String JavaDoc os = attributes.getValue("os"); //$NON-NLS-1$
372
String JavaDoc ws = attributes.getValue("ws"); //$NON-NLS-1$
373
String JavaDoc arch = attributes.getValue("arch"); //$NON-NLS-1$
374
if (isValidEnvironment(os, ws, arch)) {
375             writeResourcePrologue(os, ws, arch);
376             out.print("\t\t<extension ");//$NON-NLS-1$
377
if (name != null)
378                 out.print("name=\"" + name + "\" "); //$NON-NLS-1$ //$NON-NLS-2$
379
if (inclusionId != null) {
380                 out.print("href=\"features/" + inclusionId); //$NON-NLS-1$
381
if (inclusionVersion != null)
382                     out.print('_' + inclusionVersion);
383                 out.print(".jnlp\" "); //$NON-NLS-1$
384
}
385             out.println("/>"); //$NON-NLS-1$
386
}
387     }
388
389     private void processFeature(Attributes attributes) {
390         id = attributes.getValue("id"); //$NON-NLS-1$
391
version = attributes.getValue("version"); //$NON-NLS-1$
392
label = processNLS(attributes.getValue("label")); //$NON-NLS-1$
393
provider = processNLS(attributes.getValue("provider-name")); //$NON-NLS-1$
394
}
395
396     /**
397      * Search for a human readable string in the feature.properties file(s) if
398      * the given string is a translateable key.
399      *
400      * @param string a translateable key or a normal string(nothing is done)
401      *
402      * @return a translateabled string or the given string if it is not a
403      * translateable key
404      */

405     private String JavaDoc processNLS(String JavaDoc string) {
406         if (string == null)
407             return null;
408         string = string.trim();
409         if (!string.startsWith("%")) { //$NON-NLS-1$
410
return string;
411         }
412         if (string.startsWith("%%")) { //$NON-NLS-1$
413
return string.substring(1);
414         }
415         int index = string.indexOf(" "); //$NON-NLS-1$
416
String JavaDoc key = index == -1 ? string : string.substring(0, index);
417         String JavaDoc dflt = index == -1 ? string : string.substring(index + 1);
418         if (nlsBundle == null) {
419             return dflt;
420         }
421         try {
422             return nlsBundle.getString(key.substring(1));
423         } catch (MissingResourceException e) {
424             return dflt;
425         }
426     }
427
428     private void writePrologue() throws IOException {
429         if (out != null)
430             return;
431         if (destination == null) {
432             featureRoot.getParentFile();
433             destination = featureRoot.getParent() + '/';
434         }
435         if (destination.endsWith("/") || destination.endsWith("\\")) //$NON-NLS-1$ //$NON-NLS-2$
436
destination = new File JavaDoc(featureRoot.getParentFile(), id + "_" + version + ".jnlp").getAbsolutePath(); //$NON-NLS-1$ //$NON-NLS-2$
437
out = new PrintWriter(new BufferedOutputStream(new FileOutputStream(destination)));
438         writePrologue();
439         out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); //$NON-NLS-1$
440
out.print("<jnlp spec=\"1.0+\" "); //$NON-NLS-1$
441
if (codebase != null)
442             out.print("codebase=\"" + codebase); //$NON-NLS-1$
443
out.println("\">"); //$NON-NLS-1$
444
out.println("\t<information>"); //$NON-NLS-1$
445
if (label != null)
446             out.println("\t\t<title>" + label + "</title>"); //$NON-NLS-1$ //$NON-NLS-2$
447
if (provider != null)
448             out.println("\t\t<vendor>" + provider + "</vendor>"); //$NON-NLS-1$ //$NON-NLS-2$
449
if (description != null)
450             out.println("\t\t<description>" + description + "</description>"); //$NON-NLS-1$ //$NON-NLS-2$
451
if (generateOfflineAllowed)
452             out.println("\t\t<offline-allowed/>"); //$NON-NLS-1$
453
out.println("\t</information>"); //$NON-NLS-1$
454
out.println("\t<security>"); //$NON-NLS-1$
455
out.println("\t\t<all-permissions/>"); //$NON-NLS-1$
456
out.println("\t</security>"); //$NON-NLS-1$
457
out.println("\t<component-desc/>"); //$NON-NLS-1$
458
out.println("\t<resources>"); //$NON-NLS-1$
459
out.println("\t\t<j2se version=\"" + j2se + "\" />"); //$NON-NLS-1$ //$NON-NLS-2$
460
out.println("\t</resources>"); //$NON-NLS-1$
461
}
462
463     private void writeEpilogue() {
464         out.println("</jnlp>"); //$NON-NLS-1$
465
}
466
467     private boolean isMatching(String JavaDoc candidateValues, String JavaDoc siteValues) {
468         if (candidateValues == null)
469             return true;
470         if (siteValues == null)
471             return false;
472         if ("*".equals(candidateValues))return true; //$NON-NLS-1$
473
if ("".equals(candidateValues))return true; //$NON-NLS-1$
474
StringTokenizer siteTokens = new StringTokenizer(siteValues, ","); //$NON-NLS-1$
475
//$NON-NLS-1$
476
while (siteTokens.hasMoreTokens()) {
477             StringTokenizer candidateTokens = new StringTokenizer(candidateValues, ","); //$NON-NLS-1$
478
String JavaDoc siteValue = siteTokens.nextToken();
479             while (candidateTokens.hasMoreTokens()) {
480                 if (siteValue.equalsIgnoreCase(candidateTokens.nextToken()))
481                     return true;
482             }
483         }
484         return false;
485     }
486
487     private boolean isValidEnvironment(String JavaDoc os, String JavaDoc ws, String JavaDoc arch) {
488         if (configs.length==0)
489             return true;
490         for (int i = 0; i < configs.length; i++) {
491             if (isMatching(os, configs[i].getOs()) && isMatching(ws, configs[i].getWs()) && isMatching(arch, configs[i].getArch()))
492                 return true;
493         }
494         return false;
495     }
496
497     private void setConfigInfo(String JavaDoc spec) {
498         if (spec != null && spec.startsWith("$")) { //$NON-NLS-1$
499
configs = new Config[0];
500             return;
501         }
502         if (spec == null) {
503             configs = new Config[] {Config.genericConfig()};
504             return;
505         }
506         StringTokenizer tokens = new StringTokenizer(spec, "&"); //$NON-NLS-1$
507
int configNbr = tokens.countTokens();
508         ArrayList configInfos = new ArrayList(configNbr);
509         while (tokens.hasMoreElements()) {
510             String JavaDoc aConfig = tokens.nextToken();
511             StringTokenizer configTokens = new StringTokenizer(aConfig, ","); //$NON-NLS-1$
512
if (configTokens.countTokens() == 3) {
513                 Config toAdd = new Config(configTokens.nextToken().trim(), configTokens.nextToken().trim(), configTokens.nextToken().trim());
514                 if (toAdd.equals(Config.genericConfig()))
515                     toAdd = Config.genericConfig();
516                 configInfos.add(toAdd);
517             }
518         }
519         if (configInfos.size() == 0)
520             configInfos.add(Config.genericConfig());
521         configs = (Config[]) configInfos.toArray(new Config[configInfos.size()]);
522     }
523 }
524
Popular Tags