KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > pde > internal > core > PlatformConfiguration


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.pde.internal.core;
12
13 import java.io.*;
14 import java.net.*;
15 import java.util.*;
16
17 import org.eclipse.core.internal.boot.*;
18 import org.eclipse.update.configurator.*;
19
20 public class PlatformConfiguration implements IPlatformConfiguration {
21
22     private static PlatformConfiguration currentPlatformConfiguration = null;
23
24     private URL configLocation;
25     private HashMap sites;
26     private HashMap externalLinkSites; // used to restore prior link site state
27
private HashMap cfgdFeatures;
28     private HashMap bootPlugins;
29     private String JavaDoc defaultFeature;
30     private long changeStamp;
31     private boolean changeStampIsValid = false;
32     private long lastFeaturesChangeStamp;
33     private long featuresChangeStamp;
34     private boolean featuresChangeStampIsValid = false;
35     private long pluginsChangeStamp;
36     private boolean pluginsChangeStampIsValid = false;
37     private boolean transientConfig = false;
38     private File cfgLockFile;
39     private RandomAccessFile cfgLockFileRAF;
40     private BootDescriptor runtimeDescriptor;
41
42     private static String JavaDoc cmdFeature = null;
43     private static String JavaDoc cmdApplication = null;
44     private static boolean cmdInitialize = false;
45     private static boolean cmdFirstUse = false;
46     private static boolean cmdUpdate = false;
47     private static boolean cmdNoUpdate = false;
48
49     static boolean DEBUG = false;
50
51     private static final String JavaDoc RUNTIME_PLUGIN_ID = "org.eclipse.core.runtime"; //$NON-NLS-1$
52

53     private static final String JavaDoc PLUGINS = "plugins"; //$NON-NLS-1$
54
private static final String JavaDoc FEATURES = "features"; //$NON-NLS-1$
55
private static final String JavaDoc CONFIG_FILE_TEMP_SUFFIX = ".tmp"; //$NON-NLS-1$
56
private static final String JavaDoc CONFIG_FILE_BAK_SUFFIX = ".bak"; //$NON-NLS-1$
57
private static final String JavaDoc PLUGIN_XML = "plugin.xml"; //$NON-NLS-1$
58
private static final String JavaDoc FRAGMENT_XML = "fragment.xml"; //$NON-NLS-1$
59
private static final String JavaDoc FEATURE_XML = "feature.xml"; //$NON-NLS-1$
60

61     private static final String JavaDoc[] BOOTSTRAP_PLUGINS = { "org.eclipse.core.boot" }; //$NON-NLS-1$
62
private static final String JavaDoc CFG_BOOT_PLUGIN = "bootstrap"; //$NON-NLS-1$
63
private static final String JavaDoc CFG_SITE = "site"; //$NON-NLS-1$
64
private static final String JavaDoc CFG_URL = "url"; //$NON-NLS-1$
65
private static final String JavaDoc CFG_POLICY = "policy"; //$NON-NLS-1$
66
private static final String JavaDoc[] CFG_POLICY_TYPE = { "USER-INCLUDE", "USER-EXCLUDE" }; //$NON-NLS-1$ //$NON-NLS-2$
67
private static final String JavaDoc CFG_POLICY_TYPE_UNKNOWN = "UNKNOWN"; //$NON-NLS-1$
68
private static final String JavaDoc CFG_LIST = "list"; //$NON-NLS-1$
69
private static final String JavaDoc CFG_STAMP = "stamp"; //$NON-NLS-1$
70
private static final String JavaDoc CFG_FEATURE_STAMP = "stamp.features"; //$NON-NLS-1$
71
private static final String JavaDoc CFG_PLUGIN_STAMP = "stamp.plugins"; //$NON-NLS-1$
72
private static final String JavaDoc CFG_UPDATEABLE = "updateable"; //$NON-NLS-1$
73
private static final String JavaDoc CFG_LINK_FILE = "linkfile"; //$NON-NLS-1$
74
private static final String JavaDoc CFG_FEATURE_ENTRY = "feature"; //$NON-NLS-1$
75
private static final String JavaDoc CFG_FEATURE_ENTRY_DEFAULT = "feature.default.id"; //$NON-NLS-1$
76
private static final String JavaDoc CFG_FEATURE_ENTRY_ID = "id"; //$NON-NLS-1$
77
private static final String JavaDoc CFG_FEATURE_ENTRY_PRIMARY = "primary"; //$NON-NLS-1$
78
private static final String JavaDoc CFG_FEATURE_ENTRY_VERSION = "version"; //$NON-NLS-1$
79
private static final String JavaDoc CFG_FEATURE_ENTRY_PLUGIN_VERSION = "plugin-version"; //$NON-NLS-1$
80
private static final String JavaDoc CFG_FEATURE_ENTRY_PLUGIN_IDENTIFIER = "plugin-identifier"; //$NON-NLS-1$
81
private static final String JavaDoc CFG_FEATURE_ENTRY_APPLICATION = "application"; //$NON-NLS-1$
82
private static final String JavaDoc CFG_FEATURE_ENTRY_ROOT = "root"; //$NON-NLS-1$
83

84     private static final String JavaDoc DEFAULT_FEATURE_ID = "org.eclipse.platform"; //$NON-NLS-1$
85
private static final String JavaDoc DEFAULT_FEATURE_APPLICATION = "org.eclipse.ui.workbench"; //$NON-NLS-1$
86

87     private static final String JavaDoc CFG_VERSION = "version"; //$NON-NLS-1$
88
private static final String JavaDoc CFG_TRANSIENT = "transient"; //$NON-NLS-1$
89
private static final String JavaDoc VERSION = "2.1"; //$NON-NLS-1$
90
private static final String JavaDoc EOF = "eof"; //$NON-NLS-1$
91
private static final int CFG_LIST_LENGTH = 10;
92
93     private static final int DEFAULT_POLICY_TYPE = ISitePolicy.USER_EXCLUDE;
94     private static final String JavaDoc[] DEFAULT_POLICY_LIST = new String JavaDoc[0];
95
96
97     protected static final String JavaDoc RECONCILER_APP = "org.eclipse.update.core.reconciler"; //$NON-NLS-1$
98

99     private static final char[] HEX = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
100
101     private static URL installURL;
102
103     public class SiteEntry implements IPlatformConfiguration.ISiteEntry {
104
105         private URL url; // this is the external URL for the site
106
private URL resolvedURL; // this is the resolved URL used internally
107
private ISitePolicy policy;
108         private boolean updateable = true;
109         private ArrayList features;
110         private ArrayList plugins;
111         private PlatformConfiguration parent;
112         private long changeStamp;
113         private boolean changeStampIsValid = false;
114         private long lastFeaturesChangeStamp;
115         private long featuresChangeStamp;
116         private boolean featuresChangeStampIsValid = false;
117         private long lastPluginsChangeStamp;
118         private long pluginsChangeStamp;
119         private boolean pluginsChangeStampIsValid = false;
120         private String JavaDoc linkFileName = null;
121
122         private SiteEntry() {
123         }
124         private SiteEntry(URL url, ISitePolicy policy, PlatformConfiguration parent) {
125             if (url == null)
126                 throw new IllegalArgumentException JavaDoc();
127
128             if (policy == null)
129                 throw new IllegalArgumentException JavaDoc();
130
131             if (parent == null)
132                 throw new IllegalArgumentException JavaDoc();
133
134             this.url = url;
135             this.policy = policy;
136             this.parent = parent;
137             this.features = null;
138             this.plugins = null;
139             this.resolvedURL = this.url;
140             if (url.getProtocol().equals(PlatformURLHandler.PROTOCOL)) {
141                 try {
142                     resolvedURL = resolvePlatformURL(url); // 19536
143
} catch (IOException e) {
144                     // will use the baseline URL ...
145
}
146             }
147         }
148
149         /*
150          * @see ISiteEntry#getURL()
151          */

152         public URL getURL() {
153             return url;
154         }
155
156         /*
157         * @see ISiteEntry#getSitePolicy()
158         */

159         public ISitePolicy getSitePolicy() {
160             return policy;
161         }
162
163         /*
164          * @see ISiteEntry#setSitePolicy(ISitePolicy)
165          */

166         public synchronized void setSitePolicy(ISitePolicy policy) {
167             if (policy == null)
168                 throw new IllegalArgumentException JavaDoc();
169             this.policy = policy;
170         }
171
172         /*
173          * @see ISiteEntry#getFeatures()
174          */

175         public String JavaDoc[] getFeatures() {
176             return getDetectedFeatures();
177         }
178
179         /*
180          * @see ISiteEntry#getPlugins()
181          */

182         public String JavaDoc[] getPlugins() {
183
184             ISitePolicy policy = getSitePolicy();
185
186             if (policy.getType() == ISitePolicy.USER_INCLUDE)
187                 return policy.getList();
188
189             if (policy.getType() == ISitePolicy.USER_EXCLUDE) {
190                 ArrayList detectedPlugins = new ArrayList(Arrays.asList(getDetectedPlugins()));
191                 String JavaDoc[] excludedPlugins = policy.getList();
192                 for (int i = 0; i < excludedPlugins.length; i++) {
193                     if (detectedPlugins.contains(excludedPlugins[i]))
194                         detectedPlugins.remove(excludedPlugins[i]);
195                 }
196                 return (String JavaDoc[]) detectedPlugins.toArray(new String JavaDoc[0]);
197             }
198
199             // bad policy type
200
return new String JavaDoc[0];
201         }
202
203         /*
204          * @see ISiteEntry#getChangeStamp()
205          */

206         public long getChangeStamp() {
207             if (!changeStampIsValid)
208                 computeChangeStamp();
209             return changeStamp;
210         }
211
212         /*
213          * @see ISiteEntry#getFeaturesChangeStamp()
214          */

215         public long getFeaturesChangeStamp() {
216             if (!featuresChangeStampIsValid)
217                 computeFeaturesChangeStamp();
218             return featuresChangeStamp;
219         }
220
221         /*
222          * @see ISiteEntry#getPluginsChangeStamp()
223          */

224         public long getPluginsChangeStamp() {
225             if (!pluginsChangeStampIsValid)
226                 computePluginsChangeStamp();
227             return pluginsChangeStamp;
228         }
229
230         /*
231          * @see ISiteEntry#isUpdateable()
232          */

233         public boolean isUpdateable() {
234             return updateable;
235         }
236
237         /*
238          * @see ISiteEntry#isNativelyLinked()
239          */

240         public boolean isNativelyLinked() {
241             return isExternallyLinkedSite();
242         }
243
244         private String JavaDoc[] detectFeatures() {
245
246             // invalidate stamps ... we are doing discovery
247
changeStampIsValid = false;
248             featuresChangeStampIsValid = false;
249             parent.changeStampIsValid = false;
250             parent.featuresChangeStampIsValid = false;
251
252             features = new ArrayList();
253
254             if (!supportsDetection(resolvedURL))
255                 return new String JavaDoc[0];
256
257             // locate feature entries on site
258
File siteRoot = new File(resolvedURL.getFile().replace('/', File.separatorChar));
259             File root = new File(siteRoot, FEATURES);
260
261             String JavaDoc[] list = root.list();
262             String JavaDoc path;
263             File plugin;
264             for (int i = 0; list != null && i < list.length; i++) {
265                 path = list[i] + File.separator + FEATURE_XML;
266                 plugin = new File(root, path);
267                 if (!plugin.exists()) {
268                     continue;
269                 }
270                 features.add(FEATURES + "/" + path.replace(File.separatorChar, '/')); //$NON-NLS-1$
271
}
272             if (DEBUG) {
273                 debug(resolvedURL.toString() + " located " + features.size() + " feature(s)"); //$NON-NLS-1$ //$NON-NLS-2$
274
}
275
276             return (String JavaDoc[]) features.toArray(new String JavaDoc[0]);
277         }
278
279         private String JavaDoc[] detectPlugins() {
280
281             // invalidate stamps ... we are doing discovery
282
changeStampIsValid = false;
283             pluginsChangeStampIsValid = false;
284             parent.changeStampIsValid = false;
285             parent.pluginsChangeStampIsValid = false;
286
287             plugins = new ArrayList();
288
289             if (!supportsDetection(resolvedURL))
290                 return new String JavaDoc[0];
291
292             // locate plugin entries on site
293
File root = new File(resolvedURL.getFile().replace('/', File.separatorChar) + PLUGINS);
294             String JavaDoc[] list = root.list();
295             String JavaDoc path;
296             File plugin;
297             for (int i = 0; list != null && i < list.length; i++) {
298                 path = list[i] + File.separator + PLUGIN_XML;
299                 plugin = new File(root, path);
300                 if (!plugin.exists()) {
301                     path = list[i] + File.separator + FRAGMENT_XML;
302                     plugin = new File(root, path);
303                     if (!plugin.exists())
304                         continue;
305                 }
306                 plugins.add(PLUGINS + "/" + path.replace(File.separatorChar, '/')); //$NON-NLS-1$
307
}
308             if (DEBUG) {
309                 debug(resolvedURL.toString() + " located " + plugins.size() + " plugin(s)"); //$NON-NLS-1$ //$NON-NLS-2$
310
}
311
312             return (String JavaDoc[]) plugins.toArray(new String JavaDoc[0]);
313         }
314
315         private synchronized String JavaDoc[] getDetectedFeatures() {
316             if (features == null)
317                 return detectFeatures();
318             return (String JavaDoc[]) features.toArray(new String JavaDoc[0]);
319         }
320
321         private synchronized String JavaDoc[] getDetectedPlugins() {
322             if (plugins == null)
323                 return detectPlugins();
324             return (String JavaDoc[]) plugins.toArray(new String JavaDoc[0]);
325         }
326
327         private URL getResolvedURL() {
328             return resolvedURL;
329         }
330
331         private void computeChangeStamp() {
332             computeFeaturesChangeStamp();
333             computePluginsChangeStamp();
334             changeStamp = resolvedURL.hashCode() ^ featuresChangeStamp ^ pluginsChangeStamp;
335             changeStampIsValid = true;
336         }
337
338         private synchronized void computeFeaturesChangeStamp() {
339             if (featuresChangeStampIsValid)
340                 return;
341
342             long start = 0;
343             if (DEBUG)
344                 start = (new Date()).getTime();
345             String JavaDoc[] features = getFeatures();
346             featuresChangeStamp = computeStamp(features);
347             featuresChangeStampIsValid = true;
348             if (DEBUG) {
349                 long end = (new Date()).getTime();
350                 debug(resolvedURL.toString() + " feature stamp: " + featuresChangeStamp + ((featuresChangeStamp == lastFeaturesChangeStamp) ? " [no changes]" : " [was " + lastFeaturesChangeStamp + "]") + " in " + (end - start) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
351
}
352         }
353
354         private synchronized void computePluginsChangeStamp() {
355             if (pluginsChangeStampIsValid)
356                 return;
357
358             long start = 0;
359             if (DEBUG)
360                 start = (new Date()).getTime();
361             String JavaDoc[] plugins = getPlugins();
362             pluginsChangeStamp = computeStamp(plugins);
363             pluginsChangeStampIsValid = true;
364             if (DEBUG) {
365                 long end = (new Date()).getTime();
366                 debug(resolvedURL.toString() + " plugin stamp: " + pluginsChangeStamp + ((pluginsChangeStamp == lastPluginsChangeStamp) ? " [no changes]" : " [was " + lastPluginsChangeStamp + "]") + " in " + (end - start) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
367
}
368         }
369
370         private long computeStamp(String JavaDoc[] targets) {
371
372             long result = 0;
373             if (!supportsDetection(resolvedURL)) {
374                 // NOTE: this path should not be executed until we support running
375
// from an arbitrary URL (in particular from http server). For
376
// now just compute stamp across the list of names. Eventually
377
// when general URLs are supported we need to do better (factor
378
// in at least the existence of the target). However, given this
379
// code executes early on the startup sequence we need to be
380
// extremely mindful of performance issues.
381
for (int i = 0; i < targets.length; i++)
382                     result ^= targets[i].hashCode();
383                 if (DEBUG)
384                     debug("*WARNING* computing stamp using URL hashcodes only"); //$NON-NLS-1$
385
} else {
386                 // compute stamp across local targets
387
String JavaDoc rootPath = resolvedURL.getFile().replace('/', File.separatorChar);
388                 if (!rootPath.endsWith(File.separator))
389                     rootPath += File.separator;
390                 File rootFile = new File(rootPath);
391                 if (rootFile.exists()) {
392                     File f = null;
393                     for (int i = 0; i < targets.length; i++) {
394                         f = new File(rootFile, targets[i]);
395                         if (f.exists())
396                             result ^= f.getAbsolutePath().hashCode() ^ f.lastModified() ^ f.length();
397                     }
398                 }
399             }
400
401             return result;
402         }
403
404         private boolean isExternallyLinkedSite() {
405             return (linkFileName != null && !linkFileName.trim().equals("")); //$NON-NLS-1$
406
}
407
408         private synchronized void refresh() {
409             // reset computed values. Will be updated on next access.
410
lastFeaturesChangeStamp = featuresChangeStamp;
411             lastPluginsChangeStamp = pluginsChangeStamp;
412             changeStampIsValid = false;
413             featuresChangeStampIsValid = false;
414             pluginsChangeStampIsValid = false;
415             features = null;
416             plugins = null;
417         }
418
419     }
420
421     public class SitePolicy implements IPlatformConfiguration.ISitePolicy {
422
423         private int type;
424         private String JavaDoc[] list;
425
426         private SitePolicy() {
427         }
428         private SitePolicy(int type, String JavaDoc[] list) {
429             if (type != ISitePolicy.USER_INCLUDE && type != ISitePolicy.USER_EXCLUDE)
430                 throw new IllegalArgumentException JavaDoc();
431             this.type = type;
432
433             if (list == null)
434                 this.list = new String JavaDoc[0];
435             else
436                 this.list = list;
437         }
438
439         /*
440          * @see ISitePolicy#getType()
441          */

442         public int getType() {
443             return type;
444         }
445
446         /*
447         * @see ISitePolicy#getList()
448         */

449         public String JavaDoc[] getList() {
450             return list;
451         }
452
453         /*
454          * @see ISitePolicy#setList(String[])
455          */

456         public synchronized void setList(String JavaDoc[] list) {
457             if (list == null)
458                 this.list = new String JavaDoc[0];
459             else
460                 this.list = list;
461         }
462
463     }
464
465     public class FeatureEntry implements IPlatformConfiguration.IFeatureEntry {
466         private String JavaDoc id;
467         private String JavaDoc version;
468         private String JavaDoc pluginVersion;
469         private String JavaDoc application;
470         private URL[] root;
471         private boolean primary;
472         private String JavaDoc pluginIdentifier;
473
474         private FeatureEntry(String JavaDoc id, String JavaDoc version, String JavaDoc pluginIdentifier, String JavaDoc pluginVersion, boolean primary, String JavaDoc application, URL[] root) {
475             if (id == null)
476                 throw new IllegalArgumentException JavaDoc();
477             this.id = id;
478             this.version = version;
479             this.pluginVersion = pluginVersion;
480             this.pluginIdentifier = pluginIdentifier;
481             this.primary = primary;
482             this.application = application;
483             this.root = (root == null ? new URL[0] : root);
484         }
485
486         private FeatureEntry(String JavaDoc id, String JavaDoc version, String JavaDoc pluginVersion, boolean primary, String JavaDoc application, URL[] root) {
487             this(id, version, id, pluginVersion, primary, application, root);
488         }
489
490         /*
491          * @see IFeatureEntry#getFeatureIdentifier()
492          */

493         public String JavaDoc getFeatureIdentifier() {
494             return id;
495         }
496
497         /*
498          * @see IFeatureEntry#getFeatureVersion()
499          */

500         public String JavaDoc getFeatureVersion() {
501             return version;
502         }
503
504         /*
505          * @see IFeatureEntry#getFeaturePluginVersion()
506          */

507         public String JavaDoc getFeaturePluginVersion() {
508             return pluginVersion;
509         }
510
511         /*
512          * @see IFeatureEntry#getFeatureApplication()
513          */

514         public String JavaDoc getFeatureApplication() {
515             return application;
516         }
517
518         /*
519          * @see IFeatureEntry#getFeatureRootURLs()
520          */

521         public URL[] getFeatureRootURLs() {
522             return root;
523         }
524
525         /*
526          * @see IFeatureEntry#canBePrimary()
527          */

528         public boolean canBePrimary() {
529             return primary;
530         }
531         /*
532          * @see IFeatureEntry#getFeaturePluginIdentifier()
533          */

534         public String JavaDoc getFeaturePluginIdentifier() {
535             return pluginIdentifier;
536         }
537
538     }
539
540
541     /*
542      * Element selector for use with "tiny" parser. Parser callers supply
543      * concrete selectors
544      */

545     public interface Selector {
546
547         /*
548          * Method is called to pre-select a specific xml type. Pre-selected
549          * elements are then fully parsed and result in calls to full
550          * select method.
551          * @return <code>true</code> is the element should be considered,
552          * <code>false</code> otherwise
553          */

554         public boolean select(String JavaDoc entry);
555
556         /*
557          * Method is called with a fully parsed element.
558          * @return <code>true</code> to select this element and terminate the parse,
559          * <code>false</code> otherwise
560          */

561         public boolean select(String JavaDoc element, HashMap attributes);
562     }
563
564     /*
565      * "Tiny" xml parser. Performs a rudimentary parse of a well-formed xml file.
566      * Is specifically geared to parsing plugin.xml files of "bootstrap" plug-ins
567      * during the platform startup sequence before full xml plugin is available.
568      */

569     public static class Parser {
570
571         private ArrayList elements = new ArrayList();
572
573         /*
574          * Construct parser for the specified file
575          */

576         public Parser(File file) {
577             try {
578                 load(new FileInputStream(file));
579             } catch (Exception JavaDoc e) {
580                 // continue ... actual parsing will report errors
581
}
582         }
583
584         /*
585          * Construct parser for the specified URL
586          */

587         public Parser(URL url) {
588             try {
589                 load(url.openStream());
590             } catch (Exception JavaDoc e) {
591                 // continue ... actual parsing will report errors
592
}
593         }
594
595         /*
596          * Return selected elements as an (attribute-name, attribute-value) map.
597          * The name of the selected element is returned as the value of entry with
598          * name "<element>".
599          * @return attribute map for selected element, or <code>null</code>
600          */

601         public HashMap getElement(Selector selector) {
602             if (selector == null)
603                 return null;
604
605             String JavaDoc element;
606             for (int i = 0; i < elements.size(); i++) {
607                 // make pre-parse selector call
608
element = (String JavaDoc) elements.get(i);
609                 if (selector.select(element)) {
610                     // parse selected entry
611
HashMap attributes = new HashMap();
612                     String JavaDoc elementName;
613                     int j;
614                     // parse out element name
615
for (j = 0; j < element.length(); j++) {
616                         if (Character.isWhitespace(element.charAt(j)))
617                             break;
618                     }
619                     if (j >= element.length()) {
620                         elementName = element;
621                     } else {
622                         elementName = element.substring(0, j);
623                         element = element.substring(j);
624                         // parse out attributes
625
StringTokenizer t = new StringTokenizer(element, "=\""); //$NON-NLS-1$
626
boolean isKey = true;
627                         String JavaDoc key = ""; //$NON-NLS-1$
628
while (t.hasMoreTokens()) {
629                             String JavaDoc token = t.nextToken().trim();
630                             if (!token.equals("")) { //$NON-NLS-1$
631
// collect (key, value) pairs
632
if (isKey) {
633                                     key = token;
634                                     isKey = false;
635                                 } else {
636                                     attributes.put(key, token);
637                                     isKey = true;
638                                 }
639                             }
640                         }
641                     }
642                     // make post-parse selector call
643
if (selector.select(elementName, attributes)) {
644                         attributes.put("<element>", elementName); //$NON-NLS-1$
645
return attributes;
646                     }
647                 }
648             }
649             return null;
650         }
651
652         private void load(InputStream is) {
653             if (is == null)
654                 return;
655
656             // read file
657
StringBuffer JavaDoc xml = new StringBuffer JavaDoc(4096);
658             char[] iobuf = new char[4096];
659             InputStreamReader r = null;
660             try {
661                 r = new InputStreamReader(is);
662                 int len = r.read(iobuf, 0, iobuf.length);
663                 while (len != -1) {
664                     xml.append(iobuf, 0, len);
665                     len = r.read(iobuf, 0, iobuf.length);
666                 }
667             } catch (Exception JavaDoc e) {
668                 return;
669             } finally {
670                 if (r != null)
671                     try {
672                         r.close();
673                     } catch (IOException e) {
674                         // ignore
675
}
676             }
677
678             // parse out element tokens
679
String JavaDoc xmlString = xml.toString();
680             StringTokenizer t = new StringTokenizer(xmlString, "<>"); //$NON-NLS-1$
681
while (t.hasMoreTokens()) {
682                 String JavaDoc token = t.nextToken().trim();
683                 if (!token.equals("")) //$NON-NLS-1$
684
elements.add(token);
685             }
686         }
687     }
688
689     public static class BootDescriptor {
690         private String JavaDoc id;
691         private String JavaDoc version;
692         private