FELIX-4290 Commit a slightly simpler fix than Pierre proposed and his test, moved into the existing ComponentFactory test class

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1535647 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/scr/changelog.txt b/scr/changelog.txt
index dc28133..4e9fe46 100644
--- a/scr/changelog.txt
+++ b/scr/changelog.txt
@@ -43,6 +43,7 @@
     * [FELIX-4223] - [DS] DependencyManager filter should be set up in enable, not activate, to avoid race conditions
     * [FELIX-4224] - [DS] Dependency manager can be active but not have m_bindMethods set
     * [FELIX-4287] - [DS] NPE when calling ComponentInstance.dispose after bundle shut down
+    * [FELIX-4290] - [DS] Issue with factory components with required configuration
 
 ** Task
     * [FELIX-3584] - [DS] Handle new LOCATION_CHANGED event
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 c8f20a1..d61fe3b 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
@@ -374,7 +374,7 @@
                 log( LogService.LOG_INFO, "Verifying if Active Component Factory is still satisfied", null );
 
                 // First update target filters.
-                super.updateTargets( getProperties() );
+                updateTargets( getProperties() );
 
                 // Next, verify dependencies
                 if ( !verifyDependencyManagers() )
@@ -392,6 +392,8 @@
             {
                 // try to activate our component factory, if all dependnecies are satisfied
                 log( LogService.LOG_DEBUG, "Attempting to activate unsatisfied component", null );
+                // First update target filters.
+                updateTargets( getProperties() );
                 activateInternal( getTrackingCount().get() );
             }
         }
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 33a9d62..c2f97b8 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
@@ -39,6 +39,7 @@
 import org.osgi.service.component.ComponentException;
 import org.osgi.service.component.ComponentFactory;
 import org.osgi.service.component.ComponentInstance;
+import org.osgi.service.log.LogService;
 
 
 @RunWith(JUnit4TestRunner.class)
@@ -570,4 +571,58 @@
         TestCase.assertEquals( Component.STATE_UNSATISFIED, referringComponent.getState() );
     }
 
+    @Test
+    public void test_component_factory_with_target_filters() throws InvalidSyntaxException
+    {
+        final String componentfactory = "factory.component.reference.targetfilter";
+        final Component component = findComponentByName( componentfactory );
+
+        TestCase.assertNotNull( component );
+        TestCase.assertFalse( component.isDefaultEnabled() );
+
+        TestCase.assertEquals( Component.STATE_DISABLED, component.getState() );
+        TestCase.assertNull( SimpleComponent.INSTANCE );
+
+        component.enable();
+        delay();
+
+        SimpleServiceImpl s1 = SimpleServiceImpl.create(bundleContext, "service1");
+        SimpleServiceImpl s2 = SimpleServiceImpl.create(bundleContext, "service2");
+
+        // supply configuration now and ensure active
+        configure( componentfactory );
+        delay();        
+
+        TestCase.assertEquals( Component.STATE_FACTORY, component.getState() );
+        TestCase.assertNull( SimpleComponent.INSTANCE );
+        
+        final ServiceReference[] refs = bundleContext.getServiceReferences( ComponentFactory.class.getName(), "("
+            + ComponentConstants.COMPONENT_FACTORY + "=" + componentfactory + ")" );
+        TestCase.assertNotNull( refs );
+        TestCase.assertEquals( 1, refs.length );
+        final ComponentFactory factory = ( ComponentFactory ) bundleContext.getService( refs[0] );
+        TestCase.assertNotNull( factory );
+
+        Hashtable<String, String> props = new Hashtable<String, String>();
+        props.put( PROP_NAME_FACTORY, PROP_NAME_FACTORY );
+        props.put("ref.target", "(value=service2)");
+        final ComponentInstance instance = factory.newInstance( props );
+        TestCase.assertNotNull( instance );
+
+        TestCase.assertNotNull( instance.getInstance() );
+        TestCase.assertEquals( SimpleComponent.INSTANCE, instance.getInstance() );
+        TestCase.assertEquals( PROP_NAME_FACTORY, SimpleComponent.INSTANCE.getProperty( PROP_NAME_FACTORY ) );
+
+        log.log(LogService.LOG_WARNING, "Bound Services: " +  SimpleComponent.INSTANCE.m_multiRef);
+        TestCase.assertFalse( SimpleComponent.INSTANCE.m_multiRef.contains( s1 ) );
+        TestCase.assertTrue( SimpleComponent.INSTANCE.m_multiRef.contains( s2 ) );
+
+        instance.dispose();
+        TestCase.assertNull( SimpleComponent.INSTANCE );
+        TestCase.assertNull( instance.getInstance() ); // SCR 112.12.6.2
+        
+        s2.drop();
+        s1.drop();
+    }
+
 }
diff --git a/scr/src/test/resources/integration_test_simple_factory_components.xml b/scr/src/test/resources/integration_test_simple_factory_components.xml
index e81acaf..1cac7ae 100644
--- a/scr/src/test/resources/integration_test_simple_factory_components.xml
+++ b/scr/src/test/resources/integration_test_simple_factory_components.xml
@@ -78,4 +78,20 @@
         />
     </scr:component>
 
+    <!-- Component Factory Instance, requiring configuration + 1 specific Reference -->
+    <scr:component name="factory.component.reference.targetfilter"
+        enabled="false"
+        configuration-policy="require"
+        factory="factory.component.reference.targetfilter" >
+        <implementation class="org.apache.felix.scr.integration.components.SimpleComponent" />
+        <reference
+            name="ref"
+            interface="org.apache.felix.scr.integration.components.SimpleService"
+            cardinality="1..1"
+            policy="dynamic"
+            bind="bindSimpleService"
+            unbind="unbindSimpleService"
+        />
+    </scr:component>
+
 </components>