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 [4/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/composite/FactoryProxy.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/FactoryProxy.java?rev=579239&r1=579238&r2=579239&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/FactoryProxy.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/FactoryProxy.java Tue Sep 25 06:27:49 2007
@@ -19,16 +19,20 @@
 package org.apache.felix.ipojo.composite;
 
 import java.util.Dictionary;
+import java.util.List;
 
 import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.ConfigurationException;
 import org.apache.felix.ipojo.Factory;
+import org.apache.felix.ipojo.FactoryStateListener;
+import org.apache.felix.ipojo.MissingHandlerException;
 import org.apache.felix.ipojo.ServiceContext;
 import org.apache.felix.ipojo.UnacceptableConfiguration;
+import org.apache.felix.ipojo.architecture.ComponentDescription;
 import org.apache.felix.ipojo.metadata.Element;
 
 /**
  * Bridge representing a Factory inside a composition.
- * 
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
 public class FactoryProxy implements Factory {
@@ -45,7 +49,6 @@
 
     /**
      * Constructor.
-     * 
      * @param fact : the targeted factory.
      * @param s : the service context to target.
      */
@@ -56,35 +59,36 @@
 
     /**
      * 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 : occurs when the creation failed due to a missing handler (the factory should be invalid)
+     * @throws ConfigurationException : occurs when the creation failed due to a configuration issue
      * @see org.apache.felix.ipojo.Factory#createComponentInstance(java.util.Dictionary)
      */
-    public ComponentInstance createComponentInstance(Dictionary configuration) throws UnacceptableConfiguration {
+    public ComponentInstance createComponentInstance(Dictionary configuration) throws UnacceptableConfiguration, MissingHandlerException, ConfigurationException {
         return m_delegate.createComponentInstance(configuration, m_context);
     }
 
     /**
      * 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 isnot valid.
+     * @throws UnacceptableConfiguration : when the given configuration is not valid.
+     * @throws MissingHandlerException : when at least one handler is missing. 
+     * @throws ConfigurationException : when an issue occurs during the oconfiguration of the instance.
      * @see org.apache.felix.ipojo.Factory#createComponentInstance(java.util.Dictionary,
      * org.apache.felix.ipojo.ServiceContext)
      */
-    public ComponentInstance createComponentInstance(Dictionary configuration, ServiceContext serviceContext) throws UnacceptableConfiguration {
+    public ComponentInstance createComponentInstance(Dictionary configuration, ServiceContext serviceContext) throws UnacceptableConfiguration, MissingHandlerException, ConfigurationException {
         return m_delegate.createComponentInstance(configuration, serviceContext);
     }
 
     /**
      * Get the component type information containing provided service,
      * configuration properties ...
-     * 
      * @return the component type information.
      * @see org.apache.felix.ipojo.Factory#getDescription()
      */
@@ -104,7 +108,6 @@
     /**
      * 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
      * @see org.apache.felix.ipojo.Factory#isAcceptable(java.util.Dictionary)
@@ -116,14 +119,46 @@
     /**
      * 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 MissingHandlerException : when at least one handler is missing
      * @see org.apache.felix.ipojo.Factory#reconfigure(java.util.Dictionary)
      */
-    public void reconfigure(Dictionary conf) throws UnacceptableConfiguration {
+    public void reconfigure(Dictionary conf) throws UnacceptableConfiguration, MissingHandlerException {
         m_delegate.reconfigure(conf);
+    }
+
+    /**
+     * Add a factory listener.
+     * @param l : the listener to add.
+     * @see org.apache.felix.ipojo.Factory#addFactoryStateListener(org.apache.felix.ipojo.FactoryStateListener)
+     */
+    public void addFactoryStateListener(FactoryStateListener l) {
+        m_delegate.addFactoryStateListener(l);
+
+    }
+
+    public List getMissingHandlers() {
+        return m_delegate.getMissingHandlers();
+    }
+
+    public List getRequiredHandlers() {
+        return m_delegate.getRequiredHandlers();
+    }
+
+    /**
+     * Remove a service listener.
+     * @param l : the listener to remove
+     * @see org.apache.felix.ipojo.Factory#removeFactoryStateListener(org.apache.felix.ipojo.FactoryStateListener)
+     */
+    public void removeFactoryStateListener(FactoryStateListener l) {
+        m_delegate.removeFactoryStateListener(l);
+
+    }
+
+    public ComponentDescription getComponentDescription() {
+        return m_delegate.getComponentDescription();
     }
 
 }

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/ServiceReferenceImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/ServiceReferenceImpl.java?rev=579239&r1=579238&r2=579239&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/ServiceReferenceImpl.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/ServiceReferenceImpl.java Tue Sep 25 06:27:49 2007
@@ -34,6 +34,11 @@
      * Service Registration attached to the service reference.
      */
     private ServiceRegistrationImpl m_registration = null;
+    
+    /**
+     * Component Instance.
+     */
+    private ComponentInstance m_cm;
 
     /**
      * Constructor.
@@ -43,6 +48,7 @@
      */
     public ServiceReferenceImpl(ComponentInstance cm, ServiceRegistrationImpl sr) {
         m_registration = sr;
+        m_cm = cm;
     }
 
     /**
@@ -51,7 +57,7 @@
      * @see org.osgi.framework.ServiceReference#getBundle()
      */
     public Bundle getBundle() {
-        throw new UnsupportedOperationException("getUsingBundles is not supported in scope");
+        return m_cm.getContext().getBundle();
     }
 
     /**

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/ServiceRegistrationImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/ServiceRegistrationImpl.java?rev=579239&r1=579238&r2=579239&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/ServiceRegistrationImpl.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/ServiceRegistrationImpl.java Tue Sep 25 06:27:49 2007
@@ -78,7 +78,7 @@
     /**
      * Property Keys List.
      */
-    private transient List m_list = new ArrayList();
+    private List m_list = new ArrayList();
 
     /**
      * Constructor.

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/ServiceRegistry.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/ServiceRegistry.java?rev=579239&r1=579238&r2=579239&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/ServiceRegistry.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/ServiceRegistry.java Tue Sep 25 06:27:49 2007
@@ -104,11 +104,11 @@
     public boolean ungetService(ComponentInstance cm, ServiceReference ref) {
 
         ServiceRegistrationImpl reg = ((ServiceReferenceImpl) ref).getServiceRegistration();
-        if (!reg.isValid()) {
-            return false;
-        } else {
+        if (reg.isValid()) {
             reg.ungetService(cm, reg.getService());
             return true;
+        } else {
+            return false;
         }
     }
 
@@ -159,11 +159,10 @@
 
     /**
      * Dispatch a service event.
-     * 
      * @param event : the service to dispatch
      */
     private void fireServiceChanged(ServiceEvent event) {
-        synchronized (this) {
+        synchronized (m_listeners) {
             // Iterate on the service listener list to notify service listener
             for (int i = 0; i < m_listeners.size(); i++) {
                 ListenerInfo li = (ListenerInfo) m_listeners.get(i);
@@ -184,10 +183,11 @@
      * @param className : required interface
      * @param expr : LDAP filter
      * @return : the list of available service references.
-     * @throws InvalidSyntaxException occurs when the LDAP filter is malformed.
+     * @throws InvalidSyntaxException
+     *             occurs when the LDAP filter is malformed.
      */
     public ServiceReference[] getServiceReferences(String className, String expr) throws InvalidSyntaxException {
-        synchronized (this) {
+        synchronized (m_regs) {
             // Define filter if expression is not null.
             Filter filter = null;
             if (expr != null) {
@@ -238,7 +238,7 @@
      * @return the first available provider or null if none available.
      */
     public ServiceReference getServiceReference(String clazz) {
-        synchronized (this) {
+        synchronized (m_regs) {
             try {
                 ServiceReference[] refs = getServiceReferences(clazz, null);
                 if (refs != null) {
@@ -253,13 +253,12 @@
 
     /**
      * Get a service object.
-     * 
      * @param cm : component instance requiring the service.
      * @param ref : the required reference.
      * @return the service object.
      */
     public Object getService(ComponentInstance cm, ServiceReference ref) {
-        synchronized (this) {
+        synchronized (m_regs) {
             // Look for the service registration for this ref
             ServiceRegistrationImpl reg = ((ServiceReferenceImpl) ref).getServiceRegistration();
             if (reg.isValid()) {
@@ -274,14 +273,13 @@
     /**
      * Get all service references consistent with the given interface and
      * filter.
-     * 
      * @param clazz : the required interface.
      * @param filter : the LDAP filter.
      * @return the list of all service reference or null if none available.
      * @throws InvalidSyntaxException occurs when the LDAP filter is malformed.
      */
     public ServiceReference[] getAllServiceReferences(String clazz, String filter) throws InvalidSyntaxException {
-        synchronized (this) {
+        synchronized (m_regs) {
             // Can delegate on getServiceReference, indeed their is no test on
             // the "modularity" conflict.
             return getServiceReferences(clazz, filter);
@@ -290,26 +288,28 @@
 
     /**
      * Add a service listener with a filter.
-     * 
      * @param listener : the service listener to add
      * @param filter : LDAP filter
      */
     public void addServiceListener(ServiceListener listener, String filter) {
-        synchronized (this) {
-            ListenerInfo li = new ListenerInfo();
-            li.m_listener = listener;
-            try {
-                li.m_filter = m_bc.createFilter(filter);
-            } catch (InvalidSyntaxException ex) {
-                System.err.println("Scope Service Registry : Problem when creating a service listener " + ex.getMessage());
-            }
-            m_listeners.add(li);
+        // If the filter is null, subscribe with no filter.
+        if (filter == null) {
+            addServiceListener(listener);
+            return;
+        }
+        
+        ListenerInfo li = new ListenerInfo();
+        li.m_listener = listener;
+        try {
+            li.m_filter = m_bc.createFilter(filter);
+        } catch (InvalidSyntaxException ex) {
+            System.err.println("Scope Service Registry : Problem when creating a service listener " + ex.getMessage());
         }
+        m_listeners.add(li);
     }
 
     /**
      * Dispatch a service properties modified event.
-     * 
      * @param reg : the implicated service registration.
      */
     public void servicePropertiesModified(ServiceRegistrationImpl reg) {
@@ -318,14 +318,11 @@
 
     /**
      * Unregister a service.
-     * 
      * @param reg : the service registration to unregister
      */
     public void unregisterService(ServiceRegistrationImpl reg) {
-        synchronized (this) {
-            m_regs.remove(reg);
-            fireServiceChanged(new ServiceEvent(ServiceEvent.UNREGISTERING, reg.getReference()));
-        }
+        m_regs.remove(reg);
+        fireServiceChanged(new ServiceEvent(ServiceEvent.UNREGISTERING, reg.getReference()));
     }
 
     /**

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/StringMap.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/StringMap.java?rev=579239&r1=579238&r2=579239&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/StringMap.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/StringMap.java Tue Sep 25 06:27:49 2007
@@ -138,14 +138,5 @@
         public void setCaseSensitive(boolean b) {
             m_isCaseSensitive = b;
         }
-
-        /**
-         * Does not support cloning.
-         * @return The current map
-         * @see java.lang.Object#clone()
-         */
-        public Object clone() {
-            return this;
-        }
     }
 }

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/architecture/ArchitectureHandler.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/architecture/ArchitectureHandler.java?rev=579239&r1=579238&r2=579239&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/architecture/ArchitectureHandler.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/architecture/ArchitectureHandler.java Tue Sep 25 06:27:49 2007
@@ -19,16 +19,12 @@
 package org.apache.felix.ipojo.composite.architecture;
 
 import java.util.Dictionary;
-import java.util.Properties;
 
 import org.apache.felix.ipojo.CompositeHandler;
-import org.apache.felix.ipojo.CompositeManager;
 import org.apache.felix.ipojo.architecture.Architecture;
 import org.apache.felix.ipojo.architecture.InstanceDescription;
 import org.apache.felix.ipojo.metadata.Element;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.framework.ServiceRegistration;
+import org.apache.felix.ipojo.util.Logger;
 
 /**
  * Composite Architecture Handler.
@@ -38,17 +34,6 @@
 public class ArchitectureHandler extends CompositeHandler implements Architecture {
 
     /**
-     * Composite Manager.
-     */
-    private CompositeManager m_manager;
-
-    /**
-     * Service Registration of the Architecture service provided by this
-     * handler.
-     */
-    private ServiceRegistration m_sr;
-
-    /**
      * Name of the component.
      */
     private String m_name;
@@ -56,55 +41,27 @@
     /**
      * Configure the handler.
      * 
-     * @param im : the instance manager
      * @param metadata : the metadata of the component
      * @param configuration : the instance configuration
      * @see org.apache.felix.ipojo.CompositeHandler#configure(org.apache.felix.ipojo.CompositeManager,
      * org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)
      */
-    public void configure(CompositeManager im, Element metadata, Dictionary configuration) {
-        if (metadata.containsAttribute("architecture")) {
-            String isArchitectureEnabled = (metadata.getAttribute("architecture")).toLowerCase();
-            if (isArchitectureEnabled.equalsIgnoreCase("true")) {
-                im.register(this);
-            }
-        }
-
+    public void configure(Element metadata, Dictionary configuration) {
         m_name = (String) configuration.get("name");
-
-        m_manager = im;
     }
 
     /**
      * Stop the handler.
-     * Unregister the service.
      * @see org.apache.felix.ipojo.Handler#stop()
      */
-    public void stop() {
-        if (m_sr != null) {
-            m_sr.unregister();
-            m_sr = null;
-        }
-    }
+    public void stop() { }
 
     /**
      * Start the handler.
-     * Register the service.
      * @see org.apache.felix.ipojo.Handler#start()
      */
-    public void start() {
-        // Unregister the service if already registered
-        if (m_sr != null) {
-            m_sr.unregister();
-        }
-
-        // Register the ManagedService
-        BundleContext bc = m_manager.getContext();
-        Dictionary properties = new Properties();
-        properties.put("Component.Type", m_manager.getComponentDescription().getName());
-        properties.put(Constants.SERVICE_PID, m_name);
-
-        m_sr = bc.registerService(Architecture.class.getName(), this, properties);
+    public void start() { 
+        log(Logger.INFO, "Start composite architecture handler with " + m_name + " name");
     }
 
     /**
@@ -113,7 +70,7 @@
      * @see org.apache.felix.ipojo.architecture.Architecture#getDescription()
      */
     public InstanceDescription getInstanceDescription() {
-        return m_manager.getInstanceDescription();
+        return getCompositeManager().getInstanceDescription();
     }
 
 }

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/instance/InstanceHandler.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/instance/InstanceHandler.java?rev=579239&r1=579238&r2=579239&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/instance/InstanceHandler.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/instance/InstanceHandler.java Tue Sep 25 06:27:49 2007
@@ -25,21 +25,17 @@
 
 import org.apache.felix.ipojo.ComponentInstance;
 import org.apache.felix.ipojo.CompositeHandler;
-import org.apache.felix.ipojo.CompositeManager;
+import org.apache.felix.ipojo.ConfigurationException;
 import org.apache.felix.ipojo.Factory;
 import org.apache.felix.ipojo.InstanceManager;
 import org.apache.felix.ipojo.InstanceStateListener;
+import org.apache.felix.ipojo.MissingHandlerException;
 import org.apache.felix.ipojo.ServiceContext;
 import org.apache.felix.ipojo.UnacceptableConfiguration;
 import org.apache.felix.ipojo.architecture.HandlerDescription;
 import org.apache.felix.ipojo.metadata.Element;
 import org.apache.felix.ipojo.parser.ParseException;
 import org.apache.felix.ipojo.util.Logger;
-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;
 
 /**
  * Composite Instance Handler.
@@ -47,38 +43,30 @@
  * This instance is determine by its type and a configuration.
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public class InstanceHandler extends CompositeHandler implements ServiceListener, InstanceStateListener {
+public class InstanceHandler extends CompositeHandler implements InstanceStateListener {
 
     /**
-     * Bundle context.
-     */
-    private BundleContext m_context;
-    
-    /**
      * Internal context.
      */
     private ServiceContext m_scope;
-    
-    /**
-     * Instance logger.
-     */
-    private Logger m_logger;
-    
+
     /**
-     * Composite Manager.
+     * Is the handler valid ?
+     * (Lifecycle controller)
      */
-    private CompositeManager m_manager;
+    private boolean m_isValid = false;
     
     /**
-     * IS the handler valid ?
+     * Available factories.
      */
-    private boolean m_validity = false;
+    private Factory[] m_factories;
     
+
     /**
      * This structure aims to manage a configuration. It stores all necessary
      * information to create an instance and to track the factory.
      */
-    private class ManagedConfiguration {
+    class ManagedConfiguration {
         /**
          * Configuration of the instance to create.
          */
@@ -93,6 +81,11 @@
          * Created instance.
          */
         private ComponentInstance m_instance;
+        
+        /**
+         * Desired Factory (can be the classname).
+         */
+        private String m_desiredFactory;
 
         /**
          * Constructor.
@@ -101,6 +94,7 @@
          */
         ManagedConfiguration(Dictionary conf) {
             m_configuration = conf;
+            m_desiredFactory = (String) conf.get("component");
         }
 
         /**
@@ -118,6 +112,10 @@
         String getFactory() {
             return m_factoryName;
         }
+        
+        String getNeededFactoryName() {
+            return m_desiredFactory;
+        }
 
         /**
          * Return the created instance.
@@ -164,49 +162,48 @@
             config.setFactory(fact.getName());
             config.getInstance().addInstanceStateListener(this);
         } catch (UnacceptableConfiguration e) {
-            m_logger.log(Logger.ERROR, "A factory is available for the configuration but the configuration is not acceptable", e);
+            log(Logger.ERROR, "A factory is available for the configuration but the configuration is not acceptable", e);
+        } catch (MissingHandlerException e) {
+            log(Logger.ERROR, "The instance creation has failed, at least one handler is missing", e);
+        } catch (ConfigurationException e) {
+            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)
+     * A new valid factory appears.
+     * @param f : factory.
      */
-    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");
+    public void bindFactory(Factory f) {
         boolean implicated = false;
-        if (ev.getType() == ServiceEvent.REGISTERED) {
-            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);
-                    createInstance(fact, m_configurations[i]);
-                    implicated = true;
-                }
-            }
-            if (implicated && !m_validity && checkValidity()) {
-                m_manager.checkInstanceState();
+        String factName = f.getName();
+        String className = f.getComponentDescription().getClassName();
+        for (int i = 0; i < m_configurations.length; i++) {
+            if (m_configurations[i].getInstance() == null && (m_configurations[i].getNeededFactoryName().equals(factName) || m_configurations[i].getNeededFactoryName().equals(className))) {
+                createInstance(f, m_configurations[i]);
+                implicated = true;
             }
-            return;
         }
-
-        if (ev.getType() == ServiceEvent.UNREGISTERING) {
-            for (int i = 0; i < m_configurations.length; i++) {
-                if (m_configurations[i].getInstance() != null && m_configurations[i].getFactory().equals(factoryName)) {
-                    m_configurations[i].setInstance(null);
-                    m_configurations[i].setFactory(null);
-                    m_context.ungetService(ref);
-                    implicated = true;
-                }
-            }
-            if (implicated && m_validity && !checkValidity()) {
-                m_manager.checkInstanceState();
+        if (implicated && ! m_isValid) {
+            checkValidity();
+        }
+    }
+    
+    /**
+     * An existing factory disappears or becomes invalid.
+     * @param f : factory
+     */
+    public void unbindFactory(Factory f) {
+        boolean implicated = false;
+        for (int i = 0; i < m_configurations.length; i++) {
+            if (m_configurations[i].getInstance() != null && m_configurations[i].getFactory().equals(f.getName())) {
+                m_configurations[i].setInstance(null);
+                m_configurations[i].setFactory(null);
+                implicated = true;
             }
-            return;
+        }
+        if (implicated && m_isValid) {
+            checkValidity();
         }
     }
 
@@ -214,31 +211,28 @@
      * Stop all created instances.
      */
     public synchronized void stop() {
-        m_context.removeServiceListener(this);
         for (int i = 0; i < m_configurations.length; i++) {
             if (m_configurations[i].getInstance() != null) {
                 m_configurations[i].getInstance().removeInstanceStateListener(this);
-                m_configurations[i].getInstance().dispose();
+                if (m_configurations[i].getInstance().getState() != ComponentInstance.DISPOSED) {
+                    m_configurations[i].getInstance().dispose();
+                }
             }
             m_configurations[i].setInstance(null);
             m_configurations[i].setFactory(null);
         }
-        m_configurations = null;
+        m_configurations = new ManagedConfiguration[0];
     }
-    
-    
+
     /**
      * Configure method.
-     * @param im : instance manager.
      * @param metadata : component type metadata.
      * @param configuration : instance configuration.
+     * @throws ConfigurationException : occurs an instance cannot be parsed correctly. 
      * @see org.apache.felix.ipojo.CompositeHandler#configure(org.apache.felix.ipojo.CompositeManager, org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)
      */
-    public void configure(CompositeManager im, Element metadata, Dictionary configuration) {
-        m_manager = im;
-        m_context = im.getContext();
-        m_logger = im.getFactory().getLogger();
-        m_scope = im.getServiceContext();
+    public void configure(Element metadata, Dictionary configuration) throws ConfigurationException {
+        m_scope = getCompositeManager().getServiceContext();
         Element[] instances = metadata.getElements("instance");
         m_configurations = new ManagedConfiguration[instances.length];
         for (int i = 0; i < instances.length; i++) {
@@ -246,20 +240,15 @@
             try {
                 conf = parseInstance(instances[i]);
             } catch (ParseException e) {
-                m_logger.log(Logger.ERROR, "An instance cannot be parsed correctly", e);
-                return;
+                log(Logger.ERROR, "An instance cannot be parsed correctly", e);
+                throw new ConfigurationException("An instance cannot be parsed correctly : " + e.getMessage(), getCompositeManager().getFactory().getName());
             }
             m_configurations[i] = new ManagedConfiguration(conf);
         }
-
-        if (m_configurations.length > 0) {
-            im.register(this);
-        }
     }
-    
+
     /**
      * Parse an Element to get a dictionary.
-     * 
      * @param instance : the Element describing an instance.
      * @return : the resulting dictionary
      * @throws ParseException : occurs when a configuration cannot be parse correctly.
@@ -269,10 +258,8 @@
         if (instance.containsAttribute("name")) {
             dict.put("name", instance.getAttribute("name"));
         }
-        if (!instance.containsAttribute("component")) {
-            throw new ParseException("An instance does not have the 'component' attribute");
-        }
-        
+        if (!instance.containsAttribute("component")) { throw new ParseException("An instance does not have the 'component' attribute"); }
+
         dict.put("component", instance.getAttribute("component"));
 
         for (int i = 0; i < instance.getElements("property").length; i++) {
@@ -281,7 +268,7 @@
 
         return dict;
     }
-    
+
     /**
      * Parse a property.
      * @param prop : the current element to parse
@@ -290,9 +277,7 @@
      */
     private void parseProperty(Element prop, Dictionary dict) throws ParseException {
         // Check that the property has a name
-        if (!prop.containsAttribute("name")) {
-            throw new ParseException("A property does not have the 'name' attribute");
-        }
+        if (!prop.containsAttribute("name")) { throw new ParseException("A property does not have the 'name' attribute"); }
         // Final case : the property element has a 'value' attribute
         if (prop.containsAttribute("value")) {
             dict.put(prop.getAttribute("name"), prop.getAttribute("value"));
@@ -300,9 +285,7 @@
             // Recursive case
             // Check if there is 'property' element
             Element[] subProps = prop.getElements("property");
-            if (subProps.length == 0) {
-                throw new ParseException("A complex property must have at least one 'property' sub-element");
-            }
+            if (subProps.length == 0) { throw new ParseException("A complex property must have at least one 'property' sub-element"); }
             Dictionary dict2 = new Properties();
             for (int i = 0; i < subProps.length; i++) {
                 parseProperty(subProps[i], dict2);
@@ -315,45 +298,20 @@
      * Start method.
      * @see org.apache.felix.ipojo.CompositeHandler#start()
      */
-    public void start() {
-        for (int i = 0; i < m_configurations.length; i++) {
-
-            // Get the component type name :
-            String componentType = (String) m_configurations[i].getConfiguration().get("component");
-            Factory fact = null;
-
-            try {
-                String fil = "(|(" + org.osgi.framework.Constants.SERVICE_PID + "=" + componentType + ")(component.class=" + componentType + "))";
-                ServiceReference[] refs = m_context.getServiceReferences(org.apache.felix.ipojo.Factory.class.getName(), fil);
-                if (refs != null) {
-                    fact = (Factory) m_context.getService(refs[0]);
-                    createInstance(fact, m_configurations[i]);
+    public void start() { 
+        for (int j = 0; j < m_factories.length; j++) {
+            String factName = m_factories[j].getName();
+            String className = m_factories[j].getComponentDescription().getClassName(); 
+            for (int i = 0; i < m_configurations.length; i++) {
+                if (m_configurations[i].getInstance() == null && (m_configurations[i].getNeededFactoryName().equals(factName) || m_configurations[i].getNeededFactoryName().equals(className))) {
+                    createInstance(m_factories[j], m_configurations[i]);
                 }
-            } catch (InvalidSyntaxException e) {
-                m_logger.log(Logger.ERROR, "Invalid syntax filter for the type : " + componentType, e);
             }
         }
-
-        // Register a service listener on Factory Service
-        try {
-            m_context.addServiceListener(this, "(objectClass=" + Factory.class.getName() + ")");
-        } catch (InvalidSyntaxException e) {
-            m_logger.log(Logger.ERROR, "Invalid syntax filter when registering a listener on Factory Service", e);
-        }
         
-        //Compute validity 
         checkValidity();
     }
-    
-    /**
-     * The handler is valid if all managed instances are created and are valid.
-     * @return true if all managed configuration have been instanciated and are valid.
-     * @see org.apache.felix.ipojo.CompositeHandler#isValid()
-     */
-    public boolean isValid() {
-        return m_validity;
-    }
-    
+
     /**
      * Check handler validity.
      * The method update the m_validity field.
@@ -362,56 +320,57 @@
     private boolean checkValidity() {
         for (int i = 0; i < m_configurations.length; i++) {
             if (m_configurations[i].getInstance() == null || m_configurations[i].getInstance().getState() != ComponentInstance.VALID) {
-                m_validity = false;
+                m_isValid = false;
                 return false;
             }
         }
-        m_validity = true;
+        m_isValid = true;
         return true;
     }
 
-    /** Instance state listener.
+    /**
+     *  Instance state listener.
      *  This method listens when managed instance states change.
      *  @param instance : instance
      *  @param newState : the now state of the given instance
      *  @see org.apache.felix.ipojo.InstanceStateListener#stateChanged(org.apache.felix.ipojo.ComponentInstance, int)
      */
     public void stateChanged(ComponentInstance instance, int newState) {
-        switch(newState) {
-            case ComponentInstance.DISPOSED : 
-            case ComponentInstance.STOPPED :
+        switch (newState) {
+            case ComponentInstance.DISPOSED:
+            case ComponentInstance.STOPPED:
                 break; // Should not happen
-            case ComponentInstance.VALID :
-                if (! m_validity && checkValidity()) { 
-                    m_manager.checkInstanceState();
+            case ComponentInstance.VALID:
+                if (!m_isValid) {
+                    checkValidity();
                 }
                 break;
-            case ComponentInstance.INVALID :
-                if (m_validity && ! checkValidity()) {
-                    m_manager.checkInstanceState();
+            case ComponentInstance.INVALID:
+                if (m_isValid) {
+                    checkValidity();
                 }
                 break;
-            default :
+            default:
                 break;
-            
+
         }
     }
-    
+
     /**
      * Method returning an instance object of the given component type.
      * This method must be called only on 'primitive' type.
      * @param type : type.
      * @return an instance object or null if not found.
      */
-    public Object getObjectFromInstance(String type)  {
+    public Object getObjectFromInstance(String type) {
         for (int i = 0; i < m_configurations.length; i++) {
-            if (m_configurations[i].getInstance() != null && type.equals(m_configurations[i].getFactory()) && m_configurations[i].getInstance().getState() == ComponentInstance.VALID) {
-                return ((InstanceManager) m_configurations[i].getInstance()).getPojoObject();
+            if (m_configurations[i].getInstance() != null && type.equals(m_configurations[i].getFactory()) && m_configurations[i].getInstance().getState() == ComponentInstance.VALID) { 
+                return ((InstanceManager) m_configurations[i].getInstance()).getPojoObject(); 
             }
         }
         return null;
     }
-    
+
     /**
      * Return the handler description, i.e. the state of created instances.
      * @return the handler description.
@@ -420,13 +379,11 @@
     public HandlerDescription getDescription() {
         List l = new ArrayList();
         for (int i = 0; i < m_configurations.length; i++) {
-            if (m_configurations[i].getInstance() != null) {
-                l.add(m_configurations[i]);
-            }
+            l.add(m_configurations[i]);
         }
-        return new InstanceHandlerDescription(InstanceHandler.class.getName(), m_validity, l);
+        return new InstanceHandlerDescription(this, l);
     }
-    
+
     /**
      * Get the list of used component type.
      * @return the list containing the used component type

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/instance/InstanceHandlerDescription.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/instance/InstanceHandlerDescription.java?rev=579239&r1=579238&r2=579239&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/instance/InstanceHandlerDescription.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/instance/InstanceHandlerDescription.java Tue Sep 25 06:27:49 2007
@@ -21,7 +21,9 @@
 import java.util.List;
 
 import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.CompositeHandler;
 import org.apache.felix.ipojo.architecture.HandlerDescription;
+import org.apache.felix.ipojo.composite.instance.InstanceHandler.ManagedConfiguration;
 import org.apache.felix.ipojo.metadata.Attribute;
 import org.apache.felix.ipojo.metadata.Element;
 
@@ -40,12 +42,11 @@
     /**
      * Constructor.
      * 
-     * @param arg0 : name of the handler
-     * @param arg1 : validity of the handler
+     * @param h : handler
      * @param insts : list of component instances
      */
-    public InstanceHandlerDescription(String arg0, boolean arg1, List insts) {
-        super(arg0, arg1);
+    public InstanceHandlerDescription(CompositeHandler h, List insts) {
+        super(h);
         m_instances = insts;
     }
 
@@ -57,25 +58,31 @@
     public Element getHandlerInfo() {
         Element instances = super.getHandlerInfo();
         for (int i = 0; i < m_instances.size(); i++) {
-            ComponentInstance inst = (ComponentInstance) m_instances.get(i);
+            ManagedConfiguration inst = (ManagedConfiguration) m_instances.get(i);
             Element instance = new Element("Instance", "");
-            instance.addAttribute(new Attribute("Name", inst.getInstanceName()));
-            String state = null;
-            switch(inst.getState()) {
-                case ComponentInstance.DISPOSED : 
-                    state = "disposed"; break;
-                case ComponentInstance.STOPPED : 
-                    state = "stopped"; break;
-                case ComponentInstance.VALID : 
-                    state = "valid"; break;
-                case ComponentInstance.INVALID : 
-                    state = "invalid"; break;
-                default :
-                    break;
+            if (inst.getInstance() != null) {
+                instance.addAttribute(new Attribute("Factory", inst.getFactory()));
+                instance.addAttribute(new Attribute("Name", inst.getInstance().getInstanceName()));
+                String state = null;
+                switch(inst.getInstance().getState()) {
+                    case ComponentInstance.DISPOSED : 
+                        state = "disposed"; break;
+                    case ComponentInstance.STOPPED : 
+                        state = "stopped"; break;
+                    case ComponentInstance.VALID : 
+                        state = "valid"; break;
+                    case ComponentInstance.INVALID : 
+                        state = "invalid"; break;
+                    default :
+                        break;
+                }
+                instance.addAttribute(new Attribute("State", state));
+                instance.addElement(inst.getInstance().getInstanceDescription().getDescription());
+            } else {
+                instance.addAttribute(new Attribute("Factory", inst.getConfiguration().get("component").toString()));
+                instance.addAttribute(new Attribute("State", "Not Available"));
             }
-            instance.addAttribute(new Attribute("State", state));
-            instance.addElement(inst.getInstanceDescription().getDescription());
-            instances.addElement(instances);
+            instances.addElement(instance);
         }
         return instances;
     }

Copied: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ExportDescription.java (from r565648, felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportExportDescription.java)
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ExportDescription.java?p2=felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ExportDescription.java&p1=felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportExportDescription.java&r1=565648&r2=579239&rev=579239&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportExportDescription.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ExportDescription.java Tue Sep 25 06:27:49 2007
@@ -20,6 +20,7 @@
 
 import java.util.List;
 
+import org.apache.felix.ipojo.CompositeHandler;
 import org.apache.felix.ipojo.architecture.HandlerDescription;
 import org.apache.felix.ipojo.metadata.Attribute;
 import org.apache.felix.ipojo.metadata.Element;
@@ -28,12 +29,7 @@
  * Description of the Import Export Handler.
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public class ImportExportDescription extends HandlerDescription {
-
-    /**
-     * List of imports.
-     */
-    private List m_imports;
+public class ExportDescription extends HandlerDescription {
 
     /**
      * List of exports.
@@ -43,14 +39,11 @@
     /**
      * Constructor.
      * 
-     * @param name : name of the handler
-     * @param isValid : handler validity
-     * @param importers : list of managed imports
+     * @param h : composite handler
      * @param exporters : list of managed exports
      */
-    public ImportExportDescription(String name, boolean isValid, List importers, List exporters) {
-        super(name, isValid);
-        m_imports = importers;
+    public ExportDescription(CompositeHandler h, List exporters) {
+        super(h);
         m_exports = exporters;
     }
 
@@ -61,26 +54,9 @@
      */
     public Element getHandlerInfo() {
         Element handler = super.getHandlerInfo();
-        for (int i = 0; i < m_imports.size(); i++) {
-            ServiceImporter imp = (ServiceImporter) m_imports.get(i);
-            Element impo = new Element("Requires", "");
-            impo.addAttribute(new Attribute("Specification", imp.getSpecification()));
-            if (imp.getFilter() != null) { impo.addAttribute(new Attribute("Filter", imp.getFilter())); }
-            if (imp.isSatisfied()) {
-                impo.addAttribute(new Attribute("State", "resolved"));
-                for (int j = 0; j < imp.getProviders().size(); j++) {
-                    Element pr = new Element("Provider", "");
-                    pr.addAttribute(new Attribute("name", (String) imp.getProviders().get(j)));
-                    impo.addElement(pr);
-                }
-            } else {
-                impo.addAttribute(new Attribute("State", "unresolved"));
-            }
-            handler.addElement(impo);
-        }
         for (int i = 0; i < m_exports.size(); i++) {
             ServiceExporter exp = (ServiceExporter) m_exports.get(i);
-            Element expo = new Element("Export", "");
+            Element expo = new Element("Exports", "");
             expo.addAttribute(new Attribute("Specification", exp.getSpecification()));
             expo.addAttribute(new Attribute("Filter", exp.getFilter()));
             if (exp.isSatisfied()) {
@@ -93,5 +69,4 @@
         return handler;
 
     }
-
 }

Added: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ExportHandler.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ExportHandler.java?rev=579239&view=auto
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ExportHandler.java (added)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ExportHandler.java Tue Sep 25 06:27:49 2007
@@ -0,0 +1,204 @@
+/* 
+ * 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.composite.service.importer;
+
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.List;
+
+import org.apache.felix.ipojo.CompositeHandler;
+import org.apache.felix.ipojo.ConfigurationException;
+import org.apache.felix.ipojo.ServiceContext;
+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;
+import org.osgi.framework.BundleContext;
+
+/**
+ * This handler manages the import and the export of services from /
+ * to the parent context.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ExportHandler extends CompositeHandler {
+
+    /**
+     * Service Scope.
+     */
+    private ServiceContext m_scope;
+
+    /**
+     * Parent context.
+     */
+    private BundleContext m_context;
+
+    /**
+     * List of exporters.
+     */
+    private List m_exporters = new ArrayList();
+
+    /**
+     * Is the handler valid ?
+     * (Lifecycle controller)
+     */
+    private boolean m_valid;
+
+    /**
+     * Initialize the component type.
+     * @param cd : component type description to populate.
+     * @param metadata : component type metadata.
+     * @see org.apache.felix.ipojo.Handler#initializeComponentFactory(org.apache.felix.ipojo.architecture.ComponentDescription, org.apache.felix.ipojo.metadata.Element)
+     */
+    public void initializeComponentFactory(ComponentDescription cd, Element metadata) {
+        // Update the component type description
+        Element[] exp = metadata.getElements("exports");
+        for (int i = 0; i < exp.length; i++) {
+            if (exp[i].containsAttribute("specification")) { // Malformed exports
+                String specification = exp[i].getAttribute("specification");
+                cd.addProvidedServiceSpecification(specification);
+            }
+        }
+    }
+
+    /**
+     * Configure the handler.
+     * @param metadata : the metadata of the component
+     * @param conf : the instance configuration
+     * @throws ConfigurationException : if the specification attribute is missing in the metadata.
+     * @see org.apache.felix.ipojo.CompositeHandler#configure(org.apache.felix.ipojo.CompositeManager,
+     * org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)
+     */
+    public void configure(Element metadata, Dictionary conf) throws ConfigurationException {
+        m_context = getCompositeManager().getContext();
+        m_scope = getCompositeManager().getServiceContext();
+
+        Element[] exp = metadata.getElements("exports");
+
+        for (int i = 0; i < exp.length; i++) {
+            boolean optional = false;
+            boolean aggregate = false;
+            String specification = null;
+
+            if (exp[i].containsAttribute("specification")) {
+                specification = exp[i].getAttribute("specification");
+                String filter = "(objectClass=" + specification + ")";
+                if (exp[i].containsAttribute("optional") && exp[i].getAttribute("optional").equalsIgnoreCase("true")) {
+                    optional = true;
+                }
+                if (exp[i].containsAttribute("aggregate") && exp[i].getAttribute("aggregate").equalsIgnoreCase("true")) {
+                    aggregate = true;
+                }
+                if (exp[i].containsAttribute("filter")) {
+                    String classnamefilter = "(objectClass=" + specification + ")";
+                    filter = null;
+                    if ("".equals(exp[i].getAttribute("filter"))) {
+                        filter = classnamefilter;
+                    } else {
+                        filter = "(&" + classnamefilter + exp[i].getAttribute("filter") + ")";
+                    }
+                }
+                ServiceExporter si = new ServiceExporter(specification, filter, aggregate, optional, m_scope, m_context, this);
+                m_exporters.add(si);
+            } else { // Malformed exports
+                log(Logger.ERROR, "Malformed exports : the specification attribute is mandatory");
+                throw new ConfigurationException("Malformed exports : the specification attribute is mandatory", getCompositeManager().getFactory().getName());
+            }
+        }
+    }
+
+    /**
+     * Start the handler.
+     * Start importers and exporters.
+     * @see org.apache.felix.ipojo.CompositeHandler#start()
+     */
+    public void start() {
+        for (int i = 0; i < m_exporters.size(); i++) {
+            ServiceExporter se = (ServiceExporter) m_exporters.get(i);
+            se.start();
+        }
+
+        isHandlerValid();
+
+    }
+
+    /**
+     * Stop the handler.
+     * Stop all importers and exporters.
+     * @see org.apache.felix.ipojo.CompositeHandler#stop()
+     */
+    public void stop() {
+        for (int i = 0; i < m_exporters.size(); i++) {
+            ServiceExporter se = (ServiceExporter) m_exporters.get(i);
+            se.stop();
+        }
+    }
+
+    /**
+     * Check the handler validity.
+     * @return true if all importers and exporters are valid
+     * @see org.apache.felix.ipojo.CompositeHandler#isValid()
+     */
+    private boolean isHandlerValid() {
+        for (int i = 0; i < m_exporters.size(); i++) {
+            ServiceExporter se = (ServiceExporter) m_exporters.get(i);
+            if (!se.isSatisfied()) {
+                m_valid = false;
+                return false;
+            }
+        }
+
+        m_valid = true;
+        return true;
+    }
+
+    /**
+     * Notify the handler that an exporter becomes invalid.
+     * 
+     * @param exporter : the implicated exporter.
+     */
+    protected void invalidating(ServiceExporter exporter) {
+        // An export is no more valid
+        if (m_valid) {
+            m_valid = false;
+        }
+
+    }
+
+    /**
+     * Notify the handler that an exporter becomes valid.
+     * 
+     * @param exporter : the implicated exporter.
+     */
+    protected void validating(ServiceExporter exporter) {
+        // An import becomes valid
+        if (!m_valid) {
+            isHandlerValid();
+        }
+    }
+
+    /**
+     * Get the import / export handler description.
+     * @return the handler description
+     * @see org.apache.felix.ipojo.CompositeHandler#getDescription()
+     */
+    public HandlerDescription getDescription() {
+        return new ExportDescription(this, m_exporters);
+    }
+}

Added: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportDescription.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportDescription.java?rev=579239&view=auto
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportDescription.java (added)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportDescription.java Tue Sep 25 06:27:49 2007
@@ -0,0 +1,79 @@
+/* 
+ * 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.composite.service.importer;
+
+import java.util.List;
+
+import org.apache.felix.ipojo.CompositeHandler;
+import org.apache.felix.ipojo.architecture.HandlerDescription;
+import org.apache.felix.ipojo.metadata.Attribute;
+import org.apache.felix.ipojo.metadata.Element;
+
+/**
+ * Description of the Import Export Handler.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ImportDescription extends HandlerDescription {
+
+    /**
+     * List of exports.
+     */
+    private List m_imports;
+
+    /**
+     * Constructor.
+     * 
+     * @param h : composite handler
+     * @param importers : list of managed imports
+     */
+    public ImportDescription(CompositeHandler h, List importers) {
+        super(h);
+        m_imports = importers;
+    }
+
+    /**
+     * Build the ImportExport handler description.
+     * @return the handler description
+     * @see org.apache.felix.ipojo.architecture.HandlerDescription#getHandlerInfo()
+     */
+    public Element getHandlerInfo() {
+        Element handler = super.getHandlerInfo();
+        for (int i = 0; i < m_imports.size(); i++) {
+            ServiceImporter imp = (ServiceImporter) m_imports.get(i);
+            Element impo = new Element("Requires", "");
+            impo.addAttribute(new Attribute("Specification", imp.getSpecification()));
+            if (imp.getFilter() != null) {
+                impo.addAttribute(new Attribute("Filter", imp.getFilter()));
+            }
+            if (imp.isSatisfied()) {
+                impo.addAttribute(new Attribute("State", "resolved"));
+                for (int j = 0; j < imp.getProviders().size(); j++) {
+                    Element pr = new Element("Provider", "");
+                    pr.addAttribute(new Attribute("name", (String) imp.getProviders().get(j)));
+                    impo.addElement(pr);
+                }
+            } else {
+                impo.addAttribute(new Attribute("State", "unresolved"));
+            }
+            handler.addElement(impo);
+        }
+        return handler;
+    }
+
+}

Copied: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportHandler.java (from r565648, felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportExportHandler.java)
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportHandler.java?p2=felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportHandler.java&p1=felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportExportHandler.java&r1=565648&r2=579239&rev=579239&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportExportHandler.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportHandler.java Tue Sep 25 06:27:49 2007
@@ -23,7 +23,7 @@
 import java.util.List;
 
 import org.apache.felix.ipojo.CompositeHandler;
-import org.apache.felix.ipojo.CompositeManager;
+import org.apache.felix.ipojo.ConfigurationException;
 import org.apache.felix.ipojo.PolicyServiceContext;
 import org.apache.felix.ipojo.ServiceContext;
 import org.apache.felix.ipojo.architecture.HandlerDescription;
@@ -37,12 +37,7 @@
  * 
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public class ImportExportHandler extends CompositeHandler {
-
-    /**
-     * Composite Manager.
-     */
-    private CompositeManager m_manager;
+public class ImportHandler extends CompositeHandler {
 
     /**
      * Service Scope.
@@ -60,52 +55,35 @@
     private List m_importers = new ArrayList();
 
     /**
-     * List of exporters.
-     */
-    private List m_exporters = new ArrayList();
-
-    /**
      * Is the handler valid ?
+     * (Lifecycle controller)
      */
     private boolean m_valid;
+    
 
     /**
      * Configure the handler.
      * 
-     * @param im : the instance manager
      * @param metadata : the metadata of the component
      * @param conf : the instance configuration
+     * @throws ConfigurationException : the specification attribute is missing. 
      * @see org.apache.felix.ipojo.CompositeHandler#configure(org.apache.felix.ipojo.CompositeManager,
      * org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)
      */
-    public void configure(CompositeManager im, Element metadata, Dictionary conf) {
-        m_manager = im;
-        m_context = im.getContext();
-        m_scope = m_manager.getServiceContext();
+    public void configure(Element metadata, Dictionary conf) throws ConfigurationException {
+        m_context = getCompositeManager().getContext();
+        m_scope = getCompositeManager().getServiceContext();
 
         Element[] imp = metadata.getElements("requires");
 
-        //DEPRECATED BLOCK:
-        if (imp.length == 0) {
-            imp = metadata.getElements("import");
-            if (imp.length != 0) {
-                im.getFactory().getLogger().log(Logger.WARNING, "Import is deprecated, please use 'requires' instead of 'import'");
-            }
-        }
-        // END OF DEPRECATED BLOCK
-        
-        Element[] exp = metadata.getElements("export");
-
         for (int i = 0; i < imp.length; i++) {
             boolean optional = false;
             boolean aggregate = false;
             String specification = null;
 
-            if (!imp[i].containsAttribute("specification")) { // Malformed import
-                im.getFactory().getLogger().log(Logger.ERROR, "Malformed import : the specification attribute is mandatory");
-            } else {
+            if (imp[i].containsAttribute("specification")) {
                 specification = imp[i].getAttribute("specification");
-                String filter = "(&(objectClass=" + specification + ")(!(service.pid=" + m_manager.getInstanceName() + ")))"; // Cannot import yourself
+                String filter = "(&(objectClass=" + specification + ")(!(instance.name=" + getCompositeManager().getInstanceName() + ")))"; // Cannot import yourself
                 if (imp[i].containsAttribute("optional") && imp[i].getAttribute("optional").equalsIgnoreCase("true")) {
                     optional = true;
                 }
@@ -113,7 +91,7 @@
                     aggregate = true;
                 }
                 if (imp[i].containsAttribute("filter")) {
-                    if (!imp[i].getAttribute("filter").equals("")) {
+                    if (!"".equals(imp[i].getAttribute("filter"))) {
                         filter = "(&" + filter + imp[i].getAttribute("filter") + ")";
                     }
                 }
@@ -133,47 +111,13 @@
                         scopePolicy = PolicyServiceContext.LOCAL_AND_GLOBAL;
                     }                
                 }
-                
                 ServiceImporter si = new ServiceImporter(specification, filter, aggregate, optional, m_context, m_scope, scopePolicy, id, this);
                 m_importers.add(si);
+            } else { // Malformed import
+                log(Logger.ERROR, "Malformed imports : the specification attribute is mandatory");
+                throw new ConfigurationException("Malformed imports : the specification attribute is mandatory", getCompositeManager().getFactory().getName());
             }
         }
-
-        for (int i = 0; i < exp.length; i++) {
-            boolean optional = false;
-            boolean aggregate = false;
-            String specification = null;
-
-            if (!exp[i].containsAttribute("specification")) { // Malformed exports
-                im.getFactory().getLogger().log(Logger.ERROR, "Malformed exports : the specification attribute is mandatory");
-            } else {
-                specification = exp[i].getAttribute("specification");
-                String filter = "(objectClass=" + specification + ")";
-                if (exp[i].containsAttribute("optional") && exp[i].getAttribute("optional").equalsIgnoreCase("true")) {
-                    optional = true;
-                }
-                if (exp[i].containsAttribute("aggregate") && exp[i].getAttribute("aggregate").equalsIgnoreCase("true")) {
-                    aggregate = true;
-                }
-                if (exp[i].containsAttribute("filter")) {
-                    String classnamefilter = "(objectClass=" + specification + ")";
-                    filter = "";
-                    if (!imp[i].getAttribute("filter").equals("")) {
-                        filter = "(&" + classnamefilter + exp[i].getAttribute("filter") + ")";
-                    } else {
-                        filter = classnamefilter;
-                    }
-                }
-                ServiceExporter si = new ServiceExporter(specification, filter, aggregate, optional, m_scope, m_context, this);
-                // Update the component type description
-                m_manager.getComponentDescription().addProvidedServiceSpecification(specification);
-                m_exporters.add(si);
-            }
-        }
-
-        if (m_importers.size() > 0 || m_exporters.size() > 0) {
-            im.register(this);
-        }
     }
 
     /**
@@ -186,12 +130,7 @@
             ServiceImporter si = (ServiceImporter) m_importers.get(i);
             si.start();
         }
-
-        for (int i = 0; i < m_exporters.size(); i++) {
-            ServiceExporter se = (ServiceExporter) m_exporters.get(i);
-            se.start();
-        }
-
+        isHandlerValid();
     }
 
     /**
@@ -204,11 +143,6 @@
             ServiceImporter si = (ServiceImporter) m_importers.get(i);
             si.stop();
         }
-
-        for (int i = 0; i < m_exporters.size(); i++) {
-            ServiceExporter se = (ServiceExporter) m_exporters.get(i);
-            se.stop();
-        }
     }
 
     /**
@@ -216,7 +150,7 @@
      * @return true if all importers and exporters are valid
      * @see org.apache.felix.ipojo.CompositeHandler#isValid()
      */
-    public boolean isValid() {
+    public boolean isHandlerValid() {
         for (int i = 0; i < m_importers.size(); i++) {
             ServiceImporter si = (ServiceImporter) m_importers.get(i);
             if (!si.isSatisfied()) {
@@ -224,15 +158,6 @@
                 return false;
             }
         }
-
-        for (int i = 0; i < m_exporters.size(); i++) {
-            ServiceExporter se = (ServiceExporter) m_exporters.get(i);
-            if (!se.isSatisfied()) {
-                m_valid = false;
-                return false;
-            }
-        }
-
         m_valid = true;
         return true;
     }
@@ -245,9 +170,8 @@
     protected void invalidating(ServiceImporter importer) {
         // An import is no more valid
         if (m_valid) {
-            m_manager.checkInstanceState();
+            m_valid = false;
         }
-
     }
 
     /**
@@ -257,44 +181,9 @@
      */
     protected void validating(ServiceImporter importer) {
         // An import becomes valid
-        if (!m_valid && isValid()) {
-            m_manager.checkInstanceState();
+        if (!m_valid) {
+            isHandlerValid();
         }
-
-    }
-
-    /**
-     * Notify the handler that an exporter becomes invalid.
-     * 
-     * @param exporter : the implicated exporter.
-     */
-    protected void invalidating(ServiceExporter exporter) {
-        // An import is no more valid
-        if (m_valid) {
-            m_manager.checkInstanceState();
-        }
-
-    }
-
-    /**
-     * Notify the handler that an exporter becomes valid.
-     * 
-     * @param exporter : the implicated exporter.
-     */
-    protected void validating(ServiceExporter exporter) {
-        // An import becomes valid
-        if (!m_valid && isValid()) {
-            m_manager.checkInstanceState();
-        }
-
-    }
-
-    /**
-     * Get the composite manager.
-     * @return the attached composite manager.
-     */
-    protected CompositeManager getManager() {
-        return m_manager;
     }
 
     /**
@@ -303,7 +192,7 @@
      * @see org.apache.felix.ipojo.CompositeHandler#getDescription()
      */
     public HandlerDescription getDescription() {
-        return new ImportExportDescription(this.getClass().getName(), isValid(), m_importers, m_exporters);
+        return new ImportDescription(this, m_importers);
     }
     
     public List getRequirements() {

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ServiceExporter.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ServiceExporter.java?rev=579239&r1=579238&r2=579239&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ServiceExporter.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ServiceExporter.java Tue Sep 25 06:27:49 2007
@@ -24,12 +24,11 @@
 import java.util.Properties;
 
 import org.apache.felix.ipojo.ServiceContext;
+import org.apache.felix.ipojo.util.Tracker;
+import org.apache.felix.ipojo.util.TrackerCustomizer;
 import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
 import org.osgi.framework.Filter;
 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;
 
@@ -38,7 +37,7 @@
  * 
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public class ServiceExporter implements ServiceListener {
+public class ServiceExporter implements TrackerCustomizer {
 
     /**
      * Destination context.
@@ -78,12 +77,17 @@
     /**
      * Reference of the handler.
      */
-    private ImportExportHandler m_handler;
+    private ExportHandler m_handler;
 
     /**
      * Is the exporter valid?
      */
     private boolean m_isValid;
+    
+    /**
+     * Tracker tracking internal service (to export).
+     */
+    private Tracker m_tracker;
 
     /**
      * Structure Reference, Registration, Service Object.
@@ -120,7 +124,7 @@
      * @param exp : handler
      */
     public ServiceExporter(String specification, String filter, boolean multiple, boolean optional, ServiceContext from, BundleContext to,
-            ImportExportHandler exp) {
+            ExportHandler exp) {
         this.m_destination = to;
         this.m_origin = from;
         this.m_handler = exp;
@@ -140,49 +144,15 @@
      * Start the provider tracking and the publication.
      */
     public void start() {
-        try {
-            ServiceReference[] refs = m_origin.getServiceReferences(m_specification, null);
-            if (refs != null) {
-                for (int i = 0; i < refs.length; i++) {
-                    if (m_filter.match(refs[i])) {
-                        Record rec = new Record();
-                        rec.m_ref = refs[i];
-                        m_records.add(rec);
-                    }
-                }
-            }
-        } catch (InvalidSyntaxException e) {
-            e.printStackTrace();
-        }
-
-        // Publish available services
-        if (m_records.size() > 0) {
-            if (m_aggregate) {
-                for (int i = 0; i < m_records.size(); i++) {
-                    Record rec = (Record) m_records.get(i);
-                    rec.m_svcObject = m_origin.getService(rec.m_ref);
-                    rec.m_reg = m_destination.registerService(m_specification, rec.m_svcObject, getProps(rec.m_ref));
-                }
-            } else {
-                Record rec = (Record) m_records.get(0);
-                rec.m_svcObject = m_origin.getService(rec.m_ref);
-                rec.m_reg = m_destination.registerService(m_specification, rec.m_svcObject, getProps(rec.m_ref));
-            }
-        }
-
-        // Register service listener
-        try {
-            m_origin.addServiceListener(this, "(" + Constants.OBJECTCLASS + "=" + m_specification + ")");
-        } catch (InvalidSyntaxException e) {
-            e.printStackTrace();
-        }
+        m_tracker = new Tracker(m_origin, m_filter, this);
+        m_tracker.open();
 
         m_isValid = isSatisfied();
     }
 
     /**
      * Transform service reference property in a dictionary.
-     * Service.PID and Factory.PID are injected too.
+     * instance.name and factory.name are injected too.
      * @param ref : the service reference.
      * @return the dictionary containing all property of the given service reference.
      */
@@ -193,8 +163,8 @@
             prop.put(keys[i], ref.getProperty(keys[i]));
         }
 
-        prop.put(Constants.SERVICE_PID, m_handler.getManager().getInstanceName());
-        prop.put("factory.pid", m_handler.getManager().getFactory().getName());
+        prop.put("instance.name", m_handler.getCompositeManager().getInstanceName());
+        prop.put("factory.name", m_handler.getCompositeManager().getFactory().getName());
 
         return prop;
     }
@@ -205,18 +175,20 @@
      * Unregister all exported services.
      */
     public void stop() {
-        m_origin.removeServiceListener(this);
+        m_tracker.close();
 
         for (int i = 0; i < m_records.size(); i++) {
             Record rec = (Record) m_records.get(i);
             rec.m_svcObject = null;
             if (rec.m_reg != null) {
                 rec.m_reg.unregister();
-                m_origin.ungetService(rec.m_ref);
+                rec.m_reg = null;
+                m_tracker.ungetService(rec.m_ref);
                 rec.m_ref = null;
             }
         }
 
+        m_tracker = null;
         m_records.clear();
 
     }
@@ -244,82 +216,71 @@
         }
         return l;
     }
+    
+    protected String getSpecification() {
+        return m_specification;
+    }
+    
+    public String getFilter() {
+        return m_filterStr;
+    }
 
     /**
-     * Service Listener Implementation.
-     * @param ev : the service event
-     * @see org.osgi.framework.ServiceListener#serviceChanged(org.osgi.framework.ServiceEvent)
-     */
-    public void serviceChanged(ServiceEvent ev) {
-        if (ev.getType() == ServiceEvent.REGISTERED) {
-            arrivalManagement(ev.getServiceReference());
-        }
-        if (ev.getType() == ServiceEvent.UNREGISTERING) {
-            departureManagement(ev.getServiceReference());
-        }
-
-        if (ev.getType() == ServiceEvent.MODIFIED) {
-            if (m_filter.match(ev.getServiceReference())) {
-                // Test if the reference is always matching with the filter
-                List l = getRecordsByRef(ev.getServiceReference());
-                if (l.size() > 0) { // The reference is already contained => update the properties
-                    for (int i = 0; i < l.size(); i++) { // Stop the implied record
-                        Record rec = (Record) l.get(i);
-                        if (rec.m_reg != null) {
-                            rec.m_reg.setProperties(getProps(rec.m_ref));
-                        }
-                    }
-                } else { // it is a new matching service => add it
-                    arrivalManagement(ev.getServiceReference());
-                }
-            } else {
-                List l = getRecordsByRef(ev.getServiceReference());
-                if (l.size() > 0) { // The reference is already contained => the service does no more match
-                    departureManagement(ev.getServiceReference());
-                }
-            }
-        }
+     * An exported service appears.
+     * @param reference : service reference
+     * @return true as the filter guaranty the export.
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addingService(org.osgi.framework.ServiceReference)
+     */
+    public boolean addingService(ServiceReference reference) {
+        Record rec = new Record();
+        rec.m_ref = reference;
+        m_records.add(rec);
+        // Publishing ?
+        if (m_records.size() == 1 || m_aggregate) { // If the service is the first one, or if it is a multiple imports
+            rec.m_svcObject = m_tracker.getService(rec.m_ref);
+            rec.m_reg = m_destination.registerService(m_specification, rec.m_svcObject, getProps(rec.m_ref));
+        }
+        // Compute the new state
+        if (!m_isValid && isSatisfied()) {
+            m_isValid = true;
+            m_handler.validating(this);
+        }
+        
+        return true;
     }
 
     /**
-     * Manage the arrival of a service.
-     * @param ref : the new service reference.
-     */
-    private void arrivalManagement(ServiceReference ref) {
-        // Check if the new service match
-        if (m_filter.match(ref)) {
-            // Add it to the record list
-            Record rec = new Record();
-            rec.m_ref = ref;
-            m_records.add(rec);
-            // Publishing ?
-            if (m_records.size() == 1 || m_aggregate) { // If the service is the
-                // first one, or if it
-                // is a multiple imports
-                rec.m_svcObject = m_origin.getService(rec.m_ref);
-                rec.m_reg = m_destination.registerService(m_specification, rec.m_svcObject, getProps(rec.m_ref));
-            }
-            // Compute the new state
-            if (!m_isValid && isSatisfied()) {
-                m_isValid = true;
-                m_handler.validating(this);
+     * An exported service was modified.
+     * @param reference : modified reference
+     * @param service : service object
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#modifiedService(org.osgi.framework.ServiceReference, java.lang.Object)
+     */
+    public void modifiedService(ServiceReference reference, Object service) { 
+        // A published service has been modified
+        List l = getRecordsByRef(reference);
+        for (int i = 0; i < l.size(); i++) { // Update the implied record
+            Record rec = (Record) l.get(i);
+            if (rec.m_reg != null) {
+                rec.m_reg.setProperties(getProps(reference));
             }
         }
     }
-
+    
     /**
-     * Manage the departure of a service.
-     * @param ref : the new service reference.
+     * An exported service disappears.
+     * @param reference : service reference
+     * @param service : service object
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#removedService(org.osgi.framework.ServiceReference, java.lang.Object)
      */
-    private void departureManagement(ServiceReference ref) {
-        List l = getRecordsByRef(ref);
+    public void removedService(ServiceReference reference, Object service) {
+        List l = getRecordsByRef(reference);
         for (int i = 0; i < l.size(); i++) { // Stop the implied record
             Record rec = (Record) l.get(i);
             if (rec.m_reg != null) {
                 rec.m_svcObject = null;
                 rec.m_reg.unregister();
                 rec.m_reg = null;
-                m_origin.ungetService(rec.m_ref);
+                m_tracker.ungetService(rec.m_ref);
             }
         }
         m_records.removeAll(l);
@@ -330,7 +291,7 @@
             if (!m_aggregate) { // Import the next one
                 Record rec = (Record) m_records.get(0);
                 if (rec.m_svcObject == null) { // It is the first service which disappears - create the next one
-                    rec.m_svcObject = m_origin.getService(rec.m_ref);
+                    rec.m_svcObject = m_tracker.getService(rec.m_ref);
                     rec.m_reg = m_destination.registerService(m_specification, rec.m_svcObject, getProps(rec.m_ref));
                 }
             }
@@ -340,14 +301,6 @@
                 m_handler.invalidating(this);
             }
         }
-    }
-
-    
-    protected String getSpecification() {
-        return m_specification;
-    }
-    
-    public String getFilter() {
-        return m_filterStr;
+        
     }
 }