KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > osgi > framework > internal > core > PackageAdminImpl


1 /*******************************************************************************
2  * Copyright (c) 2003, 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
12 package org.eclipse.osgi.framework.internal.core;
13
14 import java.io.IOException JavaDoc;
15 import java.security.AccessController JavaDoc;
16 import java.security.PrivilegedAction JavaDoc;
17 import java.util.ArrayList JavaDoc;
18 import org.eclipse.osgi.framework.adaptor.BundleClassLoader;
19 import org.eclipse.osgi.framework.adaptor.BundleData;
20 import org.eclipse.osgi.framework.debug.Debug;
21 import org.eclipse.osgi.internal.profile.Profile;
22 import org.eclipse.osgi.service.resolver.*;
23 import org.eclipse.osgi.util.NLS;
24 import org.osgi.framework.*;
25 import org.osgi.service.packageadmin.*;
26
27 /**
28  * PackageAdmin service for the OSGi specification.
29  *
30  * Framework service which allows bundle programmers to inspect the packages
31  * exported in the framework and eagerly update or uninstall bundles.
32  *
33  * If present, there will only be a single instance of this service
34  * registered in the framework.
35  *
36  * <p> The term <i>exported package</i> (and the corresponding interface
37  * {@link ExportedPackage}) refers to a package that has actually been
38  * exported (as opposed to one that is available for export).
39  *
40  * <p> Note that the information about exported packages returned by this
41  * service is valid only until the next time {@link #refreshPackages(org.osgi.framework.Bundle[])} is
42  * called.
43  * If an ExportedPackage becomes stale, (that is, the package it references
44  * has been updated or removed as a result of calling
45  * PackageAdmin.refreshPackages()),
46  * its getName() and getSpecificationVersion() continue to return their
47  * old values, isRemovalPending() returns true, and getExportingBundle()
48  * and getImportingBundles() return null.
49  */

50 public class PackageAdminImpl implements PackageAdmin {
51     /** framework object */
52     protected Framework framework;
53
54     /*
55      * We need to make sure that the GetBundleAction class loads early to prevent a ClassCircularityError when checking permissions.
56      * See bug 161561
57      */

58     static {
59         Class JavaDoc c;
60         c = GetBundleAction.class;
61         c.getName(); // to prevent compiler warnings
62
}
63
64     static class GetBundleAction implements PrivilegedAction JavaDoc {
65         private Class JavaDoc clazz;
66         private PackageAdminImpl impl;
67
68         public GetBundleAction(PackageAdminImpl impl, Class JavaDoc clazz) {
69             this.impl = impl;
70             this.clazz = clazz;
71         }
72
73         public Object JavaDoc run() {
74             return impl.getBundlePriv(clazz);
75         }
76     }
77
78     /**
79      * Constructor.
80      *
81      * @param framework Framework object.
82      */

83     protected PackageAdminImpl(Framework framework) {
84         this.framework = framework;
85     }
86
87     public ExportedPackage[] getExportedPackages(Bundle bundle) {
88         ArrayList JavaDoc allExports = new ArrayList JavaDoc();
89         synchronized (framework.bundles) {
90             ExportPackageDescription[] allDescriptions = framework.adaptor.getState().getExportedPackages();
91             for (int i = 0; i < allDescriptions.length; i++) {
92                 if (!allDescriptions[i].isRoot())
93                     continue;
94                 ExportedPackageImpl exportedPackage = createExportedPackage(allDescriptions[i]);
95                 if (exportedPackage == null)
96                     continue;
97                 if (bundle == null || exportedPackage.supplier.getBundle() == bundle)
98                     allExports.add(exportedPackage);
99             }
100         }
101         return (ExportedPackage[]) (allExports.size() == 0 ? null : allExports.toArray(new ExportedPackage[allExports.size()]));
102     }
103
104     private ExportedPackageImpl createExportedPackage(ExportPackageDescription description) {
105         BundleDescription exporter = description.getExporter();
106         if (exporter == null || exporter.getHost() != null)
107             return null;
108         BundleLoaderProxy proxy = (BundleLoaderProxy) exporter.getUserObject();
109         if (proxy == null) {
110             BundleHost bundle = (BundleHost) framework.getBundle(exporter.getBundleId());
111             if (bundle == null)
112                 return null;
113             proxy = bundle.getLoaderProxy();
114         }
115         return new ExportedPackageImpl(description, proxy);
116     }
117
118     public ExportedPackage getExportedPackage(String JavaDoc name) {
119         ExportedPackage[] allExports = getExportedPackages((Bundle) null);
120         if (allExports == null)
121             return null;
122         ExportedPackage result = null;
123         for (int i = 0; i < allExports.length; i++) {
124             if (name.equals(allExports[i].getName())) {
125                 if (result == null) {
126                     result = allExports[i];
127                 } else {
128                     // TODO not efficient but this is not called very often
129
Version curVersion = Version.parseVersion(result.getSpecificationVersion());
130                     Version newVersion = Version.parseVersion(allExports[i].getSpecificationVersion());
131                     if (newVersion.compareTo(curVersion) >= 0)
132                         result = allExports[i];
133                 }
134             }
135         }
136         return result;
137     }
138
139     public ExportedPackage[] getExportedPackages(String JavaDoc name) {
140         ExportedPackage[] allExports = getExportedPackages((Bundle) null);
141         if (allExports == null)
142             return null;
143         ArrayList JavaDoc result = new ArrayList JavaDoc(1); // rare to have more than one
144
for (int i = 0; i < allExports.length; i++)
145             if (name.equals(allExports[i].getName()))
146                 result.add(allExports[i]);
147         return (ExportedPackage[]) (result.size() == 0 ? null : result.toArray(new ExportedPackage[result.size()]));
148     }
149
150     public void refreshPackages(Bundle[] input) {
151         framework.checkAdminPermission(framework.systemBundle, AdminPermission.RESOLVE);
152
153         AbstractBundle[] copy = null;
154         if (input != null) {
155             synchronized (input) {
156                 copy = new AbstractBundle[input.length];
157                 System.arraycopy(input, 0, copy, 0, input.length);
158             }
159         }
160
161         final AbstractBundle[] bundles = copy;
162         Thread JavaDoc refresh = framework.secureAction.createThread(new Runnable JavaDoc() {
163             public void run() {
164                 doResolveBundles(bundles, true);
165                 if ("true".equals(FrameworkProperties.getProperty("osgi.forcedRestart"))) //$NON-NLS-1$ //$NON-NLS-2$
166
framework.shutdown();
167             }
168         }, "Refresh Packages"); //$NON-NLS-1$
169

170         refresh.start();
171     }
172
173     public boolean resolveBundles(Bundle[] bundles) {
174         framework.checkAdminPermission(framework.systemBundle, AdminPermission.RESOLVE);
175         doResolveBundles(null, false);
176         if (bundles == null)
177             bundles = framework.getAllBundles();
178         for (int i = 0; i < bundles.length; i++)
179             if (!((AbstractBundle) bundles[i]).isResolved())
180                 return false;
181
182         return true;
183     }
184
185     synchronized void doResolveBundles(AbstractBundle[] bundles, boolean refreshPackages) {
186         try {
187             if (Profile.PROFILE && Profile.STARTUP)
188                 Profile.logEnter("resolve bundles"); //$NON-NLS-1$
189
framework.publishBundleEvent(Framework.BATCHEVENT_BEGIN, framework.systemBundle);
190             AbstractBundle[] refreshedBundles = null;
191             BundleDescription[] descriptions = null;
192             synchronized (framework.bundles) {
193                 int numBundles = bundles == null ? 0 : bundles.length;
194                 if (!refreshPackages)
195                     // in this case we must make descriptions non-null so we do
196
// not force the removal pendings to be processed when resolving
197
// the state.
198
descriptions = new BundleDescription[0];
199                 else if (numBundles > 0) {
200                     ArrayList JavaDoc results = new ArrayList JavaDoc(numBundles);
201                     for (int i = 0; i < numBundles; i++) {
202                         BundleDescription description = bundles[i].getBundleDescription();
203                         if (description != null && description.getBundleId() != 0 && !results.contains(description))
204                             results.add(description);
205                         // add in any bundles that have the same symbolic name see bug (169593)
206
AbstractBundle[] sameNames = framework.bundles.getBundles(bundles[i].getSymbolicName());
207                         if (sameNames != null && sameNames.length > 1) {
208                             for (int j = 0; j < sameNames.length; j++)
209                                 if (sameNames[j] != bundles[i]) {
210                                     BundleDescription sameName = sameNames[j].getBundleDescription();
211                                     if (sameName != null && sameName.getBundleId() != 0 && !results.contains(sameName))
212                                         results.add(sameName);
213                                 }
214                         }
215                     }
216                     descriptions = (BundleDescription[]) (results.size() == 0 ? null : results.toArray(new BundleDescription[results.size()]));
217                 }
218             }
219             State systemState = framework.adaptor.getState();
220             BundleDelta[] delta = systemState.resolve(descriptions).getChanges();
221             refreshedBundles = processDelta(delta, refreshPackages);
222             // if we end up refreshing the system bundle or one of its fragments the framework will be shutdown and
223
// should be re-started. This call should return without doing further work.
224
if (!framework.isActive())
225                 return;
226             if (refreshPackages) {
227                 AbstractBundle[] allBundles = framework.getAllBundles();
228                 for (int i = 0; i < allBundles.length; i++)
229                     allBundles[i].unresolvePermissions();
230                 // increment the system state timestamp if we are refreshing packages.
231
// this is needed incase we suspended a bundle from processing the delta (bug 167483)
232
if (delta.length > 0)
233                     systemState.setTimeStamp(systemState.getTimeStamp() == Long.MAX_VALUE ? 0 : systemState.getTimeStamp() + 1);
234             }
235             // always resume bundles incase we have lazy-start bundles
236
resumeBundles(refreshedBundles, refreshPackages);
237         } catch (Throwable JavaDoc t) {
238             if (Debug.DEBUG && Debug.DEBUG_PACKAGEADMIN) {
239                 Debug.println("PackageAdminImpl.doResolveBundles: Error occured :"); //$NON-NLS-1$
240
Debug.printStackTrace(t);
241             }
242             if (t instanceof RuntimeException JavaDoc)
243                 throw (RuntimeException JavaDoc) t;
244             if (t instanceof Error JavaDoc)
245                 throw (Error JavaDoc) t;
246         } finally {
247             if (Profile.PROFILE && Profile.STARTUP)
248                 Profile.logExit("resolve bundles"); //$NON-NLS-1$
249
if (framework.isActive()) {
250                 framework.publishBundleEvent(Framework.BATCHEVENT_END, framework.systemBundle);
251                 if (refreshPackages)
252                     framework.publishFrameworkEvent(FrameworkEvent.PACKAGES_REFRESHED, framework.systemBundle, null);
253             }
254         }
255     }
256
257     private void resumeBundles(AbstractBundle[] bundles, boolean refreshPackages) {
258         if (Debug.DEBUG && Debug.DEBUG_PACKAGEADMIN) {
259             Debug.println("PackageAdminImpl: restart the bundles"); //$NON-NLS-1$
260
}
261         if (bundles == null)
262             return;
263         for (int i = 0; i < bundles.length; i++) {
264             if (!bundles[i].isResolved() || (!refreshPackages && ((bundles[i].getBundleData().getStatus() & Constants.BUNDLE_LAZY_START) == 0 || bundles[i].testStateChanging(Thread.currentThread()))))
265                 // skip bundles that are not resolved or
266
// if we are doing resolveBundles then skip non-lazy start bundles and bundles currently changing state by this thread
267
continue;
268             framework.resumeBundle(bundles[i]);
269         }
270     }
271
272     private void suspendBundle(AbstractBundle bundle) {
273         // attempt to suspend the bundle or obtain the state change lock
274
// Note that this may fail but we cannot quit the
275
// refreshPackages operation because of it. (bug 84169)
276
if (bundle.isActive() && !bundle.isFragment()) {
277             framework.suspendBundle(bundle, true);
278         } else {
279             if (bundle.getStateChanging() != Thread.currentThread())
280                 try {
281                     bundle.beginStateChange();
282                 } catch (BundleException e) {
283                     framework.publishFrameworkEvent(FrameworkEvent.ERROR, bundle, e);
284                 }
285         }
286
287         if (Debug.DEBUG && Debug.DEBUG_PACKAGEADMIN) {
288             if (bundle.stateChanging == null) {
289                 Debug.println("Bundle state change lock is clear! " + bundle); //$NON-NLS-1$
290
Debug.printStackTrace(new Exception JavaDoc("Stack trace")); //$NON-NLS-1$
291
}
292         }
293     }
294
295     private void applyRemovalPending(BundleDelta bundleDelta) throws BundleException {
296         if ((bundleDelta.getType() & BundleDelta.REMOVAL_COMPLETE) != 0) {
297             BundleDescription bundle = bundleDelta.getBundle();
298             if (bundle.getDependents() != null && bundle.getDependents().length > 0) {
299                 /* Reaching here is an internal error */
300                 if (Debug.DEBUG && Debug.DEBUG_PACKAGEADMIN) {
301                     Debug.println("Bundles still depend on removed bundle! " + bundle); //$NON-NLS-1$
302
Debug.printStackTrace(new Exception JavaDoc("Stack trace")); //$NON-NLS-1$
303
}
304                 throw new BundleException(Msg.OSGI_INTERNAL_ERROR);
305             }
306             BundleLoaderProxy proxy = (BundleLoaderProxy) bundle.getUserObject();
307             if (proxy != null) {
308                 BundleHost.closeBundleLoader(proxy);
309                 try {
310                     proxy.getBundleHost().getBundleData().close();
311                 } catch (IOException JavaDoc e) {
312                     // ignore
313
}
314             }
315         }
316     }
317
318     private AbstractBundle setResolved(BundleDescription bundleDescription) {
319         if (!bundleDescription.isResolved())
320             return null;
321         AbstractBundle bundle = framework.getBundle(bundleDescription.getBundleId());
322         if (bundle == null) {
323             BundleException be = new BundleException(NLS.bind(Msg.BUNDLE_NOT_IN_FRAMEWORK, bundleDescription));
324             framework.publishFrameworkEvent(FrameworkEvent.ERROR, framework.systemBundle, be);
325             return null;
326         }
327         boolean resolve = true;
328         if (bundle.isFragment()) {
329             BundleDescription[] hosts = bundleDescription.getHost().getHosts();
330             for (int i = 0; i < hosts.length; i++) {
331                 BundleHost host = (BundleHost) framework.getBundle(hosts[i].getBundleId());
332                 resolve = ((BundleFragment) bundle).addHost(host.getLoaderProxy());
333             }
334         }
335         if (resolve)
336             bundle.resolve();
337         return bundle;
338     }
339
340     private AbstractBundle[] applyDeltas(BundleDelta[] bundleDeltas) throws BundleException {
341         ArrayList JavaDoc results = new ArrayList JavaDoc(bundleDeltas.length);
342         for (int i = 0; i < bundleDeltas.length; i++) {
343             int type = bundleDeltas[i].getType();
344             if ((type & (BundleDelta.REMOVAL_PENDING | BundleDelta.REMOVAL_COMPLETE)) != 0)
345                 applyRemovalPending(bundleDeltas[i]);
346             if ((type & BundleDelta.RESOLVED) != 0) {
347                 AbstractBundle bundle = setResolved(bundleDeltas[i].getBundle());
348                 if (bundle != null && bundle.isResolved())
349                     results.add(bundle);
350             }
351         }
352         return (AbstractBundle[]) (results.size() == 0 ? null : results.toArray(new AbstractBundle[results.size()]));
353     }
354
355     private AbstractBundle[] processDelta(BundleDelta[] bundleDeltas, boolean refreshPackages) {
356         ArrayList JavaDoc bundlesList = new ArrayList JavaDoc(bundleDeltas.length);
357         // get all the bundles that are going to be refreshed
358
for (int i = 0; i < bundleDeltas.length; i++) {
359             if ((bundleDeltas[i].getType() & BundleDelta.REMOVAL_COMPLETE) != 0 && (bundleDeltas[i].getType() & BundleDelta.REMOVED) == 0)
360                 // this means the bundle was previously pending removal; do not add to list because it was already removed from before.
361
continue;
362             AbstractBundle changedBundle = framework.getBundle(bundleDeltas[i].getBundle().getBundleId());
363             if (changedBundle != null && !bundlesList.contains(changedBundle))
364                 bundlesList.add(changedBundle);
365         }
366         AbstractBundle[] refresh = (AbstractBundle[]) bundlesList.toArray(new AbstractBundle[bundlesList.size()]);
367         // first sort by id/start-level order
368
Util.sort(refresh);
369         // then sort by dependency order
370
StartLevelManager.sortByDependency(refresh);
371         boolean[] previouslyResolved = new boolean[refresh.length];
372         AbstractBundle[] resolved = null;
373         try {
374             try {
375                 if (Debug.DEBUG && Debug.DEBUG_PACKAGEADMIN) {
376                     Debug.println("refreshPackages: Suspend each bundle and acquire its state change lock"); //$NON-NLS-1$
377
}
378                 // find which bundles were previously resolved and handle extension bundles
379
boolean restart = false;
380                 for (int i = refresh.length - 1; i >= 0; i--) {
381                     previouslyResolved[i] = refresh[i].isResolved();
382                     if (refresh[i] == framework.systemBundle)
383                         restart = true;
384                     else if (((refresh[i].bundledata.getType() & BundleData.TYPE_FRAMEWORK_EXTENSION) != 0) && previouslyResolved[i])
385                         restart = true;
386                     else if ((refresh[i].bundledata.getType() & BundleData.TYPE_BOOTCLASSPATH_EXTENSION) != 0)
387                         restart = true;
388                 }
389                 if (restart) {
390                     FrameworkProperties.setProperty("osgi.forcedRestart", "true"); //$NON-NLS-1$ //$NON-NLS-2$
391
// do not shutdown the framework while holding the PackageAdmin lock (bug 194149)
392
return null;
393                 }
394                 // now suspend each bundle and grab its state change lock.
395
if (refreshPackages)
396                     for (int i = refresh.length - 1; i >= 0; i--)
397                         suspendBundle(refresh[i]);
398                 /*
399                  * Refresh the bundles which will unexport the packages.
400                  * This will move RESOLVED bundles to the INSTALLED state.
401                  */

402                 if (Debug.DEBUG && Debug.DEBUG_PACKAGEADMIN) {
403                     Debug.println("refreshPackages: refresh the bundles"); //$NON-NLS-1$
404
}
405
406                 synchronized (framework.bundles) {
407                     for (int i = 0; i < refresh.length; i++)
408                         refresh[i].refresh();
409                 }
410                 // send out unresolved events outside synch block (defect #80610)
411
for (int i = 0; i < refresh.length; i++) {
412                     // send out unresolved events
413
if (previouslyResolved[i])
414                         framework.publishBundleEvent(BundleEvent.UNRESOLVED, refresh[i]);
415                 }
416
417                 /*
418                  * apply Deltas.
419                  */

420                 if (Debug.DEBUG && Debug.DEBUG_PACKAGEADMIN) {
421                     Debug.println("refreshPackages: applying deltas to bundles"); //$NON-NLS-1$
422
}
423                 synchronized (framework.bundles) {
424                     resolved = applyDeltas(bundleDeltas);
425                 }
426
427             } finally {
428                 /*
429                  * Release the state change locks.
430                  */

431                 if (Debug.DEBUG && Debug.DEBUG_PACKAGEADMIN) {
432                     Debug.println("refreshPackages: release the state change locks"); //$NON-NLS-1$
433
}
434                 if (refreshPackages)
435                     for (int i = 0; i < refresh.length; i++) {
436                         AbstractBundle changedBundle = refresh[i];
437                         changedBundle.completeStateChange();
438                     }
439             }
440             /*
441              * Take this opportunity to clean up the adaptor storage.
442              */

443             if (refreshPackages) {
444                 if (Debug.DEBUG && Debug.DEBUG_PACKAGEADMIN)
445                     Debug.println("refreshPackages: clean up adaptor storage"); //$NON-NLS-1$
446
try {
447                     framework.adaptor.compactStorage();
448                 } catch (IOException JavaDoc e) {
449                     if (Debug.DEBUG && Debug.DEBUG_PACKAGEADMIN) {
450                         Debug.println("refreshPackages exception: " + e.getMessage()); //$NON-NLS-1$
451
Debug.printStackTrace(e);
452                     }
453                     framework.publishFrameworkEvent(FrameworkEvent.ERROR, framework.systemBundle, new BundleException(Msg.BUNDLE_REFRESH_FAILURE, e));
454                 }
455             }
456         } catch (BundleException e) {
457             if (Debug.DEBUG && Debug.DEBUG_PACKAGEADMIN) {
458                 Debug.println("refreshPackages exception: " + e.getMessage()); //$NON-NLS-1$
459
Debug.printStackTrace(e.getNestedException() == null ? e : e.getNestedException());
460             }
461             framework.publishFrameworkEvent(FrameworkEvent.ERROR, framework.systemBundle, new BundleException(Msg.BUNDLE_REFRESH_FAILURE, e));
462         }
463
464         // send out any resolved. This must be done after the state change locks have been release.
465
if (Debug.DEBUG && Debug.DEBUG_PACKAGEADMIN)
466             Debug.println("refreshPackages: send out RESOLVED events"); //$NON-NLS-1$
467
if (resolved != null)
468             for (int i = 0; i < resolved.length; i++)
469                 framework.publishBundleEvent(BundleEvent.RESOLVED, resolved[i]);
470
471         return refresh;
472     }
473
474     public RequiredBundle[] getRequiredBundles(String JavaDoc symbolicName) {
475         AbstractBundle[] bundles;
476         if (symbolicName == null)
477             bundles = framework.getAllBundles();
478         else
479             bundles = framework.getBundleBySymbolicName(symbolicName);
480         if (bundles == null || bundles.length == 0)
481             return null;
482
483         ArrayList JavaDoc result = new ArrayList JavaDoc(bundles.length);
484         for (int i = 0; i < bundles.length; i++) {
485             if (bundles[i].isFragment() || !bundles[i].isResolved() || bundles[i].getSymbolicName() == null)
486                 continue;
487             result.add(((BundleHost) bundles[i]).getLoaderProxy());
488         }
489         return result.size() == 0 ? null : (RequiredBundle[]) result.toArray(new RequiredBundle[result.size()]);
490     }
491
492     public Bundle[] getBundles(String JavaDoc symbolicName, String JavaDoc versionRange) {
493         if (symbolicName == null) {
494             throw new IllegalArgumentException JavaDoc();
495         }
496         AbstractBundle bundles[] = framework.getBundleBySymbolicName(symbolicName);
497         if (bundles == null)
498             return null;
499
500         if (versionRange == null) {
501             AbstractBundle[] result = new AbstractBundle[bundles.length];
502             System.arraycopy(bundles, 0, result, 0, result.length);
503             return result;
504         }
505
506         // This code depends on the array of bundles being in descending
507
// version order.
508
ArrayList JavaDoc result = new ArrayList JavaDoc(bundles.length);
509         VersionRange range = new VersionRange(versionRange);
510         for (int i = 0; i < bundles.length; i++) {
511             if (range.isIncluded(bundles[i].getVersion())) {
512                 result.add(bundles[i]);
513             }
514         }
515
516         if (result.size() == 0)
517             return null;
518         return (AbstractBundle[]) result.toArray(new AbstractBundle[result.size()]);
519     }
520
521     public Bundle[] getFragments(Bundle bundle) {
522         return ((AbstractBundle) bundle).getFragments();
523     }
524
525     public Bundle[] getHosts(Bundle bundle) {
526         BundleLoaderProxy[] hosts = ((AbstractBundle) bundle).getHosts();
527         if (hosts == null)
528             return null;
529         Bundle[] result = new Bundle[hosts.length];
530         for (int i = 0; i < hosts.length; i++)
531             result[i] = hosts[i].getBundleHost();
532         return result;
533     }
534
535     Bundle getBundlePriv(Class JavaDoc clazz) {
536         ClassLoader JavaDoc cl = clazz.getClassLoader();
537         if (cl instanceof BundleClassLoader)
538             return ((BundleLoader) ((BundleClassLoader) cl).getDelegate()).bundle;
539         if (cl == getClass().getClassLoader())
540             return framework.systemBundle;
541         return null;
542     }
543
544     public Bundle getBundle(final Class JavaDoc clazz) {
545         if (System.getSecurityManager() == null)
546             return getBundlePriv(clazz);
547         return (Bundle) AccessController.doPrivileged(new GetBundleAction(this, clazz));
548     }
549
550     public int getBundleType(Bundle bundle) {
551         return ((AbstractBundle) bundle).isFragment() ? PackageAdmin.BUNDLE_TYPE_FRAGMENT : 0;
552     }
553
554     protected void cleanup() { //This is only called when the framework is shutting down
555
}
556
557     protected void setResolvedBundles(SystemBundle systemBundle) {
558         checkSystemBundle(systemBundle);
559         // Now set the actual state of the bundles from the persisted state.
560
State state = framework.adaptor.getState();
561         BundleDescription[] descriptions = state.getBundles();
562         for (int i = 0; i < descriptions.length; i++) {
563             if (descriptions[i].getBundleId() == 0)
564                 setFrameworkVersion(descriptions[i]);
565             else
566                 setResolved(descriptions[i]);
567         }
568     }
569
570     private void checkSystemBundle(SystemBundle systemBundle) {
571         try {
572             // first check that the system bundle has not changed since last saved state.
573
State state = framework.adaptor.getState();
574             BundleDescription oldSystemBundle = state.getBundle(0);
575             boolean different = false;
576             if (oldSystemBundle == null || !systemBundle.getBundleData().getVersion().equals(oldSystemBundle.getVersion()))
577                 different = true;
578             if (!different && FrameworkProperties.getProperty("osgi.dev") == null) //$NON-NLS-1$
579
return; // return quick if not in dev mode; system bundle version changes with each build
580
BundleDescription newSystemBundle = state.getFactory().createBundleDescription(state, systemBundle.getHeaders(""), systemBundle.getLocation(), 0); //$NON-NLS-1$
581
if (newSystemBundle == null)
582                 throw new BundleException(Msg.OSGI_SYSTEMBUNDLE_DESCRIPTION_ERROR);
583             if (!different) {
584                 // need to check to make sure the system bundle description is up to date in the state.
585
ExportPackageDescription[] oldPackages = oldSystemBundle.getExportPackages();
586                 ExportPackageDescription[] newPackages = newSystemBundle.getExportPackages();
587                 if (oldPackages.length >= newPackages.length) {
588                     for (int i = 0; i < newPackages.length && !different; i++) {
589                         if (oldPackages[i].getName().equals(newPackages[i].getName())) {
590                             Object JavaDoc oldVersion = oldPackages[i].getVersion();
591                             Object JavaDoc newVersion = newPackages[i].getVersion();
592                             different = oldVersion == null ? newVersion != null : !oldVersion.equals(newVersion);
593                         } else {
594                             different = true;
595                         }
596                     }
597                 } else {
598                     different = true;
599                 }
600             }
601             if (different) {
602                 state.removeBundle(0);
603                 state.addBundle(newSystemBundle);
604                 // force resolution so packages are properly linked
605
state.resolve(false);
606             }
607         } catch (BundleException e) /* fatal error */{
608             e.printStackTrace();
609             throw new RuntimeException JavaDoc(NLS.bind(Msg.OSGI_SYSTEMBUNDLE_CREATE_EXCEPTION, e.getMessage()));
610         }
611     }
612
613     private void setFrameworkVersion(BundleDescription systemBundle) {
614         ExportPackageDescription[] packages = systemBundle.getExportPackages();
615         for (int i = 0; i < packages.length; i++)
616             if (packages[i].getName().equals(Constants.OSGI_FRAMEWORK_PACKAGE)) {
617                 FrameworkProperties.setProperty(Constants.FRAMEWORK_VERSION, packages[i].getVersion().toString());
618                 break;
619             }
620         FrameworkProperties.setProperty(Constants.OSGI_IMPL_VERSION_KEY, systemBundle.getVersion().toString());
621     }
622 }
623
Popular Tags