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 2010/01/19 14:24:01 UTC

svn commit: r900769 - in /incubator/aries/trunk/spi-fly/src: main/java/org/apache/aries/spifly/SPIBundleTracker.java test/java/org/apache/aries/spifly/SPIBundleTrackerTest.java test/resources/org/apache/aries/spifly/TestSPIBundle2_1.0.0.jar

Author: davidb
Date: Tue Jan 19 13:24:01 2010
New Revision: 900769

URL: http://svn.apache.org/viewvc?rev=900769&view=rev
Log:
Require an opt-in Manifest header in order for bundles to be considered as SPI providers.
The header is:
  SPI-Provider: <value not used at the moment>

Unit tests included.

Added:
    incubator/aries/trunk/spi-fly/src/test/resources/org/apache/aries/spifly/TestSPIBundle2_1.0.0.jar   (with props)
Modified:
    incubator/aries/trunk/spi-fly/src/main/java/org/apache/aries/spifly/SPIBundleTracker.java
    incubator/aries/trunk/spi-fly/src/test/java/org/apache/aries/spifly/SPIBundleTrackerTest.java

Modified: incubator/aries/trunk/spi-fly/src/main/java/org/apache/aries/spifly/SPIBundleTracker.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/spi-fly/src/main/java/org/apache/aries/spifly/SPIBundleTracker.java?rev=900769&r1=900768&r2=900769&view=diff
==============================================================================
--- incubator/aries/trunk/spi-fly/src/main/java/org/apache/aries/spifly/SPIBundleTracker.java (original)
+++ incubator/aries/trunk/spi-fly/src/main/java/org/apache/aries/spifly/SPIBundleTracker.java Tue Jan 19 13:24:01 2010
@@ -36,6 +36,7 @@
 
 public class SPIBundleTracker extends BundleTracker {
     public static final String SPI_PROVIDER_URL = "spi.provider.url";
+    public static final String OPT_IN_HEADER = "SPI-Provider";
     
     final Activator activator;
     List<ServiceRegistration> registrations = new ArrayList<ServiceRegistration>();
@@ -53,6 +54,13 @@
             return rv;
         }
         
+        if (bundle.getHeaders().get(OPT_IN_HEADER) == null) {
+            log(LogService.LOG_INFO, "Skipping bundle for SPI provider consideration: " + bundle.getSymbolicName());
+            return rv;
+        } else {
+            log(LogService.LOG_INFO, "Considering bundle for SPI provider: " + bundle.getSymbolicName());
+        }
+        
         Enumeration<?> entries = bundle.findEntries("META-INF/services", "*", false);
         if (entries == null) {
             return rv;

Modified: incubator/aries/trunk/spi-fly/src/test/java/org/apache/aries/spifly/SPIBundleTrackerTest.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/spi-fly/src/test/java/org/apache/aries/spifly/SPIBundleTrackerTest.java?rev=900769&r1=900768&r2=900769&view=diff
==============================================================================
--- incubator/aries/trunk/spi-fly/src/test/java/org/apache/aries/spifly/SPIBundleTrackerTest.java (original)
+++ incubator/aries/trunk/spi-fly/src/test/java/org/apache/aries/spifly/SPIBundleTrackerTest.java Tue Jan 19 13:24:01 2010
@@ -18,10 +18,16 @@
  */
 package org.apache.aries.spifly;
 
+import java.io.IOException;
 import java.net.URL;
 import java.net.URLClassLoader;
 import java.util.Collections;
 import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.jar.Attributes;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
 
 import junit.framework.TestCase;
 
@@ -58,14 +64,16 @@
         
         SPIBundleTracker sbt = new SPIBundleTracker(bc, new Activator());
 
-        URL jarURL = getClass().getResource("TestSPIBundle_1.0.0.jar");
+        URL jarURL = getClass().getResource("TestSPIBundle2_1.0.0.jar");
+        Dictionary<String, Object> headers = getManifestHeaders(jarURL);               
         URL url = new URL("jar:" + jarURL + "!/META-INF/services/javax.xml.parsers.DocumentBuilderFactory");
         final ClassLoader mockBundleLoader = new URLClassLoader(new URL[] {jarURL});  
         
         Bundle b = EasyMock.createMock(Bundle.class);
-        EasyMock.expect(b.getSymbolicName()).andReturn("x.y.z");
+        EasyMock.expect(b.getSymbolicName()).andReturn("x.y.z").anyTimes();
         EasyMock.expect(b.findEntries("META-INF/services", "*", false))
             .andReturn(Collections.enumeration(Collections.singleton(url)));
+        EasyMock.expect(b.getHeaders()).andReturn(headers).anyTimes();
         EasyMock.expect(b.loadClass((String) EasyMock.anyObject())).andAnswer(new IAnswer<Class<?>>() {
             public Class<?> answer() throws Throwable {
                 return mockBundleLoader.loadClass((String) EasyMock.getCurrentArguments()[0]);
@@ -77,7 +85,7 @@
             EasyMock.anyObject(), (Dictionary) EasyMock.anyObject())).andAnswer(new IAnswer<ServiceRegistration>() {
                 public ServiceRegistration answer() throws Throwable {
                     Object impl = EasyMock.getCurrentArguments()[1];
-                    assertEquals("org.example.test.TestDomBuilderFactory", impl.getClass().getName());
+                    assertEquals("org.example.test.Test2DomBuilderFactory", impl.getClass().getName());
                     assertNotNull(((Dictionary) EasyMock.getCurrentArguments()[2]).get(SPIBundleTracker.SPI_PROVIDER_URL)); 
                     return EasyMock.createMock(ServiceRegistration.class);
                 }
@@ -93,16 +101,58 @@
         
         EasyMock.verify(bc2);
     }
-    
-    public void testAddingUnrelatedBundle() {
+
+    @SuppressWarnings("unchecked")
+    public void testAddingNonMarkedBundle() throws Exception {
         BundleContext bc = EasyMock.createMock(BundleContext.class);
         EasyMock.expect(bc.getBundle()).andReturn(EasyMock.createMock(Bundle.class));
         EasyMock.replay(bc);
         
         SPIBundleTracker sbt = new SPIBundleTracker(bc, new Activator());
+
+        URL jarURL = getClass().getResource("TestSPIBundle_1.0.0.jar");
+        Dictionary<String, Object> headers = getManifestHeaders(jarURL);               
+        URL url = new URL("jar:" + jarURL + "!/META-INF/services/javax.xml.parsers.DocumentBuilderFactory");
+        final ClassLoader mockBundleLoader = new URLClassLoader(new URL[] {jarURL});  
         
         Bundle b = EasyMock.createMock(Bundle.class);
-        EasyMock.expect(b.getSymbolicName()).andReturn("x.y.z");
+        EasyMock.expect(b.getSymbolicName()).andReturn("x.y.z").anyTimes();
+        EasyMock.expect(b.findEntries("META-INF/services", "*", false))
+            .andReturn(Collections.enumeration(Collections.singleton(url)));
+        EasyMock.expect(b.getHeaders()).andReturn(headers).anyTimes();
+        EasyMock.expect(b.loadClass((String) EasyMock.anyObject())).andAnswer(new IAnswer<Class<?>>() {
+            public Class<?> answer() throws Throwable {
+                return mockBundleLoader.loadClass((String) EasyMock.getCurrentArguments()[0]);
+            }
+        });
+
+        BundleContext bc2 = EasyMock.createMock(BundleContext.class);
+        // no services are expected to be registered.
+        EasyMock.replay(bc2);
+
+        EasyMock.expect(b.getBundleContext()).andReturn(bc2);
+        EasyMock.replay(b);
+        
+        assertEquals("Precondition failed", 0, sbt.registrations.size());
+        sbt.addingBundle(b, null);
+        assertEquals(0, sbt.registrations.size());
+        
+        EasyMock.verify(bc2); // verify that bc2.registerService() was never called
+    }
+
+    public void testAddingUnrelatedButMarkedBundle() {
+        BundleContext bc = EasyMock.createMock(BundleContext.class);
+        EasyMock.expect(bc.getBundle()).andReturn(EasyMock.createMock(Bundle.class));
+        EasyMock.replay(bc);
+        
+        SPIBundleTracker sbt = new SPIBundleTracker(bc, new Activator());
+        
+        Dictionary<String, Object> headers = new Hashtable<String, Object>();
+        headers.put(SPIBundleTracker.OPT_IN_HEADER, "somevalue");
+
+        Bundle b = EasyMock.createMock(Bundle.class);
+        EasyMock.expect(b.getSymbolicName()).andReturn("x.y.z").anyTimes();
+        EasyMock.expect(b.getHeaders()).andReturn(headers).anyTimes();
         EasyMock.expect(b.findEntries("META-INF/services", "*", false)).andReturn(null);
         EasyMock.replay(b);
 
@@ -181,4 +231,18 @@
         
         EasyMock.verify(bc);
     }
+    
+    private Dictionary<String, Object> getManifestHeaders(URL jarURL) throws IOException {
+        JarFile jf = new JarFile(jarURL.getFile());
+        try {
+            Attributes attrs = jf.getManifest().getMainAttributes();
+            Hashtable<String, Object> headers = new Hashtable<String, Object>(); 
+            for (Map.Entry<Object, Object> entry : attrs.entrySet()) {
+                headers.put(entry.getKey().toString(), entry.getValue());
+            }
+            return headers;
+        } finally {
+            jf.close();
+        }
+    }    
 }

Added: incubator/aries/trunk/spi-fly/src/test/resources/org/apache/aries/spifly/TestSPIBundle2_1.0.0.jar
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/spi-fly/src/test/resources/org/apache/aries/spifly/TestSPIBundle2_1.0.0.jar?rev=900769&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/aries/trunk/spi-fly/src/test/resources/org/apache/aries/spifly/TestSPIBundle2_1.0.0.jar
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream