Apply patch (FELIX-3934) to special case fragment identity requirements
wires.


git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1452535 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/resolver/src/main/java/org/apache/felix/resolver/ResolverImpl.java b/resolver/src/main/java/org/apache/felix/resolver/ResolverImpl.java
index 4fa2d0b..4a3ee90 100644
--- a/resolver/src/main/java/org/apache/felix/resolver/ResolverImpl.java
+++ b/resolver/src/main/java/org/apache/felix/resolver/ResolverImpl.java
@@ -29,9 +29,11 @@
 import java.util.Map.Entry;
 import java.util.Set;
 import java.util.StringTokenizer;
+
 import org.osgi.framework.namespace.BundleNamespace;
 import org.osgi.framework.namespace.ExecutionEnvironmentNamespace;
 import org.osgi.framework.namespace.HostNamespace;
+import org.osgi.framework.namespace.IdentityNamespace;
 import org.osgi.framework.namespace.PackageNamespace;
 import org.osgi.resource.Capability;
 import org.osgi.resource.Namespace;
@@ -1725,11 +1727,28 @@
                         if (!cand.getNamespace().startsWith("osgi.wiring.")
                             || !resource.equals(cand.getResource()))
                         {
+                            // If we don't already have wires for the candidate,
+                            // then recursively populate them.
                             if (!rc.getWirings().containsKey(cand.getResource()))
                             {
-                                populateWireMap(rc, cand.getResource(),
+                                // Need to special case the candidate for identity
+                                // capabilities since it may be from a fragment and
+                                // we don't want to populate wires for the fragment,
+                                // but rather the host to which it is attached.
+                                Resource targetCand = cand.getResource();
+                                if (IdentityNamespace.IDENTITY_NAMESPACE.equals(cand.getNamespace())
+                                    && Util.isFragment(targetCand))
+                                {
+                                    targetCand = allCandidates.getCandidates(
+                                        targetCand.getRequirements(HostNamespace.HOST_NAMESPACE).get(0))
+                                            .iterator().next().getResource();
+                                    targetCand = allCandidates.getWrappedHost(targetCand);
+                                }
+
+                                populateWireMap(rc, targetCand,
                                     resourcePkgMap, wireMap, allCandidates);
                             }
+
                             Wire wire = new WireImpl(
                                 unwrappedResource,
                                 getDeclaredRequirement(req),
diff --git a/resolver/src/main/java/org/apache/felix/resolver/test/IdentityCapability.java b/resolver/src/main/java/org/apache/felix/resolver/test/IdentityCapability.java
index 033efdb..adcd858 100644
--- a/resolver/src/main/java/org/apache/felix/resolver/test/IdentityCapability.java
+++ b/resolver/src/main/java/org/apache/felix/resolver/test/IdentityCapability.java
@@ -20,6 +20,7 @@
 
 import java.util.HashMap;
 import java.util.Map;
+
 import org.osgi.framework.namespace.IdentityNamespace;
 import org.osgi.resource.Capability;
 import org.osgi.resource.Resource;
@@ -30,12 +31,13 @@
     private final Map<String, String> m_dirs;
     private final Map<String, Object> m_attrs;
 
-    public IdentityCapability(Resource resource, String name)
+    public IdentityCapability(Resource resource, String name, String type)
     {
         m_resource = resource;
         m_dirs = new HashMap<String, String>();
         m_attrs = new HashMap<String, Object>();
         m_attrs.put(IdentityNamespace.IDENTITY_NAMESPACE, name);
+        m_attrs.put(IdentityNamespace.CAPABILITY_TYPE_ATTRIBUTE, type);
     }
 
     public String getNamespace()
diff --git a/resolver/src/main/java/org/apache/felix/resolver/test/Main.java b/resolver/src/main/java/org/apache/felix/resolver/test/Main.java
index a5a975e..524d077 100644
--- a/resolver/src/main/java/org/apache/felix/resolver/test/Main.java
+++ b/resolver/src/main/java/org/apache/felix/resolver/test/Main.java
@@ -24,9 +24,12 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+
 import org.apache.felix.resolver.Logger;
 import org.apache.felix.resolver.ResolverImpl;
 import org.osgi.framework.namespace.BundleNamespace;
+import org.osgi.framework.namespace.HostNamespace;
+import org.osgi.framework.namespace.IdentityNamespace;
 import org.osgi.framework.namespace.PackageNamespace;
 import org.osgi.resource.Capability;
 import org.osgi.resource.Namespace;
@@ -45,11 +48,14 @@
 
         Map<Resource, Wiring> wirings = new HashMap<Resource, Wiring>();
         Map<Requirement, List<Capability>> candMap = new HashMap<Requirement, List<Capability>>();
+        List<Resource> mandatory;
+        ResolveContextImpl rci;
+        Map<Resource, List<Wire>> wireMap;
 
         System.out.println("\nSCENARIO 1\n");
-        List<Resource> mandatory = populateScenario1(wirings, candMap);
-        ResolveContextImpl rci = new ResolveContextImpl(wirings, candMap, mandatory, Collections.EMPTY_LIST);
-        Map<Resource, List<Wire>> wireMap = resolver.resolve(rci);
+        mandatory = populateScenario1(wirings, candMap);
+        rci = new ResolveContextImpl(wirings, candMap, mandatory, Collections.EMPTY_LIST);
+        wireMap = resolver.resolve(rci);
         System.out.println("RESULT " + wireMap);
 
         System.out.println("\nSCENARIO 2\n");
@@ -98,6 +104,11 @@
         wireMap = resolver.resolve(rci);
         System.out.println("RESULT " + wireMap);
 
+        System.out.println("\nSCENARIO 7\n");
+        mandatory = populateScenario7(wirings, candMap);
+        rci = new ResolveContextImpl(wirings, candMap, mandatory, Collections.EMPTY_LIST);
+        wireMap = resolver.resolve(rci);
+        System.out.println("RESULT " + wireMap);
     }
 
     private static List<Resource> populateScenario1(
@@ -399,4 +410,47 @@
         resources.add(a2);
         return resources;
     }
+
+    private static List<Resource> populateScenario7(
+            Map<Resource, Wiring> wirings, Map<Requirement, List<Capability>> candMap)
+    {
+        wirings.clear();
+        candMap.clear();
+
+        ResourceImpl a1 = new ResourceImpl("A");
+        GenericCapability a1_hostCap = new GenericCapability(a1, HostNamespace.HOST_NAMESPACE);
+        a1_hostCap.addAttribute(HostNamespace.HOST_NAMESPACE, "A");
+        a1.addCapability(a1_hostCap);
+
+        ResourceImpl f1 = new ResourceImpl("F1", IdentityNamespace.TYPE_FRAGMENT);
+        GenericRequirement f1_hostReq = new GenericRequirement(f1, HostNamespace.HOST_NAMESPACE);
+        f1_hostReq.addDirective(Namespace.REQUIREMENT_FILTER_DIRECTIVE, "(" + HostNamespace.HOST_NAMESPACE + "=A)");
+        f1.addRequirement(f1_hostReq);
+
+        ResourceImpl f2 = new ResourceImpl("F2", IdentityNamespace.TYPE_FRAGMENT);
+        GenericRequirement f2_hostReq = new GenericRequirement(f2, HostNamespace.HOST_NAMESPACE);
+        f2_hostReq.addDirective(Namespace.REQUIREMENT_FILTER_DIRECTIVE, "(" + HostNamespace.HOST_NAMESPACE + "=A)");
+        f2.addRequirement(f2_hostReq);
+
+        ResourceImpl b1 = new ResourceImpl("B");
+        GenericRequirement b1_identityReq = new GenericRequirement(f2, IdentityNamespace.IDENTITY_NAMESPACE);
+        b1_identityReq.addDirective(Namespace.REQUIREMENT_FILTER_DIRECTIVE, "(" + IdentityNamespace.IDENTITY_NAMESPACE + "=F2)");
+        b1.addRequirement(b1_identityReq);
+
+        candMap.put(
+            f1.getRequirements(null).get(0),
+            a1.getCapabilities(HostNamespace.HOST_NAMESPACE));
+        candMap.put(
+            f2.getRequirements(null).get(0),
+            a1.getCapabilities(HostNamespace.HOST_NAMESPACE));
+        candMap.put(
+            b1.getRequirements(null).get(0),
+            f2.getCapabilities(IdentityNamespace.IDENTITY_NAMESPACE));
+        List<Resource> resources = new ArrayList<Resource>();
+        resources.add(a1);
+        resources.add(f1);
+        resources.add(f2);
+        resources.add(b1);
+        return resources;
+    }
 }
\ No newline at end of file
diff --git a/resolver/src/main/java/org/apache/felix/resolver/test/ResourceImpl.java b/resolver/src/main/java/org/apache/felix/resolver/test/ResourceImpl.java
index 7971f97..dabc141 100644
--- a/resolver/src/main/java/org/apache/felix/resolver/test/ResourceImpl.java
+++ b/resolver/src/main/java/org/apache/felix/resolver/test/ResourceImpl.java
@@ -30,10 +30,13 @@
     private final List<Capability> m_caps;
     private final List<Requirement> m_reqs;
 
-    public ResourceImpl(String name)
+    public ResourceImpl(String name) {
+        this(name, IdentityNamespace.TYPE_BUNDLE);
+    }
+    public ResourceImpl(String name, String type)
     {
         m_caps = new ArrayList<Capability>();
-        m_caps.add(0, new IdentityCapability(this, name));
+        m_caps.add(0, new IdentityCapability(this, name, type));
         m_reqs = new ArrayList<Requirement>();
     }