FELIX-3700: Unregister ComponentFactory when configuration is lost and when
configuration-policy is required.


git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1399224 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java
index 5d6c5e4..bb26ce7 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java
@@ -312,9 +312,38 @@
     {
         if ( pid.equals( getComponentMetadata().getConfigurationPid() ) )
         {
-            // deleting configuration of a component factory is like
-            // providing an empty configuration
-            m_configuration = new Hashtable();
+            log( LogService.LOG_DEBUG, "Handling configuration removal", null );
+
+            boolean release = obtainReadLock( "ComponentFactoryImpl.configurationDeleted" );
+            try
+            {
+                // nothing to do if there is no configuration currently known.
+                if (! m_isConfigured)
+                {
+                    log( LogService.LOG_DEBUG, "ignoring configuration removal: not currently configured", null );
+                    return;
+                }
+                
+                // So far, we were configured: clear the current configuration.
+                m_isConfigured = false;
+                m_configuration = new Hashtable();
+
+                log( LogService.LOG_DEBUG, "Current component factory state={0}", new Object[] { getState() }, null );
+
+                // And deactivate if we are not currently disposed and if configuration is required
+                if ( ( getState() & STATE_DISPOSED ) == 0 && getComponentMetadata().isConfigurationRequired() )
+                {
+                    log( LogService.LOG_DEBUG, "Deactivating component factory (required configuration has gone)", null );
+                    deactivateInternal( ComponentConstants.DEACTIVATION_REASON_CONFIGURATION_DELETED );
+                }
+            }
+            finally
+            {
+                if ( release )
+                {
+                    releaseReadLock( "ComponentFactoryImpl.configurationDeleted" );
+                }
+            }
         }
         else
         {
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 05727c1..1053202 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
@@ -304,10 +304,10 @@
         final Object instanceManager = getFieldValue( instance, "m_componentManager" );
         TestCase.assertTrue( instanceMap.containsValue( instanceManager ) );
 
-        // delete config, ensure factory still active and component instance, not changed
+        // delete config, ensure factory is not active anymore and component instance not changed
         deleteConfig( componentname );
         delay();
-        TestCase.assertEquals( Component.STATE_FACTORY, component.getState() );
+        TestCase.assertEquals( Component.STATE_UNSATISFIED, component.getState() );
 
         TestCase.assertNotNull( instance.getInstance() );
         TestCase.assertEquals( SimpleComponent.INSTANCE, instance.getInstance() );