Author: fmeschbe
Date: Tue Nov 13 23:40:56 2012
New Revision: 1409028

URL: http://svn.apache.org/viewvc?rev=1409028&view=rev
Log:
FELIX-3754 Internally register the component instance before calling the 
activate method to make sure (dynamic) services can be bound during activation. 
In case of activation failure, the instance has to be unregistered again. Plus 
test case.

Modified:
    
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java
    
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceFactoryComponentManager.java
    
felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/ComponentActivationTest.java
    
felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/components/ActivatorComponent.java
    
felix/trunk/scr/src/test/resources/integration_test_activation_components.xml

Modified: 
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java?rev=1409028&r1=1409027&r2=1409028&view=diff
==============================================================================
--- 
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java
 (original)
+++ 
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java
 Tue Nov 13 23:40:56 2012
@@ -123,6 +123,14 @@ public class ImmediateComponentManager e
                     m_componentContext = tmpContext;
                     m_implementationObject = implementationObject;
                 }
+
+
+                public void unsetImplementationObject( Object 
implementationObject )
+                {
+                    m_componentContext = null;
+                    m_implementationObject = null;
+                }
+
             } );
 
             // if something failed creating the component instance, return 
false
@@ -180,6 +188,7 @@ public class ImmediateComponentManager e
 
     protected interface SetImplementationObject {
         void setImplementationObject(Object implementationObject);
+        void unsetImplementationObject(Object implementationObject);
     }
 
     protected Object createImplementationObject( ComponentContext 
componentContext, SetImplementationObject setter )
@@ -235,11 +244,17 @@ public class ImmediateComponentManager e
             }
         }
 
-        // 4. Call the activate method, if present
+        // 4. set the implementation object prematurely
+        setter.setImplementationObject( implementationObject );
+
+        // 5. Call the activate method, if present
         final MethodResult result = 
getComponentMethods().getActivateMethod().invoke( implementationObject, new 
ActivatorParameter(
                 componentContext, 1 ), null );
         if ( result == null )
         {
+            // make sure the implementation object is not available
+            setter.unsetImplementationObject( implementationObject );
+
             // 112.5.8 If the activate method throws an exception, SCR must 
log an error message
             // containing the exception with the Log Service and activation 
fails
             it = getDependencyManagers();
@@ -253,7 +268,6 @@ public class ImmediateComponentManager e
         }
         else
         {
-            setter.setImplementationObject( implementationObject );
             setServiceProperties( result );
         }
 

Modified: 
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceFactoryComponentManager.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceFactoryComponentManager.java?rev=1409028&r1=1409027&r2=1409028&view=diff
==============================================================================
--- 
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceFactoryComponentManager.java
 (original)
+++ 
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceFactoryComponentManager.java
 Tue Nov 13 23:40:56 2012
@@ -152,6 +152,13 @@ public class ServiceFactoryComponentMana
                     changeState( Active.getInstance() );
                 }
             }
+
+
+            public void unsetImplementationObject( Object implementationObject 
)
+            {
+                serviceContexts.remove( implementationObject );
+                serviceContext.setImplementationObject( null );
+            }
         } );
 
         // register the components component context if successfull

Modified: 
felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/ComponentActivationTest.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/ComponentActivationTest.java?rev=1409028&r1=1409027&r2=1409028&view=diff
==============================================================================
--- 
felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/ComponentActivationTest.java
 (original)
+++ 
felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/ComponentActivationTest.java
 Tue Nov 13 23:40:56 2012
@@ -22,6 +22,7 @@ package org.apache.felix.scr.integration
 import junit.framework.TestCase;
 
 import org.apache.felix.scr.Component;
+import org.apache.felix.scr.integration.components.ActivatorComponent;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.ops4j.pax.exam.junit.JUnit4TestRunner;
@@ -185,4 +186,31 @@ public class ComponentActivationTest ext
         delay();
         TestCase.assertEquals( Component.STATE_DISABLED, component.getState() 
);
     }
+
+
+    @Test
+    public void test_activate_register_service()
+    {
+        final String componentname = "ActivatorComponent.activate.with.bind";
+
+        final Component component = findComponentByName( componentname );
+
+        TestCase.assertNotNull( component );
+        TestCase.assertFalse( component.isDefaultEnabled() );
+
+        TestCase.assertEquals( Component.STATE_DISABLED, component.getState() 
);
+
+        component.enable();
+        delay();
+
+        TestCase.assertEquals( Component.STATE_ACTIVE, component.getState() );
+
+        ActivatorComponent ac = (ActivatorComponent) 
component.getComponentInstance().getInstance();
+        TestCase.assertNotNull( ac.getSimpleService() );
+
+        component.disable();
+
+        delay();
+        TestCase.assertEquals( Component.STATE_DISABLED, component.getState() 
);
+    }
 }

Modified: 
felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/components/ActivatorComponent.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/components/ActivatorComponent.java?rev=1409028&r1=1409027&r2=1409028&view=diff
==============================================================================
--- 
felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/components/ActivatorComponent.java
 (original)
+++ 
felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/components/ActivatorComponent.java
 Tue Nov 13 23:40:56 2012
@@ -21,6 +21,9 @@ package org.apache.felix.scr.integration
 
 import java.util.Map;
 
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+
 
 public class ActivatorComponent
 {
@@ -29,14 +32,23 @@ public class ActivatorComponent
 
     public static final String FLAG_FAIL_DEACTIVATE = "failDeactivate";
 
+    public static final String FLAG_REGISTER_SERVICE = "registerService";
+
+    private ServiceRegistration registration;
+
+    private SimpleService simpleService;
 
     @SuppressWarnings("unused")
-    private void myActivate( Map<?, ?> configuration )
+    private void myActivate( BundleContext context, Map<?, ?> configuration )
     {
         if ( configuration.containsKey( FLAG_FAIL_ACTIVATE ) )
         {
             throw new IllegalStateException( "myActivate fails" );
         }
+        if ( configuration.containsKey( FLAG_REGISTER_SERVICE ) )
+        {
+            registration = context.registerService( 
SimpleService.class.getName(), new SimpleServiceImpl(), null );
+        }
     }
 
 
@@ -47,5 +59,33 @@ public class ActivatorComponent
         {
             throw new IllegalStateException( "myDeactivate fails" );
         }
+        if ( registration != null )
+        {
+            registration.unregister();
+            registration = null;
+        }
+    }
+
+
+    public SimpleService getSimpleService()
+    {
+        return simpleService;
+    }
+
+
+    @SuppressWarnings("unused")
+    private void bindSimpleService( SimpleService simpleService )
+    {
+        this.simpleService = simpleService;
+    }
+
+
+    @SuppressWarnings("unused")
+    private void unbindSimpleService( SimpleService simpleService )
+    {
+        if ( this.simpleService == simpleService )
+        {
+            this.simpleService = null;
+        }
     }
 }

Modified: 
felix/trunk/scr/src/test/resources/integration_test_activation_components.xml
URL: 
http://svn.apache.org/viewvc/felix/trunk/scr/src/test/resources/integration_test_activation_components.xml?rev=1409028&r1=1409027&r2=1409028&view=diff
==============================================================================
--- 
felix/trunk/scr/src/test/resources/integration_test_activation_components.xml 
(original)
+++ 
felix/trunk/scr/src/test/resources/integration_test_activation_components.xml 
Tue Nov 13 23:40:56 2012
@@ -70,4 +70,21 @@
         <implementation 
class="org.apache.felix.scr.integration.components.ActivatorComponent" />
         <property name="failDeactivate" value="true" />
     </scr:component>
+
+    <!-- bind service during activate -->
+    <scr:component name="ActivatorComponent.activate.with.bind"
+        enabled="false"
+        activate="myActivate"
+        deactivate="myDeactivate">
+        <implementation 
class="org.apache.felix.scr.integration.components.ActivatorComponent" />
+        <property name="registerService" value="true" />
+        <reference
+            name="service"
+            
interface="org.apache.felix.scr.integration.components.SimpleService"
+            bind="bindSimpleService"
+            unbind="unbindSimpleService"
+            policy="dynamic"
+            cardinality="0..n"
+        />
+    </scr:component>
 </components>


Reply via email to