FELIX-4011 use a final ComponentContext since it now has useful state (later made non-final again) and make ComponentInstance a separate class
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1463769 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 70a67ef..fe1c5ea 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
@@ -34,12 +34,13 @@
* Implementation for the ComponentContext interface
*
*/
-public class ComponentContextImpl implements ExtComponentContext, ComponentInstance {
+public class ComponentContextImpl implements ExtComponentContext {
private final AbstractComponentManager m_componentManager;
private final EdgeInfo[] edgeInfos;
-
+
+ private volatile ComponentInstance m_componentInstance;
ComponentContextImpl( AbstractComponentManager componentManager )
{
@@ -110,7 +111,7 @@
public ComponentInstance getComponentInstance()
{
- return this;
+ return m_componentInstance;
}
@@ -132,24 +133,49 @@
}
- //---------- ComponentInstance interface ------------------------------
-
- public Object getInstance()
- {
- return getComponentManager().getInstance();
- }
-
-
- public void dispose()
- {
- getComponentManager().dispose();
- }
-
//---------- Speculative MutableProperties interface ------------------------------
public void setServiceProperties(Dictionary properties)
{
getComponentManager().setServiceProperties(properties );
}
+
+ //---------- ComponentInstance interface support ------------------------------
+ Object getImplementationObject()
+ {
+ return getComponentManager().getInstance();
+ }
+
+ void newComponentInstance()
+ {
+ m_componentInstance = new ComponentInstanceImpl(this);
+ }
+
+ void clearComponentInstance(){
+ m_componentInstance = null;
+ }
+
+ private static class ComponentInstanceImpl implements ComponentInstance
+ {
+ private final ComponentContextImpl m_componentContext;
+
+ private ComponentInstanceImpl(ComponentContextImpl m_componentContext)
+ {
+ this.m_componentContext = m_componentContext;
+ }
+
+
+ public Object getInstance()
+ {
+ return m_componentContext.getImplementationObject();
+ }
+
+
+ public void dispose()
+ {
+ m_componentContext.getComponentManager().dispose();
+ }
+
+ }
}
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 33af8c3..57c7af7 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
@@ -59,7 +59,7 @@
private final AtomicInteger m_useCount = new AtomicInteger( );
// The context that will be passed to the implementationObject
- private ComponentContextImpl m_componentContext;
+ private final ComponentContextImpl m_componentContext = new ComponentContextImpl(this);
// the component holder responsible for managing this component
private ComponentHolder m_componentHolder;
@@ -120,9 +120,7 @@
}
if ( m_implementationObject == null )
{
- final ComponentContextImpl tmpContext = new ComponentContextImpl( this );
- m_componentContext = tmpContext;
- S tmpComponent = createImplementationObject( tmpContext, new SetImplementationObject<S>()
+ S tmpComponent = createImplementationObject( m_componentContext, new SetImplementationObject<S>()
{
public void setImplementationObject( S implementationObject )
{
@@ -175,7 +173,6 @@
m_tmpImplementationObject = null;
cleanupImplementationObject( implementationObject );
log( LogService.LOG_DEBUG, "Unset and deconfigured implementation object for component {0} in deleteComponent for reason {1}", new Object[] { getName(), REASONS[ reason ] }, null );
- m_componentContext = null;
m_properties = null;
m_serviceProperties = null;
}
@@ -184,7 +181,7 @@
public ComponentInstance getComponentInstance()
{
- return m_componentContext;
+ return m_componentContext.getComponentInstance();
}
@@ -238,7 +235,7 @@
}
- protected S createImplementationObject( ComponentContext componentContext, SetImplementationObject setter )
+ protected S createImplementationObject( ComponentContextImpl componentContext, SetImplementationObject setter )
{
final Class<S> implementationObjectClass;
final S implementationObject;
@@ -262,6 +259,8 @@
log( LogService.LOG_ERROR, "Error during instantiation of the implementation object", t );
return null;
}
+
+ componentContext.newComponentInstance();
// 3. set the implementation object prematurely
setter.presetImplementationObject( implementationObject );
@@ -343,6 +342,7 @@
protected void cleanupImplementationObject( Object implementationObject )
{
m_componentContext.clearEdgeInfos();
+ m_componentContext.clearComponentInstance();
}
State getSatisfiedState()
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 92f5823..d1a36ba 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
@@ -83,9 +83,9 @@
for (Iterator i = serviceContexts.values().iterator(); i.hasNext(); )
{
BundleComponentContext componentContext = ( BundleComponentContext ) i.next();
- disposeImplementationObject( componentContext.getInstance(), componentContext, reason );
+ disposeImplementationObject( componentContext.getImplementationObject(), componentContext, reason );
i.remove();
- cleanupImplementationObject( componentContext.getInstance() );
+ cleanupImplementationObject( componentContext.getImplementationObject() );
log( LogService.LOG_DEBUG, "Unset implementation object for component {0} in deleteComponent for reason {1}", new Object[] { getName(), REASONS[ reason ] }, null );
}
}
@@ -240,7 +240,7 @@
MethodResult result = MethodResult.VOID;
for ( BundleComponentContext componentContext : serviceContexts.values() )
{
- Object instance = componentContext.getInstance();
+ Object instance = componentContext.getImplementationObject();
result = modifiedMethod.invoke( instance,
new ActivateMethod.ActivatorParameter( componentContext, -1 ), MethodResult.VOID, this );
@@ -284,9 +284,9 @@
}
- //---------- ComponentInstance interface ------------------------------
+ //---------- ComponentInstance interface support ------------------------------
- public Object getInstance()
+ Object getImplementationObject()
{
return m_implementationObject;
}
diff --git a/scr/src/test/java/org/apache/felix/scr/integration/ComponentFactoryTest.java b/scr/src/test/java/org/apache/felix/scr/integration/ComponentFactoryTest.java
index 1053202..631a921 100644
--- a/scr/src/test/java/org/apache/felix/scr/integration/ComponentFactoryTest.java
+++ b/scr/src/test/java/org/apache/felix/scr/integration/ComponentFactoryTest.java
@@ -94,7 +94,7 @@
TestCase.assertNotNull( instanceMap );
TestCase.assertEquals( 1, instanceMap.size() );
- final Object instanceManager = getFieldValue( instance, "m_componentManager" );
+ final Object instanceManager = getComponentManagerFromComponentInstance( instance );
TestCase.assertTrue( instanceMap.containsValue( instanceManager ) );
// check registered components
@@ -169,7 +169,7 @@
TestCase.assertNotNull( instanceMap );
TestCase.assertEquals( 1, instanceMap.size() );
- final Object instanceManager = getFieldValue( instance, "m_componentManager" );
+ final Object instanceManager = getComponentManagerFromComponentInstance( instance );
TestCase.assertTrue( instanceMap.containsValue( instanceManager ) );
// disable the factory
@@ -301,7 +301,7 @@
TestCase.assertNotNull( instanceMap );
TestCase.assertEquals( 1, instanceMap.size() );
- final Object instanceManager = getFieldValue( instance, "m_componentManager" );
+ final Object instanceManager = getComponentManagerFromComponentInstance( instance );
TestCase.assertTrue( instanceMap.containsValue( instanceManager ) );
// delete config, ensure factory is not active anymore and component instance not changed
@@ -377,7 +377,7 @@
TestCase.assertNotNull( instanceMap );
TestCase.assertEquals( 1, instanceMap.size() );
- final Object instanceManager = getFieldValue( instance, "m_componentManager" );
+ final Object instanceManager = getComponentManagerFromComponentInstance( instance );
TestCase.assertTrue( instanceMap.containsValue( instanceManager ) );
// check registered components
diff --git a/scr/src/test/java/org/apache/felix/scr/integration/ComponentTestBase.java b/scr/src/test/java/org/apache/felix/scr/integration/ComponentTestBase.java
index df5e10d..62ac025 100644
--- a/scr/src/test/java/org/apache/felix/scr/integration/ComponentTestBase.java
+++ b/scr/src/test/java/org/apache/felix/scr/integration/ComponentTestBase.java
@@ -370,6 +370,12 @@
return null; // keep the compiler happy
}
}
+
+ protected Object getComponentManagerFromComponentInstance( Object instance )
+ {
+ Object cc = getFieldValue( instance, "m_componentContext");
+ return getFieldValue( cc, "m_componentManager" );
+ }
protected static Field getField( Class<?> type, String fieldName ) throws NoSuchFieldException
diff --git a/scr/src/test/java/org/apache/felix/scr/integration/ConfigurationComponentFactoryTest.java b/scr/src/test/java/org/apache/felix/scr/integration/ConfigurationComponentFactoryTest.java
index fb0e4d2..9f0dfad 100644
--- a/scr/src/test/java/org/apache/felix/scr/integration/ConfigurationComponentFactoryTest.java
+++ b/scr/src/test/java/org/apache/felix/scr/integration/ConfigurationComponentFactoryTest.java
@@ -98,7 +98,7 @@
TestCase.assertNotNull( instanceMap );
TestCase.assertEquals( 1, instanceMap.size() );
- final Object instanceManager = getFieldValue( SimpleComponent.INSTANCE.m_activateContext.getComponentInstance(), "m_componentManager" );
+ final Object instanceManager = getFieldValue( SimpleComponent.INSTANCE.m_activateContext, "m_componentManager" );
TestCase.assertTrue( instanceMap.containsValue( instanceManager ) );