KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sourceforge > jarbundler > PropertyListWriter


1 /*
2  * Write the application bundle file: Info.plist
3  *
4  * Copyright (c) 2006, William A. Gilbert <gilbert@informagen.com> All rights reserved.
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by the Free
8  * Software Foundation; either version 2 of the License, or (at your option)
9  * any later version.
10  *
11  * This program is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14  * more details.
15  *
16  * You should have received a copy of the GNU General Public License along with
17  * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
18  * Place - Suite 330, Boston, MA 02111-1307, USA.
19  */

20
21 package net.sourceforge.jarbundler;
22
23 // This package's imports
24
import net.sourceforge.jarbundler.AppBundleProperties;
25
26 // Java I/O
27
import java.io.BufferedWriter JavaDoc;
28 import java.io.File JavaDoc;
29 import java.io.FileOutputStream JavaDoc;
30 import java.io.IOException JavaDoc;
31 import java.io.OutputStreamWriter JavaDoc;
32 import java.io.Writer JavaDoc;
33
34 // Java Utility
35
import java.util.Hashtable JavaDoc;
36 import java.util.Iterator JavaDoc;
37 import java.util.List JavaDoc;
38
39 // Java language imports
40
import java.lang.Boolean JavaDoc;
41 import java.lang.ClassCastException JavaDoc;
42 import java.lang.Double JavaDoc;
43 import java.lang.String JavaDoc;
44 import java.lang.System JavaDoc;
45
46 // Apache Ant
47
import org.apache.tools.ant.BuildException;
48 import org.apache.tools.ant.util.FileUtils;
49
50 // Java XML DOM creation
51
import javax.xml.parsers.DocumentBuilderFactory JavaDoc;
52 import javax.xml.parsers.DocumentBuilder JavaDoc;
53 import javax.xml.parsers.ParserConfigurationException JavaDoc;
54
55 // W3C DOM
56
import org.w3c.dom.Document JavaDoc;
57 import org.w3c.dom.DOMImplementation JavaDoc;
58 import org.w3c.dom.Node JavaDoc;
59 import org.w3c.dom.Element JavaDoc;
60 import org.w3c.dom.Attr JavaDoc;
61
62
63 // Xerces serializer
64
import org.apache.xml.serialize.OutputFormat;
65 import org.apache.xml.serialize.XMLSerializer;
66 import org.apache.xml.serialize.LineSeparator;
67
68
69
70 /**
71  * Write out a Java application bundle property list file. For descriptions of
72  * the property list keys, see <a
73  * HREF="http://developer.apple.com/documentation/MacOSX/Conceptual/BPRuntimeConfig/Articles/PListKeys.html"
74  * >Apple docs</a>.
75  */

76
77
78 public class PropertyListWriter {
79
80
81     // Our application bundle properties
82
private AppBundleProperties bundleProperties;
83
84     private double version = 1.3;
85
86     // DOM version of Info.plist file
87
private Document JavaDoc document = null;
88
89
90     private FileUtils fileUtils = FileUtils.getFileUtils();
91     
92     /**
93      * Create a new Property List writer.
94      */

95     public PropertyListWriter(AppBundleProperties bundleProperties) {
96         this.bundleProperties = bundleProperties;
97         setJavaVersion(bundleProperties.getJVMVersion());
98     }
99
100     private void setJavaVersion(String JavaDoc version) {
101
102         if (version == null)
103             return;
104
105         this.version = Double.valueOf(version.substring(0, 3)).doubleValue();
106     }
107
108
109     public void writeFile(File JavaDoc fileName) throws BuildException {
110
111         Writer JavaDoc writer = null;
112
113         try {
114
115             this.document = createDOM();
116             buildDOM();
117
118             // Serialize the DOM into the writer
119
writer = new BufferedWriter JavaDoc(new OutputStreamWriter JavaDoc(
120                                         new FileOutputStream JavaDoc(fileName), "UTF-8"));
121             // Prettify the XML Two space indenting, no line wrapping
122
OutputFormat outputFormat = new OutputFormat();
123             outputFormat.setMethod("xml");
124             outputFormat.setIndenting(true);
125             outputFormat.setIndent(2);
126             outputFormat.setLineWidth(0);
127             
128             // Create a DOM serlializer and write the XML
129
XMLSerializer serializer = new XMLSerializer(writer, outputFormat);
130             serializer.asDOMSerializer();
131             serializer.serialize(this.document);
132
133         } catch (ParserConfigurationException JavaDoc pce) {
134             throw new BuildException(pce);
135         } catch (IOException JavaDoc ex) {
136             throw new BuildException("Unable to write \"" + fileName + "\"");
137         } finally {
138             fileUtils.close(writer);
139         }
140
141
142     }
143
144     private Document JavaDoc createDOM() throws ParserConfigurationException JavaDoc {
145     
146         DocumentBuilderFactory JavaDoc factory = DocumentBuilderFactory.newInstance();
147         DocumentBuilder JavaDoc documentBuilder = factory.newDocumentBuilder();
148         DOMImplementation JavaDoc domImpl = documentBuilder.getDOMImplementation();
149
150         // We needed to reference using the full class name here because we already have
151
// a class named "DocumentType"
152

153         org.w3c.dom.DocumentType JavaDoc doctype = domImpl.createDocumentType(
154                "plist",
155                "-//Apple Computer//DTD PLIST 1.0//EN",
156                "http://www.apple.com/DTDs/PropertyList-1.0.dtd");
157
158         return domImpl.createDocument(null, "plist", doctype);
159     }
160
161
162     private void buildDOM() {
163
164         Element JavaDoc plist = this.document.getDocumentElement();
165         plist.setAttribute("version","1.0");
166
167         // Open the top level dictionary, <dict>
168

169         Node JavaDoc dict = createNode("dict", plist);
170
171         // Application short name i.e. About menu name
172
writeKeyStringPair("CFBundleName", bundleProperties.getCFBundleName(), dict);
173
174         // Finder 'Version' label, defaults to "1.0"
175
writeKeyStringPair("CFBundleShortVersionString", bundleProperties.getCFBundleShortVersionString(), dict);
176         
177         // Finder 'Get Info'
178
writeKeyStringPair("CFBundleGetInfoString", bundleProperties.getCFBundleGetInfoString(), dict);
179         
180         // Mac OS X required key, defaults to "false"
181
writeKeyStringPair("CFBundleAllowMixedLocalizations",
182              (bundleProperties.getCFBundleAllowMixedLocalizations() ? "true" : "false"),
183              dict);
184
185         // Mac OS X required, defaults to "6.0"
186
writeKeyStringPair("CFBundleInfoDictionaryVersion",
187              bundleProperties.getCFBundleInfoDictionaryVersion(), dict);
188
189         // Bundle Executable name, required, defaults to "JavaApplicationStub"
190
writeKeyStringPair("CFBundleExecutable", bundleProperties.getCFBundleExecutable(), dict);
191
192         // Bundle Development Region, required, defaults to "English"
193
writeKeyStringPair("CFBundleDevelopmentRegion", bundleProperties.getCFBundleDevelopmentRegion(), dict);
194
195         // Bundle Package Type, required, defaults tp "APPL"
196
writeKeyStringPair("CFBundlePackageType", bundleProperties.getCFBundlePackageType(), dict);
197
198         // Bundle Signature, required, defaults tp "????"
199
writeKeyStringPair("CFBundleSignature", bundleProperties.getCFBundleSignature(), dict);
200
201         // Application build number, optional
202
if (bundleProperties.getCFBundleVersion() != null)
203             writeKeyStringPair("CFBundleVersion", bundleProperties.getCFBundleVersion(), dict);
204         
205         // Application Icon file, optional
206
if (bundleProperties.getCFBundleIconFile() != null)
207             writeKeyStringPair("CFBundleIconFile", bundleProperties.getCFBundleIconFile(), dict);
208
209         // Bundle Identifier, optional
210
if (bundleProperties.getCFBundleIdentifier() != null)
211             writeKeyStringPair("CFBundleIdentifier", bundleProperties.getCFBundleIdentifier(), dict);
212
213         // Help Book Folder, optional
214
if (bundleProperties.getCFBundleHelpBookFolder() != null)
215             writeKeyStringPair("CFBundleHelpBookFolder", bundleProperties.getCFBundleHelpBookFolder(), dict);
216
217         // Help Book Name, optional
218
if (bundleProperties.getCFBundleHelpBookName() != null)
219             writeKeyStringPair("CFBundleHelpBookName", bundleProperties.getCFBundleHelpBookName(), dict);
220
221         // Document Types, optional
222
List JavaDoc documentTypes = bundleProperties.getDocumentTypes();
223
224         if (documentTypes.size() > 0)
225             writeDocumentTypes(documentTypes, dict);
226
227         // Java entry in the plist dictionary
228
writeKey("Java", dict);
229         Node JavaDoc javaDict = createNode("dict", dict);
230
231         // Main class, required
232
writeKeyStringPair("MainClass", bundleProperties.getMainClass(), javaDict);
233
234         // Target JVM version, optional but recommended
235
if (bundleProperties.getJVMVersion() != null)
236             writeKeyStringPair("JVMVersion", bundleProperties.getJVMVersion(), javaDict);
237
238
239         // Classpath is composed of two types, required
240
// 1: Jars bundled into the JAVA_ROOT of the application
241
// 2: External directories or files with an absolute path
242

243         List JavaDoc classPath = bundleProperties.getClassPath();
244         List JavaDoc extraClassPath = bundleProperties.getExtraClassPath();
245
246         if ((classPath.size() > 0) || (extraClassPath.size() > 0))
247             writeClasspath(classPath, extraClassPath, javaDict);
248         
249
250         // JVM options, optional
251
if (bundleProperties.getVMOptions() != null)
252             writeKeyStringPair("VMOptions", bundleProperties.getVMOptions(), javaDict);
253
254         // Working directory, optional
255
if (bundleProperties.getWorkingDirectory() != null)
256             writeKeyStringPair("WorkingDirectory", bundleProperties.getWorkingDirectory(), javaDict);
257
258         // Main class arguments, optional
259
if (bundleProperties.getArguments() != null)
260             writeKeyStringPair("Arguments", bundleProperties.getArguments(), javaDict);
261
262         // Java properties, optional
263
Hashtable JavaDoc javaProperties = bundleProperties.getJavaProperties();
264
265         if (javaProperties.isEmpty() == false)
266             writeJavaProperties(javaProperties, javaDict);
267
268
269         // Services, optional
270
List JavaDoc services = bundleProperties.getServices();
271         if (services.size() > 0)
272             writeServices(services,dict);
273         
274     }
275
276
277     private void writeDocumentTypes(List JavaDoc documentTypes, Node JavaDoc appendTo) {
278
279         writeKey("CFBundleDocumentTypes", appendTo);
280         
281         Node JavaDoc array = createNode("array", appendTo);
282
283         Iterator JavaDoc itor = documentTypes.iterator();
284
285         while (itor.hasNext()) {
286
287             DocumentType documentType = (DocumentType) itor.next();
288
289             Node JavaDoc documentDict = createNode("dict", array);
290
291             writeKeyStringPair("CFBundleTypeName", documentType.getName(), documentDict);
292             writeKeyStringPair("CFBundleTypeRole", documentType.getRole(), documentDict);
293
294             File JavaDoc iconFile = documentType.getIconFile();
295
296             if (iconFile != null)
297                 writeKeyStringPair("CFBundleTypeIconFile", iconFile.getName(), documentDict);
298
299
300             List JavaDoc extensions = documentType.getExtensions();
301
302             if (extensions.isEmpty() == false) {
303                 writeKey("CFBundleTypeExtensions", documentDict);
304                 writeArray(extensions, documentDict);
305             }
306
307             List JavaDoc osTypes = documentType.getOSTypes();
308
309             if (osTypes.isEmpty() == false) {
310                 writeKey("CFBundleTypeOSTypes", documentDict);
311                 writeArray(osTypes, documentDict);
312             }
313
314             
315             List JavaDoc mimeTypes = documentType.getMimeTypes();
316
317             if (mimeTypes.isEmpty() == false) {
318                 writeKey("CFBundleTypeMIMETypes", documentDict);
319                 writeArray(mimeTypes, documentDict);
320             }
321
322             // Only write this key if true
323
if (documentType.isBundle())
324                 writeKeyStringPair("LSTypeIsPackage", "true", documentDict);
325         }
326     }
327     
328     private void writeServices(List JavaDoc services, Node JavaDoc appendTo) {
329     
330         writeKey("NSServices",appendTo);
331         Node JavaDoc array = createNode("array",appendTo);
332         Iterator JavaDoc itor = services.iterator();
333         
334         while (itor.hasNext()) {
335             Service service = (Service)itor.next();
336             Node JavaDoc serviceDict = createNode("dict",array);
337
338             String JavaDoc portName = service.getPortName();
339             if (portName == null)
340                 portName = bundleProperties.getCFBundleName();
341             
342             writeKeyStringPair("NSPortName", portName, serviceDict);
343             writeKeyStringPair("NSMessage",service.getMessage(),serviceDict);
344             
345             List JavaDoc sendTypes = service.getSendTypes();
346             if (!sendTypes.isEmpty()) {
347                 writeKey("NSSendTypes",serviceDict);
348                 writeArray(sendTypes,serviceDict);
349             }
350             
351             List JavaDoc returnTypes = service.getReturnTypes();
352             if (!returnTypes.isEmpty()) {
353                 writeKey("NSReturnTypes",serviceDict);
354                 writeArray(returnTypes,serviceDict);
355             }
356             
357             writeKey("NSMenuItem",serviceDict);
358             Node JavaDoc menuItemDict = createNode("dict",serviceDict);
359             writeKeyStringPair("default",service.getMenuItem(),menuItemDict);
360             
361             String JavaDoc keyEquivalent = service.getKeyEquivalent();
362             if (null != keyEquivalent) {
363                 writeKey("NSKeyEquivalent",serviceDict);
364                 Node JavaDoc keyEquivalentDict = createNode("dict",serviceDict);
365                 writeKeyStringPair("default",keyEquivalent,keyEquivalentDict);
366             }
367             
368             String JavaDoc userData = service.getUserData();
369             if (null != userData)
370                 writeKeyStringPair("NSUserData", userData, serviceDict);
371             
372             String JavaDoc timeout = service.getTimeout();
373             if (null != timeout)
374                 writeKeyStringPair("NSTimeout",timeout,serviceDict);
375         }
376     }
377
378     private void writeClasspath(List JavaDoc classpath, List JavaDoc extraClasspath, Node JavaDoc appendTo) {
379         writeKey("ClassPath", appendTo);
380         classpath.addAll(extraClasspath);
381         writeArray(classpath, appendTo);
382     }
383
384
385     private void writeJavaProperties(Hashtable JavaDoc javaProperties, Node JavaDoc appendTo) {
386     
387         writeKey("Properties", appendTo);
388         
389         Node JavaDoc propertiesDict = createNode("dict", appendTo);
390
391         for (Iterator JavaDoc i = javaProperties.keySet().iterator(); i.hasNext();) {
392             String JavaDoc key = (String JavaDoc) i.next();
393
394             if (key.startsWith("com.apple.") && (version >= 1.4)) {
395                 System.out.println("Deprecated as of 1.4: " + key);
396                 continue;
397             }
398
399             writeKeyStringPair(key, (String JavaDoc)javaProperties.get(key), propertiesDict);
400         }
401     }
402
403     private Node JavaDoc createNode(String JavaDoc tag, Node JavaDoc appendTo) {
404         Node JavaDoc node = this.document.createElement(tag);
405         appendTo.appendChild(node);
406         return node;
407     }
408
409
410     private void writeKeyStringPair(String JavaDoc key, String JavaDoc string, Node JavaDoc appendTo) {
411     
412         if (string == null)
413             return;
414     
415         writeKey(key, appendTo);
416         writeString(string, appendTo);
417     }
418
419
420     private void writeKey(String JavaDoc key, Node JavaDoc appendTo) {
421         Element JavaDoc keyNode = this.document.createElement("key");
422         appendTo.appendChild(keyNode);
423         keyNode.appendChild(this.document.createTextNode(key));
424     }
425
426
427     private void writeString(String JavaDoc string, Node JavaDoc appendTo) {
428         Element JavaDoc stringNode = this.document.createElement("string");
429         stringNode.appendChild(this.document.createTextNode(string));
430         appendTo.appendChild(stringNode);
431     }
432
433     private void writeArray(List JavaDoc stringList, Node JavaDoc appendTo) {
434     
435         Node JavaDoc arrayNode = createNode("array", appendTo);
436
437         for (Iterator JavaDoc it = stringList.iterator(); it.hasNext();)
438             writeString((String JavaDoc)it.next(), arrayNode);
439         
440     }
441
442 }
443
Popular Tags