KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > sync4j > syncclient > spap > installer > SPSInstaller


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

18 package sync4j.syncclient.spap.installer;
19
20 import java.io.*;
21
22 import java.util.Vector JavaDoc;
23 import java.util.Hashtable JavaDoc;
24
25 import sync4j.syncclient.common.FileSystemTools;
26 import sync4j.syncclient.common.StringTools;
27
28 import sync4j.syncclient.sps.common.DataStoreMetadata;
29 import sync4j.syncclient.spap.Asset;
30 import sync4j.syncclient.spap.Application;
31 import sync4j.syncclient.spap.ApplicationManager;
32 import sync4j.syncclient.spap.ApplicationManagementException;
33 import sync4j.syncclient.spap.AssetManagementException;
34 import sync4j.syncclient.spap.AssetInstallationException;
35 import sync4j.syncclient.spap.installer.InstallationContext;
36 import sync4j.syncclient.spdm.ManagementNode;
37 import sync4j.syncclient.spdm.SimpleDeviceManager;
38 import sync4j.syncclient.spdm.DMException;
39
40
41 /**
42  * This is the installer class for SPS applications. It creates the required
43  * DM structure and moves the datastore classes where appropriate.
44  *
45  * @author Stefano Fornari
46  * @version $Id: SPSInstaller.java,v 1.2 2005/01/19 11:18:36 fabius Exp $
47  */

48 public class SPSInstaller {
49
50     private static final String JavaDoc PALMINSTALL = "palminstall.exe";
51     private static final String JavaDoc PPCINSTALL = "ppcinstall.exe";
52     private static final String JavaDoc CONTEXT_APPLICATIONS = "conduit/applications";
53
54     public static int install(InstallationContext ctx)
55     throws AssetManagementException {
56         try {
57             ManagementNode appsNode =
58                 SimpleDeviceManager.getDeviceManager().getManagementTree(CONTEXT_APPLICATIONS);
59
60             String JavaDoc adf = null;
61             Application app = null;
62
63             try {
64                 adf = readADF(ctx.getWorkingDirectory());
65             } catch (ApplicationManagementException e) {
66                 //
67
// adf not found!
68
//
69
app = ApplicationManager.applicationFromAsset(ctx.getAsset());
70             }
71
72             if (app == null) {
73                 app = ApplicationManager.applicationFromADF(adf);
74                 app.setAssetId(ctx.getAsset().getId());
75                 saveStoreManagerClass(
76                     ctx.getWorkingDirectory(),
77                     ctx.getLibDirectory()
78                 );
79             }
80
81             registerApplication(appsNode, app);
82
83             installBinaries( ctx.getWorkingDirectory(),
84                              ctx.getBinDirectory() ,
85                              PALMINSTALL ,
86                              ".pdb" );
87             installBinaries( ctx.getWorkingDirectory(),
88                              ctx.getBinDirectory() ,
89                              PALMINSTALL ,
90                              ".prc" );
91             installBinaries( ctx.getWorkingDirectory(),
92                              ctx.getBinDirectory() ,
93                              PPCINSTALL ,
94                              ".cab" );
95         } catch (AssetInstallationException e) {
96             throw e;
97         } catch (AssetManagementException e) {
98             throw e;
99         } catch (Exception JavaDoc e) {
100             throw new AssetManagementException(e.getMessage(), e);
101         }
102
103         return 0;
104     }
105
106     public static int uninstall(InstallationContext ctx)
107     throws AssetManagementException {
108         ManagementNode appsNode =
109                 SimpleDeviceManager.getDeviceManager().getManagementTree(CONTEXT_APPLICATIONS);
110
111         ManagementNode sourceNode = null;
112         ManagementNode[] sources = null;
113
114         Hashtable JavaDoc sourceValues = null;
115
116         String JavaDoc storeManagerPackage = null;
117         String JavaDoc storeManagerPath = null;
118         String JavaDoc storeManager = null;
119         String JavaDoc dirTmp = null;
120
121         String JavaDoc adf = null;
122         Application app = null;
123         try {
124             try {
125                 adf = readADF(ctx.getWorkingDirectory());
126             } catch (ApplicationManagementException e) {
127                 //
128
// adf not found!
129
//
130
app = ApplicationManager.applicationFromAsset(ctx.getAsset());
131             }
132
133             if (app == null) {
134                 app = ApplicationManager.applicationFromADF(adf);
135
136                 deleteStoreManagerClasses(ctx.getWorkingDirectory(), ctx.getLibDirectory());
137             }
138
139             appsNode.removeNode(app.getFixedURI());
140         } catch (Exception JavaDoc e) {
141             throw new AssetManagementException("Error reading configuration information: " + e, e);
142         }
143         return 0;
144     }
145
146     /**
147      * Registers the given application into the Device Managet
148      *
149      * @param appsNode the management node under which applications are
150      * registered
151      * @param app application to register
152      *
153      * @throws DMException in case of error
154      */

155     private static void registerApplication(ManagementNode appsNode, Application app)
156     throws DMException {
157         String JavaDoc value;
158
159         //
160
// Application info first
161
//
162
String JavaDoc uri = app.getFixedURI() + "/application";
163         appsNode.setValue(
164             uri, "applicationDisplayName", app.getDisplayName()
165         );
166         appsNode.setValue(
167             uri, "applicationURI", app.getUri()
168         );
169         value = app.getSupportUrl();
170
171         if (value != null) {
172             appsNode.setValue(uri, "applicationSupportUrl", value);
173         }
174         value = app.getSupportEmail();
175         if (value != null) {
176             appsNode.setValue(uri, "applicationSupportMail", value);
177         }
178
179         appsNode.setValue(
180             uri, "applicationAuthor", app.getAuthor()
181         );
182         appsNode.setValue(
183             uri, "applicationDescription", app.getDescription()
184         );
185         appsNode.setValue(
186             uri, "applicationVersion", app.getVersion()
187         );
188         appsNode.setValue(
189             uri, "assetId", app.getAssetId()
190         );
191         appsNode.setValue(
192             uri, "sync", "true" /* default */
193         );
194
195         String JavaDoc name = new File(app.getUri()).getName();
196
197         //
198
// Data stores now
199
//
200
Vector JavaDoc stores = app.getDataStoresMetadata();
201         DataStoreMetadata md;
202         int l = (stores != null) ? stores.size() : 0;
203
204         // just create the context
205
appsNode.setValue(app.getFixedURI() + "/spds/sources", "", "");
206
207         String JavaDoc node = app.getFixedURI() + "/spds/sources/source";
208         for (int i=0; i<l; ++i) {
209             md = (DataStoreMetadata)stores.elementAt(i);
210             appsNode.setValue(
211                 node + String.valueOf(i + 1), "sourceURI", app.getContentId() + '/' + md.getName()
212             );
213             appsNode.setValue(
214                 node + String.valueOf(i + 1), "creatorId", app.getCreatorId()
215             );
216             appsNode.setValue(
217                 node + String.valueOf(i + 1), "dataStoreType", app.getDataStoreType()
218             );
219             appsNode.setValue(
220                 node + String.valueOf(i + 1), "syncModes", StringTools.join(md.getSyncModes())
221             );
222             appsNode.setValue(
223                 node + String.valueOf(i + 1), "sync", md.getDefaultSync()
224             );
225             appsNode.setValue(
226                 node + String.valueOf(i + 1), "name", md.getDisplayName()
227             );
228             appsNode.setValue(
229                 node + String.valueOf(i + 1), "sourceClass", "sync4j.syncclient.spds.source.SPSSyncSource"
230             );
231             appsNode.setValue(
232                 node + String.valueOf(i + 1), "type", "xml/record"
233             );
234             appsNode.setValue(
235                 node + String.valueOf(i + 1), "storeManager", StringTools.replaceSpecial(name)
236             );
237             appsNode.setValue(
238                 node + String.valueOf(i + 1), "storeManagerPackage", app.getStoreManagerPkg()
239             );
240             appsNode.setValue(
241                 node + String.valueOf(i + 1), "sortDB", String.valueOf(md.isSoftSort())
242             );
243             if (md.getStoreVolume() != null) {
244                 appsNode.setValue(
245                     node + String.valueOf(i + 1), "storeVolume", md.getStoreVolume()
246                 );
247             }
248         }
249     }
250
251     /**
252      * Copy class files from the working directory where the asset has been
253      * extracted to the desrination directory.
254      *
255      * @param workingDirectory the working directory where the asset has been extracted
256      * @param destinationDirectory where to copy the files
257      *
258      **/

259     private static void saveStoreManagerClass(
260         String JavaDoc workingDirectory, String JavaDoc destinationDirectory
261     ) throws IOException {
262         FileOutputStream out = null;
263         FileInputStream in = null;
264
265         int l = workingDirectory.length();
266
267         try{
268             String JavaDoc[] classes = FileSystemTools.getAllFiles(workingDirectory, ".class");
269
270             File source, dest;
271             byte[] buf;
272             for (int i=0; i<classes.length; ++i) {
273                 source = new File(classes[i]);
274                 dest = new File(destinationDirectory, classes[i].substring(l));
275
276                 dest.getParentFile().mkdirs();
277
278
279                 buf = new byte[(int)source.length()];
280
281                 in = new FileInputStream(source);
282                 in.read(buf);
283                 in.close(); in = null;
284
285                 out = new FileOutputStream(dest);
286                 out.write(buf);
287                 out.close(); out = null;
288             }
289         } finally {
290             if (in != null) {
291                 in.close();
292             }
293             if (out != null) {
294                 out.close();
295             }
296         }
297     }
298
299     /**
300      * Deletes the classes part of the installed package from the binary directory.
301      *
302      * @param workingDirectory the working directory
303      *
304      * @throws IOException in case of errors
305      */

306      private static void deleteStoreManagerClasses(String JavaDoc workingDirectory,
307                                                    String JavaDoc destinationDirectory)
308      throws IOException {
309          int l = workingDirectory.length();
310
311          String JavaDoc[] classes = FileSystemTools.getAllFiles(workingDirectory, ".class");
312
313          File f, p;
314          String JavaDoc[] children;
315          for (int i=0; i<classes.length; ++i) {
316              f = new File(destinationDirectory, classes[i].substring(l));
317              p = new File(f.getParent());
318
319              f.delete();
320
321              //
322
// If the directory remains empty, remove it and its empty parents
323
//
324
do {
325                  children = p.list();
326
327                  if ((children != null) && (children.length == 0)) {
328                      p.delete();
329                      p = new File(p.getParent());
330                  }
331              } while ((children != null) && (children.length == 0));
332          }
333      }
334
335     /**
336      * Reads the Application Description File from the working directory
337      *
338      * @param workingDirectory the working directory
339      *
340      * @return the content of the ADF file as a String
341      */

342     private static String JavaDoc readADF(String JavaDoc workingDirectory)
343     throws ApplicationManagementException {
344         try {
345             String JavaDoc[] files = new File(workingDirectory).list();
346
347             for (int i=0; i<files.length; ++i) {
348                 if (files[i].toLowerCase().endsWith(".adf")) {
349                     return new String JavaDoc(
350                         FileSystemTools.getFile(workingDirectory + File.separator + files[i])
351                     );
352                 }
353             }
354         } catch (IOException e) {
355             throw new ApplicationManagementException(
356                 "Error reading the adf file in " + new File(workingDirectory).getAbsolutePath() + ": " + e, e
357             );
358         }
359
360         throw new ApplicationManagementException(
361             "No Application Definition File (.adf) found in " + new File(workingDirectory).getAbsolutePath()
362         );
363     }
364
365     /**
366      * Executes the binaries installation external program
367      *
368      * @param workingDirectory the working directory
369      * @param binDirectory the directory where the install program resides
370      * @param installProgram the install program to use
371      * @param fileType file type that the given install program has to process
372      *
373      * @throws AssetManagementException in case of errors
374      */

375     private static void installBinaries(String JavaDoc workingDirectory,
376                                         String JavaDoc binDirectory ,
377                                         String JavaDoc installProgram ,
378                                         String JavaDoc fileType )
379     throws AssetManagementException {
380         StringBuffer JavaDoc output = new StringBuffer JavaDoc();
381         int c;
382
383         if (!fileType.startsWith(".")) {
384             fileType = "." + fileType;
385         }
386
387         try {
388             String JavaDoc cmd = binDirectory + File.separator + installProgram + " ";
389
390             String JavaDoc[] files = new File(workingDirectory).list();
391             if (files == null) {
392                 return;
393             }
394
395             //
396
// Processes all the files in the working directory; the onse that
397
// are of te specified types are passed to the external installation
398
// program.
399
//
400
for (int i=0; i<files.length; ++i) {
401
402                 if (!(files[i].toLowerCase().endsWith(fileType.toLowerCase()))) {
403                     continue;
404                 }
405
406                 if (PALMINSTALL.equals(installProgram)) {
407                     cmd += (' ' + files[i]);
408                 } else if (PPCINSTALL.equals(installProgram)) {
409                     cmd += (" \"" + files[i] + "\"");
410                 }
411
412                 Process JavaDoc proc = Runtime.getRuntime().exec(
413                     cmd,
414                     null,
415                     new File(workingDirectory)
416                 );
417
418                 InputStream is = proc.getErrorStream();
419
420                 while((c = is.read()) != -1) {
421                     output.append((char)c);
422                 }
423
424                 if (PALMINSTALL.equals(installProgram)) {
425                     proc.waitFor();
426                 }
427
428                 if (proc.exitValue() != 0) {
429                     throw new AssetInstallationException( "Error executing "
430                                                         + cmd
431                                                         + ": "
432                                                         + output.toString()
433                                                         );
434                 }
435             }
436         } catch (AssetManagementException e) {
437             throw e;
438         } catch (Exception JavaDoc e) {
439             throw new AssetManagementException(
440                 "Error executing the PRC/PDB installation: " + e, e
441             );
442         }
443     }
444 }
Popular Tags