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/12/20 13:54:55 UTC

svn commit: r1051088 - in /incubator/aries/trunk/spi-fly/contrib/pilot_using_weavinghook: SpiFly/src/org/apache/aries/spifly/ClientWeavingHook.java SpiFlyTests/src/org/apache/aries/spifly/ClientWeavingHookTest.java

Author: davidb
Date: Mon Dec 20 12:54:54 2010
New Revision: 1051088

URL: http://svn.apache.org/viewvc?rev=1051088&view=rev
Log:
Added support for selecting the JRE (through the system bundle) for selecting an SPI implementation.

Modified:
    incubator/aries/trunk/spi-fly/contrib/pilot_using_weavinghook/SpiFly/src/org/apache/aries/spifly/ClientWeavingHook.java
    incubator/aries/trunk/spi-fly/contrib/pilot_using_weavinghook/SpiFlyTests/src/org/apache/aries/spifly/ClientWeavingHookTest.java

Modified: incubator/aries/trunk/spi-fly/contrib/pilot_using_weavinghook/SpiFly/src/org/apache/aries/spifly/ClientWeavingHook.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/spi-fly/contrib/pilot_using_weavinghook/SpiFly/src/org/apache/aries/spifly/ClientWeavingHook.java?rev=1051088&r1=1051087&r2=1051088&view=diff
==============================================================================
--- incubator/aries/trunk/spi-fly/contrib/pilot_using_weavinghook/SpiFly/src/org/apache/aries/spifly/ClientWeavingHook.java (original)
+++ incubator/aries/trunk/spi-fly/contrib/pilot_using_weavinghook/SpiFly/src/org/apache/aries/spifly/ClientWeavingHook.java Mon Dec 20 12:54:54 2010
@@ -34,12 +34,9 @@ import org.osgi.framework.hooks.weaving.
 import org.osgi.service.log.LogService;
 
 public class ClientWeavingHook implements WeavingHook {
-    private final BundleContext bundleContext;
     private final String addedImport;
     
     ClientWeavingHook(BundleContext context) {
-        bundleContext = context;
-        
         Bundle b = context.getBundle();
         String bver = b.getVersion().toString();
         String bsn = b.getSymbolicName();
@@ -95,7 +92,7 @@ public class ClientWeavingHook implement
                 
             String bsn = element.getAttribute("bundle");
             if (bsn != null) {
-                for (Bundle b : bundleContext.getBundles()) {
+                for (Bundle b : consumerBundle.getBundleContext().getBundles()) {
                     if (b.getSymbolicName().equals(bsn)) {
                         selectedBundles.add(b);
                         break;                        
@@ -103,6 +100,17 @@ public class ClientWeavingHook implement
                 }
             }
             
+            String bid = element.getAttribute("bundleId");
+            if (bid != null) {
+                bid = bid.trim();
+                for (Bundle b : consumerBundle.getBundleContext().getBundles()) {
+                    if (("" + b.getBundleId()).equals(bid)) {
+                        selectedBundles.add(b);
+                        break;                        
+                    }
+                }                
+            }
+            
             Activator.activator.log(LogService.LOG_INFO, "Weaving " + className + "#" + methodName + " from bundle " + 
                 consumerBundle.getSymbolicName() + " to " + (selectedBundles.size() == 0 ? " any provider" : selectedBundles));
             

Modified: incubator/aries/trunk/spi-fly/contrib/pilot_using_weavinghook/SpiFlyTests/src/org/apache/aries/spifly/ClientWeavingHookTest.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/spi-fly/contrib/pilot_using_weavinghook/SpiFlyTests/src/org/apache/aries/spifly/ClientWeavingHookTest.java?rev=1051088&r1=1051087&r2=1051088&view=diff
==============================================================================
--- incubator/aries/trunk/spi-fly/contrib/pilot_using_weavinghook/SpiFlyTests/src/org/apache/aries/spifly/ClientWeavingHookTest.java (original)
+++ incubator/aries/trunk/spi-fly/contrib/pilot_using_weavinghook/SpiFlyTests/src/org/apache/aries/spifly/ClientWeavingHookTest.java Mon Dec 20 12:54:54 2010
@@ -33,13 +33,13 @@ public class ClientWeavingHookTest {
         
     @Test
     public void testClientWeavingHookBasicServiveLoaderUsage() throws Exception {
-        BundleContext spiFlyBundleContext = mockSpiFlyBundle("spifly", Version.parseVersion("1.9.4"));               
+        Bundle spiFlyBundle = mockSpiFlyBundle("spifly", Version.parseVersion("1.9.4"));               
        
         Dictionary<String, String> headers = new Hashtable<String, String>();
         headers.put(SpiFlyConstants.SPI_CONSUMER_HEADER, "true");
-        Bundle consumerBundle = mockConsumerBundle(headers);
+        Bundle consumerBundle = mockConsumerBundle(headers, spiFlyBundle);
 
-        WeavingHook wh = new ClientWeavingHook(spiFlyBundleContext);
+        WeavingHook wh = new ClientWeavingHook(spiFlyBundle.getBundleContext());
         
         // Weave the TestClient class.
         URL clsUrl = getClass().getResource("TestClient.class");
@@ -67,11 +67,13 @@ public class ClientWeavingHookTest {
 
     @Test
     public void testClientWeavingHookMultipleProviders() throws Exception {
+        Bundle spiFlyBundle = mockSpiFlyBundle();
+
         Dictionary<String, String> headers = new Hashtable<String, String>();
         headers.put(SpiFlyConstants.SPI_CONSUMER_HEADER, "true");
-        Bundle consumerBundle = mockConsumerBundle(headers);
+        Bundle consumerBundle = mockConsumerBundle(headers, spiFlyBundle);
 
-        WeavingHook wh = new ClientWeavingHook(mockSpiFlyBundle());
+        WeavingHook wh = new ClientWeavingHook(spiFlyBundle.getBundleContext());
 
         // Weave the TestClient class.
         URL clsUrl = getClass().getResource("TestClient.class");
@@ -97,14 +99,15 @@ public class ClientWeavingHookTest {
     public void testClientSpecifyingProvider() throws Exception {
         Dictionary<String, String> headers = new Hashtable<String, String>();
         headers.put(SpiFlyConstants.SPI_CONSUMER_HEADER, "java.util.ServiceLoader#load(java.lang.Class);bundle=impl2");
-        Bundle consumerBundle = mockConsumerBundle(headers);
 
         Bundle providerBundle1 = mockProviderBundle("impl1", 1, "META-INF/services/org.apache.aries.mytest.MySPI");
         Bundle providerBundle2 = mockProviderBundle("impl2", 2, "META-INF/services/org.apache.aries.mytest.MySPI");
         Activator.activator.registerProviderBundle("org.apache.aries.mytest.MySPI", providerBundle1);
         Activator.activator.registerProviderBundle("org.apache.aries.mytest.MySPI", providerBundle2);
 
-        WeavingHook wh = new ClientWeavingHook(mockSpiFlyBundle(consumerBundle, providerBundle1, providerBundle2));
+        Bundle consumerBundle = mockConsumerBundle(headers, providerBundle1, providerBundle2);
+        Bundle spiFlyBundle = mockSpiFlyBundle(consumerBundle, providerBundle1, providerBundle2);        
+        WeavingHook wh = new ClientWeavingHook(spiFlyBundle.getBundleContext());
 
         // Weave the TestClient class.
         URL clsUrl = getClass().getResource("TestClient.class");
@@ -125,12 +128,14 @@ public class ClientWeavingHookTest {
     }
     
     @Test
-    public void testJAXPClientWantsJREImplementation() throws Exception {
+    public void testJAXPClientWantsJREImplementation1() throws Exception {
+        Bundle systembundle = mockSystemBundle();
+
         Dictionary<String, String> headers = new Hashtable<String, String>();
-        headers.put(SpiFlyConstants.SPI_CONSUMER_HEADER, "todo");
-        Bundle consumerBundle = mockConsumerBundle(headers);
+        headers.put(SpiFlyConstants.SPI_CONSUMER_HEADER, "javax.xml.parsers.DocumentBuilderFactory#newInstance()");
+        Bundle consumerBundle = mockConsumerBundle(headers, systembundle);
 
-        WeavingHook wh = new ClientWeavingHook(mockSpiFlyBundle(consumerBundle));
+        WeavingHook wh = new ClientWeavingHook(mockSpiFlyBundle(consumerBundle, systembundle).getBundleContext());
 
         URL clsUrl = getClass().getResource("JaxpClient.class");
         WovenClass wc = new MyWovenClass(clsUrl, "org.apache.aries.spifly.JaxpClient", consumerBundle);
@@ -142,16 +147,65 @@ public class ClientWeavingHookTest {
         Assert.assertEquals("JAXP implementation from JRE", "com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl", result.getName());                
     }
     
+    // If there is an alternate implementation it should always be favoured over the JRE one
     @Test
-    public void testJAXPClientWantsAltImplementation() throws Exception {
+    public void testJAXPClientWantsAltImplementation1() throws Exception {
+        Bundle systembundle = mockSystemBundle();
+
+        Bundle providerBundle = mockProviderBundle("impl3", 1, "META-INF/services/javax.xml.parsers.DocumentBuilderFactory");
+        Activator.activator.registerProviderBundle("javax.xml.parsers.DocumentBuilderFactory", providerBundle);
+
         Dictionary<String, String> headers = new Hashtable<String, String>();
-        headers.put(SpiFlyConstants.SPI_CONSUMER_HEADER, "javax.xml.parsers.DocumentBuilderFactory#newInstance();bundle=impl3");
-        Bundle consumerBundle = mockConsumerBundle(headers);
+        headers.put(SpiFlyConstants.SPI_CONSUMER_HEADER, "javax.xml.parsers.DocumentBuilderFactory#newInstance()");
+        Bundle consumerBundle = mockConsumerBundle(headers, providerBundle, systembundle);
+
+        WeavingHook wh = new ClientWeavingHook(mockSpiFlyBundle(consumerBundle, providerBundle, systembundle).getBundleContext());
+
+        URL clsUrl = getClass().getResource("JaxpClient.class");
+        WovenClass wc = new MyWovenClass(clsUrl, "org.apache.aries.spifly.JaxpClient", consumerBundle);
+        wh.weave(wc);
+        
+        Class<?> cls = wc.getDefinedClass();
+        Method method = cls.getMethod("test", new Class [] {});
+        Class<?> result = (Class<?>) method.invoke(cls.newInstance());
+        Assert.assertEquals("JAXP implementation from JRE", "org.apache.aries.spifly.impl3.MyAltDocumentBuilderFactory", result.getName());                
+    }
+
+    @Test
+    public void testJAXPClientWantsJREImplementation2() throws Exception {
+        Bundle systembundle = mockSystemBundle();
         
         Bundle providerBundle = mockProviderBundle("impl3", 1, "META-INF/services/javax.xml.parsers.DocumentBuilderFactory");
         Activator.activator.registerProviderBundle("javax.xml.parsers.DocumentBuilderFactory", providerBundle);
 
-        WeavingHook wh = new ClientWeavingHook(mockSpiFlyBundle(consumerBundle));
+        Dictionary<String, String> headers = new Hashtable<String, String>();
+        headers.put(SpiFlyConstants.SPI_CONSUMER_HEADER, "javax.xml.parsers.DocumentBuilderFactory#newInstance();bundleId=0");
+        Bundle consumerBundle = mockConsumerBundle(headers, providerBundle, systembundle);
+
+        WeavingHook wh = new ClientWeavingHook(mockSpiFlyBundle(consumerBundle, providerBundle, systembundle).getBundleContext());
+
+        URL clsUrl = getClass().getResource("JaxpClient.class");
+        WovenClass wc = new MyWovenClass(clsUrl, "org.apache.aries.spifly.JaxpClient", consumerBundle);
+        wh.weave(wc);
+        
+        Class<?> cls = wc.getDefinedClass();
+        Method method = cls.getMethod("test", new Class [] {});
+        Class<?> result = (Class<?>) method.invoke(cls.newInstance());
+        Assert.assertEquals("JAXP implementation from JRE", "com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl", result.getName());                
+    }
+
+    @Test
+    public void testJAXPClientWantsAltImplementation2() throws Exception {
+        Bundle systembundle = mockSystemBundle();
+
+        Bundle providerBundle = mockProviderBundle("impl3", 1, "META-INF/services/javax.xml.parsers.DocumentBuilderFactory");
+        Activator.activator.registerProviderBundle("javax.xml.parsers.DocumentBuilderFactory", providerBundle);
+
+        Dictionary<String, String> headers = new Hashtable<String, String>();
+        headers.put(SpiFlyConstants.SPI_CONSUMER_HEADER, "javax.xml.parsers.DocumentBuilderFactory#newInstance();bundle=impl3");
+        Bundle consumerBundle = mockConsumerBundle(headers, providerBundle, systembundle);
+        
+        WeavingHook wh = new ClientWeavingHook(mockSpiFlyBundle(consumerBundle, providerBundle, systembundle).getBundleContext());
 
         URL clsUrl = getClass().getResource("JaxpClient.class");
         WovenClass wc = new MyWovenClass(clsUrl, "org.apache.aries.spifly.JaxpClient", consumerBundle);
@@ -163,15 +217,12 @@ public class ClientWeavingHookTest {
         Assert.assertEquals("JAXP implementation from alternative bundle", "org.apache.aries.spifly.impl3.MyAltDocumentBuilderFactory", result.getName());                        
     }
     
-    private BundleContext mockSpiFlyBundle(Bundle ... bundles) {
+    private Bundle mockSpiFlyBundle(Bundle ... bundles) {
         return mockSpiFlyBundle("spifly", new Version(1, 0, 0), bundles);
     }
     
-    private BundleContext mockSpiFlyBundle(String bsn, Version version, Bundle ... bundles) {
+    private Bundle mockSpiFlyBundle(String bsn, Version version, Bundle ... bundles) {
         Bundle spiFlyBundle = EasyMock.createMock(Bundle.class);
-        EasyMock.expect(spiFlyBundle.getSymbolicName()).andReturn(bsn).anyTimes();
-        EasyMock.expect(spiFlyBundle.getVersion()).andReturn(version);
-        EasyMock.replay(spiFlyBundle);
 
         BundleContext spiFlyBundleContext = EasyMock.createMock(BundleContext.class);
         EasyMock.expect(spiFlyBundleContext.getBundle()).andReturn(spiFlyBundle);
@@ -179,7 +230,13 @@ public class ClientWeavingHookTest {
         allBundles.add(spiFlyBundle);
         EasyMock.expect(spiFlyBundleContext.getBundles()).andReturn(allBundles.toArray(new Bundle [] {}));
         EasyMock.replay(spiFlyBundleContext);
-        return spiFlyBundleContext;
+
+        EasyMock.expect(spiFlyBundle.getSymbolicName()).andReturn(bsn).anyTimes();
+        EasyMock.expect(spiFlyBundle.getVersion()).andReturn(version);
+        EasyMock.expect(spiFlyBundle.getBundleContext()).andReturn(spiFlyBundleContext).anyTimes();
+        EasyMock.replay(spiFlyBundle);
+
+        return spiFlyBundle;
     }
 
     private Bundle mockProviderBundle(String subdir, long id, String ... resources) {
@@ -195,20 +252,38 @@ public class ClientWeavingHookTest {
         Bundle providerBundle = EasyMock.createMock(Bundle.class);
         EasyMock.expect(providerBundle.adapt(BundleWiring.class)).andReturn(bw);
         EasyMock.expect(providerBundle.getSymbolicName()).andReturn(subdir).anyTimes();
-        EasyMock.expect(providerBundle.getBundleId()).andReturn(id);
+        EasyMock.expect(providerBundle.getBundleId()).andReturn(id).anyTimes();
         EasyMock.replay(providerBundle);
         return providerBundle;
     }
 
-    private Bundle mockConsumerBundle(Dictionary<String, String> headers) {
-        // Create a mock object for the client bundle which holds the code that uses ServiceLoader.load().
+    private Bundle mockConsumerBundle(Dictionary<String, String> headers, Bundle ... otherBundles) {
+        // Create a mock object for the client bundle which holds the code that uses ServiceLoader.load() 
+        // or another SPI invocation.
+        BundleContext bc = EasyMock.createMock(BundleContext.class);
+        
         Bundle consumerBundle = EasyMock.createMock(Bundle.class);
         EasyMock.expect(consumerBundle.getSymbolicName()).andReturn("testConsumer").anyTimes();
         EasyMock.expect(consumerBundle.getHeaders()).andReturn(headers);
+        EasyMock.expect(consumerBundle.getBundleContext()).andReturn(bc);
+        EasyMock.expect(consumerBundle.getBundleId()).andReturn(Long.MAX_VALUE).anyTimes();
         EasyMock.replay(consumerBundle);        
-        
+
+        List<Bundle> allBundles = new ArrayList<Bundle>(Arrays.asList(otherBundles));
+        allBundles.add(consumerBundle);
+        EasyMock.expect(bc.getBundles()).andReturn(allBundles.toArray(new Bundle [] {}));
+        EasyMock.replay(bc);
+
         return consumerBundle;
     }
+    
+    private Bundle mockSystemBundle() {
+        Bundle systemBundle = EasyMock.createMock(Bundle.class);
+        EasyMock.expect(systemBundle.getBundleId()).andReturn(0L).anyTimes();
+        EasyMock.replay(systemBundle);
+        
+        return systemBundle;
+    }
             
     private class TestImplClassLoader extends URLClassLoader {
         private final List<String> resources;