KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > ui > macbundler > BundleBuilder


1 /*******************************************************************************
2  * Copyright (c) 2000, 2004 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.jdt.internal.ui.macbundler;
12
13 import java.io.*;
14 import java.util.*;
15 import java.util.List JavaDoc;
16
17 import javax.xml.parsers.*;
18 import javax.xml.parsers.DocumentBuilder JavaDoc;
19 import javax.xml.transform.*;
20 import javax.xml.transform.Transformer JavaDoc;
21 import javax.xml.transform.dom.DOMSource JavaDoc;
22 import javax.xml.transform.stream.StreamResult JavaDoc;
23
24 import org.w3c.dom.*;
25 import org.w3c.dom.Document JavaDoc;
26
27 import org.eclipse.core.runtime.IProgressMonitor;
28
29
30 public class BundleBuilder implements BundleAttributes {
31     
32     private List JavaDoc fProcesses= new ArrayList();
33     private BundleDescription fBundleDescription;
34     
35     
36     public void createBundle(BundleDescription bd, IProgressMonitor pm) throws IOException {
37         
38         fBundleDescription= bd;
39         
40         File tmp_dir= new File(bd.get(DESTINATIONDIRECTORY));
41         String JavaDoc app_dir_name= bd.get(APPNAME) + ".app"; //$NON-NLS-1$
42
File app_dir= new File(tmp_dir, app_dir_name);
43         if (app_dir.exists())
44             deleteDir(app_dir);
45         app_dir= createDir(tmp_dir, app_dir_name, false); //$NON-NLS-1$
46

47         File contents_dir= createDir(app_dir, "Contents", false); //$NON-NLS-1$
48
createPkgInfo(contents_dir);
49
50         File macos_dir= createDir(contents_dir, "MacOS", false); //$NON-NLS-1$
51
String JavaDoc launcher_path= bd.get(LAUNCHER);
52         if (launcher_path == null)
53             throw new IOException();
54         String JavaDoc launcher= copyFile(macos_dir, launcher_path, null);
55         
56         File resources_dir= createDir(contents_dir, "Resources", false); //$NON-NLS-1$
57
File java_dir= createDir(resources_dir, "Java", false); //$NON-NLS-1$
58

59         createInfoPList(contents_dir, resources_dir, java_dir, launcher);
60         
61         Iterator iter= fProcesses.iterator();
62         while (iter.hasNext()) {
63             Process JavaDoc p= (Process JavaDoc) iter.next();
64             try {
65                 p.waitFor();
66             } catch (InterruptedException JavaDoc e) {
67                 // silently ignore
68
}
69         }
70     }
71     
72     private void createInfoPList(File contents_dir, File resources_dir, File java_dir, String JavaDoc launcher) throws IOException {
73         
74         File info= new File(contents_dir, "Info.plist"); //$NON-NLS-1$
75
FileOutputStream fos= new FileOutputStream(info);
76         BufferedOutputStream fOutputStream= new BufferedOutputStream(fos);
77         
78         DocumentBuilder JavaDoc docBuilder= null;
79         DocumentBuilderFactory factory= DocumentBuilderFactory.newInstance();
80         factory.setValidating(false);
81         try {
82             docBuilder= factory.newDocumentBuilder();
83         } catch (ParserConfigurationException ex) {
84             System.err.println("createInfoPList: could not get XML builder"); //$NON-NLS-1$
85
}
86         Document JavaDoc doc= docBuilder.newDocument();
87         
88         Element plist= doc.createElement("plist"); //$NON-NLS-1$
89
doc.appendChild(plist);
90         plist.setAttribute("version", "1.0"); //$NON-NLS-1$ //$NON-NLS-2$
91

92         Element dict= doc.createElement("dict"); //$NON-NLS-1$
93
plist.appendChild(dict);
94         
95         pair(dict, "CFBundleExecutable", null, launcher); //$NON-NLS-1$
96
pair(dict, "CFBundleGetInfoString", GETINFO, null); //$NON-NLS-1$
97
pair(dict, "CFBundleInfoDictionaryVersion", null, "6.0"); //$NON-NLS-1$ //$NON-NLS-2$
98

99         String JavaDoc iconName= null;
100         String JavaDoc appName= fBundleDescription.get(APPNAME, null);
101         if (appName != null)
102             iconName= appName + ".icns"; //$NON-NLS-1$
103
String JavaDoc fname= copyFile(resources_dir, fBundleDescription.get(ICONFILE, null), iconName);
104         if (fname != null)
105             pair(dict, "CFBundleIconFile", null, fname); //$NON-NLS-1$
106

107         pair(dict, "CFBundleIdentifier", IDENTIFIER, null); //$NON-NLS-1$
108
pair(dict, "CFBundleName", APPNAME, null); //$NON-NLS-1$
109
pair(dict, "CFBundlePackageType", null, "APPL"); //$NON-NLS-1$ //$NON-NLS-2$
110
pair(dict, "CFBundleShortVersionString", VERSION, null); //$NON-NLS-1$
111
pair(dict, "CFBundleSignature", SIGNATURE, "????"); //$NON-NLS-1$ //$NON-NLS-2$
112
pair(dict, "CFBundleVersion", null, "1.0.1"); //$NON-NLS-1$ //$NON-NLS-2$
113

114         Element jdict= doc.createElement("dict"); //$NON-NLS-1$
115
add(dict, "Java", jdict); //$NON-NLS-1$
116

117         pair(jdict, "JVMVersion", JVMVERSION, null); //$NON-NLS-1$
118
pair(jdict, "MainClass", MAINCLASS, null); //$NON-NLS-1$
119
pair(jdict, "WorkingDirectory", WORKINGDIR, null); //$NON-NLS-1$
120

121         if (fBundleDescription.get(USES_SWT, false))
122             addTrue(jdict, "StartOnMainThread"); //$NON-NLS-1$
123

124         String JavaDoc arguments= fBundleDescription.get(ARGUMENTS, null);
125         if (arguments != null) {
126             Element argArray= doc.createElement("array"); //$NON-NLS-1$
127
add(jdict, "Arguments", argArray); //$NON-NLS-1$
128
StringTokenizer st= new StringTokenizer(arguments);
129             while (st.hasMoreTokens()) {
130                 String JavaDoc arg= st.nextToken();
131                 Element type= doc.createElement("string"); //$NON-NLS-1$
132
argArray.appendChild(type);
133                 type.appendChild(doc.createTextNode(arg));
134             }
135         }
136         
137         pair(jdict, "VMOptions", VMOPTIONS, null); //$NON-NLS-1$
138

139         int[] id= new int[] { 0 };
140         ResourceInfo[] ris= fBundleDescription.getResources(true);
141         if (ris.length > 0) {
142             StringBuffer JavaDoc cp= new StringBuffer JavaDoc();
143             for (int i= 0; i < ris.length; i++) {
144                 ResourceInfo ri= ris[i];
145                 String JavaDoc e= processClasspathEntry(java_dir, ri.fPath, id);
146                 if (cp.length() > 0)
147                     cp.append(':');
148                 cp.append(e);
149             }
150             add(jdict, "ClassPath", cp.toString()); //$NON-NLS-1$
151
}
152
153         ris= fBundleDescription.getResources(false);
154         if (ris.length > 0) {
155             for (int i= 0; i < ris.length; i++) {
156                 ResourceInfo ri= ris[i];
157                 processClasspathEntry(java_dir, ri.fPath, id);
158             }
159         }
160
161         try {
162             // Write the document to the stream
163
Transformer JavaDoc transformer= TransformerFactory.newInstance().newTransformer();
164             transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, "-//Apple Computer//DTD PLIST 1.0//EN"); //$NON-NLS-1$
165
transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, "http://www.apple.com/DTDs/PropertyList-1.0.dtd"); //$NON-NLS-1$
166
transformer.setOutputProperty(OutputKeys.METHOD, "xml"); //$NON-NLS-1$
167
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); //$NON-NLS-1$
168
transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
169
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4"); //$NON-NLS-1$ //$NON-NLS-2$
170
DOMSource JavaDoc source= new DOMSource JavaDoc(doc);
171             StreamResult JavaDoc result= new StreamResult JavaDoc(fOutputStream);
172             transformer.transform(source, result);
173         } catch (TransformerException e) {
174             System.err.println("createInfoPList: could not transform to XML"); //$NON-NLS-1$
175
}
176     }
177     
178     private void add(Element dict, String JavaDoc key, Element value) {
179         Document JavaDoc document= dict.getOwnerDocument();
180         Element k= document.createElement("key"); //$NON-NLS-1$
181
dict.appendChild(k);
182         k.appendChild(document.createTextNode(key));
183         dict.appendChild(value);
184     }
185     
186     private void create(Element parent, String JavaDoc s) {
187         Document JavaDoc document= parent.getOwnerDocument();
188         Element type= document.createElement("string"); //$NON-NLS-1$
189
parent.appendChild(type);
190         type.appendChild(document.createTextNode(s));
191     }
192
193     private void createTrue(Element parent) {
194         Document JavaDoc document= parent.getOwnerDocument();
195         Element type= document.createElement("true"); //$NON-NLS-1$
196
parent.appendChild(type);
197     }
198
199     private void add(Element dict, String JavaDoc key, String JavaDoc value) {
200         Document JavaDoc document= dict.getOwnerDocument();
201         Element k= document.createElement("key"); //$NON-NLS-1$
202
dict.appendChild(k);
203         k.appendChild(document.createTextNode(key));
204         create(dict, value);
205     }
206     
207     private void addTrue(Element dict, String JavaDoc key) {
208         Document JavaDoc document= dict.getOwnerDocument();
209         Element k= document.createElement("key"); //$NON-NLS-1$
210
dict.appendChild(k);
211         k.appendChild(document.createTextNode(key));
212         createTrue(dict);
213     }
214     
215     private void pair(Element dict, String JavaDoc outkey, String JavaDoc inkey, String JavaDoc dflt) {
216         String JavaDoc value= null;
217         if (inkey != null)
218             value= fBundleDescription.get(inkey, dflt);
219         else
220             value= dflt;
221         if (value != null && value.trim().length() > 0) {
222             add(dict, outkey, value);
223         }
224     }
225     
226     private String JavaDoc processClasspathEntry(File java_dir, String JavaDoc name, int[] id_ref) throws IOException {
227         File f= new File(name);
228         if (f.isDirectory()) {
229             int id= id_ref[0]++;
230             String JavaDoc archivename= "jar_" + id + ".jar"; //$NON-NLS-1$ //$NON-NLS-2$
231
File to= new File(java_dir, archivename);
232             zip(name, to.getAbsolutePath());
233             name= archivename;
234         } else {
235             name= copyFile(java_dir, name, null);
236         }
237         return "$JAVAROOT/" + name; //$NON-NLS-1$
238
}
239     
240     private void createPkgInfo(File contents_dir) throws IOException {
241         File pkgInfo= new File(contents_dir, "PkgInfo"); //$NON-NLS-1$
242
FileOutputStream os= new FileOutputStream(pkgInfo);
243         os.write(("APPL" + fBundleDescription.get(SIGNATURE, "????")).getBytes()); //$NON-NLS-1$ //$NON-NLS-2$
244
os.close();
245     }
246         
247     private static void deleteDir(File dir) {
248         File[] files= dir.listFiles();
249         if (files != null) {
250             for (int i= 0; i < files.length; i++)
251                 deleteDir(files[i]);
252         }
253         dir.delete();
254     }
255     
256     private File createDir(File parent_dir, String JavaDoc dir_name, boolean remove) throws IOException {
257         File dir= new File(parent_dir, dir_name);
258         if (dir.exists()) {
259             if (!remove)
260                 return dir;
261             deleteDir(dir);
262         }
263         if (! dir.mkdir())
264             throw new IOException("cannot create dir " + dir_name); //$NON-NLS-1$
265
return dir;
266     }
267     
268     private String JavaDoc copyFile(File todir, String JavaDoc fromPath, String JavaDoc toname) throws IOException {
269         if (toname == null) {
270             int pos= fromPath.lastIndexOf('/');
271             if (pos >= 0)
272                 toname= fromPath.substring(pos+1);
273             else
274                 toname= fromPath;
275         }
276         File to= new File(todir, toname);
277         fProcesses.add(Runtime.getRuntime().exec(new String JavaDoc[] { "/bin/cp", fromPath, to.getAbsolutePath() })); //$NON-NLS-1$
278
return toname;
279     }
280
281     private void zip(String JavaDoc dir, String JavaDoc dest) throws IOException {
282         fProcesses.add(Runtime.getRuntime().exec(new String JavaDoc[] { "/usr/bin/jar", "cf", dest, "-C", dir, "." })); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
283
}
284 }
285
Popular Tags