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>