FELIX-5195 Provide-Capability not being processed for Resources

Applying patch in behalf of Stephen Kahmann with many thanks.
This closes #53


git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1733051 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/DataModelHelperImpl.java b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/DataModelHelperImpl.java
index aefde53..5971a67 100644
--- a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/DataModelHelperImpl.java
+++ b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/DataModelHelperImpl.java
@@ -560,6 +560,7 @@
         doExports(resource, headers);
         doImports(resource, headers);
         doExecutionEnvironment(resource, headers);
+        doProvides(resource, headers);
     }
 
     private static void doCategories(ResourceImpl resource, Headers headers)
@@ -704,6 +705,17 @@
         }
     }
 
+    private static void doProvides(ResourceImpl resource, Headers headers) {
+        Clause[] clauses = Parser.parseHeader(headers.getHeader(Constants.PROVIDE_CAPABILITY));
+
+        if (clauses != null) {
+            for (Clause clause : clauses) {
+                CapabilityImpl capability = createCapability(clause.getName(), clause);
+                resource.addCapability(capability);
+            }
+        }
+    }
+
     private static CapabilityImpl createCapability(String name, Clause clause)
     {
         CapabilityImpl capability = new CapabilityImpl(name);
@@ -713,7 +725,7 @@
         for (int i = 0; attributes != null && i < attributes.length; i++)
         {
             String key = attributes[i].getName();
-            if (key.equalsIgnoreCase(Constants.PACKAGE_SPECIFICATION_VERSION) || key.equalsIgnoreCase(Constants.VERSION_ATTRIBUTE))
+            if (key.equalsIgnoreCase(Constants.PACKAGE_SPECIFICATION_VERSION) || key.equalsIgnoreCase(Constants.VERSION_ATTRIBUTE) || key.equalsIgnoreCase("version:Version"))
             {
                 continue;
             }
@@ -846,6 +858,11 @@
         {
             v = clause.getAttribute(Constants.BUNDLE_VERSION_ATTRIBUTE);
         }
+        if (v == null)
+        {
+            v = clause.getAttribute("version:Version");
+        }
+
         return VersionCleaner.clean(v);
     }
 
diff --git a/bundlerepository/src/test/java/org/apache/felix/bundlerepository/impl/DataModelHelperTest.java b/bundlerepository/src/test/java/org/apache/felix/bundlerepository/impl/DataModelHelperTest.java
index 758539b..b4f0e1e 100644
--- a/bundlerepository/src/test/java/org/apache/felix/bundlerepository/impl/DataModelHelperTest.java
+++ b/bundlerepository/src/test/java/org/apache/felix/bundlerepository/impl/DataModelHelperTest.java
@@ -19,13 +19,20 @@
 package org.apache.felix.bundlerepository.impl;
 
 import java.net.URL;
+import java.util.Map;
 import java.util.jar.Attributes;
 
 import junit.framework.TestCase;
+import org.apache.felix.bundlerepository.Capability;
 import org.apache.felix.bundlerepository.DataModelHelper;
 import org.apache.felix.bundlerepository.Repository;
 import org.apache.felix.bundlerepository.Resource;
+import org.apache.felix.utils.manifest.Clause;
+import org.osgi.framework.Constants;
+
 import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 
 public class DataModelHelperTest extends TestCase
 {
@@ -65,7 +72,49 @@
         r.setFilter("(&(package=javax.transaction)(partial=true)(mandatory:<*partial))");
         assertEquals("(&(package=javax.transaction)(partial=true)(mandatory:<*partial))", r.getFilter());
     }
-    
+
+    public void testCapabilities() throws Exception {
+        Attributes attr = new Attributes();
+        attr.putValue("Manifest-Version", "1.0");
+        attr.putValue("Bundle-Name", "Apache Felix Utils");
+        attr.putValue("Bundle-Version", "0.1.0.SNAPSHOT");
+        attr.putValue("Bundle-ManifestVersion", "2");
+        attr.putValue("Bundle-License", "http://www.apache.org/licenses/LICENSE-2.0.txt");
+        attr.putValue("Bundle-Description", "Utility classes for OSGi.");
+        attr.putValue("Import-Package", "org.osgi.framework;version=\"[1.4,2)\"");
+        attr.putValue("Bundle-SymbolicName", "org.apache.felix.utils");
+        attr.putValue("Provide-Capability", "osgi.extender;osgi.extender=\"osgi.component\";uses:=\"\n" +
+                " org.osgi.service.component\";version:Version=\"1.3\",osgi.service;objectCl\n" +
+                " ass:List<String>=\"org.osgi.service.component.runtime.ServiceComponentRu\n" +
+                " ntime\";uses:=\"org.osgi.service.component.runtime\"");
+
+        Resource resource = dmh.createResource(attr);
+
+        assertEquals(3, resource.getCapabilities().length);
+
+        Capability bundleCap = null;
+        Capability osgiExtenderCap = null;
+        Capability osgiServiceCap = null;
+
+        for (Capability capability : resource.getCapabilities()) {
+            if (capability.getName().equals("bundle")) {
+                bundleCap = capability;
+            } else if (capability.getName().equals("osgi.extender")) {
+                osgiExtenderCap = capability;
+            } else {
+                osgiServiceCap = capability;
+            }
+        }
+
+        assertNotNull(bundleCap);
+        assertNotNull(osgiExtenderCap);
+        assertNotNull(osgiServiceCap);
+
+        assertEquals("osgi.extender", osgiExtenderCap.getName());
+        assertEquals("osgi.component", osgiExtenderCap.getPropertiesAsMap().get("osgi.extender"));
+        assertEquals("1.3.0", osgiExtenderCap.getPropertiesAsMap().get(Constants.VERSION_ATTRIBUTE).toString());
+    }
+
     public void testGzipResource() throws Exception {
         URL urlArchive = getClass().getResource("/spec_repository.gz");
         assertNotNull("GZ archive was not found", urlArchive);
diff --git a/bundlerepository/src/test/java/org/apache/felix/bundlerepository/impl/ResolverImplTest.java b/bundlerepository/src/test/java/org/apache/felix/bundlerepository/impl/ResolverImplTest.java
index 12f8118..56a8395 100644
--- a/bundlerepository/src/test/java/org/apache/felix/bundlerepository/impl/ResolverImplTest.java
+++ b/bundlerepository/src/test/java/org/apache/felix/bundlerepository/impl/ResolverImplTest.java
@@ -60,9 +60,7 @@
     {
         URL url = getClass().getResource("/spec_repository.xml");
         RepositoryAdminImpl repoAdmin = createRepositoryAdmin();
-        RepositoryImpl repo = (RepositoryImpl) repoAdmin.addRepository(url);
-
-        System.out.println(repo.getResources().length + " Resources in Repo");
+        repoAdmin.addRepository(url);
 
         Resolver resolver = repoAdmin.resolver();
 
@@ -79,6 +77,46 @@
         assertTrue("Resolver could not resolve", resolver.resolve());
     }
 
+    public void testSpec2() throws Exception
+    {
+        URL url = getClass().getResource("/spec_repository.xml");
+        RepositoryAdminImpl repoAdmin = createRepositoryAdmin();
+        repoAdmin.addRepository(url);
+
+        Resolver resolver = repoAdmin.resolver();
+
+        // Create a Local Resource with an extender capability
+        CapabilityImpl capability = new CapabilityImpl("osgi.extender");
+        capability.addProperty("osgi.extender", "osgi.component");
+        capability.addProperty("version", "Version", "1.3");
+
+        org.apache.felix.bundlerepository.Capability[] capabilities = { capability };
+
+        Resource resource = EasyMock.createMock(Resource.class);
+        EasyMock.expect(resource.getSymbolicName()).andReturn("com.test.bundleA").anyTimes();
+        EasyMock.expect(resource.getRequirements()).andReturn(null).anyTimes();
+        EasyMock.expect(resource.getCapabilities()).andReturn(capabilities).anyTimes();
+        EasyMock.expect(resource.getURI()).andReturn("http://test.com").anyTimes();
+        EasyMock.expect(resource.isLocal()).andReturn(true).anyTimes();
+
+        EasyMock.replay(resource);
+
+        resolver.add(resource);
+
+        // Set the requirements to get the bundle
+        RequirementImpl requirement = new RequirementImpl("foo");
+        requirement.setFilter("(bar=bread)");
+
+        Requirement[] requirements = { requirement };
+
+        Resource[] discoverResources = repoAdmin.discoverResources(requirements);
+        assertNotNull(discoverResources);
+        assertEquals(1, discoverResources.length);
+
+        resolver.add(discoverResources[0]);
+        assertTrue("Resolver could not resolve", resolver.resolve());
+    }
+
     public void testMatchingReq() throws Exception
     {
         RepositoryAdminImpl repoAdmin = createRepositoryAdmin();
diff --git a/bundlerepository/src/test/resources/spec_repository.gz b/bundlerepository/src/test/resources/spec_repository.gz
index 8f065b8..778c8b1 100644
--- a/bundlerepository/src/test/resources/spec_repository.gz
+++ b/bundlerepository/src/test/resources/spec_repository.gz
Binary files differ
diff --git a/bundlerepository/src/test/resources/spec_repository.xml b/bundlerepository/src/test/resources/spec_repository.xml
index a578a6a..0db196d 100644
--- a/bundlerepository/src/test/resources/spec_repository.xml
+++ b/bundlerepository/src/test/resources/spec_repository.xml
@@ -44,6 +44,27 @@
       <directive name='filter' value='(osgi.wiring.package=com.foo)'/>
     </requirement>
   </resource>
+    <resource>
+        <capability namespace='osgi.identity'>
+            <attribute name='osgi.identity' value='org.apache.felix.bundlerepository.test_file_5'/>
+            <attribute name='type' value='osgi.bundle'/>
+            <attribute name='version' type='Version' value='2.2.3.something'/>
+            <attribute name='license' value='http://www.opensource.org/licenses/mytestlicense2' />
+        </capability>
+        <capability namespace='osgi.content'>
+            <attribute name='osgi.content' value='a1c64578808c38a63cd6563e9936f025638aeaf9de70f36765367db81c0afc38'/>
+            <attribute name='url' value='repo_files/test_file_5.jar'/>
+            <attribute name='size' type='Long' value='3'/>
+            <attribute name='mime' value='application/vnd.osgi.bundle'/>
+        </capability>
+        <capability namespace='foo'>
+            <attribute name='bar' value='bread'/>
+        </capability>
+        <requirement namespace="osgi.extender">
+            <directive name="filter" value="(&amp;(osgi.extender=osgi.component)(version&gt;=1.0.0)(!(version&gt;=2.0.0)))"/>
+            <directive name="effective" value="active"/>
+        </requirement>
+    </resource>
   <resource>
     <capability namespace='osgi.identity'>
       <attribute name='osgi.identity' value='org.apache.sshd.core'/>