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