You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by cl...@apache.org on 2007/09/25 15:27:54 UTC
svn commit: r579239 [1/8] - in /felix/trunk/ipojo: annotations/ ant/ arch/
arch/src/main/java/org/apache/felix/ipojo/arch/ arch/src/main/resources/
core/ core/src/main/java/org/apache/felix/ipojo/
core/src/main/java/org/apache/felix/ipojo/architecture/...
Author: clement
Date: Tue Sep 25 06:27:49 2007
New Revision: 579239
URL: http://svn.apache.org/viewvc?rev=579239&view=rev
Log:
Commit the base of the new iPOJO version.
Added:
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/CompositeFactory.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/ConfigurationException.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/FactoryStateListener.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/HandlerFactory.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/HandlerManager.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/MissingHandlerException.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/PrimitiveHandler.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ExportDescription.java
- copied, changed from r565648, felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportExportDescription.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ExportHandler.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportDescription.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportHandler.java
- copied, changed from r565648, felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportExportHandler.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Tracker.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/util/TrackerCustomizer.java
felix/trunk/ipojo/core/src/main/resources/metadata.xml
Removed:
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/DefaultServiceContext.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportExportDescription.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportExportHandler.java
Modified:
felix/trunk/ipojo/annotations/pom.xml
felix/trunk/ipojo/ant/pom.xml
felix/trunk/ipojo/arch/pom.xml
felix/trunk/ipojo/arch/src/main/java/org/apache/felix/ipojo/arch/ArchCommandImpl.java
felix/trunk/ipojo/arch/src/main/resources/metadata.xml
felix/trunk/ipojo/core/pom.xml
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/ComponentFactory.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/ComponentInstance.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/CompositeHandler.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/CompositeManager.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/Extender.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/Factory.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/Handler.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoConfiguration.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoContext.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceCreator.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceManager.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/PolicyServiceContext.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/ServiceContext.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/ComponentDescription.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/HandlerDescription.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/InstanceDescription.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/CompositeServiceContext.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/FactoryProxy.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/ServiceReferenceImpl.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/ServiceRegistrationImpl.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/ServiceRegistry.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/StringMap.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/architecture/ArchitectureHandler.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/instance/InstanceHandler.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/instance/InstanceHandlerDescription.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ServiceExporter.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ServiceImporter.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorDescription.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorHandler.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/SvcInstance.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/CompositionMetadata.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/POJOWriter.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedService.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandler.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandlerDescription.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/ServiceExporter.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/SpecificationMetadata.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/architecture/ArchitectureHandler.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurableProperty.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyCallback.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandlerDescription.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallback.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallbackHandler.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/controller/ControllerHandler.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/Property.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedService.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandlerDescription.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/ManifestMetadataParser.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/ManipulationMetadata.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Callback.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Logger.java
felix/trunk/ipojo/manipulator/pom.xml
felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/ManipulationProperty.java
felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/Manipulator.java
felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/PojoAdapter.java
felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/Pojoization.java
felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/xml/parser/XMLMetadataParser.java
felix/trunk/ipojo/metadata/pom.xml
felix/trunk/ipojo/metadata/src/main/java/org/apache/felix/ipojo/metadata/Element.java
felix/trunk/ipojo/plugin/pom.xml
Modified: felix/trunk/ipojo/annotations/pom.xml
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/annotations/pom.xml?rev=579239&r1=579238&r2=579239&view=diff
==============================================================================
--- felix/trunk/ipojo/annotations/pom.xml (original)
+++ felix/trunk/ipojo/annotations/pom.xml Tue Sep 25 06:27:49 2007
@@ -9,7 +9,7 @@
<modelVersion>4.0.0</modelVersion>
<artifactId>org.apache.felix.ipojo.annotations</artifactId>
<packaging>bundle</packaging>
- <version>0.7.3-SNAPSHOT</version>
+ <version>0.7.5-SNAPSHOT</version>
<name>iPOJO Annotations</name>
<build>
<plugins>
Modified: felix/trunk/ipojo/ant/pom.xml
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/ant/pom.xml?rev=579239&r1=579238&r2=579239&view=diff
==============================================================================
--- felix/trunk/ipojo/ant/pom.xml (original)
+++ felix/trunk/ipojo/ant/pom.xml Tue Sep 25 06:27:49 2007
@@ -9,18 +9,18 @@
<modelVersion>4.0.0</modelVersion>
<artifactId>org.apache.felix.ipojo.ant</artifactId>
<packaging>bundle</packaging>
- <version>0.7.3-SNAPSHOT</version>
+ <version>0.7.5-SNAPSHOT</version>
<name>iPOJO Ant Task</name>
<dependencies>
<dependency>
<groupId>${pom.groupId}</groupId>
<artifactId>org.apache.felix.ipojo.metadata</artifactId>
- <version>0.7.3-SNAPSHOT</version>
+ <version>0.7.5-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>${pom.groupId}</groupId>
<artifactId>org.apache.felix.ipojo.manipulator</artifactId>
- <version>0.7.3-SNAPSHOT</version>
+ <version>0.7.5-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>xerces</groupId>
Modified: felix/trunk/ipojo/arch/pom.xml
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/arch/pom.xml?rev=579239&r1=579238&r2=579239&view=diff
==============================================================================
--- felix/trunk/ipojo/arch/pom.xml (original)
+++ felix/trunk/ipojo/arch/pom.xml Tue Sep 25 06:27:49 2007
@@ -8,7 +8,7 @@
<modelVersion>4.0.0</modelVersion>
<packaging>bundle</packaging>
<name>Apache Felix iPOJO Arch Command</name>
- <version>0.7.3-SNAPSHOT</version>
+ <version>0.7.5-SNAPSHOT</version>
<artifactId>org.apache.felix.ipojo.arch</artifactId>
<dependencies>
<dependency>
Modified: felix/trunk/ipojo/arch/src/main/java/org/apache/felix/ipojo/arch/ArchCommandImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/arch/src/main/java/org/apache/felix/ipojo/arch/ArchCommandImpl.java?rev=579239&r1=579238&r2=579239&view=diff
==============================================================================
--- felix/trunk/ipojo/arch/src/main/java/org/apache/felix/ipojo/arch/ArchCommandImpl.java (original)
+++ felix/trunk/ipojo/arch/src/main/java/org/apache/felix/ipojo/arch/ArchCommandImpl.java Tue Sep 25 06:27:49 2007
@@ -22,6 +22,7 @@
import org.apache.felix.ipojo.ComponentInstance;
import org.apache.felix.ipojo.Factory;
+import org.apache.felix.ipojo.HandlerFactory;
import org.apache.felix.ipojo.architecture.Architecture;
import org.apache.felix.ipojo.architecture.InstanceDescription;
import org.apache.felix.shell.Command;
@@ -42,6 +43,12 @@
* Factory services.
*/
private Factory[] m_factories;
+
+
+ /**
+ * Handler Factories.
+ */
+ private Factory[] m_handlers;
/**
* Get the command name.
@@ -58,7 +65,7 @@
* @see org.apache.felix.shell.Command#getUsage()
*/
public String getUsage() {
- return "arch [-factories] [-instances] [-factory factory_name] [-instance instance_name]";
+ return "arch [-factories] [-instances] [-handlers] [-factory factory_name] [-instance instance_name]";
}
/**
@@ -78,39 +85,43 @@
* @see org.apache.felix.shell.Command#execute(java.lang.String, java.io.PrintStream, java.io.PrintStream)
*/
public void execute(String line, PrintStream out, PrintStream err) {
- synchronized (this) {
- String line2 = line.substring("arch".length()).trim();
-
- if (line2.equalsIgnoreCase("-instances") || line2.length() == 0) {
- printInstances(out);
- return;
- }
-
- if (line2.equalsIgnoreCase("-factories")) {
- printFactories(out);
- return;
- }
-
- if (line2.startsWith("-factory")) {
- String name = line2.substring("-factory".length()).trim();
- printFactory(name, out, err);
- return;
- }
-
- if (line2.startsWith("-instance")) {
- String name = line2.substring("-instance".length()).trim();
- printInstance(name, out, err);
- return;
- }
-
- err.println(getUsage());
+ String line2 = line.substring("arch".length()).trim();
+
+ if (line2.equalsIgnoreCase("-instances") || line2.length() == 0) {
+ printInstances(out);
+ return;
+ }
+
+ if (line2.equalsIgnoreCase("-factories")) {
+ printFactories(out);
+ return;
}
+ if (line2.startsWith("-factory")) {
+ String name = line2.substring("-factory".length()).trim();
+ printFactory(name, out, err);
+ return;
+ }
+
+ if (line2.startsWith("-instance")) {
+ String name = line2.substring("-instance".length()).trim();
+ printInstance(name, out, err);
+ return;
+ }
+
+ if (line2.startsWith("-handlers")) {
+ printHandlers(out);
+ return;
+ }
+
+ err.println(getUsage());
}
/**
* Print instance list.
- * @param out : default print stream
+ *
+ * @param out :
+ * default print stream
*/
private void printInstances(PrintStream out) {
for (int i = 0; i < m_archs.length; i++) {
@@ -150,7 +161,11 @@
*/
private void printFactories(PrintStream out) {
for (int i = 0; i < m_factories.length; i++) {
- out.println("Factory " + m_factories[i].getName());
+ if (m_factories[i].getMissingHandlers().size() == 0) {
+ out.println("Factory " + m_factories[i].getName() + " (VALID)");
+ } else {
+ out.println("Factory " + m_factories[i].getName() + " (INVALID : " + m_factories[i].getMissingHandlers() + ")");
+ }
}
}
@@ -168,5 +183,24 @@
}
}
err.println("Factory " + name + " not found");
+ }
+
+ /**
+ * Print the list of available handlers (and validity).
+ * @param out : default print stream
+ */
+ private void printHandlers(PrintStream out) {
+ for (int i = 0; i < m_handlers.length; i++) {
+ HandlerFactory hf = (HandlerFactory) m_handlers[i];
+ String name = hf.getHandlerName();
+ if ("composite".equals(hf.getType())) {
+ name = name + " [composite]";
+ }
+ if (hf.getMissingHandlers().size() == 0) {
+ out.println("Handler " + name + " (VALID)");
+ } else {
+ out.println("Handler " + name + " (INVALID : " + hf.getMissingHandlers() + ")");
+ }
+ }
}
}
Modified: felix/trunk/ipojo/arch/src/main/resources/metadata.xml
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/arch/src/main/resources/metadata.xml?rev=579239&r1=579238&r2=579239&view=diff
==============================================================================
--- felix/trunk/ipojo/arch/src/main/resources/metadata.xml (original)
+++ felix/trunk/ipojo/arch/src/main/resources/metadata.xml Tue Sep 25 06:27:49 2007
@@ -3,7 +3,8 @@
<Component className="org.apache.felix.ipojo.arch.ArchCommandImpl">
<Provides/>
<Requires field="m_archs" optional="true"/>
- <Requires field="m_factories" optional="true"/>
+ <Requires field="m_factories" optional="true" filter="(!(handler.name=*))"/>
+ <Requires field="m_handlers" optional="true" filter="(handler.name=*)"/>
</Component>
<instance component="org.apache.felix.ipojo.arch.ArchCommandImpl" name="ArchCommand"/>
</iPOJO>
Modified: felix/trunk/ipojo/core/pom.xml
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/pom.xml?rev=579239&r1=579238&r2=579239&view=diff
==============================================================================
--- felix/trunk/ipojo/core/pom.xml (original)
+++ felix/trunk/ipojo/core/pom.xml Tue Sep 25 06:27:49 2007
@@ -9,7 +9,7 @@
<packaging>bundle</packaging>
<name>Apache Felix iPOJO</name>
<artifactId>org.apache.felix.ipojo</artifactId>
- <version>0.7.3-SNAPSHOT</version>
+ <version>0.7.5-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>${pom.groupId}</groupId>
@@ -24,12 +24,12 @@
<dependency>
<groupId>${pom.groupId}</groupId>
<artifactId>org.apache.felix.ipojo.metadata</artifactId>
- <version>0.7.3-SNAPSHOT</version>
+ <version>0.7.5-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>${pom.groupId}</groupId>
<artifactId>org.apache.felix.ipojo.manipulator</artifactId>
- <version>0.7.3-SNAPSHOT</version>
+ <version>0.7.5-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
@@ -64,19 +64,35 @@
org.objectweb.asm*;-split-package:=merge-first
</Private-Package>
<Export-Package>
- org.apache.felix.ipojo; version="0.7.3",
- org.apache.felix.ipojo.metadata; version="0.7.3",
- org.apache.felix.ipojo.architecture; version="0.7.3",
- org.apache.felix.ipojo.parser; version="0.7.3",
- org.apache.felix.ipojo.util; version="0.7.3",
- org.apache.felix.ipojo.handlers.dependency; version="0.7.3",
- org.apache.felix.ipojo.handlers.providedservice; version="0.7.3",
- org.apache.felix.ipojo.composite; version="0.7.3",
+ org.apache.felix.ipojo; version="0.7.5",
+ org.apache.felix.ipojo.metadata; version="0.7.5",
+ org.apache.felix.ipojo.architecture; version="0.7.5",
+ org.apache.felix.ipojo.parser; version="0.7.5",
+ org.apache.felix.ipojo.util; version="0.7.5",
+ org.apache.felix.ipojo.handlers.dependency; version="0.7.5",
+ org.apache.felix.ipojo.handlers.providedservice; version="0.7.5",
+ org.apache.felix.ipojo.composite; version="0.7.5",
org.osgi.service.cm,
org.osgi.service.log
</Export-Package>
+ <_donotcopy>(CVS|.svn|.+.bak|~.+|metadata.xml)</_donotcopy>
</instructions>
</configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.apache.felix.ipojo.plugin</artifactId>
+ <version>${pom.version}</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>ipojo-bundle</goal>
+ </goals>
+ <configuration>
+ <metadata>metadata.xml</metadata>
+ </configuration>
+ </execution>
+ </executions>
</plugin>
</plugins>
</build>
Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/ComponentFactory.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/ComponentFactory.java?rev=579239&r1=579238&r2=579239&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/ComponentFactory.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/ComponentFactory.java Tue Sep 25 06:27:49 2007
@@ -33,8 +33,12 @@
import org.apache.felix.ipojo.architecture.PropertyDescription;
import org.apache.felix.ipojo.metadata.Element;
import org.apache.felix.ipojo.util.Logger;
+import org.apache.felix.ipojo.util.Tracker;
+import org.apache.felix.ipojo.util.TrackerCustomizer;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.cm.ConfigurationException;
import org.osgi.service.cm.ManagedServiceFactory;
@@ -46,167 +50,125 @@
*
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
-public class ComponentFactory implements Factory, ManagedServiceFactory {
+public class ComponentFactory implements Factory, ManagedServiceFactory, TrackerCustomizer {
/**
* List of the managed instance name. This list is shared by all factories.
*/
- private static List m_instancesName = new ArrayList();
+ protected static List m_instancesName = new ArrayList();
+
+ /**
+ * Component-Type description exposed by the factory service.
+ */
+ protected ComponentDescription m_componentDesc;
/**
* List of the managed instance managers. The key of this map is the
- * name (i.e. PID) of the created instance
+ * name (i.e. instance names) of the created instance
*/
- private Map m_componentInstances = new HashMap();
-
-
+ protected Map m_componentInstances = new HashMap();
+
/**
- * True if the component is a composition.
+ * Component Type provided by this factory.
*/
- private boolean m_isComposite = false;
-
+ protected Element m_componentMetadata;
+
/**
* The bundle context reference.
*/
- private BundleContext m_context = null;
-
+ protected BundleContext m_context = null;
+
/**
- * Component Implementation class.
+ * Factory Name. Could be the component class name if the
+ * factory name is not set.
*/
- private byte[] m_clazz = null;
+ protected String m_factoryName;
/**
- * Component Implementation Class Name.
+ * List of required handler.
*/
- private String m_componentClassName = null;
+ protected List m_handlerIdentifiers = new ArrayList();
/**
- * Composition Name.
+ * List of listeners.
*/
- private String m_typeName = null;
-
+ protected List m_listeners = new ArrayList(5);
+
/**
- * Class loader to delegate loading.
+ * Logger for the factory (and all component instance).
*/
- private FactoryClassloader m_classLoader = null;
+ protected Logger m_logger;
/**
- * Component Type provided by this factory. //TODO Should we keep this ?
- * reference ?
+ * Factory state.
*/
- private Element m_componentMetadata;
+ protected int m_state = Factory.INVALID;
/**
- * Factory Name (i.e. Factory PID). Could be the component class name if the
- * factory name is not set.
+ * Tracker used to track required handler factories.
*/
- private String m_factoryName;
-
+ protected Tracker m_tracker;
+
/**
- * Service Registration of this factory (Factory & ManagedServiceFactory).
+ * Component Type Name.
*/
- private ServiceRegistration m_sr;
+ protected String m_typeName = null;
/**
- * Component-Type description exposed by the factory service.
+ * Class loader to delegate loading.
*/
- private ComponentDescription m_componentDesc;
-
+ private FactoryClassloader m_classLoader = null;
+
/**
- * Logger for the factory (and all component instance).
+ * Component Implementation class.
+ */
+ private byte[] m_clazz = null;
+
+ /**
+ * Component Implementation Class Name.
*/
- private Logger m_logger;
+ private String m_componentClassName = null;
/**
* Index used to generate instance name if not set.
*/
private long m_index = 0;
-
+
/**
- * FactoryClassloader.
+ * Service Registration of this factory (Factory & ManagedServiceFactory).
*/
- private class FactoryClassloader extends ClassLoader {
-
- /**
- * Map of defined classes [Name, Class Object].
- */
- private Map m_definedClasses = new HashMap();
-
- /**
- * load the class.
- *
- * @see java.lang.ClassLoader#loadClass(java.lang.String, boolean)
- * @param name : the name of the class
- * @param resolve : should be the class resolve now ?
- * @return : the loaded class
- * @throws ClassNotFoundException : the class to load is not found
- */
- protected synchronized Class loadClass(final String name, final boolean resolve) throws ClassNotFoundException {
- return m_context.getBundle().loadClass(name);
- }
-
- /**
- * Return the URL of the asked resource.
- *
- * @param arg : the name of the resource to find.
- * @return the URL of the resource.
- * @see java.lang.ClassLoader#getResource(java.lang.String)
- */
- public URL getResource(String arg) {
- return m_context.getBundle().getResource(arg);
- }
-
- /**
- * The defineClass method.
- *
- * @param name : name of the class
- * @param b : the byte array of the class
- * @param domain : the protection domain
- * @return : the defined class.
- * @throws Exception : if a problem is detected during the loading
- */
- public Class defineClass(String name, byte[] b, ProtectionDomain domain) throws Exception {
- if (m_definedClasses.containsKey(name)) {
- return (Class) m_definedClasses.get(name);
- }
- final Class c = super.defineClass(name, b, 0, b.length, domain);
- m_definedClasses.put(name, c);
- return c;
- }
+ private ServiceRegistration m_sr;
+
+ /**
+ * Create a instance manager factory. The class is given in parameter. The
+ * component type is not a composite.
+ * @param bc : bundle context
+ * @param clazz : the component class
+ * @param cm : metadata of the component
+ */
+ public ComponentFactory(BundleContext bc, byte[] clazz, Element cm) {
+ this(bc, cm);
+ m_clazz = clazz;
}
-
+
/**
* Create a instance manager factory.
- *
* @param bc : bundle context
* @param cm : metadata of the component to create
*/
public ComponentFactory(BundleContext bc, Element cm) {
m_context = bc;
m_componentMetadata = cm;
- if (cm.getName().equalsIgnoreCase("composite")) {
- m_componentClassName = null;
- m_isComposite = true;
- // Get the name
- if (cm.containsAttribute("name")) {
- m_typeName = cm.getAttribute("name");
- } else {
- System.err.println("A composite needs a name");
- return;
- }
- } else {
- if (cm.containsAttribute("className")) {
- m_componentClassName = cm.getAttribute("className");
- } else {
- System.err.println("A component needs a class name");
- return;
- }
- // Get the name
- if (cm.containsAttribute("name")) {
- m_typeName = cm.getAttribute("name");
- }
+
+ if (! check(cm)) {
+ return;
}
+ // Get the name
+ if (cm.containsAttribute("name")) {
+ m_typeName = cm.getAttribute("name");
+ }
+
if (m_typeName != null) {
m_logger = new Logger(m_context, m_typeName, Logger.WARNING);
} else {
@@ -214,201 +176,265 @@
}
computeFactoryName();
+ computeRequiredHandlers();
}
/**
- * Create a instance manager factory. The class is given in parameter. The
- * component type is not a composite.
- *
- * @param bc : bundle context
- * @param clazz : the component class
- * @param cm : metadata of the component
+ * Add a factory listener.
+ * @param l : the factory listener to add
+ * @see org.apache.felix.ipojo.Factory#addFactoryStateListener(org.apache.felix.ipojo.FactoryStateListener)
*/
- public ComponentFactory(BundleContext bc, byte[] clazz, Element cm) {
- m_context = bc;
- m_clazz = clazz;
- m_componentClassName = cm.getAttribute("className");
- m_componentMetadata = cm;
-
- // Get the name
- if (cm.containsAttribute("name")) {
- m_typeName = cm.getAttribute("name");
- m_logger = new Logger(m_context, m_typeName, Logger.WARNING);
- } else {
- m_logger = new Logger(m_context, m_componentClassName, Logger.WARNING);
+ public void addFactoryStateListener(FactoryStateListener l) {
+ synchronized (m_listeners) {
+ m_listeners.add(l);
}
-
- computeFactoryName();
+ // TODO do we need to notify the actual state of the factory to the new listener ?
}
/**
- * Return the bundle context.
- *
- * @return the Bundle Context.
+ * A new handler factory is detected.
+ * Test if the factory can be used or not.
+ * @param reference : the new service reference.
+ * @return true if the given factory reference match with a required handler.
+ * @see org.apache.felix.ipojo.util.TrackerCustomizer#addingService(org.osgi.framework.ServiceReference)
*/
- protected BundleContext getBundleContext() {
- return m_context;
- }
-
- protected String getComponentTypeName() {
- return m_typeName;
+ public boolean addingService(ServiceReference reference) {
+ for (int i = 0; i < m_handlerIdentifiers.size(); i++) {
+ HandlerIdentifier hi = (HandlerIdentifier) m_handlerIdentifiers.get(i);
+ if (hi.m_reference == null && match(hi, reference)) {
+ hi.setReference(reference);
+ computeFactoryState();
+ return true;
+ }
+ }
+ return false;
}
/**
- * Get the implementation class of the component type.
- *
- * @return the name of the component-type implementation class.
+ * Check method : allow a factory to check if given element are correct.
+ * A component factory metadata are correct if they contain the 'classname' attribute.
+ * @param cm : the metadata
+ * @return true if the metadata are correct
*/
- protected String getComponentClassName() {
- return m_componentClassName;
+ public boolean check(Element cm) {
+ if (cm.containsAttribute("className")) {
+ m_componentClassName = cm.getAttribute("className");
+ return true;
+ } else {
+ System.err.println("A component needs a class name : " + cm);
+ return false;
+ }
}
/**
- * Get the logger used by instances of he current factory.
- *
- * @return the factory logger.
+ * Create an instance. The given configuration needs to contain the 'name'
+ * property.
+ * @param configuration : configuration of the created instance.
+ * @return the created component instance.
+ * @throws UnacceptableConfiguration : occurs if the given configuration is
+ * not consistent with the component type of this factory.
+ * @throws MissingHandlerException : occurs if an handler is unavailable when the instance is created.
+ * @throws org.apache.felix.ipojo.ConfigurationException : occurs when the instance or type configuration are not correct.
+ * @see org.apache.felix.ipojo.Factory#createComponentInstance(java.util.Dictionary)
*/
- public Logger getLogger() {
- return m_logger;
+ public synchronized ComponentInstance createComponentInstance(Dictionary configuration) throws UnacceptableConfiguration, MissingHandlerException, org.apache.felix.ipojo.ConfigurationException {
+ return createComponentInstance(configuration, null);
}
/**
- * Compute the factory name.
- */
- private void computeFactoryName() {
- if (m_componentMetadata.containsAttribute("factory")) {
- // DEPRECATED BLOCK
- if (m_componentMetadata.getAttribute("factory").equalsIgnoreCase("no")) {
- m_logger.log(Logger.WARNING, "'factory=no' is deprecated, Please use 'factory=false' instead of 'factory='no'");
- m_factoryName = null;
- return;
- }
- // END OF DEPRECATED BLOCK
- if (m_componentMetadata.getAttribute("factory").equalsIgnoreCase("false")) {
- m_factoryName = null;
- return;
- }
- if (m_componentMetadata.getAttribute("factory").equalsIgnoreCase("true")) {
- if (m_typeName == null) { //m_typeName is necessary set for composite.
- m_factoryName = m_componentMetadata.getAttribute("className");
- } else {
- m_factoryName = m_typeName;
- }
- return;
- }
- // factory is set with the factory name
- m_factoryName = m_componentMetadata.getAttribute("factory");
- return;
- } else {
- if (m_typeName == null) { //m_typeName is necessary set for composite.
- m_factoryName = m_componentMetadata.getAttribute("className");
- } else {
- m_factoryName = m_typeName;
- }
- return;
- }
- }
-
- /**
- * Stop all the instance managers.
+ * Create an instance. The given configuration needs to contain the 'name'
+ * property.
+ * @param configuration : configuration of the created instance.
+ * @param serviceContext : the service context to push for this instance.
+ * @return the created component instance.
+ * @throws UnacceptableConfiguration : occurs if the given configuration is
+ * not consistent with the component type of this factory.
+ * @throws MissingHandlerException : occurs when an handler is unavailable when creating the instance.
+ * @throws org.apache.felix.ipojo.ConfigurationException : when the instance configuration failed.
+ * @see org.apache.felix.ipojo.Factory#createComponentInstance(java.util.Dictionary)
*/
- public synchronized void stop() {
- final Collection col = m_componentInstances.values();
- final Iterator it = col.iterator();
- while (it.hasNext()) {
- final ComponentInstance ci = (ComponentInstance) it.next();
- if (ci.isStarted()) {
- if (ci instanceof CompositeManager) {
- ((CompositeManager) ci).kill();
- } else {
- ((InstanceManager) ci).kill();
- }
- }
- m_instancesName.remove(ci.getInstanceName());
+ public ComponentInstance createComponentInstance(Dictionary configuration, ServiceContext serviceContext) throws UnacceptableConfiguration, MissingHandlerException, org.apache.felix.ipojo.ConfigurationException {
+ if (m_state == INVALID) {
+ throw new MissingHandlerException(getMissingHandlers());
}
- m_componentInstances.clear();
- if (m_sr != null) {
- m_sr.unregister();
+ if (configuration == null) {
+ configuration = new Properties();
}
- m_sr = null;
- m_componentDesc = null;
- }
-
- /**
- * Start all the instance managers.
- */
- public synchronized void start() {
- if (m_componentDesc != null) { // Already started.
- return;
+
+ try {
+ checkAcceptability(configuration);
+ } catch (UnacceptableConfiguration e) {
+ m_logger.log(Logger.ERROR, "The configuration is not acceptable : " + e.getMessage());
+ throw new UnacceptableConfiguration("The configuration " + configuration + " is not acceptable for " + m_factoryName + ": " + e.getMessage());
}
- final Properties props = new Properties();
- // create a ghost component
- if (!m_isComposite) {
- final InstanceManager ghost = new InstanceManager(this, new IPojoContext(m_context));
- final Properties p = new Properties();
- p.put("name", "ghost");
- ghost.configure(m_componentMetadata, p);
- m_componentDesc = ghost.getComponentDescription();
+
+ String n = null;
+ if (configuration.get("name") != null) {
+ n = (String) configuration.get("name");
} else {
- final CompositeManager ghost = new CompositeManager(this, new IPojoContext(m_context));
- final Properties p = new Properties();
- p.put("name", "ghost");
- ghost.configure(m_componentMetadata, p);
- m_componentDesc = ghost.getComponentDescription();
+ n = generateName();
+ configuration.put("name", n);
}
-
- // Check if the factory should be exposed
- if (m_factoryName == null) {
- return;
+
+ if (m_instancesName.contains(n)) {
+ throw new UnacceptableConfiguration("Name already used : " + n);
+ } else {
+ m_instancesName.add(n);
}
- if (!m_isComposite) {
- props.put("component.class", m_componentClassName);
+ BundleContext context = null;
+ if (serviceContext == null) {
+ context = new IPojoContext(m_context);
} else {
- props.put("component.class", "no implementation class");
+ context = new IPojoContext(m_context, serviceContext);
}
- props.put("factory.name", m_factoryName);
- if (m_typeName != null) {
- props.put("component.type", m_typeName);
+ List handlers = new ArrayList();
+ for (int i = 0; i < m_handlerIdentifiers.size(); i++) {
+ HandlerIdentifier hi = (HandlerIdentifier) m_handlerIdentifiers.get(i);
+ handlers.add(getHandlerInstance(hi, serviceContext));
}
- props.put("component.providedServiceSpecifications", m_componentDesc.getprovidedServiceSpecification());
- props.put("component.properties", m_componentDesc.getProperties());
- props.put("component.description", m_componentDesc);
- props.put("component.desc", m_componentDesc.toString());
+ InstanceManager instance = new InstanceManager(this, context, (HandlerManager[]) handlers.toArray(new HandlerManager[0]));
+ instance.configure(m_componentMetadata, configuration);
- // Add Factory PID to the component properties
- props.put(Constants.SERVICE_PID, m_factoryName);
-
- // Exposition of the factory service
- m_sr = m_context.registerService(new String[] { Factory.class.getName(), ManagedServiceFactory.class.getName() }, this, props);
+ m_componentInstances.put(n, instance);
+ instance.start();
+ return instance;
}
/**
- * Callback called by instance when disposed.
- *
- * @param ci : the destroyed instance
- */
- protected synchronized void disposed(ComponentInstance ci) {
- m_instancesName.remove(ci.getInstanceName());
- m_componentInstances.remove(ci.getInstanceName());
+ * Define a class.
+ * @param name : qualified name of the class
+ * @param b : byte array of the class
+ * @param domain : protection domain of the class
+ * @return the defined class object
+ * @throws Exception : an exception occur during the definition
+ */
+ public Class defineClass(String name, byte[] b, ProtectionDomain domain) throws Exception {
+ if (m_classLoader == null) {
+ m_classLoader = new FactoryClassloader();
+ }
+ return m_classLoader.defineClass(name, b, domain);
+ }
+
+ /**
+ * Delete an instance.
+ * @param in : name of the instance to delete
+ * @see org.osgi.service.cm.ManagedServiceFactory#deleted(java.lang.String)
+ */
+ public synchronized void deleted(String in) {
+ m_instancesName.remove(in);
+ final ComponentInstance cm = (ComponentInstance) m_componentInstances.remove(in);
+ if (cm == null) {
+ return; // do nothing, the component does not exist !
+ } else {
+ cm.dispose();
+ }
+ }
+
+ /**
+ * Get the component type description.
+ * @return the component type description object. Null if not already computed.
+ */
+ public ComponentDescription getComponentDescription() {
+ return m_componentDesc;
}
/**
* Get the component type description attached to this factory.
- *
* @return : the component type description
* @see org.apache.felix.ipojo.Factory#getDescription()
*/
public Element getDescription() {
+ if (m_componentDesc == null) { return new Element("No description available for " + getName(), ""); }
return m_componentDesc.getDescription();
}
+
+ /**
+ * Get the logger used by instances of he current factory.
+ * @return the factory logger.
+ */
+ public Logger getLogger() {
+ return m_logger;
+ }
+
+ /**
+ * Get the list of missing handlers.
+ * @return the list of missing handlers (namespace:name)
+ * @see org.apache.felix.ipojo.Factory#getMissingHandlers()
+ */
+ public List getMissingHandlers() {
+ List l = new ArrayList();
+ for (int i = 0; i < m_handlerIdentifiers.size(); i++) {
+ HandlerIdentifier hi = (HandlerIdentifier) m_handlerIdentifiers.get(i);
+ if (hi.m_reference == null) {
+ l.add(hi.getFullName());
+ }
+ }
+ return l;
+ }
/**
- * Load a class.
+ * Get the name of this factory.
*
+ * @return the name of this factory
+ * @see org.apache.felix.ipojo.Factory#getName()
+ */
+ public String getName() {
+ if (m_factoryName != null) {
+ return m_factoryName;
+ } else if (m_typeName != null) {
+ return m_typeName;
+ } else {
+ return m_componentClassName;
+ }
+ }
+
+ /**
+ * Get the list of required handlers.
+ * @return the list of required handlers (namespace:name)
+ * @see org.apache.felix.ipojo.Factory#getRequiredHandlers()
+ */
+ public List getRequiredHandlers() {
+ List l = new ArrayList();
+ for (int i = 0; i < m_handlerIdentifiers.size(); i++) {
+ HandlerIdentifier hi = (HandlerIdentifier) m_handlerIdentifiers.get(i);
+ l.add(hi.getFullName());
+ }
+ return l;
+ }
+
+ /**
+ * Return the URL of a resource.
+ * @param resName : resource name
+ * @return the URL of the resource
+ */
+ public URL getResource(String resName) {
+ return m_context.getBundle().getResource(resName);
+ }
+
+ /**
+ * Check if the given configuration is acceptable as a component instance
+ * configuration. This method checks that if all the configurable properties
+ * have a value.
+ * @param conf : the configuration to check
+ * @return true when the configuration seems to be acceptable
+ */
+ public boolean isAcceptable(Dictionary conf) {
+ try {
+ checkAcceptability(conf);
+ } catch (UnacceptableConfiguration e) {
+ return false;
+ } catch (MissingHandlerException e) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Load a class.
* @param className : name of the class to load
* @return the resulting Class object
* @throws ClassNotFoundException : happen when the class is not found
@@ -430,279 +456,603 @@
}
/**
- * Define a class.
- *
- * @param name : qualified name of the class
- * @param b : byte array of the class
- * @param domain : protection domain of the class
- * @return the defined class object
- * @throws Exception : an exception occur during the definition
- */
- public Class defineClass(String name, byte[] b, ProtectionDomain domain) throws Exception {
- if (m_classLoader == null) {
- m_classLoader = new FactoryClassloader();
- }
- return m_classLoader.defineClass(name, b, domain);
- }
-
- /**
- * Return the URL of a resource.
- *
- * @param resName : resource name
- * @return the URL of the resource
+ * A used handler factory is modified.
+ * @param reference : the service reference
+ * @param service : the Factory object (if already get)
+ * @see org.apache.felix.ipojo.util.TrackerCustomizer#modifiedService(org.osgi.framework.ServiceReference, java.lang.Object)
*/
- public URL getResource(String resName) {
- return m_context.getBundle().getResource(resName);
+ public void modifiedService(ServiceReference reference, Object service) {
+ // Noting to do
}
/**
- * Create an instance. The given configuration needs to contain the 'name'
- * property.
- *
- * @param configuration : configuration of the created instance.
- * @return the created component instance.
- * @throws UnacceptableConfiguration : occurs if the given configuration is
- * not consistent with the component type of this factory.
- * @see org.apache.felix.ipojo.Factory#createComponentInstance(java.util.Dictionary)
+ * Reconfigure an existing instance.
+ * @param properties : the new configuration to push.
+ * @throws UnacceptableConfiguration : occurs if the new configuration is
+ * not consistent with the component type.
+ * @throws MissingHandlerException : occurs if the current factory is not valid.
+ * @see org.apache.felix.ipojo.Factory#reconfigure(java.util.Dictionary)
*/
- public synchronized ComponentInstance createComponentInstance(Dictionary configuration) throws UnacceptableConfiguration {
- if (configuration == null) {
- configuration = new Properties();
- }
-
- try {
- checkAcceptability(configuration);
- } catch (UnacceptableConfiguration e) {
- m_logger.log(Logger.ERROR, "The configuration is not acceptable : " + e.getMessage());
- throw new UnacceptableConfiguration("The configuration " + configuration + " is not acceptable for " + m_factoryName + ": " + e);
+ public synchronized void reconfigure(Dictionary properties) throws UnacceptableConfiguration, MissingHandlerException {
+ if (properties == null || properties.get("name") == null) {
+ throw new UnacceptableConfiguration("The configuration does not contains the \"name\" property");
}
+ final String name = (String) properties.get("name");
+ InstanceManager cm = (InstanceManager) m_componentInstances.get(name);
- String pid = null;
- if (configuration.get("name") != null) {
- pid = (String) configuration.get("name");
+ if (cm == null) {
+ return; // The instance does not exist.
} else {
- pid = generateName();
- configuration.put("name", pid);
+ checkAcceptability(properties); // Test if the configuration is acceptable
}
+ cm.reconfigure(properties); // re-configure the component
+ }
- if (m_instancesName.contains(pid)) {
- throw new UnacceptableConfiguration("Name already used : " + pid);
- } else {
- m_instancesName.add(pid);
+ /**
+ * A used factory disappears.
+ * @param reference : service reference.
+ * @param service : factory object.
+ * @see org.apache.felix.ipojo.util.TrackerCustomizer#removedService(org.osgi.framework.ServiceReference, java.lang.Object)
+ */
+ public void removedService(ServiceReference reference, Object service) {
+ // Look for the implied reference and invalid the handler identifier
+ boolean touched = false;
+ for (int i = 0; i < m_handlerIdentifiers.size(); i++) {
+ HandlerIdentifier hi = (HandlerIdentifier) m_handlerIdentifiers.get(i);
+ if (reference.equals(hi.getReference())) {
+ hi.setReference(null); // This method will unget the service.
+ touched = true;
+ }
}
+ if (touched) { computeFactoryState(); }
+ }
- final IPojoContext context = new IPojoContext(m_context);
- ComponentInstance instance = null;
- if (!m_isComposite) {
- final InstanceManager inst = new InstanceManager(this, context);
- inst.configure(m_componentMetadata, configuration);
- instance = inst;
- } else {
- final CompositeManager inst = new CompositeManager(this, context);
- inst.configure(m_componentMetadata, configuration);
- instance = inst;
+ /**
+ * Remove a factory listener.
+ * @param l : the factory listener to remove
+ * @see org.apache.felix.ipojo.Factory#removeFactoryStateListener(org.apache.felix.ipojo.FactoryStateListener)
+ */
+ public void removeFactoryStateListener(FactoryStateListener l) {
+ synchronized (m_listeners) {
+ m_listeners.remove(l);
}
-
- m_componentInstances.put(pid, instance);
- instance.start();
- return instance;
}
/**
- * Create an instance. The given configuration needs to contain the 'name'
- * property.
- *
- * @param configuration : configuration of the created instance.
- * @param serviceContext : the service context to push for this instance.
- * @return the created component instance.
- * @throws UnacceptableConfiguration : occurs if the given configuration is
- * not consistent with the component type of this factory.
- * @see org.apache.felix.ipojo.Factory#createComponentInstance(java.util.Dictionary)
+ * Start the factory.
*/
- public ComponentInstance createComponentInstance(Dictionary configuration, ServiceContext serviceContext) throws UnacceptableConfiguration {
- if (configuration == null) {
- configuration = new Properties();
- }
+ public synchronized void start() {
+ if (m_componentDesc != null) { // Already started.
+ return;
+ }
try {
- checkAcceptability(configuration);
- } catch (UnacceptableConfiguration e) {
- m_logger.log(Logger.ERROR, "The configuration is not acceptable : " + e.getMessage());
- throw new UnacceptableConfiguration("The configuration " + configuration + " is not acceptable for " + m_factoryName + ": " + e.getMessage());
- }
-
-
- String pid = null;
- if (configuration.get("name") != null) {
- pid = (String) configuration.get("name");
- } else {
- pid = generateName();
- configuration.put("name", pid);
+ String filter = "(&(" + Constants.OBJECTCLASS + "=" + Factory.class.getName() + ")"
+ + "(" + Handler.HANDLER_NAME_PROPERTY + "=*)" + "(" + Handler.HANDLER_NAMESPACE_PROPERTY + "=*)" /* Look only for handlers */
+ + "(" + Handler.HANDLER_TYPE_PROPERTY + "=" + PrimitiveHandler.HANDLER_TYPE + ")"
+ + "(factory.state=1)"
+ + ")";
+ m_tracker = new Tracker(m_context, m_context.createFilter(filter), this);
+ m_tracker.open();
+
+ } catch (InvalidSyntaxException e) {
+ m_logger.log(Logger.ERROR, "A factory filter is not valid: " + e.getMessage());
+ return;
}
- if (m_instancesName.contains(pid)) {
- throw new UnacceptableConfiguration("Name already used : " + pid);
- } else {
- m_instancesName.add(pid);
- }
+ computeFactoryState();
- final IPojoContext context = new IPojoContext(m_context, serviceContext);
- ComponentInstance instance = null;
- if (!m_isComposite) {
- final InstanceManager inst = new InstanceManager(this, context);
- inst.configure(m_componentMetadata, configuration);
- instance = inst;
- } else {
- final CompositeManager inst = new CompositeManager(this, context);
- inst.configure(m_componentMetadata, configuration);
- instance = inst;
+ if (m_factoryName == null) {
+ return;
}
-
- m_componentInstances.put(pid, instance);
- instance.start();
- return instance;
+
+ // Exposition of the factory service
+ m_sr = m_context.registerService(new String[] { Factory.class.getName(), ManagedServiceFactory.class.getName() }, this, getProperties());
}
/**
- * Delete an instance.
- *
- * @param pid : name of the instance to delete
- * @see org.osgi.service.cm.ManagedServiceFactory#deleted(java.lang.String)
+ * Stop all the instance managers.
*/
- public synchronized void deleted(String pid) {
- m_instancesName.remove(pid);
- final InstanceManager cm = (InstanceManager) m_componentInstances.remove(pid);
- if (cm == null) {
- return; // do nothing, the component does not exist !
- } else {
- cm.dispose();
+ public synchronized void stop() {
+ if (m_sr != null) {
+ m_sr.unregister();
+ m_sr = null;
}
- }
-
- /**
- * Get the name of this factory.
- *
- * @return the name of this factory
- * @see org.apache.felix.ipojo.Factory#getName()
- */
- public String getName() {
- if (m_factoryName != null) {
- return m_factoryName;
- } else if (m_typeName != null) {
- return m_typeName;
- } else {
- return m_componentClassName;
+
+ if (m_tracker != null) {
+ m_tracker.close();
+ }
+
+ final Collection col = m_componentInstances.values();
+ final Iterator it = col.iterator();
+ while (it.hasNext()) {
+ InstanceManager ci = (InstanceManager) it.next();
+ if (ci.getState() != ComponentInstance.DISPOSED) {
+ ci.kill();
+ }
+ m_instancesName.remove(ci.getInstanceName());
}
+
+ m_componentInstances.clear();
+
+ // Release each handler
+ for (int i = 0; i < m_handlerIdentifiers.size(); i++) {
+ HandlerIdentifier hi = (HandlerIdentifier) m_handlerIdentifiers.get(i);
+ if (hi.getReference() != null) {
+ hi.setReference(null);
+ }
+ }
+
+ m_tracker = null;
+ m_componentDesc = null;
+ m_classLoader = null;
+ m_clazz = null;
+ m_state = INVALID;
}
-
+
/**
* Create of update an instance.
- *
- * @param pid : name of the instance
+ * @param in : name of the instance
* @param properties : configuration of the instance
* @throws ConfigurationException : if the configuration is not consistent
* for this component type
* @see org.osgi.service.cm.ManagedServiceFactory#updated(java.lang.String,
* java.util.Dictionary)
*/
- public synchronized void updated(String pid, Dictionary properties) throws ConfigurationException {
- final InstanceManager cm = (InstanceManager) m_componentInstances.get(pid);
+ public synchronized void updated(String in, Dictionary properties) throws ConfigurationException {
+ final InstanceManager cm = (InstanceManager) m_componentInstances.get(in);
if (cm == null) {
try {
- properties.put("name", pid); // Add the name in the configuration
+ properties.put("name", in); // Add the name in the configuration
createComponentInstance(properties);
} catch (UnacceptableConfiguration e) {
m_logger.log(Logger.ERROR, "The configuration is not acceptable : " + e.getMessage());
throw new ConfigurationException(properties.toString(), e.getMessage());
+ } catch (MissingHandlerException e) {
+ m_logger.log(Logger.ERROR, "Handler not available : " + e.getMessage());
+ throw new ConfigurationException(properties.toString(), e.getMessage());
+ } catch (org.apache.felix.ipojo.ConfigurationException e) {
+ m_logger.log(Logger.ERROR, "The Component Type metadata are not correct : " + e.getMessage());
+ throw new ConfigurationException(properties.toString(), e.getMessage());
}
} else {
try {
- properties.put("name", pid); // Add the name in the configuration
- checkAcceptability(properties); // Test if the configuration is acceptable
+ properties.put("name", in); // Add the name in the configuration
+ reconfigure(properties); // re-configure the component
} catch (UnacceptableConfiguration e) {
m_logger.log(Logger.ERROR, "The configuration is not acceptable : " + e.getMessage());
throw new ConfigurationException(properties.toString(), e.getMessage());
+ } catch (MissingHandlerException e) {
+ m_logger.log(Logger.ERROR, "The facotry is not valid, at least one handler is missing : " + e.getMessage());
+ throw new ConfigurationException(properties.toString(), e.getMessage());
}
- cm.reconfigure(properties); // re-configure the component
}
}
/**
- * Check if the given configuration is acceptable as a component instance
- * configuration. This method checks that if all the configurable properties
- * have a value.
- *
- * @param conf : the configuration to check
- * @return true when the configuration seems to be acceptable
+ * Test is a configuration is acceptable for the factory.
+ * @param conf : the configuration to test.
+ * @throws UnacceptableConfiguration : the configuration is not acceptable.
+ * @throws MissingHandlerException : the factory is not valid.
*/
- public boolean isAcceptable(Dictionary conf) {
+ protected void checkAcceptability(Dictionary conf) throws UnacceptableConfiguration, MissingHandlerException {
+ computeFactoryState();
+
+ if (m_state == Factory.INVALID) {
+ throw new MissingHandlerException(getMissingHandlers());
+ }
+
final PropertyDescription[] props = m_componentDesc.getProperties();
for (int i = 0; i < props.length; i++) {
final PropertyDescription pd = props[i];
- // Failed if the props has no default value and the configuration
- // does not push a value
+ // Failed if the props has no default value and the configuration does not push a value
if (pd.getValue() == null && conf.get(pd.getName()) == null) {
- return false;
+ throw new UnacceptableConfiguration("The configuration does not contains the \"" + pd.getName() + "\" property");
}
}
- return true;
+ }
+
+ /**
+ * Compute the component type description.
+ * The factory must be valid when calling this method.
+ * @throws org.apache.felix.ipojo.ConfigurationException if one handler has rejected the configuration.
+ */
+ protected void computeDescription() throws org.apache.felix.ipojo.ConfigurationException {
+ List l = new ArrayList();
+ for (int i = 0; i < m_handlerIdentifiers.size(); i++) {
+ HandlerIdentifier hi = (HandlerIdentifier) m_handlerIdentifiers.get(i);
+ l.add(hi.getFullName());
+ }
+
+ m_componentDesc = new ComponentDescription(getName(), m_componentClassName, m_state, l, getMissingHandlers(), m_context.getBundle().getBundleId());
+
+ for (int i = 0; i < m_handlerIdentifiers.size(); i++) {
+ HandlerIdentifier hi = (HandlerIdentifier) m_handlerIdentifiers.get(i);
+ HandlerManager hm = getHandlerInstance(hi, null);
+ hm.getHandler();
+ Handler ch = hm.getHandler();
+ ch.initializeComponentFactory(m_componentDesc, m_componentMetadata);
+ ((Pojo) ch).getComponentInstance().dispose();
+ }
}
/**
- * Test is a configuration is acceptable for the factory.
- *
- * @param conf : the configuration to test.
- * @throws UnacceptableConfiguration : the configuration is not acceptable.
+ * Compute the factory name.
*/
- private void checkAcceptability(Dictionary conf) throws UnacceptableConfiguration {
- final PropertyDescription[] props = m_componentDesc.getProperties();
- for (int i = 0; i < props.length; i++) {
- final PropertyDescription pd = props[i];
- // Failed if the props has no default value and the configuration
- // does not push a value
- if (pd.getValue() == null && conf.get(pd.getName()) == null) {
- throw new UnacceptableConfiguration("The configuration does not contains the \"" + pd.getName() + "\" property");
+ protected void computeFactoryName() {
+ if (m_componentMetadata.containsAttribute("factory")) {
+ // DEPRECATED BLOCK
+ if (m_componentMetadata.getAttribute("factory").equalsIgnoreCase("no")) {
+ m_logger.log(Logger.WARNING, "'factory=no' is deprecated, Please use 'factory=false' instead of 'factory='no'");
+ m_factoryName = null;
+ return;
}
+ // END OF DEPRECATED BLOCK
+ if (m_componentMetadata.getAttribute("factory").equalsIgnoreCase("false")) {
+ m_factoryName = null;
+ return;
+ }
+ if (m_componentMetadata.getAttribute("factory").equalsIgnoreCase("true")) {
+ if (m_typeName == null) { //m_typeName is necessary set for composite.
+ m_factoryName = m_componentMetadata.getAttribute("className");
+ } else {
+ m_factoryName = m_typeName;
+ }
+ return;
+ }
+ // factory is set with the factory name
+ m_factoryName = m_componentMetadata.getAttribute("factory");
+ return;
+ } else {
+ if (m_typeName == null) { //m_typeName is necessary set for composite.
+ m_factoryName = m_componentMetadata.getAttribute("className");
+ } else {
+ m_factoryName = m_typeName;
+ }
+ return;
}
}
+
+ /**
+ * Compute factory state.
+ */
+ protected void computeFactoryState() {
+ boolean isValid = true;
+ for (int i = 0; isValid && i < m_handlerIdentifiers.size(); i++) {
+ HandlerIdentifier hi = (HandlerIdentifier) m_handlerIdentifiers.get(i);
+ isValid = hi.m_reference != null;
+ }
+
+ if (isValid && m_componentDesc == null) {
+ try {
+ computeDescription();
+ } catch (org.apache.felix.ipojo.ConfigurationException e) {
+ m_logger.log(Logger.ERROR, "The component type metadata are not correct : " + e.getMessage());
+ stop();
+ return;
+ }
+ }
+
+ if (isValid && m_state == INVALID) {
+ m_state = VALID;
+ if (m_sr != null) {
+ m_sr.setProperties(getProperties());
+ }
+ for (int i = 0; i < m_listeners.size(); i++) {
+ ((FactoryStateListener) m_listeners.get(i)).stateChanged(this, VALID);
+ }
+ return;
+ }
+ if (!isValid && m_state == VALID) {
+ m_state = INVALID;
+
+ final Collection col = m_componentInstances.values();
+ final Iterator it = col.iterator();
+ while (it.hasNext()) {
+ InstanceManager ci = (InstanceManager) it.next();
+ if (ci.getState() != ComponentInstance.DISPOSED) {
+ ci.kill();
+ }
+ m_instancesName.remove(ci.getInstanceName());
+ }
+
+ m_componentInstances.clear();
+
+ if (m_sr != null) {
+ m_sr.setProperties(getProperties());
+ }
+
+ for (int i = 0; i < m_listeners.size(); i++) {
+ ((FactoryStateListener) m_listeners.get(i)).stateChanged(this, INVALID);
+ }
+ return;
+ }
+ }
+
/**
- * Reconfigure an existing instance.
- *
- * @param properties : the new configuration to push.
- * @throws UnacceptableConfiguration : occurs if the new configuration is
- * not consistent with the component type.
- * @see org.apache.felix.ipojo.Factory#reconfigure(java.util.Dictionary)
+ * Compute required handlers.
*/
- public void reconfigure(Dictionary properties) throws UnacceptableConfiguration {
- if (properties == null || properties.get("name") == null) {
- throw new UnacceptableConfiguration("The configuration does not contains the \"name\" property");
+ protected void computeRequiredHandlers() {
+ Element[] elems = m_componentMetadata.getElements();
+ for (int i = 0; i < elems.length; i++) {
+ Element current = elems[i];
+ if (current.getName().equals("manipulation")) { continue; }
+ HandlerIdentifier hi = new HandlerIdentifier(current.getName(), current.getNameSpace());
+ if (! m_handlerIdentifiers.contains(hi)) { m_handlerIdentifiers.add(hi); }
}
- final String name = (String) properties.get("name");
- ComponentInstance cm = null;
- if (m_isComposite) {
- cm = (CompositeManager) m_componentInstances.get(name);
- } else {
- cm = (InstanceManager) m_componentInstances.get(name);
+
+ // Add architecture if needed
+ HandlerIdentifier hi = new HandlerIdentifier("architecture", "");
+ if (! m_handlerIdentifiers.contains(hi) && m_componentMetadata.containsAttribute("architecture") && m_componentMetadata.getAttribute("architecture").equalsIgnoreCase("true")) {
+ m_handlerIdentifiers.add(hi);
}
- if (cm == null) {
- return; // The instance does not exist.
- } else {
- checkAcceptability(properties); // Test if the configuration is acceptable
+
+ // Add lifecycle callback if immediate = true
+ HandlerIdentifier hi2 = new HandlerIdentifier("callback", "");
+ if (! m_handlerIdentifiers.contains(hi2) && m_componentMetadata.containsAttribute("immediate") && m_componentMetadata.getAttribute("immediate").equalsIgnoreCase("true")) {
+ m_handlerIdentifiers.add(hi2);
}
- cm.reconfigure(properties); // re-configure the component
+ }
+
+ /**
+ * Callback called by instance when disposed.
+ * @param ci : the destroyed instance
+ */
+ protected void disposed(ComponentInstance ci) {
+ m_instancesName.remove(ci.getInstanceName());
+ m_componentInstances.remove(ci.getInstanceName());
}
/**
* Generate an instance name.
* @return an non already used name
*/
- private synchronized String generateName() {
+ protected synchronized String generateName() {
String name = getName() + "-" + m_index;
while (m_instancesName.contains(name)) {
m_index = m_index + 1;
name = getName() + "-" + m_index;
}
return name;
+ }
+
+ /**
+ * Return the bundle context.
+ * @return the Bundle Context.
+ */
+ protected BundleContext getBundleContext() {
+ return m_context;
+ }
+
+ /**
+ * Get the implementation class of the component type.
+ *
+ * @return the name of the component-type implementation class.
+ */
+ protected String getComponentClassName() {
+ return m_componentClassName;
+ }
+
+ protected String getComponentTypeName() {
+ return m_typeName;
+ }
+
+ /**
+ * Compute factory properties.
+ * @return the properties.
+ */
+ protected Properties getProperties() {
+ final Properties props = new Properties();
+
+ props.put("component.class", m_componentClassName);
+
+ props.put("factory.name", m_factoryName);
+ if (m_typeName != null) {
+ props.put("component.type", m_typeName);
+ }
+
+ if (m_componentDesc != null) {
+ props.put("component.providedServiceSpecifications", m_componentDesc.getprovidedServiceSpecification());
+ props.put("component.properties", m_componentDesc.getProperties());
+ props.put("component.description", m_componentDesc);
+ props.put("component.desc", m_componentDesc.toString());
+ }
+
+ // Add factory state
+ props.put("factory.state", "" + m_state);
+
+ return props;
+ }
+
+ /**
+ * Check if the given handler identifier and the service reference can match.
+ * @param hi : the handler identifier.
+ * @param ref : the service reference.
+ * @return true if the service reference can fulfill the handler requirement
+ */
+ protected boolean match(HandlerIdentifier hi, ServiceReference ref) {
+ String name = (String) ref.getProperty(Handler.HANDLER_NAME_PROPERTY);
+ String ns = (String) ref.getProperty(Handler.HANDLER_NAMESPACE_PROPERTY);
+ if (IPojoConfiguration.IPOJO_NAMESPACE.equals(ns)) {
+ ns = "";
+ }
+ return name.equals(hi.m_name) && ns.equals(hi.m_namespace);
+ }
+
+ /**
+ * Return an handler object.
+ *
+ * @param hi : handler to create.
+ * @param sc : service context in which create the handler (instance context).
+ * @return the Handler object.
+ */
+ private HandlerManager getHandlerInstance(HandlerIdentifier hi, ServiceContext sc) {
+ Factory factory = hi.getFactory();
+ try {
+ return (HandlerManager) factory.createComponentInstance(null, sc);
+ } catch (MissingHandlerException e) {
+ m_logger.log(Logger.ERROR, "The creation of the handler " + hi.getFullName() + " has failed: " + e.getMessage());
+ return null;
+ } catch (UnacceptableConfiguration e) {
+ m_logger.log(Logger.ERROR, "The creation of the handler " + hi.getFullName() + " has failed (UnacceptableConfiguration): " + e.getMessage());
+ return null;
+ } catch (org.apache.felix.ipojo.ConfigurationException e) {
+ m_logger.log(Logger.ERROR, "The configuration of the handler " + hi.getFullName() + " has failed (ConfigurationException): " + e.getMessage());
+ return null;
+ }
+ }
+
+ /**
+ * Structure storing required handlers.
+ */
+ class HandlerIdentifier {
+ /**
+ * Factory to create this handler.
+ */
+ private Factory m_factory;
+
+ /**
+ * Handler name.
+ */
+ private String m_name;
+
+ /**
+ * Handler namespace.
+ */
+ private String m_namespace;
+
+ /**
+ * Service Reference of the handler factory.
+ */
+ private ServiceReference m_reference;
+
+ /**
+ * Constructor.
+ * @param n : handler name.
+ * @param ns : handler namespace.
+ */
+ public HandlerIdentifier(String n, String ns) {
+ m_name = n;
+ m_namespace = ns;
+ }
+
+ /**
+ * Equals method.
+ * Two handlers are equals if they have same name and namespace or they share the same service reference.
+ * @param o : object to compare to the current object.
+ * @return : true if the two compared object are equals
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ public boolean equals(Object o) {
+ if (o instanceof HandlerIdentifier) {
+ return ((HandlerIdentifier) o).getName().equalsIgnoreCase(m_name) && ((HandlerIdentifier) o).getNamespace().equalsIgnoreCase(m_namespace);
+ }
+ return false;
+ }
+
+ /**
+ * Get the factory object used for this handler.
+ * The object is get when used for the first time.
+ * @return the factory object.
+ */
+ public Factory getFactory() {
+ if (m_reference == null) {
+ return null;
+ }
+ if (m_factory == null) {
+ m_factory = (Factory) m_tracker.getService(getReference());
+ }
+ return m_factory;
+ }
+
+ /**
+ * Get the handler full name (namespace:name).
+ * @return the handler full name
+ */
+ public String getFullName() {
+ if ("".equals(m_namespace)) {
+ return IPojoConfiguration.IPOJO_NAMESPACE + ":" + m_name;
+ } else {
+ return m_namespace + ":" + m_name;
+ }
+ }
+
+ public String getName() {
+ return m_name;
+ }
+
+ public String getNamespace() {
+ return m_namespace;
+ }
+
+ public ServiceReference getReference() {
+ return m_reference;
+ }
+
+ /**
+ * Set the service reference.
+ * If the new service reference is null, it unget the used factory (if already get).
+ * @param ref : new service reference.
+ */
+ public void setReference(ServiceReference ref) {
+ if (m_reference != null) {
+ m_tracker.ungetService(m_reference);
+ m_factory = null;
+ }
+ m_reference = ref;
+ }
+ }
+
+ /**
+ * FactoryClassloader.
+ */
+ private class FactoryClassloader extends ClassLoader {
+
+ /**
+ * Map of defined classes [Name, Class Object].
+ */
+ private Map m_definedClasses = new HashMap();
+
+ /**
+ * The defineClass method.
+ *
+ * @param name : name of the class
+ * @param b : the byte array of the class
+ * @param domain : the protection domain
+ * @return : the defined class.
+ * @throws Exception : if a problem is detected during the loading
+ */
+ public Class defineClass(String name, byte[] b, ProtectionDomain domain) throws Exception {
+ if (m_definedClasses.containsKey(name)) {
+ return (Class) m_definedClasses.get(name);
+ }
+ final Class c = super.defineClass(name, b, 0, b.length, domain);
+ m_definedClasses.put(name, c);
+ return c;
+ }
+
+ /**
+ * Return the URL of the asked resource.
+ *
+ * @param arg : the name of the resource to find.
+ * @return the URL of the resource.
+ * @see java.lang.ClassLoader#getResource(java.lang.String)
+ */
+ public URL getResource(String arg) {
+ return m_context.getBundle().getResource(arg);
+ }
+
+ /**
+ * Load the class.
+ * @see java.lang.ClassLoader#loadClass(java.lang.String, boolean)
+ * @param name : the name of the class
+ * @param resolve : should be the class resolve now ?
+ * @return : the loaded class
+ * @throws ClassNotFoundException : the class to load is not found
+ */
+ protected Class loadClass(final String name, final boolean resolve) throws ClassNotFoundException {
+ return m_context.getBundle().loadClass(name);
+ }
}
}
Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/ComponentInstance.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/ComponentInstance.java?rev=579239&r1=579238&r2=579239&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/ComponentInstance.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/ComponentInstance.java Tue Sep 25 06:27:49 2007
@@ -20,13 +20,11 @@
import java.util.Dictionary;
-import org.apache.felix.ipojo.architecture.ComponentDescription;
import org.apache.felix.ipojo.architecture.InstanceDescription;
import org.osgi.framework.BundleContext;
/**
* The component instance class manages one instance of a component type.
- *
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
public interface ComponentInstance {
@@ -76,13 +74,6 @@
* @return the actual state of the component instance.
*/
int getState();
-
- /**
- * Return component-type description of this instance.
- * @return the component type information. Each handler can participate to
- * the component description.
- */
- ComponentDescription getComponentDescription();
/**
* Return the instance description.