diff options
author | Thomas Watson | 2008-12-19 21:10:00 +0000 |
---|---|---|
committer | Thomas Watson | 2008-12-19 21:10:00 +0000 |
commit | c0bf408b216d2511900a0e48b4185d50fb6017e2 (patch) | |
tree | cc91e6e2a43514f5088471048125db7503fed0b8 /bundles/org.eclipse.osgi/resolver | |
parent | f1a814066412e3ae14174179eea848452496bb34 (diff) | |
download | rt.equinox.framework-c0bf408b216d2511900a0e48b4185d50fb6017e2.tar.gz rt.equinox.framework-c0bf408b216d2511900a0e48b4185d50fb6017e2.tar.xz rt.equinox.framework-c0bf408b216d2511900a0e48b4185d50fb6017e2.zip |
Bug 254021 Implement new LinkBundleFactory service (rfc 138)
Diffstat (limited to 'bundles/org.eclipse.osgi/resolver')
5 files changed, 135 insertions, 43 deletions
diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/CompositeResolveHelper.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/CompositeResolveHelper.java new file mode 100644 index 000000000..5f7cdba7d --- /dev/null +++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/CompositeResolveHelper.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright (c) 2008 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.osgi.internal.module; + +import org.eclipse.osgi.service.resolver.ExportPackageDescription; + +public interface CompositeResolveHelper { + public boolean giveExports(ExportPackageDescription[] matchingExports); +} diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/CompositeResolveHelperRegistry.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/CompositeResolveHelperRegistry.java new file mode 100644 index 000000000..f4cd6fb80 --- /dev/null +++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/CompositeResolveHelperRegistry.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright (c) 2008 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.osgi.internal.module; + +import org.eclipse.osgi.service.resolver.BundleDescription; + +public interface CompositeResolveHelperRegistry { + public CompositeResolveHelper getCompositeResolveHelper(BundleDescription bundle); +} diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/ResolverBundle.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/ResolverBundle.java index dcae3876c..d44e4416f 100644 --- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/ResolverBundle.java +++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/ResolverBundle.java @@ -392,19 +392,19 @@ public class ResolverBundle extends VersionSupplier implements Comparable { return false; if (!existingDescription.getVersion().equals(newDescription.getVersion())) return false; - if (!equivalentMaps(existingDescription.getAttributes(), newDescription.getAttributes())) + if (!equivalentMaps(existingDescription.getAttributes(), newDescription.getAttributes(), true)) return false; - if (!equivalentMaps(existingDescription.getDirectives(), newDescription.getDirectives())) + if (!equivalentMaps(existingDescription.getDirectives(), newDescription.getDirectives(), true)) return false; return true; } - private boolean equivalentMaps(Map existingDirectives, Map newDirectives) { + public static boolean equivalentMaps(Map existingDirectives, Map newDirectives, boolean exactMatch) { if (existingDirectives == null && newDirectives == null) return true; if (existingDirectives == null ? newDirectives != null : newDirectives == null) return false; - if (existingDirectives.size() != newDirectives.size()) + if (exactMatch && existingDirectives.size() != newDirectives.size()) return false; for (Iterator entries = existingDirectives.entrySet().iterator(); entries.hasNext();) { Entry entry = (Entry) entries.next(); diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/ResolverImpl.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/ResolverImpl.java index 2d80e5263..19eff3497 100644 --- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/ResolverImpl.java +++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/ResolverImpl.java @@ -72,6 +72,7 @@ public class ResolverImpl implements org.eclipse.osgi.service.resolver.Resolver private GroupingChecker groupingChecker; private Comparator selectionPolicy; private boolean developmentMode = false; + private volatile CompositeResolveHelperRegistry compositeHelpers; public ResolverImpl(BundleContext context, boolean checkPermissions) { this.permissionChecker = new PermissionChecker(context, checkPermissions, this); @@ -535,46 +536,76 @@ public class ResolverImpl implements org.eclipse.osgi.service.resolver.Resolver resolveFragment(unresolved[i]); } checkUsesConstraints(bundles, platformProperties, rejectedSingletons); + checkComposites(bundles, platformProperties, rejectedSingletons); + } + + private void checkComposites(ResolverBundle[] bundles, Dictionary[] platformProperties, ArrayList rejectedSingletons) { + CompositeResolveHelperRegistry helpers = getCompositeHelpers(); + if (helpers == null) + return; + Set exclude = null; + for (int i = 0; i < bundles.length; i++) { + CompositeResolveHelper helper = helpers.getCompositeResolveHelper(bundles[i].getBundle()); + if (helper == null) + continue; + if (!bundles[i].isResolved()) + continue; + if (!helper.giveExports(getExportsWiredTo(bundles[i]))) { + state.addResolverError(bundles[i].getBundle(), ResolverError.DISABLED_BUNDLE, null, null); + bundles[i].setResolvable(false); + bundles[i].clearRefs(); + setBundleUnresolved(bundles[i], false, developmentMode); + if (exclude == null) + exclude = new HashSet(1); + exclude.add(bundles[i]); + } + } + reResolveBundles(exclude, bundles, platformProperties, rejectedSingletons); } private void checkUsesConstraints(ResolverBundle[] bundles, Dictionary[] platformProperties, ArrayList rejectedSingletons) { ArrayList conflictingConstraints = findBestCombination(bundles); + if (conflictingConstraints == null) + return; Set conflictedBundles = null; - if (conflictingConstraints != null) { - for (Iterator conflicts = conflictingConstraints.iterator(); conflicts.hasNext();) { - ResolverConstraint conflict = (ResolverConstraint) conflicts.next(); - if (conflict.isOptional()) { - conflict.clearPossibleSuppliers(); - continue; - } + for (Iterator conflicts = conflictingConstraints.iterator(); conflicts.hasNext();) { + ResolverConstraint conflict = (ResolverConstraint) conflicts.next(); + if (conflict.isOptional()) { + conflict.clearPossibleSuppliers(); + continue; + } + if (conflictedBundles == null) conflictedBundles = new HashSet(conflictingConstraints.size()); - ResolverBundle conflictedBundle; - if (conflict.isFromFragment()) - conflictedBundle = (ResolverBundle) bundleMapping.get(conflict.getVersionConstraint().getBundle()); - else - conflictedBundle = conflict.getBundle(); - if (conflictedBundle != null) { - if (DEBUG_USES) - System.out.println("Found conflicting constraint: " + conflict + " in bundle " + conflictedBundle); //$NON-NLS-1$//$NON-NLS-2$ - conflictedBundles.add(conflictedBundle); - int type = conflict instanceof ResolverImport ? ResolverError.IMPORT_PACKAGE_USES_CONFLICT : ResolverError.REQUIRE_BUNDLE_USES_CONFLICT; - state.addResolverError(conflictedBundle.getBundle(), type, conflict.getVersionConstraint().toString(), conflict.getVersionConstraint()); - conflictedBundle.setResolvable(false); - conflictedBundle.clearRefs(); - setBundleUnresolved(conflictedBundle, false, developmentMode); - } + ResolverBundle conflictedBundle; + if (conflict.isFromFragment()) + conflictedBundle = (ResolverBundle) bundleMapping.get(conflict.getVersionConstraint().getBundle()); + else + conflictedBundle = conflict.getBundle(); + if (conflictedBundle != null) { + if (DEBUG_USES) + System.out.println("Found conflicting constraint: " + conflict + " in bundle " + conflictedBundle); //$NON-NLS-1$//$NON-NLS-2$ + conflictedBundles.add(conflictedBundle); + int type = conflict instanceof ResolverImport ? ResolverError.IMPORT_PACKAGE_USES_CONFLICT : ResolverError.REQUIRE_BUNDLE_USES_CONFLICT; + state.addResolverError(conflictedBundle.getBundle(), type, conflict.getVersionConstraint().toString(), conflict.getVersionConstraint()); + conflictedBundle.setResolvable(false); + conflictedBundle.clearRefs(); + setBundleUnresolved(conflictedBundle, false, developmentMode); } - if (conflictedBundles != null && conflictedBundles.size() > 0) { - ArrayList remainingUnresolved = new ArrayList(); - for (int i = 0; i < bundles.length; i++) { - if (!conflictedBundles.contains(bundles[i])) { - setBundleUnresolved(bundles[i], false, developmentMode); - remainingUnresolved.add(bundles[i]); - } - } - resolveBundles0((ResolverBundle[]) remainingUnresolved.toArray(new ResolverBundle[remainingUnresolved.size()]), platformProperties, rejectedSingletons); + } + reResolveBundles(conflictedBundles, bundles, platformProperties, rejectedSingletons); + } + + private void reResolveBundles(Set exclude, ResolverBundle[] bundles, Dictionary[] platformProperties, ArrayList rejectedSingletons) { + if (exclude == null || exclude.size() == 0) + return; + ArrayList remainingUnresolved = new ArrayList(); + for (int i = 0; i < bundles.length; i++) { + if (!exclude.contains(bundles[i])) { + setBundleUnresolved(bundles[i], false, developmentMode); + remainingUnresolved.add(bundles[i]); } } + resolveBundles0((ResolverBundle[]) remainingUnresolved.toArray(new ResolverBundle[remainingUnresolved.size()]), platformProperties, rejectedSingletons); } private ArrayList findBestCombination(ResolverBundle[] bundles) { @@ -1434,12 +1465,7 @@ public class ResolverImpl implements org.eclipse.osgi.service.resolver.Resolver ExportPackageDescription[] substitutedExportsArray = (ExportPackageDescription[]) substitutedExports.toArray(new ExportPackageDescription[substitutedExports.size()]); // Gather exports that have been wired to - ResolverImport[] imports = rb.getImportPackages(); - ArrayList exportsWiredTo = new ArrayList(imports.length); - for (int i = 0; i < imports.length; i++) - if (imports[i].getSelectedSupplier() != null) - exportsWiredTo.add(imports[i].getSelectedSupplier().getBaseDescription()); - ExportPackageDescription[] exportsWiredToArray = (ExportPackageDescription[]) exportsWiredTo.toArray(new ExportPackageDescription[exportsWiredTo.size()]); + ExportPackageDescription[] exportsWiredToArray = getExportsWiredTo(rb); // Gather bundles that have been wired to BundleConstraint[] requires = rb.getRequires(); @@ -1472,6 +1498,16 @@ public class ResolverImpl implements org.eclipse.osgi.service.resolver.Resolver state.resolveBundle(rb.getBundle(), rb.isResolved(), hostBundles, selectedExportsArray, substitutedExportsArray, bundlesWiredToArray, exportsWiredToArray); } + private static ExportPackageDescription[] getExportsWiredTo(ResolverBundle rb) { + // Gather exports that have been wired to + ResolverImport[] imports = rb.getImportPackages(); + ArrayList exportsWiredTo = new ArrayList(imports.length); + for (int i = 0; i < imports.length; i++) + if (imports[i].getSelectedSupplier() != null) + exportsWiredTo.add(imports[i].getSelectedSupplier().getBaseDescription()); + return (ExportPackageDescription[]) exportsWiredTo.toArray(new ExportPackageDescription[exportsWiredTo.size()]); + } + // Resolve dynamic import public synchronized ExportPackageDescription resolveDynamicImport(BundleDescription importingBundle, String requestedPackage) { if (state == null) @@ -1616,6 +1652,12 @@ public class ResolverImpl implements org.eclipse.osgi.service.resolver.Resolver if (!bundle.getBundle().isResolved() && !developmentMode) return; + CompositeResolveHelperRegistry currentLinks = compositeHelpers; + if (currentLinks != null) { + CompositeResolveHelper helper = currentLinks.getCompositeResolveHelper(bundle.getBundle()); + if (helper != null) + helper.giveExports(null); + } // if not removed then add to the list of unresolvedBundles, // passing false for devmode because we need all fragments detached setBundleUnresolved(bundle, removed, false); @@ -1739,4 +1781,12 @@ public class ResolverImpl implements org.eclipse.osgi.service.resolver.Resolver public Comparator getSelectionPolicy() { return selectionPolicy; } + + public void setCompositeResolveHelperRegistry(CompositeResolveHelperRegistry compositeHelpers) { + this.compositeHelpers = compositeHelpers; + } + + CompositeResolveHelperRegistry getCompositeHelpers() { + return compositeHelpers; + } } diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateImpl.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateImpl.java index 39b8c553f..d369399c9 100644 --- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateImpl.java +++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateImpl.java @@ -19,6 +19,7 @@ import org.eclipse.osgi.framework.internal.core.Constants; import org.eclipse.osgi.framework.internal.core.FilterImpl; import org.eclipse.osgi.framework.util.*; import org.eclipse.osgi.internal.baseadaptor.StateManager; +import org.eclipse.osgi.internal.loader.BundleLoaderProxy; import org.eclipse.osgi.service.resolver.*; import org.eclipse.osgi.util.ManifestElement; import org.eclipse.osgi.util.NLS; @@ -121,7 +122,7 @@ public abstract class StateImpl implements State { if (getSystemBundle().equals(newDescription.getSymbolicName())) resetSystemExports(); if (resolver != null) { - boolean pending = existing.getDependents().length > 0; + boolean pending = isInUse(existing); resolver.bundleUpdated(newDescription, existing, pending); if (pending) { getDelta().recordBundleRemovalPending(existing); @@ -161,7 +162,7 @@ public abstract class StateImpl implements State { getDelta().recordBundleRemoved((BundleDescriptionImpl) toRemove); ((BundleDescriptionImpl) toRemove).setStateBit(BundleDescriptionImpl.REMOVAL_PENDING, true); if (resolver != null) { - boolean pending = toRemove.getDependents().length > 0; + boolean pending = isInUse(toRemove); resolver.bundleRemoved(toRemove, pending); if (pending) { getDelta().recordBundleRemovalPending((BundleDescriptionImpl) toRemove); @@ -182,6 +183,13 @@ public abstract class StateImpl implements State { } } + private boolean isInUse(BundleDescription bundle) { + Object userObject = bundle.getUserObject(); + if (userObject instanceof BundleLoaderProxy) + return ((BundleLoaderProxy) userObject).inUse(); + return bundle.getDependents().length > 0; + } + public StateDelta getChanges() { synchronized (this.monitor) { return getDelta(); |