felix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From clem...@apache.org
Subject svn commit: r579239 [2/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/...
Date Tue, 25 Sep 2007 13:27:54 GMT
Added: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/CompositeFactory.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/CompositeFactory.java?rev=579239&view=auto
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/CompositeFactory.java (added)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/CompositeFactory.java Tue Sep 25 06:27:49 2007
@@ -0,0 +1,404 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.ipojo;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Dictionary;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.felix.ipojo.architecture.ComponentDescription;
+import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.util.Logger;
+import org.apache.felix.ipojo.util.Tracker;
+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;
+
+/**
+ * The component factory manages component instance objects. This management
+ * consist in creating and managing component instance build with the component
+ * factory. This class could export Factory and ManagedServiceFactory services.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class CompositeFactory extends ComponentFactory implements Factory {
+
+    /**
+     * Service Registration of this factory (Factory & ManagedServiceFactory).
+     */
+    private ServiceRegistration m_sr;
+
+    /**
+     * Create a composite factory.
+     * @param bc : bundle context
+     * @param cm : metadata of the component to create
+     */
+    public CompositeFactory(BundleContext bc, Element cm) {
+        super(bc, cm);
+    }
+    
+    /**
+     * Check if the metadata are well formed.
+     * @param cm : metadata
+     * @return true if the metadata are correct.
+     * @see org.apache.felix.ipojo.ComponentFactory#check(org.apache.felix.ipojo.metadata.Element)
+     */
+    public boolean check(Element cm) {
+     // Get the name
+        if (cm.containsAttribute("name")) {
+            m_typeName = cm.getAttribute("name");
+            return true;
+        } else {
+            System.err.println("A composite needs a name");
+            return false;
+        }
+    }
+    
+    /**
+     * Check if the given handler identifier can be fulfilled by the given service reference.
+     * @param hi : handler identifier.
+     * @param ref : service reference.
+     * @return true if the service reference can fulfill the given handler identifier
+     * @see org.apache.felix.ipojo.ComponentFactory#match(org.apache.felix.ipojo.ComponentFactory.HandlerIdentifier, org.osgi.framework.ServiceReference)
+     */
+    public boolean match(HandlerIdentifier hi, ServiceReference ref) {
+        String name = (String) ref.getProperty(Handler.HANDLER_NAME_PROPERTY);
+        String ns = (String) ref.getProperty(Handler.HANDLER_NAMESPACE_PROPERTY);
+        String type = (String) ref.getProperty(Handler.HANDLER_TYPE_PROPERTY);
+        
+        if ("composite".equals(type)) {
+            if (IPojoConfiguration.IPOJO_NAMESPACE.equals(ns)) {
+                ns = "";
+            }
+            return name.equals(hi.getName()) && ns.equals(hi.getNamespace()); 
+        } else {
+            return false;
+        }
+    }
+    
+    /**
+     * Compute required handlers.
+     */
+    protected void computeRequiredHandlers() {
+        Element[] elems = m_componentMetadata.getElements();
+        for (int i = 0; i < elems.length; i++) {
+            Element current = elems[i]; 
+            HandlerIdentifier hi = new HandlerIdentifier(current.getName(), current.getNameSpace());
+            if (! m_handlerIdentifiers.contains(hi)) { m_handlerIdentifiers.add(hi); }
+        }
+        
+        // Add architecture if needed
+        if (m_componentMetadata.containsAttribute("architecture") && m_componentMetadata.getAttribute("architecture").equalsIgnoreCase("true")) {
+            HandlerIdentifier hi = new HandlerIdentifier("architecture", "");
+            if (! m_handlerIdentifiers.contains(hi)) { m_handlerIdentifiers.add(hi); }
+        }
+    }
+    
+    /**
+     * Stop all the instance managers.
+     */
+    public synchronized void stop() {
+        m_tracker.close();
+        
+        final Collection col = m_componentInstances.values();
+        final Iterator it = col.iterator();
+        while (it.hasNext()) {
+            CompositeManager ci = (CompositeManager) it.next();
+            if (ci.getState() != ComponentInstance.DISPOSED) {
+                ci.kill();
+            }
+            m_instancesName.remove(ci.getInstanceName());
+        }
+        
+        m_componentInstances.clear();
+        if (m_sr != null) { 
+            m_sr.unregister();
+            m_sr = null;
+        }
+        m_tracker = null;
+        m_componentDesc = null;
+        m_state = INVALID;
+    }
+
+    /**
+     * Start all the instance managers.
+     */
+    public synchronized void start() {
+        if (m_componentDesc != null) { // Already started.
+            return;
+        } 
+        try {
+            String filter = "(&(" + Constants.OBJECTCLASS + "=" + Factory.class.getName() + ")"
+                    + "(" + Handler.HANDLER_NAME_PROPERTY + "=*)" + "(" + Handler.HANDLER_NAMESPACE_PROPERTY + "=*)" /* Look only for handlers */
+                    + "(" + Handler.HANDLER_TYPE_PROPERTY + "=" + CompositeHandler.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;
+        }
+        
+        computeFactoryState();
+        
+        // Check if the factory should be exposed
+        if (m_factoryName == null) { return; }
+        
+        // Exposition of the factory service
+        m_sr = m_context.registerService(new String[] { Factory.class.getName() }, this, getProperties());
+    }
+    
+    
+    /**
+     * Compute factory service properties.
+     * @return the factory service properties
+     * @see org.apache.felix.ipojo.ComponentFactory#getProperties()
+     */
+    protected Properties getProperties() {
+        final Properties props = new Properties();
+        
+        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);
+        
+        props.put("factory.name", m_factoryName);
+        props.put("component.type", m_typeName);
+        
+        return props;
+    }
+
+
+    /**
+     * 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 ConfigurationException  : occurs if an error occurs during the instance configuration.
+     * @see org.apache.felix.ipojo.Factory#createComponentInstance(java.util.Dictionary)
+     */
+    public synchronized ComponentInstance createComponentInstance(Dictionary configuration) throws UnacceptableConfiguration, MissingHandlerException, ConfigurationException {
+        return createComponentInstance(configuration, null);
+    }
+
+    /**
+     * 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 ConfigurationException  : occurs when the instance configuration failed.
+     * @see org.apache.felix.ipojo.Factory#createComponentInstance(java.util.Dictionary)
+     */
+    public synchronized ComponentInstance createComponentInstance(Dictionary configuration, ServiceContext serviceContext) throws UnacceptableConfiguration, MissingHandlerException, ConfigurationException {
+        if (m_state == INVALID) {
+            throw new MissingHandlerException(getMissingHandlers());
+        }
+        
+        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.getMessage());
+        }
+
+        
+        String in = null;
+        if (configuration.get("name") != null) {
+            in = (String) configuration.get("name");
+        } else {
+            in = generateName();
+            configuration.put("name", in);
+        }
+        
+        if (m_instancesName.contains(in)) {
+            throw new UnacceptableConfiguration("Name already used : " + in + "(" + m_instancesName + ")");
+        } else {
+            m_instancesName.add(in);
+        }
+
+        BundleContext context = null;
+        if (serviceContext == null) {
+            context = new IPojoContext(m_context);
+        } else {
+            context = new IPojoContext(m_context, serviceContext);
+        }
+        ComponentInstance instance = null;
+        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));
+        }
+       
+        final CompositeManager inst = new CompositeManager(this, context, (HandlerManager[]) handlers.toArray(new HandlerManager[0]));
+        inst.configure(m_componentMetadata, configuration);
+        instance = inst;
+
+        m_componentInstances.put(in, instance);
+        instance.start();
+        return instance;
+    }
+
+    /**
+     * 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 when an handler is unavailable when creating the instance.
+     * @see org.apache.felix.ipojo.Factory#reconfigure(java.util.Dictionary)
+     */
+    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");
+        
+        ComponentInstance cm = (CompositeManager) m_componentInstances.get(name);
+        
+        if (cm == null) {
+            return; // The instance does not exist.
+        }
+        
+        cm.reconfigure(properties); // re-configure the component
+    }
+    
+    /**
+     * 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.getReference() != 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()) {
+                CompositeManager ci = (CompositeManager) it.next();
+                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;
+        }
+
+    }
+
+    /**
+     * Compute component type description.
+     * @throws ConfigurationException : if one handler has rejected the configuration.
+     * @see org.apache.felix.ipojo.ComponentFactory#computeDescription()
+     */
+    public void computeDescription() throws 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(), "composite", 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();
+        }
+    }
+    
+    /**
+     * Get a composite handler object for the given handler identifier.
+     * @param handler : the handler identifier.
+     * @param sc : the service context in which creating the handler.
+     * @return the composite handler object or null if not found.
+     */
+    private HandlerManager getHandlerInstance(HandlerIdentifier handler, ServiceContext sc) {
+        Factory factory = (Factory) m_context.getService(handler.getReference());
+        try {
+            return (HandlerManager) factory.createComponentInstance(null, sc);
+        } catch (MissingHandlerException e) {
+            m_logger.log(Logger.ERROR, "The creation of the composite handler " + handler.getFullName() + " has failed: " + e.getMessage());
+            return null;
+        } catch (UnacceptableConfiguration e) {
+            m_logger.log(Logger.ERROR, "The creation of the composite handler " + handler.getFullName() + " has failed (UnacceptableConfiguration): " + e.getMessage());
+            return null;
+        } catch (ConfigurationException e) {
+            m_logger.log(Logger.ERROR, "The creation of the composite handler " + handler.getFullName() + " has failed (ConfigurationException): " + e.getMessage());
+            return null;
+        }
+    }
+}

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/CompositeHandler.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/CompositeHandler.java?rev=579239&r1=579238&r2=579239&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/CompositeHandler.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/CompositeHandler.java Tue Sep 25 06:27:49 2007
@@ -18,10 +18,6 @@
  */
 package org.apache.felix.ipojo;
 
-import java.util.Dictionary;
-
-import org.apache.felix.ipojo.architecture.HandlerDescription;
-import org.apache.felix.ipojo.metadata.Element;
 
 /**
  * Composite Handler Abstract Class. An composite handler need implements these
@@ -29,58 +25,60 @@
  * 
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public abstract class CompositeHandler {
-
-    /**
-     * Configure the handler.
-     * 
-     * @param im : the instance manager
-     * @param metadata : the metadata of the component
-     * @param configuration : the instance configuration
-     */
-    public abstract void configure(CompositeManager im, Element metadata, Dictionary configuration);
-
+public abstract class CompositeHandler extends Handler {
+    
     /**
-     * Stop the handler : stop the management.
+     * Composite Handler type.
      */
-    public abstract void stop();
-
+    public static final String HANDLER_TYPE = "composite";
+    
     /**
-     * Start the handler : start the management.
+     * Reference on the composite manager.
      */
-    public abstract void start();
-
+    private CompositeManager m_manager;
+    
     /**
-     * Is the actual state valid for this handler ?
-     * 
-     * @return true is the state seems valid for the handler
+     * Set the manager.
+     * This method me be called only once time.
+     * @param cm : the composite manager.
      */
-    public boolean isValid() {
-        return true;
+    public final void attach(ComponentInstance cm) {
+        m_manager = (CompositeManager) cm;
     }
-
+    
+    public final CompositeManager getCompositeManager() {
+        return m_manager;
+    }
+        
     /**
-     * This method is called when the component state changed.
-     * 
-     * @param state : the new state
+     * Log method.
+     * @param level : message level (Logger class constant)
+     * @param message : message to log
      */
-    public void stateChanged(int state) {
+    public void log(int level, String message) {
+        m_manager.getFactory().getLogger().log(level, message);
     }
-
+    
     /**
-     * Return the description of the handler.
-     * @return the description of the handler.
+     * Log method.
+     * @param level : message level (Logger class constant)
+     * @param message : message to log
+     * @param ex : exception to attach to the message
      */
-    public HandlerDescription getDescription() {
-        return new HandlerDescription(this.getClass().getName(), isValid());
+    public void log(int level, String message, Throwable ex) {
+        m_manager.getFactory().getLogger().log(level, message, ex);
     }
-
+    
     /**
-     * The instance is reconfiguring.
-     * 
-     * @param configuration : New instance configuration.
+     * Get a plugged handler of the same container.
+     * This method must be call only in the start method (or after).
+     * In the configure method, this method can not return a consistent
+     * result as all handlers are not plugged. 
+     * @param name : name of the handler to find (class name). 
+     * @return the composite handler object or null if the handler is not found.
      */
-    public void reconfigure(Dictionary configuration) {
+    public final Handler getHandler(String name) {
+        return m_manager.getCompositeHandler(name);
     }
-
+    
 }

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/CompositeManager.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/CompositeManager.java?rev=579239&r1=579238&r2=579239&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/CompositeManager.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/CompositeManager.java Tue Sep 25 06:27:49 2007
@@ -18,14 +18,14 @@
  */
 package org.apache.felix.ipojo;
 
+import java.util.ArrayList;
 import java.util.Dictionary;
+import java.util.List;
 
 import org.apache.felix.ipojo.architecture.Architecture;
-import org.apache.felix.ipojo.architecture.ComponentDescription;
 import org.apache.felix.ipojo.architecture.InstanceDescription;
 import org.apache.felix.ipojo.composite.CompositeServiceContext;
 import org.apache.felix.ipojo.metadata.Element;
-import org.apache.felix.ipojo.util.Logger;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServiceReference;
@@ -37,62 +37,81 @@
  * 
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public class CompositeManager implements ComponentInstance {
+public class CompositeManager implements ComponentInstance, InstanceStateListener {
 
     /**
-     * Parent factory (ComponentFactory).
+     * The context of the component.
      */
-    private ComponentFactory m_factory;
+    private BundleContext m_context;
 
     /**
-     * Name of the component instance.
+     * Parent factory (ComponentFactory).
      */
-    private String m_name;
+    private ComponentFactory m_factory;
 
     /**
-     * The context of the component.
+     * Composite Handler list.
      */
-    private BundleContext m_context;
+    private HandlerManager[] m_handlers = new HandlerManager[0];
 
     /**
-     * Composite Handler list.
+     * Instance State Listener List.
      */
-    private CompositeHandler[] m_handlers = new CompositeHandler[0];
+    private List m_instanceListeners = new ArrayList();
 
     /**
-     * Component state (STOPPED at the beginning).
+     * Internal service context of the composition.
      */
-    private int m_state = STOPPED;
+    private CompositeServiceContext m_internalContext;
     
     /**
-     * Instance State Listener List.
-     */
-    private InstanceStateListener[] m_instanceListeners = new InstanceStateListener[0];
-
-
-    /**
-     * Component type information.
+     * Name of the component instance.
      */
-    private ComponentDescription m_componentDesc;
+    private String m_name;
 
     /**
-     * Internal service context of the composition.
+     * Component state (STOPPED at the beginning).
      */
-    private CompositeServiceContext m_internalContext;
+    private int m_state = STOPPED;
 
-    // Constructor
     /**
      * Construct a new Component Manager.
-     * 
      * @param factory : the factory managing the instance manager
      * @param bc : the bundle context to give to the instance
+     * @param handlers : the handlers to plug
      */
-    public CompositeManager(ComponentFactory factory, BundleContext bc) {
+    public CompositeManager(ComponentFactory factory, BundleContext bc, HandlerManager[] handlers) {
         m_factory = factory;
         m_context = bc;
         // Initialize the service context.
         m_internalContext = new CompositeServiceContext(m_context, this);
-        m_factory.getLogger().log(Logger.INFO, "[Bundle " + m_context.getBundle().getBundleId() + "] Create an instance manager from the factory " + m_factory);
+        m_handlers = handlers;
+    }
+
+    /**
+     * Plug the given handler to the current container.
+     * @param h : the handler to plug.
+     */
+    public synchronized void addCompositeHandler(HandlerManager h) {
+        if (m_handlers.length > 0) {
+            HandlerManager[] newInstances = new HandlerManager[m_handlers.length + 1];
+            System.arraycopy(m_handlers, 0, newInstances, 0, m_handlers.length);
+            newInstances[m_handlers.length] = h;
+            m_handlers = newInstances;
+        } else {
+            m_handlers = new HandlerManager[] { h };
+        }
+    }
+
+    /**
+     * Add an instance to the created instance list.
+     * @param listener : the instance state listener to add.
+     * @see org.apache.felix.ipojo.ComponentInstance#addInstanceStateListener(org.apache.felix.ipojo.InstanceStateListener)
+     */
+    public void addInstanceStateListener(InstanceStateListener listener) {
+        synchronized (m_instanceListeners) {
+            m_instanceListeners.add(listener);
+        }
     }
 
     /**
@@ -101,76 +120,89 @@
      * 
      * @param cm : the component type metadata
      * @param configuration : the configuration of the instance
+     * @throws ConfigurationException : occurs when the component type are incorrect.
      */
-    public void configure(Element cm, Dictionary configuration) {
-        // Stop all previous registered handler
-        if (m_handlers.length != 0) {
-            stop();
-        }
-
-        // Clear the handler list
-        m_handlers = new CompositeHandler[0];
-
-        // ComponentInfo initialization
-        m_componentDesc = new ComponentDescription(m_factory.getName());
-
+    public void configure(Element cm, Dictionary configuration) throws ConfigurationException {        
         // Add the name
         m_name = (String) configuration.get("name");
-
+        
         // Create the standard handlers and add these handlers to the list
-        for (int i = 0; i < IPojoConfiguration.INTERNAL_COMPOSITE_HANDLERS.length; i++) {
-            // Create a new instance
-            try {
-                CompositeHandler h = (CompositeHandler) IPojoConfiguration.INTERNAL_COMPOSITE_HANDLERS[i].newInstance();
-                h.configure(this, cm, configuration);
-            } catch (InstantiationException e) {
-                m_factory.getLogger().log(Logger.ERROR,
-                        "[" + m_name + "] Cannot instantiate the handler " + IPojoConfiguration.INTERNAL_HANDLERS[i] + " : " + e.getMessage());
-            } catch (IllegalAccessException e) {
-                m_factory.getLogger().log(Logger.ERROR,
-                        "[" + m_name + "] Cannot instantiate the handler " + IPojoConfiguration.INTERNAL_HANDLERS[i] + " : " + e.getMessage());
-            }
+        for (int i = 0; i < m_handlers.length; i++) {
+            m_handlers[i].init(this, cm, configuration);
+        }
+    }
+    
+    /** 
+     * Dispose the instance.
+     * @see org.apache.felix.ipojo.ComponentInstance#dispose()
+     */
+    public void dispose() {
+        if (m_state > STOPPED) { stop(); }
+        
+        for (int i = 0; i < m_instanceListeners.size(); i++) {
+            ((InstanceStateListener) m_instanceListeners.get(i)).stateChanged(this, DISPOSED);
         }
+        
+        m_factory.disposed(this);
 
-        // Look for namespaces
-        for (int i = 0; i < cm.getNamespaces().length; i++) {
-            if (!cm.getNamespaces()[i].equals("")) {
-                // It is not an internal handler, try to load it
-                try {
-                    Class c = m_context.getBundle().loadClass(cm.getNamespaces()[i]);
-                    CompositeHandler h = (CompositeHandler) c.newInstance();
-                    h.configure(this, cm, configuration);
-                } catch (ClassNotFoundException e) {
-                    m_factory.getLogger()
-                            .log(Logger.ERROR, "[" + m_name + "] Cannot instantiate the handler " + cm.getNamespaces()[i] + " : " + e.getMessage());
-                } catch (InstantiationException e) {
-                    m_factory.getLogger()
-                            .log(Logger.ERROR, "[" + m_name + "] Cannot instantiate the handler " + cm.getNamespaces()[i] + " : " + e.getMessage());
-                } catch (IllegalAccessException e) {
-                    m_factory.getLogger()
-                            .log(Logger.ERROR, "[" + m_name + "] Cannot instantiate the handler " + cm.getNamespaces()[i] + " : " + e.getMessage());
-                }
+        // Cleaning
+        m_state = DISPOSED;
+        for (int i = 0; i < m_handlers.length; i++) {
+            m_handlers[i].dispose();
+        }
+        m_handlers = new HandlerManager[0];
+        m_instanceListeners.clear();
+    }
+
+    /**
+     * Return a specified handler.
+     * @param name : class name of the handler to find
+     * @return : the handler, or null if not found
+     */
+    public CompositeHandler getCompositeHandler(String name) {
+        for (int i = 0; i < m_handlers.length; i++) {
+            HandlerFactory fact = (HandlerFactory) m_handlers[i].getFactory();
+            if (fact.getHandlerName().equals(name) || fact.getComponentClassName().equals(name)) {
+                return (CompositeHandler) m_handlers[i].getHandler();
             }
         }
+        return null;
     }
 
     /**
-     * Return the component type description of this instance.
-     * @return the component type information.
-     * @see org.apache.felix.ipojo.ComponentInstance#getComponentDescription()
+     * Get the bundle context used by this instance.
+     * @return the parent context of the instance.
+     * @see org.apache.felix.ipojo.ComponentInstance#getContext()
      */
-    public ComponentDescription getComponentDescription() {
-        return m_componentDesc;
+    public BundleContext getContext() {
+        return m_context;
     }
 
     /**
+     * Get the factory which create this instance.
+     * @return the factory of the component
+     * @see org.apache.felix.ipojo.ComponentInstance#getFactory()
+     */
+    public ComponentFactory getFactory() {
+        return m_factory;
+    }
+    
+    /**
+     * Get the global bundle context.
+     * @return the global bundle context.
+     */
+    public BundleContext getGlobalContext() {
+        IPojoContext c = (IPojoContext) m_context;
+        return c.getGlobalContext();
+    }
+    
+    /**
      * Return the instance description of this instance.
      * @return the instance description.
      * @see org.apache.felix.ipojo.ComponentInstance#getInstanceDescription()
      */
-    public synchronized InstanceDescription getInstanceDescription() {
-        int componentState = getState();
-        InstanceDescription instanceDescription = new InstanceDescription(m_name, componentState, getContext().getBundle().getBundleId(), m_componentDesc);
+    public InstanceDescription getInstanceDescription() {
+        InstanceDescription instanceDescription = new InstanceDescription(m_name, m_state, getContext().getBundle().getBundleId(), m_factory.getComponentDescription());
         CompositeHandler[] handlers = getRegistredCompositeHandlers();
         for (int i = 0; i < handlers.length; i++) {
             instanceDescription.addHandler(handlers[i].getDescription());
@@ -194,144 +226,43 @@
     }
 
     /**
-     * REturn the list of handlers plugged on this instance.
-     * @return the list of the registered handlers.
+     * Get the instance name.
+     * @return the instance name
+     * @see org.apache.felix.ipojo.ComponentInstance#getInstanceName()
      */
-    public CompositeHandler[] getRegistredCompositeHandlers() {
-        return m_handlers;
+    public String getInstanceName() {
+        return m_name;
     }
 
     /**
-     * Return a specified handler.
-     * 
-     * @param name : class name of the handler to find
-     * @return : the handler, or null if not found
+     * Get the parent service context.
+     * @return the parent service context.
      */
-    public CompositeHandler getCompositeHandler(String name) {
-        for (int i = 0; i < m_handlers.length; i++) {
-            if (m_handlers[i].getClass().getName().equalsIgnoreCase(name)) {
-                return m_handlers[i];
-            }
-        }
-        return null;
+    public ServiceContext getParentServiceContext() {
+        IPojoContext c = (IPojoContext) m_context;
+        return c.getServiceContext();
     }
 
-    // ===================== Lifecycle management =====================
-
     /**
-     * Start the instance manager.
+     * REturn the list of handlers plugged on this instance.
+     * @return the list of the registered handlers.
      */
-    public void start() {
-        if (m_state != STOPPED) {
-            return;
-        } // Instance already started
-
-        // Start all the handlers
-        m_factory.getLogger().log(Logger.INFO, "[" + m_name + "] Start the instance manager with " + m_handlers.length + " handlers");
-
-        // The new state of the component is UNRESOLVED
-        m_state = INVALID;
-
-        m_internalContext.start(); // Turn on the factory tracking
-
+    public CompositeHandler[] getRegistredCompositeHandlers() {
+        CompositeHandler[] h = new CompositeHandler[m_handlers.length];
         for (int i = 0; i < m_handlers.length; i++) {
-            m_handlers[i].start();
-        }
-
-        // Defines the state of the component :
-        checkInstanceState();
-    }
-
-    /**
-     * Stop the instance manager.
-     */
-    public void stop() {
-        if (m_state == STOPPED) {
-            return;
-        } // Instance already stopped
-
-        setState(INVALID);
-        // Stop all the handlers
-        for (int i = m_handlers.length - 1; i > -1; i--) {
-            m_handlers[i].stop();
-        }
-
-        m_internalContext.stop(); // Turn off the factory tracking
-        m_state = STOPPED;
-        
-        for (int i = 0; i < m_instanceListeners.length; i++) {
-            m_instanceListeners[i].stateChanged(this, STOPPED);
+            h[i] = (CompositeHandler) m_handlers[i].getHandler();
         }
-    }
-    
-    /** 
-     * Dispose the instance.
-     * @see org.apache.felix.ipojo.ComponentInstance#dispose()
-     */
-    public void dispose() {
-        if (m_state > STOPPED) {
-            stop();
-        }
-        
-        for (int i = 0; i < m_instanceListeners.length; i++) {
-            m_instanceListeners[i].stateChanged(this, DISPOSED);
-        }
-        
-        m_factory.disposed(this);
-
-        // Cleaning
-        m_state = DISPOSED;
-        m_handlers = new CompositeHandler[0];
-        m_instanceListeners = new InstanceStateListener[0];
+        return h;
     }
     
     /**
-     * Kill the current instance.
-     * Only the factory of this instance can call this method.
-     */
-    protected void kill() {
-        if (m_state > STOPPED) {
-            stop();
-        }
-        
-        for (int i = 0; i < m_instanceListeners.length; i++) {
-            m_instanceListeners[i].stateChanged(this, DISPOSED);
-        }
-
-        // Cleaning
-        m_state = DISPOSED;
-        m_handlers = new CompositeHandler[0];
-        m_instanceListeners = new InstanceStateListener[0];
-    }
-
-    /**
-     * Set the state of the component. 
-     * Ff the state changed call the stateChanged(int) method on the handlers.
-     * @param state : new state
+     * Get the internal service context of this instance.
+     * @return the internal service context.
      */
-    public void setState(int state) {
-        if (m_state != state) {
-
-            // Log the state change
-            if (state == INVALID) {
-                m_factory.getLogger().log(Logger.INFO, "[" + m_name + "]  State -> INVALID");
-            }
-            if (state == VALID) {
-                m_factory.getLogger().log(Logger.INFO, "[" + m_name + "] State -> VALID");
-            }
-
-            // The state changed call the handler stateChange method
-            m_state = state;
-            for (int i = m_handlers.length - 1; i > -1; i--) {
-                m_handlers[i].stateChanged(state);
-            }
-            
-            for (int i = 0; i < m_instanceListeners.length; i++) {
-                m_instanceListeners[i].stateChanged(this, state);
-            }
-        }
+    public ServiceContext getServiceContext() {
+        return m_internalContext;
     }
-
+    
     /**
      * Get the actual state of the instance.
      * @return the actual state of the instance
@@ -340,203 +271,158 @@
     public int getState() {
         return m_state;
     }
-
+    
     /**
      * Check if the instance is started.
      * @return true if the instance is started.
      * @see org.apache.felix.ipojo.ComponentInstance#isStarted()
      */
     public boolean isStarted() {
-        return m_state != STOPPED;
+        return m_state > STOPPED;
     }
-    
+
     /**
-     * Add an instance to the created instance list.
-     * @param listener : the instance state listener to add.
-     * @see org.apache.felix.ipojo.ComponentInstance#addInstanceStateListener(org.apache.felix.ipojo.InstanceStateListener)
+     * Reconfigure the current instance.
+     * @param configuration : the new instance configuration.
+     * @see org.apache.felix.ipojo.ComponentInstance#reconfigure(java.util.Dictionary)
      */
-    public void addInstanceStateListener(InstanceStateListener listener) {
-        for (int i = 0; (m_instanceListeners != null) && (i < m_instanceListeners.length); i++) {
-            if (m_instanceListeners[i] == listener) {
-                return;
-            }
-        }
-
-        if (m_instanceListeners.length > 0) {
-            InstanceStateListener[] newInstances = new InstanceStateListener[m_instanceListeners.length + 1];
-            System.arraycopy(m_instanceListeners, 0, newInstances, 0, m_instanceListeners.length);
-            newInstances[m_instanceListeners.length] = listener;
-            m_instanceListeners = newInstances;
-        } else {
-            m_instanceListeners = new InstanceStateListener[] { listener };
+    public void reconfigure(Dictionary configuration) {
+        for (int i = 0; i < m_handlers.length; i++) {
+            m_handlers[i].reconfigure(configuration);
         }
     }
-    
+
     /**
      * Remove an instance state listener.
      * @param listener : the listener to remove
      * @see org.apache.felix.ipojo.ComponentInstance#removeInstanceStateListener(org.apache.felix.ipojo.InstanceStateListener)
      */
     public void removeInstanceStateListener(InstanceStateListener listener) {
-        int idx = -1;
-        for (int i = 0; i < m_instanceListeners.length; i++) {
-            if (m_instanceListeners[i] == listener) {
-                idx = i;
-                break;
-            }
-        }
-        
-        if (idx >= 0) {
-            if ((m_instanceListeners.length - 1) == 0) {
-                m_instanceListeners = new InstanceStateListener[0];
-            } else {
-                InstanceStateListener[] newInstances = new InstanceStateListener[m_instanceListeners.length - 1];
-                System.arraycopy(m_instanceListeners, 0, newInstances, 0, idx);
-                if (idx < newInstances.length) {
-                    System.arraycopy(m_instanceListeners, idx + 1, newInstances, idx, newInstances.length - idx);
-                }
-                m_instanceListeners = newInstances;
-            }
+        synchronized (m_instanceListeners) {
+            m_instanceListeners.remove(listener);
         }
     }
 
-    // ===================== end Lifecycle management =====================
-
-    // ================== Class & Instance management ===================
-
     /**
-     * Get the factory which create this instance.
-     * @return the factory of the component
-     * @see org.apache.felix.ipojo.ComponentInstance#getFactory()
+     * Set the state of the component. 
+     * if the state changed call the stateChanged(int) method on the handlers.
+     * @param state : new state
      */
-    public ComponentFactory getFactory() {
-        return m_factory;
-    }
-
-    // ======================== Handlers Management ======================
+    public void setState(int state) {
+        if (m_state != state) {
 
-    /**
-     * Register the given handler to the current instance manager.
-     * 
-     * @param h : the handler to register
-     */
-    public void register(CompositeHandler h) {
-        for (int i = 0; (m_handlers != null) && (i < m_handlers.length); i++) {
-            if (m_handlers[i] == h) {
-                return;
+            // The state changed call the handler stateChange method
+            m_state = state;
+            for (int i = m_handlers.length - 1; i > -1; i--) {
+                m_handlers[i].getHandler().stateChanged(state);
+            }
+            
+            for (int i = 0; i < m_instanceListeners.size(); i++) {
+                ((InstanceStateListener) m_instanceListeners.get(i)).stateChanged(this, state);
             }
-        }
-
-        if (m_handlers != null) {
-            CompositeHandler[] newList = new CompositeHandler[m_handlers.length + 1];
-            System.arraycopy(m_handlers, 0, newList, 0, m_handlers.length);
-            newList[m_handlers.length] = h;
-            m_handlers = newList;
         }
     }
 
     /**
-     * Unregister the given handler.
-     * 
-     * @param h : the handler to unregister
+     * Start the instance manager.
      */
-    public void unregister(CompositeHandler h) {
-        int idx = -1;
+    public synchronized void start() {
+        if (m_state > STOPPED) {
+            return;
+        } // Instance already started
+
+
+        // The new state of the component is UNRESOLVED
+        m_state = INVALID;
+
+        m_internalContext.start(); // Turn on the factory tracking
+
         for (int i = 0; i < m_handlers.length; i++) {
-            if (m_handlers[i] == h) {
-                idx = i;
-                break;
-            }
+            m_handlers[i].start();
+            m_handlers[i].addInstanceStateListener(this);
         }
-
-        if (idx >= 0) {
-            if ((m_handlers.length - 1) == 0) {
-                m_handlers = new CompositeHandler[0];
-            } else {
-                CompositeHandler[] newList = new CompositeHandler[m_handlers.length - 1];
-                System.arraycopy(m_handlers, 0, newList, 0, idx);
-                if (idx < newList.length) {
-                    System.arraycopy(m_handlers, idx + 1, newList, idx, newList.length - idx);
-                }
-                m_handlers = newList;
+        
+        for (int i = 0; i < m_handlers.length; i++) {
+            if (m_handlers[i].getState() != VALID) {
+                setState(INVALID);
+                return;
             }
         }
+        setState(VALID);
+        
     }
 
     /**
-     * Get the bundle context used by this instance.
-     * @return the parent context of the instance.
-     * @see org.apache.felix.ipojo.ComponentInstance#getContext()
-     */
-    public BundleContext getContext() {
-        return m_context;
-    }
-
-    /**
-     * Check the state of all handlers.
-     */
-    public void checkInstanceState() {
-        m_factory.getLogger().log(Logger.INFO, "[" + m_name + "] Check the instance state");
-        boolean isValid = true;
-        for (int i = 0; i < m_handlers.length; i++) {
-            boolean b = m_handlers[i].isValid();
-            isValid = isValid && b;
-        }
-
+     * State Change listener callback.
+     * This method is notified at each time a plugged handler becomes invalid.
+     * @param instance : changing instance 
+     * @param newState : new state
+     * @see org.apache.felix.ipojo.InstanceStateListener#stateChanged(org.apache.felix.ipojo.ComponentInstance, int)
+     */
+    public synchronized void stateChanged(ComponentInstance instance, int newState) {
+        if (m_state <= STOPPED) { return; }
+     
         // Update the component state if necessary
-        if (!isValid && m_state == VALID) {
+        if (newState == INVALID && m_state == VALID) {
             // Need to update the state to UNRESOLVED
             setState(INVALID);
             return;
         }
-        if (isValid && m_state == INVALID) {
-            setState(VALID);
+        if (newState == VALID && m_state == INVALID) {
+            // An handler becomes valid => check if all handlers are valid
+            boolean isValid = true;
+            for (int i = 0; i < m_handlers.length; i++) {
+                isValid = isValid && m_handlers[i].getState() == VALID;
+            }
+            
+            if (isValid) { setState(VALID); }
+        }
+        if (newState == DISPOSED) {
+            kill();
         }
     }
 
     /**
-     * Get the instance name.
-     * @return the instance name
-     * @see org.apache.felix.ipojo.ComponentInstance#getInstanceName()
+     * Stop the instance manager.
      */
-    public String getInstanceName() {
-        return m_name;
-    }
+    public synchronized void stop() {
+        if (m_state <= STOPPED) {
+            return;
+        } // Instance already stopped
 
-    /**
-     * Reconfigure the current instance.
-     * @param configuration : the new instance configuration.
-     * @see org.apache.felix.ipojo.ComponentInstance#reconfigure(java.util.Dictionary)
-     */
-    public void reconfigure(Dictionary configuration) {
-        for (int i = 0; i < m_handlers.length; i++) {
-            m_handlers[i].reconfigure(configuration);
+        setState(INVALID);
+        // Stop all the handlers
+        for (int i = m_handlers.length - 1; i > -1; i--) {
+            m_handlers[i].removeInstanceStateListener(this);
+            m_handlers[i].stop();
         }
-    }
-
-    /**
-     * Get the internal service context of this instance.
-     * @return the internal service context.
-     */
-    public ServiceContext getServiceContext() {
-        return m_internalContext;
-    }
 
-    /**
-     * Get the global bundle context.
-     * @return the global bundle context.
-     */
-    public BundleContext getGlobalContext() {
-        IPojoContext c = (IPojoContext) m_context;
-        return c.getGlobalContext();
+        m_internalContext.stop(); // Turn off the factory tracking
+        m_state = STOPPED;
+        
+        for (int i = 0; i < m_instanceListeners.size(); i++) {
+            ((InstanceStateListener) m_instanceListeners.get(i)).stateChanged(this, STOPPED);
+        }
     }
     
     /**
-     * Get the parent service context.
-     * @return the parent service context.
+     * Kill the current instance.
+     * Only the factory of this instance can call this method.
      */
-    public ServiceContext getParentServiceContext() {
-        IPojoContext c = (IPojoContext) m_context;
-        return c.getServiceContext();
+    protected synchronized void kill() {
+        if (m_state > STOPPED) { stop(); }
+        
+        for (int i = 0; i < m_instanceListeners.size(); i++) {
+            ((InstanceStateListener) m_instanceListeners.get(i)).stateChanged(this, DISPOSED);
+        }
+
+        // Cleaning
+        m_state = DISPOSED;
+        
+        for (int i = 0; i < m_handlers.length; i++) {
+            m_handlers[i].dispose();
+        }
+        m_handlers = new HandlerManager[0];
+        m_instanceListeners.clear();
     }
 }

Added: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/ConfigurationException.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/ConfigurationException.java?rev=579239&view=auto
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/ConfigurationException.java (added)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/ConfigurationException.java Tue Sep 25 06:27:49 2007
@@ -0,0 +1,62 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.ipojo;
+
+/**
+ * Configuration Exception.
+ * This exception occurs when component metadata are not correct.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ConfigurationException extends Exception {
+    
+    /**
+     * Serialization Id.
+     */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Message.
+     */
+    private String m_message;
+    
+    /**
+     * Component Type on which the error occurs.
+     */
+    private String m_type;
+    
+    /**
+     * Constructor.
+     * @param mes : message
+     * @param typ : component type
+     */
+    public ConfigurationException(String mes, String typ) {
+        m_type = typ;
+        m_message = mes;
+    }
+    
+    /**
+     * Get the error message.
+     * @return the error message.
+     * @see java.lang.Throwable#getMessage()
+     */
+    public String getMessage() {
+        return "The configuration is not correct for the type " + m_type + " : " + m_message;
+    }
+
+}

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/Extender.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/Extender.java?rev=579239&r1=579238&r2=579239&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/Extender.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/Extender.java Tue Sep 25 06:27:49 2007
@@ -66,7 +66,6 @@
      */
     private long m_bundleId;
     
-    
     /**
      * Bundle Listener Notification.
      * @param event : the bundle event.
@@ -160,10 +159,15 @@
         m_components = new Hashtable();
         m_creators = new Hashtable();
         
-        synchronized (this) {
-            for (int i = 0; i < bc.getBundles().length; i++) {
-                if (bc.getBundles()[i].getState() == Bundle.ACTIVE) {
-                    startManagementFor(bc.getBundles()[i]);
+        // Begin by initializing core handlers
+        startManagementFor(bc.getBundle());
+        
+        synchronized (m_components) {
+            synchronized (m_creators) {
+                for (int i = 0; i < bc.getBundles().length; i++) {
+                    if (bc.getBundles()[i].getState() == Bundle.ACTIVE) {
+                        startManagementFor(bc.getBundles()[i]);
+                    }
                 }
             }
         }
@@ -190,7 +194,7 @@
         m_components = null;
         Enumeration e2 = m_creators.keys();
         while (e2.hasMoreElements()) {
-            InstanceCreator creator = (InstanceCreator) m_creators.get(e2.nextElement());
+            InstanceCreator creator = (InstanceCreator) m_creators.remove(e2.nextElement());
             creator.stop();
         }
         m_creators = null;
@@ -201,9 +205,18 @@
      * @param cm : the new component metadata.
      * @param bundle : the bundle.
      */
-    private void addComponentFactory(Bundle bundle, Element cm) {        
-        ComponentFactory factory = new ComponentFactory(bundle.getBundleContext(), cm);
-        
+    private void addComponentFactory(Bundle bundle, Element cm) {
+        ComponentFactory factory = null;
+        if (cm.getName().equalsIgnoreCase("component")) {
+            factory = new ComponentFactory(bundle.getBundleContext(), cm);
+        } else if (cm.getName().equalsIgnoreCase("composite")) {
+            factory = new CompositeFactory(bundle.getBundleContext(), cm);
+        } else if (cm.getName().equalsIgnoreCase("handler")) {
+            factory = new HandlerFactory(bundle.getBundleContext(), cm);
+        } else {
+            err("Not recognized element type : " + cm.getName(), null);
+        }
+
         ComponentFactory[] cfs = (ComponentFactory[]) m_components.get(bundle);
         
         // If the factory array is not empty add the new factory at the end
@@ -219,7 +232,7 @@
     }
     
     /**
-     * Start the management factories and create instances.
+     * Start the management of factories and create instances.
      * @param bundle : the bundle. 
      * @param confs : the instances to create.
      */
@@ -227,43 +240,15 @@
         ComponentFactory[] cfs = (ComponentFactory[]) m_components.get(bundle);
         
         // Start the factories
-        for (int j = 0; cfs != null && j < cfs.length; j++) {
-            cfs[j].start();
-        }
-
-        Dictionary[] outsiders = new Dictionary[0];
-        
-        for (int i = 0; confs != null && i < confs.length; i++) {
-            Dictionary conf = confs[i];
-            boolean created = false;
-            for (int j = 0; cfs != null && j < cfs.length; j++) {
-                String componentClass = cfs[j].getComponentClassName();
-                String factoryName = cfs[j].getName();
-                String componentName = cfs[j].getComponentTypeName();
-                if (conf.get("component") != null && (conf.get("component").equals(componentClass) || conf.get("component").equals(factoryName)) || conf.get("component").equals(componentName)) {
-                    try {
-                        cfs[j].createComponentInstance(conf);
-                        created = true;
-                    } catch (UnacceptableConfiguration e) {
-                        System.err.println("Cannot create the instance " + conf.get("name") + " : " + e.getMessage());
-                    }
-                }
-            }
-            if (!created && conf.get("component") != null) {
-                if (outsiders.length != 0) {
-                    Dictionary[] newList = new Dictionary[outsiders.length + 1];
-                    System.arraycopy(outsiders, 0, newList, 0, outsiders.length);
-                    newList[outsiders.length] = conf;
-                    outsiders = newList;
-                } else {
-                    outsiders = new Dictionary[] { conf };
-                }
+        if (cfs != null) {
+            for (int j = 0; j < cfs.length; j++) {
+                cfs[j].start();
             }
         }
 
         // Create the instance creator if needed.
-        if (outsiders.length > 0) {
-            m_creators.put(bundle, new InstanceCreator(bundle.getBundleContext(), outsiders));
+        if (confs.length > 0) {
+            m_creators.put(bundle, new InstanceCreator(bundle.getBundleContext(), confs, cfs));
         }
     }
     
@@ -285,5 +270,4 @@
             System.err.println("[iPOJO-Core] " + message);
         }
     }
-
 }

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/Factory.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/Factory.java?rev=579239&r1=579238&r2=579239&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/Factory.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/Factory.java Tue Sep 25 06:27:49 2007
@@ -19,49 +19,62 @@
 package org.apache.felix.ipojo;
 
 import java.util.Dictionary;
+import java.util.List;
 
+import org.apache.felix.ipojo.architecture.ComponentDescription;
 import org.apache.felix.ipojo.metadata.Element;
 
 /**
- * Component Type Factory Service. This service is exposed by a instance manager
- * factory, and allows the dynamic creation of component instance.
- * 
+ * Component Type Factory Service. This service is exposed by a instance manager factory, and allows the dynamic creation of component instance.
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
 public interface Factory {
 
     /**
+     * Factory State. A valid factory is a factory where all required handlers are available.
+     */
+    int VALID = 1;
+
+    /**
+     * Factory State. An invalid factory is a factory where at least one required handler is unavailable. Creating an instance with an invalid factory failed.
+     */
+    int INVALID = 0;
+
+    /**
      * Create an instance manager (i.e. component type instance).
-     * 
      * @param configuration : the configuration properties for this component.
      * @return the created instance manager.
      * @throws UnacceptableConfiguration : when a given configuration is not valid.
+     * @throws MissingHandlerException : when an handler is missing.
+     * @throws ConfigurationException : when the instance configuration failed.
      */
-    ComponentInstance createComponentInstance(Dictionary configuration) throws UnacceptableConfiguration;
+    ComponentInstance createComponentInstance(Dictionary configuration) throws UnacceptableConfiguration, MissingHandlerException, ConfigurationException;
 
     /**
-     * Create an instance manager (i.e. component type instance). This has these
-     * service interaction in the scope given in argument.
-     * 
+     * Create an instance manager (i.e. component type instance). This has these service interaction in the scope given in argument.
      * @param configuration : the configuration properties for this component.
      * @param serviceContext : the service context of the component.
      * @return the created instance manager.
      * @throws UnacceptableConfiguration : when the given configuration is not valid.
+     * @throws MissingHandlerException : when an handler is missing.
+     * @throws ConfigurationException : when the instance configuration failed.
      */
-    ComponentInstance createComponentInstance(Dictionary configuration, ServiceContext serviceContext) throws UnacceptableConfiguration;
+    ComponentInstance createComponentInstance(Dictionary configuration, ServiceContext serviceContext) throws UnacceptableConfiguration, MissingHandlerException, ConfigurationException;
 
     /**
-     * Get the component type information containing provided service,
-     * configuration properties ...
-     * 
+     * Get the component type information containing provided service, configuration properties ...
      * @return the component type information.
      */
     Element getDescription();
 
     /**
-     * Check if the given configuration is acceptable as a configuration of a
-     * component instance.
-     * 
+     * Get the component type description.
+     * @return the component type description object
+     */
+    ComponentDescription getComponentDescription();
+
+    /**
+     * Check if the given configuration is acceptable as a configuration of a component instance.
      * @param conf : the configuration to test
      * @return true if the configuration is acceptable
      */
@@ -74,13 +87,35 @@
     String getName();
 
     /**
-     * Reconfigure an instance already created. This configuration need to have
-     * the name property to identify the instance.
-     * 
+     * Reconfigure an instance already created. This configuration need to have the name property to identify the instance.
      * @param conf : the configuration to reconfigure the instance.
-     * @throws UnacceptableConfiguration : if the given configuration is not
-     * consistent for the targeted instance.
+     * @throws UnacceptableConfiguration : if the given configuration is not consistent for the targeted instance.
+     * @throws MissingHandlerException : when an handler is missing.
+     */
+    void reconfigure(Dictionary conf) throws UnacceptableConfiguration, MissingHandlerException;
+
+    /**
+     * Add a factory state listener on the current factory.
+     * @param l : the listener to add
+     */
+    void addFactoryStateListener(FactoryStateListener l);
+
+    /**
+     * Remove the given factory state listener from the listener list.
+     * @param l : the listener to remove
+     */
+    void removeFactoryStateListener(FactoryStateListener l);
+
+    /**
+     * Get the list of missing handlers.
+     * @return the list containing the name of missing handlers (Name : namespace:name)
+     */
+    List getMissingHandlers();
+
+    /**
+     * Get the list of required handlers.
+     * @return the list containing the name of required handlers (Name : namespace:name)
      */
-    void reconfigure(Dictionary conf) throws UnacceptableConfiguration;
+    List getRequiredHandlers();
 
 }

Added: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/FactoryStateListener.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/FactoryStateListener.java?rev=579239&view=auto
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/FactoryStateListener.java (added)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/FactoryStateListener.java Tue Sep 25 06:27:49 2007
@@ -0,0 +1,35 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.ipojo;
+
+/**
+ * Factory state listener.
+ * This listener allows anyone to be notified when the listened factory state changes. 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public interface FactoryStateListener {
+    
+    /**
+     * State change listener.
+     * Each time an instance state change, this method is called.
+     * @param factory : changing factory
+     * @param newState : new instance state
+     */
+    void stateChanged(Factory factory, int newState);
+}

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/Handler.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/Handler.java?rev=579239&r1=579238&r2=579239&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/Handler.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/Handler.java Tue Sep 25 06:27:49 2007
@@ -20,100 +20,126 @@
 
 import java.util.Dictionary;
 
+import org.apache.felix.ipojo.architecture.ComponentDescription;
 import org.apache.felix.ipojo.architecture.HandlerDescription;
 import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.util.Logger;
 
 /**
- * Handler Abstract Class. An handler need implements these method to be notified
- * of lifecycle change, GETFIELD & PUTFIELD instruction as well as method entry and exit.
+ * Handler Abstract Class.
  * 
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
 public abstract class Handler {
-
+    
     /**
-     * Configure the handler.
-     * 
-     * @param im : the instance manager
-     * @param metadata : the metadata of the component
-     * @param configuration : the instance configuration
+     * Handler namespace property.
      */
-    public abstract void configure(InstanceManager im, Element metadata, Dictionary configuration);
-
+    public static final String HANDLER_NAMESPACE_PROPERTY = "handler.namespace";
+    
     /**
-     * Stop the handler : stop the management.
+     * Handler name property. 
      */
-    public abstract void stop();
-
+    public static final String HANDLER_NAME_PROPERTY = "handler.name";
+    
     /**
-     * Start the handler : start the management.
+     * Handler type property. 
      */
-    public abstract void start();
-
+    public static final String HANDLER_TYPE_PROPERTY = "handler.type";
+    
     /**
-     * This method is called when a PUTFIELD operation is detected.
-     * 
-     * @param fieldName : the field name
-     * @param value : the value passed to the field
+     * Log method.
+     * @param level : message level (Logger class constant)
+     * @param message : message to log
      */
-    public void setterCallback(String fieldName, Object value) {
-    }
-
+    public abstract void log(int level, String message);
+    
+    /**
+     * Log method.
+     * @param level : message level (Logger class constant)
+     * @param message : message to log
+     * @param ex : exception to attach to the message
+     */
+    public abstract void log(int level, String message, Throwable ex);
+    
+    /**
+     * Get a plugged handler of the same container.
+     * This method must be call only in the start method (or after). 
+     * In the configure method, this method can not return a consistent
+     * result as all handlers are not plugged. 
+     * @param name : name of the handler to find (class name or qualified handler name (ns:name)). 
+     * @return the handler object or null if the handler is not found.
+     */
+    public abstract Handler getHandler(String name);
+    
     /**
-     * This method is called when a GETFIELD operation is detected.
-     * 
-     * @param fieldName : the field name
-     * @param value : the value passed to the field (by the previous handler)
-     * @return : the managed value of the field
+     * Attach the current handler object to the given component instance.
+     * An attached handler becomes a part of the instance container.
+     * @param ci : the component instance on which the current handler will be attached.
      */
-    public Object getterCallback(String fieldName, Object value) {
-        return value;
+    protected abstract void attach(ComponentInstance ci);
+    
+    /**
+     * Check if the current handler is valid.
+     * This method must not be override.
+     * @return true if the handler is valid.
+     */
+    public final boolean isValid() {
+        if (this instanceof Pojo) {
+            return getInstance().getState() == ComponentInstance.VALID;
+        } else {
+            log(Logger.ERROR, "The handler is not a POJO : " + this.getClass().getName());
+            return false;
+        }
     }
     
+    
     /**
-     * This method is called when the execution enter in a method.
-     * 
-     * @param methodId : the method identifier
+     * Get the component instance of the current handler.
+     * @return : the component instance.
      */
-    public void entryCallback(String methodId) {
+    public final ComponentInstance getInstance() {
+        if (this instanceof Pojo) {
+            return ((Pojo) this).getComponentInstance();
+        } else {
+            log(Logger.ERROR, "The handler is not a POJO : " + this.getClass().getName());
+            return null;
+        }
     }
+    
+    /**
+     * Initialize component factory.
+     * This method aims to gather component factory properties. Each handler wanting to contribute need to override this 
+     * method and add properties to the given component description.
+     * @param cd : component description.
+     * @param metadata : component type metadata.
+     * @throws ConfigurationException : if the metadata are not correct (early detection).
+     */
+    public void initializeComponentFactory(ComponentDescription cd, Element metadata) throws ConfigurationException {  }
 
     /**
-     * This method is called when the execution exit a method (before a return or a throw).
-     * If the given returned object is an instance of Exception, this means that the method throwed this exception.
-     * If the given returned object is null, either the method is void, either it returns null.
-     * You must not modified the returned object.
-     * @param methodId : the method identifier
-     * @param returnedObj : the returned object (boxed for primitive type)
+     * Configure the handler.
+     * @param metadata : the metadata of the component
+     * @param configuration : the instance configuration
+     * @throws ConfigurationException : if the metadata are not correct.
      */
-    public void exitCallback(String methodId, Object returnedObj) {
-    }
+    public abstract void configure(Element metadata, Dictionary configuration) throws ConfigurationException;
 
     /**
-     * Is the actual state valid for this handler ?
-     * 
-     * @return true is the state seems valid for the handler
+     * Stop the handler : stop the management.
      */
-    public boolean isValid() {
-        return true;
-    }
+    public abstract void stop();
 
     /**
-     * This method is called when the component state changed.
-     * 
-     * @param state : the new state
+     * Start the handler : start the management.
      */
-    public void stateChanged(int state) {
-    }
+    public abstract void start();
 
     /**
-     * This method is called when an instance of the component is created, but
-     * before someone can use it.
-     * 
-     * @param instance : the created instance
+     * This method is called when the component state changed.
+     * @param state : the new state
      */
-    public void createInstance(Object instance) {
-    }
+    public void stateChanged(int state) { }
 
     /**
      * Return the current handler description.
@@ -121,14 +147,12 @@
      * @return the description of the handler..
      */
     public HandlerDescription getDescription() {
-        return new HandlerDescription(this.getClass().getName(), isValid());
+        return new HandlerDescription(this);
     }
 
     /**
      * The instance is reconfiguring.
-     * 
      * @param configuration : New instance configuration.
      */
-    public void reconfigure(Dictionary configuration) {
-    }
+    public void reconfigure(Dictionary configuration) { }
 }

Added: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/HandlerFactory.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/HandlerFactory.java?rev=579239&view=auto
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/HandlerFactory.java (added)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/HandlerFactory.java Tue Sep 25 06:27:49 2007
@@ -0,0 +1,258 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.ipojo;
+
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.util.Logger;
+import org.apache.felix.ipojo.util.Tracker;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceRegistration;
+
+/**
+ * The component factory manages component instance objects. This management
+ * consist in creating and managing component instance build with the component
+ * factory. This class could export Factory and ManagedServiceFactory services.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class HandlerFactory extends ComponentFactory implements Factory {
+
+    /**
+     * Service Registration of this factory (Factory & ManagedServiceFactory).
+     */
+    private ServiceRegistration m_sr;
+    
+    /**
+     * Handler type (composite|primitive).
+     * Default: handler.
+     */
+    private String m_type = "primitive";
+    
+    /**
+     * Default iPOJO Namespace.
+     */
+    private String m_namespace = IPojoConfiguration.IPOJO_NAMESPACE;
+
+    /**
+     * Create a composite factory.
+     * @param bc : bundle context
+     * @param cm : metadata of the component to create
+     */
+    public HandlerFactory(BundleContext bc, Element cm) {
+        super(bc, cm);
+        
+        // Get the name
+        if (cm.containsAttribute("name")) {
+            m_typeName = cm.getAttribute("name").toLowerCase();
+        } else {
+            System.err.println("An Handler needs a name");
+            return;
+        }
+        
+        // Get the type
+        if (cm.containsAttribute("type")) {
+            m_type = cm.getAttribute("type");
+        }
+        
+        // Get the namespace
+        if (cm.containsAttribute("namespace")) {
+            m_namespace = cm.getAttribute("namespace").toLowerCase();
+        }        
+    }
+    
+    public String getNamespace() {
+        return m_namespace;
+    }
+    
+    public String getHandlerName() {
+        return m_namespace + ":" + getName();
+    }
+    
+    public String getType() {
+        return m_type;
+    }
+
+    /**
+     * Start all the instance managers.
+     */
+    public synchronized void start() {
+        if (m_componentDesc != null) { // Already started.
+            return;
+        } 
+        
+        try {
+            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;
+        }
+                
+        computeFactoryState();
+        
+        // Check if the factory should be exposed
+        if (m_factoryName == null) { return; }
+        
+        // Exposition of the factory service
+        m_sr = m_context.registerService(new String[] { Factory.class.getName()}, this, getProperties());
+    }
+    
+    /**
+     * Stop the factory.
+     * This method does not disposed created instances.
+     * These instances will be disposed by the instance managers.
+     */
+    public synchronized void stop() {
+        if (m_sr != null) {
+            m_sr.unregister();
+            m_sr = null;
+        }
+        
+        m_tracker.close();
+        
+        // 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_handlerIdentifiers.clear();        
+        m_listeners.clear();
+        m_tracker = null;
+        m_componentDesc = null;
+        m_state = INVALID;        
+    }
+    
+    
+    /**
+     * Compute factory service properties.
+     * This method add three mandatory handler factory properties (name, namespace and type)
+     * @return the properties.
+     * @see org.apache.felix.ipojo.ComponentFactory#getProperties()
+     */
+    protected Properties getProperties() {
+        final Properties props = super.getProperties();
+
+        props.put(Handler.HANDLER_NAME_PROPERTY, m_typeName);
+        props.put(Handler.HANDLER_NAMESPACE_PROPERTY, m_namespace);
+        props.put(Handler.HANDLER_TYPE_PROPERTY, m_type);
+        
+        return props;
+    }
+    
+    /**
+     * 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 ComponentInstance createComponentInstance(Dictionary configuration, ServiceContext serviceContext) throws UnacceptableConfiguration, MissingHandlerException, org.apache.felix.ipojo.ConfigurationException {
+        if (m_state == INVALID) {
+            throw new MissingHandlerException(getMissingHandlers());
+        }
+        
+        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.getMessage());
+        }
+
+        
+        String in = null;
+        if (configuration.get("name") != null) {
+            in = (String) configuration.get("name");
+        } else {
+            in = generateName();
+            configuration.put("name", in);
+        }
+        
+        if (m_instancesName.contains(in)) {
+            throw new UnacceptableConfiguration("Name already used : " + in);
+        } else {
+            m_instancesName.add(in);
+        }
+
+        BundleContext context = null;
+        if (serviceContext == null) {
+            context = new IPojoContext(m_context);
+        } else {
+            context = new IPojoContext(m_context, serviceContext);
+        }
+        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));
+        }
+        HandlerManager instance = new HandlerManager(this, context, (HandlerManager[]) handlers.toArray(new HandlerManager[0]));
+        instance.configure(m_componentMetadata, configuration);
+
+        m_componentInstances.put(in, instance);
+        
+        
+        return instance;
+    }
+    
+    /**
+     * 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;
+        }
+    }
+}

Added: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/HandlerManager.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/HandlerManager.java?rev=579239&view=auto
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/HandlerManager.java (added)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/HandlerManager.java Tue Sep 25 06:27:49 2007
@@ -0,0 +1,159 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.ipojo;
+
+import java.util.Dictionary;
+
+import org.apache.felix.ipojo.metadata.Element;
+import org.osgi.framework.BundleContext;
+
+/**
+* The handler manager manages an handler instance.
+* 
+* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+*/
+public class HandlerManager extends InstanceManager {
+    
+    /**
+     * Handler object (contained).
+     */
+    private Handler m_handler;
+
+    /**
+     * Constructor.
+     * @param factory : handler factory
+     * @param bc : bundle context
+     * @param handlers : handler array
+     */
+    public HandlerManager(ComponentFactory factory, BundleContext bc, HandlerManager[] handlers) {
+        super(factory, bc, handlers);
+    }
+    
+    /**
+     * Get the contained handler object.
+     * If not already created it creates the object.
+     * @return the handler object.
+     */
+    public Handler getHandler() {
+        if (m_handler == null) {
+            createHandlerObject();
+        }
+        return m_handler;
+    }
+    
+    /**
+     * Create and initialize the handler object.
+     * @param ci : component instance on which the handler will be attached.
+     * @param cm : component metadata.
+     * @param configuration : instance configuration.
+     * @throws ConfigurationException if the handler configuration failed.
+     */
+    public void init(ComponentInstance ci, Element cm, Dictionary configuration) throws ConfigurationException {
+        createHandlerObject();
+        m_handler.attach(ci);
+        m_handler.configure(cm, configuration);
+    }
+    
+    /**
+     * Create the handler object.
+     * This method does nothing if the object is already created.
+     */
+    private void createHandlerObject() {
+        if (m_handler != null) { return; }
+        Handler h  = (Handler) createPojoObject();
+        if (h instanceof PrimitiveHandler) {
+            m_handler = (PrimitiveHandler) h;
+        } else {
+            m_handler = (CompositeHandler) h;
+        }
+    }
+    
+    /**
+     * Start the instance manager.
+     */
+    public synchronized void start() {
+        if (m_state != STOPPED) {
+            return;
+        } // Instance already started
+
+        for (int i = 0; i < m_handlers.length; i++) {
+            m_handlers[i].addInstanceStateListener(this);
+            m_handlers[i].start();
+        }
+        
+        m_handler.start(); // Call the handler start method.
+        
+        for (int i = 0; i < m_handlers.length; i++) {
+            if (! m_handlers[i].getHandler().isValid()) {
+                setState(INVALID);
+                return;
+            }
+        }
+        setState(VALID);
+    }
+    
+    /**
+     * Stop the instance manager.
+     */
+    public synchronized void stop() {
+        if (m_state == STOPPED) {
+            return;
+        } // Instance already stopped
+        
+
+        setState(INVALID);
+        
+        m_handler.stop();
+        
+        // Stop all the handlers
+        for (int i = m_handlers.length - 1; i > -1; i--) {
+            m_handlers[i].removeInstanceStateListener(this);
+            m_handlers[i].stop();
+        }
+
+        m_state = STOPPED;
+        for (int i = 0; i < m_instanceListeners.size(); i++) {
+            ((InstanceStateListener) m_instanceListeners.get(i)).stateChanged(this, STOPPED);
+        }
+    }
+    
+    /** 
+     * Dispose the instance.
+     * @see org.apache.felix.ipojo.ComponentInstance#dispose()
+     */
+    public synchronized void dispose() {
+        super.dispose();
+        m_handler = null;
+    }
+    
+    /**
+     * Kill the current instance.
+     * Only the factory of this instance can call this method.
+     */
+    protected void kill() {
+        super.dispose();
+        m_handler = null;
+    }
+
+    
+    
+    
+   
+
+}



Mime
View raw message