KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sslexplorer > agent > client > util > AbstractApplicationLauncher


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

19             
20 package com.sslexplorer.agent.client.util;
21
22 import java.io.File JavaDoc;
23 import java.io.FileInputStream JavaDoc;
24 import java.io.FileOutputStream JavaDoc;
25 import java.io.IOException JavaDoc;
26 import java.io.InputStream JavaDoc;
27 import java.io.InputStreamReader JavaDoc;
28 import java.io.StringReader JavaDoc;
29 import java.lang.reflect.Method JavaDoc;
30 import java.net.URL JavaDoc;
31 import java.net.URLConnection JavaDoc;
32 import java.text.MessageFormat JavaDoc;
33 import java.util.Enumeration JavaDoc;
34 import java.util.Hashtable JavaDoc;
35 import java.util.Vector JavaDoc;
36 import java.util.zip.Adler32 JavaDoc;
37 import java.util.zip.CheckedInputStream JavaDoc;
38
39 import com.sslexplorer.agent.client.util.types.DefaultAgentApplicationType;
40 import com.sslexplorer.agent.client.util.types.ExecutableApplicationType;
41 import com.sslexplorer.agent.client.util.types.HtmlApplicationType;
42 import com.sslexplorer.agent.client.util.types.JavaApplicationType;
43
44 /**
45  * Launches an application shortcut by downloading the extension descriptor for
46  * the appropriate application extension, processing it then launching the
47  * application.
48  * <p>
49  * During processing of the descriptor, additional files may be download and
50  * cached on the client.
51  * <p>
52  * How the application is launched depends on its type. Types include
53  * {@link JavaApplicationType}, {@link DefaultAgentApplicationType},
54  * {@link HtmlApplicationType}, {@link ExecutableApplicationType}.
55  *
56  * @author Brett Smith <a HREF="mailto: brett@3sp.com">&lt;brett@3sp.com&gt;</a>
57  */

58 public abstract class AbstractApplicationLauncher {
59
60     static Vector JavaDoc EMPTY_VECTOR = new Vector JavaDoc();
61     File JavaDoc installDir;
62     File JavaDoc sharedDir;
63     String JavaDoc typeName;
64
65     String JavaDoc name;
66     String JavaDoc ticket;
67
68     // Protected instance variables
69

70     protected String JavaDoc applicationStoreProtocol;
71     protected String JavaDoc applicationStoreHost;
72     protected String JavaDoc applicationStoreUser;
73     protected int applicationStorePort;
74     protected ApplicationLauncherEvents events;
75     protected Hashtable JavaDoc parameters;
76     
77     // Privaet instance variables
78

79     private long totalBytesToDownload = 0;
80     private Vector JavaDoc filesToDownload = new Vector JavaDoc();
81     private Hashtable JavaDoc sharedFilesToDowload = new Hashtable JavaDoc();
82     private Hashtable JavaDoc descriptorParams = new Hashtable JavaDoc();
83     private boolean debug = false;
84     private String JavaDoc localProxyURL;
85     private ApplicationType type;
86     private Hashtable JavaDoc replacements = new Hashtable JavaDoc();
87     private Vector JavaDoc transformations = new Vector JavaDoc();
88     private boolean hasPrepared = false;
89     private File JavaDoc cacheDir;
90     private String JavaDoc smallIcon, largeIcon;
91     
92     /**
93      * Constructor.
94      *
95      * @param cacheDir cache directory
96      * @param applicationStoreProtocol application store protocol (http / https)
97      * @param applicationStoreUser application store userinfo (CHECK user /
98      * password or ticket?)
99      * @param applicationStoreHost application store host
100      * @param applicationStorePort application store port
101      * @param parameters parmaeters
102      * @param events callback interface for events
103      */

104     public AbstractApplicationLauncher(File JavaDoc cacheDir, String JavaDoc applicationStoreProtocol, String JavaDoc applicationStoreUser, String JavaDoc applicationStoreHost,
105                                int applicationStorePort, Hashtable JavaDoc parameters, ApplicationLauncherEvents events) {
106         this.cacheDir = cacheDir;
107         this.applicationStoreProtocol = applicationStoreProtocol;
108         this.applicationStoreHost = applicationStoreHost;
109         this.applicationStoreUser = applicationStoreUser;
110         this.applicationStorePort = applicationStorePort;
111         this.parameters = parameters;
112         this.events = events;
113     }
114
115     /**
116      * Set the URL of the local proxy server (if required). This is used when
117      * replacing variables in the extension descriptor.
118      *
119      * @param localProxyURL local proxy URL
120      */

121     public void setLocalProxyURL(String JavaDoc localProxyURL) {
122         this.localProxyURL = localProxyURL;
123     }
124
125     /**
126      * If set to true, a <b>debug</b> property with be added to parameters.
127      *
128      * @param debug send debug parameter
129      */

130     public void setDebug(boolean debug) {
131         this.debug = debug;
132     }
133
134     /**
135      * Get the application type implementation.
136      *
137      * @return application type
138      */

139     public ApplicationType getApplicationType() {
140         return type;
141     }
142
143     /**
144      * Prepare and download and process the extension descriptor.
145      *
146      * @throws IOException on any error
147      */

148     public void prepare() throws IOException JavaDoc {
149
150         hasPrepared = true;
151         
152         if (events != null)
153             events.debug(Messages.getString("ApplicationLauncher.checkingParameters")); //$NON-NLS-1$
154

155         // Add a debug parameter if were debugging
156
if (debug) {
157             parameters.put("debug", "true"); //$NON-NLS-1$ //$NON-NLS-2$
158
}
159
160         ticket = (String JavaDoc) parameters.get("ticket"); //$NON-NLS-1$
161
if (events != null && ticket!=null)
162             events.debug(MessageFormat.format(Messages.getString("ApplicationLauncher.storingTicket"), new Object JavaDoc[] { ticket })); //$NON-NLS-1$
163

164         XMLElement element = new XMLElement();
165         
166         // Read the XML into a string first so it can be displayed upon exception
167

168         events.debug(Messages.getString("ApplicationLauncher.gettingDescriptorStream")); //$NON-NLS-1$
169
InputStreamReader JavaDoc reader = new InputStreamReader JavaDoc(getApplicationDescriptor());
170         events.debug(Messages.getString("ApplicationLauncher.readingDescriptorStream")); //$NON-NLS-1$
171
char[] cbuf = new char[65536];
172         StringBuffer JavaDoc xml = new StringBuffer JavaDoc();
173         int read = 0;
174         while (read != -1) {
175             read = reader.read(cbuf,0,cbuf.length);
176             if(read != -1) {
177                 events.debug(MessageFormat.format(Messages.getString("ApplicationLauncher.readBlock"), new Object JavaDoc[] { String.valueOf(read) })); //$NON-NLS-1$
178
xml.append(cbuf,0,read);
179             }
180         }
181         try {
182             events.debug(Messages.getString("ApplicationLauncher.parsingDescriptor")); //$NON-NLS-1$
183
element.parseFromReader(new StringReader JavaDoc(xml.toString()));
184             events.debug(Messages.getString("ApplicationLauncher.parsedDescriptor")); //$NON-NLS-1$
185
}
186         catch(XMLParseException xmlpe) {
187             if (events != null) {
188                 events.debug(MessageFormat.format(Messages.getString("ApplicationLauncher.failedToParseXML"), new Object JavaDoc[] { xmlpe.getMessage() } ) ); //$NON-NLS-1$
189
events.debug(xml.toString());
190             }
191             throw xmlpe;
192         }
193         
194
195         events.debug("[XML] [" + xml.toString() + "]");
196
197         if (events != null)
198             events.debug(Messages.getString("ApplicationLauncher.receivedResponseFromServer")); //$NON-NLS-1$
199

200         if (!element.getName().equals("application") && !element.getName().equals("error") //$NON-NLS-1$ //$NON-NLS-2$
201
&& !element.getName().equals("extension")) { //$NON-NLS-1$
202
throw new IOException JavaDoc(Messages.getString("ApplicationLauncher.urlDoesNotPointToApplicationDescriptor")); //$NON-NLS-1$
203
} else if (element.getName().equals("error")) { //$NON-NLS-1$
204
throw new IOException JavaDoc(element.getContent());
205         }
206
207         name = (String JavaDoc) element.getAttribute("extension"); //$NON-NLS-1$
208
if (name == null) {
209             name = (String JavaDoc) element.getAttribute("application"); //$NON-NLS-1$
210
}
211
212         typeName = (String JavaDoc) element.getAttribute("type"); //$NON-NLS-1$
213
smallIcon = (String JavaDoc) element.getAttribute("smallIcon"); //$NON-NLS-1$
214
largeIcon = (String JavaDoc) element.getAttribute("largeIcon"); //$NON-NLS-1$
215

216         try {
217            type = ApplicationTypeManager.getInstance().createType(typeName);
218         } catch (Throwable JavaDoc t) {
219             t.printStackTrace();
220             throw new IOException JavaDoc(MessageFormat.format(Messages.getString("ApplicationLauncher.failedToLoadApplicationDescriptor"), new Object JavaDoc[] { typeName + " " + t.getMessage() })); //$NON-NLS-1$
221
}
222
223         if (events != null)
224             events.debug(MessageFormat.format(Messages.getString("ApplicationLauncher.applicationNameIs"), new Object JavaDoc[] { name, type.getClass().getName() })); //$NON-NLS-1$
225

226         if (events != null) {
227             events.processingDescriptor();
228         }
229
230         if (events != null)
231             events.debug(Messages.getString("ApplicationLauncher.creatingInstallFolder")); //$NON-NLS-1$
232

233         // This code attempts to detect the MSJVM and obtain the users profile
234
// directory so that it can be used as the users home.
235

236         if (events != null)
237             events.debug(MessageFormat.format(Messages.getString("ApplicationLauncher.userHomeIs"), new Object JavaDoc[] { cacheDir.getAbsolutePath() })); //$NON-NLS-1$
238

239         installDir = new File JavaDoc(cacheDir, "applications" + File.separator + name); //$NON-NLS-1$ //$NON-NLS-2$
240

241         sharedDir = new File JavaDoc(cacheDir, "shared"); //$NON-NLS-1$ //$NON-NLS-2$
242

243         if (!installDir.exists()) {
244             installDir.mkdirs();
245         }
246
247         if (!sharedDir.exists()) {
248             sharedDir.mkdirs();
249         }
250
251         if (events != null)
252             events.debug(MessageFormat.format(Messages.getString("ApplicationLauncher.installingTo"), new Object JavaDoc[] { installDir.getAbsolutePath() })); //$NON-NLS-1$
253

254         Enumeration JavaDoc e = element.enumerateChildren();
255
256         while (e.hasMoreElements()) {
257             XMLElement el = (XMLElement) e.nextElement();
258
259             if (el.getName().equalsIgnoreCase("files")) { //$NON-NLS-1$
260
processFiles(el);
261             } else if (el.getName().equalsIgnoreCase("tunnel")) { //$NON-NLS-1$
262
// This should contain the host and port of a tunnel that
263
// we need to create
264
createTunnel(el);
265             } else if (el.getName().equalsIgnoreCase("parameter")) { //$NON-NLS-1$
266
addParameter(el);
267             } else if (el.getName().equalsIgnoreCase("messages")) { //$NON-NLS-1$
268
// Ignore as its a server side element
269
} else if (el.getName().equalsIgnoreCase("description")) { //$NON-NLS-1$
270
// Simply ignore.. should we throw an exception if an element is
271
// not known?
272
} else if (el.getName().equalsIgnoreCase("replacements")) { //$NON-NLS-1$
273
FileReplacement replacement = new FileReplacement(installDir);
274                 replacement.processReplacementXML(el, this);
275                 replacements.put(replacement.getId(), replacement);
276             } else if (processLauncherElement(el)) {
277                 // This allows us to override more element types in extended
278
// application launchers (i.e. registry parameters)
279
continue;
280             } else if (el.getName().equalsIgnoreCase("transform")) { //$NON-NLS-1$
281
ParameterTransformation trans = new ParameterTransformation(el, this);
282                 transformations.addElement(trans);
283             } else {
284                 type.prepare(this, events, el);
285             }
286         }
287     }
288     
289     public void download() throws IOException JavaDoc {
290         
291         downloadFiles();
292
293         if (events != null)
294             events.debug(Messages.getString("ApplicationLauncher.applyingParameterTransformations")); //$NON-NLS-1$
295

296         for (Enumeration JavaDoc ep = transformations.elements(); ep.hasMoreElements();) {
297             ParameterTransformation trans = (ParameterTransformation) ep.nextElement();
298             trans.processTransformation();
299         }
300
301         if (events != null)
302             events.debug(Messages.getString("ApplicationLauncher.creatingReplacements")); //$NON-NLS-1$
303

304         for (Enumeration JavaDoc ep = replacements.elements(); ep.hasMoreElements();) {
305             FileReplacement replacement = (FileReplacement) ep.nextElement();
306             replacement.createReplacementsFile(this);
307         }
308
309         if (events != null)
310             events.debug(Messages.getString("ApplicationLauncher.replacementsCreatedPreparationComplete")); //$NON-NLS-1$
311
}
312     
313     /**
314      * Get the name of the small icon for this application.
315      *
316      * @return small icon
317      */

318     public String JavaDoc getSmallIcon() {
319         return smallIcon;
320     }
321     
322     /**
323      * Get the name of the large icon for this application.
324      *
325      * @return small icon
326      */

327     public String JavaDoc getLargeIcon() {
328         return largeIcon;
329     }
330
331     /**
332      * Download the application descriptor. This should not be called directory,
333      * it gets called during {@link #prepare()}.
334      *
335      * @return application descriptor stream
336      * @throws IOException
337      */

338     protected abstract InputStream JavaDoc getApplicationDescriptor() throws IOException JavaDoc;
339
340     protected boolean processLauncherElement(XMLElement e) {
341         return false;
342     }
343
344     /**
345      * Get the application name
346      *
347      * @return application name
348      */

349     public String JavaDoc getName() {
350         return name;
351     }
352
353     /**
354      * Get the directory where the applications files will be installed.
355      *
356      * @return install directory
357      */

358     public File JavaDoc getInstallDir() {
359         return installDir;
360     }
361
362     /**
363      * Start the application
364      */

365     public void start() throws IOException JavaDoc {
366         download();
367         type.start();
368     }
369
370     /**
371      * Add a new parameter to the launcher. This must be done before the
372      * application is launched.
373      *
374      * @param parameter
375      * @param value
376      */

377     public void addParameter(String JavaDoc parameter, String JavaDoc value) {
378
379         if (events != null) {
380             events.debug(MessageFormat.format(Messages.getString("ApplicationLauncher.addingParameter"), new Object JavaDoc[] { parameter, value }));//$NON-NLS-1$
381
}
382
383         descriptorParams.put(parameter, value);
384     }
385
386     /**
387      * Process the application extension descriptor.
388      *
389      * @param element XML element
390      * @throws IOException
391      */

392     public void processFiles(XMLElement element) throws IOException JavaDoc {
393         processFiles(element, null);
394     }
395
396     /**
397      * Process the application extension descriptor.
398      *
399      * @param element XML element
400      * @param app application
401      * @throws IOException
402      */

403     public void processFiles(XMLElement element, String JavaDoc app) throws IOException JavaDoc {
404
405         Enumeration JavaDoc en = element.enumerateChildren();
406         XMLElement e;
407
408         while (en.hasMoreElements()) {
409             e = (XMLElement) en.nextElement();
410             if (e.getName().equalsIgnoreCase("file")) { //$NON-NLS-1$
411
if(checkCondition(type, e, parameters)) {
412                     addFile(e, app);
413                 }
414             } else if (e.getName().equalsIgnoreCase("if")) { //$NON-NLS-1$
415
if (checkCondition(type, e, parameters)) {
416                     processFiles(e, app);
417                 }
418
419             } else
420                 throw new IOException JavaDoc(MessageFormat.format(Messages.getString("ApplicationLauncher.invalidElementInFiles"), new Object JavaDoc[] { e.getName() }));//$NON-NLS-1$ //$NON-NLS-2$
421
}
422
423     }
424
425     /**
426      * Check for the conditions of elements to make sure they are appropriate
427      * for the current platform / environment.
428      * <p>
429      * Only files that are ok will be downloaded / synchornized
430      *
431      * @param el file element
432      * @return ok for use
433      * @throws IOException
434      * @throws IllegalArgumentException
435      */

436     public static boolean checkCondition(ApplicationType type, XMLElement el, Hashtable JavaDoc params) throws IOException JavaDoc, IllegalArgumentException JavaDoc {
437         String JavaDoc jre = (String JavaDoc) el.getAttribute("jre"); //$NON-NLS-1$
438
String JavaDoc os = (String JavaDoc) el.getAttribute("os"); //$NON-NLS-1$
439
String JavaDoc osVersion = (String JavaDoc) el.getAttribute("osversion"); //$NON-NLS-1$
440
String JavaDoc arch = (String JavaDoc) el.getAttribute("arch"); //$NON-NLS-1$
441
String JavaDoc parameter = (String JavaDoc) el.getAttribute("parameter"); //$NON-NLS-1$
442
String JavaDoc string = (String JavaDoc) el.getAttribute("string"); //$NON-NLS-1$
443
if(jre != null) {
444             if(!Utils.isSupportedJRE(jre)) {
445                 return false;
446             }
447         }
448         if(os != null) {
449             if(!Utils.isSupportedPlatform(os)) {
450                 return false;
451             }
452         }
453         if(osVersion != null) {
454             if(!Utils.isSupportedOSVersion(osVersion)) {
455                 return false;
456             }
457         }
458         if(arch != null) {
459             if(!Utils.isSupportedArch(arch)) {
460                 return false;
461             }
462         }
463         if (parameter != null) {
464             if(params == null) {
465                 throw new IOException JavaDoc(Messages.getString("ApplicationLauncher.noParametersToTestAgainst")); //$NON-NLS-1$
466
}
467             String JavaDoc requiredValue = (String JavaDoc) el.getAttribute("value"); //$NON-NLS-1$
468
boolean not = "true".equalsIgnoreCase(((String JavaDoc) el.getAttribute("not"))); //$NON-NLS-1$ //$NON-NLS-2$
469

470             // Check the parameter
471
String JavaDoc paramValue = (String JavaDoc) params.get(parameter);
472
473             if ((!not && !requiredValue.equalsIgnoreCase(paramValue)) || (not && requiredValue.equalsIgnoreCase(paramValue))) {
474                 return false;
475             }
476         }
477         if(string != null) {
478             String JavaDoc requiredValue = (String JavaDoc) el.getAttribute("value"); //$NON-NLS-1$
479
boolean not = "true".equalsIgnoreCase(((String JavaDoc) el.getAttribute("not"))); //$NON-NLS-1$ //$NON-NLS-2$
480

481             if ((!not && !requiredValue.equalsIgnoreCase(string)) || (not && requiredValue.equalsIgnoreCase(string))) {
482                 return false;
483             }
484         }
485         return true;
486     }
487
488     /**
489      * Get the application extentsion descriptor parameters as a hastable of
490      * string objects
491      *
492      * @return descriptor parameters
493      */

494     public Hashtable JavaDoc getDescriptorParams() {
495         return descriptorParams;
496     }
497
498     /**
499      * Add shared file element.
500      *
501      * @param e shared file element
502      * @return file
503      * @throws IOException
504      */

505     public File JavaDoc addShared(XMLElement e) throws IOException JavaDoc {
506         return addShared(e, null);
507     }
508
509     /**
510      * Add shared file element.
511      *
512      * @param e shared file element
513      * @param app application
514      * @return file
515      * @throws IOException
516      */

517     public File JavaDoc addShared(XMLElement e, String JavaDoc app) throws IOException JavaDoc {
518         return addFile(e, app, true);
519
520     }
521
522     /**
523      * Add a file.
524      *
525      * @param e file element
526      * @param app application
527      * @return file
528      * @throws IOException
529      */

530     public File JavaDoc addFile(XMLElement e, String JavaDoc app) throws IOException JavaDoc {
531         return addFile(e, app, false);
532     }
533
534     /**
535      * Add a file.
536      *
537      * @param e file element
538      * @param app application
539      * @param fileMap file map
540      * @return file
541      * @throws IOException
542      */

543     File JavaDoc addFile(XMLElement e, String JavaDoc app, boolean shared) throws IOException JavaDoc {
544
545         boolean executable = "true".equals(e.getStringAttribute("exec", "false"));
546         boolean readOnly = "true".equals(e.getStringAttribute("readOnly", "false"));
547         String JavaDoc targetDirName = e.getStringAttribute("targetDir");
548         
549
550         /**
551          * LDP - Make sure any downloaded files are using the correct seperator
552          * char for the platform.
553          */

554         String JavaDoc name = e.getStringAttribute("name", "");
555         if(name.equals("")) {
556             name = Utils.trimmedBothOrBlank(e.getContent());
557         }
558         name = name.replace('/', File.separatorChar);
559         
560         // Work out the target file
561
File JavaDoc targetDir = installDir;
562         File JavaDoc entry = new File JavaDoc(installDir, name);
563         if(!Utils.isNullOrTrimmedBlank(targetDirName)) {
564             if(shared) {
565                 throw new IOException JavaDoc("Cannot specify target directory for shared files.");
566             }
567             targetDir = new File JavaDoc(installDir, targetDirName);
568             String JavaDoc filename = name;
569             int idx = name.lastIndexOf(File.separatorChar);
570             if(idx != -1) {
571                 filename = filename.substring(idx + 1);
572             }
573             entry = new File JavaDoc(targetDir, filename);
574             if (events != null) {
575                 events.debug("Alternative target directory of " + targetDirName + " (" + targetDir.getAbsolutePath() + ") provided. Target is " + entry.getAbsolutePath());
576             }
577         }
578         
579         DownloadableFile df = new DownloadableFile(name, app, executable, readOnly, entry, 0);
580         long size = 0;
581         try {
582             size = Long.parseLong((String JavaDoc) e.getAttribute("size")); //$NON-NLS-1$
583
}
584         catch(NumberFormatException JavaDoc nfe) {
585             throw new IOException JavaDoc(MessageFormat.format(Messages.getString("ApplicationLauncher.invalidSize"), new Object JavaDoc[] { name })); //$NON-NLS-1$
586

587         }
588         
589         if (events != null) {
590             events.debug(MessageFormat.format(Messages.getString("ApplicationLauncher.addingFile"), new Object JavaDoc[] { entry.getAbsolutePath(), new Long JavaDoc(size) } ) ); //$NON-NLS-1$
591
}
592
593         if (e.getAttribute("checksum") == null || e.getAttribute("size") == null) { //$NON-NLS-1$ //$NON-NLS-2$
594
throw new IOException JavaDoc(MessageFormat.format(Messages.getString("ApplicationLauncher.expectedChecksumAndSize"), new Object JavaDoc[] { name })); //$NON-NLS-1$
595
}
596         df.setChecksum(Long.parseLong((String JavaDoc) e.getAttribute("checksum")));
597         if (entry.exists()) {
598
599             // The file exists so lets check its size and checksum to determine
600
// whether we need to download it again$
601

602             long currentChecksum = generateChecksum(entry);
603
604             if (events != null) {
605                 events.debug(MessageFormat.format(Messages.getString("ApplicationLauncher.fileExistsCurrentChecksum"), new Object JavaDoc[] { new Long JavaDoc(currentChecksum), new Long JavaDoc(df.getChecksum()) })); //$NON-NLS-1$ //$NON-NLS-2$
606
}
607
608             if (currentChecksum != df.getChecksum() || entry.length() != size) {
609                 if (events != null) {
610                     events.debug(Messages.getString("ApplicationLauncher.checksumMismatchDownloading")); //$NON-NLS-1$
611
}
612
613                 if(shared)
614                     sharedFilesToDowload.put(name, df);
615                 else
616                     filesToDownload.addElement(df);
617                 
618                 totalBytesToDownload += entry.length();
619             }
620         } else {
621             if (events != null) {
622                 events.debug(Messages.getString("ApplicationLauncher.fileDoesntExistDownloading")); //$NON-NLS-1$
623
}
624
625             // We currently do not have the file so add it to the download list
626
if(shared)
627                 sharedFilesToDowload.put(name, df);
628             else
629                 filesToDownload.addElement(df);
630             totalBytesToDownload += size;
631         }
632         
633         // Add aliases
634
Enumeration JavaDoc ae = e.enumerateChildren();
635         while (ae.hasMoreElements()) {
636             XMLElement el = (XMLElement) ae.nextElement();
637             if(el.getName().equals("alias")) {
638                 df.addAlias(Utils.trimmedBothOrBlank(el.getContent()));
639             }
640         }
641
642         return entry;
643     }
644
645     /**
646      * Download a single file from an application extension.
647      *
648      * @param basedir directory to install to
649      * @param app application extension id
650      * @param filename filename to download
651      * @param target file to download to
652      * @param bytesSoFar value to start byte count at, this value will be added
653      * to then returned
654      * @param executable make executable
655      * @param readOnly make read only
656      * @param aliases aliases
657      * @return bytes read so far
658      * @throws IOException on any error
659      */

660     public long downloadFile(File JavaDoc basedir, String JavaDoc app, String JavaDoc filename, File JavaDoc target, long bytesSoFar, boolean executable, boolean readOnly, Vector JavaDoc aliases, long checksum) throws IOException JavaDoc {
661
662         /**
663          * LDP - Another method that delegates collection of a HTTP request to a
664          * seperate method so that it can be overidden.
665          */

666         if (events != null)
667             events.debug(MessageFormat.format(Messages.getString("ApplicationLauncher.downloading"), new Object JavaDoc[] { filename, target.getAbsolutePath() })); //$NON-NLS-1$ //$NON-NLS-2$
668

669         File JavaDoc f = new File JavaDoc(target.getParent());
670         f.mkdirs();
671
672         if (events != null)
673             events.debug(MessageFormat.format(Messages.getString("ApplicationLauncher.creating"), new Object JavaDoc[] { target.getAbsolutePath() })); //$NON-NLS-1$
674

675         target.delete();
676         FileOutputStream JavaDoc out = new FileOutputStream JavaDoc(target);
677         InputStream JavaDoc in = getDownloadFile(app, ticket, filename);
678         byte[] buf = new byte[16384];
679         int read;
680         while ((read = in.read(buf)) > -1) {
681             out.write(buf, 0, read);
682             bytesSoFar += read;
683
684             if (events != null)
685                 events.progressedDownload(bytesSoFar);
686         }
687         if (events != null)
688             events.debug(Messages.getString("ApplicationLauncher.finishingDownloadFile")); //$NON-NLS-1$
689

690         in.close();
691         out.close();
692         
693         if(executable) {
694             try {
695                 if (events != null)
696                     events.debug(MessageFormat.format(Messages.getString("ApplicationLauncher.makingExecutable"), new Object JavaDoc[] { target.getPath() } ) ); //$NON-NLS-1$
697
Utils.makeExecutable(target);
698             }
699             catch(IOException JavaDoc ioe) {
700                 if (events != null)
701                     events.debug(MessageFormat.format(Messages.getString("ApplicationLauncher.failedToMakeExecutable"), new Object JavaDoc[] { target.getPath(), ioe.getMessage() } ) ); //$NON-NLS-1$
702
}
703         }
704         
705         long newChecksum = generateChecksum(target);
706         if(newChecksum != checksum) {
707             events.debug("WARNING. File " + target.getPath() + " does not match expected checksum. Checksum is " + newChecksum + ", should be " + checksum);
708         }
709         
710         if(readOnly) {
711             try {
712                 if (events != null)
713                     events.debug(MessageFormat.format(Messages.getString("ApplicationLauncher.makingReadOnly"), new Object JavaDoc[] { target.getPath() } ) ); //$NON-NLS-1$
714
Utils.makeReadOnly(target);
715             }
716             catch(IOException JavaDoc ioe) {
717                 if (events != null)
718                     events.debug(MessageFormat.format(Messages.getString("ApplicationLauncher.failedToMakeReadOnly"), new Object JavaDoc[] { target.getPath(), ioe.getMessage() } ) ); //$NON-NLS-1$
719
}
720         }
721         
722         if(aliases != null && aliases.size() >0) {
723             for(Enumeration JavaDoc e = aliases.elements(); e.hasMoreElements(); ) {
724                 String JavaDoc alias = (String JavaDoc)e.nextElement();
725                 // Copy for now, look into how to link
726
File JavaDoc aliasTarget = new File JavaDoc(basedir, alias);
727                 if(events != null) {
728                     events.debug("Copying " + target.getPath() + " to " + aliasTarget.getPath());
729                 }
730                 Utils.copyFile(target, aliasTarget);
731             }
732         }
733
734         return bytesSoFar;
735
736     }
737
738     /**
739      * Get the hostname on which the application store (i.e. the SSL-Explorer
740      * server) is running.
741      *
742      * @return application store host
743      */

744     public String JavaDoc getApplicationStoreHost() {
745         return applicationStoreHost;
746     }
747
748     /**
749      * Get the port on which the application store (i.e. the SSL-Explorer
750      * server) is running.
751      *
752      * @return application store port
753      */

754     public int getApplicationStorePort() {
755         return applicationStorePort;
756     }
757
758     /**
759      * Get the protocol of where the application store (i.e. the SSL-Explorer
760      * server) is locate. This will be either <i>http</i> or <i>https</i>.
761      *
762      * @return application store protocol
763      */

764     public String JavaDoc getApplicationStoreProtocol() {
765         return applicationStoreProtocol;
766     }
767
768     // Utility methods
769

770     /**
771      * Replace the standard tokens in the source string with the value know by
772      * this VPN client.
773      * <p>
774      * Supports values include :- <code>${client:installDir}</code> - Client
775      * installation directory<br/> <code>${sslexplorer:user}</code> -
776      * SSL-Exploreruser<br/> <code>${sslexplorer:host}</code> - SSL-Explorer
777      * host<br/> <code>${sslexplorer:port}</code> - SSL-Explorer port<br/>
778      * <code>${sslexplorer:protocol}</code> - Protocol (http / https)<br/>
779      * <code>${sslexplorer:localProxyURL}</code> - Local proxy server URL<br/>
780      * <code>${tunnel:XXXXX.hostname}</code> - Named tunnel hostname<br/>
781      * <code>${tunnel:XXXXX.port}</code> - Named tunnel port<br/>
782      *
783      * @param str source string
784      * @return processed string
785      */

786     public String JavaDoc replaceTokens(String JavaDoc str) {
787         str = replaceAllTokens(str, "${client:installDir}", installDir.getAbsolutePath()); //$NON-NLS-1$
788
str = replaceAllTokens(str, "${sslexplorer:user}", applicationStoreUser == null ? "" : applicationStoreUser); //$NON-NLS-1$ //$NON-NLS-2$
789
str = replaceAllTokens(str, "${sslexplorer:host}", applicationStoreHost == null ? "" : applicationStoreHost); //$NON-NLS-1$ //$NON-NLS-2$
790
str = replaceAllTokens(str, "${sslexplorer:port}", applicationStorePort == -1 ? "" : String.valueOf(applicationStorePort)); //$NON-NLS-1$ //$NON-NLS-2$
791
str = replaceAllTokens(str, "${sslexplorer:protocol}", applicationStoreProtocol == null ? "" : applicationStoreProtocol); //$NON-NLS-1$ //$NON-NLS-2$
792
str = replaceAllTokens(str, "${client:localProxyURL}", localProxyURL == null ? "" : localProxyURL); //$NON-NLS-1$ //$NON-NLS-2$
793
for (Enumeration JavaDoc e = descriptorParams.keys(); e.hasMoreElements();) {
794             String JavaDoc key = (String JavaDoc) e.nextElement();
795             String JavaDoc val = (String JavaDoc) descriptorParams.get(key);
796             str = replaceAllTokens(str, "${param:" + key + "}", val); //$NON-NLS-1$ //$NON-NLS-2$
797
}
798         return str;
799     }
800
801     public InputStream JavaDoc getDownloadFile(String JavaDoc name, String JavaDoc ticket, String JavaDoc filename) throws IOException JavaDoc {
802         URL JavaDoc file = new URL JavaDoc(applicationStoreProtocol, applicationStoreHost, applicationStorePort, "/getApplicationFile.do" //$NON-NLS-1$
803
+ "?name=" + name + "&ticket=" + ticket + "&file=" + filename); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
804
if (events != null)
805             events.debug(MessageFormat.format(Messages.getString("ApplicationLauncher.requestApplicationUsing"), new Object JavaDoc[] { file.toExternalForm() })); //$NON-NLS-1$
806

807         URLConnection JavaDoc con = file.openConnection();
808         con.setUseCaches(false);
809
810         try {
811             Method JavaDoc m = con.getClass().getMethod("setConnectTimeout", new Class JavaDoc[] { int.class }); //$NON-NLS-1$
812
if (events != null) {
813                 events.debug(Messages.getString("ApplicationLauncher.runtime5")); //$NON-NLS-1$
814
}
815             m.invoke(con, new Object JavaDoc[] { new Integer JavaDoc(20000) });
816             m = con.getClass().getMethod("setReadTimeout", new Class JavaDoc[] { int.class }); //$NON-NLS-1$
817
m.invoke(con, new Object JavaDoc[] { new Integer JavaDoc(20000) });
818         } catch (Throwable JavaDoc t) {
819         }
820
821         return con.getInputStream();
822     }
823
824     /**
825      * Replace all occures of a token in a source string with another value
826      *
827      * @param source source string
828      * @param token token to replace
829      * @param value value to replace with
830      * @return result
831      */

832     public static String JavaDoc replaceAllTokens(String JavaDoc source, String JavaDoc token, String JavaDoc value) {
833         // Prevent infinite loop
834
if(token.equals(value)) {
835             return source;
836         }
837         
838         int idx;
839
840         do {
841             idx = source.indexOf(token);
842
843             if (idx > -1) {
844                 source = source.substring(0, idx) + value
845                     + ((source.length() - idx <= token.length()) ? "" : source.substring(idx + token.length())); //$NON-NLS-1$
846
}
847
848         } while (idx > -1);
849
850         return source;
851     }
852
853
854     private void addParameter(XMLElement e) throws IOException JavaDoc {
855         String JavaDoc parameter = (String JavaDoc) e.getAttribute("name"); //$NON-NLS-1$
856
String JavaDoc value = (String JavaDoc) e.getAttribute("value"); //$NON-NLS-1$
857
if (events != null) {
858             events.debug(MessageFormat.format(Messages.getString("ApplicationLauncher.addingParameter"), new Object JavaDoc[] { parameter, value }));//$NON-NLS-1$
859
}
860
861         descriptorParams.put(parameter, value);
862     }
863
864     protected void createTunnel(XMLElement e) throws IOException JavaDoc {
865          throw new IOException JavaDoc(Messages.getString("ApplicationLauncher.tunnelRequiredButNoEventHandler")); //$NON-NLS-1$
866
}
867
868     private long generateChecksum(File JavaDoc f) throws IOException JavaDoc {
869
870         Adler32 JavaDoc alder = new Adler32 JavaDoc();
871         CheckedInputStream JavaDoc in = new CheckedInputStream JavaDoc(new FileInputStream JavaDoc(f), alder);
872         try {
873             byte[] buf = new byte[4096];
874             int read = 0;
875             while ((read = in.read(buf)) > -1)
876                 ;
877
878             alder = (Adler32 JavaDoc) in.getChecksum();
879
880             return alder.getValue();
881         } finally {
882             in.close();
883         }
884     }
885
886     private void downloadFiles() throws IOException JavaDoc {
887
888         if (events != null)
889             events.debug(Messages.getString("ApplicationLauncher.downloadingFiles")); //$NON-NLS-1$
890

891         if (events != null)
892             events.startDownload(totalBytesToDownload);
893
894         long bytesSoFar = 0;
895
896         DownloadableFile df;
897         for (int i = 0; i < filesToDownload.size(); i++) {
898             df = (DownloadableFile) filesToDownload.elementAt(i);
899             bytesSoFar = downloadFile(installDir,
900                 (df.getApplicationName() == null ? name : df.getApplicationName()),
901                 df.getName(),
902                 df.getTarget(),
903                 bytesSoFar,
904                 df.isExecutable(),
905                 df.isReadOnly(),
906                 df.getAliases(),
907                 df.getChecksum());
908         }
909
910         for (Enumeration JavaDoc e = sharedFilesToDowload.keys(); e.hasMoreElements();) {
911             String JavaDoc name = (String JavaDoc) e.nextElement();
912             df = (DownloadableFile) sharedFilesToDowload.get(name);
913             bytesSoFar = downloadFile(sharedDir,
914                 (df.getApplicationName() == null ? name : df.getApplicationName()),
915                 df.getName(),
916                 df.getTarget(),
917                 bytesSoFar,
918                 df.isExecutable(),
919                 df.isReadOnly(),
920                 df.getAliases(),
921                 df.getChecksum());
922         }
923
924         if (events != null)
925             events.completedDownload();
926
927         if (events != null)
928             events.debug(Messages.getString("ApplicationLauncher.completedDownloadingFiles")); //$NON-NLS-1$
929
}
930
931     public Vector JavaDoc getTunnels() {
932         return EMPTY_VECTOR;
933     }
934     
935     public void processErrorMessage(String JavaDoc text) {
936         events.error(text);
937     }
938 }
Popular Tags