Add the HandlerFactory interface to avoid the ClassCastException when proxying factories (Issue Felix-552)
As a consequence, the archi command now target this kind of factory.
Some tests have been updated to reflect this change.

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@656044 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/ipojo/core/pom.xml b/ipojo/core/pom.xml
index d561153..803f13b 100644
--- a/ipojo/core/pom.xml
+++ b/ipojo/core/pom.xml
@@ -72,7 +72,7 @@
 						</Bundle-Activator>
 						<IPOJO-Extension>
 							component:org.apache.felix.ipojo.ComponentFactory,
-							handler:org.apache.felix.ipojo.HandlerFactory
+							handler:org.apache.felix.ipojo.HandlerManagerFactory
 						</IPOJO-Extension>
 						<Import-Package>
 							org.osgi.framework, org.osgi.service.cm,
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/HandlerFactory.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/HandlerFactory.java
index 9a10c73..1c30774 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/HandlerFactory.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/HandlerFactory.java
@@ -18,156 +18,45 @@
  */

 package org.apache.felix.ipojo;

 

-import java.util.Dictionary;

-

-import org.apache.felix.ipojo.architecture.ComponentTypeDescription;

-import org.apache.felix.ipojo.metadata.Element;

-import org.osgi.framework.BundleContext;

 

 /**

- * The component factory manages component instance objects. This management

- * consist in creating and managing component instance build with the component

- * factory. This class could export Factory and ManagedServiceFactory services.

- * 

+ * Service interface published by handler factory. 

  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>

  */

-public class HandlerFactory extends ComponentFactory implements Factory {

+public interface HandlerFactory extends Factory {

 

     /**

      * iPOJO Default Namespace.

      */

-    public static final String IPOJO_NAMESPACE = "org.apache.felix.ipojo";

+    String IPOJO_NAMESPACE = "org.apache.felix.ipojo";

 

     /**

-     * Handler type (composite|primitive).

+     * Gets the namespace associated with this handler factory.

+     * @return the namespace used by this handler

      */

-    private final String m_type;

+    String getNamespace();

 

     /**

-     * iPOJO Handler Namespace.

-     * (Set the the iPOJO default namespace is not specified)

+     * Gets the name associated with this handler factory.

+     * @return the name used by this handler

      */

-    private final String m_namespace;

+    String getHandlerName();

 

     /**

-     * Handler start level.

-     * Lower level are priority are configured and started before higher level, and are stopped after. 

+     * Gets the type of created handler.

+     * The handler can only be plugged on instance container with the same type.

+     * Basically, types are primitive and composite.

+     * @return the types of the handler

      */

-    private final int m_level;

+    String getType();

 

     /**

-     * Creates a handler factory.

-     * @param context : bundle context

-     * @param metadata : metadata of the component to create

-     * @throws ConfigurationException occurs when the element describing the factory is malformed.

+     * Gets the start level of the handlers created by this factory.

+     * Handlers with a low start level are configured and started before 

+     * handlers with an higher start level. Moreover, these handlers are

+     * stopped and disposed after.

+     * @return the handler's start level

      */

-    public HandlerFactory(BundleContext context, Element metadata) throws ConfigurationException {

-        super(context, metadata);

+    int getStartLevel();

 

-        // Get the name

-        m_factoryName = metadata.getAttribute("name");

-        if (m_factoryName == null) { throw new ConfigurationException("An Handler needs a name"); }

-

-        // Get the type

-        String type = metadata.getAttribute("type");

-        if (type != null) {

-            m_type = type;

-        } else {

-            m_type = "primitive"; // Set to primitive if not specified.

-        }

-

-        String level = metadata.getAttribute("level");

-        if (level != null) {

-            m_level = new Integer(level).intValue();

-        } else {

-            m_level = Integer.MAX_VALUE; // Set to max if not specified.

-        }

-

-        // Get the namespace

-        String namespace = metadata.getAttribute("namespace");

-        if (namespace != null) {

-            m_namespace = namespace.toLowerCase();

-        } else {

-            m_namespace = IPOJO_NAMESPACE; // Set to the iPOJO default namespace if not specified.

-        }

-    }

-

-    public String getNamespace() {

-        return m_namespace;

-    }

-

-    public String getHandlerName() {

-        return m_namespace + ":" + getName();

-    }

-

-    public String getType() {

-        return m_type;

-    }

-

-    public int getStartLevel() {

-        return m_level;

-    }

-

-    public ComponentTypeDescription getComponentTypeDescription() {

-        return new HandlerTypeDescription(this);

-    }

-

-    /**

-     * Stops the factory.

-     * This method does not disposed created instances.

-     * These instances will be disposed by the instance managers.

-     * This method is called with the lock.

-     */

-    public void stopping() {

-        if (m_tracker != null) {

-            m_tracker.close();

-            m_tracker = null;

-        }

-    }

-

-    /**

-     * Creates an instance. The given configuration needs to contain the 'name'

-     * property. This method is called when holding the lock.

-     * @param configuration : configuration of the created instance.

-     * @param context : the service context to push for this instance.

-     * @param handlers : handler array to used.

-     * @return the created component instance.

-     * not consistent with the component type of this factory.

-     * @throws org.apache.felix.ipojo.ConfigurationException : when the instance configuration failed.

-     * @see org.apache.felix.ipojo.Factory#createComponentInstance(java.util.Dictionary)

-     */

-    public ComponentInstance createInstance(Dictionary configuration, IPojoContext context, HandlerManager[] handlers) throws ConfigurationException {

-        HandlerManager instance = new HandlerManager(this, context, handlers);

-        instance.configure(m_componentMetadata, configuration);

-        return instance;

-    }

-

-    private class HandlerTypeDescription extends ComponentTypeDescription {

-

-        /**

-         * Constructor.

-         * @param factory : factory.

-         */

-        public HandlerTypeDescription(Factory factory) {

-            super(factory);

-        }

-

-        /**

-         * Add properties to publish : 

-         * handler.name, handler.namespace, handler.type and handler.level if the level is not Integer.MAX.

-         * @return return the dictionary to publish.

-         * @see org.apache.felix.ipojo.architecture.ComponentTypeDescription#getPropertiesToPublish()

-         */

-        public Dictionary getPropertiesToPublish() {

-            Dictionary props = super.getPropertiesToPublish();

-

-            props.put(Handler.HANDLER_NAME_PROPERTY, m_factoryName);

-            props.put(Handler.HANDLER_NAMESPACE_PROPERTY, m_namespace);

-            props.put(Handler.HANDLER_TYPE_PROPERTY, m_type);

-            if (m_level != Integer.MAX_VALUE) {

-                props.put(Handler.HANDLER_LEVEL_PROPERTY, new Integer(m_level));

-            }

-            return props;

-        }

-    }

 }

diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoFactory.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoFactory.java
index 87cf4a9..a967e88 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoFactory.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoFactory.java
@@ -503,7 +503,7 @@
         if (m_isPublic) {

             // Exposition of the factory service

             m_sr =

-                    m_context.registerService(new String[] { Factory.class.getName(), ManagedServiceFactory.class.getName() }, this, m_componentDesc

+                    m_context.registerService(m_componentDesc.getFactoryInterfacesToPublish(), this, m_componentDesc

                             .getPropertiesToPublish());

         }

     }

diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/ComponentTypeDescription.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/ComponentTypeDescription.java
index 39081d9..f49390e 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/ComponentTypeDescription.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/ComponentTypeDescription.java
@@ -27,6 +27,7 @@
 import org.apache.felix.ipojo.metadata.Element;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
+import org.osgi.service.cm.ManagedServiceFactory;
 
 /**
  * Component Type description.
@@ -58,7 +59,7 @@
     }
 
     /**
-     * Get a printable form of the current component type description.
+     * Gets a printable form of the current component type description.
      * @return printable form of the component type description
      * @see java.lang.Object#toString()
      */
@@ -67,7 +68,7 @@
     }
 
     /**
-     * Get the implementation class of this component type.
+     * Gets the implementation class of this component type.
      * @return the component type implementation class name.
      */
     public String getClassName() {
@@ -75,7 +76,7 @@
     }
 
     /**
-     * Get component-type properties.
+     * Gets component-type properties.
      * @return the list of configuration properties accepted by the component type type.
      */
     public PropertyDescription[] getProperties() {
@@ -83,7 +84,7 @@
     }
 
     /**
-     * Add a String property in the component type.
+     * Adds a String property in the component type.
      * @param name : property name.
      * @param value : property value.
      */
@@ -92,7 +93,7 @@
     }
     
     /**
-     * Add a String property in the component type.
+     * Adds a String property in the component type.
      * @param name : property name.
      * @param value : property value.
      * @param immutable : the property is immutable.
@@ -103,7 +104,7 @@
     }
 
     /**
-     * Add a configuration properties to the component type.
+     * Adds a configuration properties to the component type.
      * @param pd : the property to add
      */
     public void addProperty(PropertyDescription pd) { //NOPMD remove the instance name of the 'name' property.
@@ -125,7 +126,7 @@
     }
 
     /**
-     * Get the list of provided service offered by instances of this type.
+     * Gets the list of provided service offered by instances of this type.
      * @return the list of the provided service.
      */
     public String[] getprovidedServiceSpecification() {
@@ -133,7 +134,7 @@
     }
 
     /**
-     * Add a provided service to the component type.
+     * Adds a provided service to the component type.
      * @param serviceSpecification : the provided service to add (interface name)
      */
     public void addProvidedServiceSpecification(String serviceSpecification) {
@@ -144,7 +145,7 @@
     }
 
     /**
-     * Return the component-type name.
+     * Returns the component-type name.
      * @return the name of this component type
      */
     public String getName() {
@@ -152,7 +153,7 @@
     }
     
     /**
-     * Compute the default service properties to publish : 
+     * Computes the default service properties to publish : 
      * factory.name, service.pid, component.providedServiceSpecification, component.properties, component.description, factory.State.
      * @return : the dictionary of properties to publish.
      */
@@ -180,10 +181,17 @@
 
     }
     
-    
-
     /**
-     * Get the component type description.
+     * Gets the interfaces published by the factory.
+     * By default publish both {@link Factory} and {@link ManagedServiceFactory}.
+     * @return : the list of interface published by the factory.
+     */
+    public String[] getFactoryInterfacesToPublish() {
+        return new String[] {Factory.class.getName(), ManagedServiceFactory.class.getName()};
+    }
+    
+    /**
+     * Gets the component type description.
      * @return : the description
      */
     public Element getDescription() {