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 2008/02/20 15:23:37 UTC

svn commit: r629469 [1/2] - in /felix/sandbox/clement/ipojo: composite/src/main/java/org/apache/felix/ipojo/composite/service/importer/ composite/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ composite/src/main/java/org/apache/fe...

Author: clement
Date: Wed Feb 20 06:23:33 2008
New Revision: 629469

URL: http://svn.apache.org/viewvc?rev=629469&view=rev
Log:
Add the abstract service dependency class implementing the iPOJO service dependency model.
Adapt concrete dependency to fit with this class.
Begin to commit the work on the context-awareness

Added:
    felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/ContextListener.java
    felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/ContextSource.java
    felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/util/AbstractServiceDependency.java
Modified:
    felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportDescription.java
    felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportHandler.java
    felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/importer/ServiceImporter.java
    felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorDescription.java
    felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorHandler.java
    felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/SvcInstance.java
    felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/CompositionMetadata.java
    felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandler.java
    felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/Extender.java
    felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoFactory.java
    felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java
    felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyCallback.java
    felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyDescription.java
    felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java
    felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/ManifestMetadataParser.java
    felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Tracker.java

Modified: felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportDescription.java
URL: http://svn.apache.org/viewvc/felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportDescription.java?rev=629469&r1=629468&r2=629469&view=diff
==============================================================================
--- felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportDescription.java (original)
+++ felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportDescription.java Wed Feb 20 06:23:33 2008
@@ -24,6 +24,7 @@
 import org.apache.felix.ipojo.composite.CompositeHandler;
 import org.apache.felix.ipojo.metadata.Attribute;
 import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.util.AbstractServiceDependency;
 
 /**
  * Description of the Import Export Handler.
@@ -57,11 +58,11 @@
         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()));
+            impo.addAttribute(new Attribute("Specification", imp.getSpecification().getName()));
             if (imp.getFilter() != null) {
                 impo.addAttribute(new Attribute("Filter", imp.getFilter()));
             }
-            if (imp.isSatisfied()) {
+            if (imp.getState() == AbstractServiceDependency.RESOLVED) {
                 impo.addAttribute(new Attribute("State", "resolved"));
                 for (int j = 0; j < imp.getProviders().size(); j++) {
                     Element pr = new Element("Provider", "");

Modified: felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportHandler.java
URL: http://svn.apache.org/viewvc/felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportHandler.java?rev=629469&r1=629468&r2=629469&view=diff
==============================================================================
--- felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportHandler.java (original)
+++ felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportHandler.java Wed Feb 20 06:23:33 2008
@@ -19,16 +19,20 @@
 package org.apache.felix.ipojo.composite.service.importer;
 
 import java.util.ArrayList;
+import java.util.Comparator;
 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.PolicyServiceContext;
-import org.apache.felix.ipojo.ServiceContext;
 import org.apache.felix.ipojo.architecture.HandlerDescription;
 import org.apache.felix.ipojo.composite.CompositeHandler;
 import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.util.AbstractServiceDependency;
 import org.osgi.framework.BundleContext;
+import org.osgi.framework.Filter;
+import org.osgi.framework.InvalidSyntaxException;
 
 /**
  * This handler manages the import and the export of services from /
@@ -39,25 +43,14 @@
 public class ImportHandler extends CompositeHandler {
 
     /**
-     * Service Scope.
-     */
-    private ServiceContext m_scope;
-
-    /**
-     * Parent context.
-     */
-    private BundleContext m_context;
-
-    /**
      * List of importers.
      */
     private List m_importers = new ArrayList();
-
-//    /**
-//     * Is the handler valid ?
-//     * (Lifecycle controller)
-//     */
-//    private boolean m_valid;
+    
+    /**
+     * Flag to check if the start method has finished.
+     */
+    private boolean m_isStarted;
     
 
     /**
@@ -70,8 +63,6 @@
      * 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[] imp = metadata.getElements("requires");
         
         // Get instance filters
@@ -92,7 +83,8 @@
                 String agg = imp[i].getAttribute("aggregate");
                 aggregate = agg != null && agg.equalsIgnoreCase("true");
 
-                String filter = "(&(objectClass=" + specification + ")(!(instance.name=" + getCompositeManager().getInstanceName() + ")))"; // Cannot import yourself
+                String filter_orig = "(&(objectClass=" + specification + ")(!(instance.name=" + getCompositeManager().getInstanceName() + ")))"; // Cannot import yourself
+                String filter = filter_orig;
                 String f = imp[i].getAttribute("filter");
                 if (f != null) {
                     filter = "(&" + filter + f + ")";
@@ -100,24 +92,37 @@
                 
                 String id = imp[i].getAttribute("id");
                 
-                int scopePolicy = -1;
                 String scope = imp[i].getAttribute("scope");
+                BundleContext bc = getCompositeManager().getGlobalContext(); // Get the default bundle context.
                 if (scope != null) {
                     if (scope.equalsIgnoreCase("global")) {
-                        scopePolicy = PolicyServiceContext.GLOBAL;
+                        bc = new PolicyServiceContext(getCompositeManager().getGlobalContext(), getCompositeManager().getParentServiceContext(), PolicyServiceContext.GLOBAL);
                     } else if (scope.equalsIgnoreCase("composite")) {
-                        scopePolicy = PolicyServiceContext.LOCAL;
+                        bc = new PolicyServiceContext(getCompositeManager().getGlobalContext(), getCompositeManager().getParentServiceContext(), PolicyServiceContext.LOCAL);
                     } else if (scope.equalsIgnoreCase("composite+global")) {
-                        scopePolicy = PolicyServiceContext.LOCAL_AND_GLOBAL;
-                    }                
+                        bc = new PolicyServiceContext(getCompositeManager().getGlobalContext(), getCompositeManager().getParentServiceContext(), PolicyServiceContext.LOCAL_AND_GLOBAL);
+                    }
                 }
                 
                 // Configure instance filter if available
                 if (filtersConfiguration != null && id != null && filtersConfiguration.get(id) != null) {
-                    filter = (String) filtersConfiguration.get(id);
+                    filter = "(&" + filter_orig + (String) filtersConfiguration.get(id) + ")";
+                }
+                
+                Filter fil = null;
+                if (filter != null) {
+                    try {
+                        fil = getCompositeManager().getGlobalContext().createFilter(filter);
+                    } catch (InvalidSyntaxException e) {
+                        throw new ConfigurationException("A required filter " + filter + " is malformed : " + e.getMessage());
+                    }
                 }
                 
-                ServiceImporter si = new ServiceImporter(specification, filter, aggregate, optional, m_context, m_scope, scopePolicy, id, this);
+                Comparator cmp = AbstractServiceDependency.getComparator(imp[i], getCompositeManager().getGlobalContext());
+                Class spec = AbstractServiceDependency.loadSpecification(specification, getCompositeManager().getGlobalContext());
+                int policy = AbstractServiceDependency.getPolicy(imp[i]);
+                
+                ServiceImporter si = new ServiceImporter(spec, fil, aggregate, optional, cmp, policy, bc, id, this);
                 m_importers.add(si);
             } else { // Malformed import
                 error( "Malformed imports : the specification attribute is mandatory");
@@ -137,6 +142,7 @@
             si.start();
         }
         isHandlerValid();
+        m_isStarted = true;
     }
 
     /**
@@ -149,6 +155,7 @@
             ServiceImporter si = (ServiceImporter) m_importers.get(i);
             si.stop();
         }
+        m_isStarted = false;
     }
 
     /**
@@ -159,12 +166,24 @@
     public void isHandlerValid() {
         for (int i = 0; i < m_importers.size(); i++) {
             ServiceImporter si = (ServiceImporter) m_importers.get(i);
-            if (!si.isSatisfied()) {
+            if (si.getState() != AbstractServiceDependency.RESOLVED) {
                 setValidity(false);
                 return;
             }
         }
         setValidity(true);
+    }
+    
+    public void stateChanged(int newState) {
+        // If we are becoming valid and started, check if we need to freeze importers.
+        if (m_isStarted && newState == ComponentInstance.VALID) { 
+            for (int i = 0; i < m_importers.size(); i++) {
+                ServiceImporter si = (ServiceImporter) m_importers.get(i);
+                if (si.isStatic()) {
+                    si.freeze();
+                }
+            }
+        }
     }
 
     /**

Modified: felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/importer/ServiceImporter.java
URL: http://svn.apache.org/viewvc/felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/importer/ServiceImporter.java?rev=629469&r1=629468&r2=629469&view=diff
==============================================================================
--- felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/importer/ServiceImporter.java (original)
+++ felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/importer/ServiceImporter.java Wed Feb 20 06:23:33 2008
@@ -19,17 +19,19 @@
 package org.apache.felix.ipojo.composite.service.importer;
 
 import java.util.ArrayList;
+import java.util.Comparator;
 import java.util.Dictionary;
 import java.util.List;
 import java.util.Properties;
 
 import org.apache.felix.ipojo.PolicyServiceContext;
-import org.apache.felix.ipojo.ServiceContext;
-import org.apache.felix.ipojo.util.Tracker;
-import org.apache.felix.ipojo.util.TrackerCustomizer;
+import org.apache.felix.ipojo.util.AbstractServiceDependency;
 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,64 +40,16 @@
  * 
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public class ServiceImporter implements TrackerCustomizer {
-
-    /**
-     * Destination context.
-     */
-    private ServiceContext m_destination;
-
-    /**
-     * Context where service need to be found. 
-     */
-    private ServiceContext m_origin;
-
-    /**
-     * Imported Specification.
-     */
-    private String m_specification;
-
-    /**
-     * LDAP filter filtering external providers.
-     */
-    private Filter m_filter;
-
-    /**
-     * String form of the LDAP filter.
-     */
-    private String m_filterStr;
-
-    /**
-     * Should we importer several providers?
-     */
-    private boolean m_aggregate = false;
-
-    /**
-     * Is the import optional?
-     */
-    private boolean m_optional = false;
-
-    /**
-     * Is the importer valid?
-     */
-    private boolean m_isValid;
-    
-    /**
-     * Resolving policy.
-     */
-    private int m_policy;
-    
-    /**
-     * TRacker tracking imported service.
-     */
-    private Tracker m_tracker;
+public class ServiceImporter extends AbstractServiceDependency {
 
     /**
      * Reference on the handler.
      */
     private ImportHandler m_handler;
+    
+    private BundleContext m_origin;
 
-    private class Record {
+    private class Record implements ServiceListener {
         /**
          * External Reference.
          */
@@ -109,6 +63,30 @@
          */
         private Object m_svcObject;
         
+        private Record(ServiceReference ref) {
+            m_ref = ref;
+            try {
+                m_origin.addServiceListener(this, "(" + Constants.SERVICE_ID + "=" + ref.getProperty(Constants.SERVICE_ID) + ")");
+            } catch (InvalidSyntaxException e) {
+                // Nothing to do.
+            }
+        }
+        
+        private void register() {
+            m_svcObject = getService(m_ref);
+            m_reg = m_handler.getCompositeManager().getServiceContext().registerService(getSpecification().getName(), m_svcObject, getProps(m_ref));
+        }
+        
+        private void dispose() {
+            m_origin.removeServiceListener(this);
+            if (m_reg != null) {
+                m_reg.unregister();
+                m_svcObject = null;
+                m_reg = null;
+            }
+            m_ref = null;
+        }
+        
         /**
          * Test object equality.
          * @param o : object to confront against the current object.
@@ -122,6 +100,14 @@
             }
             return false;
         }
+
+        public synchronized void serviceChanged(ServiceEvent evt) {
+            // In case of modification, modify the service imported service registration.
+            if (m_reg != null && evt.getType() == ServiceEvent.MODIFIED) {
+                      m_reg.setProperties(getProps(evt.getServiceReference()));
+              }
+            }
+            
     }
 
     /**
@@ -138,6 +124,8 @@
      * Is this requirement attached to a service-level requirement.
      */
     private boolean m_isServiceLevelRequirement;
+    
+    private boolean m_isFrozen;
 
     /**
      * Constructor.
@@ -152,41 +140,18 @@
      * @param id : requirement id (may be null)
      * @param in : handler
      */
-    public ServiceImporter(String specification, String filter, boolean multiple, boolean optional, BundleContext from, ServiceContext to, int policy, String id,
-            ImportHandler in) {
-        this.m_destination = to;
-        try {
-            this.m_filter = from.createFilter(filter);
-        } catch (InvalidSyntaxException e) {
-            e.printStackTrace();
-            return;
-        }
-        this.m_aggregate = multiple;
-        this.m_specification = specification;
-        this.m_optional = optional;
+    public ServiceImporter(Class specification, Filter filter, boolean multiple, boolean optional, Comparator cmp, int policy, BundleContext bc, String id, ImportHandler in) {
+        super(specification, multiple, optional, filter, cmp, policy, bc);
+        
+        m_origin = bc;
+        
         this.m_handler = in;
         
         if (m_id == null) {
-            m_id = m_specification;
+            m_id = super.getSpecification().getName();
         } else {
             m_id = id;
         }
-        
-        if (policy == -1) {
-            m_policy = PolicyServiceContext.LOCAL_AND_GLOBAL;  
-        } else {
-            m_policy = policy;
-        }
-    }
-
-    /**
-     * Start method to begin the import.
-     */
-    public void start() {
-        m_origin = new PolicyServiceContext(m_handler.getCompositeManager().getGlobalContext(), m_handler.getCompositeManager().getParentServiceContext(), m_policy);
-        m_tracker = new Tracker(m_origin, m_filter, this);
-        m_tracker.open();
-        m_isValid = isSatisfied();
     }
 
     /**
@@ -195,7 +160,7 @@
      * @param ref : the reference.
      * @return the property dictionary
      */
-    private Dictionary getProps(ServiceReference ref) {
+    private static Dictionary getProps(ServiceReference ref) {
         Properties prop = new Properties();
         String[] keys = ref.getPropertyKeys();
         for (int i = 0; i < keys.length; i++) {
@@ -203,38 +168,36 @@
         }
         return prop;
     }
+    
+    public boolean isStatic() {
+        return getBindingPolicy() == STATIC_BINDING_POLICY;
+    }
+    
+    public void freeze() {
+        m_isFrozen = true;
+    }
+    
+    public boolean isFrozen() {
+        return m_isFrozen;
+    }
 
     /**
      * Stop the management of the import.
      */
     public void stop() {
 
-        m_tracker.close();
+        super.stop();
 
         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_tracker.ungetService(rec.m_ref);
-                rec.m_ref = null;
-            }
+            rec.dispose();
         }
         
-        m_tracker = null;
         m_records.clear();
 
     }
 
     /**
-     * Check if the import is satisfied.
-     * @return true if the import is optional or at least one provider is imported
-     */
-    public boolean isSatisfied() {
-        return m_optional || m_records.size() > 0;
-    }
-
-    /**
      * Get the record list using the given reference.
      * 
      * @param ref : the reference
@@ -251,10 +214,6 @@
         return l;
     }
 
-    public String getSpecification() {
-        return m_specification;
-    }
-
     /**
      * Build the list of imported service provider.
      * @return the list of all imported services.
@@ -265,11 +224,6 @@
             l.add((((Record) m_records.get(i)).m_ref).getProperty("instance.name"));
         }
         return l;
-
-    }
-
-    public String getFilter() {
-        return m_filterStr;
     }
     
     /**
@@ -279,7 +233,8 @@
      */
     public void setServiceLevelDependency() {
         m_isServiceLevelRequirement = true;
-        m_policy = PolicyServiceContext.LOCAL;
+        PolicyServiceContext bc = new PolicyServiceContext(m_handler.getCompositeManager().getGlobalContext(), m_handler.getCompositeManager().getParentServiceContext(), PolicyServiceContext.LOCAL);
+        setBundleContext(bc);
     }
 
     public String getId() {
@@ -289,104 +244,34 @@
     public boolean isServiceLevelRequirement() {
         return m_isServiceLevelRequirement;
     }
-    
-    public boolean isAggregate() {
-        return m_aggregate;
-    }
-    
-    public boolean isOptional() {
-        return m_optional;
-    }
 
-    /**
-     * A new service 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) {
-        for (int i = 0; i < m_records.size(); i++) {
-            Record rec = (Record) m_records.get(i);
-            if (rec.m_ref == reference) {
-                return false; // Already contained
-            }
-        }
-        return true;
+    public void invalidate() {
+        m_handler.invalidating(this);
     }
-    
-    /**
-     * The given service reference was added inside the tracker list.
-     * Register the internal service.
-     * @param reference : added reference
-     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addedService(org.osgi.framework.ServiceReference)
-     */
-    public void addedService(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);
-        }
+
+    public void onDependencyReconfiguration(ServiceReference[] departs, ServiceReference[] arrivals) {
+        throw new UnsupportedOperationException("Service import does not support dependency reconfiguration");
     }
 
-    /**
-     * An imported service was modified.
-     * @param reference : service reference
-     * @param service : service object (if already get)
-     * @see org.apache.felix.ipojo.util.TrackerCustomizer#modifiedService(org.osgi.framework.ServiceReference, java.lang.Object)
-     */
-    public void modifiedService(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_reg.setProperties(getProps(rec.m_ref));
-            }
-        }
+    public void onServiceArrival(ServiceReference ref) {
+        Record rec = new Record(ref);
+        m_records.add(rec);
+        // Always register the reference, as the method is call only when needed. 
+        rec.register();
     }
 
-    /**
-     * An imported service disappears.
-     *@param reference : service reference
-     * @param service : service object (if already get)
-     * @see org.apache.felix.ipojo.util.TrackerCustomizer#removedService(org.osgi.framework.ServiceReference, java.lang.Object)
-     */
-    public void removedService(ServiceReference reference, Object service) {
-        List l = getRecordsByRef(reference);
+    public void onServiceDeparture(ServiceReference ref) {
+        List l = getRecordsByRef(ref);
         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_tracker.ungetService(rec.m_ref);
-            }
+            rec.dispose();
+            
         }
         m_records.removeAll(l);
+    }
 
-        // Check the validity & if we need to re-import the service
-        if (m_records.size() > 0) {
-            // There is other available services
-            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_tracker.getService(rec.m_ref);
-                    rec.m_reg = m_destination.registerService(m_specification, rec.m_svcObject, getProps(rec.m_ref));
-                }
-            }
-        } else {
-            if (!m_optional) {
-                m_isValid = false;
-                m_handler.invalidating(this);
-            }
-        }
+    public void validate() {
+        m_handler.validating(this);
     }
 
 }

Modified: felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorDescription.java
URL: http://svn.apache.org/viewvc/felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorDescription.java?rev=629469&r1=629468&r2=629469&view=diff
==============================================================================
--- felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorDescription.java (original)
+++ felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorDescription.java Wed Feb 20 06:23:33 2008
@@ -28,6 +28,7 @@
 import org.apache.felix.ipojo.composite.CompositeHandler;
 import org.apache.felix.ipojo.metadata.Attribute;
 import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.util.AbstractServiceDependency;
 import org.osgi.framework.ServiceReference;
 
 /**
@@ -63,13 +64,13 @@
         for (int i = 0; i < m_instances.size(); i++) {
             SvcInstance inst = (SvcInstance) m_instances.get(i);
             Element service = new Element("Service", "");
-            service.addAttribute(new Attribute("Specification", inst.getSpecification()));
+            service.addAttribute(new Attribute("Specification", inst.getServiceSpecification()));
             String state = "unresolved";
-            if (inst.isSatisfied()) {
+            if (inst.getState() == AbstractServiceDependency.RESOLVED) {
                 state = "resolved";
             }
             service.addAttribute(new Attribute("State", state));
-            Map map = inst.getUsedReferences();
+            Map map = inst.getMatchingFactories();
             Set keys = map.keySet();
             Iterator it = keys.iterator();
             while (it.hasNext()) {

Modified: felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorHandler.java
URL: http://svn.apache.org/viewvc/felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorHandler.java?rev=629469&r1=629468&r2=629469&view=diff
==============================================================================
--- felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorHandler.java (original)
+++ felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorHandler.java Wed Feb 20 06:23:33 2008
@@ -19,14 +19,19 @@
 package org.apache.felix.ipojo.composite.service.instantiator;
 
 import java.util.ArrayList;
+import java.util.Comparator;
 import java.util.Dictionary;
 import java.util.List;
 import java.util.Properties;
 
+import org.apache.felix.ipojo.ComponentInstance;
 import org.apache.felix.ipojo.ConfigurationException;
 import org.apache.felix.ipojo.architecture.HandlerDescription;
 import org.apache.felix.ipojo.composite.CompositeHandler;
 import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.util.AbstractServiceDependency;
+import org.osgi.framework.Filter;
+import org.osgi.framework.InvalidSyntaxException;
 
 /**
  * Service Instantiator Class. This handler allows to instantiate service
@@ -40,6 +45,8 @@
      * List of instances to manage.
      */
     private List/* <SvcInstance> */m_instances = new ArrayList();
+    
+    private boolean m_isStarted;
 
     /**
      * Configure the handler.
@@ -62,6 +69,14 @@
             if (f != null) {
                 filter = "(&" + filter + f + ")";
             }
+            
+            Filter fil;
+            try {
+                fil = getCompositeManager().getGlobalContext().createFilter(filter);
+            } catch (InvalidSyntaxException e) {
+                throw new ConfigurationException("Malformed filter " + filter + " : " + e.getMessage());
+            }
+            
             Properties prop = new Properties();
             Element[] props = services[i].getElements("property");
             for (int k = 0; props != null && k < props.length; k++) {
@@ -75,7 +90,13 @@
             String op = services[i].getAttribute("optional");
             boolean opt = op != null && op.equalsIgnoreCase("true");
             
-            SvcInstance inst = new SvcInstance(this, spec, prop, agg, opt, filter);
+            int policy = AbstractServiceDependency.getPolicy(services[i]);
+            
+            Comparator cmp = AbstractServiceDependency.getComparator(services[i], getCompositeManager().getGlobalContext());
+            
+            //String source = services[i].getAttribute("context-source");
+            
+            SvcInstance inst = new SvcInstance(this, spec, prop, agg, opt, fil, cmp, policy);
             m_instances.add(inst);
         }
     }
@@ -93,6 +114,7 @@
         }
 
         isHandlerValid();
+        m_isStarted = true;
     }
 
     /**
@@ -103,7 +125,7 @@
     private void isHandlerValid() {
         for (int i = 0; i < m_instances.size(); i++) {
             SvcInstance inst = (SvcInstance) m_instances.get(i);
-            if (!inst.isSatisfied()) {
+            if (inst.getState() != AbstractServiceDependency.RESOLVED) {
                 setValidity(false);
                 return;
             }
@@ -122,6 +144,19 @@
             inst.stop();
         }
         m_instances.clear();
+        m_isStarted = false;
+    }
+    
+    public void stateChanged(int newState) {
+        // If we are becoming valid and started, check if we need to freeze importers.
+        if (m_isStarted && newState == ComponentInstance.VALID) { 
+            for (int i = 0; i < m_instances.size(); i++) {
+                SvcInstance si = (SvcInstance) m_instances.get(i);
+                if (si.getBindingPolicy() == AbstractServiceDependency.STATIC_BINDING_POLICY) {
+                    si.freeze();
+                }
+            }
+        }
     }
 
     /**

Modified: felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/SvcInstance.java
URL: http://svn.apache.org/viewvc/felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/SvcInstance.java?rev=629469&r1=629468&r2=629469&view=diff
==============================================================================
--- felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/SvcInstance.java (original)
+++ felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/SvcInstance.java Wed Feb 20 06:23:33 2008
@@ -18,6 +18,7 @@
  */
 package org.apache.felix.ipojo.composite.service.instantiator;
 
+import java.util.Comparator;
 import java.util.Dictionary;
 import java.util.Enumeration;
 import java.util.HashMap;
@@ -30,12 +31,10 @@
 import org.apache.felix.ipojo.ConfigurationException;
 import org.apache.felix.ipojo.Factory;
 import org.apache.felix.ipojo.MissingHandlerException;
-import org.apache.felix.ipojo.ServiceContext;
 import org.apache.felix.ipojo.UnacceptableConfiguration;
-import org.apache.felix.ipojo.metadata.Element;
-import org.apache.felix.ipojo.util.Tracker;
-import org.apache.felix.ipojo.util.TrackerCustomizer;
-import org.osgi.framework.InvalidSyntaxException;
+import org.apache.felix.ipojo.architecture.ComponentTypeDescription;
+import org.apache.felix.ipojo.util.AbstractServiceDependency;
+import org.osgi.framework.Filter;
 import org.osgi.framework.ServiceReference;
 
 /**
@@ -44,12 +43,7 @@
  * 
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public class SvcInstance implements TrackerCustomizer {
-
-    /**
-     * Required specification.
-     */
-    private String m_specification;
+public class SvcInstance extends AbstractServiceDependency {
 
     /**
      * Configuration to push to the instance.
@@ -57,39 +51,18 @@
     private Dictionary m_configuration;
 
     /**
-     * Map of factory references => instance or NO_INSTANCE.
-     */
-    private Map /* ServiceReference */m_usedRef = new HashMap();
-
-    /**
-     * Does we instantiate several provider ?
-     */
-    private boolean m_isAggregate = false;
-
-    /**
-     * Is the service optional ?
-     */
-    private boolean m_isOptional = false;
-
-    /**
      * Handler creating the service instance.
      */
     private ServiceInstantiatorHandler m_handler;
-
-    /**
-     * Service Context (internal scope).
-     */
-    private ServiceContext m_context;
-
-    /**
-     * True if the service instantiation is valid.
-     */
-    private boolean m_isValid = false;
-
+    
     /**
-     * Tracker used to track required factory.
+     * Map of matching factories  Service Reference => instance or null (null if the service reference is not actually used).
      */
-    private Tracker m_tracker;
+    private Map /*<ServiceReference, Instance>*/m_matchingFactories = new HashMap();
+    
+    private String m_specification;
+    
+    private boolean m_isFrozen;
 
     /**
      * Constructor.
@@ -99,63 +72,48 @@
      * @param isAgg : is the service instance an aggregate service ?
      * @param isOpt : is the service instance optional ?
      * @param filt : LDAP filter
+     * @throws ConfigurationException : an attribute cannot be parsed correctly, or is incorrect.
      */
-    public SvcInstance(ServiceInstantiatorHandler h, String spec, Dictionary conf, boolean isAgg, boolean isOpt, String filt) {
-        m_handler = h;
-        m_context = h.getCompositeManager().getServiceContext();
+    public SvcInstance(ServiceInstantiatorHandler h, String spec, Dictionary conf, boolean isAgg, boolean isOpt, Filter filt, Comparator cmp, int policy) throws ConfigurationException {
+        super(Factory.class, isAgg, isOpt, filt, cmp, policy, null);
+        
         m_specification = spec;
+        
+        m_handler = h;
+        setBundleContext(m_handler.getCompositeManager().getServiceContext());
+        
         m_configuration = conf;
-        m_isAggregate = isAgg;
-        m_isOptional = isOpt;
-        try {
-            m_tracker  = new Tracker(m_context, h.getCompositeManager().getContext().createFilter(filt), this);
-        } catch (InvalidSyntaxException e) {
-            e.printStackTrace();
-        }
-    }
 
-    /**
-     * Start the service instance.
-     * @param sc
-     */
-    public void start() {
-        m_tracker.open();
-        m_isValid = isSatisfied();
+
+        //TODO managing several sources
     }
 
     /**
      * Stop the service instance.
      */
     public void stop() {
-        m_tracker.close();
-        
-        Set keys = m_usedRef.keySet();
+        super.stop();
+
+        Set keys = m_matchingFactories.keySet();
         Iterator it = keys.iterator();
         while (it.hasNext()) {
             ServiceReference ref = (ServiceReference) it.next();
-            Object o = m_usedRef.get(ref);
+            Object o = m_matchingFactories.get(ref);
             if (o != null) {
                 ((ComponentInstance) o).dispose();
             }
         }
-        m_usedRef.clear();
-        m_tracker = null;
-        m_isValid = false;
-    }
+        
+        m_matchingFactories.clear();
 
-    /**
-     * Check if an instance is already created.
-     * @return true if at least one instance is created.
-     */
-    private boolean isAnInstanceCreated() {
-        Set keys = m_usedRef.keySet();
-        Iterator it = keys.iterator();
-        while (it.hasNext()) {
-            if (m_usedRef.get(it.next()) != null)  {
-                return true;
-            }
-        }
-        return false;
+    }
+    
+    public boolean isFrozen() {
+        return m_isFrozen;
+    }
+    
+    public void freeze() {
+        m_isFrozen = true;
     }
 
     /**
@@ -163,8 +121,11 @@
      * The instance is not added inside the map.
      * @param factory : the factory from which we need to create the instance.
      * @return the created component instance.
+     * @throws ConfigurationException : the instance cannot be configured correctly.
+     * @throws MissingHandlerException  : the factory is invalid.
+     * @throws UnacceptableConfiguration : the given configuration is invalid for the given factory.
      */
-    private ComponentInstance createInstance(Factory factory) {
+    private ComponentInstance createInstance(Factory factory) throws UnacceptableConfiguration, MissingHandlerException, ConfigurationException {
         // Add an unique name if not specified.
         Properties p = new Properties();
         Enumeration kk = m_configuration.keys();
@@ -173,90 +134,43 @@
             p.put(k, m_configuration.get(k));
         }
         ComponentInstance instance = null;
-        try {
-            instance = factory.createComponentInstance(p);
-        } catch (UnacceptableConfiguration e) {
-            e.printStackTrace();
-        } catch (MissingHandlerException e) {
-            e.printStackTrace();
-        } catch (ConfigurationException e) {
-            e.printStackTrace();
-        }
+        instance = factory.createComponentInstance(p);
         return instance;
     }
 
     /**
-     * Create an instance for the next available factory.
-     */
-    private void createNextInstance() {
-        Set keys = m_usedRef.keySet();
-        Iterator it = keys.iterator();
-        ServiceReference ref = (ServiceReference) it.next();
-        try {
-            Factory factory = (Factory) m_context.getService(ref);
-
-            // Add an unique name if not specified.
-            Properties p = new Properties();
-            Enumeration kk = m_configuration.keys();
-            while (kk.hasMoreElements()) {
-                String k = (String) kk.nextElement();
-                p.put(k, m_configuration.get(k));
-            }
-            
-            ComponentInstance instance = factory.createComponentInstance(p);
-            m_usedRef.put(ref, instance);
-            m_context.ungetService(ref);
-        } catch (UnacceptableConfiguration e) {
-            m_handler.error( "A matching factory (" + ref.getProperty("instance.name") + ") seems to refuse the given configuration : " + e.getMessage());
-        } catch (MissingHandlerException e) {
-            m_handler.error( "A matching factory (" + ref.getProperty("instance.name") + ") seems to refuse the given configuration : " + e.getMessage());
-        } catch (ConfigurationException e) {
-            m_handler.error( "A matching factory (" + ref.getProperty("instance.name") + ") seems to refuse the given configuration : " + e.getMessage());
-        }
-    }
-
-
-
-    /**
-     * Check if the service instance is satisfied.
-     * @return true if the service instance if satisfied.
-     */
-    public boolean isSatisfied() {
-        return m_isOptional || m_usedRef.size() > 0;
-    }
-
-    /**
      * Does the service instance match with the given factory ?
      * @param fact : the factory to test.
      * @return true if the factory match, false otherwise.
      */
-    private boolean match(Factory fact) {
-        //TODO : use the service reference instead of the factory object to avoid to get the factory.
+    public boolean match(ServiceReference fact) {
         // Check if the factory can provide the specification
-        Element[] provides = fact.getDescription().getElements("provides");
+        ComponentTypeDescription desc = (ComponentTypeDescription) fact.getProperty("component.description");
+        if (desc == null) { 
+            return false; // No component type description. 
+        } 
+       
+        String[] provides = desc.getprovidedServiceSpecification();
         for (int i = 0; provides != null && i < provides.length; i++) {
-            if (provides[i].getAttribute("specification").equals(m_specification)) {
-
+            if (provides[i].equals(m_specification)) {
                 // Check that the factory needs every properties contained in
                 // the configuration
+                org.apache.felix.ipojo.architecture.PropertyDescription[] props = desc.getProperties();
                 Enumeration e = m_configuration.keys();
                 while (e.hasMoreElements()) {
                     String k = (String) e.nextElement();
-                    if (!containsProperty(k, fact)) {
-                        return false;
-                    }
+                    if (!containsProperty(k, props)) { return false; }
                 }
 
-                // Add an unique name if not specified.
                 Properties p = new Properties();
                 Enumeration keys = m_configuration.keys();
                 while (keys.hasMoreElements()) {
                     String k = (String) keys.nextElement();
                     p.put(k, m_configuration.get(k));
                 }
-
-                // Check the acceptability.
-                return fact.isAcceptable(p);
+                
+                Factory factory = (Factory) getService(fact);
+                return factory.isAcceptable(p);
             }
         }
         return false;
@@ -269,16 +183,11 @@
      * @param factory : factory to test
      * @return true if the factory support this property
      */
-    private boolean containsProperty(String name, Factory factory) {
-        Element[] props = factory.getDescription().getElements("property");
+    private boolean containsProperty(String name, org.apache.felix.ipojo.architecture.PropertyDescription[] props) {
         for (int i = 0; props != null && i < props.length; i++) {
-            if (props[i].getAttribute("name").equalsIgnoreCase(name)) {
-                return true;
-            }
+            if (props[i].getName().equalsIgnoreCase(name)) { return true; }
         }
-        if (name.equalsIgnoreCase("name")) {
-            return true;
-        } // Skip the name property
+        if (name.equalsIgnoreCase("name")) { return true; } // Skip the name property
         return false;
     }
 
@@ -286,101 +195,58 @@
      * Get the required specification.
      * @return the required specification.
      */
-    public String getSpecification() {
+    public String getServiceSpecification() {
         return m_specification;
     }
     
-    public boolean isAggregate() {
-        return m_isAggregate;
-    }
-    
-    public boolean isOptional() {
-        return m_isOptional;
-    }
-
     /**
      * Get the map of used references [reference, component instance].
      * @return the map of used references.
      */
-    protected Map getUsedReferences() {
-        return m_usedRef;
+    protected Map getMatchingFactories() {
+        return m_matchingFactories;
     }
 
-    /**
-     * A factory potentially matching with the managed instance appears.
-     * @param reference : service reference
-     * @return : true if the factory match
-     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addingService(org.osgi.framework.ServiceReference)
-     */
-    public boolean addingService(ServiceReference reference) {
-        Factory fact = (Factory) m_tracker.getService(reference);
-        if (match(fact)) {
-            m_tracker.ungetService(reference);
-            return true;
-        } else {
-            m_tracker.ungetService(reference);
-            return false;
-        }
+    public void invalidate() {
+        m_handler.invalidate();
         
     }
-    
-    /**
-     * A matching service reference has been added in the tracker. 
-     * @param reference : added reference.
-     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addedService(org.osgi.framework.ServiceReference)
-     */
-    public void addedService(ServiceReference reference) {
-        Factory fact = (Factory) m_tracker.getService(reference);
-        if (m_isAggregate) { // Create an instance for the new factory
-            m_usedRef.put(reference, createInstance(fact));
-            if (!m_isValid) {
-                m_isValid = true;
-                m_handler.validate();
-            }
-        } else {
-            if (!isAnInstanceCreated()) {
-                m_usedRef.put(reference, createInstance(fact));
-            } else {
-                m_usedRef.put(reference, null); // Store the reference
-            }
-            if (!m_isValid) {
-                m_isValid = true;
-                m_handler.validate();
-            }
-        }
-        m_tracker.ungetService(reference);
+
+    public void onDependencyReconfiguration(ServiceReference[] departs, ServiceReference[] arrivals) {
+        // TODO Auto-generated method stub
+        
     }
 
-    /**
-     * A used factory was modified.
-     * @param reference : service reference
-     * @param service : object if already get
-     * @see org.apache.felix.ipojo.util.TrackerCustomizer#modifiedService(org.osgi.framework.ServiceReference, java.lang.Object)
-     */
-    public void modifiedService(ServiceReference reference, Object service) { } 
+    public void onServiceArrival(ServiceReference ref) {
+        // The given factory matches.
+        try {
+        Factory fact = (Factory) getService(ref);
+        ComponentInstance ci = createInstance(fact);
+        m_matchingFactories.put(ref, ci);
+        } catch (UnacceptableConfiguration e) {
+            m_handler.error("A matching factory refuse the actual configuration : " + e.getMessage());
+            m_handler.getCompositeManager().stop();
+        } catch (MissingHandlerException e) {
+            m_handler.error("A matching factory is no more valid : " + e.getMessage());
+            m_handler.getCompositeManager().stop();
+        } catch (ConfigurationException e) {
+            m_handler.error("A matching configuration is refuse by the instance : " + e.getMessage());
+            m_handler.getCompositeManager().stop();
+        }
         
-    /**
-     * A used factory disappears.
-     * @param reference : service reference
-     * @param service : object if already get
-     * @see org.apache.felix.ipojo.util.TrackerCustomizer#removedService(org.osgi.framework.ServiceReference, java.lang.Object)
-     */
-    public void removedService(ServiceReference reference, Object service) {
-     // Remove the reference is contained
-        Object o = m_usedRef.remove(reference);
+    }
+
+    public void onServiceDeparture(ServiceReference ref) {
+        // Remove the reference is contained
+        Object o = m_matchingFactories.remove(ref);
         if (o != null) {
             ((ComponentInstance) o).dispose();
-            if (m_usedRef.size() > 0) {
-                if (!m_isAggregate) {
-                    createNextInstance(); // Create an instance with another factory
-                }
-            } else { // No more candidate
-                if (!m_isOptional) {
-                    m_isValid = false;
-                    m_handler.invalidate();
-                }
-            }
         }
+    }
+
+    public void validate() {
+        m_handler.validate();
+        
     }
 
 }

Modified: felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/CompositionMetadata.java
URL: http://svn.apache.org/viewvc/felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/CompositionMetadata.java?rev=629469&r1=629468&r2=629469&view=diff
==============================================================================
--- felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/CompositionMetadata.java (original)
+++ felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/CompositionMetadata.java Wed Feb 20 06:23:33 2008
@@ -129,7 +129,7 @@
                     m_handler.error( "The factory " + type + " is not available, cannot check the composition");
                     throw new CompositionException("The factory " + type + " needs to be available to check the composition");
                 } else {
-                    String className = (String) refs[0].getProperty("component.class"); //TODO !!!!
+                    String className = (String) refs[0].getProperty("component.class");
                     Class impl = m_context.getBundle().loadClass(className);
                     SpecificationMetadata spec = new SpecificationMetadata(impl, type, m_handler);
                     FieldMetadata field = new FieldMetadata(spec);
@@ -233,8 +233,8 @@
         try {
             clazz = getBundleContext().getBundle().loadClass(m_specification.getName());
         } catch (ClassNotFoundException e1) {
-            //TODO
-            e1.printStackTrace();
+            // The class has already be loaded.
+            return null;
         }
         byte[] pojo = POJOWriter.dump(clazz, m_name, getFieldList(), getMethodList());
         Manipulator m = new Manipulator();

Modified: felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandler.java
URL: http://svn.apache.org/viewvc/felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandler.java?rev=629469&r1=629468&r2=629469&view=diff
==============================================================================
--- felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandler.java (original)
+++ felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandler.java Wed Feb 20 06:23:33 2008
@@ -41,7 +41,10 @@
 import org.apache.felix.ipojo.metadata.Element;
 import org.apache.felix.ipojo.parser.ManifestMetadataParser;
 import org.apache.felix.ipojo.parser.ParseException;
+import org.apache.felix.ipojo.util.AbstractServiceDependency;
 import org.osgi.framework.BundleContext;
+import org.osgi.framework.Filter;
+import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServiceReference;
 
 /**
@@ -186,7 +189,7 @@
 
         for (int i = 0; sh != null && i < sh.getInstances().size(); i++) {
             SvcInstance svc = (SvcInstance) sh.getInstances().get(i);
-            String itf = svc.getSpecification();
+            String itf = svc.getServiceSpecification();
             boolean agg = svc.isAggregate();
             boolean opt = svc.isOptional();
 
@@ -196,7 +199,7 @@
 
         for (int i = 0; ih != null && i < ih.getRequirements().size(); i++) {
             ServiceImporter si = (ServiceImporter) ih.getRequirements().get(i);
-            String itf = si.getSpecification();
+            String itf = si.getSpecification().getName();
             boolean agg = si.isAggregate();
             boolean opt = si.isOptional();
 
@@ -269,7 +272,7 @@
         String requirement = element.getAttribute("specification");
         for (int i = 0; i < ih.getRequirements().size(); i++) {
             ServiceImporter imp = (ServiceImporter) ih.getRequirements().get(i);
-            if (imp.getSpecification().equals(requirement)) { return imp; }
+            if (imp.getId().equals(requirement) || imp.getSpecification().getName().equals(requirement)) { return imp; }
         }
         return null;
     }
@@ -310,6 +313,7 @@
                 ih = (ImportHandler) ci.getHandler();
                 getCompositeManager().addCompositeHandler(ci);
             }
+            
             String spec = elem.getAttribute("specification");
             String filter = "(&(objectClass=" + spec + ")(!(instance.name=" + getCompositeManager().getInstanceName() + ")))"; // Cannot import yourself
             String f = elem.getAttribute("filter");
@@ -317,7 +321,24 @@
                 filter = "(&" + filter + f + ")";
             }
             
-            ServiceImporter si = new ServiceImporter(spec, filter, agg, opt, getCompositeManager().getContext(), getCompositeManager().getServiceContext(), PolicyServiceContext.LOCAL, null, ih);
+            BundleContext  bc = new PolicyServiceContext(getCompositeManager().getGlobalContext(), getCompositeManager().getParentServiceContext(), PolicyServiceContext.GLOBAL);
+            
+            Filter fil = null;
+            try {
+                fil = getCompositeManager().getGlobalContext().createFilter(filter);
+            } catch (InvalidSyntaxException e) {
+                throw new CompositionException("A required filter " + filter + " is malformed : " + e.getMessage());
+            }
+            
+            Class specToImport = null;
+            try {
+                specToImport = getCompositeManager().getGlobalContext().getBundle().loadClass(spec);
+            } catch (ClassNotFoundException e) {
+                throw new CompositionException("A required specification cannot be loaded : " + spec);
+            }
+            
+            ServiceImporter si = new ServiceImporter(specToImport, fil, agg, opt, null, AbstractServiceDependency.DYNAMIC_BINDING_POLICY, bc, null, ih);
+            
             ih.getRequirements().add(si);
             SpecificationMetadata sm = new SpecificationMetadata(spec, m_context, agg, opt, this);
             m_services.add(sm); // Update the available types

Added: felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/ContextListener.java
URL: http://svn.apache.org/viewvc/felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/ContextListener.java?rev=629469&view=auto
==============================================================================
--- felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/ContextListener.java (added)
+++ felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/ContextListener.java Wed Feb 20 06:23:33 2008
@@ -0,0 +1,36 @@
+/* 
+ * 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;
+
+
+/**
+ * Context Source Listener.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public interface ContextListener {
+    
+    /**
+     * A monitored value has been modified.
+     * @param source : context source containing the property
+     * @param property : modified property name
+     * @param value : new value of the property
+     */
+    void update(ContextSource source, String property, Object value);
+
+}

Added: felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/ContextSource.java
URL: http://svn.apache.org/viewvc/felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/ContextSource.java?rev=629469&view=auto
==============================================================================
--- felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/ContextSource.java (added)
+++ felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/ContextSource.java Wed Feb 20 06:23:33 2008
@@ -0,0 +1,57 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.ipojo;
+
+import java.util.Dictionary;
+
+
+/**
+ * Context Source service interface.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public interface ContextSource {
+    
+    /**
+     * Get the current value of the given property.
+     * @param property : property name
+     * @return the property value, null if unknown
+     */
+    Object getProperty(String property);
+    
+    /**
+     * Get the whole context.
+     * @return the dictionary [Property, Value]
+     */
+    Dictionary getContext();
+    
+    /**
+     * Register a context listener on the given set of properties.
+     * The listener will be notified of every change made on these properties.
+     * @param listener : the context listener to register.
+     * @param properties : property set monitored by the listener.
+     */
+    void registerContextListener(ContextListener listener, String[] properties);
+    
+    /**
+     * Unregister the given context listener.
+     * @param listener : the listener to unregister.
+     */
+    void unregisterContextListener(ContextListener listener);
+
+}

Modified: felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/Extender.java
URL: http://svn.apache.org/viewvc/felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/Extender.java?rev=629469&r1=629468&r2=629469&view=diff
==============================================================================
--- felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/Extender.java (original)
+++ felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/Extender.java Wed Feb 20 06:23:33 2008
@@ -146,7 +146,7 @@
 
         for (int i = 0; i < toRemove.size(); i++) {
             ManagedAbstractFactoryType mft = (ManagedAbstractFactoryType) toRemove.get(i);
-            System.out.println("[iPOJO-Core] The factory type available: " + mft.m_type + " is no more available");
+            System.err.println("[iPOJO-Core] The factory type available: " + mft.m_type + " is no more available");
             mft.m_bundle = null;
             mft.m_clazz = null;
             mft.m_createdFactories = null;
@@ -199,7 +199,7 @@
             }
             ManagedAbstractFactoryType mft = new ManagedAbstractFactoryType(clazz, type, bundle);
             m_abstractFactoryTypes.add(mft);
-            System.out.println("[iPOJO-Core] New factory type available: " + type);
+            System.err.println("[iPOJO-Core] New factory type available: " + type);
 
             for (int j = m_unboundTypes.size() - 1; j >= 0; j--) {
                 UnboundComponentType unbound = (UnboundComponentType) m_unboundTypes.get(j);

Modified: felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoFactory.java
URL: http://svn.apache.org/viewvc/felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoFactory.java?rev=629469&r1=629468&r2=629469&view=diff
==============================================================================
--- felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoFactory.java (original)
+++ felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoFactory.java Wed Feb 20 06:23:33 2008
@@ -768,7 +768,7 @@
          */
         public void unRef() {
             if (m_reference != null) {
-                m_context.ungetService(m_reference);
+                //m_context.ungetService(m_reference); // Will be unget automatically
                 m_factory = null;
                 m_reference = null;
             }

Modified: felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java
URL: http://svn.apache.org/viewvc/felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java?rev=629469&r1=629468&r2=629469&view=diff
==============================================================================
--- felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java (original)
+++ felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java Wed Feb 20 06:23:33 2008
@@ -21,59 +21,24 @@
 import java.lang.reflect.Array;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Proxy;
-import java.util.ArrayList;
-import java.util.Collections;
+import java.util.Arrays;
+import java.util.Comparator;
 import java.util.List;
 
 import org.apache.felix.ipojo.ComponentInstance;
-import org.apache.felix.ipojo.IPojoContext;
 import org.apache.felix.ipojo.InstanceManager;
 import org.apache.felix.ipojo.Nullable;
 import org.apache.felix.ipojo.PolicyServiceContext;
-import org.apache.felix.ipojo.ServiceContext;
-import org.apache.felix.ipojo.util.ServiceReferenceRankingComparator;
-import org.apache.felix.ipojo.util.Tracker;
-import org.apache.felix.ipojo.util.TrackerCustomizer;
+import org.apache.felix.ipojo.util.AbstractServiceDependency;
+import org.osgi.framework.BundleContext;
 import org.osgi.framework.Filter;
-import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServiceReference;
 
 /**
  * Represent a service dependency of the component instance.
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public class Dependency implements TrackerCustomizer {
-
-    /**
-     * Dependency State : RESOLVED.
-     */
-    public static final int RESOLVED = 1;
-
-    /**
-     * Dependency State : UNRESOLVED.
-     */
-    public static final int UNRESOLVED = 2;
-    
-    /**
-     * Dependency State : BROKEN.
-     * Broken means that a used service disappears for static dependency.
-     */
-    public static final int BROKEN = 3;
-    
-    /**
-     * Dynamic Binding Policy (default).
-     */
-    public static final int DYNAMIC_POLICY = 0;
-
-    /**
-     * Dynamic Priority Binding Policy.
-     */
-    public static final int DYNAMIC_PRIORITY_POLICY = 1;
-    
-    /**
-     * Static Binding Policy.
-     */
-    public static final int STATIC_POLICY = 2;
+public class Dependency extends AbstractServiceDependency {
 
     /**
      * Reference on the Dependency Handler.
@@ -91,104 +56,41 @@
     private DependencyCallback[] m_callbacks = new DependencyCallback[0];
 
     /**
-     * Service Specification required by the dependency.
-     */
-    private String m_specification;
-    
-    /**
-     * Dependency ID (declared ID, if not declare use the specification).
-     */
-    private String m_id;
-
-    /**
-     * Is the dependency a multiple dependency ?
-     */
-    private boolean m_isAggregate = false;
-
-    /**
-     * Is the Dependency an optional dependency ?
-     */
-    private boolean m_isOptional = false;
-
-    /**
-     * LDAP Filter of the Dependency (String form).
-     */
-    private String m_strFilter;
-    
-    /**
      * Is the dependency a service level dependency.
      */
     private boolean m_isServiceLevelRequirement = false;
-    
-    /**
-     * Resolution policy.
-     */
-    private int m_policy = PolicyServiceContext.LOCAL_AND_GLOBAL; 
 
     /**
-     * Array of service references.
-     * m_ref : Array
+     * Is the provider set frozen ?
      */
-    private List m_references = new ArrayList();
+    private boolean m_isFrozen = false;
     
     /**
-     * Array of service reference containing used service references. 
+     * Is the dependency started ?
      */
-    private List m_usedReferences = new ArrayList();
+    private boolean m_isStarted;
 
     /**
-     * State of the dependency. 0 : stopped, 1 : valid, 2 : invalid. 
-     * m_state : int
-     */
-    private int m_state;
-
-    /**
-     * Class of the dependency. 
-     * Useful to create in the case of multiple dependency
-     */
-    private Class m_clazz;
-
-    /**
-     * LDAP Filter of the dependency.
-     */
-    private Filter m_filter;
-    
-    /**
-     * Service Context in which resolving the dependency.
-     */
-    private ServiceContext m_serviceContext;
-    
-    /**
      * Thread Local.
      */
     private ServiceUsage m_usage = new ServiceUsage();
 
     /**
-     * Service Tracker.
-     */
-    private Tracker m_tracker;
-    
-    /**
-     * IS the instance activated ? 
-     */
-    private boolean m_activated = false;
-    
-    /**
-     * Binding Policy.
-     */
-    private int m_bindingPolicy;
-    
-    /**
      * Nullable object.
      */
     private Object m_nullable;
-    
+
     /**
      * Default-Implementation.
      */
     private String m_di;
 
     /**
+     * Id of the dependency.
+     */
+    private String m_id;
+
+    /**
      * Dependency constructor. After the creation the dependency is not started.
      * 
      * @param dh : the dependency handler managing this dependency
@@ -198,79 +100,40 @@
      * @param isOptional : is the dependency an optional dependency ?
      * @param isAggregate : is the dependency an aggregate dependency
      * @param id : id of the dependency, may be null
+     * @param sc : bundle context (or service context) to use.
      * @param policy : resolution policy
-     * @param bindingPolicy : binding policy
+     * @param cmp : comparator to sort references
      * @param di : default-implementation class
      */
-    public Dependency(DependencyHandler dh, String field, String spec, String filter, boolean isOptional, boolean isAggregate, String id, int policy, int bindingPolicy, String di) {
+    public Dependency(DependencyHandler dh, String field, Class spec, Filter filter, boolean isOptional, boolean isAggregate, String id, BundleContext sc, int policy, Comparator cmp, String di) {
+        super(spec, isAggregate, isOptional, filter, cmp, policy, sc);
         m_handler = dh;
         m_field = field;
-        m_specification = spec;
-        m_isOptional = isOptional;
         m_di = di;
-       
-        m_strFilter = filter;
-        m_isAggregate = isAggregate;
-        if (m_id == null) {
-            m_id = m_specification;
-        } else {
-            m_id = id;
-        }
-        if (policy != -1) {
-            m_policy = policy;
-        }
-        
-        m_bindingPolicy = bindingPolicy;
-        
-        // Fix the policy according to the level
-        if ((m_policy == PolicyServiceContext.LOCAL_AND_GLOBAL || m_policy == PolicyServiceContext.LOCAL) && ((((IPojoContext) m_handler.getInstanceManager().getContext()).getServiceContext()) == null)) {
-            // We are not in a composite : BOTH | STRICT => GLOBAL
-            m_policy = PolicyServiceContext.GLOBAL;
-        }
-    }
-
-    public String getField() {
-        return m_field;
-    }
 
-
-    public String getSpecification() {
-        return m_specification;
-    }
-
-
-    public boolean isOptional() {
-        return m_isOptional;
-    }
-
-
-    public boolean isAggregate() {
-        return m_isAggregate;
+        if (id != null) {
+            m_id = id;
+        } else if (spec != null) {
+            m_id = spec.getName();
+        } // Else wait the setSpecification call.
     }
 
     /**
-     * Set the dependency to aggregate.
-     */
-    protected void setAggregate() {
-        m_isAggregate = true;
-    }
-    
-    /**
-     * Activate the dependency.
-     * For static policy it freezes the service reference set.
+     * Set the specification of the current dependency.
+     * In order to store the id of the dependency, this
+     * method is override.
+     * @param spec : request service Class
+     * @see org.apache.felix.ipojo.util.AbstractServiceDependency#setSpecification(java.lang.Class)
      */
-    void activate() {
-        if (m_bindingPolicy == STATIC_POLICY) {
-            m_activated = true;
+    public void setSpecification(Class spec) {
+        super.setSpecification(spec);
+        if (m_id == null) {
+            m_id = spec.getName();
         }
     }
 
-    /**
-     * Set the tracked specification for this dependency.
-     * @param spec : the tracked specification (interface name)
-     */
-    protected void setSpecification(String spec) {
-        m_specification = spec;
+    public String getField() {
+        return m_field;
     }
 
     /**
@@ -288,30 +151,28 @@
         }
     }
 
+    /**
+     * Stop the current dependency.
+     * @see org.apache.felix.ipojo.util.AbstractServiceDependency#stop()
+     */
+    public void stop() {
+        m_isStarted = false;
+        super.stop();
+    }
 
     /**
      * Get the string form of the filter.
      * @return : the string form of the filter.
      */
-    public String getFilter() {
-        if (m_strFilter == null) { return ""; }
-        return m_strFilter;
+    public String getStringFilter() {
+        return getFilter().toString();
     }
 
-
     public DependencyHandler getHandler() {
         return m_handler;
     }
 
     /**
-     * Build the Set [service reference] of used services.
-     * @return the used service.
-     */
-    public List getUsedServices() {
-        return m_usedReferences;
-    }
-
-    /**
      * This method is called by the replaced code in the component
      * implementation class. Construct the service object list is necessary.
      * 
@@ -322,29 +183,28 @@
         // Initialize the thread local object is not already touched.
         if (m_usage.getObjects().isEmpty()) {
             if (isAggregate()) {
-                synchronized (m_tracker) {
-                    for (int i = 0; i < m_references.size(); i++) {
-                        ServiceReference ref = (ServiceReference) m_references.get(i);
-                        m_usage.addUsage(getService(ref), ref);
-                    }
+                ServiceReference[] refs = super.getServiceReferences();
+                for (int i = 0; refs != null && i < refs.length; i++) {
+                    ServiceReference ref = refs[i];
+                    m_usage.addUsage(getService(ref), ref);
                 }
             } else {
-                if (m_references.size() == 0) {
+                if (getSize() == 0) {
                     if (m_nullable == null) {
-                        m_handler.warn("[" + m_handler.getInstanceManager().getInstanceName() + "] The dependency is not optional, however no service object can be injected in " + m_field + " -> " + m_specification);
+                        m_handler.warn("[" + m_handler.getInstanceManager().getInstanceName() + "] The dependency is not optional, however no service object can be injected in " + m_field + " -> " + getSpecification().getName());
                         return null;
                     }
                     m_usage.getObjects().add(m_nullable);
                 } else {
-                    ServiceReference ref = (ServiceReference) m_references.get(0);
+                    ServiceReference ref = getServiceReference();
                     m_usage.addUsage(getService(ref), ref);
                 }
             }
             m_usage.setStackLevel(1);
         }
 
-        if (m_isAggregate) { // Multiple dependency
-            return (Object[]) m_usage.getObjects().toArray((Object[]) Array.newInstance(m_clazz, m_usage.getObjects().size()));
+        if (isAggregate()) { // Multiple dependency
+            return (Object[]) m_usage.getObjects().toArray((Object[]) Array.newInstance(getSpecification(), m_usage.getObjects().size()));
         } else {
             return m_usage.getObjects().get(0);
         }
@@ -374,39 +234,30 @@
             }
         }
     }
-
-    /**
-     * Get a service object for the given reference according to the resolving policy.
-     * @param ref : service reference
-     * @return the service object
-     */
-    private synchronized Object getService(ServiceReference ref) {
-        if (!m_usedReferences.contains(ref)) {
-            m_usedReferences.add(ref);
-        }
-        return m_tracker.getService(ref);
-    }
     
-    /**
-     * Unget the given service reference according to the resolving policy.
-     * @param ref : service reference to unget
-     */
-    private void ungetService(ServiceReference ref) {
-        m_tracker.ungetService(ref);
+    public synchronized boolean isFrozen() {
+        return m_isFrozen;
     }
 
     /**
      * Call the bind method.
      * @param instance : instance on which calling the bind method.
      */
-    protected synchronized void callBindMethod(Object instance) {
-        if (m_tracker == null) { return; }
+    protected synchronized void onObjectCreation(Object instance) {
+        if (!m_isStarted) { return; }
+
+        // We are notified of an instance creation, we have to freeze when the static policy is used
+        if (getBindingPolicy() == STATIC_BINDING_POLICY) {
+            m_isFrozen = true;
+        }
+
         // Check optional case : nullable object case : do not call bind on nullable object
-        if (m_isOptional && m_references.size() == 0) { return; }
+        if (isOptional() && getSize() == 0) { return; }
 
-        if (m_isAggregate) {
-            for (int i = 0; i < m_references.size(); i++) {
-                ServiceReference ref = (ServiceReference) m_references.get(i);
+        if (isAggregate()) {
+            ServiceReference[] refs = getServiceReferences();
+            for (int i = 0; i < refs.length; i++) {
+                ServiceReference ref = (ServiceReference) refs[i];
                 for (int j = 0; j < m_callbacks.length; j++) {
                     if (m_callbacks[j].getMethodType() == DependencyCallback.BIND) {
                         try {
@@ -428,7 +279,7 @@
             for (int j = 0; j < m_callbacks.length; j++) {
                 if (m_callbacks[j].getMethodType() == DependencyCallback.BIND) {
                     try {
-                        ServiceReference ref = (ServiceReference) m_references.get(0);
+                        ServiceReference ref = getServiceReference();
                         if (ref != null) {
                             m_callbacks[j].callOnInstance(instance, ref, getService(ref));
                         }
@@ -479,22 +330,7 @@
      * Start the dependency.
      */
     public void start() {
-        
-        m_serviceContext = new PolicyServiceContext(m_handler.getInstanceManager().getGlobalContext(), m_handler.getInstanceManager().getLocalServiceContext(), m_policy);
-        
-        // Construct the filter with the objectclass + filter
-        String filter = "(objectClass=" + m_specification + ")";
-        if (m_strFilter != null) {
-            filter = "(&" + filter + m_strFilter + ")";
-        }
-        
-        try {
-            m_clazz = m_handler.getInstanceManager().getContext().getBundle().loadClass(m_specification);
-        } catch (ClassNotFoundException e) {
-            throw new IllegalStateException("Cannot load the interface class for the dependency " + m_field + " [" + m_specification + "]");
-        }
-        
-        if (m_isOptional && ! m_isAggregate) {
+        if (isOptional() && !isAggregate()) {
             if (m_di != null) {
                 try {
                     Class c = getHandler().getInstanceManager().getContext().getBundle().loadClass(m_di);
@@ -507,59 +343,19 @@
                     throw new IllegalStateException("Cannot load the default-implementation " + m_di + " : " + e.getMessage());
                 }
             } else {
-                m_nullable = Proxy.newProxyInstance(getHandler().getInstanceManager().getClazz().getClassLoader(), new Class[] {m_clazz, Nullable.class}, new NullableObject());
+                m_nullable = Proxy.newProxyInstance(getHandler().getInstanceManager().getClazz().getClassLoader(), new Class[] { getSpecification(), Nullable.class }, new NullableObject());
             }
         }
-        
-        m_state = UNRESOLVED;
 
-        try {
-            m_filter = m_handler.getInstanceManager().getContext().createFilter(filter); // Store the filter
-        } catch (InvalidSyntaxException e1) {
-            throw new IllegalStateException("A filter is malformed : " + filter + " - " + e1.getMessage());
-        }  
-        m_tracker = new Tracker(m_serviceContext, m_filter, this);
-        m_tracker.open();
-        if (m_tracker.size() == 0 && !m_isOptional) {
-            m_state = UNRESOLVED;
-        } else {
-            m_state = RESOLVED;
-        }
-    }
+        super.start();
 
-    /**
-     * Stop the dependency.
-     */
-    public void stop() {
-        if (m_tracker != null) {
-            m_tracker.close(); // Will unget all used reference.
-            m_tracker = null;
+        if (getBindingPolicy() == STATIC_BINDING_POLICY && m_handler.getInstanceManager().getPojoObjects() != null) {
+            m_isFrozen = true;
         }
-
-        m_state = UNRESOLVED;
-
-        m_activated = false;
-        m_references.clear();
-        m_usedReferences.clear();
-        m_clazz = null;
-    }
-
-    /**
-     * Return the state of the dependency.
-     * @return the state of the dependency (1 : valid, 2 : invalid)
-     */
-    public int getState() {
-        return m_state;
+        
+        m_isStarted = true;
     }
 
-    /**
-     * Return the list of used service reference.
-     * @return the service reference list.
-     */
-    public List getServiceReferences() {
-        return m_references;
-    }
-    
     protected DependencyCallback[] getCallbacks() {
         return m_callbacks;
     }
@@ -570,13 +366,13 @@
      */
     public void setServiceLevelDependency() {
         m_isServiceLevelRequirement = true;
-        m_policy = PolicyServiceContext.LOCAL;
+        setBundleContext(new PolicyServiceContext(m_handler.getInstanceManager().getGlobalContext(), m_handler.getInstanceManager().getLocalServiceContext(), PolicyServiceContext.LOCAL));
     }
 
     public String getId() {
         return m_id;
     }
-    
+
     public boolean isServiceLevelRequirement() {
         return m_isServiceLevelRequirement;
     }
@@ -585,17 +381,17 @@
      * Method called when a thread enters in a method.
      */
     public void entry() {
-        if (! m_usage.getObjects().isEmpty()) {
+        if (!m_usage.getObjects().isEmpty()) {
             int level = m_usage.getStackLevel();
             m_usage.setStackLevel(level++);
         }
     }
-    
+
     /**
      * Method called when a thread exits a method.
      */
     public void exit() {
-        if (! m_usage.getObjects().isEmpty()) {
+        if (!m_usage.getObjects().isEmpty()) {
             int level = m_usage.getStackLevel();
             level = level - 1;
             if (level == 0) {
@@ -605,93 +401,63 @@
         }
     }
 
-   /**
-    * A new service is detected. This method check the reference against the stored filter.
-    * @param ref : new service reference.
-    * @return the service object, null is the service object is rejected.
-    * @see org.osgi.util.tracker.ServiceTrackerCustomizer#addingService(org.osgi.framework.ServiceReference)
-    */
-    public boolean addingService(ServiceReference ref) {
-        if (! m_activated) {
-            return true;
-        }
-        return false;
+    /**
+     * A new service has to be injected.
+     * @param reference : the new matching service reference.
+     * @see org.apache.felix.ipojo.util.AbstractServiceDependency#onServiceArrival(org.osgi.framework.ServiceReference)
+     */
+    public void onServiceArrival(ServiceReference reference) {
+        callBindMethod(reference);
+        //The method is only called when a new service arrives, or when the used one is replaced.
     }
-    
+
     /**
-     * A new service reference has been added in the tracker.
-     * Call the bind method if needed, and check the dependency context.
-     * @param reference : added reference.
-     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addedService(org.osgi.framework.ServiceReference)
-     */
-    public void addedService(ServiceReference reference) {
-        m_references.add(reference);
-        if (m_bindingPolicy == DYNAMIC_PRIORITY_POLICY) {
-            Collections.sort(m_references, new ServiceReferenceRankingComparator());
-        }
-        m_state = RESOLVED;
-        if (m_isAggregate || m_references.size() == 1) {
-            callBindMethod(reference);
-        }
-        
+     * A used (already injected) service disappears.
+     * @param ref : leaving service reference.
+     * @see org.apache.felix.ipojo.util.AbstractServiceDependency#onServiceDeparture(org.osgi.framework.ServiceReference)
+     */
+    public void onServiceDeparture(ServiceReference ref) {
+        callUnbindMethod(ref);
+    }
+
+    /**
+     * The dependency is now invalid (unresolved or broken).
+     * @see org.apache.felix.ipojo.util.AbstractServiceDependency#invalidate()
+     */
+    public void invalidate() {
         m_handler.checkContext();
     }
 
     /**
-     * A used service is modified.
-     * @param ref : modified reference
-     * @param arg1 : service object (returned when added) 
-     * @see org.osgi.util.tracker.ServiceTrackerCustomizer#modifiedService(org.osgi.framework.ServiceReference, java.lang.Object)
-     */
-    public void modifiedService(ServiceReference ref, Object arg1) { }
-
-    /**
-     * A used service disappears.
-     * @param ref : implicated service.
-     * @param arg1 : service object.
-     * @see org.osgi.util.tracker.ServiceTrackerCustomizer#removedService(org.osgi.framework.ServiceReference, java.lang.Object)
-     */
-    public void removedService(ServiceReference ref, Object arg1) {
-        // Call unbind method
-        boolean hasChanged = false;
-        m_references.remove(ref);
-        if (m_usedReferences.remove(ref)) {
-            callUnbindMethod(ref);
-            
-            // Null the ref in the instance manager map
-            if (m_field != null) {
-                m_handler.getInstanceManager().onSet(null, m_field, null);
-            }
-            
-            // Unget the service reference
-            ungetService(ref);
-            hasChanged = true;
-        }
-        
-        if (m_bindingPolicy == STATIC_POLICY) {
-            if (hasChanged && m_activated) {
-                m_state = BROKEN;
-            }
-        } else {
-            // Is the state valid or invalid, the reference is already removed
-            if (m_references.size() == 0 && !m_isOptional) {
-                m_state = UNRESOLVED;
-            } else {
-                m_state = RESOLVED;
-            }
-            
-            // Is there any change ?
-            if (!m_isAggregate) {
-                if (hasChanged) { // The used reference has been removed
-                    if (m_references.size() != 0) {
-                        callBindMethod(m_references.get(0));
-                    }
-                }
-            }
-        }
+     * The dependency has been reconfigured.
+     * @param departs : service no more matching.
+     * @param arrivals : new services
+     * @see org.apache.felix.ipojo.util.AbstractServiceDependency#onDependencyReconfiguration(org.osgi.framework.ServiceReference[], org.osgi.framework.ServiceReference[])
+     */
+    public void onDependencyReconfiguration(ServiceReference[] departs, ServiceReference[] arrivals) {
+        throw new UnsupportedOperationException("Dependency set change is not yet supported");
+    }
 
+    /**
+     * The dependency is now valid (resolved).
+     * @see org.apache.felix.ipojo.util.AbstractServiceDependency#validate()
+     */
+    public void validate() {
         m_handler.checkContext();
-        return;
+
+    }
+
+    /**
+     * Get the used service references list.
+     * @return the used service reference or null if no service reference are available.
+     */
+    public List getServiceReferencesAsList() {
+        ServiceReference[] refs = super.getServiceReferences();
+        if (refs != null) {
+            return Arrays.asList(refs);
+        } else {
+            return null;
+        }
     }
 
 }