Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Watson2010-09-10 21:07:23 +0000
committerThomas Watson2010-09-10 21:07:23 +0000
commit7076dcc6df0d657844e66a5b391f7ef8b29de63e (patch)
treefa65bcf4367c61ec8170bccd0d486c8e122e2c83 /bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/GroupingChecker.java
parent3970c45e2cf13db77bf65732ed8e069f5a221406 (diff)
downloadrt.equinox.framework-7076dcc6df0d657844e66a5b391f7ef8b29de63e.tar.gz
rt.equinox.framework-7076dcc6df0d657844e66a5b391f7ef8b29de63e.tar.xz
rt.equinox.framework-7076dcc6df0d657844e66a5b391f7ef8b29de63e.zip
Bug 323427 - [RFC 154] Support for generic capabilities and requirementsv20100910
Diffstat (limited to 'bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/GroupingChecker.java')
-rw-r--r--bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/GroupingChecker.java96
1 files changed, 68 insertions, 28 deletions
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 737bd958e..f86617081 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
@@ -20,7 +20,7 @@ public class GroupingChecker {
// a mapping of bundles to their package roots; keyed by
// ResolverBundle -> HashMap of packages; keyed by
// package name -> PackageRoots
- private HashMap bundles = new HashMap();
+ private Map<ResolverBundle, Map<String, PackageRoots>> bundles = new HashMap<ResolverBundle, Map<String, PackageRoots>>();
/*
* This method fully populates a bundles package roots for the purpose of resolving
@@ -34,7 +34,7 @@ public class GroupingChecker {
for (int j = 0; j < requires.length; j++) {
ResolverBundle selectedSupplier = (ResolverBundle) requires[j].getSelectedSupplier();
if (selectedSupplier != null)
- isConsistentInternal(bundle, selectedSupplier, new ArrayList(1), true, null);
+ isConsistentInternal(bundle, selectedSupplier, new ArrayList<ResolverBundle>(1), true, null);
}
// process all imports
// must check resolved imports to get any dynamically resolved imports
@@ -53,11 +53,11 @@ public class GroupingChecker {
* If an inconsistency is found the export inconsistency is returned; otherwise null is returned
*/
public PackageRoots[][] isConsistent(ResolverBundle requiringBundle, ResolverBundle matchingBundle) {
- ArrayList results = isConsistentInternal(requiringBundle, matchingBundle, new ArrayList(1), false, null);
- return results == null ? null : (PackageRoots[][]) results.toArray(new PackageRoots[results.size()][]);
+ List<PackageRoots[]> results = isConsistentInternal(requiringBundle, matchingBundle, new ArrayList<ResolverBundle>(1), false, null);
+ return results == null ? null : results.toArray(new PackageRoots[results.size()][]);
}
- private ArrayList isConsistentInternal(ResolverBundle requiringBundle, ResolverBundle matchingBundle, ArrayList visited, boolean dynamicImport, ArrayList results) {
+ private List<PackageRoots[]> isConsistentInternal(ResolverBundle requiringBundle, ResolverBundle matchingBundle, List<ResolverBundle> visited, boolean dynamicImport, List<PackageRoots[]> results) {
// needed to prevent endless cycles
if (visited.contains(matchingBundle))
return results;
@@ -86,8 +86,20 @@ public class GroupingChecker {
* If an inconsistency is found the export returned; otherwise null is returned
*/
public PackageRoots[][] isConsistent(ResolverBundle importingBundle, ResolverExport matchingExport) {
- ArrayList results = isConsistentInternal(importingBundle, matchingExport, false, null);
- return results == null ? null : (PackageRoots[][]) results.toArray(new PackageRoots[results.size()][]);
+ List<PackageRoots[]> results = isConsistentInternal(importingBundle, matchingExport, false, null);
+ return results == null ? null : results.toArray(new PackageRoots[results.size()][]);
+ }
+
+ public PackageRoots[][] isConsistent(ResolverBundle requiringBundle, GenericCapability matchingCapability) {
+ String[] uses = matchingCapability.getUsesDirective();
+ if (uses == null)
+ return null;
+ ArrayList<PackageRoots[]> results = new ArrayList<PackageRoots[]>(0);
+ for (String usedPackage : uses) {
+ PackageRoots providingRoots = getPackageRoots(matchingCapability.getResolverBundle(), usedPackage, null);
+ providingRoots.addConflicts(requiringBundle, usedPackage, null, results);
+ }
+ return results.size() == 0 ? null : results.toArray(new PackageRoots[results.size()][]);
}
/*
@@ -97,11 +109,11 @@ public class GroupingChecker {
* consistent with the possible matching dynamic export.
*/
public PackageRoots[][] isDynamicConsistent(ResolverBundle importingBundle, ResolverExport matchingExport) {
- ArrayList results = isConsistentInternal(importingBundle, matchingExport, true, null);
- return results == null ? null : (PackageRoots[][]) results.toArray(new PackageRoots[results.size()][]);
+ List<PackageRoots[]> results = isConsistentInternal(importingBundle, matchingExport, true, null);
+ return results == null ? null : results.toArray(new PackageRoots[results.size()][]);
}
- private ArrayList isConsistentInternal(ResolverBundle importingBundle, ResolverExport matchingExport, boolean dyanamicImport, ArrayList results) {
+ private List<PackageRoots[]> isConsistentInternal(ResolverBundle importingBundle, ResolverExport matchingExport, boolean dyanamicImport, List<PackageRoots[]> results) {
PackageRoots exportingRoots = getPackageRoots(matchingExport.getExporter(), matchingExport.getName(), null);
// check that the exports uses packages are consistent with existing package roots
results = exportingRoots.isConsistentClassSpace(importingBundle, null, results);
@@ -109,34 +121,48 @@ public class GroupingChecker {
return results;
// for dynamic imports we must check that each existing root is consistent with the possible matching export
PackageRoots importingRoots = getPackageRoots(importingBundle, matchingExport.getName(), null);
- HashMap importingPackages = (HashMap) bundles.get(importingBundle);
+ Map<String, PackageRoots> importingPackages = bundles.get(importingBundle);
if (importingPackages != null)
- for (Iterator allImportingPackages = importingPackages.values().iterator(); allImportingPackages.hasNext();) {
- PackageRoots roots = (PackageRoots) allImportingPackages.next();
+ for (Iterator<PackageRoots> allImportingPackages = importingPackages.values().iterator(); allImportingPackages.hasNext();) {
+ PackageRoots roots = allImportingPackages.next();
if (roots != importingRoots)
results = roots.isConsistentClassSpace(exportingRoots, matchingExport.getExporter(), null, results);
}
+ // 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);
+ }
+ }
+ }
return results;
}
/*
* returns package roots for a specific package name for a specific bundle
*/
- PackageRoots getPackageRoots(ResolverBundle bundle, String packageName, ArrayList visited) {
- HashMap packages = (HashMap) bundles.get(bundle);
+ PackageRoots getPackageRoots(ResolverBundle bundle, String packageName, List<ResolverBundle> visited) {
+ Map<String, PackageRoots> packages = bundles.get(bundle);
if (packages == null) {
- packages = new HashMap(5);
+ packages = new HashMap<String, PackageRoots>(5);
bundles.put(bundle, packages);
}
- PackageRoots packageRoots = (PackageRoots) packages.get(packageName);
+ PackageRoots packageRoots = packages.get(packageName);
if (packageRoots == null) {
- packageRoots = createPackageRoots(bundle, packageName, visited == null ? new ArrayList(1) : visited);
+ packageRoots = createPackageRoots(bundle, packageName, visited == null ? new ArrayList<ResolverBundle>(1) : visited);
packages.put(packageName, packageRoots);
}
return packageRoots != null ? packageRoots : nullPackageRoots;
}
- private PackageRoots createPackageRoots(ResolverBundle bundle, String packageName, ArrayList visited) {
+ private PackageRoots createPackageRoots(ResolverBundle bundle, String packageName, List<ResolverBundle> visited) {
if (visited.contains(bundle))
return null;
visited.add(bundle); // prevent endless cycles
@@ -167,7 +193,7 @@ public class GroupingChecker {
}
// check if the bundle exports the package
ResolverExport[] exports = bundle.getExports(packageName);
- ArrayList roots = new ArrayList(0);
+ List<PackageRoots> roots = new ArrayList<PackageRoots>(0);
// check roots from required bundles
BundleConstraint[] requires = bundle.getRequires();
for (int i = 0; i < requires.length; i++) {
@@ -196,7 +222,7 @@ public class GroupingChecker {
}
}
if (exports.length > 0 || roots.size() > 1) {
- PackageRoots[] requiredRoots = (PackageRoots[]) roots.toArray(new PackageRoots[roots.size()]);
+ PackageRoots[] requiredRoots = roots.toArray(new PackageRoots[roots.size()]);
if (exports.length == 0) {
PackageRoots superSet = requiredRoots[0];
for (int i = 1; i < requiredRoots.length; i++) {
@@ -220,7 +246,7 @@ public class GroupingChecker {
result.addRoot(exports[i]);
return result;
}
- return (PackageRoots) (roots.size() == 0 ? nullPackageRoots : roots.get(0));
+ return roots.size() == 0 ? nullPackageRoots : roots.get(0);
}
public void clear() {
@@ -280,11 +306,11 @@ public class GroupingChecker {
addRoot(packageRoots.roots[i]);
}
- public ArrayList isConsistentClassSpace(ResolverBundle importingBundle, ArrayList visited, ArrayList results) {
+ public List<PackageRoots[]> isConsistentClassSpace(ResolverBundle importingBundle, List<PackageRoots> visited, List<PackageRoots[]> results) {
if (roots == null)
return results;
if (visited == null)
- visited = new ArrayList(1);
+ visited = new ArrayList<PackageRoots>(1);
if (visited.contains(this))
return results;
visited.add(this);
@@ -304,7 +330,7 @@ public class GroupingChecker {
if (thisUsedRoots != nullPackageRoots && importingUsedRoots != nullPackageRoots)
if (!(subSet(thisUsedRoots.roots, importingUsedRoots.roots) || subSet(importingUsedRoots.roots, thisUsedRoots.roots))) {
if (results == null)
- results = new ArrayList(1);
+ results = new ArrayList<PackageRoots[]>(1);
results.add(new PackageRoots[] {this, importingUsedRoots});
}
// need to check the usedRoots consistency for transitive closure
@@ -314,7 +340,7 @@ public class GroupingChecker {
return results;
}
- public ArrayList isConsistentClassSpace(PackageRoots exportingRoots, ResolverBundle exporter, ArrayList visited, ArrayList results) {
+ public List<PackageRoots[]> isConsistentClassSpace(PackageRoots exportingRoots, ResolverBundle exporter, List<PackageRoots> visited, List<PackageRoots[]> results) {
if (roots == null)
return results;
int size = roots.length;
@@ -324,7 +350,7 @@ public class GroupingChecker {
if (uses == null)
continue;
if (visited == null)
- visited = new ArrayList(1);
+ visited = new ArrayList<PackageRoots>(1);
if (visited.contains(this))
return results;
visited.add(this);
@@ -338,7 +364,7 @@ public class GroupingChecker {
if (thisUsedRoots != nullPackageRoots && exportingUsedRoots != nullPackageRoots)
if (!(subSet(thisUsedRoots.roots, exportingUsedRoots.roots) || subSet(exportingUsedRoots.roots, thisUsedRoots.roots))) {
if (results == null)
- results = new ArrayList(1);
+ results = new ArrayList<PackageRoots[]>(1);
results.add(new PackageRoots[] {this, exportingUsedRoots});
}
// need to check the usedRoots consistency for transitive closure
@@ -348,6 +374,20 @@ public class GroupingChecker {
return results;
}
+ List<PackageRoots[]> addConflicts(ResolverBundle bundle, String usedPackage, List<PackageRoots> visited, List<PackageRoots[]> results) {
+ PackageRoots bundleUsedRoots = getPackageRoots(bundle, usedPackage, null);
+ if (this == bundleUsedRoots)
+ return results;
+ if (this != nullPackageRoots && bundleUsedRoots != nullPackageRoots)
+ if (!(subSet(this.roots, bundleUsedRoots.roots) || subSet(bundleUsedRoots.roots, this.roots))) {
+ if (results == null)
+ results = new ArrayList<PackageRoots[]>(1);
+ results.add(new PackageRoots[] {this, bundleUsedRoots});
+ }
+ // need to check the usedRoots consistency for transitive closure
+ return this.isConsistentClassSpace(bundleUsedRoots, bundle, visited, results);
+ }
+
// TODO this is a behavioral change; before we only required 1 supplier to match; now roots must be subsets
private boolean subSet(ResolverExport[] superSet, ResolverExport[] subSet) {
for (int i = 0; i < subSet.length; i++) {

Back to the top