1 11 12 package org.eclipse.osgi.framework.internal.core; 13 14 import java.io.IOException ; 15 import java.security.AccessController ; 16 import java.security.PrivilegedAction ; 17 import java.util.ArrayList ; 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 50 public class PackageAdminImpl implements PackageAdmin { 51 52 protected Framework framework; 53 54 58 static { 59 Class c; 60 c = GetBundleAction.class; 61 c.getName(); } 63 64 static class GetBundleAction implements PrivilegedAction { 65 private Class clazz; 66 private PackageAdminImpl impl; 67 68 public GetBundleAction(PackageAdminImpl impl, Class clazz) { 69 this.impl = impl; 70 this.clazz = clazz; 71 } 72 73 public Object run() { 74 return impl.getBundlePriv(clazz); 75 } 76 } 77 78 83 protected PackageAdminImpl(Framework framework) { 84 this.framework = framework; 85 } 86 87 public ExportedPackage[] getExportedPackages(Bundle bundle) { 88 ArrayList allExports = new ArrayList (); 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 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 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 name) { 140 ExportedPackage[] allExports = getExportedPackages((Bundle) null); 141 if (allExports == null) 142 return null; 143 ArrayList result = new ArrayList (1); 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 refresh = framework.secureAction.createThread(new Runnable () { 163 public void run() { 164 doResolveBundles(bundles, true); 165 if ("true".equals(FrameworkProperties.getProperty("osgi.forcedRestart"))) framework.shutdown(); 167 } 168 }, "Refresh Packages"); 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"); 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 descriptions = new BundleDescription[0]; 199 else if (numBundles > 0) { 200 ArrayList results = new ArrayList (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 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 (!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 if (delta.length > 0) 233 systemState.setTimeStamp(systemState.getTimeStamp() == Long.MAX_VALUE ? 0 : systemState.getTimeStamp() + 1); 234 } 235 resumeBundles(refreshedBundles, refreshPackages); 237 } catch (Throwable t) { 238 if (Debug.DEBUG && Debug.DEBUG_PACKAGEADMIN) { 239 Debug.println("PackageAdminImpl.doResolveBundles: Error occured :"); Debug.printStackTrace(t); 241 } 242 if (t instanceof RuntimeException ) 243 throw (RuntimeException ) t; 244 if (t instanceof Error ) 245 throw (Error ) t; 246 } finally { 247 if (Profile.PROFILE && Profile.STARTUP) 248 Profile.logExit("resolve bundles"); 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"); } 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 continue; 268 framework.resumeBundle(bundles[i]); 269 } 270 } 271 272 private void suspendBundle(AbstractBundle bundle) { 273 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); Debug.printStackTrace(new Exception ("Stack trace")); } 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 300 if (Debug.DEBUG && Debug.DEBUG_PACKAGEADMIN) { 301 Debug.println("Bundles still depend on removed bundle! " + bundle); Debug.printStackTrace(new Exception ("Stack trace")); } 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 e) { 312 } 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 results = new ArrayList (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 bundlesList = new ArrayList (bundleDeltas.length); 357 for (int i = 0; i < bundleDeltas.length; i++) { 359 if ((bundleDeltas[i].getType() & BundleDelta.REMOVAL_COMPLETE) != 0 && (bundleDeltas[i].getType() & BundleDelta.REMOVED) == 0) 360 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 Util.sort(refresh); 369 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"); } 378 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"); return null; 393 } 394 if (refreshPackages) 396 for (int i = refresh.length - 1; i >= 0; i--) 397 suspendBundle(refresh[i]); 398 402 if (Debug.DEBUG && Debug.DEBUG_PACKAGEADMIN) { 403 Debug.println("refreshPackages: refresh the bundles"); } 405 406 synchronized (framework.bundles) { 407 for (int i = 0; i < refresh.length; i++) 408 refresh[i].refresh(); 409 } 410 for (int i = 0; i < refresh.length; i++) { 412 if (previouslyResolved[i]) 414 framework.publishBundleEvent(BundleEvent.UNRESOLVED, refresh[i]); 415 } 416 417 420 if (Debug.DEBUG && Debug.DEBUG_PACKAGEADMIN) { 421 Debug.println("refreshPackages: applying deltas to bundles"); } 423 synchronized (framework.bundles) { 424 resolved = applyDeltas(bundleDeltas); 425 } 426 427 } finally { 428 431 if (Debug.DEBUG && Debug.DEBUG_PACKAGEADMIN) { 432 Debug.println("refreshPackages: release the state change locks"); } 434 if (refreshPackages) 435 for (int i = 0; i < refresh.length; i++) { 436 AbstractBundle changedBundle = refresh[i]; 437 changedBundle.completeStateChange(); 438 } 439 } 440 443 if (refreshPackages) { 444 if (Debug.DEBUG && Debug.DEBUG_PACKAGEADMIN) 445 Debug.println("refreshPackages: clean up adaptor storage"); try { 447 framework.adaptor.compactStorage(); 448 } catch (IOException e) { 449 if (Debug.DEBUG && Debug.DEBUG_PACKAGEADMIN) { 450 Debug.println("refreshPackages exception: " + e.getMessage()); 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()); 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 if (Debug.DEBUG && Debug.DEBUG_PACKAGEADMIN) 466 Debug.println("refreshPackages: send out RESOLVED events"); 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 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 result = new ArrayList (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 symbolicName, String versionRange) { 493 if (symbolicName == null) { 494 throw new IllegalArgumentException (); 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 ArrayList result = new ArrayList (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 clazz) { 536 ClassLoader 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 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() { } 556 557 protected void setResolvedBundles(SystemBundle systemBundle) { 558 checkSystemBundle(systemBundle); 559 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 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) return; BundleDescription newSystemBundle = state.getFactory().createBundleDescription(state, systemBundle.getHeaders(""), systemBundle.getLocation(), 0); if (newSystemBundle == null) 582 throw new BundleException(Msg.OSGI_SYSTEMBUNDLE_DESCRIPTION_ERROR); 583 if (!different) { 584 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 oldVersion = oldPackages[i].getVersion(); 591 Object 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 state.resolve(false); 606 } 607 } catch (BundleException e) { 608 e.printStackTrace(); 609 throw new RuntimeException (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 |