KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > update > internal > configurator > SiteEntry


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 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.update.internal.configurator;
12
13 import java.io.*;
14 import java.net.*;
15 import java.util.ArrayList JavaDoc;
16 import java.util.Arrays JavaDoc;
17 import java.util.Collection JavaDoc;
18 import java.util.Date JavaDoc;
19 import java.util.HashMap JavaDoc;
20 import java.util.Iterator JavaDoc;
21 import java.util.Map JavaDoc;
22 import java.util.zip.*;
23
24 import org.eclipse.core.runtime.*;
25 import org.eclipse.osgi.service.environment.*;
26 import org.eclipse.osgi.util.NLS;
27 import org.eclipse.update.configurator.*;
28 import org.eclipse.update.configurator.IPlatformConfiguration.*;
29 import org.w3c.dom.*;
30 import org.xml.sax.*;
31
32
33 public class SiteEntry implements IPlatformConfiguration.ISiteEntry, IConfigurationConstants{
34     private static final String JavaDoc MAC_OS_MARKER = ".DS_Store"; //$NON-NLS-1$
35

36     private URL url; // this is the external URL for the site
37
private URL resolvedURL; // this is the resolved URL used internally
38
private ISitePolicy policy;
39     private boolean updateable = true;
40     private Map JavaDoc featureEntries;
41     private ArrayList JavaDoc pluginEntries;
42     private long changeStamp;
43     private long featuresChangeStamp;
44     private long pluginsChangeStamp;
45     private String JavaDoc linkFileName;
46     private boolean enabled = true;
47     private Configuration config;
48     
49     private static FeatureParser featureParser = new FeatureParser();
50     private static PluginParser pluginParser = new PluginParser();
51     private static boolean isMacOS = Utils.getOS().equals(Constants.OS_MACOSX);
52
53     public SiteEntry(URL url) {
54         this(url,null);
55     }
56     
57     public SiteEntry(URL url, ISitePolicy policy) {
58         if (url == null)
59             try {
60                 url = new URL("platform:/base/"); //$NON-NLS-1$ try using platform-relative URL
61
} catch (MalformedURLException e) {
62                 url = PlatformConfiguration.getInstallURL(); // ensure we come up ... use absolute file URL
63
}
64             
65         if (policy == null)
66             policy = new SitePolicy(PlatformConfiguration.getDefaultPolicy(), DEFAULT_POLICY_LIST);
67
68         if (url.getProtocol().equals("file")) { //$NON-NLS-1$
69
try {
70                 // TODO remove this when platform fixes local file url's
71
this.url = new File(url.getFile()).toURL();
72             } catch (MalformedURLException e1) {
73                 this.url = url;
74             }
75         } else
76             this.url = url;
77         
78         this.policy = policy;
79         this.resolvedURL = this.url;
80         if (url.getProtocol().equals("platform")) { //$NON-NLS-1$
81
try {
82                 resolvedURL = PlatformConfiguration.resolvePlatformURL(url); // 19536
83
} catch (IOException e) {
84                 // will use the baseline URL ...
85
}
86         }
87     }
88
89     public void setConfig(Configuration config) {
90         this.config = config;
91     }
92     
93     public Configuration getConfig() {
94         return config;
95     }
96     
97     /*
98      * @see ISiteEntry#getURL()
99      */

100     public URL getURL() {
101         return url;
102     }
103
104     /*
105     * @see ISiteEntry#getSitePolicy()
106     */

107     public ISitePolicy getSitePolicy() {
108         return policy;
109     }
110
111     /*
112      * @see ISiteEntry#setSitePolicy(ISitePolicy)
113      */

114     public synchronized void setSitePolicy(ISitePolicy policy) {
115         if (policy == null)
116             throw new IllegalArgumentException JavaDoc();
117         this.policy = policy;
118     }
119
120     /*
121      * @see ISiteEntry#getFeatures()
122      */

123     public String JavaDoc[] getFeatures() {
124         return getDetectedFeatures();
125     }
126
127     /*
128      * @see ISiteEntry#getPlugins()
129      */

130     public String JavaDoc[] getPlugins() {
131
132         ISitePolicy policy = getSitePolicy();
133
134         if (policy.getType() == ISitePolicy.USER_INCLUDE)
135             return policy.getList();
136
137         if (policy.getType() == ISitePolicy.USER_EXCLUDE) {
138             ArrayList JavaDoc detectedPlugins = new ArrayList JavaDoc(Arrays.asList(getDetectedPlugins()));
139             String JavaDoc[] excludedPlugins = policy.getList();
140             for (int i = 0; i < excludedPlugins.length; i++) {
141                 if (detectedPlugins.contains(excludedPlugins[i]))
142                     detectedPlugins.remove(excludedPlugins[i]);
143             }
144             return (String JavaDoc[]) detectedPlugins.toArray(new String JavaDoc[0]);
145         }
146         
147         if (policy.getType() == ISitePolicy.MANAGED_ONLY) {
148             PluginEntry[] managedPlugins = getManagedPlugins();
149             String JavaDoc[] managedPluginsURLs = new String JavaDoc[managedPlugins.length];
150             for (int i=0; i<managedPlugins.length; i++)
151                 managedPluginsURLs[i] = managedPlugins[i].getURL();
152             
153             return managedPluginsURLs;
154         }
155
156         // bad policy type
157
return new String JavaDoc[0];
158     }
159
160     private PluginEntry[] getManagedPlugins() {
161         // Note:
162
// We detect all the plugins on the site, but it would be faster
163
// to just lookup the plugins that correspond to the entries found in each feature.
164
// TODO fix the above
165
if (pluginEntries == null)
166             detectPlugins();
167         if (featureEntries == null)
168             detectFeatures();
169         
170         // cache all the plugin entries for faster lookup later
171
Map JavaDoc cachedPlugins = new HashMap JavaDoc(pluginEntries.size());
172         for (int i=0; i<pluginEntries.size(); i++) {
173             PluginEntry p = (PluginEntry)pluginEntries.get(i);
174             cachedPlugins.put(p.getVersionedIdentifier(), p);
175         }
176         
177         ArrayList JavaDoc managedPlugins = new ArrayList JavaDoc();
178         for (Iterator JavaDoc iterator=featureEntries.values().iterator(); iterator.hasNext();) {
179             Object JavaDoc feature = iterator.next();
180             if (!(feature instanceof FeatureEntry))
181                 continue;
182             
183             PluginEntry[] plugins = ((FeatureEntry)feature).getPluginEntries();
184             for (int i=0; i<plugins.length; i++)
185                 if (cachedPlugins.containsKey(plugins[i].getVersionedIdentifier()))
186                     managedPlugins.add(cachedPlugins.get(plugins[i].getVersionedIdentifier()));
187                     
188         }
189         return (PluginEntry[])managedPlugins.toArray(new PluginEntry[managedPlugins.size()]);
190     }
191     
192     public PluginEntry[] getPluginEntries() {
193         String JavaDoc[] pluginURLs = getPlugins();
194         // hash the array, for faster lookups
195
HashMap JavaDoc map = new HashMap JavaDoc(pluginURLs.length);
196         for (int i=0; i<pluginURLs.length; i++)
197             map.put(pluginURLs[i], pluginURLs[i]);
198         
199         if (pluginEntries == null)
200                 detectPlugins();
201         
202         ArrayList JavaDoc plugins = new ArrayList JavaDoc(pluginURLs.length);
203         for (int i=0; i<pluginEntries.size(); i++) {
204             PluginEntry p = (PluginEntry)pluginEntries.get(i);
205             if (map.containsKey(p.getURL()))
206                 plugins.add(p);
207         }
208         return (PluginEntry[])plugins.toArray(new PluginEntry[plugins.size()]);
209     }
210     
211     /*
212      * @see ISiteEntry#getChangeStamp()
213      */

214     public long getChangeStamp() {
215         if (changeStamp == 0)
216             computeChangeStamp();
217         return changeStamp;
218     }
219
220     /*
221      * @see ISiteEntry#getFeaturesChangeStamp()
222      */

223     public long getFeaturesChangeStamp() {
224         if (featuresChangeStamp == 0)
225             computeFeaturesChangeStamp();
226         return featuresChangeStamp;
227     }
228
229     /*
230      * @see ISiteEntry#getPluginsChangeStamp()
231      */

232     public long getPluginsChangeStamp() {
233         if (pluginsChangeStamp == 0)
234             computePluginsChangeStamp();
235         return pluginsChangeStamp;
236     }
237
238     /*
239      * @see ISiteEntry#isUpdateable()
240      */

241     public boolean isUpdateable() {
242         return updateable;
243     }
244     
245     public void setUpdateable(boolean updateable) {
246         this.updateable = updateable;
247     }
248
249     /*
250      * @see ISiteEntry#isNativelyLinked()
251      */

252     public boolean isNativelyLinked() {
253         return isExternallyLinkedSite();
254     }
255
256     public URL getResolvedURL() {
257         return resolvedURL;
258     }
259     
260     /**
261      * Detect new features (timestamp > current site timestamp)
262      * and validates existing features (they might have been removed)
263      */

264     private void detectFeatures() {
265
266         if (featureEntries != null)
267             validateFeatureEntries();
268         else
269             featureEntries = new HashMap JavaDoc();
270
271         if (!PlatformConfiguration.supportsDetection(resolvedURL))
272             return;
273
274         // locate feature entries on site
275
File siteRoot = new File(resolvedURL.getFile().replace('/', File.separatorChar));
276         File featuresDir = new File(siteRoot, FEATURES);
277         if (featuresDir.exists()) {
278             // handle the installed features under the features directory
279
File[] dirs = featuresDir.listFiles(new FileFilter() {
280                 public boolean accept(File f) {
281                     // mac os folders contain a file .DS_Store in each folder, and we need to skip it (bug 76869)
282
if (isMacOS && f.getName().equals(MAC_OS_MARKER))
283                         return false;
284                     boolean valid = f.isDirectory() && (new File(f,FEATURE_XML).exists());
285                     if (!valid)
286                         Utils.log(NLS.bind(Messages.SiteEntry_cannotFindFeatureInDir, (new String JavaDoc[] { f.getAbsolutePath() })));
287                     return valid;
288                 }
289             });
290         
291             for (int index = 0; index < dirs.length; index++) {
292                 try {
293                     File featureXML = new File(dirs[index], FEATURE_XML);
294                     if (featureXML.lastModified() <= featuresChangeStamp &&
295                         dirs[index].lastModified() <= featuresChangeStamp)
296                         continue;
297                     URL featureURL = featureXML.toURL();
298                     FeatureEntry featureEntry = featureParser.parse(featureURL);
299                     if (featureEntry != null)
300                         addFeatureEntry(featureEntry);
301                 } catch (MalformedURLException e) {
302                     Utils.log(NLS.bind(Messages.InstalledSiteParser_UnableToCreateURLForFile, (new String JavaDoc[] { featuresDir.getAbsolutePath() })));
303                 }
304             }
305         }
306         
307         Utils.debug(resolvedURL.toString() + " located " + featureEntries.size() + " feature(s)"); //$NON-NLS-1$ //$NON-NLS-2$
308
}
309     
310     /**
311      * Detect new plugins (timestamp > current site timestamp)
312      * and validates existing plugins (they might have been removed)
313      */

314     private void detectPlugins() {
315         boolean compareTimeStamps = false;
316         if (pluginEntries != null) {
317             validatePluginEntries();
318             compareTimeStamps = true; // only pick up newer plugins
319
} else
320             pluginEntries = new ArrayList JavaDoc();
321
322         if (!PlatformConfiguration.supportsDetection(resolvedURL))
323             return;
324
325         // locate plugin entries on site
326
File pluginsDir = new File(resolvedURL.getFile(), PLUGINS);
327         
328         if (pluginsDir.exists() && pluginsDir.isDirectory()) {
329             File[] files = pluginsDir.listFiles();
330             for (int i = 0; i < files.length; i++) {
331                 if(files[i].isDirectory()){
332                     detectUnpackedPlugin(files[i], compareTimeStamps);
333                 }else if(files[i].getName().endsWith(".jar")){ //$NON-NLS-1$
334
detectPackedPlugin(files[i], compareTimeStamps);
335                 }else{
336                     // not bundle file
337
}
338             }
339         }
340         
341         Utils.debug(resolvedURL.toString() + " located " + pluginEntries.size() + " plugin(s)"); //$NON-NLS-1$ //$NON-NLS-2$
342
}
343
344     /**
345      * @param file a plugin jar
346      * @param compareTimeStamps set to true when looking for plugins changed since last time they were detected
347      */

348     private void detectPackedPlugin(File file, boolean compareTimeStamps) {
349         // plugin to run directly from jar
350
if (compareTimeStamps && file.lastModified() <= pluginsChangeStamp) {
351             return;
352         }
353         String JavaDoc entryName = META_MANIFEST_MF;
354         ZipFile z = null;
355         InputStream bundleManifestIn = null;
356         InputStream pluginManifestIn = null;
357         String JavaDoc pluginURL = PLUGINS + "/" + file.getName(); //$NON-NLS-1$
358
try {
359             // First, check if has valid bundle manifest
360
z = new ZipFile(file);
361             if (z.getEntry(entryName) != null) {
362                 bundleManifestIn = z.getInputStream(new ZipEntry(entryName));
363                 BundleManifest manifest = new BundleManifest(bundleManifestIn,
364                         pluginURL);
365                 if (manifest.exists()) {
366                     addPluginEntry(manifest.getPluginEntry());
367                     return;
368                 }
369             }
370             // no bundle manifest, check for plugin.xml or fragment.xml
371
entryName = PLUGIN_XML;
372             if (z.getEntry(entryName) == null) {
373                 entryName = FRAGMENT_XML;
374             }
375             if (z.getEntry(entryName) != null) {
376                 pluginManifestIn = z.getInputStream(new ZipEntry(entryName));
377                 PluginEntry entry1 = pluginParser.parse(pluginManifestIn,
378                         pluginURL);
379                 addPluginEntry(entry1);
380             }
381         } catch (IOException e5) {
382             String JavaDoc pluginFileString2 = pluginURL + "!" + entryName; //$NON-NLS-1$
383
Utils.log(NLS.bind(Messages.InstalledSiteParser_ErrorAccessing, (new String JavaDoc[] { pluginFileString2 })));
384         } catch (SAXException e3) {
385             String JavaDoc pluginFileString1 = pluginURL + "!" + entryName; //$NON-NLS-1$
386
Utils.log(NLS.bind(Messages.InstalledSiteParser_ErrorParsingFile, (new String JavaDoc[] { pluginFileString1 })));
387         } finally {
388             if (bundleManifestIn != null) {
389                 try {
390                     bundleManifestIn.close();
391                 } catch (IOException e4) {
392                 }
393             }
394             if (pluginManifestIn != null) {
395                 try {
396                     pluginManifestIn.close();
397                 } catch (IOException e2) {
398                 }
399             }
400             if (z != null) {
401                 try {
402                     z.close();
403                 } catch (IOException e1) {
404                 }
405             }
406         }
407     }
408     /**
409      * @param file a plugin directory
410      * @param compareTimeStamps set to true when looking for plugins changed since last time they were detected
411      */

412     private void detectUnpackedPlugin(File file, boolean compareTimeStamps) {
413         // unpacked plugin
414
long dirTimestamp = file.lastModified();
415         File pluginFile = new File(file, META_MANIFEST_MF);
416         try {
417             // First, check if has valid bundle manifest
418
BundleManifest bundleManifest = new BundleManifest(pluginFile);
419             if (bundleManifest.exists()) {
420                 if (compareTimeStamps
421                         && dirTimestamp <= pluginsChangeStamp
422                         && pluginFile.lastModified() <= pluginsChangeStamp)
423                     return;
424                 PluginEntry entry = bundleManifest.getPluginEntry();
425                 addPluginEntry(entry);
426             } else {
427                 // no bundle manifest, check for plugin.xml or fragment.xml
428
pluginFile = new File(file, PLUGIN_XML);
429                 if (!pluginFile.exists()) {
430                     pluginFile = new File(file, FRAGMENT_XML);
431                 }
432                 if (pluginFile.exists() && !pluginFile.isDirectory()) {
433                     // TODO in the future, assume that the timestamps are not
434
// reliable,
435
// or that the user manually modified an existing plugin,
436
// so
437
// the apparently modifed plugin may actually be configured
438
// already.
439
// We will need to double check for this. END to do.
440
if (compareTimeStamps
441                             && dirTimestamp <= pluginsChangeStamp
442                             && pluginFile.lastModified() <= pluginsChangeStamp)
443                         return;
444                     PluginEntry entry = pluginParser.parse(pluginFile);
445                     addPluginEntry(entry);
446                 }
447             }
448         } catch (IOException e) {
449             String JavaDoc pluginFileString = pluginFile.getAbsolutePath();
450             if (ConfigurationActivator.DEBUG)
451                 Utils.log(Utils.newStatus(NLS.bind(Messages.InstalledSiteParser_ErrorParsingFile, (new String JavaDoc[] { pluginFileString })), e));
452             else
453                 Utils.log(NLS.bind(Messages.InstalledSiteParser_ErrorAccessing, (new String JavaDoc[] { pluginFileString })));
454         } catch (SAXException e) {
455             String JavaDoc pluginFileString = pluginFile.getAbsolutePath();
456             Utils.log(NLS.bind(Messages.InstalledSiteParser_ErrorParsingFile, (new String JavaDoc[] { pluginFileString })));
457         }
458     }
459
460     /**
461      * @return list of feature url's (relative to site)
462      */

463     private synchronized String JavaDoc[] getDetectedFeatures() {
464         if (featureEntries == null)
465             detectFeatures();
466         String JavaDoc[] features = new String JavaDoc[featureEntries.size()];
467         Iterator JavaDoc iterator = featureEntries.values().iterator();
468         for (int i=0; i<features.length; i++)
469             features[i] = ((FeatureEntry)iterator.next()).getURL();
470         return features;
471     }
472
473     /**
474      * @return list of plugin url's (relative to site)
475      */

476     private synchronized String JavaDoc[] getDetectedPlugins() {
477         if (pluginEntries == null)
478             detectPlugins();
479         
480         String JavaDoc[] plugins = new String JavaDoc[pluginEntries.size()];
481         for (int i=0; i<plugins.length; i++)
482             plugins[i] = ((PluginEntry)pluginEntries.get(i)).getURL();
483         return plugins;
484     }
485
486     private void computeChangeStamp() {
487         changeStamp = Math.max(computeFeaturesChangeStamp(), computePluginsChangeStamp());
488 // changeStampIsValid = true;
489
}
490
491     private synchronized long computeFeaturesChangeStamp() {
492         if (featuresChangeStamp > 0)
493             return featuresChangeStamp;
494         
495         long start = 0;
496         if (ConfigurationActivator.DEBUG)
497             start = (new Date JavaDoc()).getTime();
498         String JavaDoc[] features = getFeatures();
499     
500         // compute stamp for the features directory
501
long dirStamp = 0;
502         if (PlatformConfiguration.supportsDetection(resolvedURL)) {
503             File root = new File(resolvedURL.getFile().replace('/', File.separatorChar));
504             File featuresDir = new File(root, FEATURES);
505             dirStamp = featuresDir.lastModified();
506         }
507         featuresChangeStamp = Math.max(dirStamp, computeStamp(features));
508         if (ConfigurationActivator.DEBUG) {
509             long end = (new Date JavaDoc()).getTime();
510             Utils.debug(resolvedURL.toString() + " feature stamp: " + featuresChangeStamp + " in " + (end - start) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
511
}
512         return featuresChangeStamp;
513     }
514
515     private synchronized long computePluginsChangeStamp() {
516         if (pluginsChangeStamp > 0)
517             return pluginsChangeStamp;
518         
519         if (!PlatformConfiguration.supportsDetection(resolvedURL)) {
520             Utils.log(NLS.bind(Messages.SiteEntry_computePluginStamp, (new String JavaDoc[] { resolvedURL.toExternalForm() })));
521             return 0;
522         }
523
524         // compute stamp for the plugins directory
525
File root = new File(resolvedURL.getFile().replace('/', File.separatorChar));
526         File pluginsDir = new File(root, PLUGINS);
527         if (!pluginsDir.exists() || !pluginsDir.isDirectory()) {
528             Utils.log(NLS.bind(Messages.SiteEntry_pluginsDir, (new String JavaDoc[] { pluginsDir.getAbsolutePath() })));
529             return 0;
530         }
531
532         pluginsChangeStamp = pluginsDir.lastModified();
533         return pluginsChangeStamp;
534     }
535
536     private long computeStamp(String JavaDoc[] targets) {
537
538         long result = 0;
539         if (!PlatformConfiguration.supportsDetection(resolvedURL)) {
540             // NOTE: this path should not be executed until we support running
541
// from an arbitrary URL (in particular from http server). For
542
// now just compute stamp across the list of names. Eventually
543
// when general URLs are supported we need to do better (factor
544
// in at least the existence of the target). However, given this
545
// code executes early on the startup sequence we need to be
546
// extremely mindful of performance issues.
547
// In fact, we should get the last modified from the connection
548
for (int i = 0; i < targets.length; i++)
549                 result ^= targets[i].hashCode();
550             Utils.debug("*WARNING* computing stamp using URL hashcodes only"); //$NON-NLS-1$
551
} else {
552             // compute stamp across local targets
553
File rootFile = new File(resolvedURL.getFile().replace('/', File.separatorChar));
554             if (rootFile.exists()) {
555                 File f = null;
556                 for (int i = 0; i < targets.length; i++) {
557                     f = new File(rootFile, targets[i]);
558                     if (f.exists())
559                         result = Math.max(result, f.lastModified());
560                 }
561             }
562         }
563
564         return result;
565     }
566     
567     public void setLinkFileName(String JavaDoc linkFileName) {
568         this.linkFileName = linkFileName;
569     }
570     
571     public String JavaDoc getLinkFileName() {
572         return linkFileName;
573     }
574
575     public boolean isExternallyLinkedSite() {
576         return (linkFileName != null && !linkFileName.trim().equals("")); //$NON-NLS-1$
577
}
578
579     public synchronized void refresh() {
580         // reset computed values. Will be updated on next access.
581
featuresChangeStamp = 0;
582         pluginsChangeStamp = 0;
583         changeStamp = 0;
584         featureEntries = null;
585         pluginEntries = null;
586     }
587     
588     public void refreshPlugins() {
589         // reset computed values. Will be updated on next access.
590
pluginsChangeStamp = 0;
591         changeStamp = 0;
592         pluginEntries = null;
593     }
594     
595     public void addFeatureEntry(IFeatureEntry feature) {
596         if (featureEntries == null)
597             featureEntries = new HashMap JavaDoc();
598         // Make sure we keep the larger version of same feature
599
IFeatureEntry existing = (FeatureEntry)featureEntries.get(feature.getFeatureIdentifier());
600         if (existing != null) {
601             VersionedIdentifier existingVersion = new VersionedIdentifier(existing.getFeatureIdentifier(), existing.getFeatureVersion());
602             VersionedIdentifier newVersion = new VersionedIdentifier(feature.getFeatureIdentifier(), feature.getFeatureVersion());
603             if (existingVersion.getVersion().compareTo(newVersion.getVersion()) < 0) {
604                 featureEntries.put(feature.getFeatureIdentifier(), feature);
605                 pluginsChangeStamp = 0;
606             } else if (existingVersion.equals(newVersion)) {
607                 // log error if same feature version/id but a different url
608
if (feature instanceof FeatureEntry && existing instanceof FeatureEntry &&
609                         !((FeatureEntry)feature).getURL().equals(((FeatureEntry)existing).getURL()))
610                 Utils.log(NLS.bind(Messages.SiteEntry_duplicateFeature, (new String JavaDoc[] { getURL().toExternalForm(), existing.getFeatureIdentifier() })));
611             }
612         } else {
613             featureEntries.put(feature.getFeatureIdentifier(), feature);
614             pluginsChangeStamp = 0;
615         }
616         if (feature instanceof FeatureEntry)
617             ((FeatureEntry)feature).setSite(this);
618     }
619     
620     public FeatureEntry[] getFeatureEntries() {
621         if (featureEntries == null)
622             detectFeatures();
623         
624         if (featureEntries == null)
625             return new FeatureEntry[0];
626         return (FeatureEntry[])featureEntries.values().toArray(new FeatureEntry[featureEntries.size()]);
627     }
628     
629     public void addPluginEntry(PluginEntry plugin) {
630         if (pluginEntries == null)
631             pluginEntries = new ArrayList JavaDoc();
632         // Note: we could use the latest version of the same plugin, like we do for features, but we let the runtime figure it out
633
pluginEntries.add(plugin);
634     }
635     
636     public PluginEntry[] getAllPluginEntries() {
637         if (pluginEntries == null)
638             detectPlugins();
639         return (PluginEntry[])pluginEntries.toArray(new PluginEntry[pluginEntries.size()]);
640     }
641     
642     public void loadFromDisk(long lastChange) throws CoreException{
643         featuresChangeStamp = lastChange;
644         pluginsChangeStamp = lastChange;
645         detectFeatures();
646         detectPlugins();
647     }
648     
649     /**
650      * Saves state as xml content in a given parent element
651      * @param doc
652      */

653     public Element toXML(Document doc) {
654
655         Element siteElement = doc.createElement(CFG_SITE);
656         
657         if (getURL() != null) {
658             URL toPersist = (config == null || config.isTransient()) ? getURL() : Utils.makeRelative(Utils.getInstallURL(), getURL());
659             siteElement.setAttribute(CFG_URL, toPersist.toString());
660         }
661         
662         siteElement.setAttribute(CFG_ENABLED, isEnabled() ? "true" : "false"); //$NON-NLS-1$ //$NON-NLS-2$
663
siteElement.setAttribute(CFG_UPDATEABLE, isUpdateable() ? "true" : "false"); //$NON-NLS-1$ //$NON-NLS-2$
664
if (isExternallyLinkedSite())
665             siteElement.setAttribute(CFG_LINK_FILE, getLinkFileName().trim().replace(File.separatorChar, '/'));
666
667         int type = getSitePolicy().getType();
668         String JavaDoc typeString = CFG_POLICY_TYPE_UNKNOWN;
669         try {
670             typeString = CFG_POLICY_TYPE[type];
671         } catch (IndexOutOfBoundsException JavaDoc e) {
672             // ignore bad attribute ...
673
}
674         siteElement.setAttribute(CFG_POLICY, typeString);
675         String JavaDoc[] list = getSitePolicy().getList();
676         if (list.length > 0) {
677             StringBuffer JavaDoc sb = new StringBuffer JavaDoc(256);
678             for (int i=0; i<list.length-1; i++) {
679                 sb.append(list[i]);
680                 sb.append(',');
681             }
682             sb.append(list[list.length-1]);
683             siteElement.setAttribute(CFG_LIST, sb.toString());
684         }
685 // // note: we don't save features inside the site element.
686

687         // collect feature entries
688
// configElement.setAttribute(CFG_FEATURE_ENTRY_DEFAULT, defaultFeature);
689
FeatureEntry[] feats = getFeatureEntries();
690         for (int i = 0; i < feats.length; i++) {
691             Element featureElement = feats[i].toXML(doc);
692             siteElement.appendChild(featureElement);
693         }
694         
695         return siteElement;
696     }
697     
698     private void validateFeatureEntries() {
699         File root = new File(resolvedURL.getFile().replace('/', File.separatorChar));
700         Iterator JavaDoc iterator = featureEntries.values().iterator();
701         Collection JavaDoc deletedFeatures = new ArrayList JavaDoc();
702         while(iterator.hasNext()) {
703             FeatureEntry feature = (FeatureEntry)iterator.next();
704             // Note: in the future, we can check for absolute url as well.
705
// For now, feature url is features/org.eclipse.foo/feature.xml
706
File featureXML = new File(root, feature.getURL());
707             if (!featureXML.exists())
708                 deletedFeatures.add(feature.getFeatureIdentifier());
709         }
710         for(Iterator JavaDoc it=deletedFeatures.iterator(); it.hasNext();){
711             featureEntries.remove(it.next());
712         }
713     }
714     
715     private void validatePluginEntries() {
716         File root = new File(resolvedURL.getFile().replace('/', File.separatorChar));
717         Collection JavaDoc deletedPlugins = new ArrayList JavaDoc();
718         for (int i=0; i<pluginEntries.size(); i++) {
719             PluginEntry plugin = (PluginEntry)pluginEntries.get(i);
720             // Note: in the future, we can check for absolute url as well.
721
// For now, feature url is plugins/org.eclipse.foo/plugin.xml
722
File pluginLocation = new File(root, plugin.getURL());
723             if (!pluginLocation.exists())
724                 deletedPlugins.add(plugin);
725         }
726         for(Iterator JavaDoc it=deletedPlugins.iterator(); it.hasNext();){
727             pluginEntries.remove(it.next());
728         }
729     }
730     
731     public boolean isEnabled() {
732         return enabled;
733     }
734     
735     public void setEnabled(boolean enable) {
736         this.enabled = enable;
737     }
738     
739     public FeatureEntry getFeatureEntry(String JavaDoc id) {
740         FeatureEntry[] features = getFeatureEntries();
741         for (int i=0; i<features.length; i++)
742             if (features[i].getFeatureIdentifier().equals(id))
743                 return features[i];
744         return null;
745     }
746     
747     
748     public boolean unconfigureFeatureEntry(IFeatureEntry feature) {
749         FeatureEntry existingFeature = getFeatureEntry(feature.getFeatureIdentifier());
750         if (existingFeature != null)
751             featureEntries.remove(existingFeature.getFeatureIdentifier());
752         return existingFeature != null;
753     }
754     
755     /*
756      * This is a bit of a hack.
757      * When no features were added to the site, but the site is initialized from platform.xml
758      * we need to set the feature set to empty, so we don't try to detect them.
759      */

760     void initialized() {
761         if (featureEntries == null)
762             featureEntries = new HashMap JavaDoc();
763     }
764 }
765
Popular Tags