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/core/pom.xml b/ipojo/core/pom.xml
index 71c838b..2e41ea2 100644
--- a/ipojo/core/pom.xml
+++ b/ipojo/core/pom.xml
@@ -98,7 +98,7 @@
               org.apache.felix.ipojo.parser; version="${ipojo.package.version}",
               org.apache.felix.ipojo.util; version="${ipojo.package.version}",
               org.apache.felix.ipojo.handlers.dependency; version="${ipojo.package.version}",
-              org.apache.felix.ipojo.handlers.providedservice; version="${ipojo.package.version}",
+              org.apache.felix.ipojo.handlers.providedservice.*; version="${ipojo.package.version}",
               org.apache.felix.ipojo.handlers.configuration; version="${ipojo.package.version}",
               org.apache.felix.ipojo.context; version="${ipojo.package.version}",
               org.osgi.service.cm,
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/strategy/ConfigurableCreationStrategy.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/strategy/ConfigurableCreationStrategy.java
new file mode 100644
index 0000000..979f707
--- /dev/null
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/strategy/ConfigurableCreationStrategy.java
@@ -0,0 +1,111 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one or more

+ * contributor license agreements. See the NOTICE file distributed with this

+ * work for additional information regarding copyright ownership. The ASF

+ * licenses this file to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance with the License.

+ * You may obtain a copy of the License at

+ * 

+ * http://www.apache.org/licenses/LICENSE-2.0

+ * 

+ * Unless required by applicable law or agreed to in writing, software

+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT

+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the

+ * License for the specific language governing permissions and limitations under

+ * the License.

+ */

+

+package org.apache.felix.ipojo.handlers.providedservice.strategy;

+

+import java.lang.reflect.Proxy;

+import java.util.Properties;

+

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

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

+import org.apache.felix.ipojo.handlers.providedservice.CreationStrategy;

+import org.osgi.framework.Bundle;

+import org.osgi.framework.BundleContext;

+import org.osgi.framework.ServiceRegistration;

+

+/**

+ * This {@link CreationStrategy} is here to ease customization of the strategy

+ * by hiding all the reflection stuff.

+ */

+public abstract class ConfigurableCreationStrategy extends CreationStrategy {

+

+    /**

+     * The instance manager passed to the iPOJO ServiceFactory to manage

+     * instances.

+     */

+    private InstanceManager manager;

+

+    /**

+     * The lists of interfaces provided by this service.

+     */

+    private String[] specs;

+

+    /**

+     * The iPOJO ServiceFactory

+     */

+    private IPOJOServiceFactory factory;

+

+    public void onPublication(final InstanceManager manager,

+            final String[] specifications, final Properties props) {

+        // Store specifications (aka interfaces)

+        this.specs = specifications;

+        this.manager = manager;

+    }

+

+    public void onUnpublication() {

+        // Try to close the factory

+        if (factory instanceof ServiceObjectFactory) {

+            ((ServiceObjectFactory) factory).close();

+        }

+    }

+

+    public Object getService(final Bundle bundle,

+            final ServiceRegistration registration) {

+        // Init the factory if needed

+        if (factory == null) {

+            factory = getServiceFactory(manager);

+        }

+        // Return a proxy wrapping the real iPOJO ServiceFactory

+        return Proxy.newProxyInstance(manager.getClazz().getClassLoader(),

+                getModifiedSpecifications(manager.getContext()),

+                new ErrorPrintingServiceFactoryProxy(factory));

+    }

+

+    public void ungetService(final Bundle bundle,

+            final ServiceRegistration registration, final Object service) {

+        // Nothing to do

+    }

+

+    /**

+     * Utility method that transform the specifications names into a Class

+     * array, appending the IPOJOServiceFactory interface to it.

+     * @param context used for class loading

+     * @return a array of Class

+     */

+    private Class[] getModifiedSpecifications(final BundleContext context) {

+        Class[] classes = new Class[specs.length + 1];

+        int i = 0;

+        for (i = 0; i < specs.length; i++) {

+            try {

+                classes[i] = context.getBundle().loadClass(specs[i]);

+            } catch (ClassNotFoundException e) {

+                // Should not happen.

+            }

+        }

+        classes[i] = IPOJOServiceFactory.class;

+        return classes;

+    }

+

+    /**

+     * User provided {@link CreationStrategy} MUST implement this method to

+     * provide the real iPOJO ServiceFactory instance.

+     * @param manager {@link InstanceManager} that the factory could use

+     * @return an instance of {@link IPOJOServiceFactory}

+     */

+    protected abstract IPOJOServiceFactory getServiceFactory(

+            final InstanceManager manager);

+}

diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/strategy/ErrorPrintingServiceFactoryProxy.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/strategy/ErrorPrintingServiceFactoryProxy.java
new file mode 100644
index 0000000..d85467e
--- /dev/null
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/strategy/ErrorPrintingServiceFactoryProxy.java
@@ -0,0 +1,94 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+

+package org.apache.felix.ipojo.handlers.providedservice.strategy;

+

+import java.lang.reflect.InvocationHandler;

+import java.lang.reflect.Method;

+

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

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

+

+/**

+ * This proxy class is here to wrap an iPOJO ServiceFactory.

+ * If the consumer of this service do not call the getService or ungetService

+ * methods, it will get an Exception with an explicit error message telling

+ * him that this service is only usable through iPOJO.

+ */

+public class ErrorPrintingServiceFactoryProxy implements InvocationHandler {

+

+	/**

+	 * Wrapped factory.

+	 */

+    private final IPOJOServiceFactory factory;

+

+    /**

+     * getService(ComponentInstance) method.

+     */

+    private static Method GET_METHOD;

+

+    /**

+     * ungetService(ComponentInstance, Object) method.

+     */

+    private static Method UNGET_METHOD;

+

+    static {

+    	// Static initialization of theses constants.

+        try {

+            GET_METHOD = IPOJOServiceFactory.class.getMethod("getService",

+                                                             new Class[]{ComponentInstance.class});

+            UNGET_METHOD = IPOJOServiceFactory.class.getMethod("ungetService",

+                                                               new Class[]{ComponentInstance.class, Object.class});

+        } catch (Exception e) {

+            // Should never happen

+        }

+    }

+

+    /**

+     * Wraps a ServiceFactory in an InvocationHandler that will delegate only

+     * get/ungetService methods to the factory. All other methods will be

+     * rejected with a meaningful error message.

+     *

+     * @param factory delegating iPOJO ServiceFactory

+     */

+    public ErrorPrintingServiceFactoryProxy(final IPOJOServiceFactory factory) {

+        this.factory = factory;

+    }

+

+    public Object invoke(final Object proxy,

+                         final Method method,

+                         final Object[] args) throws Throwable {

+

+        // Handle get/unget operations

+        if (GET_METHOD.equals(method)) {

+            return factory.getService((ComponentInstance) args[0]);

+        }

+        if (UNGET_METHOD.equals(method)) {

+            factory.ungetService((ComponentInstance) args[0], args[1]);

+            return null;

+        }

+

+        // All other methods are rejected

+        throw new UnsupportedOperationException("This service requires an advanced creation policy. "

+                        + "Before calling the service, call the IPOJOServiceFactory.getService(ComponentInstance) "

+                        + "method to get the service object. ");

+

+    }

+

+}

diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/strategy/ServiceObjectFactory.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/strategy/ServiceObjectFactory.java
new file mode 100644
index 0000000..89ac4a2
--- /dev/null
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/strategy/ServiceObjectFactory.java
@@ -0,0 +1,34 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+

+package org.apache.felix.ipojo.handlers.providedservice.strategy;

+

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

+

+/**

+ * Extended iPOJOServiceFactory that supports a close() operation.

+ */

+public interface ServiceObjectFactory extends IPOJOServiceFactory {

+

+    /**

+     * Called when the supporting CreationStrategy is unpublished

+     * from the service registry.

+     */

+    void close();

+}

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>