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.