Fragments should only be discarded when they no longer match any
hosts. (FELIX-2858)
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1076257 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/Candidates.java b/framework/src/main/java/org/apache/felix/framework/resolver/Candidates.java
index 854fac3..54e8a8f 100644
--- a/framework/src/main/java/org/apache/felix/framework/resolver/Candidates.java
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/Candidates.java
@@ -42,11 +42,11 @@
private final Map<Capability, Set<Requirement>> m_dependentMap;
// Maps a requirement to the capability it matches.
private final Map<Requirement, SortedSet<Capability>> m_candidateMap;
- // Maps a module to a map containing its potential fragments; the
- // fragment map maps a fragment symbolic name to a map that maps
- // a version to a list of fragments matching that symbolic name
- // and version.
- private final Map<Module, Map<String, Map<Version, List<Module>>>> m_hostFragments;
+ // Maps a host capability to a map containing its potential fragments;
+ // the fragment map maps a fragment symbolic name to a map that maps
+ // a version to a list of fragments requirements matching that symbolic
+ // name and version.
+ private final Map<Capability, Map<String, Map<Version, List<Requirement>>>> m_hostFragments;
// Maps a module to its associated wrapped module; this only happens
// when a module being resolved has fragments to attach to it.
private final Map<Module, WrappedModule> m_allWrappedHosts;
@@ -63,7 +63,7 @@
Module root,
Map<Capability, Set<Requirement>> dependentMap,
Map<Requirement, SortedSet<Capability>> candidateMap,
- Map<Module, Map<String, Map<Version, List<Module>>>> hostFragments,
+ Map<Capability, Map<String, Map<Version, List<Requirement>>>> hostFragments,
Map<Module, WrappedModule> wrappedHosts)
{
m_root = root;
@@ -86,7 +86,8 @@
m_root = root;
m_dependentMap = new HashMap<Capability, Set<Requirement>>();
m_candidateMap = new HashMap<Requirement, SortedSet<Capability>>();
- m_hostFragments = new HashMap<Module, Map<String, Map<Version, List<Module>>>>();
+ m_hostFragments =
+ new HashMap<Capability, Map<String, Map<Version, List<Requirement>>>>();
m_allWrappedHosts = new HashMap<Module, WrappedModule>();
}
@@ -118,27 +119,28 @@
// Keep track of hosts and associated fragments.
if (isFragment)
{
- Map<String, Map<Version, List<Module>>> fragments =
- m_hostFragments.get(cap.getModule());
+ Map<String, Map<Version, List<Requirement>>>
+ fragments = m_hostFragments.get(cap);
if (fragments == null)
{
- fragments = new HashMap<String, Map<Version, List<Module>>>();
- m_hostFragments.put(cap.getModule(), fragments);
+ fragments = new HashMap<String, Map<Version, List<Requirement>>>();
+ m_hostFragments.put(cap, fragments);
}
- Map<Version, List<Module>> fragmentVersions =
+ Map<Version, List<Requirement>> fragmentVersions =
fragments.get(req.getModule().getSymbolicName());
if (fragmentVersions == null)
{
- fragmentVersions = new TreeMap<Version, List<Module>>(Collections.reverseOrder());
+ fragmentVersions =
+ new TreeMap<Version, List<Requirement>>(Collections.reverseOrder());
fragments.put(req.getModule().getSymbolicName(), fragmentVersions);
}
- List<Module> actual = fragmentVersions.get(req.getModule().getVersion());
+ List<Requirement> actual = fragmentVersions.get(req.getModule().getVersion());
if (actual == null)
{
- actual = new ArrayList<Module>();
+ actual = new ArrayList<Requirement>();
fragmentVersions.put(req.getModule().getVersion(), actual);
}
- actual.add(req.getModule());
+ actual.add(req);
}
}
}
@@ -224,41 +226,54 @@
// Steps 1 and 2
List<WrappedModule> wrappedHosts = new ArrayList<WrappedModule>();
List<Module> unselectedFragments = new ArrayList<Module>();
- for (Entry<Module, Map<String, Map<Version, List<Module>>>> entry :
+ for (Entry<Capability, Map<String, Map<Version, List<Requirement>>>> hostEntry :
m_hostFragments.entrySet())
{
// Step 1
+ Capability hostCap = hostEntry.getKey();
+ Map<String, Map<Version, List<Requirement>>> fragments = hostEntry.getValue();
List<Module> selectedFragments = new ArrayList<Module>();
- Module host = entry.getKey();
- Map<String, Map<Version, List<Module>>> fragments = entry.getValue();
- for (Entry<String, Map<Version, List<Module>>> fragEntry : fragments.entrySet())
+ for (Entry<String, Map<Version, List<Requirement>>> fragEntry : fragments.entrySet())
{
boolean isFirst = true;
- for (Entry<Version, List<Module>> versionEntry : fragEntry.getValue().entrySet())
+ for (Entry<Version, List<Requirement>> versionEntry
+ : fragEntry.getValue().entrySet())
{
- for (Module m : versionEntry.getValue())
+ for (Requirement hostReq : versionEntry.getValue())
{
- if (isFirst && !m.isRemovalPending())
+ // Select the highest version of the fragment that
+ // is not removal pending.
+ if (isFirst && !hostReq.getModule().isRemovalPending())
{
- selectedFragments.add(m);
+ selectedFragments.add(hostReq.getModule());
isFirst = false;
}
+ // For any fragment that wasn't selected, remove the
+ // current host as a potential host for it and remove it
+ // as a dependent on the host. If there are no more
+ // potential hosts for the fragment, then mark it as
+ // unselected for later removal.
else
{
-// TODO: FRAGMENT RESOLVER - Fragments should only be removed when they no longer
-// match any hosts, not immediately.
- unselectedFragments.add(m);
+ m_dependentMap.get(hostCap).remove(hostReq);
+ SortedSet<Capability> hosts = m_candidateMap.get(hostReq);
+ hosts.remove(hostCap);
+ if (hosts.isEmpty())
+ {
+ unselectedFragments.add(hostReq.getModule());
+ }
}
}
}
}
// Step 2
- WrappedModule wrappedHost = new WrappedModule(host, selectedFragments);
+ WrappedModule wrappedHost = new WrappedModule(hostCap.getModule(), selectedFragments);
wrappedHosts.add(wrappedHost);
- m_allWrappedHosts.put(host, wrappedHost);
+ m_allWrappedHosts.put(hostCap.getModule(), wrappedHost);
}
+System.out.println("+++ UNSELECTED FRAGMENTS: " + unselectedFragments);
// Step 3
for (Module m : unselectedFragments)
{
@@ -364,18 +379,19 @@
if (isFragment)
{
- Map<String, Map<Version, List<Module>>> fragments =
- m_hostFragments.get(cap.getModule());
+ Map<String, Map<Version, List<Requirement>>>
+ fragments = m_hostFragments.get(cap);
if (fragments != null)
{
- Map<Version, List<Module>> fragmentVersions =
+ Map<Version, List<Requirement>> fragmentVersions =
fragments.get(req.getModule().getSymbolicName());
if (fragmentVersions != null)
{
- List<Module> actual = fragmentVersions.get(req.getModule().getVersion());
+ List<Requirement> actual =
+ fragmentVersions.get(req.getModule().getVersion());
if (actual != null)
{
- actual.remove(req.getModule());
+ actual.remove(req);
if (actual.isEmpty())
{
fragmentVersions.remove(req.getModule().getVersion());
@@ -384,7 +400,7 @@
fragments.remove(req.getModule().getSymbolicName());
if (fragments.isEmpty())
{
- m_hostFragments.remove(cap.getModule());
+ m_hostFragments.remove(cap);
}
}
}