Fix issue FELIX-1885
Simplify how to create a service object policy.


git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@883832 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/ipojo/tests/core/service-providing-strategies/src/main/java/org/apache/felix/ipojo/test/scenarios/component/strategies/DummyCreationStrategy2.java b/ipojo/tests/core/service-providing-strategies/src/main/java/org/apache/felix/ipojo/test/scenarios/component/strategies/DummyCreationStrategy2.java
new file mode 100644
index 0000000..8b2374f
--- /dev/null
+++ b/ipojo/tests/core/service-providing-strategies/src/main/java/org/apache/felix/ipojo/test/scenarios/component/strategies/DummyCreationStrategy2.java
@@ -0,0 +1,15 @@
+package org.apache.felix.ipojo.test.scenarios.component.strategies;

+

+import org.apache.felix.ipojo.IPOJOServiceFactory;

+import org.apache.felix.ipojo.InstanceManager;

+import org.apache.felix.ipojo.handlers.providedservice.strategy.ConfigurableCreationStrategy;

+

+public class DummyCreationStrategy2 extends ConfigurableCreationStrategy {

+

+	protected IPOJOServiceFactory getServiceFactory(InstanceManager manager) {

+		return new DummyServiceFactory(manager);

+	}

+    

+    

+}

+

diff --git a/ipojo/tests/core/service-providing-strategies/src/main/java/org/apache/felix/ipojo/test/scenarios/component/strategies/DummyServiceFactory.java b/ipojo/tests/core/service-providing-strategies/src/main/java/org/apache/felix/ipojo/test/scenarios/component/strategies/DummyServiceFactory.java
new file mode 100644
index 0000000..3c9c24d
--- /dev/null
+++ b/ipojo/tests/core/service-providing-strategies/src/main/java/org/apache/felix/ipojo/test/scenarios/component/strategies/DummyServiceFactory.java
@@ -0,0 +1,61 @@
+package org.apache.felix.ipojo.test.scenarios.component.strategies;

+

+import java.util.Collection;

+import java.util.HashMap;

+import java.util.Iterator;

+import java.util.Map;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.InstanceManager;

+import org.apache.felix.ipojo.handlers.providedservice.strategy.ServiceObjectFactory;

+

+public class DummyServiceFactory implements ServiceObjectFactory {

+

+    /**

+     * Map [ComponentInstance->ServiceObject] storing created service objects.

+     */

+    private Map/*<ComponentInstance, ServiceObject>*/ m_instances = new HashMap();

+    

+    private InstanceManager m_manager;

+

+    public DummyServiceFactory(InstanceManager manager) {

+        m_manager = manager;

+    }

+

+    /**

+     * A service object is required.

+     * This policy returns a service object per asking instance.

+     * @param instance the instance requiring the service object

+     * @return the service object for this instance

+     * @see org.apache.felix.ipojo.IPOJOServiceFactory#getService(org.apache.felix.ipojo.ComponentInstance)

+     */

+    public Object getService(ComponentInstance instance) {

+        Object obj = m_instances.get(instance);

+        if (obj == null) {

+            obj = m_manager.createPojoObject();

+            m_instances.put(instance, obj);

+        }

+        return obj;

+    }

+

+    /**

+     * A service object is unget.

+     * The service object is removed from the map and deleted.

+     * @param instance the instance releasing the service

+     * @param svcObject the service object

+     * @see org.apache.felix.ipojo.IPOJOServiceFactory#ungetService(org.apache.felix.ipojo.ComponentInstance, java.lang.Object)

+     */

+    public void ungetService(ComponentInstance instance, Object svcObject) {

+        Object pojo = m_instances.remove(instance);

+        m_manager.deletePojoObject(pojo);

+    }

+

+    public void close() {

+        Collection col = m_instances.values();

+        Iterator it = col.iterator();

+        while (it.hasNext()) {

+            m_manager.deletePojoObject(it.next());

+        }

+        m_instances.clear();

+    }

+}

diff --git a/ipojo/tests/core/service-providing-strategies/src/main/java/org/apache/felix/ipojo/test/scenarios/ps/strategies/CustomStrategy2Test.java b/ipojo/tests/core/service-providing-strategies/src/main/java/org/apache/felix/ipojo/test/scenarios/ps/strategies/CustomStrategy2Test.java
new file mode 100644
index 0000000..db6bf46
--- /dev/null
+++ b/ipojo/tests/core/service-providing-strategies/src/main/java/org/apache/felix/ipojo/test/scenarios/ps/strategies/CustomStrategy2Test.java
@@ -0,0 +1,201 @@
+package org.apache.felix.ipojo.test.scenarios.ps.strategies;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.PrimitiveInstanceDescription;
+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;
+import org.apache.felix.ipojo.junit4osgi.helpers.IPOJOHelper;
+import org.apache.felix.ipojo.test.scenarios.component.strategies.FooBarProviderType1;
+import org.apache.felix.ipojo.test.scenarios.component.strategies.FooProviderType1;
+import org.apache.felix.ipojo.test.scenarios.ps.service.BarService;
+import org.apache.felix.ipojo.test.scenarios.ps.service.CheckService;
+import org.apache.felix.ipojo.test.scenarios.ps.service.FooService;
+import org.osgi.framework.ServiceReference;
+
+import java.util.Properties;
+
+public class CustomStrategy2Test extends OSGiTestCase {
+
+
+    private IPOJOHelper helper;
+    private ComponentInstance cons1, cons2, prov;
+    private ComponentInstance cons3, prov2;
+
+    public void setUp() {
+        helper = new IPOJOHelper(this);
+        cons1 = helper.createComponentInstance("PSS-Cons");
+        assertEquals("cons1 invalid", ComponentInstance.INVALID, cons1.getState());
+        cons2 = helper.createComponentInstance("PSS-Cons");
+        assertEquals("cons2 invalid", ComponentInstance.INVALID, cons2.getState());
+        prov = helper.createComponentInstance("PSS-FooProviderType-Custom2");
+        prov2 = helper.createComponentInstance("PSS-FooBarProviderType-Custom2");
+        cons3 =  helper.createComponentInstance("PSS-ConsBar");
+        prov2.stop();
+        prov.stop();
+    }
+
+    public void tearDown() {
+        reset();
+    }
+
+
+    private void reset() {
+        FooProviderType1.resetIds();
+        FooBarProviderType1.resetIds();
+    }
+
+    private void checkCreatedObjects(ComponentInstance ci, int expected) {
+        assertEquals("Number of created objects", expected, ((PrimitiveInstanceDescription) ci.getInstanceDescription()).getCreatedObjects().length);
+    }
+
+    public void testOneService() {
+        prov.start();
+        cons2.stop();
+        cons1.stop();
+        assertEquals("Prov valid", ComponentInstance.VALID, prov.getState());
+        ServiceReference ref = helper.getServiceReferenceByName(FooService.class.getName(), prov.getInstanceName());
+        assertNotNull("Service available", ref);
+        checkCreatedObjects(prov, 0);
+
+        // Step 1 : create start one consumer
+        cons1.start();
+        ServiceReference refcons1 = helper.getServiceReferenceByName(CheckService.class.getName(), cons1.getInstanceName());
+        assertNotNull("Cons1 Service available", refcons1);
+
+        CheckService cs_cons1 = (CheckService) getServiceObject(refcons1);
+        Properties props = cs_cons1.getProps();
+        Long id = (Long) props.get("id");
+        FooService fscons1 = (FooService) props.get("object");
+        assertEquals("id 1", 1, id.intValue());
+        checkCreatedObjects(prov, 1);
+
+
+        // Step 2 : create a second consumer
+        cons2.start();
+        ServiceReference refcons2 = helper.getServiceReferenceByName(CheckService.class.getName(), cons2.getInstanceName());
+        assertNotNull("Cons2 Service available", refcons2);
+
+        CheckService cs_cons2 = (CheckService) getServiceObject(refcons2);
+        Properties props2 = cs_cons2.getProps();
+        Long id2 = (Long) props2.get("id");
+        FooService fscons2 = (FooService) props2.get("object");
+        assertEquals("id 2", 2, id2.intValue());
+        checkCreatedObjects(prov, 2);
+
+
+        assertNotSame("Two objects", fscons1, fscons2);
+
+        // Step 3 : stop the second provider
+        System.out.println("cons2 stopping");
+        cons2.stop();
+        System.out.println("cons2 stopped");
+        checkCreatedObjects(prov, 1);
+
+        // Step 4 : stop the first consumer
+        cons1.stop();
+        checkCreatedObjects(prov, 0);
+    }
+
+    public void testObjectCreation() {
+        prov.start();
+
+        // The two consumers are started and use their own objects.
+        ServiceReference refcons1 = helper.getServiceReferenceByName(CheckService.class.getName(), cons1.getInstanceName());
+        assertNotNull("Cons1 Service available", refcons1);
+        CheckService cs_cons1 = (CheckService) getServiceObject(refcons1);
+        Properties props = cs_cons1.getProps();
+        FooService fscons1 = (FooService) props.get("object");
+
+        ServiceReference refcons2 = helper.getServiceReferenceByName(CheckService.class.getName(), cons2.getInstanceName());
+        assertNotNull("Cons2 Service available", refcons2);
+        CheckService cs_cons2 = (CheckService) getServiceObject(refcons2);
+        Properties props2 = cs_cons2.getProps();
+        FooService fscons2 = (FooService) props2.get("object");
+
+        checkCreatedObjects(prov, 2);
+        assertNotSame("Two objects", fscons1, fscons2);
+
+        // Stop the provider
+        prov.stop();
+        // Cons1 and 2 are invalid.
+        assertEquals("Cons1 invalidity", ComponentInstance.INVALID, cons1.getState());
+        assertEquals("Cons2 invalidity", ComponentInstance.INVALID, cons2.getState());
+
+        // No object created in prov
+        checkCreatedObjects(prov, 0);
+
+        // Restart the provider
+        prov.start();
+
+        // Consumers are valid.
+        assertEquals("Cons1 validity", ComponentInstance.VALID, cons1.getState());
+        assertEquals("Cons2 validity", ComponentInstance.VALID, cons2.getState());
+
+        // Check objects
+        refcons1 = helper.getServiceReferenceByName(CheckService.class.getName(), cons1.getInstanceName());
+        assertNotNull("Cons1 Service available", refcons1);
+        cs_cons1 = (CheckService) getServiceObject(refcons1);
+        props = cs_cons1.getProps();
+        Object fscons3 = (FooService) props.get("object");
+
+        refcons2 = helper.getServiceReferenceByName(CheckService.class.getName(), cons2.getInstanceName());
+        assertNotNull("Cons2 Service available", refcons2);
+        cs_cons2 = (CheckService) getServiceObject(refcons2);
+        props2 = cs_cons2.getProps();
+        Object fscons4 = (FooService) props2.get("object");
+
+        checkCreatedObjects(prov, 2);
+        assertNotSame("Two objects", fscons3, fscons4);
+        assertNotSame("Two new objects - 1", fscons3, fscons1);
+        assertNotSame("Two new objects - 2", fscons4, fscons2);
+
+    }
+
+    public void testTwoServices() {
+        cons3.stop();
+        prov2.start();
+        cons1.stop();
+        assertEquals("Prov valid", ComponentInstance.VALID, prov2.getState());
+        ServiceReference ref = helper.getServiceReferenceByName(FooService.class.getName(), prov2.getInstanceName());
+        assertNotNull("Service available", ref);
+        ServiceReference refBar = helper.getServiceReferenceByName(BarService.class.getName(), prov2.getInstanceName());
+        assertNotNull("Service available", refBar);
+        checkCreatedObjects(prov2, 0);
+
+        // Step 1 : create start one consumer
+        cons1.start();
+        ServiceReference refcons1 = helper.getServiceReferenceByName(CheckService.class.getName(), cons1.getInstanceName());
+        assertNotNull("Cons1 Service available", refcons1);
+
+        CheckService cs_cons1 = (CheckService) getServiceObject(refcons1);
+        Properties props = cs_cons1.getProps();
+        Long id = (Long) props.get("id");
+        FooService fscons1 = (FooService) props.get("object");
+        assertEquals("id 1", 1, id.intValue());
+        checkCreatedObjects(prov2, 1);
+
+
+        // Step 2 : create a second consumer
+        cons3.start();
+        ServiceReference refcons2 = helper.getServiceReferenceByName(CheckService.class.getName(), cons3.getInstanceName());
+        assertNotNull("Cons2 Service available", refcons2);
+
+        CheckService cs_cons2 = (CheckService) getServiceObject(refcons2);
+        Properties props2 = cs_cons2.getProps();
+        Long id2 = (Long) props2.get("id");
+        FooService fscons2 = (FooService) props2.get("object");
+        assertEquals("id 2", 2, id2.intValue());
+        checkCreatedObjects(prov2, 2);
+
+
+        assertNotSame("Two objects", fscons1, fscons2);
+
+        // Step 3 : stop the second provider
+        cons3.stop();
+        checkCreatedObjects(prov2, 1);
+
+        // Step 4 : stop the first consumer
+        cons1.stop();
+        checkCreatedObjects(prov, 0);
+    }
+
+}
\ No newline at end of file
diff --git a/ipojo/tests/core/service-providing-strategies/src/main/resources/metadata.xml b/ipojo/tests/core/service-providing-strategies/src/main/resources/metadata.xml
index 21f931b..901cede 100755
--- a/ipojo/tests/core/service-providing-strategies/src/main/resources/metadata.xml
+++ b/ipojo/tests/core/service-providing-strategies/src/main/resources/metadata.xml
@@ -30,17 +30,29 @@
 		<provides strategy="instance"/>

 	</component>

 	

-	<component

-		classname="org.apache.felix.ipojo.test.scenarios.component.strategies.FooProviderType1"

-		name="PSS-FooProviderType-Custom" architecture="true">

-		<provides strategy="org.apache.felix.ipojo.test.scenarios.component.strategies.DummyCreationStrategy"/>

-	</component>

-	

-	<component

-		classname="org.apache.felix.ipojo.test.scenarios.component.strategies.FooBarProviderType1"

-		name="PSS-FooBarProviderType-Custom" architecture="true">

-		<provides strategy="org.apache.felix.ipojo.test.scenarios.component.strategies.DummyCreationStrategy"/>

-	</component>

-	

-	

+    <component

+        classname="org.apache.felix.ipojo.test.scenarios.component.strategies.FooProviderType1"

+        name="PSS-FooProviderType-Custom" architecture="true">

+        <provides strategy="org.apache.felix.ipojo.test.scenarios.component.strategies.DummyCreationStrategy"/>

+    </component>

+

+    <component

+        classname="org.apache.felix.ipojo.test.scenarios.component.strategies.FooBarProviderType1"

+        name="PSS-FooBarProviderType-Custom" architecture="true">

+        <provides strategy="org.apache.felix.ipojo.test.scenarios.component.strategies.DummyCreationStrategy"/>

+    </component>

+

+    <component

+        classname="org.apache.felix.ipojo.test.scenarios.component.strategies.FooProviderType1"

+        name="PSS-FooProviderType-Custom2" architecture="true">

+        <provides strategy="org.apache.felix.ipojo.test.scenarios.component.strategies.DummyCreationStrategy2"/>

+    </component>

+

+    <component

+        classname="org.apache.felix.ipojo.test.scenarios.component.strategies.FooBarProviderType1"

+        name="PSS-FooBarProviderType-Custom2" architecture="true">

+        <provides strategy="org.apache.felix.ipojo.test.scenarios.component.strategies.DummyCreationStrategy2"/>

+    </component>

+

+

 </ipojo>