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;
}