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() {