KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > pde > internal > build > site > PDEState


1 /*******************************************************************************
2  * Copyright (c) 2004, 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 - Initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.pde.internal.build.site;
12
13 import java.io.*;
14 import java.net.URL JavaDoc;
15 import java.util.*;
16 import java.util.jar.JarFile JavaDoc;
17 import java.util.zip.ZipEntry JavaDoc;
18 import java.util.zip.ZipFile JavaDoc;
19 import org.eclipse.core.runtime.*;
20 import org.eclipse.osgi.service.pluginconversion.PluginConversionException;
21 import org.eclipse.osgi.service.pluginconversion.PluginConverter;
22 import org.eclipse.osgi.service.resolver.*;
23 import org.eclipse.osgi.util.ManifestElement;
24 import org.eclipse.osgi.util.NLS;
25 import org.eclipse.pde.internal.build.*;
26 import org.osgi.framework.*;
27
28 // This class provides a higher level API on the state
29
public class PDEState implements IPDEBuildConstants, IBuildPropertiesConstants {
30     private static final String JavaDoc PROFILE_EXTENSION = ".profile"; //$NON-NLS-1$
31
private static final String JavaDoc SYSTEM_PACKAGES = "org.osgi.framework.system.packages"; //$NON-NLS-1$
32

33     private StateObjectFactory factory;
34     protected State state;
35     private long id;
36     private Properties repositoryVersions;
37     private HashMap bundleClasspaths;
38     private Map patchBundles;
39     private List addedBundle;
40     private List unqualifiedBundles; //All the bundle description objects that have .qualifier in them
41
private Dictionary platformProperties;
42     private List sortedBundles = null;
43     private long lastSortingDate = 0L;
44     
45     private String JavaDoc javaProfile;
46     private String JavaDoc[] javaProfiles;
47
48     protected long getNextId() {
49         return ++id;
50     }
51
52     public PDEState(PDEUIStateWrapper initialState) {
53         this();
54         state = initialState.getState();
55         factory = state.getFactory();
56         id = initialState.getNextId();
57         bundleClasspaths = initialState.getClasspaths();
58         patchBundles = initialState.getPatchData();
59         addedBundle = new ArrayList();
60         unqualifiedBundles = new ArrayList();
61         forceQualifiers();
62     }
63
64     public PDEState() {
65         factory = Platform.getPlatformAdmin().getFactory();
66         state = factory.createState();
67         state.setResolver(Platform.getPlatformAdmin().getResolver());
68         id = 0;
69         bundleClasspaths = new HashMap();
70         patchBundles = new HashMap();
71         loadPluginTagFile();
72     }
73
74     public StateObjectFactory getFactory() {
75         return factory;
76     }
77
78     public boolean addBundleDescription(BundleDescription toAdd) {
79         return state.addBundle(toAdd);
80     }
81
82     private PluginConverter acquirePluginConverter() throws Exception JavaDoc {
83         return (PluginConverter) BundleHelper.getDefault().acquireService(PluginConverter.class.getName());
84     }
85
86     //Add a bundle to the state, updating the version number
87
public boolean addBundle(Dictionary enhancedManifest, File JavaDoc bundleLocation) {
88         updateVersionNumber(enhancedManifest);
89         try {
90             BundleDescription descriptor;
91             descriptor = factory.createBundleDescription(state, enhancedManifest, bundleLocation.getAbsolutePath(), getNextId());
92             bundleClasspaths.put(new Long JavaDoc(descriptor.getBundleId()), getClasspath(enhancedManifest));
93             String JavaDoc patchValue = fillPatchData(enhancedManifest);
94             if (patchValue != null)
95                 patchBundles.put(new Long JavaDoc(descriptor.getBundleId()), patchValue);
96             rememberQualifierTagPresence(descriptor);
97             if (addBundleDescription(descriptor) == true && addedBundle != null)
98                 addedBundle.add(descriptor);
99         } catch (BundleException e) {
100             IStatus status = new Status(IStatus.WARNING, IPDEBuildConstants.PI_PDEBUILD, EXCEPTION_STATE_PROBLEM, NLS.bind(Messages.exception_stateAddition, enhancedManifest.get(Constants.BUNDLE_NAME)), e);
101             BundleHelper.getDefault().getLog().log(status);
102             return false;
103         }
104         return true;
105     }
106
107     private void rememberQualifierTagPresence(BundleDescription descriptor) {
108         Properties bundleProperties = null;
109         bundleProperties = (Properties) descriptor.getUserObject();
110         if (bundleProperties == null) {
111             bundleProperties = new Properties();
112             descriptor.setUserObject(bundleProperties);
113         }
114         bundleProperties.setProperty(PROPERTY_QUALIFIER, "marker"); //$NON-NLS-1$
115
}
116
117     private void mapVersionReplacedBundle(BundleDescription oldBundle, BundleDescription newBundle ) {
118         Properties bundleProperties = null;
119         bundleProperties = (Properties) oldBundle.getUserObject();
120         if (bundleProperties == null) {
121             bundleProperties = new Properties();
122             oldBundle.setUserObject(bundleProperties);
123         }
124         bundleProperties.setProperty(PROPERTY_VERSION_REPLACEMENT, String.valueOf(newBundle.getBundleId()));
125     }
126     
127     private String JavaDoc[] getClasspath(Dictionary manifest) {
128         String JavaDoc fullClasspath = (String JavaDoc) manifest.get(Constants.BUNDLE_CLASSPATH);
129         String JavaDoc[] result = new String JavaDoc[0];
130         try {
131             if (fullClasspath != null) {
132                 ManifestElement[] classpathEntries;
133                 classpathEntries = ManifestElement.parseHeader(Constants.BUNDLE_CLASSPATH, fullClasspath);
134                 result = new String JavaDoc[classpathEntries.length];
135                 for (int i = 0; i < classpathEntries.length; i++) {
136                     result[i] = classpathEntries[i].getValue();
137                 }
138             }
139         } catch (BundleException e) {
140             //Ignore
141
}
142         return result;
143     }
144
145     private String JavaDoc fillPatchData(Dictionary manifest) {
146         if (manifest.get("Eclipse-ExtensibleAPI") != null) { //$NON-NLS-1$
147
return "Eclipse-ExtensibleAPI: true"; //$NON-NLS-1$
148
}
149
150         if (manifest.get("Eclipse-PatchFragment") != null) { //$NON-NLS-1$
151
return "Eclipse-PatchFragment: true"; //$NON-NLS-1$
152
}
153         return null;
154     }
155
156     private void loadPluginTagFile() {
157         repositoryVersions = new Properties();
158         try {
159             InputStream input = new BufferedInputStream(new FileInputStream(AbstractScriptGenerator.getWorkingDirectory() + '/' + DEFAULT_PLUGIN_REPOTAG_FILENAME_DESCRIPTOR));
160             try {
161                 repositoryVersions.load(input);
162             } finally {
163                 input.close();
164             }
165         } catch (IOException e) {
166             //Ignore
167
}
168     }
169
170     public boolean addBundle(File JavaDoc bundleLocation) {
171         Dictionary manifest;
172         manifest = loadManifest(bundleLocation);
173         if (manifest == null)
174             return false;
175         try {
176             hasQualifier(bundleLocation, manifest);
177         } catch (BundleException e) {
178             //should not happen since we know the header
179
}
180         return addBundle(manifest, bundleLocation);
181     }
182
183     private void updateVersionNumber(Dictionary manifest) {
184         String JavaDoc newVersion = null;
185         try {
186             String JavaDoc symbolicName = (String JavaDoc) manifest.get(Constants.BUNDLE_SYMBOLICNAME);
187             if (symbolicName == null)
188                 return;
189
190             symbolicName = ManifestElement.parseHeader(Constants.BUNDLE_SYMBOLICNAME, symbolicName)[0].getValue();
191             newVersion = QualifierReplacer.replaceQualifierInVersion((String JavaDoc) manifest.get(Constants.BUNDLE_VERSION), symbolicName, (String JavaDoc) manifest.get(PROPERTY_QUALIFIER), repositoryVersions);
192         } catch (BundleException e) {
193             //ignore
194
}
195         if (newVersion != null)
196             manifest.put(Constants.BUNDLE_VERSION, newVersion);
197     }
198
199     /**
200      * @param bundleLocation
201      * @param manifest
202      * @throws BundleException
203      */

204     private void hasQualifier(File JavaDoc bundleLocation, Dictionary manifest) throws BundleException {
205         ManifestElement[] versionInfo = ManifestElement.parseHeader(Constants.BUNDLE_VERSION, (String JavaDoc) manifest.get(Constants.BUNDLE_VERSION));
206         if (versionInfo != null) {
207             if (versionInfo[0].getValue().endsWith(PROPERTY_QUALIFIER)) {
208                 manifest.put(PROPERTY_QUALIFIER, getQualifierPropery(bundleLocation.getAbsolutePath()));
209             }
210         }
211     }
212
213     private String JavaDoc getQualifierPropery(String JavaDoc bundleLocation) {
214         String JavaDoc qualifierInfo = null;
215         try {
216             qualifierInfo = AbstractScriptGenerator.readProperties(bundleLocation, IPDEBuildConstants.PROPERTIES_FILE, IStatus.INFO).getProperty(PROPERTY_QUALIFIER);
217         } catch (CoreException e) {
218             //ignore
219
}
220         if (qualifierInfo == null)
221             qualifierInfo = PROPERTY_CONTEXT;
222         return qualifierInfo;
223     }
224
225     //Return a dictionary representing a manifest. The data may result from plugin.xml conversion
226
private Dictionary basicLoadManifest(File JavaDoc bundleLocation) {
227         InputStream manifestStream = null;
228         ZipFile JavaDoc jarFile = null;
229         try {
230             if ("jar".equalsIgnoreCase(new Path(bundleLocation.getName()).getFileExtension()) && bundleLocation.isFile()) { //$NON-NLS-1$
231
jarFile = new ZipFile JavaDoc(bundleLocation, ZipFile.OPEN_READ);
232                 ZipEntry JavaDoc manifestEntry = jarFile.getEntry(JarFile.MANIFEST_NAME);
233                 if (manifestEntry != null) {
234                     manifestStream = jarFile.getInputStream(manifestEntry);
235                 }
236             } else {
237                 manifestStream = new BufferedInputStream(new FileInputStream(new File JavaDoc(bundleLocation, JarFile.MANIFEST_NAME)));
238             }
239         } catch (IOException e) {
240             //ignore
241
}
242
243         //It is not a manifest, but a plugin or a fragment
244
if (manifestStream == null)
245             return convertPluginManifest(bundleLocation, true);
246
247         try {
248             Hashtable result = new Hashtable();
249             result.putAll(ManifestElement.parseBundleManifest(manifestStream, null));
250             return result;
251         } catch (IOException ioe) {
252             return null;
253         } catch (BundleException e) {
254             return null;
255         } finally {
256             try {
257                 manifestStream.close();
258             } catch (IOException e1) {
259                 //Ignore
260
}
261             try {
262                 if (jarFile != null)
263                     jarFile.close();
264             } catch (IOException e2) {
265                 //Ignore
266
}
267         }
268     }
269
270     private void enforceSymbolicName(File JavaDoc bundleLocation, Dictionary initialManifest) {
271         if (initialManifest.get(Constants.BUNDLE_SYMBOLICNAME) != null)
272             return;
273
274         Dictionary generatedManifest = convertPluginManifest(bundleLocation, false);
275         if (generatedManifest == null)
276             return;
277
278         //merge manifests. The values from the generated manifest are added to the initial one. Values from the initial one are not deleted
279
Enumeration enumeration = generatedManifest.keys();
280         while (enumeration.hasMoreElements()) {
281             Object JavaDoc key = enumeration.nextElement();
282             if (initialManifest.get(key) == null)
283                 initialManifest.put(key, generatedManifest.get(key));
284         }
285     }
286
287     private void enforceClasspath(Dictionary manifest) {
288         String JavaDoc classpath = (String JavaDoc) manifest.get(Constants.BUNDLE_CLASSPATH);
289         if (classpath == null)
290             manifest.put(Constants.BUNDLE_CLASSPATH, "."); //$NON-NLS-1$
291
}
292
293     private Dictionary loadManifest(File JavaDoc bundleLocation) {
294         Dictionary manifest = basicLoadManifest(bundleLocation);
295         if (manifest == null)
296             return null;
297
298         enforceSymbolicName(bundleLocation, manifest);
299         enforceClasspath(manifest);
300         return manifest;
301     }
302
303     private Dictionary convertPluginManifest(File JavaDoc bundleLocation, boolean logConversionException) {
304         PluginConverter converter;
305         try {
306             converter = acquirePluginConverter();
307             return converter.convertManifest(bundleLocation, false, AbstractScriptGenerator.isBuildingOSGi() ? null : "2.1", false, null); //$NON-NLS-1$
308
} catch (PluginConversionException convertException) {
309             if (bundleLocation.getName().equals(org.eclipse.pde.build.Constants.FEATURE_FILENAME_DESCRIPTOR))
310                 return null;
311             if (!new File JavaDoc(bundleLocation, org.eclipse.pde.build.Constants.PLUGIN_FILENAME_DESCRIPTOR).exists() && !new File JavaDoc(bundleLocation, org.eclipse.pde.build.Constants.FRAGMENT_FILENAME_DESCRIPTOR).exists())
312                 return null;
313             if (logConversionException) {
314                 IStatus status = new Status(IStatus.WARNING, PI_PDEBUILD, 0, NLS.bind(Messages.exception_errorConverting, bundleLocation.getAbsolutePath()), convertException);
315                 BundleHelper.getDefault().getLog().log(status);
316             }
317             return null;
318         } catch (Exception JavaDoc serviceException) {
319             IStatus status = new Status(IStatus.WARNING, PI_PDEBUILD, 0, NLS.bind(Messages.exception_cannotAcquireService, "Plugin converter"), serviceException); //$NON-NLS-1$
320
BundleHelper.getDefault().getLog().log(status);
321             return null;
322         }
323     }
324
325     public void addBundles(Collection bundles) {
326         for (Iterator iter = bundles.iterator(); iter.hasNext();) {
327             File JavaDoc bundle = (File JavaDoc) iter.next();
328             addBundle(bundle);
329         }
330     }
331
332     public void resolveState() {
333         List configs = AbstractScriptGenerator.getConfigInfos();
334         Dictionary[] properties = new Dictionary[configs.size()];
335
336         // Set the JRE profile
337
String JavaDoc systemPackages = null;
338         String JavaDoc ee = null;
339         if (javaProfile == null)
340             javaProfile = getDefaultJavaProfile();
341         Properties profileProps = getJavaProfileProperties();
342         if (profileProps != null) {
343             systemPackages = profileProps.getProperty(SYSTEM_PACKAGES);
344             ee = profileProps.getProperty(Constants.FRAMEWORK_EXECUTIONENVIRONMENT);
345         }
346
347         int i = 0;
348         for (Iterator iter = configs.iterator(); iter.hasNext(); i++) {
349             Config aConfig = (Config) iter.next();
350             Dictionary prop = new Hashtable();
351             if (AbstractScriptGenerator.getPropertyAsBoolean(IBuildPropertiesConstants.RESOLVER_DEV_MODE))
352                 prop.put(PROPERTY_RESOLVER_MODE, VALUE_DEVELOPMENT);
353             String JavaDoc os = aConfig.getOs();
354             String JavaDoc ws = aConfig.getWs();
355             String JavaDoc arch = aConfig.getArch();
356             if (Config.ANY.equalsIgnoreCase(os))
357                 prop.put(OSGI_OS, CatchAllValue.singleton);
358             else
359                 prop.put(OSGI_OS, os);
360
361             if (Config.ANY.equalsIgnoreCase(ws))
362                 prop.put(OSGI_WS, CatchAllValue.singleton);
363             else
364                 prop.put(OSGI_WS, ws);
365
366             if (Config.ANY.equalsIgnoreCase(arch))
367                 prop.put(OSGI_ARCH, CatchAllValue.singleton);
368             else
369                 prop.put(OSGI_ARCH, arch);
370
371             // Set the JRE profile
372
if (systemPackages != null)
373                 prop.put(SYSTEM_PACKAGES, systemPackages);
374             if (ee != null)
375                 prop.put(Constants.FRAMEWORK_EXECUTIONENVIRONMENT, ee);
376
377             // check the user-specified platform properties
378
if (platformProperties != null) {
379                 for (Enumeration e = platformProperties.keys(); e.hasMoreElements();) {
380                     String JavaDoc key = (String JavaDoc) e.nextElement();
381                     prop.put(key, platformProperties.get(key));
382                 }
383             }
384
385             properties[i] = prop;
386         }
387         state.setPlatformProperties(properties);
388         state.resolve(false);
389     }
390
391     private String JavaDoc getDefaultJavaProfile() {
392         if (javaProfiles == null)
393             setJavaProfiles(getOSGiLocation());
394         if (javaProfiles != null && javaProfiles.length > 0)
395             return javaProfiles[0];
396         return null;
397     }
398
399     public State getState() {
400         return state;
401     }
402
403     public BundleDescription[] getDependentBundles(String JavaDoc bundleId, Version version) {
404         BundleDescription root = state.getBundle(bundleId, version);
405         return getDependentBundles(root);
406     }
407
408     /**
409      * This methods return the bundleDescriptions to which imports have been
410      * bound to.
411      *
412      * @param root
413      */

414     public static BundleDescription[] getImportedBundles(BundleDescription root) {
415         if (root == null)
416             return new BundleDescription[0];
417         ExportPackageDescription[] packages = root.getResolvedImports();
418         ArrayList resolvedImports = new ArrayList(packages.length);
419         for (int i = 0; i < packages.length; i++)
420             if (!root.getLocation().equals(packages[i].getExporter().getLocation()) && !resolvedImports.contains(packages[i].getExporter()))
421                 resolvedImports.add(packages[i].getExporter());
422         return (BundleDescription[]) resolvedImports.toArray(new BundleDescription[resolvedImports.size()]);
423     }
424
425     /**
426      * This methods return the bundleDescriptions to which required bundles
427      * have been bound to.
428      *
429      * @param root
430      */

431     public static BundleDescription[] getRequiredBundles(BundleDescription root) {
432         if (root == null)
433             return new BundleDescription[0];
434         return root.getResolvedRequires();
435     }
436
437     public BundleDescription getResolvedBundle(String JavaDoc bundleId, String JavaDoc version) {
438         return getBundle(bundleId, version, true);
439     }
440     
441     public BundleDescription getBundle(String JavaDoc bundleId, String JavaDoc version, boolean resolved) {
442         if (IPDEBuildConstants.GENERIC_VERSION_NUMBER.equals(version) || version == null) {
443             BundleDescription bundle = getResolvedBundle(bundleId);
444             if(bundle == null && !resolved)
445                 bundle = getState().getBundle(bundleId, null);
446             return bundle;
447         }
448         Version parsedVersion = Version.parseVersion(version);
449         BundleDescription description = getState().getBundle(bundleId, parsedVersion);
450         if (description != null && (!resolved || description.isResolved()))
451             return description;
452
453         int qualifierIdx = -1;
454         if ((qualifierIdx = parsedVersion.getQualifier().indexOf(IBuildPropertiesConstants.PROPERTY_QUALIFIER)) != -1) {
455             BundleDescription[] bundles = getState().getBundles(bundleId);
456
457             String JavaDoc qualifierPrefix = qualifierIdx > 0 ? parsedVersion.getQualifier().substring(0, qualifierIdx - 1) : ""; //$NON-NLS-1$
458

459             for (int i = 0; i < bundles.length; i++) {
460                 Version bundleVersion = bundles[i].getVersion();
461                 if (bundleVersion.getMajor() == parsedVersion.getMajor() && bundleVersion.getMinor() == parsedVersion.getMinor() && bundleVersion.getMicro() >= parsedVersion.getMicro() && bundleVersion.getQualifier().compareTo(qualifierPrefix) >= 0)
462                     return bundles[i];
463             }
464         }
465         return null;
466     }
467
468     public BundleDescription getResolvedBundle(String JavaDoc bundleId) {
469         BundleDescription[] description = getState().getBundles(bundleId);
470         if (description == null)
471             return null;
472         for (int i = 0; i < description.length; i++) {
473             if (description[i].isResolved())
474                 return description[i];
475         }
476         return null;
477     }
478
479     public static BundleDescription[] getDependentBundles(BundleDescription root) {
480         BundleDescription[] imported = getImportedBundles(root);
481         BundleDescription[] required = getRequiredBundles(root);
482         BundleDescription[] dependents = new BundleDescription[imported.length + required.length];
483         System.arraycopy(imported, 0, dependents, 0, imported.length);
484         System.arraycopy(required, 0, dependents, imported.length, required.length);
485         return dependents;
486     }
487
488     public static BundleDescription[] getDependentBundlesWithFragments(BundleDescription root) {
489         BundleDescription[] imported = getImportedBundles(root);
490         BundleDescription[] importedByFragments = getImportedByFragments(root);
491         BundleDescription[] required = getRequiredBundles(root);
492         BundleDescription[] requiredByFragments = getRequiredByFragments(root);
493         BundleDescription[] dependents = new BundleDescription[imported.length + importedByFragments.length + required.length + requiredByFragments.length];
494         System.arraycopy(imported, 0, dependents, 0, imported.length);
495         System.arraycopy(importedByFragments, 0, dependents, imported.length, importedByFragments.length);
496         System.arraycopy(required, 0, dependents, imported.length + importedByFragments.length, required.length);
497         System.arraycopy(requiredByFragments, 0, dependents, imported.length + importedByFragments.length + required.length, requiredByFragments.length);
498         return dependents;
499     }
500
501     public static BundleDescription[] getImportedByFragments(BundleDescription root) {
502         BundleDescription[] fragments = root.getFragments();
503         List importedByFragments = new ArrayList();
504         for (int i = 0; i < fragments.length; i++) {
505             if (!fragments[i].isResolved())
506                 continue;
507             merge(importedByFragments, getImportedBundles(fragments[i]));
508         }
509         BundleDescription[] result = new BundleDescription[importedByFragments.size()];
510         return (BundleDescription[]) importedByFragments.toArray(result);
511     }
512
513     public static BundleDescription[] getRequiredByFragments(BundleDescription root) {
514         BundleDescription[] fragments = root.getFragments();
515         List importedByFragments = new ArrayList();
516         for (int i = 0; i < fragments.length; i++) {
517             if (!fragments[i].isResolved())
518                 continue;
519             merge(importedByFragments, getRequiredBundles(fragments[i]));
520         }
521         BundleDescription[] result = new BundleDescription[importedByFragments.size()];
522         return (BundleDescription[]) importedByFragments.toArray(result);
523     }
524
525     public static void merge(List source, BundleDescription[] toAdd) {
526         for (int i = 0; i < toAdd.length; i++) {
527             if (!source.contains(toAdd[i]))
528                 source.add(toAdd[i]);
529         }
530     }
531
532     public Properties loadPropertyFileIn(Map toMerge, File JavaDoc location) {
533         Properties result = new Properties();
534         result.putAll(toMerge);
535         try {
536             InputStream propertyStream = new BufferedInputStream(new FileInputStream(new File JavaDoc(location, PROPERTIES_FILE)));
537             try {
538                 result.load(propertyStream);
539             } finally {
540                 propertyStream.close();
541             }
542         } catch (Exception JavaDoc e) {
543             //ignore because compiled plug-ins do not have such files
544
}
545         return result;
546     }
547
548     public HashMap getExtraData() {
549         return bundleClasspaths;
550     }
551
552     public Map getPatchData() {
553         return patchBundles;
554     }
555
556     public List getSortedBundles() {
557         if (lastSortingDate != getState().getTimeStamp()) {
558             lastSortingDate = getState().getTimeStamp();
559             BundleDescription[] toSort = getState().getResolvedBundles();
560             Platform.getPlatformAdmin().getStateHelper().sortBundles(toSort);
561             sortedBundles = Arrays.asList(toSort);
562         }
563         return sortedBundles;
564     }
565
566     public void cleanupOriginalState() {
567         if (addedBundle == null && unqualifiedBundles == null)
568             return;
569
570         for (Iterator iter = addedBundle.iterator(); iter.hasNext();) {
571             BundleDescription added = (BundleDescription) iter.next();
572             state.removeBundle(added);
573         }
574
575         for (Iterator iter = unqualifiedBundles.iterator(); iter.hasNext();) {
576             BundleDescription toAddBack = (BundleDescription) iter.next();
577             state.removeBundle(toAddBack.getBundleId());
578             addBundleDescription(toAddBack);
579         }
580
581         BundleDescription[] allBundles = state.getBundles();
582         for (int i = 0; i < allBundles.length; i++) {
583             allBundles[i].setUserObject(null);
584         }
585         state.resolve();
586     }
587
588     private File JavaDoc getOSGiLocation() {
589         BundleDescription osgiBundle = state.getBundle("org.eclipse.osgi", null); //$NON-NLS-1$
590
if (osgiBundle == null)
591             return null;
592         return new File JavaDoc(osgiBundle.getLocation());
593     }
594
595     private void setJavaProfiles(File JavaDoc bundleLocation) {
596         String JavaDoc[] foundProfiles = null;
597         if (bundleLocation == null)
598             foundProfiles = getRuntimeJavaProfiles();
599         else if (bundleLocation.isDirectory())
600             foundProfiles = getDirJavaProfiles(bundleLocation);
601         else
602             foundProfiles = getJarJavaProfiles(bundleLocation);
603         javaProfiles = foundProfiles;
604     }
605
606     private String JavaDoc[] getRuntimeJavaProfiles() {
607         BundleContext context = BundleHelper.getDefault().getBundle().getBundleContext();
608         Bundle systemBundle = context.getBundle(0);
609
610         URL JavaDoc url = systemBundle.getEntry("profile.list"); //$NON-NLS-1$
611
if (url != null) {
612             try {
613                 return getJavaProfiles(new BufferedInputStream(url.openStream()));
614             } catch (IOException e) {
615                 //no profile.list?
616
}
617         }
618
619         ArrayList results = new ArrayList(6);
620         Enumeration entries = systemBundle.findEntries("/", "*.profile", false); //$NON-NLS-1$ //$NON-NLS-2$
621
while (entries.hasMoreElements()) {
622             URL JavaDoc entryUrl = (URL JavaDoc) entries.nextElement();
623             results.add(entryUrl.getFile().substring(1));
624         }
625
626         return sortProfiles((String JavaDoc[]) results.toArray(new String JavaDoc[results.size()]));
627     }
628
629     private String JavaDoc[] getDirJavaProfiles(File JavaDoc bundleLocation) {
630         // try the profile list first
631
File JavaDoc profileList = new File JavaDoc(bundleLocation, "profile.list"); //$NON-NLS-1$
632
if (profileList.exists())
633             try {
634                 return getJavaProfiles(new BufferedInputStream(new FileInputStream(profileList)));
635             } catch (IOException e) {
636                 // this should not happen because we just checked if the file exists
637
}
638         String JavaDoc[] profiles = bundleLocation.list(new FilenameFilter() {
639             public boolean accept(File JavaDoc dir, String JavaDoc name) {
640                 return name.endsWith(PROFILE_EXTENSION);
641             }
642         });
643         return sortProfiles(profiles);
644     }
645
646     private String JavaDoc[] getJarJavaProfiles(File JavaDoc bundleLocation) {
647         ZipFile JavaDoc zipFile = null;
648         ArrayList results = new ArrayList(6);
649         try {
650             zipFile = new ZipFile JavaDoc(bundleLocation, ZipFile.OPEN_READ);
651             ZipEntry JavaDoc profileList = zipFile.getEntry("profile.list"); //$NON-NLS-1$
652
if (profileList != null)
653                 try {
654                     return getJavaProfiles(zipFile.getInputStream(profileList));
655                 } catch (IOException e) {
656                     // this should not happen, just incase do the default
657
}
658
659             Enumeration entries = zipFile.entries();
660             while (entries.hasMoreElements()) {
661                 String JavaDoc entryName = ((ZipEntry JavaDoc) entries.nextElement()).getName();
662                 if (entryName.indexOf('/') < 0 && entryName.endsWith(PROFILE_EXTENSION))
663                     results.add(entryName);
664             }
665         } catch (IOException e) {
666             // nothing to do
667
} finally {
668             if (zipFile != null)
669                 try {
670                     zipFile.close();
671                 } catch (IOException e) {
672                     // nothing to do
673
}
674         }
675         return sortProfiles((String JavaDoc[]) results.toArray(new String JavaDoc[results.size()]));
676     }
677
678     private String JavaDoc[] getJavaProfiles(InputStream is) throws IOException {
679         Properties props = new Properties();
680         props.load(is);
681         return ManifestElement.getArrayFromList(props.getProperty("java.profiles"), ","); //$NON-NLS-1$ //$NON-NLS-2$
682
}
683
684     private String JavaDoc[] sortProfiles(String JavaDoc[] profiles) {
685         Arrays.sort(profiles, new Comparator() {
686             public int compare(Object JavaDoc profile1, Object JavaDoc profile2) {
687                 // need to make sure JavaSE, J2SE profiles are sorted ahead of all other profiles
688
String JavaDoc p1 = (String JavaDoc) profile1;
689                 String JavaDoc p2 = (String JavaDoc) profile2;
690                 if (p1.startsWith("JavaSE") && !p2.startsWith("JavaSE")) //$NON-NLS-1$ //$NON-NLS-2$
691
return -1;
692                 if (!p1.startsWith("JavaSE") && p2.startsWith("JavaSE")) //$NON-NLS-1$ //$NON-NLS-2$
693
return 1;
694                 if (p1.startsWith("J2SE") && !p2.startsWith("J2SE")) //$NON-NLS-1$ //$NON-NLS-2$
695
return -1;
696                 if (!p1.startsWith("J2SE") && p2.startsWith("J2SE")) //$NON-NLS-1$ //$NON-NLS-2$
697
return 1;
698                 return -p1.compareTo(p2);
699             }
700         });
701         return profiles;
702     }
703
704     private Properties getJavaProfileProperties() {
705         if (javaProfile == null)
706             return null;
707         File JavaDoc location = getOSGiLocation();
708         InputStream is = null;
709         ZipFile JavaDoc zipFile = null;
710         try {
711             if (location == null) {
712                 BundleContext context = BundleHelper.getDefault().getBundle().getBundleContext();
713                 Bundle systemBundle = context.getBundle(0);
714
715                 URL JavaDoc url = systemBundle.getEntry(javaProfile);
716                 is = new BufferedInputStream(url.openStream());
717             } else if (location.isDirectory()) {
718                 is = new BufferedInputStream(new FileInputStream(new File JavaDoc(location, javaProfile)));
719             } else {
720                 zipFile = null;
721                 try {
722                     zipFile = new ZipFile JavaDoc(location, ZipFile.OPEN_READ);
723                     ZipEntry JavaDoc entry = zipFile.getEntry(javaProfile);
724                     if (entry != null)
725                         is = zipFile.getInputStream(entry);
726                 } catch (IOException e) {
727                     // nothing to do
728
}
729             }
730             Properties profile = new Properties();
731             profile.load(is);
732             return profile;
733         } catch (IOException e) {
734             // nothing to do
735
} finally {
736             if (is != null)
737                 try {
738                     is.close();
739                 } catch (IOException e) {
740                     // nothing to do
741
}
742             if (zipFile != null)
743                 try {
744                     zipFile.close();
745                 } catch (IOException e) {
746                     // nothing to do
747
}
748         }
749         return null;
750     }
751
752     //Replace the version numbers that ends with .qualifier
753
private void forceQualifiers() {
754         BundleDescription[] resolvedBundles = state.getResolvedBundles(); //We only get the resolved bundles since, changing the qualifier should not change the resolution state
755
for (int i = 0; i < resolvedBundles.length; i++) {
756             if (resolvedBundles[i].getVersion().getQualifier().endsWith(PROPERTY_QUALIFIER)) {
757                 BundleDescription b = resolvedBundles[i];
758                 unqualifiedBundles.add(state.removeBundle(b.getBundleId())); //We keep the removed bundle so we can reinsert it in the state when we are done
759
String JavaDoc newVersion = QualifierReplacer.replaceQualifierInVersion(b.getVersion().toString(), b.getSymbolicName(), getQualifierPropery(b.getLocation()), null);
760
761                 //Here it is important to reuse the same bundle id than the bundle we are removing so that we don't loose the information about the classpath
762
BundleDescription newBundle = state.getFactory().createBundleDescription(b.getBundleId(), b.getSymbolicName(), new Version(newVersion), b.getLocation(), b.getRequiredBundles(), b.getHost(), b.getImportPackages(), b.getExportPackages(), b.isSingleton(), b.attachFragments(), b.dynamicFragments(), b.getPlatformFilter(), b.getExecutionEnvironments(), b.getGenericRequires(), b.getGenericCapabilities());
763                 addBundleDescription(newBundle);
764                 rememberQualifierTagPresence(newBundle);
765                 mapVersionReplacedBundle(b, newBundle);
766             }
767         }
768         state.resolve();
769     }
770
771     /*
772      * If this bundle had its qualifier version replaced, return the replacement bundle description
773      * return the original bundle if no replacement occurred
774      */

775     public BundleDescription getVersionReplacement(BundleDescription bundle) {
776         Properties props = (Properties) bundle.getUserObject();
777         if (props == null)
778             return bundle;
779         String JavaDoc idString = props.getProperty(PROPERTY_VERSION_REPLACEMENT);
780         if (idString == null)
781             return bundle;
782         try {
783             long newId = Long.parseLong(idString);
784             BundleDescription newBundle = state.getBundle(newId);
785             if (newBundle != null)
786                 return newBundle;
787         } catch (NumberFormatException JavaDoc e) {
788             // fall through
789
}
790         return bundle;
791     }
792
793     public void setPlatformProperties(Dictionary platformProperties) {
794         this.platformProperties = platformProperties;
795     }
796 }
797
Popular Tags