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 [3/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/...

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoConfiguration.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoConfiguration.java?rev=579239&r1=579238&r2=579239&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoConfiguration.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoConfiguration.java Tue Sep 25 06:27:49 2007
@@ -19,7 +19,7 @@
 package org.apache.felix.ipojo;
 
 import org.apache.felix.ipojo.composite.instance.InstanceHandler;
-import org.apache.felix.ipojo.composite.service.importer.ImportExportHandler;
+import org.apache.felix.ipojo.composite.service.importer.ImportHandler;
 import org.apache.felix.ipojo.composite.service.instantiator.ServiceInstantiatorHandler;
 import org.apache.felix.ipojo.handlers.architecture.ArchitectureHandler;
 import org.apache.felix.ipojo.handlers.configuration.ConfigurationHandler;
@@ -39,6 +39,12 @@
      * iPOJO logger log level.
      */
     public static final int LOG_LEVEL = Logger.WARNING;
+    
+    
+    /**
+     * iPOJO Default Namespace.
+     */
+    public static final String IPOJO_NAMESPACE = "org.apache.felix.ipojo";
 
     /**
      * Available handlers in the iPOJO bundle.
@@ -57,10 +63,11 @@
      */
     public static final Class[] INTERNAL_COMPOSITE_HANDLERS = new Class[] { 
         ServiceInstantiatorHandler.class, 
-        ImportExportHandler.class,
+        ImportHandler.class,
         InstanceHandler.class,
         org.apache.felix.ipojo.composite.service.provides.ProvidedServiceHandler.class,
         org.apache.felix.ipojo.composite.architecture.ArchitectureHandler.class
     };
+    
 
 }

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoContext.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoContext.java?rev=579239&r1=579238&r2=579239&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoContext.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoContext.java Tue Sep 25 06:27:49 2007
@@ -39,7 +39,7 @@
  * 
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public class IPojoContext implements BundleContext {
+public class IPojoContext implements BundleContext, ServiceContext {
 
     /**
      * BundleContext used to access bundle method.
@@ -58,7 +58,6 @@
      */
     public IPojoContext(BundleContext bc) {
         m_bundleContext = bc;
-        m_serviceContext = new DefaultServiceContext(bc);
     }
 
     /**
@@ -100,7 +99,11 @@
      * @see org.osgi.framework.BundleContext#addServiceListener(org.osgi.framework.ServiceListener, java.lang.String)
      */
     public void addServiceListener(ServiceListener listener, String filter) throws InvalidSyntaxException {
-        m_serviceContext.addServiceListener(listener, filter);
+        if (m_serviceContext == null) {
+            m_bundleContext.addServiceListener(listener, filter);
+        } else {
+            m_serviceContext.addServiceListener(listener, filter);
+        }
     }
 
     /**
@@ -109,7 +112,11 @@
      * @see org.osgi.framework.BundleContext#addServiceListener(org.osgi.framework.ServiceListener)
      */
     public void addServiceListener(ServiceListener listener) {
-        m_serviceContext.addServiceListener(listener);
+        if (m_serviceContext == null) {
+            m_bundleContext.addServiceListener(listener);
+        } else {
+            m_serviceContext.addServiceListener(listener);
+        }
     }
 
 
@@ -133,7 +140,11 @@
      * @see org.osgi.framework.BundleContext#getAllServiceReferences(java.lang.String, java.lang.String)
      */
     public ServiceReference[] getAllServiceReferences(String clazz, String filter) throws InvalidSyntaxException {
-        return m_serviceContext.getAllServiceReferences(clazz, filter);
+        if (m_serviceContext == null) {
+            return m_bundleContext.getAllServiceReferences(clazz, filter);
+        } else {
+            return m_serviceContext.getAllServiceReferences(clazz, filter);
+        }
     }
 
     /**
@@ -192,7 +203,11 @@
      * @see org.osgi.framework.BundleContext#getService(org.osgi.framework.ServiceReference)
      */
     public Object getService(ServiceReference reference) {
-        return m_serviceContext.getService(reference);
+        if (m_serviceContext == null) {
+            return m_bundleContext.getService(reference);
+        } else {
+            return m_serviceContext.getService(reference);
+        }
     }
 
     /**
@@ -202,7 +217,11 @@
      * @see org.osgi.framework.BundleContext#getServiceReference(java.lang.String)
      */
     public ServiceReference getServiceReference(String clazz) {
-        return m_serviceContext.getServiceReference(clazz);
+        if (m_serviceContext == null) {
+            return m_bundleContext.getServiceReference(clazz);
+        } else {
+            return m_serviceContext.getServiceReference(clazz);
+        }
     }
 
     /**
@@ -214,7 +233,11 @@
      * @see org.osgi.framework.BundleContext#getServiceReferences(java.lang.String, java.lang.String)
      */
     public ServiceReference[] getServiceReferences(String clazz, String filter) throws InvalidSyntaxException {
-        return m_serviceContext.getServiceReferences(clazz, filter);
+        if (m_serviceContext == null) {
+            return m_bundleContext.getServiceReferences(clazz, filter);
+        } else {
+            return m_serviceContext.getServiceReferences(clazz, filter);
+        }
     }
 
     /**
@@ -249,7 +272,11 @@
      * @see org.apache.felix.ipojo.ServiceContext#registerService(java.lang.String[], java.lang.Object, java.util.Dictionary)
      */
     public ServiceRegistration registerService(String[] clazzes, Object service, Dictionary properties) {
-        return m_serviceContext.registerService(clazzes, service, properties);
+        if (m_serviceContext == null) {
+            return m_bundleContext.registerService(clazzes, service, properties);
+        } else {
+            return m_serviceContext.registerService(clazzes, service, properties);
+        }
     }
 
     /**
@@ -261,7 +288,11 @@
      * @see org.osgi.framework.BundleContext#registerService(java.lang.String, java.lang.Object, java.util.Dictionary)
      */
     public ServiceRegistration registerService(String clazz, Object service, Dictionary properties) {
-        return m_serviceContext.registerService(clazz, service, properties);
+        if (m_serviceContext == null) {
+            return m_bundleContext.registerService(clazz, service, properties);
+        } else {
+            return m_serviceContext.registerService(clazz, service, properties);
+        }
     }
 
     /**
@@ -289,7 +320,11 @@
      * @see org.osgi.framework.BundleContext#removeServiceListener(org.osgi.framework.ServiceListener)
      */
     public void removeServiceListener(ServiceListener listener) {
-        m_serviceContext.removeServiceListener(listener);
+        if (m_serviceContext == null) {
+            m_bundleContext.removeServiceListener(listener);
+        } else {
+            m_serviceContext.removeServiceListener(listener);
+        }
     }
 
     /**
@@ -299,7 +334,11 @@
      * @see org.osgi.framework.BundleContext#ungetService(org.osgi.framework.ServiceReference)
      */
     public boolean ungetService(ServiceReference reference) {
-        return m_serviceContext.ungetService(reference);
+        if (m_serviceContext == null) {
+            return m_bundleContext.ungetService(reference);
+        } else {
+            return m_serviceContext.ungetService(reference);
+        }
     }
     
     /**
@@ -315,6 +354,9 @@
      * @return the service context.
      */
     public ServiceContext getServiceContext() {
+        if (m_serviceContext == null) {
+            return this;
+        }
         return m_serviceContext;
     }
 

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceCreator.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceCreator.java?rev=579239&r1=579238&r2=579239&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceCreator.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceCreator.java Tue Sep 25 06:27:49 2007
@@ -21,10 +21,10 @@
 import java.util.Dictionary;
 
 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.InvalidSyntaxException;
-import org.osgi.framework.ServiceEvent;
-import org.osgi.framework.ServiceListener;
 import org.osgi.framework.ServiceReference;
 
 /**
@@ -33,7 +33,7 @@
  * 
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public class InstanceCreator implements ServiceListener {
+public class InstanceCreator implements TrackerCustomizer, FactoryStateListener {
     /**
      * Bundle Context.
      */
@@ -43,6 +43,11 @@
      * Logger to log messages if error occurs.
      */
     private Logger m_logger;
+    
+    /**
+     * Private factories.
+     */
+    private ComponentFactory[] m_factories;
 
     /**
      * This structure aims to manage a configuration. It stores all necessary
@@ -122,44 +127,52 @@
     private ManagedConfiguration[] m_configurations = new ManagedConfiguration[0];
 
     /**
+     * Service Tracker tracking factories.
+     */
+    private Tracker m_tracker;
+
+    /**
      * Constructor.
      * 
      * @param context : the bundle context.
      * @param configurations : configuration set to create and maintain.
+     * @param factories : private factories.
      */
-    public InstanceCreator(BundleContext context, Dictionary[] configurations) {
+    public InstanceCreator(BundleContext context, Dictionary[] configurations, ComponentFactory[] factories) {
         m_context = context;
         m_logger = new Logger(context, "InstanceCreator" + context.getBundle().getBundleId(), Logger.WARNING);
+        
         m_configurations = new ManagedConfiguration[configurations.length];
+        m_factories = factories;
+       
         for (int i = 0; i < configurations.length; i++) {
             ManagedConfiguration conf = new ManagedConfiguration(configurations[i]);
             m_configurations[i] = conf;
-
             // Get the component type name :
             String componentType = (String) conf.getConfiguration().get("component");
-            Factory fact = null;
 
-            try {
-                String fil = "(|(" + org.osgi.framework.Constants.SERVICE_PID + "=" + componentType + ")" 
-                    + "(component.class=" + componentType + ")(component.type=" + componentType + "))";
-                ServiceReference[] refs = context.getServiceReferences(org.apache.felix.ipojo.Factory.class.getName(), fil);
-                if (refs != null) {
-                    fact = (Factory) m_context.getService(refs[0]);
-                    createInstance(fact, conf);
-                } else {
-                    m_logger.log(Logger.WARNING, "No factory available for the type : " + componentType);
+            boolean found = false;
+            for (int j = 0; m_factories != null && !found && j < m_factories.length; j++) {
+                if (m_factories[j].m_state == Factory.VALID && (m_factories[j].getName().equals(componentType) || (m_factories[j].getComponentClassName() != null && m_factories[j].getComponentClassName().equals(componentType)))) {
+                    createInstance(m_factories[j], conf);
+                    found = true;
                 }
-            } catch (InvalidSyntaxException e) {
-                m_logger.log(Logger.ERROR, "Invalid syntax filter for the type : " + componentType, e);
             }
         }
-
-        // Register a service listener on Factory Service
+        
+        for (int i = 0; m_factories != null && i < m_factories.length; i++) {
+            m_factories[i].addFactoryStateListener(this);
+        }
+       
+        
+        String filter = "(&(objectclass=" + Factory.class.getName() + ")(factory.state=1))";
         try {
-            m_context.addServiceListener(this, "(objectClass=" + Factory.class.getName() + ")");
+            m_tracker = new Tracker(m_context, m_context.createFilter(filter), this);
+            m_tracker.open();
         } catch (InvalidSyntaxException e) {
-            m_logger.log(Logger.ERROR, "Invalid syntax filter when registering a listener on Factory Service", e);
-        }
+            e.printStackTrace();
+            return;
+        } 
     }
 
     /**
@@ -175,37 +188,60 @@
             config.setFactory(fact.getName());
         } catch (UnacceptableConfiguration e) {
             m_logger.log(Logger.ERROR, "A factory is available for the configuration but the configuration is not acceptable", e);
+        } catch (MissingHandlerException e) {
+            m_logger.log(Logger.ERROR, "The instance creation has failed, at least one handler is missing", e);
+        } catch (ConfigurationException e) {
+            m_logger.log(Logger.ERROR, "The instance creation has failed, an error during the configuration has occured", e);
         }
     }
 
     /**
-     * Service Listener implementation.
-     * @param ev : the service event
-     * @see org.osgi.framework.ServiceListener#serviceChanged(org.osgi.framework.ServiceEvent)
-     */
-    public void serviceChanged(ServiceEvent ev) {
-        ServiceReference ref = ev.getServiceReference();
-        String factoryName = (String) ref.getProperty(org.osgi.framework.Constants.SERVICE_PID);
-        String componentClass = (String) ref.getProperty("component.class");
+     * Stop all created instances.
+     */
+    public synchronized void stop() {
+        m_tracker.close();
+        
+        for (int i = 0; m_factories != null && i < m_factories.length; i++) {
+            m_factories[i].removeFactoryStateListener(this);
+        }
+        
+        for (int i = 0; i < m_configurations.length; i++) {
+            if (m_configurations[i].getInstance() != null) {
+                m_configurations[i].getInstance().dispose();
+            }
+            m_configurations[i].setInstance(null);
+            m_configurations[i].setFactory(null);
+        }
+        
+        m_factories = null;
+        m_tracker = null;
+        m_logger = null;
+        m_configurations = null;
+    }
 
-        if (ev.getType() == ServiceEvent.REGISTERED) { // A new factory appears
+    /**
+     * Factory state changed method.
+     * @param factory : factory.
+     * @param newState : new state.
+     * @see org.apache.felix.ipojo.FactoryStateListener#stateChanged(org.apache.felix.ipojo.Factory, int)
+     */
+    public void stateChanged(Factory factory, int newState) {
+        if (newState == Factory.VALID) {
             for (int i = 0; i < m_configurations.length; i++) {
                 if (m_configurations[i].getInstance() == null
-                        && (m_configurations[i].getConfiguration().get("component").equals(factoryName) || m_configurations[i].getConfiguration().get(
-                                "component").equals(componentClass))) {
-                    Factory fact = (Factory) m_context.getService(ref);
+                        && (m_configurations[i].getConfiguration().get("component").equals(factory.getName()) || m_configurations[i].getConfiguration().get(
+                                "component").equals(((ComponentFactory) factory).getComponentClassName()))) {
+                    Factory fact = factory;
                     createInstance(fact, m_configurations[i]);
                 }
             }
             return;
-        }
-
-        if (ev.getType() == ServiceEvent.UNREGISTERING) {
+        } else {
+            // newState == INVALID
             for (int i = 0; i < m_configurations.length; i++) {
-                if (m_configurations[i].getInstance() != null && m_configurations[i].getFactory().equals(factoryName)) {
+                if (m_configurations[i].getInstance() != null && m_configurations[i].getFactory().equals(factory.getName())) {
                     m_configurations[i].setInstance(null);
                     m_configurations[i].setFactory(null);
-                    m_context.ungetService(ref);
                 }
             }
             return;
@@ -213,18 +249,56 @@
     }
 
     /**
-     * Stop all created instances.
+     * A new factory has been detected.
+     * @param ref : the factory service reference.
+     * @return true if the factory can be used to create a managed instance.
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addingService(org.osgi.framework.ServiceReference)
      */
-    public synchronized void stop() {
-        m_context.removeServiceListener(this);
+    public boolean addingService(ServiceReference ref) {
+        String factoryName = (String) ref.getProperty("factory.name");
+        String componentClass = (String) ref.getProperty("component.class");
+        boolean isValid = ((String) ref.getProperty("factory.state")).equals("" + Factory.VALID); 
+        Factory fact = (Factory) m_tracker.getService(ref);
+
+        boolean used = false;
+        if (isValid) {
+            for (int i = 0; i < m_configurations.length; i++) {
+                if (m_configurations[i].getInstance() == null
+                        && (m_configurations[i].getConfiguration().get("component").equals(factoryName) || m_configurations[i].getConfiguration().get("component").equals(componentClass))) {
+                    createInstance(fact, m_configurations[i]);
+                    used = true;
+                }
+            }
+        }
+        return used;
+    }
+
+    /**
+     * A used factory is modified.
+     * @param ref : modified reference.
+     * @param obj : factory object.
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#modifiedService(org.osgi.framework.ServiceReference, java.lang.Object)
+     */
+    public void modifiedService(ServiceReference ref, Object obj) {
+        // Nothing to do.
+    }
+
+    /**
+     * A used factory disappears.
+     * All created instance are disposed.
+     * @param ref : service reference.
+     * @param obj : factory object.
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#removedService(org.osgi.framework.ServiceReference, java.lang.Object)
+     */
+    public void removedService(ServiceReference ref, Object obj) {
+        Factory fact = (Factory) obj;
         for (int i = 0; i < m_configurations.length; i++) {
-            if (m_configurations[i].getInstance() != null) {
-                m_configurations[i].getInstance().dispose();
+            if (m_configurations[i].getInstance() != null && m_configurations[i].getFactory().equals(fact.getName())) {
+                m_configurations[i].setInstance(null);
+                m_configurations[i].setFactory(null);
             }
-            m_configurations[i].setInstance(null);
-            m_configurations[i].setFactory(null);
         }
-        m_configurations = null;
+        m_tracker.ungetService(ref);
     }
 
 }

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceManager.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceManager.java?rev=579239&r1=579238&r2=579239&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceManager.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceManager.java Tue Sep 25 06:27:49 2007
@@ -27,7 +27,6 @@
 import java.util.Map;
 import java.util.Set;
 
-import org.apache.felix.ipojo.architecture.ComponentDescription;
 import org.apache.felix.ipojo.architecture.InstanceDescription;
 import org.apache.felix.ipojo.metadata.Element;
 import org.apache.felix.ipojo.parser.FieldMetadata;
@@ -41,32 +40,42 @@
  * 
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public class InstanceManager implements ComponentInstance {
-
-    /**
-     * Parent factory (ComponentFactory).
-     */
-    private ComponentFactory m_factory;
+public class InstanceManager implements ComponentInstance, InstanceStateListener {
 
     /**
      * Name of the component instance.
      */
-    private String m_name;
+    protected String m_name;
 
     /**
      * Name of the component type implementation class.
      */
-    private String m_className;
+    protected String m_className;
+    
+    /**
+     * Handler list.
+     */
+    protected HandlerManager[] m_handlers = new HandlerManager[0];
 
     /**
-     * The context of the component.
+     * Component state (STOPPED at the beginning).
      */
-    private BundleContext m_context;
+    protected int m_state = STOPPED;
+    
+    /**
+     * Instance State Listener List.
+     */
+    protected List m_instanceListeners = new ArrayList();
+    
+    /**
+     * Parent factory (ComponentFactory).
+     */
+    private ComponentFactory m_factory;
 
     /**
-     * Handler list.
+     * The context of the component.
      */
-    private Handler[] m_handlers = new Handler[0];
+    private BundleContext m_context;
 
     /**
      * Map [field, handler list] storing handlers interested by the field.
@@ -79,11 +88,6 @@
     private Map m_methodRegistration = new HashMap();
 
     /**
-     * Component state (STOPPED at the beginning).
-     */
-    private int m_state = STOPPED;
-
-    /**
      * Manipulated class.
      */
     private Class m_clazz;
@@ -92,17 +96,7 @@
      * Instances of the components.
      */
     private Object[] m_pojoObjects = new Object[0];
-    
-    /**
-     * Instance State Listener List.
-     */
-    private List m_instanceListeners = new ArrayList();
 
-    /**
-     * Component type information.
-     */
-    private ComponentDescription m_componentDesc;
-    
    /**
     * Is the component instance state changing?
     */
@@ -118,11 +112,12 @@
      * 
      * @param factory : the factory managing the instance manager
      * @param bc : the bundle context to give to the instance
+     * @param handlers : handlers array
      */
-    public InstanceManager(ComponentFactory factory, BundleContext bc) {
+    public InstanceManager(ComponentFactory factory, BundleContext bc, HandlerManager[] handlers) {
         m_factory = factory;
         m_context = bc;
-        m_factory.getLogger().log(Logger.INFO, "[Bundle " + m_context.getBundle().getBundleId() + "] Create an instance manager from the factory " + m_factory);
+        m_handlers = handlers;
     }
 
     /**
@@ -131,82 +126,28 @@
      * 
      * @param cm : the component type metadata
      * @param configuration : the configuration of the instance
+     * @throws ConfigurationException : occurs if the metadata are not correct
      */
-    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 Handler[0];
-
-        // Set the component-type metadata
+    public void configure(Element cm, Dictionary configuration) throws ConfigurationException {
         m_className = cm.getAttribute("className");
-        if (m_className == null) {
-            m_factory.getLogger().log(Logger.ERROR, "The class name of the component cannot be set, it does not exist in the metadata");
-        }
-
-        // ComponentInfo initialization
-        m_componentDesc = new ComponentDescription(m_factory.getName(), m_className, m_context.getBundle().getBundleId());
-
+        
         // 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_HANDLERS.length; i++) {
-            // Create a new instance
-            try {
-                Handler h = (Handler) IPojoConfiguration.INTERNAL_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());
-            }
-        }
-
-        // 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]);
-                    Handler h = (Handler) 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());
-                }
-            }
+        for (int i = 0; i < m_handlers.length; i++) {
+            m_handlers[i].init(this, cm, configuration);
         }
     }
 
     /**
-     * Get the component type description of the current instance.
-     * @return the component type information.
-     * @see org.apache.felix.ipojo.ComponentInstance#getComponentDescription()
-     */
-    public ComponentDescription getComponentDescription() {
-        return m_componentDesc;
-    }
-
-    /**
      * Get the description of the current instance. 
      * @return the instance description.
      * @see org.apache.felix.ipojo.ComponentInstance#getInstanceDescription()
      */
     public InstanceDescription getInstanceDescription() {
         int componentState = getState();
-        InstanceDescription instanceDescription = new InstanceDescription(m_name, componentState, getContext().getBundle().getBundleId(), m_componentDesc);
+        InstanceDescription instanceDescription = new InstanceDescription(m_name, componentState, getContext().getBundle().getBundleId(), m_factory.getComponentDescription());
 
         String[] objects = new String[getPojoObjects().length];
         for (int i = 0; i < getPojoObjects().length; i++) {
@@ -226,59 +167,64 @@
      * @return the handler array of plugged handlers.
      */
     public Handler[] getRegistredHandlers() {
-        return m_handlers;
+        Handler[] h = new Handler[m_handlers.length];
+        for (int i = 0; i < m_handlers.length; i++) {
+            h[i] = m_handlers[i].getHandler();
+        }
+        return h;
     }
 
     /**
      * Return a specified handler.
      * 
-     * @param name : class name of the handler to find
+     * @param name : class name of the handler to find or its qualified name (namespace:name)
      * @return : the handler, or null if not found
      */
     public Handler getHandler(String name) {
         for (int i = 0; i < m_handlers.length; i++) {
-            if (m_handlers[i].getClass().getName().equalsIgnoreCase(name)) {
-                return m_handlers[i];
+            HandlerFactory fact = (HandlerFactory) m_handlers[i].getHandler().getInstance().getFactory();
+            if (fact.getHandlerName().equals(name)) {
+                return m_handlers[i].getHandler();
             }
         }
         return null;
     }
 
-    // ===================== Lifecycle management =====================
-
     /**
      * Start the instance manager.
      */
-    public void start() {
+    public synchronized 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;
-
+        
         for (int i = 0; i < m_handlers.length; i++) {
+            m_handlers[i].addInstanceStateListener(this);
             m_handlers[i].start();
         }
-
-        // Defines the state of the component :
-        checkInstanceState();
+        
+        for (int i = 0; i < m_handlers.length; i++) {
+            if (m_handlers[i].getState() != VALID) {
+                setState(INVALID);
+                return;
+            }
+        }
+        setState(VALID);
     }
 
     /**
      * Stop the instance manager.
      */
-    public void stop() {
+    public synchronized 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].removeInstanceStateListener(this);
             m_handlers[i].stop();
         }
         
@@ -294,22 +240,28 @@
      * Dispose the instance.
      * @see org.apache.felix.ipojo.ComponentInstance#dispose()
      */
-    public void dispose() {
+    public synchronized void dispose() {
         if (m_state > STOPPED) { // Valid or invalid
             stop();
         }
         
+        m_state = DISPOSED;
+        
         for (int i = 0; i < m_instanceListeners.size(); i++) {
             ((InstanceStateListener) m_instanceListeners.get(i)).stateChanged(this, DISPOSED);
         }
         
         m_factory.disposed(this);
-
-        // Cleaning
-        m_handlers = new Handler[0];
+        
+        for (int i = 0; i < m_handlers.length; i++) {
+            m_handlers[i].dispose();
+        }
+        
+        m_handlers = new HandlerManager[0];
         m_fieldRegistration = new HashMap();
+        m_methodRegistration = new HashMap();
         m_clazz = null;
-        m_pojoObjects = new Object[0];
+        m_inTransition = false;
         m_instanceListeners.clear();
     }
     
@@ -328,10 +280,16 @@
 
         // Cleaning
         m_state = DISPOSED;
-        m_handlers = new Handler[0];
+        
+        for (int i = 0; i < m_handlers.length; i++) {
+            m_handlers[i].dispose();
+        }
+        
+        m_handlers = new HandlerManager[0];
         m_fieldRegistration = new HashMap();
+        m_methodRegistration = new HashMap();
         m_clazz = null;
-        m_pojoObjects = new Object[0];
+        m_inTransition = false;
         m_instanceListeners.clear();
     }
     
@@ -342,7 +300,7 @@
      * the second call is stored and executed after the first one is finished.
      * @param state : the new state
      */
-    private synchronized void setState(int state) {
+    public void setState(int state) {
         if (m_inTransition) {
             m_stateQueue.add(new Integer(state)); 
             return;
@@ -351,18 +309,10 @@
         if (m_state != state) {
             m_inTransition = true;
 
-            // 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);
+                m_handlers[i].getHandler().stateChanged(state);
             }
             
             for (int i = 0; i < m_instanceListeners.size(); i++) {
@@ -401,7 +351,9 @@
      * @see org.apache.felix.ipojo.ComponentInstance#addInstanceStateListener(org.apache.felix.ipojo.InstanceStateListener)
      */
     public void addInstanceStateListener(InstanceStateListener listener) {
-        m_instanceListeners.add(listener);
+        synchronized (m_instanceListeners) {
+            m_instanceListeners.add(listener);
+        }
     }
 
     /**
@@ -410,13 +362,11 @@
      * @see org.apache.felix.ipojo.ComponentInstance#removeInstanceStateListener(org.apache.felix.ipojo.InstanceStateListener)
      */
     public void removeInstanceStateListener(InstanceStateListener listener) {
-        m_instanceListeners.remove(listener);
+        synchronized (m_instanceListeners) {
+            m_instanceListeners.remove(listener);
+        }
     }
 
-    // ===================== end Lifecycle management =====================
-
-    // ================== Class & Instance management ===================
-
     /**
      * Get the factory which create the current instance.
      * @return the factory of the component
@@ -450,7 +400,7 @@
      * Add an instance to the created instance list.
      * @param o : the instance to add
      */
-    private void addInstance(Object o) {
+    private synchronized void addInstance(Object o) {
         for (int i = 0; (m_pojoObjects != null) && (i < m_pojoObjects.length); i++) {
             if (m_pojoObjects[i] == o) {
                 return;
@@ -468,12 +418,20 @@
     }
 
     /**
-     * Remove an instance from the created instance list.
-     * The instance will be destroyed by the garbage collector.
+     * Get the array of object created by the instance.
+     * @return the created instance of the component instance.
+     */
+    public Object[] getPojoObjects() {
+        return m_pojoObjects;
+    }
+
+    /**
+     * Delete the created instance (remove it from the list, to allow the
+     * garbage collector to eat the instance).
      * 
-     * @param o : the instance to remove
+     * @param o : the instance to delete
      */
-    private void removeInstance(Object o) {
+    public synchronized void deletePojoObject(Object o) {
         int idx = -1;
         for (int i = 0; i < m_pojoObjects.length; i++) {
             if (m_pojoObjects[i] == o) {
@@ -497,24 +455,6 @@
     }
 
     /**
-     * Get the array of object created by the instance.
-     * @return the created instance of the component instance.
-     */
-    public Object[] getPojoObjects() {
-        return m_pojoObjects;
-    }
-
-    /**
-     * Delete the created instance (remove it from the list, to allow the
-     * garbage collector to eat the instance).
-     * 
-     * @param o : the instance to delete
-     */
-    public void deletePojoObject(Object o) {
-        removeInstance(o);
-    }
-
-    /**
      * Create an instance of the component. This method need to be called one
      * time only for singleton provided service
      * 
@@ -527,7 +467,6 @@
         }
         Object instance = null;
         try {
-
             // Try to find if there is a constructor with a bundle context as
             // parameter :
             try {
@@ -554,17 +493,20 @@
             m_factory.getLogger().log(Logger.ERROR,
                     "[" + m_name + "] createInstance -> The Component Instance is not accessible (security reason) : " + e.getMessage());
         } catch (InvocationTargetException e) {
-            m_factory.getLogger().log(Logger.ERROR,
-                    "[" + m_name + "] createInstance -> Cannot invoke the constructor method (illegal target) : " + e.getMessage());
+            m_factory.getLogger().log(Logger.ERROR, "[" + m_name + "] createInstance -> Cannot invoke the constructor method (illegal target) : " + e.getMessage());
+            e.printStackTrace();
         } catch (NoSuchMethodException e) {
             m_factory.getLogger().log(Logger.ERROR, "[" + m_name + "] createInstance -> Cannot invoke the constructor (method not found) : " + e.getMessage());
         }
+        if (instance == null) {
+            m_factory.getLogger().log(Logger.ERROR, "[" + m_name + "] createInstance -> Cannot create the instance");
+        }
 
         // Register the new instance
         addInstance(instance);
         // Call createInstance on Handlers :
         for (int i = 0; i < m_handlers.length; i++) {
-            m_handlers[i].createInstance(instance);
+            ((PrimitiveHandler) m_handlers[i].getHandler()).objectCreated(instance);
         }
         return instance;
     }
@@ -574,7 +516,7 @@
      * If no object created, create and return one object.
      * @return the instance of the component instance to use for singleton component
      */
-    public Object getPojoObject() {
+    public synchronized Object getPojoObject() {
         if (m_pojoObjects.length == 0) {
             createPojoObject();
         }
@@ -592,30 +534,6 @@
         return m_clazz;
     }
 
-    // ================== end Class & Instance management ================
-
-    // ======================== Handlers Management ======================
-
-    /**
-     * Register the given handler to the current instance manager.
-     * 
-     * @param h : the handler to register
-     */
-    public void register(Handler h) {
-        for (int i = 0; (m_handlers != null) && (i < m_handlers.length); i++) {
-            if (m_handlers[i] == h) {
-                return;
-            }
-        }
-
-        if (m_handlers != null) {
-            Handler[] newList = new Handler[m_handlers.length + 1];
-            System.arraycopy(m_handlers, 0, newList, 0, m_handlers.length);
-            newList[m_handlers.length] = h;
-            m_handlers = newList;
-        }
-    }
-
     /**
      * Register an handler. The handler will be notified of event on each field
      * given in the list.
@@ -624,19 +542,18 @@
      * @param fields : the field metadata list
      * @param methods : the method metadata list
      */
-    public void register(Handler h, FieldMetadata[] fields, MethodMetadata[] methods) {
-        register(h);
+    public void register(PrimitiveHandler h, FieldMetadata[] fields, MethodMetadata[] methods) {
         for (int i = 0; fields != null && i < fields.length; i++) {
             if (m_fieldRegistration.get(fields[i].getFieldName()) == null) {
-                m_fieldRegistration.put(fields[i].getFieldName(), new Handler[] { h });
+                m_fieldRegistration.put(fields[i].getFieldName(), new PrimitiveHandler[] { h });
             } else {
-                Handler[] list = (Handler[]) m_fieldRegistration.get(fields[i].getFieldName());
+                PrimitiveHandler[] list = (PrimitiveHandler[]) m_fieldRegistration.get(fields[i].getFieldName());
                 for (int j = 0; j < list.length; j++) {
                     if (list[j] == h) {
                         return;
                     }
                 }
-                Handler[] newList = new Handler[list.length + 1];
+                PrimitiveHandler[] newList = new PrimitiveHandler[list.length + 1];
                 System.arraycopy(list, 0, newList, 0, list.length);
                 newList[list.length] = h;
                 m_fieldRegistration.put(fields[i].getFieldName(), newList);
@@ -644,15 +561,15 @@
         }
         for (int i = 0; methods != null && i < methods.length; i++) {
             if (m_methodRegistration.get(methods[i].getMethodIdentifier()) == null) {
-                m_methodRegistration.put(methods[i].getMethodIdentifier(), new Handler[] { h });
+                m_methodRegistration.put(methods[i].getMethodIdentifier(), new PrimitiveHandler[] { h });
             } else {
-                Handler[] list = (Handler[]) m_methodRegistration.get(methods[i].getMethodIdentifier());
+                PrimitiveHandler[] list = (PrimitiveHandler[]) m_methodRegistration.get(methods[i].getMethodIdentifier());
                 for (int j = 0; j < list.length; j++) {
                     if (list[j] == h) {
                         return;
                     }
                 }
-                Handler[] newList = new Handler[list.length + 1];
+                PrimitiveHandler[] newList = new PrimitiveHandler[list.length + 1];
                 System.arraycopy(list, 0, newList, 0, list.length);
                 newList[list.length] = h;
                 m_methodRegistration.put(methods[i].getMethodIdentifier(), newList);
@@ -669,12 +586,12 @@
      * @param fields : the field metadata list
      * @param methods : the method metadata list
      */
-    public void unregister(Handler h, FieldMetadata[] fields, MethodMetadata[] methods) {
+    public void unregister(PrimitiveHandler h, FieldMetadata[] fields, MethodMetadata[] methods) {
         for (int i = 0; i < fields.length; i++) {
             if (m_fieldRegistration.get(fields[i].getFieldName()) == null) {
                 break;
             } else {
-                Handler[] list = (Handler[]) m_fieldRegistration.get(fields[i].getFieldName());
+                PrimitiveHandler[] list = (PrimitiveHandler[]) m_fieldRegistration.get(fields[i].getFieldName());
                 int idx = -1;
                 for (int j = 0; j < list.length; j++) {
                     if (list[j] == h) {
@@ -685,9 +602,9 @@
 
                 if (idx >= 0) {
                     if ((list.length - 1) == 0) {
-                        list = new Handler[0];
+                        list = new PrimitiveHandler[0];
                     } else {
-                        Handler[] newList = new Handler[list.length - 1];
+                        PrimitiveHandler[] newList = new PrimitiveHandler[list.length - 1];
                         System.arraycopy(list, 0, newList, 0, idx);
                         if (idx < newList.length) {
                             System.arraycopy(list, idx + 1, newList, idx, newList.length - idx);
@@ -702,7 +619,7 @@
             if (m_methodRegistration.get(methods[i].getMethodIdentifier()) == null) {
                 break;
             } else {
-                Handler[] list = (Handler[]) m_methodRegistration.get(methods[i].getMethodIdentifier());
+                PrimitiveHandler[] list = (PrimitiveHandler[]) m_methodRegistration.get(methods[i].getMethodIdentifier());
                 int idx = -1;
                 for (int j = 0; j < list.length; j++) {
                     if (list[j] == h) {
@@ -713,9 +630,9 @@
 
                 if (idx >= 0) {
                     if ((list.length - 1) == 0) {
-                        list = new Handler[0];
+                        list = new PrimitiveHandler[0];
                     } else {
-                        Handler[] newList = new Handler[list.length - 1];
+                        PrimitiveHandler[] newList = new PrimitiveHandler[list.length - 1];
                         System.arraycopy(list, 0, newList, 0, idx);
                         if (idx < newList.length) {
                             System.arraycopy(list, idx + 1, newList, idx, newList.length - idx);
@@ -727,34 +644,6 @@
             }
         }
     }
-
-    /**
-     * Unregister the given handler.
-     * 
-     * @param h : the handler to unregister
-     */
-    public void unregister(Handler h) {
-        int idx = -1;
-        for (int i = 0; i < m_handlers.length; i++) {
-            if (m_handlers[i] == h) {
-                idx = i;
-                break;
-            }
-        }
-
-        if (idx >= 0) {
-            if ((m_handlers.length - 1) == 0) {
-                m_handlers = new Handler[0];
-            } else {
-                Handler[] newList = new Handler[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;
-            }
-        }
-    }
     
     public Set getRegistredFields() {
         return m_fieldRegistration.keySet();
@@ -772,13 +661,13 @@
      * @param fieldName : the field name on which the GETFIELD instruction is
      * called
      * @param initialValue : the value of the field in the code
-     * @return the value decided by the last asked handler (throw a warining if
+     * @return the value decided by the last asked handler (throw a warning if
      * two fields decide two different values)
      */
-    public Object getterCallback(String fieldName, Object initialValue) {
+    public synchronized Object getterCallback(String fieldName, Object initialValue) {
         Object result = null;
         // Get the list of registered handlers
-        Handler[] list = (Handler[]) m_fieldRegistration.get(fieldName);
+        PrimitiveHandler[] list = (PrimitiveHandler[]) m_fieldRegistration.get(fieldName);
         for (int i = 0; list != null && i < list.length; i++) {
             Object handlerResult = list[i].getterCallback(fieldName, initialValue);
             if (handlerResult != initialValue) {
@@ -797,8 +686,8 @@
      * Dispatch entry method event on registered handler.
      * @param methodId : method id
      */
-    public void entryCallback(String methodId) {
-        Handler[] list = (Handler[]) m_methodRegistration.get(methodId);
+    public synchronized void entryCallback(String methodId) {
+        PrimitiveHandler[] list = (PrimitiveHandler[]) m_methodRegistration.get(methodId);
         for (int i = 0; list != null && i < list.length; i++) {
             list[i].entryCallback(methodId);
         }
@@ -811,8 +700,8 @@
      * @param methodId : method id
      * @param e : returned object.
      */
-    public void exitCallback(String methodId, Object e) {
-        Handler[] list = (Handler[]) m_methodRegistration.get(methodId);
+    public synchronized void exitCallback(String methodId, Object e) {
+        PrimitiveHandler[] list = (PrimitiveHandler[]) m_methodRegistration.get(methodId);
         for (int i = 0; list != null && i < list.length; i++) {
             list[i].exitCallback(methodId, e);
         }
@@ -826,9 +715,9 @@
      * called
      * @param objectValue : the value of the field
      */
-    public void setterCallback(String fieldName, Object objectValue) {
+    public synchronized void setterCallback(String fieldName, Object objectValue) {
         // Get the list of registered handlers
-        Handler[] list = (Handler[]) m_fieldRegistration.get(fieldName);
+        PrimitiveHandler[] list = (PrimitiveHandler[]) m_fieldRegistration.get(fieldName);
 
         for (int i = 0; list != null && i < list.length; i++) {
             list[i].setterCallback(fieldName, objectValue);
@@ -853,29 +742,6 @@
     }
 
     /**
-     * Check the state of all handlers.
-     */
-    public void checkInstanceState() {
-        if (!isStarted()) { return; }
-        
-        boolean isValid = true;
-        for (int i = 0; i < m_handlers.length; i++) {
-            boolean b = m_handlers[i].isValid();
-            isValid = isValid && b;
-        }
-     
-        // Update the component state if necessary
-        if (!isValid && m_state == VALID) {
-            // Need to update the state to UNRESOLVED
-            setState(INVALID);
-            return;
-        }
-        if (isValid && m_state == INVALID) {
-            setState(VALID);
-        }
-    }
-
-    /**
      * Get the instance name.
      * @return the instance name.
      * @see org.apache.felix.ipojo.ComponentInstance#getInstanceName()
@@ -891,7 +757,7 @@
      */
     public void reconfigure(Dictionary configuration) {
         for (int i = 0; i < m_handlers.length; i++) {
-            m_handlers[i].reconfigure(configuration);
+            m_handlers[i].getHandler().reconfigure(configuration);
         }
     }
 
@@ -903,6 +769,34 @@
         return m_className;
     }
 
-    // ======================= end Handlers Management =====================
-
+    /**
+     * 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 (newState == INVALID && m_state == VALID) {
+            // Need to update the state to UNRESOLVED
+            setState(INVALID);
+            return;
+        }
+        if (newState == VALID && m_state == INVALID) {
+            // An handler becomes valid => check if all handlers are valid
+            for (int i = 0; i < m_handlers.length; i++) {
+                if (m_handlers[i].getState() != VALID) { return; }
+            }
+            setState(VALID);
+            return;
+        }
+        
+        if (newState == DISPOSED) {
+            dispose();
+        }
+        
+    }
 }

Added: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/MissingHandlerException.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/MissingHandlerException.java?rev=579239&view=auto
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/MissingHandlerException.java (added)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/MissingHandlerException.java Tue Sep 25 06:27:49 2007
@@ -0,0 +1,60 @@
+/* 
+ * 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.List;
+
+/**
+ * Missing Handler Exception.
+ * This exception occurs when an handler is missing to build an instance.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class MissingHandlerException extends Exception {
+    
+    /**
+     * Serialization Id. 
+     */
+    private static final long serialVersionUID = 5047792897590881478L;
+    
+    /**
+     * Message. 
+     */
+    private String m_message;
+    
+    /**
+     * Constructor.
+     * @param missing : list of missing handlers.
+     */
+    public MissingHandlerException(List missing) {
+        m_message = "Missing handlers : ";
+        for (int i = 0; i < missing.size(); i++) {
+            m_message += (String) missing.get(i) + " ";
+        }
+    }
+    
+    /**
+     * Get the error message.
+     * @return : the error message
+     * @see java.lang.Throwable#getMessage()
+     */
+    public String getMessage() {
+        return m_message;
+    }
+
+}

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/PolicyServiceContext.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/PolicyServiceContext.java?rev=579239&r1=579238&r2=579239&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/PolicyServiceContext.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/PolicyServiceContext.java Tue Sep 25 06:27:49 2007
@@ -18,10 +18,17 @@
  */
 package org.apache.felix.ipojo;
 
+import java.io.File;
+import java.io.InputStream;
 import java.util.Dictionary;
 
 import org.apache.felix.ipojo.composite.ServiceReferenceImpl;
+import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.BundleListener;
+import org.osgi.framework.Filter;
+import org.osgi.framework.FrameworkListener;
 import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServiceListener;
 import org.osgi.framework.ServiceReference;
@@ -56,12 +63,12 @@
     /**
      * Global service registry.
      */
-    private BundleContext m_global;
+    public BundleContext m_global;
     
     /**
      * Local (Composite) Service Registry.
      */
-    private ServiceContext m_local;
+    public ServiceContext m_local;
     
     /**
      * Resolving policy.
@@ -292,6 +299,127 @@
         } else {
             return m_global.ungetService(reference);
         }
+    }
+
+    /**
+     * Add a bundle listener.
+     * Delegate on the global bundle context.
+     * @param arg0 : bundle listener to add
+     * @see org.osgi.framework.BundleContext#addBundleListener(org.osgi.framework.BundleListener)
+     */
+    public void addBundleListener(BundleListener arg0) {
+        m_global.addBundleListener(arg0);
+    }
+
+    /**
+     * Add a framework listener.
+     * Delegate on the global bundle context.
+     * @param arg0 : framework listener to add.
+     * @see org.osgi.framework.BundleContext#addFrameworkListener(org.osgi.framework.FrameworkListener)
+     */
+    public void addFrameworkListener(FrameworkListener arg0) {
+        m_global.addFrameworkListener(arg0);
+    }
+
+    /**
+     * Create a LDAP filter.
+     * @param arg0 : String-form of the filter
+     * @return the created filter object
+     * @throws InvalidSyntaxException : if the given argument is not a valid against the LDAP grammar.
+     * @see org.osgi.framework.BundleContext#createFilter(java.lang.String)
+     */
+    public Filter createFilter(String arg0) throws InvalidSyntaxException {
+        return m_global.createFilter(arg0);
+    }
+
+    /**
+     * Get the current bundle.
+     * @return the current bundle
+     * @see org.osgi.framework.BundleContext#getBundle()
+     */
+    public Bundle getBundle() {
+        return m_global.getBundle();
+    }
+
+    /**
+     * Get the bundle object with the given id.
+     * @param id : bundle id
+     * @return the bundle object
+     * @see org.osgi.framework.BundleContext#getBundle(long)
+     */
+    public Bundle getBundle(long id) {
+        return m_global.getBundle(id);
+    }
+
+    /**
+     * Get installed bundles.
+     * @return the list of installed bundles
+     * @see org.osgi.framework.BundleContext#getBundles()
+     */
+    public Bundle[] getBundles() {
+        return m_global.getBundles();
+    }
+
+
+    /**
+     * Get a data file.
+     * @param filename : File name.
+     * @return the File object
+     * @see org.osgi.framework.BundleContext#getDataFile(java.lang.String)
+     */
+    public File getDataFile(String filename) {
+        return m_global.getDataFile(filename);
+    }
+
+    /**
+     * Get a property value.
+     * @param key : key of the asked property
+     * @return the property value (object) or null if no property are associated with the given key
+     * @see org.osgi.framework.BundleContext#getProperty(java.lang.String)
+     */
+    public String getProperty(String key) {
+        return m_global.getProperty(key);
+    }
+
+    /**
+     * Install a bundle.
+     * @param location : URL of the bundle to install
+     * @return the installed bundle
+     * @throws BundleException : if the bundle cannot be installed correctly
+     * @see org.osgi.framework.BundleContext#installBundle(java.lang.String)
+     */
+    public Bundle installBundle(String location) throws BundleException {
+        return m_global.installBundle(location);
+    }
+
+    /**
+     * Install a bundle.
+     * @param location : URL of the bundle to install
+     * @param input : 
+     * @return the installed bundle
+     * @throws BundleException : if the bundle cannot be installed correctly
+     * @see org.osgi.framework.BundleContext#installBundle(java.lang.String, java.io.InputStream)
+     */
+    public Bundle installBundle(String location, InputStream input) throws BundleException {
+        return m_global.installBundle(location, input);
+    }
+
+    /**
+     * Remove a bundle listener.
+     * @param listener : the listener to remove
+     * @see org.osgi.framework.BundleContext#removeBundleListener(org.osgi.framework.BundleListener)
+     */
+    public void removeBundleListener(BundleListener listener) {
+        m_global.removeBundleListener(listener);
+    }
+
+    /**
+     * Remove a framework listener.
+     * @param listener : the listener to remove
+     * @see org.osgi.framework.BundleContext#removeFrameworkListener(org.osgi.framework.FrameworkListener)
+     */
+    public void removeFrameworkListener(FrameworkListener listener) {
+        m_global.removeFrameworkListener(listener);
     }
 
 }

Added: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/PrimitiveHandler.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/PrimitiveHandler.java?rev=579239&view=auto
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/PrimitiveHandler.java (added)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/PrimitiveHandler.java Tue Sep 25 06:27:49 2007
@@ -0,0 +1,124 @@
+/* 
+ * 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;
+
+/**
+* Abstract class to extends for primitive handler.
+* 
+* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+*/
+public abstract class PrimitiveHandler extends Handler {
+    
+    /**
+     * "Primitive" Handler type (value).
+     */
+    public static final String HANDLER_TYPE = "primitive";
+    
+    /**
+     * Reference on the instance manager.
+     */
+    private InstanceManager m_manager;
+    
+    /**
+     * Attach the current handler to the given instance.
+     * @param im ! the instance on which the current handler will be attached.
+     * @see org.apache.felix.ipojo.Handler#attach(org.apache.felix.ipojo.ComponentInstance)
+     */
+    protected final void attach(ComponentInstance im) {
+        m_manager = (InstanceManager) im;
+    }
+    
+    public InstanceManager getInstanceManager() {
+        return m_manager;
+    }
+    
+    /**
+     * Log method.
+     * @param level : message level (Logger class constant)
+     * @param message : message to log
+     */
+    public void log(int level, String message) {
+        m_manager.getFactory().getLogger().log(level, message);
+    }
+    
+    /**
+     * Log method.
+     * @param level : message level (Logger class constant)
+     * @param message : message to log
+     * @param ex : exception to attach to the message
+     */
+    public void log(int level, String message, Throwable ex) {
+        m_manager.getFactory().getLogger().log(level, message, 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 final Handler getHandler(String name) {
+        return m_manager.getHandler(name);
+    }
+    
+    /**
+     * This method is called when a PUTFIELD operation is detected.
+     * @param fieldName : the field name
+     * @param value : the value passed to the field
+     */
+    public void setterCallback(String fieldName, Object value) { }
+
+    /**
+     * 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
+     */
+    public Object getterCallback(String fieldName, Object value) {
+        return value;
+    }
+    
+    /**
+     * This method is called when the execution enter in a method.
+     * @param methodId : the method identifier
+     */
+    public void entryCallback(String methodId) { }
+
+    /**
+     * 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)
+     */
+    public void exitCallback(String methodId, Object returnedObj) { }
+    
+    /**
+     * This method is called when an instance of the component is created, but
+     * before someone can use it.
+     * @param instance : the created instance
+     */
+    public void objectCreated(Object instance) { }
+    
+    
+
+}

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/ServiceContext.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/ServiceContext.java?rev=579239&r1=579238&r2=579239&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/ServiceContext.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/ServiceContext.java Tue Sep 25 06:27:49 2007
@@ -20,6 +20,7 @@
 
 import java.util.Dictionary;
 
+import org.osgi.framework.BundleContext;
 import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServiceListener;
 import org.osgi.framework.ServiceReference;
@@ -31,7 +32,7 @@
  * 
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public interface ServiceContext {
+public interface ServiceContext extends BundleContext {
 
     /**
      * Add a service listener.

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/ComponentDescription.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/ComponentDescription.java?rev=579239&r1=579238&r2=579239&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/ComponentDescription.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/ComponentDescription.java Tue Sep 25 06:27:49 2007
@@ -18,12 +18,14 @@
  */
 package org.apache.felix.ipojo.architecture;
 
+import java.util.List;
+
+import org.apache.felix.ipojo.Factory;
 import org.apache.felix.ipojo.metadata.Attribute;
 import org.apache.felix.ipojo.metadata.Element;
 
 /**
- * Component Type information.
- * 
+ * Component Type description.
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
 public class ComponentDescription {
@@ -47,32 +49,43 @@
      * Get the name of this component type.
      */
     private String m_name;
-    
+
     /**
      * Bundle Id of the bundle containing this type.
      */
     private long m_bundleId;
 
     /**
-     * Constructor.
-     * 
-     * @param name : name of the component type (factory name).
-     * @param className : implementation class.
-     * @param bundle : bundle id.
+     * State of the factory.
      */
-    public ComponentDescription(String name, String className, long bundle) {
-        m_name = name;
-        m_className = className;
-        m_bundleId = bundle;
-    }
+    private int m_state;
 
     /**
-     * Constructor for composite.
-     * 
-     * @param name : name of the component type (factory name).
+     * Required handler list.
      */
-    public ComponentDescription(String name) {
+    private List m_rh;
+
+    /**
+     * Missing handler list.
+     */
+    private List m_mh;
+
+    /**
+     * Constructor.
+     * @param name : name.
+     * @param className : implementation class or "composite"
+     * @param state : state of the type (valid or invalid)
+     * @param rh : required handler list
+     * @param mh : missing handler list
+     * @param bundle : bundle containing the type
+     */
+    public ComponentDescription(String name, String className, int state, List rh, List mh, long bundle) {
         m_name = name;
+        m_className = className;
+        m_bundleId = bundle;
+        m_state = state;
+        m_rh = rh;
+        m_mh = mh;
     }
 
     /**
@@ -94,27 +107,33 @@
 
     /**
      * Get component-type properties.
-     * @return the list of configuration properties accepted by the component type
-     * type.
+     * @return the list of configuration properties accepted by the component type type.
      */
     public PropertyDescription[] getProperties() {
         return m_properties;
     }
 
     /**
+     * Add a String property in the component type.
+     * @param name : property name.
+     * @param value : property value.
+     */
+    public void addProperty(String name, String value) {
+        PropertyDescription pd = new PropertyDescription(name, String.class.getName(), value);
+        addProperty(pd);
+    }
+
+    /**
      * Add a configuration properties to the component type.
-     * 
      * @param pd : the property to add
      */
     public void addProperty(PropertyDescription pd) {
-        if (pd.getName().equals("name")) {
+        if ("name".equals(pd.getName())) {
             pd = new PropertyDescription(pd.getName(), pd.getType(), null); // Erase the instance name
         }
-        
+
         for (int i = 0; i < m_properties.length; i++) {
-            if (m_properties[i].getName().equals(pd.getName())) {
-                return;
-            }
+            if (m_properties[i].getName().equals(pd.getName())) { return; }
         }
 
         PropertyDescription[] newProps = new PropertyDescription[m_properties.length + 1];
@@ -133,8 +152,7 @@
 
     /**
      * Add a provided service to the component type.
-     * @param serviceSpecification : the provided service to add (interface
-     * name)
+     * @param serviceSpecification : the provided service to add (interface name)
      */
     public void addProvidedServiceSpecification(String serviceSpecification) {
         String[] newSs = new String[m_providedServiceSpecification.length + 1];
@@ -150,29 +168,43 @@
     public String getName() {
         return m_name;
     }
-    
+
     /**
      * Get the component type description.
      * @return : the description
      */
     public Element getDescription() {
         Element desc = new Element("Factory", "");
-        
+
         desc.addAttribute(new Attribute("name", m_name));
         desc.addAttribute(new Attribute("bundle", "" + m_bundleId));
-        
+
         if (m_className != null) {
             desc.addAttribute(new Attribute("Implementation-Class", m_className));
         } else {
             desc.addAttribute(new Attribute("Composite", "true"));
         }
-        
+
+        String state = "valid";
+        if (m_state == Factory.INVALID) {
+            state = "invalid";
+        }
+        desc.addAttribute(new Attribute("state", state));
+
+        // Display required & missing handlers
+        Element rh = new Element("RequiredHandlers", "");
+        rh.addAttribute(new Attribute("list", m_rh.toString()));
+        Element mh = new Element("MissingHandlers", "");
+        mh.addAttribute(new Attribute("list", m_mh.toString()));
+        desc.addElement(rh);
+        desc.addElement(mh);
+
         for (int i = 0; i < m_providedServiceSpecification.length; i++) {
             Element prov = new Element("provides", "");
             prov.addAttribute(new Attribute("specification", m_providedServiceSpecification[i]));
             desc.addElement(prov);
         }
-        
+
         for (int i = 0; i < m_properties.length; i++) {
             Element prop = new Element("property", "");
             prop.addAttribute(new Attribute("name", m_properties[i].getName()));
@@ -184,7 +216,7 @@
             }
             desc.addElement(prop);
         }
-        
+
         return desc;
     }
 

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/HandlerDescription.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/HandlerDescription.java?rev=579239&r1=579238&r2=579239&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/HandlerDescription.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/HandlerDescription.java Tue Sep 25 06:27:49 2007
@@ -18,6 +18,8 @@
  */
 package org.apache.felix.ipojo.architecture;
 
+import org.apache.felix.ipojo.CompositeHandler;
+import org.apache.felix.ipojo.Handler;
 import org.apache.felix.ipojo.metadata.Attribute;
 import org.apache.felix.ipojo.metadata.Element;
 
@@ -41,12 +43,21 @@
     /**
      * Constructor.
      * 
-     * @param name : handler name
-     * @param isValid : is the handler valid
+     * @param h : handler.
      */
-    public HandlerDescription(String name, boolean isValid) {
-        m_handlerName = name;
-        m_isValid = isValid;
+    public HandlerDescription(Handler h) {
+        m_handlerName = h.getClass().getName();
+        m_isValid = h.isValid();
+    }
+
+    /**
+     * Constructor.
+     * 
+     * @param h : composite handler.
+     */
+    public HandlerDescription(CompositeHandler h) {
+        m_handlerName = h.getClass().getName();
+        m_isValid = h.isValid();
     }
 
     /**

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/InstanceDescription.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/InstanceDescription.java?rev=579239&r1=579238&r2=579239&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/InstanceDescription.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/InstanceDescription.java Tue Sep 25 06:27:49 2007
@@ -150,8 +150,7 @@
         // Verify that the dependency description is not already in the array.
         for (int i = 0; i < m_containedInstances.length; i++) {
             if (m_containedInstances[i] == inst) {
-                return; // NOTHING TO DO, the description is already in the
-                        // array
+                return; // NOTHING TO DO, the description is already in the array
             }
         }
         // The component Description is not in the array, add it
@@ -232,10 +231,12 @@
             instance.addElement(obj);
         }
         // Contained instance (exposing architecture) (empty if primitive)
-        for (int i = 0; i < m_containedInstances.length; i++) {
+        if (m_containedInstances.length > 0) {
             Element inst = new Element("ContainedInstances", "");
-            inst.addElement(m_containedInstances[i].getDescription());
-            instance.addElement(inst);
+            for (int i = 0; i < m_containedInstances.length; i++) {
+                inst.addElement(m_containedInstances[i].getDescription());
+                instance.addElement(inst);
+            }
         }
         return instance;
 

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/CompositeServiceContext.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/CompositeServiceContext.java?rev=579239&r1=579238&r2=579239&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/CompositeServiceContext.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/CompositeServiceContext.java Tue Sep 25 06:27:49 2007
@@ -18,6 +18,8 @@
  */
 package org.apache.felix.ipojo.composite;
 
+import java.io.File;
+import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.Dictionary;
 import java.util.List;
@@ -27,10 +29,15 @@
 import org.apache.felix.ipojo.Factory;
 import org.apache.felix.ipojo.IPojoContext;
 import org.apache.felix.ipojo.ServiceContext;
+import org.apache.felix.ipojo.util.Tracker;
+import org.apache.felix.ipojo.util.TrackerCustomizer;
+import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.BundleListener;
+import org.osgi.framework.Filter;
+import org.osgi.framework.FrameworkListener;
 import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceEvent;
 import org.osgi.framework.ServiceListener;
 import org.osgi.framework.ServiceReference;
 import org.osgi.framework.ServiceRegistration;
@@ -41,7 +48,7 @@
  * 
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public class CompositeServiceContext implements ServiceContext, ServiceListener {
+public class CompositeServiceContext implements ServiceContext, TrackerCustomizer {
 
     /**
      * Structure storing the reference, the factory and the registration.
@@ -85,6 +92,11 @@
      * Global service context.
      */
     private BundleContext m_global;
+    
+    /**
+     * Tracker tracking Factories to import.
+     */
+    private Tracker m_tracker;
 
     /**
      * Constructor. This constructor instantiate a service registry with the
@@ -225,34 +237,18 @@
     }
 
     /**
-     * Initiate the factory list.
-     */
-    private void importFactories() {
-        try {
-            ServiceReference[] refs = m_global.getServiceReferences(Factory.class.getName(), null);
-            if (refs != null) {
-                for (int i = 0; i < refs.length; i++) {
-                    importFactory(refs[i]);
-                }
-            }
-        } catch (InvalidSyntaxException e) {
-            e.printStackTrace(); // Should not happen
-        }
-    }
-
-    /**
      * Import a factory form the parent to the internal registry.
      * 
      * @param ref : the reference of the factory to import.
      */
-    private void importFactory(ServiceReference ref) {
+    private void importFactory(ServiceReference ref) {        
         Record rec = new Record();
         m_factories.add(rec);
         Dictionary dict = new Properties();
         for (int j = 0; j < ref.getPropertyKeys().length; j++) {
             dict.put(ref.getPropertyKeys()[j], ref.getProperty(ref.getPropertyKeys()[j]));
         }
-        rec.m_fact = new FactoryProxy((Factory) m_global.getService(ref), this);
+        rec.m_fact = new FactoryProxy((Factory) m_tracker.getService(ref), this);
         rec.m_reg = registerService(Factory.class.getName(), rec.m_fact, dict);
         rec.m_ref = ref;
     }
@@ -266,9 +262,11 @@
         for (int i = 0; i < m_factories.size(); i++) {
             Record rec = (Record) m_factories.get(i);
             if (rec.m_ref == ref) {
-                rec.m_reg.unregister();
-                rec.m_fact = null;
-                m_global.ungetService(rec.m_ref);
+                if (rec.m_reg != null) {
+                    rec.m_reg.unregister();
+                    rec.m_fact = null;
+                }
+                m_tracker.ungetService(rec.m_ref);
                 m_factories.remove(rec);
                 return;
             }
@@ -278,44 +276,22 @@
     /**
      * Start the registry management.
      */
-    public synchronized void start() {
-        importFactories();
-        try {
-            m_global.addServiceListener(this, "(" + Constants.OBJECTCLASS + "=" + Factory.class.getName() + ")");
-        } catch (InvalidSyntaxException e) {
-            e.printStackTrace(); // Should not happen
-        }
+    public void start() {
+        m_tracker = new Tracker(m_global, Factory.class.getName(), this);
+        m_tracker.open();
     }
 
     /**
      * Stop the registry management.
      */
     public synchronized void stop() {
-        m_global.removeServiceListener(this);
+        m_tracker.close();
         m_registry.reset();
         for (int i = 0; i < m_factories.size(); i++) {
             Record rec = (Record) m_factories.get(i);
             removeFactory(rec.m_ref);
         }
-    }
-
-    /**
-     * Service Listener implementation.
-     * @param event : the service event
-     * @see org.osgi.framework.ServiceListener#serviceChanged(org.osgi.framework.ServiceEvent)
-     */
-    public void serviceChanged(ServiceEvent event) {
-        if (event.getType() == ServiceEvent.REGISTERED) {
-            if (!containsRef(event.getServiceReference())) {
-                importFactory(event.getServiceReference());
-            }
-            return;
-        }
-        if (event.getType() == ServiceEvent.UNREGISTERING) {
-            if (containsRef(event.getServiceReference())) {
-                removeFactory(event.getServiceReference());
-            }
-        }
+        m_tracker = null;
     }
 
     /**
@@ -332,5 +308,173 @@
             }
         }
         return false;
+    }
+
+    /**
+     * Add a bundle listener.
+     * Delegate on the global bundle context.
+     * @param arg0 : bundle listener to add
+     * @see org.osgi.framework.BundleContext#addBundleListener(org.osgi.framework.BundleListener)
+     */
+    public void addBundleListener(BundleListener arg0) {
+        m_global.addBundleListener(arg0);
+    }
+
+    /**
+     * Add a framework listener.
+     * Delegate on the global bundle context.
+     * @param arg0 : framework listener to add.
+     * @see org.osgi.framework.BundleContext#addFrameworkListener(org.osgi.framework.FrameworkListener)
+     */
+    public void addFrameworkListener(FrameworkListener arg0) {
+        m_global.addFrameworkListener(arg0);
+    }
+
+    /**
+     * Create a LDAP filter.
+     * @param arg0 : String-form of the filter
+     * @return the created filter object
+     * @throws InvalidSyntaxException : if the given argument is not a valid against the LDAP grammar.
+     * @see org.osgi.framework.BundleContext#createFilter(java.lang.String)
+     */
+    public Filter createFilter(String arg0) throws InvalidSyntaxException {
+        return m_global.createFilter(arg0);
+    }
+
+    /**
+     * Get the current bundle.
+     * @return the current bundle
+     * @see org.osgi.framework.BundleContext#getBundle()
+     */
+    public Bundle getBundle() {
+        return m_global.getBundle();
+    }
+
+    /**
+     * Get the bundle object with the given id.
+     * @param id : bundle id
+     * @return the bundle object
+     * @see org.osgi.framework.BundleContext#getBundle(long)
+     */
+    public Bundle getBundle(long id) {
+        return m_global.getBundle(id);
+    }
+
+    /**
+     * Get installed bundles.
+     * @return the list of installed bundles
+     * @see org.osgi.framework.BundleContext#getBundles()
+     */
+    public Bundle[] getBundles() {
+        return m_global.getBundles();
+    }
+
+
+    /**
+     * Get a data file.
+     * @param filename : File name.
+     * @return the File object
+     * @see org.osgi.framework.BundleContext#getDataFile(java.lang.String)
+     */
+    public File getDataFile(String filename) {
+        return m_global.getDataFile(filename);
+    }
+
+    /**
+     * Get a property value.
+     * @param key : key of the asked property
+     * @return the property value (object) or null if no property are associated with the given key
+     * @see org.osgi.framework.BundleContext#getProperty(java.lang.String)
+     */
+    public String getProperty(String key) {
+        return m_global.getProperty(key);
+    }
+
+    /**
+     * Install a bundle.
+     * @param location : URL of the bundle to install
+     * @return the installed bundle
+     * @throws BundleException : if the bundle cannot be installed correctly
+     * @see org.osgi.framework.BundleContext#installBundle(java.lang.String)
+     */
+    public Bundle installBundle(String location) throws BundleException {
+        return m_global.installBundle(location);
+    }
+
+    /**
+     * Install a bundle.
+     * @param location : URL of the bundle to install
+     * @param input : 
+     * @return the installed bundle
+     * @throws BundleException : if the bundle cannot be installed correctly
+     * @see org.osgi.framework.BundleContext#installBundle(java.lang.String, java.io.InputStream)
+     */
+    public Bundle installBundle(String location, InputStream input) throws BundleException {
+        return m_global.installBundle(location, input);
+    }
+
+    /**
+     * Remove a bundle listener.
+     * @param listener : the listener to remove
+     * @see org.osgi.framework.BundleContext#removeBundleListener(org.osgi.framework.BundleListener)
+     */
+    public void removeBundleListener(BundleListener listener) {
+        m_global.removeBundleListener(listener);
+    }
+
+    /**
+     * Remove a framework listener.
+     * @param listener : the listener to remove
+     * @see org.osgi.framework.BundleContext#removeFrameworkListener(org.osgi.framework.FrameworkListener)
+     */
+    public void removeFrameworkListener(FrameworkListener listener) {
+        m_global.removeFrameworkListener(listener);
+    }
+
+    /**
+     * A new factory is detected.
+     * @param reference : service reference
+     * @return true if not already imported.
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addingService(org.osgi.framework.ServiceReference)
+     */
+    public boolean addingService(ServiceReference reference) {
+        if (!containsRef(reference)) {
+            importFactory(reference);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * An imported factory is modified.
+     * @param reference : modified reference
+     * @param service : factory object.
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#modifiedService(org.osgi.framework.ServiceReference, java.lang.Object)
+     */
+    public void modifiedService(ServiceReference reference, Object service) {
+        for (int i = 0; i < m_factories.size(); i++) {
+            Record rec = (Record) m_factories.get(i);
+            if (rec.m_ref == reference) {
+                Dictionary dict = new Properties();
+                for (int j = 0; j < reference.getPropertyKeys().length; j++) {
+                    dict.put(reference.getPropertyKeys()[j], reference.getProperty(reference.getPropertyKeys()[j]));
+                }
+                rec.m_reg.setProperties(dict);
+                return;
+            }
+        }
+    }
+
+    /**
+     * An imported factory disappears.
+     * @param reference : 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) {
+        if (containsRef(reference)) {
+            removeFactory(reference);
+        }
+        
     }
 }