FELIX-3559 Fix factory components whose newInstances are services referred to by other components

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1371859 13f79535-47bb-0310-9956-ffa450edef68
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 8ad0b8e..e6b1db3 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
@@ -50,7 +50,7 @@
     static
     {
         // uncomment to enable debugging of this test class
-        // paxRunnerVmOption = DEBUG_VM_OPTION;
+//        paxRunnerVmOption = DEBUG_VM_OPTION;
     }
 
 
@@ -517,4 +517,61 @@
 //        TestCase.assertNull( SimpleComponent.INSTANCE );
 //        TestCase.assertNull( instanceNonMatch.getInstance() ); // SCR 112.12.6.2
     }
+
+    @Test
+    public void test_component_factory_referredTo() throws InvalidSyntaxException
+    {
+        //set up the component that refers to the service the factory will create.
+        final String referringComponentName = "ComponentReferringToFactoryObject";
+        final Component referringComponent = findComponentByName( referringComponentName );
+        TestCase.assertNotNull( referringComponent );
+        referringComponent.enable();
+        delay();
+
+        //make sure it's unsatisfied (service is not yet available
+        TestCase.assertEquals( Component.STATE_UNSATISFIED, referringComponent.getState() );
+
+
+        final String componentname = "factory.component.referred";
+        final String componentfactory = "factory.component.factory.referred";
+
+        final Component component = findComponentByName( componentname );
+
+        TestCase.assertNotNull( component );
+        TestCase.assertFalse( component.isDefaultEnabled() );
+
+        TestCase.assertEquals( Component.STATE_DISABLED, component.getState() );
+        TestCase.assertNull( SimpleComponent.INSTANCE );
+
+        component.enable();
+        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 );
+
+        // create the factory instance
+        Hashtable<String, String> props = new Hashtable<String, String>();
+        props.put( "service.pid", "myFactoryInstance" );
+        final ComponentInstance instance = factory.newInstance( props );
+        TestCase.assertNotNull( instance );
+
+        TestCase.assertNotNull( instance.getInstance() );
+
+        //The referring service should now be active
+        TestCase.assertEquals( Component.STATE_ACTIVE, referringComponent.getState() );
+
+        instance.dispose();
+        TestCase.assertNull( instance.getInstance() ); // SCR 112.12.6.2
+
+        //make sure it's unsatisfied (service is no longer available)
+        TestCase.assertEquals( Component.STATE_UNSATISFIED, referringComponent.getState() );
+    }
+
 }
diff --git a/scr/src/test/java/org/apache/felix/scr/integration/components/SimpleServiceImpl.java b/scr/src/test/java/org/apache/felix/scr/integration/components/SimpleServiceImpl.java
index f90d44a..49ac37d 100644
--- a/scr/src/test/java/org/apache/felix/scr/integration/components/SimpleServiceImpl.java
+++ b/scr/src/test/java/org/apache/felix/scr/integration/components/SimpleServiceImpl.java
@@ -52,6 +52,10 @@
         return instance;
     }
 
+    public SimpleServiceImpl()
+    {
+        this("", 0);
+    }
 
     SimpleServiceImpl( final String value, final int ranking )
     {
diff --git a/scr/src/test/resources/integration_test_simple_components.xml b/scr/src/test/resources/integration_test_simple_components.xml
index e1b710d..04f0f9d 100644
--- a/scr/src/test/resources/integration_test_simple_components.xml
+++ b/scr/src/test/resources/integration_test_simple_components.xml
@@ -138,4 +138,31 @@
         />
     </scr:component>
 
+    <!-- Component Factory Instances, instance is referred to by another component -->
+    <scr:component name="factory.component.referred"
+        enabled="false"
+        factory="factory.component.factory.referred" >
+        <implementation class="org.apache.felix.scr.integration.components.SimpleServiceImpl" />
+        <service>
+            <provide interface="org.apache.felix.scr.integration.components.SimpleService" />
+        </service>
+    </scr:component>
+
+    <!-- component has a reference to service created by the factory.component.referred factory component-->
+    <scr:component name="ComponentReferringToFactoryObject"
+        enabled="false"
+        immediate="true">
+        <implementation class="org.apache.felix.scr.integration.components.SimpleComponent" />
+        <property name="service.pid" value="ComponentReferringToFactoryObject" />
+        <reference
+            name="ref"
+            interface="org.apache.felix.scr.integration.components.SimpleService"
+            cardinality="1..1"
+            policy="dynamic"
+            bind="bindSimpleService"
+            unbind="unbindSimpleService"
+            target="(service.pid=myFactoryInstance)"
+        />
+    </scr:component>
+
 </components>