Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Watson2012-10-10 14:56:16 +0000
committerThomas Watson2012-10-10 14:56:16 +0000
commitc4443d18acafe486c4f38ea4ce880a304ba8892f (patch)
tree86d2819972f039eaf2a550f73779aabaeb6b365a /bundles
parentafd5f96ac81c0cc17918da755c85b32ce4fabded (diff)
downloadrt.equinox.framework-c4443d18acafe486c4f38ea4ce880a304ba8892f.tar.gz
rt.equinox.framework-c4443d18acafe486c4f38ea4ce880a304ba8892f.tar.xz
rt.equinox.framework-c4443d18acafe486c4f38ea4ce880a304ba8892f.zip
Bug 358923 - [R5] Improve support for multiple cardinality and uses constraints on generic capabilitiesv20121010-145616
Diffstat (limited to 'bundles')
-rw-r--r--bundles/org.eclipse.osgi.tests/META-INF/MANIFEST.MF2
-rw-r--r--bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/services/resolver/OSGiCapabilityTest.java104
-rw-r--r--bundles/org.eclipse.osgi.tests/test_files/genericCapability/c6.v100.osgi.MF7
-rw-r--r--bundles/org.eclipse.osgi.tests/test_files/genericCapability/c6.v110.osgi.MF7
-rw-r--r--bundles/org.eclipse.osgi.tests/test_files/genericCapability/c6.v120.osgi.MF7
-rw-r--r--bundles/org.eclipse.osgi.tests/test_files/genericCapability/c6.v130.osgi.MF7
-rw-r--r--bundles/org.eclipse.osgi.tests/test_files/genericCapability/c6.v140.osgi.MF7
-rw-r--r--bundles/org.eclipse.osgi.tests/test_files/genericCapability/c6.v150.osgi.MF7
-rw-r--r--bundles/org.eclipse.osgi.tests/test_files/genericCapability/c6.v160.osgi.MF7
-rw-r--r--bundles/org.eclipse.osgi.tests/test_files/genericCapability/p5.v101.osgi.MF7
-rw-r--r--bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/GenericConstraint.java22
-rw-r--r--bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/GroupingChecker.java22
-rw-r--r--bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/ResolverImpl.java47
13 files changed, 215 insertions, 38 deletions
diff --git a/bundles/org.eclipse.osgi.tests/META-INF/MANIFEST.MF b/bundles/org.eclipse.osgi.tests/META-INF/MANIFEST.MF
index 4e1b54fd7..64a7849bd 100644
--- a/bundles/org.eclipse.osgi.tests/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.osgi.tests/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Core OSGi Tests
Bundle-SymbolicName: org.eclipse.osgi.tests;singleton:=true
-Bundle-Version: 3.8.0.qualifier
+Bundle-Version: 3.9.0.qualifier
Bundle-ClassPath: osgitests.jar
Bundle-Vendor: Eclipse.org
Bundle-Localization: plugin
diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/services/resolver/OSGiCapabilityTest.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/services/resolver/OSGiCapabilityTest.java
index 6e00f7614..69514c36e 100644
--- a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/services/resolver/OSGiCapabilityTest.java
+++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/services/resolver/OSGiCapabilityTest.java
@@ -415,6 +415,110 @@ public class OSGiCapabilityTest extends AbstractStateTest {
checkUsedCapability(c4v130, p5v100Capability);
}
+ public void testOSGiCardinalityUses() throws BundleException {
+ State state = buildEmptyState();
+ long bundleID = 0;
+ Dictionary manifest;
+
+ manifest = loadManifest("p5.v100.osgi.MF");
+ BundleDescription p5v100 = state.getFactory().createBundleDescription(state, manifest, (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME), bundleID++);
+ manifest = loadManifest("p5.v101.osgi.MF");
+ BundleDescription p5v101 = state.getFactory().createBundleDescription(state, manifest, (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME), bundleID++);
+ manifest = loadManifest("p5.v110.osgi.MF");
+ BundleDescription p5v110 = state.getFactory().createBundleDescription(state, manifest, (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME), bundleID++);
+ manifest = loadManifest("p6.v100.osgi.MF");
+ BundleDescription p6v100 = state.getFactory().createBundleDescription(state, manifest, (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME), bundleID++);
+ manifest = loadManifest("p6.v110.osgi.MF");
+ BundleDescription p6v110 = state.getFactory().createBundleDescription(state, manifest, (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME), bundleID++);
+ manifest = loadManifest("p7.v100.osgi.MF");
+ BundleDescription p7v100 = state.getFactory().createBundleDescription(state, manifest, (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME), bundleID++);
+ manifest = loadManifest("p7.v110.osgi.MF");
+ BundleDescription p7v110 = state.getFactory().createBundleDescription(state, manifest, (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME), bundleID++);
+ manifest = loadManifest("c6.v100.osgi.MF");
+ BundleDescription c6v100 = state.getFactory().createBundleDescription(state, manifest, (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME), bundleID++);
+ manifest = loadManifest("c6.v110.osgi.MF");
+ BundleDescription c6v110 = state.getFactory().createBundleDescription(state, manifest, (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME), bundleID++);
+ manifest = loadManifest("c6.v120.osgi.MF");
+ BundleDescription c6v120 = state.getFactory().createBundleDescription(state, manifest, (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME), bundleID++);
+ manifest = loadManifest("c6.v130.osgi.MF");
+ BundleDescription c6v130 = state.getFactory().createBundleDescription(state, manifest, (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME), bundleID++);
+ manifest = loadManifest("c6.v140.osgi.MF");
+ BundleDescription c6v140 = state.getFactory().createBundleDescription(state, manifest, (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME), bundleID++);
+
+ state.addBundle(p5v100);
+ state.addBundle(p5v101);
+ state.addBundle(p5v110);
+ state.addBundle(p6v100);
+ state.addBundle(p6v110);
+ state.addBundle(p7v100);
+ state.addBundle(p7v110);
+ state.addBundle(c6v100);
+ state.addBundle(c6v110);
+ state.addBundle(c6v120);
+ state.addBundle(c6v130);
+ state.addBundle(c6v140);
+
+ state.resolve();
+
+ assertTrue("p5v100", p5v100.isResolved());
+ assertTrue("p5v100", p5v101.isResolved());
+ assertTrue("p5v110", p5v110.isResolved());
+ assertTrue("p6v100", p6v100.isResolved());
+ assertTrue("p6v110", p6v110.isResolved());
+ assertTrue("p7v100", p7v100.isResolved());
+ assertTrue("p7v110", p7v110.isResolved());
+ assertTrue("c6v100", c6v100.isResolved());
+ assertTrue("c6v110", c6v110.isResolved());
+ assertTrue("c6v120", c6v120.isResolved());
+ assertTrue("c6v130", c6v130.isResolved());
+ assertTrue("c6v140", c6v140.isResolved());
+
+ state.linkDynamicImport(c6v120, "p6");
+ state.linkDynamicImport(c6v120, "p7");
+
+ GenericDescription[] p5v100Capability = p5v100.getSelectedGenericCapabilities();
+ GenericDescription[] p5v101Capability = p5v101.getSelectedGenericCapabilities();
+ List expectedCapabilityList = new ArrayList();
+ expectedCapabilityList.addAll(Arrays.asList(p5v100Capability));
+ expectedCapabilityList.addAll(Arrays.asList(p5v101Capability));
+ for (Iterator iCapabilities = expectedCapabilityList.iterator(); iCapabilities.hasNext();) {
+ if (!"namespace.5".equals(((GenericDescription) iCapabilities.next()).getType())) {
+ iCapabilities.remove();
+ }
+ }
+
+ ExportPackageDescription[] p6v100Exports = p6v100.getSelectedExports();
+ ExportPackageDescription[] p7v100Exports = p7v100.getSelectedExports();
+ ExportPackageDescription[] expectedPackages = new ExportPackageDescription[] {p6v100Exports[0], p7v100Exports[0]};
+
+ checkUsedImports(c6v100, expectedPackages);
+ checkUsedImports(c6v110, expectedPackages);
+ checkUsedImports(c6v120, expectedPackages);
+
+ BundleDescription[] expectedRequired = new BundleDescription[] {p6v100, p7v100};
+ checkUsedRequires(c6v130, expectedRequired);
+ checkUsedRequires(c6v140, expectedRequired);
+
+ GenericDescription[] expectedCapabilities = (GenericDescription[]) expectedCapabilityList.toArray(new GenericDescription[expectedCapabilityList.size()]);
+ checkUsedCapability(c6v100, expectedCapabilities);
+ checkUsedCapability(c6v110, expectedCapabilities);
+ checkUsedCapability(c6v120, expectedCapabilities);
+ checkUsedCapability(c6v130, expectedCapabilities);
+ checkUsedCapability(c6v140, expectedCapabilities);
+
+ manifest = loadManifest("c6.v150.osgi.MF");
+ BundleDescription c6v150 = state.getFactory().createBundleDescription(state, manifest, (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME), bundleID++);
+ manifest = loadManifest("c6.v160.osgi.MF");
+ BundleDescription c6v160 = state.getFactory().createBundleDescription(state, manifest, (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME), bundleID++);
+
+ state.addBundle(c6v150);
+ state.addBundle(c6v160);
+ state.resolve();
+
+ assertFalse("c6v150", c6v150.isResolved());
+ assertFalse("c6v160", c6v160.isResolved());
+ }
+
public void testDeclaringIdentityCapability() {
State state = buildEmptyState();
Hashtable manifest = new Hashtable();
diff --git a/bundles/org.eclipse.osgi.tests/test_files/genericCapability/c6.v100.osgi.MF b/bundles/org.eclipse.osgi.tests/test_files/genericCapability/c6.v100.osgi.MF
new file mode 100644
index 000000000..1ebc43565
--- /dev/null
+++ b/bundles/org.eclipse.osgi.tests/test_files/genericCapability/c6.v100.osgi.MF
@@ -0,0 +1,7 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: c6.osgi
+Bundle-Version: 1.0
+Require-Capability:
+ namespace.5; filter:="(version=1.0)"; cardinality:="multiple"
+Import-Package: p6, p7
diff --git a/bundles/org.eclipse.osgi.tests/test_files/genericCapability/c6.v110.osgi.MF b/bundles/org.eclipse.osgi.tests/test_files/genericCapability/c6.v110.osgi.MF
new file mode 100644
index 000000000..ffb12e753
--- /dev/null
+++ b/bundles/org.eclipse.osgi.tests/test_files/genericCapability/c6.v110.osgi.MF
@@ -0,0 +1,7 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: c6.osgi
+Bundle-Version: 1.1
+Require-Capability:
+ namespace.5; filter:="(namespace.5=test)"; cardinality:="multiple"
+Import-Package: p6; p7; version="[1.0,1.1)"
diff --git a/bundles/org.eclipse.osgi.tests/test_files/genericCapability/c6.v120.osgi.MF b/bundles/org.eclipse.osgi.tests/test_files/genericCapability/c6.v120.osgi.MF
new file mode 100644
index 000000000..e684e0771
--- /dev/null
+++ b/bundles/org.eclipse.osgi.tests/test_files/genericCapability/c6.v120.osgi.MF
@@ -0,0 +1,7 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: c6.osgi
+Bundle-Version: 1.2
+Require-Capability:
+ namespace.5; filter:="(version=1.0)"; cardinality:="multiple"
+DynamicImport-Package: p6, p7
diff --git a/bundles/org.eclipse.osgi.tests/test_files/genericCapability/c6.v130.osgi.MF b/bundles/org.eclipse.osgi.tests/test_files/genericCapability/c6.v130.osgi.MF
new file mode 100644
index 000000000..44fe7cfcb
--- /dev/null
+++ b/bundles/org.eclipse.osgi.tests/test_files/genericCapability/c6.v130.osgi.MF
@@ -0,0 +1,7 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: c6.osgi
+Bundle-Version: 1.3
+Require-Capability:
+ namespace.5; filter:="(version=1.0)"; cardinality:="multiple"
+Require-Bundle: p6.osgi, p7.osgi
diff --git a/bundles/org.eclipse.osgi.tests/test_files/genericCapability/c6.v140.osgi.MF b/bundles/org.eclipse.osgi.tests/test_files/genericCapability/c6.v140.osgi.MF
new file mode 100644
index 000000000..9e0d9963a
--- /dev/null
+++ b/bundles/org.eclipse.osgi.tests/test_files/genericCapability/c6.v140.osgi.MF
@@ -0,0 +1,7 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: c6.osgi
+Bundle-Version: 1.4
+Require-Capability:
+ namespace.5; filter:="(namespace.5=test)"; cardinality:="multiple"
+Require-Bundle: p6.osgi; bundle-version="[1.0,1.1)", p7.osgi; bundle-version="[1.0,1.1)"
diff --git a/bundles/org.eclipse.osgi.tests/test_files/genericCapability/c6.v150.osgi.MF b/bundles/org.eclipse.osgi.tests/test_files/genericCapability/c6.v150.osgi.MF
new file mode 100644
index 000000000..9693fa4a0
--- /dev/null
+++ b/bundles/org.eclipse.osgi.tests/test_files/genericCapability/c6.v150.osgi.MF
@@ -0,0 +1,7 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: c6.osgi
+Bundle-Version: 1.5
+Require-Capability:
+ namespace.5; filter:="(version=1.0)"; cardinality:="multiple"
+Import-Package: p6; p7; version="[1.1,1.2)"
diff --git a/bundles/org.eclipse.osgi.tests/test_files/genericCapability/c6.v160.osgi.MF b/bundles/org.eclipse.osgi.tests/test_files/genericCapability/c6.v160.osgi.MF
new file mode 100644
index 000000000..b4b513318
--- /dev/null
+++ b/bundles/org.eclipse.osgi.tests/test_files/genericCapability/c6.v160.osgi.MF
@@ -0,0 +1,7 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: c6.osgi
+Bundle-Version: 1.6
+Require-Capability:
+ namespace.5; filter:="(version=1.0)"; cardinality:="multiple"
+Require-Bundle: p6.osgi; bundle-version="[1.1,1.2)", p7.osgi; bundle-version="[1.1,1.2)"
diff --git a/bundles/org.eclipse.osgi.tests/test_files/genericCapability/p5.v101.osgi.MF b/bundles/org.eclipse.osgi.tests/test_files/genericCapability/p5.v101.osgi.MF
new file mode 100644
index 000000000..b17f58dfb
--- /dev/null
+++ b/bundles/org.eclipse.osgi.tests/test_files/genericCapability/p5.v101.osgi.MF
@@ -0,0 +1,7 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: p5.osgi
+Bundle-Version: 1.0.1
+Provide-Capability:
+ namespace.5; namespace.5=test; version:Version="1.0"; uses:="p6, p7"
+Import-Package: p6; p7; version="[1.0,1.1)"
diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/GenericConstraint.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/GenericConstraint.java
index a84a05812..44589173c 100644
--- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/GenericConstraint.java
+++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/GenericConstraint.java
@@ -17,12 +17,13 @@ import org.osgi.framework.Constants;
public class GenericConstraint extends ResolverConstraint {
private final boolean effective;
- private boolean supplierHasUses;
+ private final boolean multiple;
GenericConstraint(ResolverBundle bundle, GenericSpecification constraint) {
super(bundle, constraint);
String effectiveDirective = constraint.getRequirement().getDirectives().get(Constants.EFFECTIVE_DIRECTIVE);
effective = effectiveDirective == null || Constants.EFFECTIVE_RESOLVE.equals(effectiveDirective);
+ multiple = (constraint.getResolution() & GenericSpecification.RESOLUTION_MULTIPLE) != 0;
}
boolean isOptional() {
@@ -34,7 +35,7 @@ public class GenericConstraint extends ResolverConstraint {
}
boolean isMultiple() {
- return !supplierHasUses && (((GenericSpecification) constraint).getResolution() & GenericSpecification.RESOLUTION_MULTIPLE) != 0;
+ return multiple;
}
boolean isEffective() {
@@ -51,21 +52,4 @@ public class GenericConstraint extends ResolverConstraint {
VersionSupplier supplier = getSelectedSupplier();
return supplier == null ? null : new VersionSupplier[] {supplier};
}
-
- @Override
- void addPossibleSupplier(VersionSupplier supplier) {
- // if there is a supplier with uses constraints then we no longer allow multiples
- supplierHasUses |= ((GenericCapability) supplier).getUsesDirective() != null;
- super.addPossibleSupplier(supplier);
- }
-
- @Override
- void clearPossibleSuppliers() {
- super.clearPossibleSuppliers();
- supplierHasUses = false;
- }
-
- boolean supplierHasUses() {
- return supplierHasUses;
- }
}
diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/GroupingChecker.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/GroupingChecker.java
index ea39971bd..0acce4bd7 100644
--- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/GroupingChecker.java
+++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/GroupingChecker.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2004, 2011 IBM Corporation and others. All rights reserved.
+ * Copyright (c) 2004, 2012 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
@@ -145,16 +145,18 @@ public class GroupingChecker {
// We also must check any generic capabilities are consistent
GenericConstraint[] genericRequires = importingBundle.getGenericRequires();
for (GenericConstraint constraint : genericRequires) {
- if (!constraint.supplierHasUses())
- continue;
- GenericCapability supplier = (GenericCapability) constraint.getSelectedSupplier();
- String[] uses = supplier.getUsesDirective();
- if (uses != null)
- for (String usedPackage : uses) {
- if (usedPackage.equals(matchingExport.getName())) {
- results = exportingRoots.addConflicts(supplier.getResolverBundle(), usedPackage, null, results);
- }
+ VersionSupplier[] suppliers = constraint.getMatchingCapabilities();
+ if (suppliers != null) {
+ for (VersionSupplier supplier : suppliers) {
+ String[] uses = ((GenericCapability) supplier).getUsesDirective();
+ if (uses != null)
+ for (String usedPackage : uses) {
+ if (usedPackage.equals(matchingExport.getName())) {
+ results = exportingRoots.addConflicts(supplier.getResolverBundle(), usedPackage, null, results);
+ }
+ }
}
+ }
}
return results;
}
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 beeed64c9..d0d54fdaa 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
@@ -872,8 +872,9 @@ public class ResolverImpl implements Resolver {
return null;
Set<String> bundleConstraints = new HashSet<String>();
Set<String> packageConstraints = new HashSet<String>();
+ Collection<GenericConstraint> multiRequirementWithMultiSuppliers = new ArrayList<GenericConstraint>();
// first try out the initial selections
- List<ResolverConstraint> initialConflicts = getConflicts(bundles, packageConstraints, bundleConstraints);
+ List<ResolverConstraint> initialConflicts = getConflicts(bundles, packageConstraints, bundleConstraints, multiRequirementWithMultiSuppliers);
if (initialConflicts == null || "tryFirst".equals(usesMode) || usesCalculationTimeout) { //$NON-NLS-1$
groupingChecker.clear();
// the first combination have no conflicts or
@@ -899,7 +900,19 @@ public class ResolverImpl implements Resolver {
selectedSupplier.setSubstitute(null);
}
}
-
+ if (!multiRequirementWithMultiSuppliers.isEmpty()) {
+ groupingChecker.clear();
+ for (GenericConstraint multiConstraint : multiRequirementWithMultiSuppliers) {
+ VersionSupplier[] matchingSuppliers = multiConstraint.getMatchingCapabilities();
+ if (matchingSuppliers != null) {
+ for (VersionSupplier supplier : matchingSuppliers) {
+ if (groupingChecker.isConsistent(multiConstraint.getBundle(), (GenericCapability) supplier) != null) {
+ multiConstraint.removePossibleSupplier(supplier);
+ }
+ }
+ }
+ }
+ }
// do not need to keep uses data in memory
groupingChecker.clear();
return conflicts;
@@ -936,7 +949,7 @@ public class ResolverImpl implements Resolver {
// first count the conflicts for the bundles with conflicts from the best combination
// this significantly reduces the time it takes to populate the GroupingChecker for cases where
// the combination is no better.
- List<ResolverConstraint> conflicts = getConflicts(bestConflictBundles, null, null);
+ List<ResolverConstraint> conflicts = getConflicts(bestConflictBundles, null, null, null);
int conflictCount = getConflictCount(conflicts);
if (conflictCount >= bestConflictCount) {
if (DEBUG_USES)
@@ -947,7 +960,7 @@ public class ResolverImpl implements Resolver {
}
// this combination improves upon the conflicts for the bundles which conflict with the current best combination;
// do an complete conflict count
- conflicts = getConflicts(bundles, null, null);
+ conflicts = getConflicts(bundles, null, null, null);
conflictCount = getConflictCount(conflicts);
if (conflictCount < bestConflictCount) {
// this combination is better that the current best combination; save this combination as the current best
@@ -1012,15 +1025,15 @@ public class ResolverImpl implements Resolver {
return result;
}
- private List<ResolverConstraint> getConflicts(ResolverBundle[] bundles, Set<String> packageConstraints, Set<String> bundleConstraints) {
+ private List<ResolverConstraint> getConflicts(ResolverBundle[] bundles, Set<String> packageConstraints, Set<String> bundleConstraints, Collection<GenericConstraint> multiRequirementWithMultiSuppliers) {
groupingChecker.clear();
List<ResolverConstraint> conflicts = null;
for (int i = 0; i < bundles.length; i++)
- conflicts = addConflicts(bundles[i], packageConstraints, bundleConstraints, conflicts);
+ conflicts = addConflicts(bundles[i], packageConstraints, bundleConstraints, multiRequirementWithMultiSuppliers, conflicts);
return conflicts;
}
- private List<ResolverConstraint> addConflicts(ResolverBundle bundle, Set<String> packageConstraints, Set<String> bundleConstraints, List<ResolverConstraint> conflicts) {
+ private List<ResolverConstraint> addConflicts(ResolverBundle bundle, Set<String> packageConstraints, Set<String> bundleConstraints, Collection<GenericConstraint> multiRequirementWithMultiSuppliers, List<ResolverConstraint> conflicts) {
BundleConstraint[] requires = bundle.getRequires();
for (int i = 0; i < requires.length; i++) {
ResolverBundle selectedSupplier = (ResolverBundle) requires[i].getSelectedSupplier();
@@ -1049,10 +1062,28 @@ public class ResolverImpl implements Resolver {
VersionSupplier[] suppliers = capabilityRequirement.getMatchingCapabilities();
if (suppliers == null)
continue;
+
+ if (multiRequirementWithMultiSuppliers != null && capabilityRequirement.isMultiple() && suppliers.length > 1) {
+ multiRequirementWithMultiSuppliers.add(capabilityRequirement);
+ }
+ // search for at least one capability that does not conflict
+ // in case of single cardinality there will only be one matching supplier
+ // in case of multiple there may be multiple suppliers, but we only need one or more to not conflict with the class space
+ Collection<PackageRoots[][]> capabilityConflicts = null;
for (VersionSupplier supplier : suppliers) {
PackageRoots[][] conflict = groupingChecker.isConsistent(bundle, (GenericCapability) supplier);
if (conflict != null) {
+ if (capabilityConflicts == null)
+ capabilityConflicts = new ArrayList<PackageRoots[][]>(1);
+ capabilityConflicts.add(conflict);
+ }
+ }
+ if (capabilityConflicts != null) {
+ for (PackageRoots[][] conflict : capabilityConflicts) {
addConflictNames(conflict, packageConstraints, bundleConstraints);
+ }
+ if (capabilityConflicts.size() == suppliers.length) {
+ // every capability conflicted
if (conflicts == null)
conflicts = new ArrayList<ResolverConstraint>(1);
conflicts.add(capabilityRequirement);
@@ -1126,7 +1157,7 @@ public class ResolverImpl implements Resolver {
}
GenericConstraint[] genericRequires = bundle.getGenericRequires();
for (GenericConstraint genericRequire : genericRequires)
- if (genericRequire.getNumPossibleSuppliers() > 1 && genericRequire.supplierHasUses())
+ if (genericRequire.getNumPossibleSuppliers() > 1 && !genericRequire.isMultiple())
multipleGenericSupplierList.add(genericRequire);
}
List<ResolverConstraint[]> results = new ArrayList<ResolverConstraint[]>();

Back to the top