Modify resolver candidate selection to compare capability versions, not
resource versions. (FELIX-1792)
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@888978 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/CapabilityImpl.java b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/CapabilityImpl.java
index 43c719a..ddde6cc 100644
--- a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/CapabilityImpl.java
+++ b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/CapabilityImpl.java
@@ -21,9 +21,11 @@
import java.util.*;
import org.osgi.service.obr.Capability;
+import org.osgi.service.obr.Resource;
public class CapabilityImpl implements Capability
{
+ private Resource m_resource;
private String m_name = null;
private Map m_map = null;
@@ -37,6 +39,16 @@
});
}
+ public Resource getResource()
+ {
+ return m_resource;
+ }
+
+ public void setResource(Resource resource)
+ {
+ m_resource = resource;
+ }
+
public String getName()
{
return m_name;
diff --git a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/LocalRepositoryImpl.java b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/LocalRepositoryImpl.java
index 8dad29b..5ae15df 100644
--- a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/LocalRepositoryImpl.java
+++ b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/LocalRepositoryImpl.java
@@ -449,6 +449,5 @@
addCapability(cap);
}
}
-
}
}
diff --git a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/RequirementImpl.java b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/RequirementImpl.java
index da60537..39b9ec1 100644
--- a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/RequirementImpl.java
+++ b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/RequirementImpl.java
@@ -122,4 +122,9 @@
{
return m_filter.toString().hashCode();
}
+
+ public synchronized String toString()
+ {
+ return m_name + ": " + getFilter();
+ }
}
\ No newline at end of file
diff --git a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/ResolverImpl.java b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/ResolverImpl.java
index d0ddcc1..814f402 100644
--- a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/ResolverImpl.java
+++ b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/ResolverImpl.java
@@ -186,14 +186,14 @@
// the local resources are preferred over the remote
// resources. Currently, we are just putting them at
// the beginning of the candidate list.
- List possibleCandidates = searchLocalResources(reqs[reqIdx]);
- possibleCandidates.addAll(searchRemoteResources(reqs[reqIdx]));
+ List candidateCapabilities = searchLocalResources(reqs[reqIdx]);
+ candidateCapabilities.addAll(searchRemoteResources(reqs[reqIdx]));
// Determine the best candidate available that
// can resolve.
- while ((candidate == null) && !possibleCandidates.isEmpty())
+ while ((candidate == null) && !candidateCapabilities.isEmpty())
{
- Resource bestResource = (Resource) getBestResource(possibleCandidates);
+ Resource bestResource = (Resource) getBestCandidate(candidateCapabilities);
// Try to resolve the best resource.
if (resolve(bestResource))
@@ -202,7 +202,7 @@
}
else
{
- possibleCandidates.remove(bestResource);
+ candidateCapabilities.remove(bestResource);
}
}
}
@@ -314,7 +314,7 @@
*/
private List searchLocalResources(Requirement req)
{
- List matchingCandidates = new ArrayList();
+ List matchingCapabilities = new ArrayList();
Resource[] resources = m_local.getResources();
for (int resIdx = 0; (resources != null) && (resIdx < resources.length); resIdx++)
{
@@ -328,13 +328,13 @@
if (caps[capIdx].getName().equals(req.getName())
&& req.isSatisfied(caps[capIdx]))
{
- matchingCandidates.add(resources[resIdx]);
+ matchingCapabilities.add(caps[capIdx]);
}
}
}
}
- return matchingCandidates;
+ return matchingCapabilities;
}
/**
@@ -344,7 +344,7 @@
*/
private List searchRemoteResources(Requirement req)
{
- List matchingCandidates = new ArrayList();
+ List matchingCapabilities = new ArrayList();
Repository[] repos = m_admin.listRepositories();
for (int repoIdx = 0; (repos != null) && (repoIdx < repos.length); repoIdx++)
@@ -362,36 +362,37 @@
if (caps[capIdx].getName().equals(req.getName())
&& req.isSatisfied(caps[capIdx]))
{
- matchingCandidates.add(resources[resIdx]);
+ matchingCapabilities.add(caps[capIdx]);
}
}
}
}
}
- return matchingCandidates;
+ return matchingCapabilities;
}
/**
* Determines which resource is preferred to deliver the required capability.
- * This implementation will select the resource with the newest version. If two resources have
- * the same version will the one with the largest number of cabailities be preferred
+ * This method selects the resource providing the highest version of the capability.
+ * If two resources provide the same version of the capability, the resource with
+ * the largest number of cabailities be preferred
* @param resources
* @return
*/
- private Resource getBestResource(List resources)
+ private Resource getBestCandidate(List caps)
{
Version bestVersion = null;
- Resource best = null;
+ Capability best = null;
- for(int resIdx = 0; resIdx < resources.size(); resIdx++)
+ for(int capIdx = 0; capIdx < caps.size(); capIdx++)
{
- Resource currentResource = (Resource) resources.get(resIdx);
+ Capability current = (Capability) caps.get(capIdx);
if (best == null)
{
- best = currentResource;
- Object v = currentResource.getProperties().get(Resource.VERSION);
+ best = current;
+ Object v = current.getProperties().get(Resource.VERSION);
if ((v != null) && (v instanceof Version))
{
bestVersion = (Version) v;
@@ -399,14 +400,16 @@
}
else
{
- Object v = currentResource.getProperties().get(Resource.VERSION);
+ Object v = current.getProperties().get(Resource.VERSION);
// If there is no version, then select the resource
// with the greatest number of capabilities.
- if ((v == null) && (bestVersion == null) && (best.getCapabilities().length < currentResource.getCapabilities().length))
+ if ((v == null) && (bestVersion == null)
+ && (((CapabilityImpl) best).getResource().getCapabilities().length
+ < ((CapabilityImpl) current).getResource().getCapabilities().length))
{
- best = currentResource;
- bestVersion = (Version) v;
+ best = current;
+ bestVersion = null;
}
else if ((v != null) && (v instanceof Version))
{
@@ -414,23 +417,24 @@
// resource's version is lower, then select it.
if ((bestVersion == null) || (bestVersion.compareTo(v) < 0))
{
- best = currentResource;
+ best = current;
bestVersion = (Version) v;
}
// If the current resource version is equal to the
// best, then select the one with the greatest
// number of capabilities.
else if ((bestVersion != null) && (bestVersion.compareTo(v) == 0)
- && (best.getCapabilities().length < currentResource.getCapabilities().length))
+ && (((CapabilityImpl) best).getResource().getCapabilities().length
+ < ((CapabilityImpl) current).getResource().getCapabilities().length))
{
- best = currentResource;
+ best = current;
bestVersion = (Version) v;
}
}
}
}
- return best;
+ return (best == null) ? null : ((CapabilityImpl) best).getResource();
}
public synchronized void deploy(boolean start)
diff --git a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/ResourceImpl.java b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/ResourceImpl.java
index 2cda523..bd2925f 100644
--- a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/ResourceImpl.java
+++ b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/ResourceImpl.java
@@ -145,6 +145,7 @@
protected void addCapability(Capability cap)
{
+ ((CapabilityImpl) cap).setResource(this);
m_capList.add(cap);
}