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 2012/06/18 16:32:28 UTC

svn commit: r1351360 - in /aries/trunk/spi-fly/spi-fly-core/src: main/java/org/apache/aries/spifly/ main/java/org/apache/aries/spifly/api/ test/java/org/apache/aries/spifly/

Author: davidb
Date: Mon Jun 18 14:32:27 2012
New Revision: 1351360

URL: http://svn.apache.org/viewvc?rev=1351360&view=rev
Log:
[SPI-Fly] Convert Providers to use OSGi Service Factories instead of plain services. 
This fixes a TCK failure.

Added:
    aries/trunk/spi-fly/spi-fly-core/src/main/java/org/apache/aries/spifly/ProviderServiceFactory.java   (with props)
Modified:
    aries/trunk/spi-fly/spi-fly-core/src/main/java/org/apache/aries/spifly/ProviderBundleTrackerCustomizer.java
    aries/trunk/spi-fly/spi-fly-core/src/main/java/org/apache/aries/spifly/api/SpiFlyConstants.java
    aries/trunk/spi-fly/spi-fly-core/src/test/java/org/apache/aries/spifly/ProviderBundleTrackerCustomizerGenericCapabilityTest.java
    aries/trunk/spi-fly/spi-fly-core/src/test/java/org/apache/aries/spifly/ProviderBundleTrackerCustomizerTest.java

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=1351360&r1=1351359&r2=1351360&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 Jun 18 14:32:27 2012
@@ -142,6 +142,11 @@ public class ProviderBundleTrackerCustom
                 String className = null;
                 while((className = reader.readLine()) != null) {
                     try {
+                        className = className.trim();
+
+                        if (className.length() == 0)
+                            continue; // empty line
+
                         if (className.startsWith("#"))
                             continue; // a comment
 
@@ -155,8 +160,7 @@ public class ProviderBundleTrackerCustom
                             continue;
 
                         Class<?> cls = bundle.loadClass(className);
-                        Object o = cls.newInstance();
-                        log(LogService.LOG_INFO, "Instantiated SPI provider: " + o);
+                        log(LogService.LOG_INFO, "Loaded SPI provider: " + cls);
 
                         Hashtable<String, Object> properties;
                         if (fromSPIProviderHeader)
@@ -166,8 +170,9 @@ public class ProviderBundleTrackerCustom
 
                         if (properties != null) {
                             properties.put(SpiFlyConstants.SERVICELOADER_MEDIATOR_PROPERTY, spiBundle.getBundleId());
-                            ServiceRegistration reg = bundle.getBundleContext()
-                                    .registerService(registrationClassName, o, properties);
+                            properties.put(SpiFlyConstants.PROVIDER_IMPLCLASS_PROPERTY, cls.getName());
+                            ServiceRegistration reg = bundle.getBundleContext().registerService(
+                                registrationClassName, new ProviderServiceFactory(cls), properties);
                             registrations.add(reg);
                             log(LogService.LOG_INFO, "Registered service: " + reg);
                         }

Added: aries/trunk/spi-fly/spi-fly-core/src/main/java/org/apache/aries/spifly/ProviderServiceFactory.java
URL: http://svn.apache.org/viewvc/aries/trunk/spi-fly/spi-fly-core/src/main/java/org/apache/aries/spifly/ProviderServiceFactory.java?rev=1351360&view=auto
==============================================================================
--- aries/trunk/spi-fly/spi-fly-core/src/main/java/org/apache/aries/spifly/ProviderServiceFactory.java (added)
+++ aries/trunk/spi-fly/spi-fly-core/src/main/java/org/apache/aries/spifly/ProviderServiceFactory.java Mon Jun 18 14:32:27 2012
@@ -0,0 +1,46 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.aries.spifly;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.ServiceRegistration;
+
+public class ProviderServiceFactory implements ServiceFactory {
+    private final Class<?> providerClass;
+
+    public ProviderServiceFactory(Class<?> cls) {
+        providerClass = cls;
+    }
+
+    @Override
+    public Object getService(Bundle bundle, ServiceRegistration registration) {
+        try {
+            return providerClass.newInstance();
+        } catch (Exception e) {
+            throw new RuntimeException("Unable to instantiate class " + providerClass +
+                " Does it have a public no-arg constructor?", e);
+        }
+    }
+
+    @Override
+    public void ungetService(Bundle bundle, ServiceRegistration registration, Object service) {
+        // nothing to do
+    }
+}

Propchange: aries/trunk/spi-fly/spi-fly-core/src/main/java/org/apache/aries/spifly/ProviderServiceFactory.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: aries/trunk/spi-fly/spi-fly-core/src/main/java/org/apache/aries/spifly/api/SpiFlyConstants.java
URL: http://svn.apache.org/viewvc/aries/trunk/spi-fly/spi-fly-core/src/main/java/org/apache/aries/spifly/api/SpiFlyConstants.java?rev=1351360&r1=1351359&r2=1351360&view=diff
==============================================================================
--- aries/trunk/spi-fly/spi-fly-core/src/main/java/org/apache/aries/spifly/api/SpiFlyConstants.java (original)
+++ aries/trunk/spi-fly/spi-fly-core/src/main/java/org/apache/aries/spifly/api/SpiFlyConstants.java Mon Jun 18 14:32:27 2012
@@ -36,6 +36,7 @@ public interface SpiFlyConstants {
 
     // Service registration property
     String SERVICELOADER_MEDIATOR_PROPERTY = "serviceloader.mediator";
+    String PROVIDER_IMPLCLASS_PROPERTY = ".org.apache.aries.spifly.provider.implclass";
 
     // The names of the extenders involved
     String PROCESSOR_EXTENDER_NAME = "osgi.serviceloader.processor";

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=1351360&r1=1351359&r2=1351360&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 Jun 18 14:32:27 2012
@@ -36,11 +36,9 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import org.apache.aries.mytest.MySPI;
+import org.apache.aries.mytest.MySPI2;
 import org.apache.aries.spifly.api.SpiFlyConstants;
-import org.apache.aries.spifly.impl1.MySPIImpl1;
-import org.apache.aries.spifly.impl2.MySPIImpl2a;
-import org.apache.aries.spifly.impl2.MySPIImpl2b;
-import org.apache.aries.spifly.impl3.MySPIImpl3;
 import org.apache.aries.spifly.impl4.MySPIImpl4a;
 import org.apache.aries.spifly.impl4.MySPIImpl4b;
 import org.apache.aries.spifly.impl4.MySPIImpl4c;
@@ -50,6 +48,7 @@ import org.junit.Test;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceFactory;
 import org.osgi.framework.ServiceReference;
 import org.osgi.framework.ServiceRegistration;
 
@@ -190,7 +189,10 @@ public class ProviderBundleTrackerCustom
 
         List<ServiceRegistration> registrations = customizer.addingBundle(implBundle, null);
         assertEquals(1, registrations.size());
-        assertEquals("org.apache.aries.mytest.MySPI2", registrations.iterator().next().getReference().getProperty(Constants.OBJECTCLASS));
+
+        String[] objectClassProp = (String [])registrations.iterator().next().getReference().getProperty(Constants.OBJECTCLASS);
+        assertEquals(1, objectClassProp.length);
+        assertEquals("org.apache.aries.mytest.MySPI2", objectClassProp[0]);
         assertNotNull(registrations.iterator().next().getReference().getProperty(SpiFlyConstants.SERVICELOADER_MEDIATOR_PROPERTY));
         assertEquals("yeah", registrations.iterator().next().getReference().getProperty("approval"));
     }
@@ -226,12 +228,13 @@ public class ProviderBundleTrackerCustom
         boolean foundMySPI = false;
         boolean foundMySPI2 = false;
         for (ServiceRegistration sr : registrations) {
-            actualObjectClasses.add((String) sr.getReference().getProperty(Constants.OBJECTCLASS));
+            List<String> objectClasses = Arrays.asList((String[]) sr.getReference().getProperty(Constants.OBJECTCLASS));
+            actualObjectClasses.addAll(objectClasses);
             assertNotNull(sr.getReference().getProperty(SpiFlyConstants.SERVICELOADER_MEDIATOR_PROPERTY));
-            if ("org.apache.aries.mytest.MySPI".equals(sr.getReference().getProperty(Constants.OBJECTCLASS))) {
+            if (objectClasses.contains("org.apache.aries.mytest.MySPI")) {
                 assertEquals("yeah", sr.getReference().getProperty("approval"));
                 foundMySPI = true;
-            } else if ("org.apache.aries.mytest.MySPI2".equals(sr.getReference().getProperty(Constants.OBJECTCLASS))) {
+            } else if (objectClasses.contains("org.apache.aries.mytest.MySPI2")) {
                 assertNull(sr.getReference().getProperty("approval"));
                 foundMySPI2 = true;
             }
@@ -271,16 +274,28 @@ public class ProviderBundleTrackerCustom
         boolean foundA = false, foundB = false, foundC = false;
         for (ServiceRegistration sreg : registrations) {
             ServiceReference sref = sreg.getReference();
-            String objectClassName = sref.getProperty(Constants.OBJECTCLASS).toString();
-            String serviceImplClassName = sref.getProperty("serviceObject").getClass().getName();
+            String objectClassName = ((String [])sref.getProperty(Constants.OBJECTCLASS))[0];
+            String serviceImplClassName = (String) sref.getProperty(SpiFlyConstants.PROVIDER_IMPLCLASS_PROPERTY);
             if (MySPIImpl4a.class.getName().equals(serviceImplClassName)) {
                 assertEquals("org.apache.aries.mytest.MySPI", objectClassName);
+
+                MySPI svc = (MySPI) implBC.getService(sreg.getReference());
+                assertEquals("impl4a", svc.someMethod(""));
+
                 foundA = true;
             } else if (MySPIImpl4b.class.getName().equals(serviceImplClassName)) {
                 assertEquals("org.apache.aries.mytest.MySPI2", objectClassName);
+
+                MySPI2 svc = (MySPI2) implBC.getService(sreg.getReference());
+                assertEquals("impl4b", svc.someMethod(""));
+
                 foundB = true;
             } else if (MySPIImpl4c.class.getName().equals(serviceImplClassName)) {
                 assertEquals("org.apache.aries.mytest.MySPI2", objectClassName);
+
+                MySPI2 svc = (MySPI2) implBC.getService(sreg.getReference());
+                assertEquals("impl4c", svc.someMethod(""));
+
                 foundC = true;
             }
         }
@@ -331,16 +346,8 @@ public class ProviderBundleTrackerCustom
         BundleContext implBC = EasyMock.createMock(BundleContext.class);
         EasyMock.<Object>expect(implBC.registerService(
                 EasyMock.eq("org.apache.aries.mytest.MySPI"),
-                EasyMock.isA(MySPIImpl2a.class),
-                (Dictionary<String,?>) EasyMock.anyObject())).andReturn(EasyMock.createNiceMock(ServiceRegistration.class));
-        EasyMock.<Object>expect(implBC.registerService(
-                EasyMock.eq("org.apache.aries.mytest.MySPI"),
-                EasyMock.isA(MySPIImpl2b.class),
-                (Dictionary<String,?>) EasyMock.anyObject())).andReturn(EasyMock.createNiceMock(ServiceRegistration.class));
-        EasyMock.<Object>expect(implBC.registerService(
-                EasyMock.eq("org.apache.aries.mytest.MySPI"),
-                EasyMock.isA(MySPIImpl3.class),
-                (Dictionary<String,?>) EasyMock.anyObject())).andReturn(EasyMock.createNiceMock(ServiceRegistration.class));
+                EasyMock.isA(ServiceFactory.class),
+                (Dictionary<String,?>) EasyMock.anyObject())).andReturn(EasyMock.createNiceMock(ServiceRegistration.class)).times(3);
         EasyMock.replay(implBC);
 
 
@@ -393,7 +400,7 @@ public class ProviderBundleTrackerCustom
         BundleContext implBC = EasyMock.createMock(BundleContext.class);
         EasyMock.<Object>expect(implBC.registerService(
                 EasyMock.eq("org.apache.aries.mytest.MySPI"),
-                EasyMock.isA(MySPIImpl1.class),
+                EasyMock.isA(ServiceFactory.class),
                 (Dictionary<String,?>) EasyMock.anyObject())).andReturn(sreg);
         EasyMock.replay(implBC);
         return implBC;
@@ -431,37 +438,28 @@ public class ProviderBundleTrackerCustom
     private BundleContext mockSPIBundleContext4() {
         BundleContext implBC = EasyMock.createNiceMock(BundleContext.class);
 
-        EasyMock.expect(implBC.
-            registerService((String) EasyMock.anyObject(), EasyMock.anyObject(), (Dictionary<String,?>)EasyMock.anyObject())).
+        EasyMock.expect(implBC.registerService((String) EasyMock.anyObject(), EasyMock.anyObject(), (Dictionary<String,?>)EasyMock.anyObject())).
             andAnswer(new IAnswer<ServiceRegistration>() {
                 @Override
                 public ServiceRegistration answer() throws Throwable {
                     final String className = (String) EasyMock.getCurrentArguments()[0];
                     final Object serviceObject = EasyMock.getCurrentArguments()[1];
-                    final Dictionary<String,?> registrationProps =
-                            (Dictionary<String, ?>) EasyMock.getCurrentArguments()[2];
-
-                    ServiceReference sref = EasyMock.createMock(ServiceReference.class);
-                    EasyMock.expect(sref.getProperty(EasyMock.anyObject(String.class))).andAnswer(new IAnswer<Object>() {
-                        @Override
-                        public Object answer() throws Throwable {
-                            Object prop = EasyMock.getCurrentArguments()[0];
-                            if (Constants.OBJECTCLASS.equals(prop)) {
-                                return className;
-                            } else if ("serviceObject".equals(prop)) {
-                                // just used by the test to check the service object that was registered.
-                                return serviceObject;
-                            } else {
-                                return registrationProps.get(prop);
-                            }
-                        }
-                    }).anyTimes();
-                    EasyMock.replay(sref);
-
-                    ServiceRegistration sreg = EasyMock.createMock(ServiceRegistration.class);
-                    EasyMock.expect(sreg.getReference()).andReturn(sref).anyTimes();
-                    EasyMock.replay(sreg);
-                    return sreg;
+                    final Dictionary<String, Object> registrationProps =
+                        (Dictionary<String, Object>) EasyMock.getCurrentArguments()[2];
+                    return new ServiceRegistrationImpl(className, serviceObject, registrationProps);
+                }
+            }).anyTimes();
+        EasyMock.expect(implBC.getService(EasyMock.anyObject(ServiceReference.class))).
+            andAnswer(new IAnswer<Object>() {
+                @Override
+                public Object answer() throws Throwable {
+                    ServiceRegistrationImpl reg = (ServiceRegistrationImpl) EasyMock.getCurrentArguments()[0];
+                    Object svc = reg.getServiceObject();
+                    if (svc instanceof ServiceFactory) {
+                        return ((ServiceFactory) svc).getService(null, reg);
+                    } else {
+                        return svc;
+                    }
                 }
             }).anyTimes();
 
@@ -497,4 +495,63 @@ public class ProviderBundleTrackerCustom
         EasyMock.replay(implBundle);
         return implBundle;
     }
+
+    private static class ServiceRegistrationImpl implements ServiceRegistration, ServiceReference {
+        private final Object serviceObject;
+        private final Dictionary<String, Object> properties;
+
+        public ServiceRegistrationImpl(String className, Object serviceObject, Dictionary<String, Object> properties) {
+            this.serviceObject = serviceObject;
+            this.properties = properties;
+            this.properties.put(Constants.OBJECTCLASS, new String[] {className});
+        }
+
+        Object getServiceObject() {
+            return serviceObject;
+        }
+
+        @Override
+        public ServiceReference getReference() {
+            return this;
+        }
+
+        @Override
+        public void setProperties(@SuppressWarnings("rawtypes") Dictionary properties) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public void unregister() {
+        }
+
+        @Override
+        public Object getProperty(String key) {
+            return properties.get(key);
+        }
+
+        @Override
+        public String[] getPropertyKeys() {
+            return Collections.list(properties.keys()).toArray(new String [] {});
+        }
+
+        @Override
+        public Bundle getBundle() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public Bundle[] getUsingBundles() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public boolean isAssignableTo(Bundle bundle, String className) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public int compareTo(Object reference) {
+            throw new UnsupportedOperationException();
+        }
+    }
 }

Modified: aries/trunk/spi-fly/spi-fly-core/src/test/java/org/apache/aries/spifly/ProviderBundleTrackerCustomizerTest.java
URL: http://svn.apache.org/viewvc/aries/trunk/spi-fly/spi-fly-core/src/test/java/org/apache/aries/spifly/ProviderBundleTrackerCustomizerTest.java?rev=1351360&r1=1351359&r2=1351360&view=diff
==============================================================================
--- aries/trunk/spi-fly/spi-fly-core/src/test/java/org/apache/aries/spifly/ProviderBundleTrackerCustomizerTest.java (original)
+++ aries/trunk/spi-fly/spi-fly-core/src/test/java/org/apache/aries/spifly/ProviderBundleTrackerCustomizerTest.java Mon Jun 18 14:32:27 2012
@@ -32,15 +32,12 @@ import java.util.Hashtable;
 import java.util.List;
 
 import org.apache.aries.spifly.api.SpiFlyConstants;
-import org.apache.aries.spifly.impl1.MySPIImpl1;
-import org.apache.aries.spifly.impl2.MySPIImpl2a;
-import org.apache.aries.spifly.impl2.MySPIImpl2b;
-import org.apache.aries.spifly.impl3.MySPIImpl3;
 import org.easymock.EasyMock;
 import org.junit.Test;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceFactory;
 import org.osgi.framework.ServiceRegistration;
 
 public class ProviderBundleTrackerCustomizerTest {
@@ -114,16 +111,8 @@ public class ProviderBundleTrackerCustom
         BundleContext implBC = EasyMock.createMock(BundleContext.class);
         EasyMock.<Object>expect(implBC.registerService(
                 EasyMock.eq("org.apache.aries.mytest.MySPI"),
-                EasyMock.isA(MySPIImpl2a.class),
-                (Dictionary<String,?>) EasyMock.anyObject())).andReturn(EasyMock.createNiceMock(ServiceRegistration.class));
-        EasyMock.<Object>expect(implBC.registerService(
-                EasyMock.eq("org.apache.aries.mytest.MySPI"),
-                EasyMock.isA(MySPIImpl2b.class),
-                (Dictionary<String,?>) EasyMock.anyObject())).andReturn(EasyMock.createNiceMock(ServiceRegistration.class));
-        EasyMock.<Object>expect(implBC.registerService(
-                EasyMock.eq("org.apache.aries.mytest.MySPI"),
-                EasyMock.isA(MySPIImpl3.class),
-                (Dictionary<String,?>) EasyMock.anyObject())).andReturn(EasyMock.createNiceMock(ServiceRegistration.class));
+                EasyMock.isA(ServiceFactory.class),
+                (Dictionary<String,?>) EasyMock.anyObject())).andReturn(EasyMock.createNiceMock(ServiceRegistration.class)).times(3);
         EasyMock.replay(implBC);
 
 
@@ -173,7 +162,7 @@ public class ProviderBundleTrackerCustom
         BundleContext implBC = EasyMock.createMock(BundleContext.class);
         EasyMock.<Object>expect(implBC.registerService(
                 EasyMock.eq("org.apache.aries.mytest.MySPI"),
-                EasyMock.isA(MySPIImpl1.class),
+                EasyMock.isA(ServiceFactory.class),
                 (Dictionary<String,?>) EasyMock.anyObject())).andReturn(sreg);
         EasyMock.replay(implBC);
         return implBC;