Return-Path: X-Original-To: apmail-felix-commits-archive@www.apache.org Delivered-To: apmail-felix-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 564269C08 for ; Fri, 17 Feb 2012 13:28:05 +0000 (UTC) Received: (qmail 48013 invoked by uid 500); 17 Feb 2012 13:28:05 -0000 Delivered-To: apmail-felix-commits-archive@felix.apache.org Received: (qmail 47928 invoked by uid 500); 17 Feb 2012 13:28:04 -0000 Mailing-List: contact commits-help@felix.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@felix.apache.org Delivered-To: mailing list commits@felix.apache.org Received: (qmail 47916 invoked by uid 99); 17 Feb 2012 13:28:04 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 17 Feb 2012 13:28:04 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 17 Feb 2012 13:28:02 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id AFB7C23889B3 for ; Fri, 17 Feb 2012 13:27:42 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1245441 - in /felix/trunk/scr/src: main/java/org/apache/felix/scr/impl/manager/ test/java/org/apache/felix/scr/integration/ test/java/org/apache/felix/scr/integration/components/ test/resources/ Date: Fri, 17 Feb 2012 13:27:42 -0000 To: commits@felix.apache.org From: fmeschbe@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20120217132742.AFB7C23889B3@eris.apache.org> Author: fmeschbe Date: Fri Feb 17 13:27:42 2012 New Revision: 1245441 URL: http://svn.apache.org/viewvc?rev=1245441&view=rev Log: FELIX-3090 Ensure target properties are properly considered when satisfying the ComponentFactory service Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/ComponentFactoryTest.java felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/components/SimpleServiceImpl.java felix/trunk/scr/src/test/resources/integration_test_simple_components.xml Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java?rev=1245441&r1=1245440&r2=1245441&view=diff ============================================================================== --- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java (original) +++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java Fri Feb 17 13:27:42 2012 @@ -22,12 +22,15 @@ import java.util.Dictionary; import java.util.HashMap; import java.util.Hashtable; import java.util.IdentityHashMap; +import java.util.Iterator; +import java.util.List; import java.util.Map; import org.apache.felix.scr.Component; import org.apache.felix.scr.impl.BundleComponentActivator; import org.apache.felix.scr.impl.config.ComponentHolder; import org.apache.felix.scr.impl.metadata.ComponentMetadata; +import org.apache.felix.scr.impl.metadata.ReferenceMetadata; import org.osgi.framework.Constants; import org.osgi.framework.ServiceRegistration; import org.osgi.service.component.ComponentConstants; @@ -169,7 +172,7 @@ public class ComponentFactoryImpl extend { log( LogService.LOG_DEBUG, "registering component factory", null ); - Dictionary serviceProperties = getProperties(); + Dictionary serviceProperties = getServiceProperties(); return getActivator().getBundleContext().registerService( new String[] { ComponentFactory.class.getName() }, getService(), serviceProperties ); } @@ -190,6 +193,25 @@ public class ComponentFactoryImpl extend public Dictionary getProperties() { + Dictionary props = getServiceProperties(); + + // add target properties of references + List depMetaData = getComponentMetadata().getDependencies(); + for ( Iterator di = depMetaData.iterator(); di.hasNext(); ) + { + ReferenceMetadata rm = ( ReferenceMetadata ) di.next(); + if ( rm.getTarget() != null ) + { + props.put( rm.getTargetPropertyName(), rm.getTarget() ); + } + } + + return props; + } + + + public Dictionary getServiceProperties() + { Dictionary props = new Hashtable(); // 112.5.5 The Component Factory service must register with the following properties @@ -404,6 +426,7 @@ public class ComponentFactoryImpl extend //---------- internal + /** * Creates an {@link ImmediateComponentManager} instance with the * {@link BundleComponentActivator} and {@link ComponentMetadata} of this Modified: felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/ComponentFactoryTest.java URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/ComponentFactoryTest.java?rev=1245441&r1=1245440&r2=1245441&view=diff ============================================================================== --- felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/ComponentFactoryTest.java (original) +++ felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/ComponentFactoryTest.java Fri Feb 17 13:27:42 2012 @@ -28,6 +28,7 @@ import junit.framework.TestCase; import org.apache.felix.scr.Component; import org.apache.felix.scr.integration.components.SimpleComponent; +import org.apache.felix.scr.integration.components.SimpleServiceImpl; import org.junit.Test; import org.junit.runner.RunWith; import org.ops4j.pax.exam.junit.JUnit4TestRunner; @@ -488,4 +489,192 @@ public class ComponentFactoryTest extend } } } + + + @Test + public void test_component_factory_reference() throws InvalidSyntaxException + { + final String componentname = "factory.component.reference"; + final String componentfactory = "factory.component.factory.reference"; + + SimpleServiceImpl.create( bundleContext, "ignored" ).setFilterProperty( "ignored" ); + + 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(); + + // missing reference -> unsatisfied + TestCase.assertEquals( Component.STATE_UNSATISFIED, component.getState() ); + TestCase.assertNull( SimpleComponent.INSTANCE ); + + // register a service : filterprop=match + SimpleServiceImpl match = SimpleServiceImpl.create( bundleContext, "required" ).setFilterProperty( "required" ); + 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 ); + + // non-overwrite filterprop + Hashtable props = new Hashtable(); + props.put( PROP_NAME_FACTORY, PROP_NAME_FACTORY ); + 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 ) ); + TestCase.assertEquals( 1, SimpleComponent.INSTANCE.m_multiRef.size() ); + TestCase.assertTrue( SimpleComponent.INSTANCE.m_multiRef.contains( match ) ); + + final Map instanceMap = ( Map ) getFieldValue( component, "m_componentInstances" ); + TestCase.assertNotNull( instanceMap ); + TestCase.assertEquals( 1, instanceMap.size() ); + + final Object instanceManager = getFieldValue( instance, "m_componentManager" ); + TestCase.assertTrue( instanceMap.containsValue( instanceManager ) ); + + // check registered components + final Component[] allFactoryComponents = findComponentsByName( componentname ); + TestCase.assertNotNull( allFactoryComponents ); + TestCase.assertEquals( 2, allFactoryComponents.length ); + for ( int i = 0; i < allFactoryComponents.length; i++ ) + { + final Component c = allFactoryComponents[i]; + if ( c.getId() == component.getId() ) + { + TestCase.assertEquals( Component.STATE_FACTORY, c.getState() ); + } + else if ( c.getId() == SimpleComponent.INSTANCE.m_id ) + { + TestCase.assertEquals( Component.STATE_ACTIVE, c.getState() ); + } + else + { + TestCase.fail( "Unexpected Component " + c ); + } + } + + instance.dispose(); + TestCase.assertNull( SimpleComponent.INSTANCE ); + TestCase.assertNull( instance.getInstance() ); // SCR 112.12.6.2 + + TestCase.assertEquals( 0, instanceMap.size() ); + TestCase.assertFalse( instanceMap.containsValue( instanceManager ) ); + + // overwritten filterprop + Hashtable propsNonMatch = new Hashtable(); + propsNonMatch.put( PROP_NAME_FACTORY, PROP_NAME_FACTORY ); + propsNonMatch.put( "ref.target", "(filterprop=nomatch)" ); + try + { + factory.newInstance( propsNonMatch ); + TestCase.fail( "Missing reference must fail instance creation" ); + } + catch ( ComponentException ce ) + { + // expected + } + + final SimpleServiceImpl noMatch = SimpleServiceImpl.create( bundleContext, "nomatch" ).setFilterProperty( + "nomatch" ); + delay(); + + final ComponentInstance instanceNonMatch = factory.newInstance( propsNonMatch ); + + TestCase.assertNotNull( instanceNonMatch ); + + TestCase.assertNotNull( instanceNonMatch.getInstance() ); + TestCase.assertEquals( SimpleComponent.INSTANCE, instanceNonMatch.getInstance() ); + TestCase.assertEquals( PROP_NAME_FACTORY, SimpleComponent.INSTANCE.getProperty( PROP_NAME_FACTORY ) ); + + TestCase.assertEquals( 1, SimpleComponent.INSTANCE.m_multiRef.size() ); + TestCase.assertTrue( SimpleComponent.INSTANCE.m_multiRef.contains( noMatch ) ); + + // check registered components + final Component[] allFactoryComponents2 = findComponentsByName( componentname ); + TestCase.assertNotNull( allFactoryComponents2 ); + TestCase.assertEquals( 2, allFactoryComponents2.length ); + for ( int i = 0; i < allFactoryComponents2.length; i++ ) + { + final Component c = allFactoryComponents2[i]; + if ( c.getId() == component.getId() ) + { + TestCase.assertEquals( Component.STATE_FACTORY, c.getState() ); + } + else if ( c.getId() == SimpleComponent.INSTANCE.m_id ) + { + TestCase.assertEquals( Component.STATE_ACTIVE, c.getState() ); + } + else + { + TestCase.fail( "Unexpected Component " + c ); + } + } + + match.getRegistration().unregister(); + delay(); + + // check registered components (ComponentFactory aint no longer) + final Component[] allFactoryComponents3 = findComponentsByName( componentname ); + TestCase.assertNotNull( allFactoryComponents3 ); + TestCase.assertEquals( 2, allFactoryComponents3.length ); + for ( int i = 0; i < allFactoryComponents3.length; i++ ) + { + final Component c = allFactoryComponents3[i]; + if ( c.getId() == component.getId() ) + { + TestCase.assertEquals( Component.STATE_UNSATISFIED, c.getState() ); + } + else if ( c.getId() == SimpleComponent.INSTANCE.m_id ) + { + TestCase.assertEquals( Component.STATE_ACTIVE, c.getState() ); + } + else + { + TestCase.fail( "Unexpected Component " + c ); + } + } + + noMatch.getRegistration().unregister(); + delay(); + + // check registered components (ComponentFactory aint no longer) + final Component[] allFactoryComponents4 = findComponentsByName( componentname ); + TestCase.assertNotNull( allFactoryComponents4 ); + TestCase.assertEquals( 1, allFactoryComponents4.length ); + for ( int i = 0; i < allFactoryComponents4.length; i++ ) + { + final Component c = allFactoryComponents4[i]; + if ( c.getId() == component.getId() ) + { + TestCase.assertEquals( Component.STATE_UNSATISFIED, c.getState() ); + } + else + { + TestCase.fail( "Unexpected Component " + c ); + } + } + + // deactivated due to unsatisfied reference + TestCase.assertNull( instanceNonMatch.getInstance() ); + TestCase.assertNull( SimpleComponent.INSTANCE ); + + instanceNonMatch.dispose(); + TestCase.assertNull( SimpleComponent.INSTANCE ); + TestCase.assertNull( instanceNonMatch.getInstance() ); // SCR 112.12.6.2 + } } Modified: felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/components/SimpleServiceImpl.java URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/components/SimpleServiceImpl.java?rev=1245441&r1=1245440&r2=1245441&view=diff ============================================================================== --- felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/components/SimpleServiceImpl.java (original) +++ felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/components/SimpleServiceImpl.java Fri Feb 17 13:27:42 2012 @@ -74,27 +74,29 @@ public class SimpleServiceImpl implement } - public void update( String value ) + public SimpleService update( String value ) { if ( this.m_registration != null ) { this.m_value = value; this.m_registration.setProperties( getProperties() ); } + return this; } - public void setFilterProperty( String filterProp ) + public SimpleServiceImpl setFilterProperty( String filterProp ) { if ( this.m_registration != null ) { this.m_filterProp = filterProp; this.m_registration.setProperties( getProperties() ); } + return this; } - public void drop() + public SimpleServiceImpl drop() { ServiceRegistration sr = getRegistration(); if ( sr != null ) @@ -102,6 +104,7 @@ public class SimpleServiceImpl implement setRegistration( null ); sr.unregister(); } + return this; } @@ -111,9 +114,10 @@ public class SimpleServiceImpl implement } - public void setRegistration( ServiceRegistration registration ) + public SimpleServiceImpl setRegistration( ServiceRegistration registration ) { m_registration = registration; + return this; } Modified: felix/trunk/scr/src/test/resources/integration_test_simple_components.xml URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/test/resources/integration_test_simple_components.xml?rev=1245441&r1=1245440&r2=1245441&view=diff ============================================================================== --- felix/trunk/scr/src/test/resources/integration_test_simple_components.xml (original) +++ felix/trunk/scr/src/test/resources/integration_test_simple_components.xml Fri Feb 17 13:27:42 2012 @@ -104,5 +104,22 @@ factory="factory.component.factory.configuration" > + + + + + +