You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by da...@apache.org on 2015/11/30 18:35:36 UTC

svn commit: r1717300 - in /aries/trunk/spi-fly: spi-fly-core/src/main/java/org/apache/aries/spifly/ spi-fly-core/src/test/java/org/apache/aries/spifly/ spi-fly-dynamic-bundle/src/test/java/org/apache/aries/spifly/dynamic/

Author: davidb
Date: Mon Nov 30 17:35:35 2015
New Revision: 1717300

URL: http://svn.apache.org/viewvc?rev=1717300&view=rev
Log:
ARIES-1461 Support for SPI Fly headers added via fragments.

Modified:
    aries/trunk/spi-fly/spi-fly-core/src/main/java/org/apache/aries/spifly/BaseActivator.java
    aries/trunk/spi-fly/spi-fly-core/src/main/java/org/apache/aries/spifly/ProviderBundleTrackerCustomizer.java
    aries/trunk/spi-fly/spi-fly-core/src/test/java/org/apache/aries/spifly/ProviderBundleTrackerCustomizerGenericCapabilityTest.java
    aries/trunk/spi-fly/spi-fly-dynamic-bundle/src/test/java/org/apache/aries/spifly/dynamic/ClientWeavingHookGenericCapabilityTest.java
    aries/trunk/spi-fly/spi-fly-dynamic-bundle/src/test/java/org/apache/aries/spifly/dynamic/ClientWeavingHookOSGi43Test.java
    aries/trunk/spi-fly/spi-fly-dynamic-bundle/src/test/java/org/apache/aries/spifly/dynamic/ClientWeavingHookTest.java

Modified: aries/trunk/spi-fly/spi-fly-core/src/main/java/org/apache/aries/spifly/BaseActivator.java
URL: http://svn.apache.org/viewvc/aries/trunk/spi-fly/spi-fly-core/src/main/java/org/apache/aries/spifly/BaseActivator.java?rev=1717300&r1=1717299&r2=1717300&view=diff
==============================================================================
--- aries/trunk/spi-fly/spi-fly-core/src/main/java/org/apache/aries/spifly/BaseActivator.java (original)
+++ aries/trunk/spi-fly/spi-fly-core/src/main/java/org/apache/aries/spifly/BaseActivator.java Mon Nov 30 17:35:35 2015
@@ -22,6 +22,7 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Hashtable;
 import java.util.Iterator;
 import java.util.List;
@@ -38,10 +39,11 @@ import java.util.concurrent.CopyOnWriteA
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
+import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.framework.wiring.BundleWire;
+import org.osgi.framework.wiring.BundleWiring;
 import org.osgi.service.log.LogService;
 import org.osgi.util.tracker.BundleTracker;
-import org.osgi.util.tracker.ServiceTracker;
 
 public abstract class BaseActivator implements BundleActivator {
     private static final Set<WeavingData> NON_WOVEN_BUNDLE = Collections.emptySet();
@@ -89,14 +91,19 @@ public abstract class BaseActivator impl
             return;
         }
 
-        Object consumerHeader = bundle.getHeaders().get(consumerHeaderName);
-        if (consumerHeader == null) {
-            consumerHeaderName = SpiFlyConstants.REQUIRE_CAPABILITY;
-            consumerHeader = bundle.getHeaders().get(consumerHeaderName);
+        Map<String, List<String>> allHeaders = new HashMap<String, List<String>>();
+        allHeaders.put(consumerHeaderName, getAllHeaders(consumerHeaderName, bundle));
+        allHeaders.put(SpiFlyConstants.REQUIRE_CAPABILITY, getAllHeaders(SpiFlyConstants.REQUIRE_CAPABILITY, bundle));
+
+        Set<WeavingData> wd = new HashSet<WeavingData>();
+        for (Map.Entry<String, List<String>> entry : allHeaders.entrySet()) {
+            String headerName = entry.getKey();
+            for (String headerVal : entry.getValue()) {
+                wd.addAll(ConsumerHeaderProcessor.processHeader(headerName, headerVal));
+            }
         }
 
-        if (consumerHeader instanceof String) {
-            Set<WeavingData> wd = ConsumerHeaderProcessor.processHeader(consumerHeaderName, (String) consumerHeader);
+        if (!wd.isEmpty()) {
             bundleWeavingData.put(bundle, Collections.unmodifiableSet(wd));
 
             for (WeavingData w : wd) {
@@ -107,6 +114,28 @@ public abstract class BaseActivator impl
         }
     }
 
+    private List<String> getAllHeaders(String headerName, Bundle bundle) {
+        List<Bundle> bundlesFragments = new ArrayList<Bundle>();
+        bundlesFragments.add(bundle);
+
+        BundleRevision rev = bundle.adapt(BundleRevision.class);
+        if (rev != null) {
+            BundleWiring wiring = rev.getWiring();
+            if (wiring != null) {
+                for (BundleWire wire : wiring.getProvidedWires("osgi.wiring.host")) {
+                    bundlesFragments.add(wire.getRequirement().getRevision().getBundle());
+                }
+            }
+        }
+
+        List<String> l = new ArrayList<String>();
+        for (Bundle bf : bundlesFragments) {
+            l.add(bf.getHeaders().get(headerName));
+        }
+
+        return l;
+    }
+
     public void removeWeavingData(Bundle bundle) {
         bundleWeavingData.remove(bundle);
     }

Modified: aries/trunk/spi-fly/spi-fly-core/src/main/java/org/apache/aries/spifly/ProviderBundleTrackerCustomizer.java
URL: http://svn.apache.org/viewvc/aries/trunk/spi-fly/spi-fly-core/src/main/java/org/apache/aries/spifly/ProviderBundleTrackerCustomizer.java?rev=1717300&r1=1717299&r2=1717300&view=diff
==============================================================================
--- aries/trunk/spi-fly/spi-fly-core/src/main/java/org/apache/aries/spifly/ProviderBundleTrackerCustomizer.java (original)
+++ aries/trunk/spi-fly/spi-fly-core/src/main/java/org/apache/aries/spifly/ProviderBundleTrackerCustomizer.java Mon Nov 30 17:35:35 2015
@@ -45,6 +45,9 @@ import org.osgi.framework.FrameworkUtil;
 import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServicePermission;
 import org.osgi.framework.ServiceRegistration;
+import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.framework.wiring.BundleWire;
+import org.osgi.framework.wiring.BundleWiring;
 import org.osgi.service.log.LogService;
 import org.osgi.util.tracker.BundleTrackerCustomizer;
 
@@ -73,15 +76,16 @@ public class ProviderBundleTrackerCustom
         Map<String, Object> customAttributes = new HashMap<String, Object>();
         if (bundle.getHeaders().get(SpiFlyConstants.REQUIRE_CAPABILITY) != null) {
             try {
-                providedServices = readServiceLoaderMediatorCapabilityMetadata(bundle.getHeaders(), customAttributes);
+                providedServices = readServiceLoaderMediatorCapabilityMetadata(bundle, customAttributes);
             } catch (InvalidSyntaxException e) {
                 log(LogService.LOG_ERROR, "Unable to read capabilities from bundle " + bundle, e);
             }
         }
 
         boolean fromSPIProviderHeader = false;
-        if (providedServices == null && bundle.getHeaders().get(SpiFlyConstants.SPI_PROVIDER_HEADER) != null) {
-            String header = bundle.getHeaders().get(SpiFlyConstants.SPI_PROVIDER_HEADER).toString().trim();
+        String spiProviderHeader = getHeaderFromBundleOrFragment(bundle, SpiFlyConstants.SPI_PROVIDER_HEADER);
+        if (providedServices == null && spiProviderHeader != null) {
+            String header = spiProviderHeader.trim();
             if ("*".equals(header)) {
                 providedServices = new ArrayList<String>();
             } else {
@@ -204,25 +208,62 @@ public class ProviderBundleTrackerCustom
         return registrations;
     }
 
+    private String getHeaderFromBundleOrFragment(Bundle bundle, String headerName) {
+        return getHeaderFromBundleOrFragment(bundle, headerName, null);
+    }
+
+    private String getHeaderFromBundleOrFragment(Bundle bundle, String headerName, String matchString) {
+        String val = bundle.getHeaders().get(headerName);
+        if (matches(val, matchString))
+            return val;
+
+        BundleRevision rev = bundle.adapt(BundleRevision.class);
+        if (rev != null) {
+            BundleWiring wiring = rev.getWiring();
+            if (wiring != null) {
+                for (BundleWire wire : wiring.getProvidedWires("osgi.wiring.host")) {
+                    Bundle fragment = wire.getRequirement().getRevision().getBundle();
+                    val = fragment.getHeaders().get(headerName);
+                    if (matches(val, matchString)) {
+                        return val;
+                    }
+                }
+            }
+        }
+
+        return null;
+    }
+
+    private boolean matches(String val, String matchString) {
+        if (val == null)
+            return false;
+
+        if (matchString == null)
+            return true;
+
+        int idx = val.indexOf(matchString);
+        return idx >= 0;
+    }
+
     // An empty list returned means 'all SPIs'
     // A return value of null means no SPIs
     // A populated list means: only these SPIs
-    private List<String> readServiceLoaderMediatorCapabilityMetadata(Dictionary<?,?> headers, Map<String, Object> customAttributes) throws InvalidSyntaxException {
-        Object requirementHeader = headers.get(SpiFlyConstants.REQUIRE_CAPABILITY);
+    private List<String> readServiceLoaderMediatorCapabilityMetadata(Bundle bundle, Map<String, Object> customAttributes) throws InvalidSyntaxException {
+        String requirementHeader = getHeaderFromBundleOrFragment(bundle, SpiFlyConstants.REQUIRE_CAPABILITY, SpiFlyConstants.SERVICELOADER_CAPABILITY_NAMESPACE);
         if (requirementHeader == null)
             return null;
 
-        List<GenericMetadata> requirements = ManifestHeaderProcessor.parseRequirementString(requirementHeader.toString());
+        List<GenericMetadata> requirements = ManifestHeaderProcessor.parseRequirementString(requirementHeader);
         GenericMetadata extenderRequirement = findRequirement(requirements, SpiFlyConstants.EXTENDER_CAPABILITY_NAMESPACE, SpiFlyConstants.REGISTRAR_EXTENDER_NAME);
         if (extenderRequirement == null)
             return null;
 
         List<GenericMetadata> capabilities;
-        Object capabilityHeader = headers.get(SpiFlyConstants.PROVIDE_CAPABILITY);
+        String capabilityHeader = getHeaderFromBundleOrFragment(bundle, SpiFlyConstants.PROVIDE_CAPABILITY, SpiFlyConstants.SERVICELOADER_CAPABILITY_NAMESPACE);
         if (capabilityHeader == null) {
             capabilities = Collections.emptyList();
         } else {
-            capabilities = ManifestHeaderProcessor.parseCapabilityString(capabilityHeader.toString());
+            capabilities = ManifestHeaderProcessor.parseCapabilityString(capabilityHeader);
         }
 
         List<String> serviceNames = new ArrayList<String>();

Modified: aries/trunk/spi-fly/spi-fly-core/src/test/java/org/apache/aries/spifly/ProviderBundleTrackerCustomizerGenericCapabilityTest.java
URL: http://svn.apache.org/viewvc/aries/trunk/spi-fly/spi-fly-core/src/test/java/org/apache/aries/spifly/ProviderBundleTrackerCustomizerGenericCapabilityTest.java?rev=1717300&r1=1717299&r2=1717300&view=diff
==============================================================================
--- aries/trunk/spi-fly/spi-fly-core/src/test/java/org/apache/aries/spifly/ProviderBundleTrackerCustomizerGenericCapabilityTest.java (original)
+++ aries/trunk/spi-fly/spi-fly-core/src/test/java/org/apache/aries/spifly/ProviderBundleTrackerCustomizerGenericCapabilityTest.java Mon Nov 30 17:35:35 2015
@@ -18,12 +18,6 @@
  */
 package org.apache.aries.spifly;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertTrue;
-
 import java.net.URL;
 import java.net.URLClassLoader;
 import java.util.Arrays;
@@ -43,10 +37,7 @@ import org.apache.aries.spifly.impl4.MyS
 import org.apache.aries.spifly.impl4.MySPIImpl4c;
 import org.easymock.EasyMock;
 import org.easymock.IAnswer;
-import org.easymock.IExpectationSetters;
-
 import org.junit.Test;
-
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
@@ -54,6 +45,12 @@ import org.osgi.framework.ServiceFactory
 import org.osgi.framework.ServiceReference;
 import org.osgi.framework.ServiceRegistration;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
 public class ProviderBundleTrackerCustomizerGenericCapabilityTest {
     @Test
     public void testAddingRemovedBundle() throws Exception {
@@ -79,7 +76,6 @@ public class ProviderBundleTrackerCustom
                 SpiFlyConstants.SERVICELOADER_CAPABILITY_NAMESPACE + "=org.apache.aries.mytest.MySPI");
         Bundle implBundle = mockSPIBundle(implBC, headers);
 
-
         assertEquals("Precondition", 0, activator.findProviderBundles("org.apache.aries.mytest.MySPI").size());
         // Call addingBundle();
         List<ServiceRegistration> registrations = customizer.addingBundle(implBundle, null);
@@ -101,6 +97,38 @@ public class ProviderBundleTrackerCustom
     }
 
     @Test
+    public void testCapReqHeadersInFragment() throws Exception {
+        Bundle mediatorBundle = EasyMock.createMock(Bundle.class);
+        EasyMock.expect(mediatorBundle.getBundleId()).andReturn(42l).anyTimes();
+        EasyMock.replay(mediatorBundle);
+        BaseActivator activator = new BaseActivator() {
+            @Override
+            public void start(BundleContext context) throws Exception {}
+        };
+
+        ProviderBundleTrackerCustomizer customizer = new ProviderBundleTrackerCustomizer(activator, mediatorBundle);
+
+        ServiceRegistration sreg = EasyMock.createMock(ServiceRegistration.class);
+        sreg.unregister();
+        EasyMock.expectLastCall();
+        EasyMock.replay(sreg);
+
+        BundleContext implBC = mockSPIBundleContext(sreg);
+        Dictionary<String, String> headers = new Hashtable<String, String>();
+        headers.put(SpiFlyConstants.REQUIRE_CAPABILITY, SpiFlyConstants.PROVIDER_REQUIREMENT);
+        headers.put(SpiFlyConstants.PROVIDE_CAPABILITY, SpiFlyConstants.SERVICELOADER_CAPABILITY_NAMESPACE + "; " +
+                SpiFlyConstants.SERVICELOADER_CAPABILITY_NAMESPACE + "=org.apache.aries.mytest.MySPI");
+        Bundle implBundle = mockSPIBundle(implBC, headers);
+
+        assertEquals("Precondition", 0, activator.findProviderBundles("org.apache.aries.mytest.MySPI").size());
+        List<ServiceRegistration> registrations = customizer.addingBundle(implBundle, null);
+        Collection<Bundle> bundles = activator.findProviderBundles("org.apache.aries.mytest.MySPI");
+        assertEquals(1, bundles.size());
+        assertSame(implBundle, bundles.iterator().next());
+
+    }
+
+    @Test
     public void testCustomAttributesBundle() throws Exception {
         Bundle mediatorBundle = EasyMock.createMock(Bundle.class);
         EasyMock.expect(mediatorBundle.getBundleId()).andReturn(42l).anyTimes();
@@ -445,7 +473,7 @@ public class ProviderBundleTrackerCustom
         BundleContext implBC = EasyMock.createNiceMock(BundleContext.class);
 
         implBC.registerService(EasyMock.anyString(),
-                               EasyMock.anyObject(), 
+                               EasyMock.anyObject(),
                                (Dictionary<String,?>)EasyMock.anyObject());
         EasyMock.expectLastCall().andAnswer(new IAnswer<ServiceRegistration<Object>>() {
             @Override

Modified: aries/trunk/spi-fly/spi-fly-dynamic-bundle/src/test/java/org/apache/aries/spifly/dynamic/ClientWeavingHookGenericCapabilityTest.java
URL: http://svn.apache.org/viewvc/aries/trunk/spi-fly/spi-fly-dynamic-bundle/src/test/java/org/apache/aries/spifly/dynamic/ClientWeavingHookGenericCapabilityTest.java?rev=1717300&r1=1717299&r2=1717300&view=diff
==============================================================================
--- aries/trunk/spi-fly/spi-fly-dynamic-bundle/src/test/java/org/apache/aries/spifly/dynamic/ClientWeavingHookGenericCapabilityTest.java (original)
+++ aries/trunk/spi-fly/spi-fly-dynamic-bundle/src/test/java/org/apache/aries/spifly/dynamic/ClientWeavingHookGenericCapabilityTest.java Mon Nov 30 17:35:35 2015
@@ -57,6 +57,7 @@ import org.osgi.framework.BundleReferenc
 import org.osgi.framework.Version;
 import org.osgi.framework.hooks.weaving.WeavingHook;
 import org.osgi.framework.hooks.weaving.WovenClass;
+import org.osgi.framework.wiring.BundleRevision;
 import org.osgi.framework.wiring.BundleWiring;
 
 public class ClientWeavingHookGenericCapabilityTest {
@@ -664,6 +665,7 @@ public class ClientWeavingHookGenericCap
         EasyMock.expect(consumerBundle.getHeaders()).andReturn(headers).anyTimes();
         EasyMock.expect(consumerBundle.getBundleContext()).andReturn(bc).anyTimes();
         EasyMock.expect(consumerBundle.getBundleId()).andReturn(Long.MAX_VALUE).anyTimes();
+        EasyMock.expect(consumerBundle.adapt(BundleRevision.class)).andReturn(null).anyTimes();
         EasyMock.replay(consumerBundle);
 
         List<Bundle> allBundles = new ArrayList<Bundle>(Arrays.asList(otherBundles));

Modified: aries/trunk/spi-fly/spi-fly-dynamic-bundle/src/test/java/org/apache/aries/spifly/dynamic/ClientWeavingHookOSGi43Test.java
URL: http://svn.apache.org/viewvc/aries/trunk/spi-fly/spi-fly-dynamic-bundle/src/test/java/org/apache/aries/spifly/dynamic/ClientWeavingHookOSGi43Test.java?rev=1717300&r1=1717299&r2=1717300&view=diff
==============================================================================
--- aries/trunk/spi-fly/spi-fly-dynamic-bundle/src/test/java/org/apache/aries/spifly/dynamic/ClientWeavingHookOSGi43Test.java (original)
+++ aries/trunk/spi-fly/spi-fly-dynamic-bundle/src/test/java/org/apache/aries/spifly/dynamic/ClientWeavingHookOSGi43Test.java Mon Nov 30 17:35:35 2015
@@ -243,6 +243,7 @@ public class ClientWeavingHookOSGi43Test
         EasyMock.expect(consumerBundle.getHeaders()).andReturn(headers).anyTimes();
         EasyMock.expect(consumerBundle.getBundleContext()).andReturn(bc).anyTimes();
         EasyMock.expect(consumerBundle.getBundleId()).andReturn(Long.MAX_VALUE).anyTimes();
+        EasyMock.expect(consumerBundle.adapt(BundleRevision.class)).andReturn(null).anyTimes();
         EasyMock.replay(consumerBundle);
 
         List<Bundle> allBundles = new ArrayList<Bundle>(Arrays.asList(otherBundles));

Modified: aries/trunk/spi-fly/spi-fly-dynamic-bundle/src/test/java/org/apache/aries/spifly/dynamic/ClientWeavingHookTest.java
URL: http://svn.apache.org/viewvc/aries/trunk/spi-fly/spi-fly-dynamic-bundle/src/test/java/org/apache/aries/spifly/dynamic/ClientWeavingHookTest.java?rev=1717300&r1=1717299&r2=1717300&view=diff
==============================================================================
--- aries/trunk/spi-fly/spi-fly-dynamic-bundle/src/test/java/org/apache/aries/spifly/dynamic/ClientWeavingHookTest.java (original)
+++ aries/trunk/spi-fly/spi-fly-dynamic-bundle/src/test/java/org/apache/aries/spifly/dynamic/ClientWeavingHookTest.java Mon Nov 30 17:35:35 2015
@@ -58,6 +58,7 @@ import org.osgi.framework.BundleReferenc
 import org.osgi.framework.Version;
 import org.osgi.framework.hooks.weaving.WeavingHook;
 import org.osgi.framework.hooks.weaving.WovenClass;
+import org.osgi.framework.wiring.BundleRevision;
 import org.osgi.framework.wiring.BundleWiring;
 
 public class ClientWeavingHookTest {
@@ -683,6 +684,7 @@ public class ClientWeavingHookTest {
         EasyMock.expect(consumerBundle.getHeaders()).andReturn(headers).anyTimes();
         EasyMock.expect(consumerBundle.getBundleContext()).andReturn(bc).anyTimes();
         EasyMock.expect(consumerBundle.getBundleId()).andReturn(Long.MAX_VALUE).anyTimes();
+        EasyMock.expect(consumerBundle.adapt(BundleRevision.class)).andReturn(null).anyTimes();
         EasyMock.replay(consumerBundle);
 
         List<Bundle> allBundles = new ArrayList<Bundle>(Arrays.asList(otherBundles));