FELIX-4011 put more stuff into ComponentContext, simplify
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1463771 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentContextImpl.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentContextImpl.java
index 34fad5e..cda6030 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentContextImpl.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentContextImpl.java
@@ -40,14 +40,27 @@
private final EdgeInfo[] edgeInfos;
- private volatile ComponentInstance m_componentInstance;
+ private final ComponentInstance m_componentInstance = new ComponentInstanceImpl(this);
+
+ private final Bundle m_usingBundle;
+
+ private final S m_implementationObject;
+
+ private volatile boolean m_implementationAccessible;
- ComponentContextImpl( AbstractComponentManager<S> componentManager )
+ ComponentContextImpl( AbstractComponentManager<S> componentManager, Bundle usingBundle, S implementationObject )
{
m_componentManager = componentManager;
+ m_usingBundle = usingBundle;
+ m_implementationObject = implementationObject;
edgeInfos = new EdgeInfo[componentManager.getComponentMetadata().getDependencies().size()];
}
+ void setImplementationAccessible(boolean implementationAccessible)
+ {
+ this.m_implementationAccessible = implementationAccessible;
+ }
+
EdgeInfo getEdgeInfo(DependencyManager<S, ?> dm)
{
int index = dm.getIndex();
@@ -105,7 +118,7 @@
public Bundle getUsingBundle()
{
- return null;
+ return m_usingBundle;
}
@@ -142,20 +155,15 @@
//---------- ComponentInstance interface support ------------------------------
- Object getImplementationObject()
+ S getImplementationObject( boolean requireAccessible )
{
- return getComponentManager().getInstance();
+ if ( !requireAccessible || m_implementationAccessible )
+ {
+ return m_implementationObject;
+ }
+ return null;
}
- void newComponentInstance()
- {
- m_componentInstance = new ComponentInstanceImpl(this);
- }
-
- void clearComponentInstance(){
- m_componentInstance = null;
- }
-
private static class ComponentInstanceImpl implements ComponentInstance
{
private final ComponentContextImpl m_componentContext;
@@ -168,7 +176,7 @@
public Object getInstance()
{
- return m_componentContext.getImplementationObject();
+ return m_componentContext.getImplementationObject(true);
}
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java
index 54b60bf..7ddc962 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java
@@ -47,19 +47,11 @@
public class ImmediateComponentManager<S> extends AbstractComponentManager<S> implements ServiceFactory<S>
{
- // The object that implements the service and that is bound to other services
- private volatile S 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 S m_tmpImplementationObject;
-
// keep the using bundles as reference "counters" for instance deactivation
private final AtomicInteger m_useCount = new AtomicInteger( );
// The context that will be passed to the implementationObject
- private final ComponentContextImpl<S> m_componentContext = new ComponentContextImpl<S>(this);
+ private volatile ComponentContextImpl<S> m_componentContext;
// the component holder responsible for managing this component
private ComponentHolder m_componentHolder;
@@ -118,26 +110,19 @@
{
throw new IllegalStateException( "need write lock (createComponent)" );
}
- if ( m_implementationObject == null )
+ if ( m_componentContext == null )
{
- S tmpComponent = createImplementationObject( m_componentContext, new SetImplementationObject<S>()
+ S tmpComponent = createImplementationObject( null, new SetImplementationObject<S>()
{
- public void setImplementationObject( S implementationObject )
+ public void presetComponentContext( ComponentContextImpl<S> componentContext )
{
- m_implementationObject = implementationObject;
- m_tmpImplementationObject = null;
- }
-
-
- public void presetImplementationObject( S implementationObject )
- {
- m_tmpImplementationObject = implementationObject;
+ m_componentContext = componentContext;
}
public void resetImplementationObject( S implementationObject )
{
- m_tmpImplementationObject = null;
+ m_componentContext = null;
}
} );
@@ -163,15 +148,12 @@
{
throw new IllegalStateException( "need write lock (deleteComponent)" );
}
- if ( m_implementationObject != null )
+ if ( m_componentContext != null )
{
- S implementationObject = m_implementationObject;
m_useCount.set( 0 );
- m_tmpImplementationObject = implementationObject;
- m_implementationObject = null;
- disposeImplementationObject( implementationObject, m_componentContext, reason );
- m_tmpImplementationObject = null;
- cleanupImplementationObject( implementationObject );
+ m_componentContext.setImplementationAccessible( false );
+ disposeImplementationObject( m_componentContext, reason );
+ m_componentContext = null;
log( LogService.LOG_DEBUG, "Unset and deconfigured implementation object for component {0} in deleteComponent for reason {1}", new Object[] { getName(), REASONS[ reason ] }, null );
m_properties = null;
m_serviceProperties = null;
@@ -181,7 +163,7 @@
public ComponentInstance getComponentInstance()
{
- return m_componentContext.getComponentInstance();
+ return m_componentContext == null? null: m_componentContext.getComponentInstance();
}
@@ -194,7 +176,7 @@
*/
Object getInstance()
{
- return m_implementationObject;
+ return m_componentContext == null? null: m_componentContext.getImplementationObject( true );
}
/**
@@ -212,30 +194,21 @@
* temporarily set the implementation object during the activator
* call.
*/
- void presetImplementationObject( S implementationObject );
+ void presetComponentContext( ComponentContextImpl<S> componentContext );
/**
* 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)}
+ * revert any temporary settings done in the {@link #presetComponentContext(ComponentContextImpl)}
* method.
*/
void resetImplementationObject( S 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( S implementationObject );
}
- protected S createImplementationObject( ComponentContextImpl componentContext, SetImplementationObject setter )
+ protected S createImplementationObject( Bundle usingBundle, SetImplementationObject setter )
{
final Class<S> implementationObjectClass;
final S implementationObject;
@@ -260,10 +233,10 @@
return null;
}
- componentContext.newComponentInstance();
+ ComponentContextImpl componentContext = new ComponentContextImpl(this, usingBundle, implementationObject);
// 3. set the implementation object prematurely
- setter.presetImplementationObject( implementationObject );
+ setter.presetComponentContext( componentContext );
// 4. Bind the target services
@@ -285,6 +258,7 @@
md.close( implementationObject );
}
+ setter.resetImplementationObject( implementationObject );
return null;
}
}
@@ -294,9 +268,6 @@
componentContext, 1 ), null, this );
if ( result == null )
{
- // make sure the implementation object is not available
- 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
for ( DependencyManager md: getReversedDependencyManagers() )
@@ -304,11 +275,14 @@
md.close( implementationObject );
}
- return null;
+ // make sure the implementation object is not available
+ setter.resetImplementationObject( implementationObject );
+
+ return null;
}
else
{
- setter.setImplementationObject( implementationObject );
+ componentContext.setImplementationAccessible( true );
setServiceProperties( result );
}
@@ -316,9 +290,10 @@
}
- protected void disposeImplementationObject( Object implementationObject, ComponentContext componentContext,
+ protected void disposeImplementationObject( ComponentContextImpl<S> componentContext,
int reason )
{
+ S implementationObject = componentContext.getImplementationObject( false );
// 1. Call the deactivate method, if present
// don't care for the result, the error (acccording to 112.5.12 If the deactivate
@@ -339,12 +314,6 @@
}
- protected void cleanupImplementationObject( Object implementationObject )
- {
- m_componentContext.clearEdgeInfos();
- m_componentContext.clearComponentInstance();
- }
-
State getSatisfiedState()
{
return Registered.getInstance();
@@ -362,20 +331,32 @@
<T> void invokeBindMethod( DependencyManager<S, T> dependencyManager, RefPair<T> refPair, int trackingCount )
{
- final S impl = ( m_tmpImplementationObject != null ) ? m_tmpImplementationObject : m_implementationObject;
- dependencyManager.invokeBindMethod( impl, refPair, trackingCount );
+ ComponentContextImpl<S> componentContext = m_componentContext;
+ if ( componentContext != null )
+ {
+ final S impl = componentContext.getImplementationObject( false );
+ dependencyManager.invokeBindMethod( impl, refPair, trackingCount );
+ }
}
<T> void invokeUpdatedMethod( DependencyManager<S, T> dependencyManager, RefPair<T> refPair, int trackingCount )
{
- final S impl = ( m_tmpImplementationObject != null ) ? m_tmpImplementationObject : m_implementationObject;
- dependencyManager.invokeUpdatedMethod( impl, refPair, trackingCount );
+ ComponentContextImpl<S> componentContext = m_componentContext;
+ if ( componentContext != null )
+ {
+ final S impl = componentContext.getImplementationObject( false );
+ dependencyManager.invokeUpdatedMethod( impl, refPair, trackingCount );
+ }
}
<T> void invokeUnbindMethod( DependencyManager<S, T> dependencyManager, RefPair<T> oldRefPair, int trackingCount )
{
- final S impl = ( m_tmpImplementationObject != null ) ? m_tmpImplementationObject : m_implementationObject;
- dependencyManager.invokeUnbindMethod( impl, oldRefPair, trackingCount );
+ ComponentContextImpl<S> componentContext = m_componentContext;
+ if ( componentContext != null )
+ {
+ final S impl = componentContext.getImplementationObject( false );
+ dependencyManager.invokeUnbindMethod( impl, oldRefPair, trackingCount );
+ }
}
protected void setFactoryProperties( Dictionary<String, Object> dictionary )
@@ -678,12 +659,6 @@
return modifiedMethod.invoke( getInstance(), new ActivatorParameter( m_componentContext, -1 ),
MethodResult.VOID, this );
}
- else if ( m_tmpImplementationObject != null)
- {
- return modifiedMethod.invoke( m_tmpImplementationObject, new ActivatorParameter( m_componentContext, -1 ),
- MethodResult.VOID, this );
-
- }
return MethodResult.VOID;
}
@@ -715,8 +690,8 @@
public S getService( Bundle bundle, ServiceRegistration<S> serviceRegistration )
{
- Object implementationObject = m_implementationObject;
- if ( implementationObject == null )
+ ComponentContextImpl<S> componentContext = m_componentContext;
+ if ( componentContext == null )
{
try
{
@@ -748,7 +723,7 @@
obtainWriteLock( "ImmediateComponentManager.getService.1" );
try
{
- if ( m_implementationObject == null )
+ if ( m_componentContext == null )
{
//state should be "Registered"
S result = (S) state().getService( this );
@@ -758,7 +733,6 @@
}
return result;
}
- implementationObject = m_implementationObject;
}
finally
{
@@ -766,7 +740,7 @@
}
}
m_useCount.incrementAndGet();
- return (S) implementationObject;
+ return m_componentContext.getImplementationObject( true );
}
public void ungetService( Bundle bundle, ServiceRegistration<S> serviceRegistration, S o )
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceFactoryComponentManager.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceFactoryComponentManager.java
index d1a36ba..8fe3a1a 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceFactoryComponentManager.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceFactoryComponentManager.java
@@ -46,7 +46,7 @@
// maintain the map of ComponentContext objects created for the
// service instances
- private IdentityHashMap<S, BundleComponentContext> serviceContexts = new IdentityHashMap<S, BundleComponentContext>();
+ private IdentityHashMap<S, ComponentContextImpl> serviceContexts = new IdentityHashMap<S, ComponentContextImpl>();
/**
* @param activator BundleComponentActivator for this DS implementation
@@ -80,12 +80,11 @@
{
throw new IllegalStateException( "need write lock (deleteComponent)" );
}
- for (Iterator i = serviceContexts.values().iterator(); i.hasNext(); )
+ for (Iterator<ComponentContextImpl> i = serviceContexts.values().iterator(); i.hasNext(); )
{
- BundleComponentContext componentContext = ( BundleComponentContext ) i.next();
- disposeImplementationObject( componentContext.getImplementationObject(), componentContext, reason );
+ ComponentContextImpl componentContext = i.next();
+ disposeImplementationObject( componentContext, reason );
i.remove();
- cleanupImplementationObject( componentContext.getImplementationObject() );
log( LogService.LOG_DEBUG, "Unset implementation object for component {0} in deleteComponent for reason {1}", new Object[] { getName(), REASONS[ reason ] }, null );
}
}
@@ -97,7 +96,7 @@
Object getInstance()
{
// this method is not expected to be called as the base call is
- // overwritten in the BundleComponentContext class
+ // overwritten in the ComponentContextImpl class
return null;
}
@@ -136,31 +135,16 @@
return null;
}
// private ComponentContext and implementation instances
- final BundleComponentContext serviceContext = new BundleComponentContext( this, bundle );
- S service = createImplementationObject( serviceContext, new SetImplementationObject<S>()
+ S service = createImplementationObject( bundle, new SetImplementationObject<S>()
{
- public void presetImplementationObject( S implementationObject )
+ public void presetComponentContext( ComponentContextImpl<S> componentContext )
{
- serviceContext.setImplementationObject( implementationObject );
- serviceContexts.put( implementationObject, serviceContext );
+ serviceContexts.put( componentContext.getImplementationObject( false ), componentContext );
}
-
- public void setImplementationObject( S implementationObject )
- {
-
- // if this is the first use of this component, switch to ACTIVE state
- if ( getState() == STATE_REGISTERED )
- {
- changeState( Active.getInstance() );
- }
- }
-
-
public void resetImplementationObject( S implementationObject )
{
serviceContexts.remove( implementationObject );
- serviceContext.setImplementationObject( null );
}
} );
@@ -172,6 +156,15 @@
// know why at this moment; this should already have been logged)
log( LogService.LOG_ERROR, "Failed creating the component instance; see log for reason", null );
}
+ else
+ {
+ // if this is the first use of this component, switch to ACTIVE state
+ if ( getState() == STATE_REGISTERED )
+ {
+ changeState( Active.getInstance() );
+ }
+
+ }
return service;
}
@@ -186,10 +179,10 @@
// When the ungetServiceMethod is called, the implementation object must be deactivated
// private ComponentContext and implementation instances
- final ComponentContext serviceContext;
+ final ComponentContextImpl<S> serviceContext;
serviceContext = serviceContexts.get( service );
- disposeImplementationObject( service, serviceContext, ComponentConstants.DEACTIVATION_REASON_DISPOSED );
+ disposeImplementationObject( serviceContext, ComponentConstants.DEACTIVATION_REASON_DISPOSED );
serviceContexts.remove( service );
cleanupImplementationObject( service );
// if this was the last use of the component, go back to REGISTERED state
@@ -238,9 +231,9 @@
{
ModifiedMethod modifiedMethod = getComponentMethods().getModifiedMethod();
MethodResult result = MethodResult.VOID;
- for ( BundleComponentContext componentContext : serviceContexts.values() )
+ for ( ComponentContextImpl componentContext : serviceContexts.values() )
{
- Object instance = componentContext.getImplementationObject();
+ Object instance = componentContext.getImplementationObject(true);
result = modifiedMethod.invoke( instance,
new ActivateMethod.ActivatorParameter( componentContext, -1 ), MethodResult.VOID, this );
@@ -257,38 +250,4 @@
return super.getComponentInstance();
}
- private static class BundleComponentContext extends ComponentContextImpl
- {
-
- private Bundle m_usingBundle;
- private Object m_implementationObject;
-
-
- BundleComponentContext( AbstractComponentManager componentManager, Bundle usingBundle )
- {
- super( componentManager );
-
- m_usingBundle = usingBundle;
- }
-
-
- private void setImplementationObject( Object implementationObject )
- {
- m_implementationObject = implementationObject;
- }
-
-
- public Bundle getUsingBundle()
- {
- return m_usingBundle;
- }
-
-
- //---------- ComponentInstance interface support ------------------------------
-
- Object getImplementationObject()
- {
- return m_implementationObject;
- }
- }
}