Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Watson2008-12-19 21:10:00 +0000
committerThomas Watson2008-12-19 21:10:00 +0000
commitc0bf408b216d2511900a0e48b4185d50fb6017e2 (patch)
treecc91e6e2a43514f5088471048125db7503fed0b8 /bundles/org.eclipse.osgi/resolver
parentf1a814066412e3ae14174179eea848452496bb34 (diff)
downloadrt.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')
-rw-r--r--bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/CompositeResolveHelper.java17
-rw-r--r--bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/CompositeResolveHelperRegistry.java17
-rw-r--r--bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/ResolverBundle.java8
-rw-r--r--bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/ResolverImpl.java124
-rw-r--r--bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateImpl.java12
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();

Back to the top