You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by ri...@apache.org on 2010/11/22 21:45:18 UTC

svn commit: r1037874 [2/2] - in /felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver: ./ manifestparser/ proto3/

Added: felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/proto3/Candidates.java
URL: http://svn.apache.org/viewvc/felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/proto3/Candidates.java?rev=1037874&view=auto
==============================================================================
--- felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/proto3/Candidates.java (added)
+++ felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/proto3/Candidates.java Mon Nov 22 20:45:18 2010
@@ -0,0 +1,343 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.resolver.proto3;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import org.apache.felix.resolver.Module;
+import org.apache.felix.resolver.ResolveException;
+import org.apache.felix.resolver.Version;
+import org.apache.felix.resolver.cs.Capability;
+import org.apache.felix.resolver.cs.Requirement;
+
+public class Candidates
+{
+    private final Module m_root;
+
+    private final Map<Capability, Set<Requirement>> m_dependentMap;
+    private final Map<Requirement, SortedSet<Capability>> m_candidateMap;
+
+    private final Map<Module, Map<String, Map<Version, List<Module>>>> m_hostFragments;
+
+    private Candidates(
+        Module root,
+        Map<Capability, Set<Requirement>> dependentMap,
+        Map<Requirement, SortedSet<Capability>> candidateMap,
+        Map<Module, Map<String, Map<Version, List<Module>>>> hostFragments)
+    {
+        m_root = root;
+        m_dependentMap = dependentMap;
+        m_candidateMap = candidateMap;
+        m_hostFragments = hostFragments;
+    }
+
+    public Candidates(Module root)
+    {
+        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>>>>();
+    }
+
+    public void add(Map<Requirement, SortedSet<Capability>> candidates)
+    {
+        for (Entry<Requirement, SortedSet<Capability>> entry : candidates.entrySet())
+        {
+            add(entry.getKey(), entry.getValue());
+        }
+    }
+
+    public void add(Requirement req, SortedSet<Capability> candidates)
+    {
+        boolean isFragment = req.getNamespace().equals(Capability.HOST_NAMESPACE);
+
+        // Record the candidates.
+        m_candidateMap.put(req, candidates);
+        // Add the requirement as a dependent on the candidates.
+        for (Capability cap : candidates)
+        {
+            Set<Requirement> dependents = m_dependentMap.get(cap);
+            if (dependents == null)
+            {
+                dependents = new HashSet<Requirement>();
+                m_dependentMap.put(cap, dependents);
+            }
+            dependents.add(req);
+            // Keep track of hosts and associated fragments.
+            if (isFragment)
+            {
+                Map<String, Map<Version, List<Module>>> fragments =
+                    m_hostFragments.get(cap.getModule());
+                if (fragments == null)
+                {
+                    fragments = new HashMap<String, Map<Version, List<Module>>>();
+                    m_hostFragments.put(cap.getModule(), fragments);
+                }
+                Map<Version, List<Module>> fragmentVersions =
+                    fragments.get(req.getModule().getSymbolicName());
+                if (fragmentVersions == null)
+                {
+                    fragmentVersions = new TreeMap<Version, List<Module>>(Collections.reverseOrder());
+                    fragments.put(req.getModule().getSymbolicName(), fragmentVersions);
+                }
+                List<Module> actual = fragmentVersions.get(req.getModule().getVersion());
+                if (actual == null)
+                {
+                    actual = new ArrayList<Module>();
+                    fragmentVersions.put(req.getModule().getVersion(), actual);
+                }
+                actual.add(req.getModule());
+            }
+        }
+    }
+
+    // Need this to remove not selected fragments.
+    private void unselectFragment(Module m) throws ResolveException
+    {
+        Set<Module> invalidModules = new HashSet<Module>();
+        remove(m, invalidModules);
+        while (!invalidModules.isEmpty())
+        {
+            Iterator<Module> it = invalidModules.iterator();
+            m = it.next();
+            it.remove();
+            remove(m, invalidModules);
+        }
+    }
+
+    // Need this to remove not selected fragments.
+    public void remove(Module m, Set<Module> invalidModules) throws ResolveException
+    {
+        for (Requirement r : m.getRequirements())
+        {
+            remove(r);
+        }
+
+        for (Capability c : m.getCapabilities())
+        {
+            remove(c, invalidModules);
+        }
+    }
+
+    public void remove(Requirement req)
+    {
+        boolean isFragment = req.getNamespace().equals(Capability.HOST_NAMESPACE);
+
+        SortedSet<Capability> candidates = m_candidateMap.remove(req);
+        if (candidates != null)
+        {
+            for (Capability cap : candidates)
+            {
+                Set<Requirement> dependents = m_dependentMap.get(cap);
+                if (dependents != null)
+                {
+                    dependents.remove(req);
+                }
+
+                if (isFragment)
+                {
+                    Map<String, Map<Version, List<Module>>> fragments =
+                        m_hostFragments.get(cap.getModule());
+                    if (fragments != null)
+                    {
+                        Map<Version, List<Module>> fragmentVersions =
+                            fragments.get(req.getModule().getSymbolicName());
+                        if (fragmentVersions != null)
+                        {
+                            List<Module> actual = fragmentVersions.get(req.getModule().getVersion());
+                            if (actual != null)
+                            {
+                                actual.remove(req.getModule());
+                                if (actual.isEmpty())
+                                {
+                                    fragmentVersions.remove(req.getModule().getVersion());
+                                    if (fragmentVersions.isEmpty())
+                                    {
+                                        fragments.remove(req.getModule().getSymbolicName());
+                                        if (fragments.isEmpty())
+                                        {
+                                            m_hostFragments.remove(cap.getModule());
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    private void remove(Capability c, Set<Module> invalidModules) throws ResolveException
+    {
+        Set<Requirement> dependents = m_dependentMap.remove(c);
+        if (dependents != null)
+        {
+            for (Requirement r : dependents)
+            {
+                SortedSet<Capability> candidates = m_candidateMap.get(r);
+                candidates.remove(c);
+                if (candidates.isEmpty())
+                {
+                    m_candidateMap.remove(r);
+                    if (!r.isOptional())
+                    {
+                        if (m_root.equals(r.getModule()))
+                        {
+                            String msg = "Unable to resolve " + m_root
+                                + ": missing requirement " + r;
+                            ResolveException ex = new ResolveException(msg, m_root, r);
+                            System.out.println("No viable candidates: " + ex);
+                            throw ex;
+                        }
+                        invalidModules.add(r.getModule());
+                    }
+                }
+            }
+        }
+    }
+
+    public Map<Requirement, SortedSet<Capability>> getCandidateMap()
+    {
+        return m_candidateMap;
+    }
+
+    public void mergeFragments()
+    {
+        List<WrappedModule> wrappedHosts = new ArrayList<WrappedModule>();
+        List<Module> unselectedFragments = new ArrayList<Module>();
+        for (Entry<Module, Map<String, Map<Version, List<Module>>>> entry :
+            m_hostFragments.entrySet())
+        {
+            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())
+            {
+                    boolean isFirst = true;
+                for (Entry<Version, List<Module>> versionEntry : fragEntry.getValue().entrySet())
+                {
+                    for (Module m : versionEntry.getValue())
+                    {
+                        if (isFirst)
+                        {
+                            selectedFragments.add(m);
+                            isFirst = false;
+                        }
+                        else
+                        {
+                            unselectedFragments.add(m);
+                        }
+                    }
+                }
+            }
+            WrappedModule wrappedHost = new WrappedModule(host);
+            for (Module fragment : selectedFragments)
+            {
+                wrappedHost.attachFragment(fragment);
+            }
+            wrappedHosts.add(wrappedHost);
+            System.out.println("+++ SELECTED FRAGMENTS " + selectedFragments + " FOR " + host);
+        }
+        for (Module m : unselectedFragments)
+        {
+            System.out.println("+++ UNSELECTED FRAGMENT " + m);
+            unselectFragment(m);
+        }
+
+        // Replace all unwrapped host capabilities with wrapped host capabilities.
+        for (WrappedModule wrappedHost : wrappedHosts)
+        {
+            for (Capability c : wrappedHost.getCapabilities())
+            {
+                Set<Requirement> dependents =
+                    m_dependentMap.get(((WrappedCapability) c).getWrappedCapability());
+                if (dependents != null)
+                {
+                    for (Requirement r : dependents)
+                    {
+                        Set<Capability> cands = m_candidateMap.get(r);
+                        cands.remove(((WrappedCapability) c).getWrappedCapability());
+                        cands.add(c);
+                    }
+                }
+            }
+            for (Requirement r : wrappedHost.getRequirements())
+            {
+                SortedSet<Capability> cands =
+                    m_candidateMap.get(((WrappedRequirement) r).getWrappedRequirement());
+                if (cands != null)
+                {
+                    m_candidateMap.put(r, new TreeSet<Capability>(cands));
+                }
+            }
+        }
+        // 1. Find all fragments to attach to a given host.
+        // 2. Remove any unselected fragments.
+        // 3. Wrap hosts and attach fragments.
+        // 4. Replace all fragments with any host it was merged into (effectively multiplying it).
+        //    * This includes setting candidates for attached fragment requirements as well as
+        //      replacing fragment capabilities with host's attached fragment capabilities.
+    }
+
+    // Need this to set candidates for host's attached fragment requirements.
+    public void copy(Requirement fragReq, Requirement hostReq)
+    {
+        // add a copy of fragReq candidates for hostReq to candidates.
+        // remove fragReq as a dependent from all candidates and add hostReq instead.
+    }
+
+    // Need this to replace fragment capabilities with attached host capabilities.
+    public void replace(Capability fragCap, Capability hostCap)
+    {
+        // Make all fragCap dependents depend on hostCap
+        // Remove fragCap as candidates from all dependents.
+    }
+
+    public Candidates copy()
+    {
+        Map<Capability, Set<Requirement>> dependentMap =
+            new HashMap<Capability, Set<Requirement>>();
+        for (Entry<Capability, Set<Requirement>> entry : m_dependentMap.entrySet())
+        {
+            Set<Requirement> dependents = new HashSet<Requirement>(entry.getValue());
+            dependentMap.put(entry.getKey(), dependents);
+        }
+
+        Map<Requirement, SortedSet<Capability>> candidateMap =
+            new HashMap<Requirement, SortedSet<Capability>>();
+        for (Entry<Requirement, SortedSet<Capability>> entry : m_candidateMap.entrySet())
+        {
+            SortedSet<Capability> candidates = new TreeSet<Capability>(entry.getValue());
+            candidateMap.put(entry.getKey(), candidates);
+        }
+
+        return new Candidates(m_root, dependentMap, candidateMap, m_hostFragments);
+    }
+}
\ No newline at end of file

Modified: felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/proto3/Proto3Resolver.java
URL: http://svn.apache.org/viewvc/felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/proto3/Proto3Resolver.java?rev=1037874&r1=1037873&r2=1037874&view=diff
==============================================================================
--- felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/proto3/Proto3Resolver.java (original)
+++ felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/proto3/Proto3Resolver.java Mon Nov 22 20:45:18 2010
@@ -28,13 +28,14 @@ import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
 import java.util.SortedSet;
+import java.util.TreeMap;
 import java.util.TreeSet;
-import org.apache.felix.resolver.CandidateComparator;
 import org.apache.felix.resolver.Module;
 import org.apache.felix.resolver.RequirementImpl;
 import org.apache.felix.resolver.ResolveException;
 import org.apache.felix.resolver.Resolver;
 import org.apache.felix.resolver.Resolver.ResolverState;
+import org.apache.felix.resolver.Version;
 import org.apache.felix.resolver.Wire;
 import org.apache.felix.resolver.WireHostImpl;
 import org.apache.felix.resolver.WireImpl;
@@ -54,12 +55,10 @@ public class Proto3Resolver implements R
 
     // Holds candidate permutations based on permutating "uses" chains.
     // These permutations are given higher priority.
-    private final List<Map<Requirement, SortedSet<Capability>>> m_usesPermutations =
-        new ArrayList<Map<Requirement, SortedSet<Capability>>>();
+    private final List<Candidates> m_usesPermutations = new ArrayList<Candidates>();
     // Holds candidate permutations based on permutating requirement candidates.
     // These permutations represent backtracking on previous decisions.
-    private final List<Map<Requirement, SortedSet<Capability>>> m_importPermutations =
-        new ArrayList<Map<Requirement, SortedSet<Capability>>>();
+    private final List<Candidates> m_importPermutations = new ArrayList<Candidates>();
 
     public Proto3Resolver()
     {
@@ -88,18 +87,17 @@ System.out.println("+++ PROTO3 RESOLVER"
         {
             try
             {
-                Map<Requirement, SortedSet<Capability>> candidateMap =
-                    new HashMap<Requirement, SortedSet<Capability>>();
+                Candidates allCandidates = new Candidates(module);
 
                 // Populate all candidates.
                 populateCandidates(
-                    state, module, candidateMap, new HashMap<Module, Object>());
+                    state, module, allCandidates, new HashMap<Module, Object>());
 
                 // Merge any fragments into hosts.
-                mergeFragments(candidateMap);
+                allCandidates.mergeFragments();
 
                 // Record the initial candidate permutation.
-                m_usesPermutations.add(candidateMap);
+                m_usesPermutations.add(allCandidates);
 
                 ResolveException rethrow = null;
 
@@ -117,20 +115,20 @@ System.out.println("+++ PROTO3 RESOLVER"
                     capDepSet.clear();
                     m_packageSourcesCache.clear();
 
-                    candidateMap = (m_usesPermutations.size() > 0)
+                    allCandidates = (m_usesPermutations.size() > 0)
                         ? m_usesPermutations.remove(0)
                         : m_importPermutations.remove(0);
-dumpCandidateMap(candidateMap);
+dumpCandidateMap(allCandidates);
 
                     // If we are resolving a fragment, then we
                     // actually want to verify its host.
                     if (hostReq != null)
                     {
-                        target = candidateMap.get(hostReq).iterator().next().getModule();
+                        target = allCandidates.getCandidateMap().get(hostReq).iterator().next().getModule();
                     }
 
                     calculatePackageSpaces(
-                        target, candidateMap, modulePkgMap,
+                        target, allCandidates, modulePkgMap,
                         capDepSet, new HashMap(), new HashSet());
 System.out.println("+++ PACKAGE SPACES START +++");
 dumpModulePkgMap(modulePkgMap);
@@ -139,7 +137,7 @@ System.out.println("+++ PACKAGE SPACES E
                     try
                     {
                         checkPackageSpaceConsistency(
-                            target, candidateMap, modulePkgMap, capDepSet, new HashMap());
+                            target, allCandidates, modulePkgMap, capDepSet, new HashMap());
                     }
                     catch (ResolveException ex)
                     {
@@ -158,8 +156,7 @@ System.out.println("+++ PACKAGE SPACES E
                 }
 
                 wireMap =
-                    populateWireMap(target, modulePkgMap, wireMap,
-                    candidateMap);
+                    populateWireMap(target, modulePkgMap, wireMap, allCandidates);
             }
             finally
             {
@@ -196,17 +193,17 @@ System.out.println("+++ PACKAGE SPACES E
         // 5. The package in question matches a dynamic import of the bundle.
         // The following call checks all of these conditions and returns
         // the associated dynamic import and matching capabilities.
-        Map<Requirement, SortedSet<Capability>> candidateMap =
+        Candidates allCandidates =
             getDynamicImportCandidates(state, module, pkgName);
-        if (candidateMap != null)
+        if (allCandidates != null)
         {
             try
             {
                 Map<Module, List<Wire>> wireMap = new HashMap();
                 Map<Module, Packages> modulePkgMap = new HashMap();
 
-                populateDynamicCandidates(state, module, candidateMap);
-                m_usesPermutations.add(candidateMap);
+                populateDynamicCandidates(state, module, allCandidates);
+                m_usesPermutations.add(allCandidates);
 
                 ResolveException rethrow = null;
 
@@ -219,18 +216,18 @@ System.out.println("+++ PACKAGE SPACES E
                     modulePkgMap.clear();
                     capDepSet.clear();
 
-                    candidateMap = (m_usesPermutations.size() > 0)
+                    allCandidates = (m_usesPermutations.size() > 0)
                         ? m_usesPermutations.remove(0)
                         : m_importPermutations.remove(0);
 
                     calculatePackageSpaces(
-                        module, candidateMap, modulePkgMap,
+                        module, allCandidates, modulePkgMap,
                         capDepSet, new HashMap(), new HashSet());
 
                     try
                     {
                         checkPackageSpaceConsistency(
-                            module, candidateMap, modulePkgMap,
+                            module, allCandidates, modulePkgMap,
                             capDepSet, new HashMap());
                     }
                     catch (ResolveException ex)
@@ -252,7 +249,7 @@ System.out.println("+++ PACKAGE SPACES E
 
 //dumpModulePkgMap(modulePkgMap);
                 wireMap = populateDynamicWireMap(
-                    module, pkgName, modulePkgMap, wireMap, candidateMap);
+                    module, pkgName, modulePkgMap, wireMap, allCandidates);
 
                 return wireMap;
             }
@@ -279,7 +276,7 @@ System.out.println("+++ PACKAGE SPACES E
         return null;
     }
 
-    private static Map<Requirement, SortedSet<Capability>> getDynamicImportCandidates(
+    private static Candidates getDynamicImportCandidates(
         ResolverState state, Module module, String pkgName)
     {
         if (m_isInvokeCount)
@@ -374,9 +371,9 @@ System.out.println("+++ PACKAGE SPACES E
 
         if (candidates.size() > 0)
         {
-            Map<Requirement, SortedSet<Capability>> candidateMap = new HashMap();
-            candidateMap.put(dynReq, candidates);
-            return candidateMap;
+            Candidates allCandidates = new Candidates(module);
+            allCandidates.add(dynReq, candidates);
+            return allCandidates;
         }
 
         return null;
@@ -385,7 +382,7 @@ System.out.println("+++ PACKAGE SPACES E
 // TODO: FELIX3 - Modify to not be recursive.
     private void populateCandidates(
         ResolverState state, Module module,
-        Map<Requirement, SortedSet<Capability>> candidateMap,
+        Candidates allCandidates,
         Map<Module, Object> resultCache)
     {
         if (m_isInvokeCount)
@@ -503,7 +500,7 @@ System.out.println("+++ PACKAGE SPACES E
                     try
                     {
                         populateCandidates(state, candCap.getModule(),
-                            candidateMap, resultCache);
+                            allCandidates, resultCache);
                     }
                     catch (ResolveException ex)
                     {
@@ -556,14 +553,14 @@ System.out.println("+++ PACKAGE SPACES E
             // Merge local candidate map into global candidate map.
             if (localCandidateMap.size() > 0)
             {
-                candidateMap.putAll(localCandidateMap);
+                allCandidates.add(localCandidateMap);
             }
         }
     }
 
     private void populateDynamicCandidates(
         ResolverState state, Module module,
-        Map<Requirement, SortedSet<Capability>> candidateMap)
+        Candidates allCandidates)
     {
         if (m_isInvokeCount)
         {
@@ -578,7 +575,7 @@ System.out.println("+++ PACKAGE SPACES E
         // matching candidates and populate their candidates if necessary.
         ResolveException rethrow = null;
         Entry<Requirement, SortedSet<Capability>> entry =
-            candidateMap.entrySet().iterator().next();
+            allCandidates.getCandidateMap().entrySet().iterator().next();
         Requirement dynReq = entry.getKey();
         SortedSet<Capability> candidates = entry.getValue();
         for (Iterator<Capability> itCandCap = candidates.iterator(); itCandCap.hasNext(); )
@@ -589,7 +586,7 @@ System.out.println("+++ PACKAGE SPACES E
                 try
                 {
                     populateCandidates(state, candCap.getModule(),
-                        candidateMap, new HashMap<Module, Object>());
+                        allCandidates, new HashMap<Module, Object>());
                 }
                 catch (ResolveException ex)
                 {
@@ -604,7 +601,7 @@ System.out.println("+++ PACKAGE SPACES E
 
         if (candidates.isEmpty())
         {
-            candidateMap.remove(dynReq);
+            allCandidates.remove(dynReq);
             if (rethrow == null)
             {
                 rethrow = new ResolveException("Dynamic import failed.", module, dynReq);
@@ -613,150 +610,9 @@ System.out.println("+++ PACKAGE SPACES E
         }
     }
 
-    private static Map<Module, WrappedModule> mergeFragments(
-        Map<Requirement, SortedSet<Capability>> candidateMap)
-    {
-        // Map of fragment module to its merged hosts.
-        Map<Module, Set<Module>> fragments = new HashMap<Module, Set<Module>>();
-        // Map of hosts to wrapped module.
-        Map<Module, WrappedModule> wrappedHosts = new HashMap<Module, WrappedModule>();
-
-        for (Entry<Requirement, SortedSet<Capability>> entry : candidateMap.entrySet())
-        {
-            // Find all host requirements to determine all fragments and
-            // the hosts into which they should be merged.
-            if (entry.getKey().getNamespace().equals(Capability.HOST_NAMESPACE))
-            {
-                for (Capability hostCap : entry.getValue())
-                {
-                    // Wrap the host.
-                    WrappedModule wrappedHost = wrappedHosts.get(hostCap.getModule());
-                    if (wrappedHost == null)
-                    {
-                        wrappedHost = new WrappedModule(hostCap.getModule());
-                        wrappedHosts.put(hostCap.getModule(), wrappedHost);
-                    }
-System.out.println("+++ ATTACHING FRAGMENT "
-    + entry.getKey().getModule()
-    + " TO HOST "
-    + wrappedHost);
-                    wrappedHost.attachFragment(entry.getKey().getModule());
-
-                    // Add fragment candidates to candidate map for wrapped host.
-                    for (Requirement wr : wrappedHost.getRequirements())
-                    {
-                        for (Requirement r : entry.getKey().getModule().getRequirements())
-                        {
-                            if (r == ((WrappedRequirement) wr).getWrappedRequirement())
-                            {
-                                TreeSet<Capability> cands =
-                                    new TreeSet<Capability>(candidateMap.get(r));
-                                candidateMap.put(wr, cands);
-                            }
-                        }
-                    }
-
-                    // Remember wrapped hosts per fragment.
-                    Set<Module> hosts = fragments.get(entry.getKey().getModule());
-                    if (hosts == null)
-                    {
-                        hosts = new HashSet<Module>();
-                        fragments.put(entry.getKey().getModule(), hosts);
-                    }
-                    hosts.add(wrappedHost);
-                }
-            }
-        }
-System.out.println("+++ WRAPPED HOSTS: " + wrappedHosts);
-System.out.println("+++ FRAGMENTS: " + fragments);
-
-        // Replace the unmerged host with the wrapped host wherever the
-        // unmerged host is a candidate. First we find the required capabilities
-        // from the unmerged host.
-        Map<Requirement, Set<Capability>> requiredHosts =
-            new HashMap<Requirement, Set<Capability>>();
-        for (Entry<Requirement, SortedSet<Capability>> entry : candidateMap.entrySet())
-        {
-            for (Capability cap : entry.getValue())
-            {
-                if (wrappedHosts.containsKey(cap.getModule()))
-                {
-                    Set<Capability> caps = requiredHosts.get(entry.getKey());
-                    if (caps == null)
-                    {
-                        caps = new HashSet<Capability>();
-                        requiredHosts.put(entry.getKey(), caps);
-                    }
-                    caps.add(cap);
-                }
-            }
-        }
-        // Then we replace them with capabilities from the wrapped host.
-        for (Entry<Requirement, Set<Capability>> entry : requiredHosts.entrySet())
-        {
-            Set<Capability> cands = candidateMap.get(entry.getKey());
-            for (Capability cap : entry.getValue())
-            {
-                cands.remove(cap);
-                Module wrappedHost = wrappedHosts.get(cap.getModule());
-                for (Capability wrappedCap : wrappedHost.getCapabilities())
-                {
-                    if (CapabilitySet.matches(wrappedCap, entry.getKey().getFilter()))
-                    {
-                        cands.add(wrappedCap);
-                    }
-                }
-            }
-        }
-
-        // Replace any fragment capabilities with capabilities from the
-        // wrapped host. First we find the required capabilities from the
-        // fragments.
-        Map<Requirement, Set<Capability>> requiredFragments =
-            new HashMap<Requirement, Set<Capability>>();
-        for (Entry<Requirement, SortedSet<Capability>> entry : candidateMap.entrySet())
-        {
-            for (Capability cap : entry.getValue())
-            {
-                if (fragments.containsKey(cap.getModule()))
-                {
-                    Set<Capability> caps = requiredFragments.get(entry.getKey());
-                    if (caps == null)
-                    {
-                        caps = new HashSet<Capability>();
-                        requiredFragments.put(entry.getKey(), caps);
-                    }
-                    caps.add(cap);
-                }
-            }
-        }
-        // Then we replace them with capabilities from the wrapped host.
-        for (Entry<Requirement, Set<Capability>> entry : requiredFragments.entrySet())
-        {
-            Set<Capability> cands = candidateMap.get(entry.getKey());
-            for (Capability cap : entry.getValue())
-            {
-                cands.remove(cap);
-                Set<Module> hosts = fragments.get(cap.getModule());
-                for (Module host : hosts)
-                {
-                    for (Capability wrappedCap : host.getCapabilities())
-                    {
-                        if (CapabilitySet.matches(wrappedCap, entry.getKey().getFilter()))
-                        {
-                            cands.add(wrappedCap);
-                        }
-                    }
-                }
-            }
-        }
-
-        return wrappedHosts;
-    }
-
     private void calculatePackageSpaces(
         Module module,
-        Map<Requirement, SortedSet<Capability>> candidateMap,
+        Candidates allCandidates,
         Map<Module, Packages> modulePkgMap,
         Map<Capability, Set<Requirement>> capDepSet,
         Map<Capability, List<Module>> usesCycleMap,
@@ -795,7 +651,7 @@ System.out.println("+++ FRAGMENTS: " + f
             for (Requirement req : module.getDynamicRequirements())
             {
                 // Get the candidates for the current requirement.
-                Set<Capability> candCaps = candidateMap.get(req);
+                Set<Capability> candCaps = allCandidates.getCandidateMap().get(req);
                 // Optional requirements may not have any candidates.
                 if (candCaps == null)
                 {
@@ -815,7 +671,7 @@ System.out.println("+++ FRAGMENTS: " + f
             for (Requirement req : module.getRequirements())
             {
                 // Get the candidates for the current requirement.
-                Set<Capability> candCaps = candidateMap.get(req);
+                Set<Capability> candCaps = allCandidates.getCandidateMap().get(req);
                 // Optional requirements may not have any candidates.
                 if (candCaps == null)
                 {
@@ -838,7 +694,7 @@ System.out.println("+++ FRAGMENTS: " + f
             Requirement req = reqs.get(i);
             Capability cap = caps.get(i);
             calculateExportedPackages(cap.getModule(), modulePkgMap);
-            mergeCandidatePackages(module, req, cap, modulePkgMap, candidateMap);
+            mergeCandidatePackages(module, req, cap, modulePkgMap, allCandidates);
             addCapabilityDependency(cap, req, capDepSet);
         }
 
@@ -846,7 +702,7 @@ System.out.println("+++ FRAGMENTS: " + f
         for (int i = 0; i < caps.size(); i++)
         {
             calculatePackageSpaces(
-                caps.get(i).getModule(), candidateMap, modulePkgMap,
+                caps.get(i).getModule(), allCandidates, modulePkgMap,
                 capDepSet, usesCycleMap, cycle);
         }
 
@@ -868,7 +724,7 @@ System.out.println("+++ FRAGMENTS: " + f
                         blame.m_cap,
                         blameReqs,
                         modulePkgMap,
-                        candidateMap,
+                        allCandidates,
                         usesCycleMap);
                 }
             }
@@ -886,7 +742,7 @@ System.out.println("+++ FRAGMENTS: " + f
                     blame.m_cap,
                     blameReqs,
                     modulePkgMap,
-                    candidateMap,
+                    allCandidates,
                     usesCycleMap);
             }
         }
@@ -894,8 +750,8 @@ System.out.println("+++ FRAGMENTS: " + f
 
     private void mergeCandidatePackages(
         Module current, Requirement currentReq, Capability candCap,
-        Map<Module, Packages> modulePkgMap, Map<Requirement,
-        SortedSet<Capability>> candidateMap)
+        Map<Module, Packages> modulePkgMap,
+        Candidates allCandidates)
     {
         if (m_isInvokeCount)
         {
@@ -941,14 +797,14 @@ System.out.println("+++ FRAGMENTS: " + f
                 {
                     Directive dir = req.getDirective(Constants.VISIBILITY_DIRECTIVE);
                     if ((dir != null) && dir.getValue().equals(Constants.VISIBILITY_REEXPORT)
-                        && (candidateMap.get(req) != null))
+                        && (allCandidates.getCandidateMap().get(req) != null))
                     {
                         mergeCandidatePackages(
                             current,
                             currentReq,
-                            candidateMap.get(req).iterator().next(),
+                            allCandidates.getCandidateMap().get(req).iterator().next(),
                             modulePkgMap,
-                            candidateMap);
+                            allCandidates);
                     }
                 }
             }
@@ -1037,7 +893,7 @@ System.out.println("+++ FRAGMENTS: " + f
         Module current, Packages currentPkgs,
         Capability mergeCap, List<Requirement> blameReqs,
         Map<Module, Packages> modulePkgMap,
-        Map<Requirement, SortedSet<Capability>> candidateMap,
+        Candidates allCandidates,
         Map<Capability, List<Module>> cycleMap)
     {
         if (m_isInvokeCount)
@@ -1105,14 +961,14 @@ System.out.println("+++ FRAGMENTS: " + f
                         List<Requirement> blameReqs2 = new ArrayList(blameReqs);
                         blameReqs2.add(blame.m_reqs.get(blame.m_reqs.size() - 1));
                         usedCaps.add(new Blame(blame.m_cap, blameReqs2));
-                            mergeUses(current, currentPkgs, blame.m_cap, blameReqs2,
-                            modulePkgMap, candidateMap, cycleMap);
+                        mergeUses(current, currentPkgs, blame.m_cap, blameReqs2,
+                            modulePkgMap, allCandidates, cycleMap);
                     }
                     else
                     {
                         usedCaps.add(new Blame(blame.m_cap, blameReqs));
                         mergeUses(current, currentPkgs, blame.m_cap, blameReqs,
-                            modulePkgMap, candidateMap, cycleMap);
+                            modulePkgMap, allCandidates, cycleMap);
                     }
                 }
             }
@@ -1120,7 +976,7 @@ System.out.println("+++ FRAGMENTS: " + f
     }
 
     private void checkPackageSpaceConsistency(
-        Module module, Map<Requirement, SortedSet<Capability>> candidateMap,
+        Module module, Candidates allCandidates,
         Map<Module, Packages> modulePkgMap, Map<Capability, Set<Requirement>> capDepSet,
         Map<Module, Object> resultCache)
     {
@@ -1144,7 +1000,7 @@ System.out.println("+++ FRAGMENTS: " + f
         Packages pkgs = modulePkgMap.get(module);
 
         ResolveException rethrow = null;
-        Map<Requirement, SortedSet<Capability>> permutation = null;
+        Candidates permutation = null;
         Set<Requirement> mutated = null;
 
         // Check for conflicting imports from fragments.
@@ -1162,9 +1018,9 @@ System.out.println("+++ FRAGMENTS: " + f
                     else if (!sourceBlame.m_cap.equals(blame.m_cap))
                     {
                         // Try to permutate the conflicting requirement.
-                        permutate(candidateMap, blame.m_reqs.get(0), m_importPermutations);
+                        permutate(allCandidates, blame.m_reqs.get(0), m_importPermutations);
                         // Try to permutate the source requirement.
-                        permutate(candidateMap, sourceBlame.m_reqs.get(0), m_importPermutations);
+                        permutate(allCandidates, sourceBlame.m_reqs.get(0), m_importPermutations);
                         // Report conflict.
                         ResolveException ex = new ResolveException(
                             "Constraint violation for package '"
@@ -1195,7 +1051,7 @@ System.out.println("+++ FRAGMENTS: " + f
                     // that conflict with existing selected candidates.
                     permutation = (permutation != null)
                         ? permutation
-                        : copyCandidateMap(candidateMap);
+                        : allCandidates.copy();
                     rethrow = (rethrow != null)
                         ? rethrow
                         : new ResolveException(
@@ -1224,7 +1080,7 @@ System.out.println("+++ FRAGMENTS: " + f
                         // See if we can permutate the candidates for blamed
                         // requirement; there may be no candidates if the module
                         // associated with the requirement is already resolved.
-                        Set<Capability> candidates = permutation.get(req);
+                        SortedSet<Capability> candidates = permutation.getCandidateMap().get(req);
                         if ((candidates != null) && (candidates.size() > 1))
                         {
                             mutated.add(req);
@@ -1267,7 +1123,7 @@ System.out.println("+++ FRAGMENTS: " + f
                         // that conflict with existing selected candidates.
                         permutation = (permutation != null)
                             ? permutation
-                            : copyCandidateMap(candidateMap);
+                            : allCandidates.copy();
                         rethrow = (rethrow != null)
                             ? rethrow
                             : new ResolveException(
@@ -1296,7 +1152,7 @@ System.out.println("+++ FRAGMENTS: " + f
                             // See if we can permutate the candidates for blamed
                             // requirement; there may be no candidates if the module
                             // associated with the requirement is already resolved.
-                            SortedSet<Capability> candidates = permutation.get(req);
+                            SortedSet<Capability> candidates = permutation.getCandidateMap().get(req);
                             if ((candidates != null) && (candidates.size() > 1))
                             {
                                 mutated.add(req);
@@ -1334,7 +1190,7 @@ System.out.println("+++ FRAGMENTS: " + f
                         // with existing import decisions, we may end up trying
                         // to permutate the same import a lot of times, so we should
                         // try to check if that the case and only permutate it once.
-                        permutateIfNeeded(candidateMap, req, m_importPermutations);
+                        permutateIfNeeded(allCandidates, req, m_importPermutations);
                     }
 
                     System.out.println("Conflict between imports: " + rethrow);
@@ -1359,7 +1215,7 @@ System.out.println("+++ FRAGMENTS: " + f
                     try
                     {
                         checkPackageSpaceConsistency(
-                            importBlame.m_cap.getModule(), candidateMap, modulePkgMap,
+                            importBlame.m_cap.getModule(), allCandidates, modulePkgMap,
                             capDepSet, resultCache);
                     }
                     catch (ResolveException ex)
@@ -1371,7 +1227,7 @@ System.out.println("+++ FRAGMENTS: " + f
                         if (permCount == (m_usesPermutations.size() + m_importPermutations.size()))
                         {
                             Requirement req = importBlame.m_reqs.get(0);
-                            permutate(candidateMap, req, m_importPermutations);
+                            permutate(allCandidates, req, m_importPermutations);
                         }
                         throw ex;
                     }
@@ -1381,15 +1237,14 @@ System.out.println("+++ FRAGMENTS: " + f
     }
 
     private static void permutate(
-        Map<Requirement, SortedSet<Capability>> candidateMap, Requirement req,
-        List<Map<Requirement, SortedSet<Capability>>> permutations)
+        Candidates allCandidates, Requirement req,
+        List<Candidates> permutations)
     {
-        SortedSet<Capability> candidates = candidateMap.get(req);
+        SortedSet<Capability> candidates = allCandidates.getCandidateMap().get(req);
         if (candidates.size() > 1)
         {
-            Map<Requirement, SortedSet<Capability>> perm =
-                copyCandidateMap(candidateMap);
-            candidates = perm.get(req);
+            Candidates perm = allCandidates.copy();
+            candidates = perm.getCandidateMap().get(req);
             Iterator it = candidates.iterator();
             it.next();
             it.remove();
@@ -1398,10 +1253,10 @@ System.out.println("+++ FRAGMENTS: " + f
     }
 
     private static void permutateIfNeeded(
-        Map<Requirement, SortedSet<Capability>> candidateMap, Requirement req,
-        List<Map<Requirement, SortedSet<Capability>>> permutations)
+        Candidates allCandidates, Requirement req,
+        List<Candidates> permutations)
     {
-        SortedSet<Capability> candidates = candidateMap.get(req);
+        SortedSet<Capability> candidates = allCandidates.getCandidateMap().get(req);
         if (candidates.size() > 1)
         {
             // Check existing permutations to make sure we haven't
@@ -1411,9 +1266,9 @@ System.out.println("+++ FRAGMENTS: " + f
             // initial candidate for the requirement in question,
             // then it has already been permutated.
             boolean permutated = false;
-            for (Map<Requirement, SortedSet<Capability>> existingPerm : permutations)
+            for (Candidates existingPerm : permutations)
             {
-                Set<Capability> existingPermCands = existingPerm.get(req);
+                Set<Capability> existingPermCands = existingPerm.getCandidateMap().get(req);
                 if (!existingPermCands.iterator().next().equals(candidates.iterator().next()))
                 {
                     permutated = true;
@@ -1423,7 +1278,7 @@ System.out.println("+++ FRAGMENTS: " + f
             // import, do so now.
             if (!permutated)
             {
-                permutate(candidateMap, req, permutations);
+                permutate(allCandidates, req, permutations);
             }
         }
     }
@@ -1592,28 +1447,6 @@ System.out.println("+++ FRAGMENTS: " + f
         return sources;
     }
 
-    private static Map<Requirement, SortedSet<Capability>> copyCandidateMap(
-        Map<Requirement, SortedSet<Capability>> candidateMap)
-    {
-        if (m_isInvokeCount)
-        {
-            String methodName = new Exception().fillInStackTrace().getStackTrace()[0].getMethodName();
-            Long count = m_invokeCounts.get(methodName);
-            count = (count == null) ? new Long(1) : new Long(count.longValue() + 1);
-            m_invokeCounts.put(methodName, count);
-        }
-
-        Map<Requirement, SortedSet<Capability>> copy =
-            new HashMap<Requirement, SortedSet<Capability>>();
-        for (Entry<Requirement, SortedSet<Capability>> entry : candidateMap.entrySet())
-        {
-            SortedSet<Capability> candidates = new TreeSet(new CandidateComparator());
-            candidates.addAll(entry.getValue());
-            copy.put(entry.getKey(), candidates);
-        }
-        return copy;
-    }
-
     private static Module getActualModule(Module m)
     {
         if (m instanceof WrappedModule)
@@ -1644,7 +1477,7 @@ System.out.println("+++ FRAGMENTS: " + f
     private static Map<Module, List<Wire>> populateWireMap(
         Module module, Map<Module, Packages> modulePkgMap,
         Map<Module, List<Wire>> wireMap,
-        Map<Requirement, SortedSet<Capability>> candidateMap)
+        Candidates allCandidates)
     {
         if (m_isInvokeCount)
         {
@@ -1653,32 +1486,32 @@ System.out.println("+++ FRAGMENTS: " + f
             count = (count == null) ? new Long(1) : new Long(count.longValue() + 1);
             m_invokeCounts.put(methodName, count);
         }
-
-        if (!module.isResolved() && !wireMap.containsKey(module))
+        Module unwrappedModule = getActualModule(module);
+        if (!unwrappedModule.isResolved() && !wireMap.containsKey(unwrappedModule))
         {
-            wireMap.put(module, (List<Wire>) Collections.EMPTY_LIST);
+            wireMap.put(unwrappedModule, (List<Wire>) Collections.EMPTY_LIST);
 
             List<Wire> packageWires = new ArrayList<Wire>();
             List<Wire> moduleWires = new ArrayList<Wire>();
 
-            for (Requirement req : module.getRequirements())
+            for (Requirement req : unwrappedModule.getRequirements())
             {
-                Set<Capability> cands = candidateMap.get(req);
+                Set<Capability> cands = allCandidates.getCandidateMap().get(req);
                 if ((cands != null) && (cands.size() > 0))
                 {
                     Capability cand = cands.iterator().next();
                     if (!cand.getModule().isResolved())
                     {
                         populateWireMap(cand.getModule(),
-                            modulePkgMap, wireMap, candidateMap);
+                            modulePkgMap, wireMap, allCandidates);
                     }
                     // Ignore modules that import themselves.
                     if (req.getNamespace().equals(Capability.PACKAGE_NAMESPACE)
-                        && !module.equals(cand.getModule()))
+                        && !unwrappedModule.equals(cand.getModule()))
                     {
                         packageWires.add(
                             new WireImpl(
-                                getActualModule(module),
+                                getActualModule(unwrappedModule),
                                 getActualRequirement(req),
                                 getActualModule(cand.getModule()),
                                 getActualCapability(cand)));
@@ -1688,7 +1521,7 @@ System.out.println("+++ FRAGMENTS: " + f
                         Packages candPkgs = modulePkgMap.get(cand.getModule());
                         moduleWires.add(
                             new WireModuleImpl(
-                                getActualModule(module),
+                                getActualModule(unwrappedModule),
                                 getActualRequirement(req),
                                 getActualModule(cand.getModule()),
                                 getActualCapability(cand),
@@ -1699,7 +1532,7 @@ System.out.println("+++ FRAGMENTS: " + f
 
             // Combine wires with module wires last.
             packageWires.addAll(moduleWires);
-            wireMap.put(module, packageWires);
+            wireMap.put(unwrappedModule, packageWires);
 
             // Add host wire for any fragments.
             if (module instanceof WrappedModule)
@@ -1717,7 +1550,7 @@ System.out.println("+++ FRAGMENTS: " + f
                         new WireHostImpl(
                             getActualModule(fragment),
                             null,
-                            getActualModule(module),
+                            unwrappedModule,
                             null));
                 }
             }
@@ -1728,8 +1561,7 @@ System.out.println("+++ FRAGMENTS: " + f
 
     private static Map<Module, List<Wire>> populateDynamicWireMap(
         Module module, String pkgName, Map<Module, Packages> modulePkgMap,
-        Map<Module, List<Wire>> wireMap,
-        Map<Requirement, SortedSet<Capability>> candidateMap)
+        Map<Module, List<Wire>> wireMap, Candidates allCandidates)
     {
         if (m_isInvokeCount)
         {
@@ -1756,7 +1588,7 @@ System.out.println("+++ FRAGMENTS: " + f
                     if (!blame.m_cap.getModule().isResolved())
                     {
                         populateWireMap(blame.m_cap.getModule(), modulePkgMap, wireMap,
-                            candidateMap);
+                            allCandidates);
                     }
 
                     List<Attribute> attrs = new ArrayList();
@@ -1783,12 +1615,12 @@ System.out.println("+++ FRAGMENTS: " + f
         return wireMap;
     }
 
-    private static void dumpCandidateMap(
-        Map<Requirement, SortedSet<Capability>> candidateMap)
+    private static void dumpCandidateMap(Candidates allCandidates)
     {
         // Create set of all modules from requirements.
         Set<Module> modules = new HashSet();
-        for (Entry<Requirement, SortedSet<Capability>> entry : candidateMap.entrySet())
+        for (Entry<Requirement, SortedSet<Capability>> entry
+            : allCandidates.getCandidateMap().entrySet())
         {
             modules.add(entry.getKey().getModule());
         }
@@ -1800,7 +1632,7 @@ System.out.println("+++ FRAGMENTS: " + f
                  + " (" + (module.isResolved() ? "RESOLVED)" : "UNRESOLVED)"));
             for (Requirement req : module.getRequirements())
             {
-                Set<Capability> candidates = candidateMap.get(req);
+                Set<Capability> candidates = allCandidates.getCandidateMap().get(req);
                 if ((candidates != null) && (candidates.size() > 0))
                 {
                     System.out.println("    " + req + ": " + candidates);
@@ -1808,7 +1640,7 @@ System.out.println("+++ FRAGMENTS: " + f
             }
             for (Requirement req : module.getDynamicRequirements())
             {
-                Set<Capability> candidates = candidateMap.get(req);
+                Set<Capability> candidates = allCandidates.getCandidateMap().get(req);
                 if ((candidates != null) && (candidates.size() > 0))
                 {
                     System.out.println("    " + req + ": " + candidates);

Modified: felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/proto3/WrappedModule.java
URL: http://svn.apache.org/viewvc/felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/proto3/WrappedModule.java?rev=1037874&r1=1037873&r2=1037874&view=diff
==============================================================================
--- felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/proto3/WrappedModule.java (original)
+++ felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/proto3/WrappedModule.java Mon Nov 22 20:45:18 2010
@@ -27,7 +27,7 @@ import org.apache.felix.resolver.cs.Requ
 
 class WrappedModule extends Module
 {
-    private final String m_name;
+    private final String m_id;
     private final Module m_module;
     private final List<Module> m_fragments = new ArrayList();
     private List<Capability> m_cachedCapabilities = null;
@@ -36,9 +36,9 @@ class WrappedModule extends Module
 // TODO: RESOLVER - WE COULD PASS ALL FRAGMENTS INTO THE CONSTRUCTOR.
     public WrappedModule(Module module)
     {
-        super(module.getName());
+        super(module.getId(), module.getSymbolicName(), module.getVersion());
         m_module = module;
-        m_name = module.getName() + " [" + super.hashCode() + "]";
+        m_id = module.getId() + " [" + super.hashCode() + "]";
     }
 
     public Module getWrappedModule()
@@ -56,9 +56,9 @@ class WrappedModule extends Module
         return m_fragments;
     }
 
-    public String getName()
+    public String getId()
     {
-        return m_name;
+        return m_id;
     }
 
     public List<Capability> getCapabilities()