felix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From fmesc...@apache.org
Subject svn commit: r1410211 - in /felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager: ImmediateComponentManager.java ServiceFactoryComponentManager.java
Date Fri, 16 Nov 2012 06:39:30 GMT
Author: fmeschbe
Date: Fri Nov 16 06:39:30 2012
New Revision: 1410211

URL: http://svn.apache.org/viewvc?rev=1410211&view=rev
Log:
FELIX-3754 Add temporary implementation object provisioning to support
  binding services during calls to the activate method but preventing
  access to the implementation object before the activate method has
  successfully terminated.

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

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=1410211&r1=1410210&r2=1410211&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
Fri Nov 16 06:39:30 2012
@@ -52,6 +52,11 @@ public class ImmediateComponentManager e
     // The object that implements the service and that is bound to other services
     private volatile Object m_implementationObject;
 
+    // The component implementation object temporarily set to allow
+    // for service updates during activation. This field is only set
+    // to a non-null value while calling the activate method
+    private volatile Object m_tmpImplementationObject;
+
     // keep the using bundles as reference "counters" for instance deactivation
     private volatile int m_useCount;
 
@@ -122,15 +127,20 @@ public class ImmediateComponentManager e
                 {
                     m_componentContext = tmpContext;
                     m_implementationObject = implementationObject;
+                    m_tmpImplementationObject = null;
                 }
 
 
-                public void unsetImplementationObject( Object implementationObject )
+                public void presetImplementationObject( Object implementationObject )
                 {
-                    m_componentContext = null;
-                    m_implementationObject = null;
+                    m_tmpImplementationObject = implementationObject;
                 }
 
+
+                public void resetImplementationObject( Object implementationObject )
+                {
+                    m_tmpImplementationObject = null;
+                }
             } );
 
             // if something failed creating the component instance, return false
@@ -186,11 +196,44 @@ public class ImmediateComponentManager e
         return m_implementationObject;
     }
 
-    protected interface SetImplementationObject {
-        void setImplementationObject(Object implementationObject);
-        void unsetImplementationObject(Object implementationObject);
+    /**
+     * The <code>SetImplementationObject</code> interface provides an
+     * API for component managers to setup the implementation object and
+     * potentially other parts as part of the {@link #createImplementationObject} method
+     * processing.
+     */
+    protected interface SetImplementationObject
+    {
+
+        /**
+         * Presets the implementation object. This method is called before
+         * the component's activator method is called and is intended to
+         * temporarily set the implementation object during the activator
+         * call.
+         */
+        void presetImplementationObject( Object implementationObject );
+
+
+        /**
+         * Resets the implementation object. This method is called after
+         * the activator method terminates with an error and is intended to
+         * revert any temporary settings done in the {@link #presetImplementationObject(Object)}
+         * method.
+         */
+        void resetImplementationObject( Object implementationObject );
+
+
+        /**
+         * Sets the implementation object. This method is called after
+         * the activator methid terminates successfully and is intended to
+         * complete setting the implementation object. Temporary presets done
+         * by the {@link #presetImplementationObject(Object)} should be
+         * removed and the implementation object is now accessible.
+         */
+        void setImplementationObject( Object implementationObject );
     }
 
+
     protected Object createImplementationObject( ComponentContext componentContext, SetImplementationObject
setter )
     {
         final Class implementationObjectClass;
@@ -245,7 +288,7 @@ public class ImmediateComponentManager e
         }
 
         // 4. set the implementation object prematurely
-        setter.setImplementationObject( implementationObject );
+        setter.presetImplementationObject( implementationObject );
 
         // 5. Call the activate method, if present
         final MethodResult result = getComponentMethods().getActivateMethod().invoke( implementationObject,
new ActivatorParameter(
@@ -253,7 +296,7 @@ public class ImmediateComponentManager e
         if ( result == null )
         {
             // make sure the implementation object is not available
-            setter.unsetImplementationObject( implementationObject );
+            setter.resetImplementationObject( 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
@@ -268,6 +311,7 @@ public class ImmediateComponentManager e
         }
         else
         {
+            setter.setImplementationObject( implementationObject );
             setServiceProperties( result );
         }
 
@@ -314,17 +358,20 @@ public class ImmediateComponentManager e
 
     void update( DependencyManager dependencyManager, ServiceReference ref )
     {
-        dependencyManager.update( m_implementationObject, ref );
+        final Object impl = ( m_tmpImplementationObject != null ) ? m_tmpImplementationObject
: m_implementationObject;
+        dependencyManager.update( impl, ref );
     }
 
     void invokeBindMethod( DependencyManager dependencyManager, ServiceReference reference
)
     {
-        dependencyManager.invokeBindMethod( m_implementationObject, reference);
+        final Object impl = ( m_tmpImplementationObject != null ) ? m_tmpImplementationObject
: m_implementationObject;
+        dependencyManager.invokeBindMethod( impl, reference);
     }
 
     void invokeUnbindMethod( DependencyManager dependencyManager, ServiceReference oldRef
)
     {
-        dependencyManager.invokeUnbindMethod( m_implementationObject, oldRef);
+        final Object impl = ( m_tmpImplementationObject != null ) ? m_tmpImplementationObject
: m_implementationObject;
+        dependencyManager.invokeUnbindMethod( impl, oldRef);
     }
 
     protected void setFactoryProperties( Dictionary dictionary )

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=1410211&r1=1410210&r2=1410211&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
Fri Nov 16 06:39:30 2012
@@ -49,6 +49,11 @@ public class ServiceFactoryComponentMana
     // service instances
     private IdentityHashMap serviceContexts = new IdentityHashMap();
 
+    // pseudo map of implementation objects to be used for service
+    // binding while calling the activate method. The map's keys and values
+    // are just the implementation objects. The objects will only be
+    // contained while the activate method is being called.
+    private IdentityHashMap tmpImplementationObjects = new IdentityHashMap();
 
     /**
      * @param activator BundleComponentActivator for this DS implementation
@@ -140,11 +145,18 @@ public class ServiceFactoryComponentMana
         final BundleComponentContext serviceContext = new BundleComponentContext( this, bundle
);
         Object service = createImplementationObject( serviceContext, new SetImplementationObject()
         {
-            public void setImplementationObject( Object implementationObject )
+            public void presetImplementationObject( Object implementationObject )
             {
                 serviceContext.setImplementationObject( implementationObject );
+                tmpImplementationObjects.put( implementationObject, serviceContext );
+
+            }
 
+
+            public void setImplementationObject( Object implementationObject )
+            {
                 serviceContexts.put( implementationObject, serviceContext );
+                tmpImplementationObjects.remove( implementationObject );
 
                 // if this is the first use of this component, switch to ACTIVE state
                 if ( getState() == STATE_REGISTERED )
@@ -154,11 +166,12 @@ public class ServiceFactoryComponentMana
             }
 
 
-            public void unsetImplementationObject( Object implementationObject )
+            public void resetImplementationObject( Object implementationObject )
             {
-                serviceContexts.remove( implementationObject );
+                tmpImplementationObjects.remove( implementationObject );
                 serviceContext.setImplementationObject( null );
             }
+
         } );
 
         // register the components component context if successfull
@@ -211,6 +224,11 @@ public class ServiceFactoryComponentMana
             Object implementationObject = it.next();
             dependencyManager.invokeBindMethod( implementationObject, reference);
         }
+        for ( Iterator it = tmpImplementationObjects.keySet().iterator(); it.hasNext(); )
+        {
+            Object implementationObject = it.next();
+            dependencyManager.invokeBindMethod( implementationObject, reference);
+        }
     }
 
     void invokeUnbindMethod( DependencyManager dependencyManager, ServiceReference oldRef
)
@@ -220,6 +238,11 @@ public class ServiceFactoryComponentMana
             Object implementationObject = it.next();
             dependencyManager.invokeUnbindMethod( implementationObject, oldRef);
         }
+        for ( Iterator it = tmpImplementationObjects.keySet().iterator(); it.hasNext(); )
+        {
+            Object implementationObject = it.next();
+            dependencyManager.invokeUnbindMethod( implementationObject, oldRef);
+        }
     }
 
     protected MethodResult invokeModifiedMethod()
@@ -234,6 +257,14 @@ public class ServiceFactoryComponentMana
                     new ActivateMethod.ActivatorParameter( componentContext, -1 ), MethodResult.VOID
);
 
         }
+        for (Iterator i = tmpImplementationObjects.values().iterator(); i.hasNext(); )
+        {
+            BundleComponentContext componentContext = ( BundleComponentContext ) i.next();
+            Object instance = componentContext.getInstance();
+            result = modifiedMethod.invoke( instance,
+                new ActivateMethod.ActivatorParameter( componentContext, -1 ), MethodResult.VOID
);
+
+        }
         return result;
     }
 



Mime
View raw message