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/26 13:20:36 UTC

svn commit: r631196 [1/3] - in /felix/sandbox/clement/ipojo: composite/ composite/src/main/java/org/apache/felix/ipojo/composite/ composite/src/main/java/org/apache/felix/ipojo/composite/instance/ composite/src/main/java/org/apache/felix/ipojo/composit...

Author: clement
Date: Tue Feb 26 04:20:30 2008
New Revision: 631196

URL: http://svn.apache.org/viewvc?rev=631196&view=rev
Log:
Add javadoc comments
Restructure composition to use only to handler with different actions : 
    <requires... becomes <subservice action="import" ...
    <service... becomes <subservice action="instantiate" ...
    <export becomes <provides action="export" ...
    <provides becomes <provides action="implement"
Fix some bug in the dynamic filter change on a dependency. Complete the work on context-source and dynamic filter change (for composite)
The abstract service dependency model use now a DependencyLifecycleListener to notify dependency state changes.
Improve the logger policy. Each bundle can set its own log level by fixing the 'ipojo.log.level' property to 'debug|info|warning|error' in their manifest.
Print the stack trace when an log message contains it.


Added:
    felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceDependencyHandler.java
      - copied, changed from r629469, 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/ServiceImporter.java
      - copied, changed from r629469, 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/provides/ExportDescription.java
      - copied, changed from r629467, felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/importer/ExportDescription.java
    felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/ServiceExporter.java
      - copied, changed from r629467, felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/importer/ServiceExporter.java
    felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/util/
    felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/util/SourceManager.java
    felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/util/DependencyLifecycleListener.java
Removed:
    felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/importer/
    felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorHandler.java
    felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoConfiguration.java
Modified:
    felix/sandbox/clement/ipojo/composite/   (props changed)
    felix/sandbox/clement/ipojo/composite/pom.xml
    felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/CompositeFactory.java
    felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/CompositeHandler.java
    felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/instance/InstanceHandler.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/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/MethodMetadata.java
    felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedService.java
    felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandler.java
    felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandlerDescription.java
    felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/SpecificationMetadata.java
    felix/sandbox/clement/ipojo/composite/src/main/resources/metadata.xml
    felix/sandbox/clement/ipojo/core/   (props changed)
    felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/HandlerFactory.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/InstanceCreator.java
    felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/ComponentTypeDescription.java
    felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/PropertyDescription.java
    felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurableProperty.java
    felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.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/DependencyHandler.java
    felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandlerDescription.java
    felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallbackHandler.java
    felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/Property.java
    felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java
    felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/ParseUtils.java
    felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/util/AbstractServiceDependency.java
    felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Logger.java

Propchange: felix/sandbox/clement/ipojo/composite/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Tue Feb 26 04:20:30 2008
@@ -1,5 +1,4 @@
-target
-bin
-.settings
-.project
+.checkstyle
 .classpath
+.project
+target

Modified: felix/sandbox/clement/ipojo/composite/pom.xml
URL: http://svn.apache.org/viewvc/felix/sandbox/clement/ipojo/composite/pom.xml?rev=631196&r1=631195&r2=631196&view=diff
==============================================================================
--- felix/sandbox/clement/ipojo/composite/pom.xml (original)
+++ felix/sandbox/clement/ipojo/composite/pom.xml Tue Feb 26 04:20:30 2008
@@ -66,6 +66,7 @@
 							org.apache.felix.ipojo.composite.architecture,
 							org.apache.felix.ipojo.composite.service*,
 							org.apache.felix.ipojo.composite.instance,
+							org.apache.felix.ipojo.composite.util,
 							!org.objectweb.asm.xml*,
 							org.objectweb.asm*;-split-package:=merge-first
 						</Private-Package>

Modified: felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/CompositeFactory.java
URL: http://svn.apache.org/viewvc/felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/CompositeFactory.java?rev=631196&r1=631195&r2=631196&view=diff
==============================================================================
--- felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/CompositeFactory.java (original)
+++ felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/CompositeFactory.java Tue Feb 26 04:20:30 2008
@@ -66,7 +66,6 @@
     /**
      * Check if the metadata are well formed.
      * @param cm : metadata
-     * @return true if the metadata are correct.
      * @throws ConfigurationException occurs when the element describing the factory is malformed.
      * @see org.apache.felix.ipojo.ComponentFactory#check(org.apache.felix.ipojo.metadata.Element)
      */
@@ -82,6 +81,7 @@
     
     /**
      * Compute required handlers.
+     * @return the list of required handler.
      */
     public List getRequiredHandlerList() {
         List list = new ArrayList();
@@ -132,6 +132,15 @@
         }
     }
     
+    /**
+     * Create an instance from the current factory.
+     * @param configuration : instance configuration
+     * @param context : bundle context to inject in the instance manager
+     * @param handlers : array of handler object to attached on the instance 
+     * @return the created instance
+     * @throws ConfigurationException either the instance configuration or the instance starting has failed 
+     * @see org.apache.felix.ipojo.ComponentFactory#createInstance(java.util.Dictionary, org.apache.felix.ipojo.IPojoContext, org.apache.felix.ipojo.HandlerManager[])
+     */
     public ComponentInstance createInstance(Dictionary configuration, IPojoContext context, HandlerManager[] handlers) throws ConfigurationException {
         CompositeManager inst = new CompositeManager(this, context, handlers);
         inst.configure(m_componentMetadata, configuration);

Modified: felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/CompositeHandler.java
URL: http://svn.apache.org/viewvc/felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/CompositeHandler.java?rev=631196&r1=631195&r2=631196&view=diff
==============================================================================
--- felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/CompositeHandler.java (original)
+++ felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/CompositeHandler.java Tue Feb 26 04:20:30 2008
@@ -43,7 +43,7 @@
     private CompositeManager m_manager;
     
     /**
-     * Composite Factory
+     * Composite Factory.
      */
     private CompositeFactory m_factory;
     

Modified: felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/instance/InstanceHandler.java
URL: http://svn.apache.org/viewvc/felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/instance/InstanceHandler.java?rev=631196&r1=631195&r2=631196&view=diff
==============================================================================
--- felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/instance/InstanceHandler.java (original)
+++ felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/instance/InstanceHandler.java Tue Feb 26 04:20:30 2008
@@ -48,12 +48,6 @@
      * Internal context.
      */
     private ServiceContext m_scope;
-
-//    /**
-//     * Is the handler valid ?
-//     * (Lifecycle controller)
-//     */
-//    private boolean m_isValid = false;
     
     /**
      * Available factories.
@@ -161,9 +155,9 @@
             config.setFactory(fact.getName());
             config.getInstance().addInstanceStateListener(this);
         } catch (UnacceptableConfiguration e) {
-            error( "A factory is available for the configuration but the configuration is not acceptable", e);
+            error("A factory is available for the configuration but the configuration is not acceptable", e);
         } catch (MissingHandlerException e) {
-            error( "The instance creation has failed, at least one handler is missing", e);
+            error("The instance creation has failed, at least one handler is missing", e);
         } catch (ConfigurationException e) {
             error("The instance creation has failed, an error during the configuration has occured", e);
         }
@@ -239,7 +233,7 @@
             try {
                 conf = parseInstance(instances[i]);
             } catch (ParseException e) {
-                error( "An instance cannot be parsed correctly", e);
+                error("An instance cannot be parsed correctly", e);
                 throw new ConfigurationException("An instance cannot be parsed correctly : " + e.getMessage());
             }
             m_configurations[i] = new ManagedConfiguration(conf);
@@ -252,7 +246,7 @@
      * @return : the resulting dictionary
      * @throws ParseException : occurs when a configuration cannot be parse correctly.
      */
-    private Dictionary parseInstance(Element instance) throws ParseException {
+    public static Dictionary parseInstance(Element instance) throws ParseException {
         Dictionary dict = new Properties();
         String name = instance.getAttribute("name");
         if (name != null) {
@@ -280,7 +274,7 @@
      * @param dict : the dictionary to populate
      * @throws ParseException : occurs if the property cannot be parsed correctly
      */
-    private void parseProperty(Element prop, Dictionary dict) throws ParseException {
+    public static void parseProperty(Element prop, Dictionary dict) throws ParseException {
         // Check that the property has a name
         String name = prop.getAttribute("name");
         String value = prop.getAttribute("value");
@@ -320,8 +314,7 @@
 
     /**
      * Check handler validity.
-     * The method update the m_validity field.
-     * @return the new validity.
+     * The method update the validaity of the handler.
      */
     private void checkValidity() {
         for (int i = 0; i < m_configurations.length; i++) {
@@ -369,8 +362,13 @@
      */
     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())) {
+                if (m_configurations[i].getInstance().getState() == ComponentInstance.VALID) {
+                    return ((InstanceManager) m_configurations[i].getInstance()).getPojoObject();
+                } else {
+                    error("An object cannot be get from the instance of the type " + type + ": invalid instance" + m_configurations[i].getInstance().getInstanceDescription().getDescription());
+                    return null;
+                }
             }
         }
         return null;

Copied: felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceDependencyHandler.java (from r629469, 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/ServiceDependencyHandler.java?p2=felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceDependencyHandler.java&p1=felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorHandler.java&r1=629469&r2=631196&rev=631196&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/ServiceDependencyHandler.java Tue Feb 26 04:20:30 2008
@@ -26,10 +26,16 @@
 
 import org.apache.felix.ipojo.ComponentInstance;
 import org.apache.felix.ipojo.ConfigurationException;
+import org.apache.felix.ipojo.PolicyServiceContext;
 import org.apache.felix.ipojo.architecture.HandlerDescription;
 import org.apache.felix.ipojo.composite.CompositeHandler;
+import org.apache.felix.ipojo.composite.instance.InstanceHandler;
+import org.apache.felix.ipojo.composite.util.SourceManager;
 import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.parser.ParseException;
 import org.apache.felix.ipojo.util.AbstractServiceDependency;
+import org.apache.felix.ipojo.util.DependencyLifecycleListener;
+import org.osgi.framework.BundleContext;
 import org.osgi.framework.Filter;
 import org.osgi.framework.InvalidSyntaxException;
 
@@ -39,65 +45,191 @@
  * 
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public class ServiceInstantiatorHandler extends CompositeHandler {
+public class ServiceDependencyHandler extends CompositeHandler implements DependencyLifecycleListener {
 
     /**
      * List of instances to manage.
      */
     private List/* <SvcInstance> */m_instances = new ArrayList();
     
+    /**
+     * List of importers.
+     */
+    private List/* <ServiceImporter> */ m_importers = new ArrayList();
+    
+    /**
+     * Flag indicating if the handler has already finished the start method.
+     */
     private boolean m_isStarted;
 
     /**
-     * Configure the handler.
-     * 
-     * @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)
+     * Source Managers.
      */
-    public void configure(Element metadata, Dictionary conf) throws ConfigurationException {
-        Element[] services = metadata.getElements("service");
-        for (int i = 0; i < services.length; i++) {
-            String spec = services[i].getAttribute("specification");
-            if (spec == null) {
-                throw new ConfigurationException("Malformed service : the specification attribute is mandatory");
+    private List m_sources;
+    
+    
+    /**
+     * Create a Service instance object form the given Element.
+     * This method parse the given element and configure the service instance object.
+     * @param service : the Element describing the service instance
+     * @throws ConfigurationException : the service instance cannot be created correctly
+     */
+    private void createServiceInstance(Element service) throws ConfigurationException {
+        String spec = service.getAttribute("specification");
+        if (spec == null) {
+            throw new ConfigurationException("Malformed service : the specification attribute is mandatory");
+        }
+        String filter = "(&(!(factory.name=" + getCompositeManager().getFactory().getComponentDescription().getName() + "))(factory.state=1))"; // Cannot reinstantiate yourself
+        String f = service.getAttribute("filter");
+        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 = service.getElements("property");
+        for (int k = 0; props != null && k < props.length; k++) {
+            try {
+                InstanceHandler.parseProperty(props[k], prop);
+            } catch (ParseException e) {
+                throw new ConfigurationException("An instance configuration is invalid : " + e.getMessage());
             }
-            String filter = "(&(!(factory.name=" + getCompositeManager().getFactory().getComponentDescription().getName() + "))(factory.state=1))"; // Cannot reinstantiate yourself
-            String f = services[i].getAttribute("filter");
+        }
+        
+        String ag = service.getAttribute("aggregate");
+        boolean agg = ag != null && ag.equalsIgnoreCase("true");
+        
+        String op = service.getAttribute("optional");
+        boolean opt = op != null && op.equalsIgnoreCase("true");
+        
+        int policy = AbstractServiceDependency.getPolicy(service);
+        
+        Comparator cmp = AbstractServiceDependency.getComparator(service, getCompositeManager().getGlobalContext());
+        
+        SvcInstance inst = new SvcInstance(this, spec, prop, agg, opt, fil, cmp, policy);
+        m_instances.add(inst);
+        
+        String sources = service.getAttribute("context-source");
+        if (sources != null) {
+            SourceManager sm = new SourceManager(sources, filter, inst, getCompositeManager());
+            if (m_sources == null) {
+                m_sources = new ArrayList(1);
+            }
+            m_sources.add(sm);
+        }
+    }
+    
+    /**
+     * Create a Service importer object from the given Element.
+     * This method parse the given element and configure the service importer object.
+     * @param imp : Element describing the import
+     * @param filterConfiguration : instance filter customization
+     * @throws ConfigurationException : the service importer cannot be created correctly
+     */
+    private void createServiceImport(Element imp, Dictionary filterConfiguration) throws ConfigurationException {
+        boolean optional = false;
+        boolean aggregate = false;
+        String specification = imp.getAttribute("specification");
+
+        if (specification != null) {
+            String opt = imp.getAttribute("optional");
+            optional = opt != null && opt.equalsIgnoreCase("true");
+
+            String agg = imp.getAttribute("aggregate");
+            aggregate = agg != null && agg.equalsIgnoreCase("true");
+
+            String original = "(&(objectClass=" + specification + ")(!(instance.name=" + getCompositeManager().getInstanceName() + ")))"; // Cannot import yourself
+            String filter = original;
+            String f = imp.getAttribute("filter");
             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());
+
+            String id = imp.getAttribute("id");
+
+            String scope = imp.getAttribute("scope");
+            BundleContext bc = getCompositeManager().getGlobalContext(); // Get the default bundle context.
+            if (scope != null) {
+                if (scope.equalsIgnoreCase("global")) {
+                    bc = new PolicyServiceContext(getCompositeManager().getGlobalContext(), getCompositeManager().getParentServiceContext(), PolicyServiceContext.GLOBAL);
+                } else if (scope.equalsIgnoreCase("composite")) {
+                    bc = new PolicyServiceContext(getCompositeManager().getGlobalContext(), getCompositeManager().getParentServiceContext(), PolicyServiceContext.LOCAL);
+                } else if (scope.equalsIgnoreCase("composite+global")) {
+                    bc = new PolicyServiceContext(getCompositeManager().getGlobalContext(), getCompositeManager().getParentServiceContext(), PolicyServiceContext.LOCAL_AND_GLOBAL);
+                }
             }
-            
-            Properties prop = new Properties();
-            Element[] props = services[i].getElements("property");
-            for (int k = 0; props != null && k < props.length; k++) {
-                String key = props[k].getAttribute("name");
-                String value = props[k].getAttribute("value");
-                prop.put(key, value);
+
+            // Configure instance filter if available
+            if (filterConfiguration != null && id != null && filterConfiguration.get(id) != null) {
+                filter = "(&" + original + (String) filterConfiguration.get(id) + ")";
             }
-            String ag = services[i].getAttribute("aggregate");
-            boolean agg = ag != null && ag.equalsIgnoreCase("true");
-            
-            String op = services[i].getAttribute("optional");
-            boolean opt = op != null && op.equalsIgnoreCase("true");
+
+            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());
+                }
+            }
+
+            Comparator cmp = AbstractServiceDependency.getComparator(imp, getCompositeManager().getGlobalContext());
+            Class spec = AbstractServiceDependency.loadSpecification(specification, getCompositeManager().getGlobalContext());
+            int policy = AbstractServiceDependency.getPolicy(imp);
+
+            ServiceImporter si = new ServiceImporter(spec, fil, aggregate, optional, cmp, policy, bc, id, this);
+            m_importers.add(si);
             
-            int policy = AbstractServiceDependency.getPolicy(services[i]);
+            String sources = imp.getAttribute("context-source");
+            if (sources != null) {
+                SourceManager sm = new SourceManager(sources, filter, si, getCompositeManager());
+                if (m_sources == null) {
+                    m_sources = new ArrayList(1);
+                }
+                m_sources.add(sm);
+            }
             
-            Comparator cmp = AbstractServiceDependency.getComparator(services[i], getCompositeManager().getGlobalContext());
+        } else { // Malformed import
+            error("Malformed imports : the specification attribute is mandatory");
+            throw new ConfigurationException("Malformed imports : the specification attribute is mandatory");
+        }
+    }
+
+    /**
+     * Configure the handler.
+     * @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(Element metadata, Dictionary conf) throws ConfigurationException {
+        Element[] services = metadata.getElements("subservice");
+        // Get instance filters
+        Dictionary filtersConfiguration = null;
+        if (conf.get("requires.filters") != null) {
+            filtersConfiguration = (Dictionary) conf.get("requires.filters");
+        }
+        
+        for (int i = 0; i < services.length; i++) {
+            String action = services[i].getAttribute("action");
+            if (action == null) {
+                throw new ConfigurationException("The action attribute must be set to 'instantiate' or 'import'");
+            } else if ("instantiate".equalsIgnoreCase(action)) {
+                createServiceInstance(services[i]);
+            } else if ("import".equalsIgnoreCase(action)) {
+                createServiceImport(services[i], filtersConfiguration);
+            } else {
+                throw new ConfigurationException("Unknown action : " + action);
+            }
             
-            //String source = services[i].getAttribute("context-source");
             
-            SvcInstance inst = new SvcInstance(this, spec, prop, agg, opt, fil, cmp, policy);
-            m_instances.add(inst);
+
         }
     }
 
@@ -107,7 +239,16 @@
      * @see org.apache.felix.ipojo.CompositeHandler#start()
      */
     public void start() {
-        // Init
+        for (int i = 0; m_sources != null && i < m_sources.size(); i++) {
+            SourceManager sm = (SourceManager) m_sources.get(i);
+            sm.start();
+        }
+        
+        for (int i = 0; i < m_importers.size(); i++) {
+            ServiceImporter si = (ServiceImporter) m_importers.get(i);
+            si.start();
+        }
+        
         for (int i = 0; i < m_instances.size(); i++) {
             SvcInstance inst = (SvcInstance) m_instances.get(i);
             inst.start();
@@ -119,10 +260,17 @@
 
     /**
      * Check the handler validity.
-     * @return true if all created service instances are valid
      * @see org.apache.felix.ipojo.CompositeHandler#isValid()
      */
     private void isHandlerValid() {
+        for (int i = 0; i < m_importers.size(); i++) {
+            ServiceImporter si = (ServiceImporter) m_importers.get(i);
+            if (si.getState() != AbstractServiceDependency.RESOLVED) {
+                setValidity(false);
+                return;
+            }
+        }
+        
         for (int i = 0; i < m_instances.size(); i++) {
             SvcInstance inst = (SvcInstance) m_instances.get(i);
             if (inst.getState() != AbstractServiceDependency.RESOLVED) {
@@ -130,6 +278,7 @@
                 return;
             }
         }
+        
         setValidity(true);
     }
 
@@ -139,17 +288,40 @@
      * @see org.apache.felix.ipojo.CompositeHandler#stop()
      */
     public void stop() {
+        for (int i = 0; m_sources != null && i < m_sources.size(); i++) {
+            SourceManager sm = (SourceManager) m_sources.get(i);
+            sm.stop();
+        }
+        
         for (int i = 0; i < m_instances.size(); i++) {
             SvcInstance inst = (SvcInstance) m_instances.get(i);
             inst.stop();
         }
-        m_instances.clear();
+        
+        for (int i = 0; i < m_importers.size(); i++) {
+            ServiceImporter si = (ServiceImporter) m_importers.get(i);
+            si.stop();
+        }
+
         m_isStarted = false;
     }
     
+    /**
+     * State change callback.
+     * This method is used to freeze the set of used provider if the static binding policy is used.
+     * @param newState : the new state of the underlying instance
+     * @see org.apache.felix.ipojo.Handler#stateChanged(int)
+     */
     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.getBindingPolicy() == AbstractServiceDependency.STATIC_BINDING_POLICY) {
+                    si.freeze();
+                }
+            }
+            
             for (int i = 0; i < m_instances.size(); i++) {
                 SvcInstance si = (SvcInstance) m_instances.get(i);
                 if (si.getBindingPolicy() == AbstractServiceDependency.STATIC_BINDING_POLICY) {
@@ -161,8 +333,9 @@
 
     /**
      * An service instance becomes valid.
+     * @param dep : dependency becoming valid.
      */
-    public void validate() {
+    public void validate(AbstractServiceDependency dep) {
         if (!getValidity()) {
             isHandlerValid();
         }
@@ -170,8 +343,9 @@
 
     /**
      * A service instance becomes invalid.
+     * @param dep : dependency becoming valid.
      */
-    public void invalidate() {
+    public void invalidate(AbstractServiceDependency dep) {
         if (getValidity()) {
             isHandlerValid();
         }
@@ -183,10 +357,14 @@
      * @see org.apache.felix.ipojo.CompositeHandler#getDescription()
      */
     public HandlerDescription getDescription() {
-        return new ServiceInstantiatorDescription(this, m_instances);
+        return new ServiceInstantiatorDescription(this, m_instances, m_importers);
     }
     
     public List getInstances() {
         return m_instances;
+    }
+    
+    public List getRequirements() {
+        return m_importers;
     }
 }

Copied: felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceImporter.java (from r629469, 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/instantiator/ServiceImporter.java?p2=felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceImporter.java&p1=felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/importer/ServiceImporter.java&r1=629469&r2=631196&rev=631196&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/instantiator/ServiceImporter.java Tue Feb 26 04:20:30 2008
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.felix.ipojo.composite.service.importer;
+package org.apache.felix.ipojo.composite.service.instantiator;
 
 import java.util.ArrayList;
 import java.util.Comparator;
@@ -27,17 +27,12 @@
 import org.apache.felix.ipojo.PolicyServiceContext;
 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;
 
 /**
  * Import a service form the parent to the internal service registry.
- * 
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
 public class ServiceImporter extends AbstractServiceDependency {
@@ -45,40 +40,56 @@
     /**
      * Reference on the handler.
      */
-    private ImportHandler m_handler;
-    
-    private BundleContext m_origin;
+    private ServiceDependencyHandler m_handler;
 
-    private class Record implements ServiceListener {
+    private final class Record {
         /**
          * External Reference.
          */
         private ServiceReference m_ref;
+
         /**
          * Internal Registration.
          */
         private ServiceRegistration m_reg;
+
         /**
          * Exposed Object.
          */
         private Object m_svcObject;
-        
+
+        /**
+         * Constructor.
+         * @param ref : service reference.
+         */
         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.
-            }
         }
-        
+
+        /**
+         * Register the current import.
+         */
         private void register() {
+            if (m_reg != null) {
+                m_reg.unregister();
+            }
             m_svcObject = getService(m_ref);
             m_reg = m_handler.getCompositeManager().getServiceContext().registerService(getSpecification().getName(), m_svcObject, getProps(m_ref));
         }
-        
+
+        /**
+         * Update the current import.
+         */
+        private void update() {
+            if (m_reg != null) {
+                m_reg.setProperties(getProps(m_ref));
+            }
+        }
+
+        /**
+         * Unregister and release the current import.
+         */
         private void dispose() {
-            m_origin.removeServiceListener(this);
             if (m_reg != null) {
                 m_reg.unregister();
                 m_svcObject = null;
@@ -86,7 +97,7 @@
             }
             m_ref = null;
         }
-        
+
         /**
          * Test object equality.
          * @param o : object to confront against the current object.
@@ -100,14 +111,6 @@
             }
             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()));
-              }
-            }
-            
     }
 
     /**
@@ -124,7 +127,10 @@
      * Is this requirement attached to a service-level requirement.
      */
     private boolean m_isServiceLevelRequirement;
-    
+
+    /**
+     * Is the set of used provider frozen ?
+     */
     private boolean m_isFrozen;
 
     /**
@@ -134,24 +140,23 @@
      * @param filter : LDAP filter
      * @param multiple : should the importer imports several services ?
      * @param optional : is the import optional ?
-     * @param from : parent context
-     * @param to : internal context
+     * @param cmp : comparator to use for the tracking 
      * @param policy : resolving policy
+     * @param bc : bundle context to use for the tracking (can be a servie context)
      * @param id : requirement id (may be null)
      * @param in : handler
      */
-    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;
-        
+    public ServiceImporter(Class specification, Filter filter, boolean multiple, boolean optional, Comparator cmp, int policy, BundleContext bc, String id, ServiceDependencyHandler in) {
+        super(specification, multiple, optional, filter, cmp, policy, bc, in);
+
         this.m_handler = in;
-        
+
         if (m_id == null) {
             m_id = super.getSpecification().getName();
         } else {
             m_id = id;
         }
+
     }
 
     /**
@@ -168,15 +173,15 @@
         }
         return prop;
     }
-    
-    public boolean isStatic() {
-        return getBindingPolicy() == STATIC_BINDING_POLICY;
-    }
-    
+
+    /**
+     * Freeze the set of used provider.
+     * This method allow to fix the set of provider when the static binding policy is used.
+     */
     public void freeze() {
         m_isFrozen = true;
     }
-    
+
     public boolean isFrozen() {
         return m_isFrozen;
     }
@@ -192,7 +197,7 @@
             Record rec = (Record) m_records.get(i);
             rec.dispose();
         }
-        
+
         m_records.clear();
 
     }
@@ -218,14 +223,14 @@
      * Build the list of imported service provider.
      * @return the list of all imported services.
      */
-    protected List getProviders() {
+    public List getProviders() {
         List l = new ArrayList();
         for (int i = 0; i < m_records.size(); i++) {
             l.add((((Record) m_records.get(i)).m_ref).getProperty("instance.name"));
         }
         return l;
     }
-    
+
     /**
      * Set that this dependency is a service level dependency.
      * This forces the scoping policy to be STRICT. 
@@ -240,19 +245,33 @@
     public String getId() {
         return m_id;
     }
-    
+
     public boolean isServiceLevelRequirement() {
         return m_isServiceLevelRequirement;
     }
 
-    public void invalidate() {
-        m_handler.invalidating(this);
-    }
-
+    /**
+     * On Dependency Reconfiguration notification method.
+     * @param departs : leaving service references.
+     * @param arrivals : new injected service references.
+     * @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("Service import does not support dependency reconfiguration");
+        for (int i = 0; departs != null && i < departs.length; i++) {
+            onServiceDeparture(departs[i]);
+        }
+        
+        for (int i = 0; arrivals != null && i < arrivals.length; i++) {
+            onServiceArrival(arrivals[i]);
+        }
     }
 
+    /**
+     * A new service is injected by the tracker.
+     * This method create a 'Record' and register it.
+     * @param ref : new service reference.
+     * @see org.apache.felix.ipojo.util.AbstractServiceDependency#onServiceArrival(org.osgi.framework.ServiceReference)
+     */
     public void onServiceArrival(ServiceReference ref) {
         Record rec = new Record(ref);
         m_records.add(rec);
@@ -260,18 +279,32 @@
         rec.register();
     }
 
+    /**
+     * A used service disappears.
+     * This method find the implicated 'Record', dispose it and remove it from the list.
+     * @param ref : leaving service reference.
+     * @see org.apache.felix.ipojo.util.AbstractServiceDependency#onServiceDeparture(org.osgi.framework.ServiceReference)
+     */
     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);
             rec.dispose();
-            
         }
         m_records.removeAll(l);
     }
 
-    public void validate() {
-        m_handler.validating(this);
+    /**
+     * A used service is modified.
+     * @param ref : modified service reference.
+     * @see org.apache.felix.ipojo.util.AbstractServiceDependency#onServiceModification(org.osgi.framework.ServiceReference)
+     */
+    public void onServiceModification(ServiceReference ref) {
+        List l = getRecordsByRef(ref);
+        for (int i = 0; i < l.size(); i++) { // Stop the implied record
+            Record rec = (Record) l.get(i);
+            rec.update();
+        }
     }
 
 }

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=631196&r1=631195&r2=631196&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 Tue Feb 26 04:20:30 2008
@@ -44,14 +44,21 @@
     private List m_instances;
 
     /**
+     * List of exports.
+     */
+    private List m_imports;
+
+    /**
      * Constructor.
      * 
      * @param h : composite handler
-     * @param insts : list of service instance
+     * @param insts : list of service instances
+     * @param imps : list of service importers
      */
-    public ServiceInstantiatorDescription(CompositeHandler h, List insts) {
+    public ServiceInstantiatorDescription(CompositeHandler h, List insts, List imps) {
         super(h);
         m_instances = insts;
+        m_imports = imps;
     }
 
     /**
@@ -61,6 +68,26 @@
      */
     public Element getHandlerInfo() {
         Element services = 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().getName()));
+            if (imp.getFilter() != null) {
+                impo.addAttribute(new Attribute("Filter", imp.getFilter()));
+            }
+            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", "");
+                    pr.addAttribute(new Attribute("name", (String) imp.getProviders().get(j)));
+                    impo.addElement(pr);
+                }
+            } else {
+                impo.addAttribute(new Attribute("State", "unresolved"));
+            }
+            services.addElement(impo);
+        }
+        
         for (int i = 0; i < m_instances.size(); i++) {
             SvcInstance inst = (SvcInstance) m_instances.get(i);
             Element service = new Element("Service", "");

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=631196&r1=631195&r2=631196&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 Tue Feb 26 04:20:30 2008
@@ -38,9 +38,7 @@
 import org.osgi.framework.ServiceReference;
 
 /**
- * Manage a service instantiation. This service create component instance
- * providing the required service specification.
- * 
+ * Manage a service instantiation. This service create component instance providing the required service specification.
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
 public class SvcInstance extends AbstractServiceDependency {
@@ -53,15 +51,21 @@
     /**
      * Handler creating the service instance.
      */
-    private ServiceInstantiatorHandler m_handler;
-    
+    private ServiceDependencyHandler m_handler;
+
     /**
-     * Map of matching factories  Service Reference => instance or null (null if the service reference is not actually used).
+     * Map of matching factories Service Reference => instance or null (null if the service reference is not actually used).
+     */
+    private Map /* <ServiceReference, Instance> */m_matchingFactories = new HashMap();
+
+    /**
+     * Required specification.
      */
-    private Map /*<ServiceReference, Instance>*/m_matchingFactories = new HashMap();
-    
     private String m_specification;
-    
+
+    /**
+     * Is the service provider frozen ? (Is used for static biding policy)
+     */
     private boolean m_isFrozen;
 
     /**
@@ -72,20 +76,19 @@
      * @param isAgg : is the service instance an aggregate service ?
      * @param isOpt : is the service instance optional ?
      * @param filt : LDAP filter
+     * @param cmp : comparator to use for the tracking
+     * @param policy : binding policy
      * @throws ConfigurationException : an attribute cannot be parsed correctly, or is incorrect.
      */
-    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);
-        
+    public SvcInstance(ServiceDependencyHandler 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, h);
+
         m_specification = spec;
-        
+
         m_handler = h;
         setBundleContext(m_handler.getCompositeManager().getServiceContext());
-        
-        m_configuration = conf;
-
 
-        //TODO managing several sources
+        m_configuration = conf;
     }
 
     /**
@@ -103,30 +106,33 @@
                 ((ComponentInstance) o).dispose();
             }
         }
-        
+
         m_matchingFactories.clear();
 
     }
-    
+
     public boolean isFrozen() {
         return m_isFrozen;
     }
-    
+
+    /**
+     * Freeze the set of used provider.
+     * This method is when the static binding policy is applied.
+     */
     public void freeze() {
         m_isFrozen = true;
     }
 
     /**
-     * Create an instance for the given reference.
-     * The instance is not added inside the map.
+     * Create an instance for the given reference. 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 MissingHandlerException : the factory is invalid.
      * @throws UnacceptableConfiguration : the given configuration is invalid for the given factory.
      */
     private ComponentInstance createInstance(Factory factory) throws UnacceptableConfiguration, MissingHandlerException, ConfigurationException {
-        // Add an unique name if not specified.
+        // Recreate the configuration to avoid sharing.
         Properties p = new Properties();
         Enumeration kk = m_configuration.keys();
         while (kk.hasMoreElements()) {
@@ -147,9 +153,9 @@
         // Check if the factory can provide the specification
         ComponentTypeDescription desc = (ComponentTypeDescription) fact.getProperty("component.description");
         if (desc == null) { 
-            return false; // No component type description. 
-        } 
-       
+            return false; // No component type description.
+        }
+
         String[] provides = desc.getprovidedServiceSpecification();
         for (int i = 0; provides != null && i < provides.length; i++) {
             if (provides[i].equals(m_specification)) {
@@ -168,7 +174,7 @@
                     String k = (String) keys.nextElement();
                     p.put(k, m_configuration.get(k));
                 }
-                
+
                 Factory factory = (Factory) getService(fact);
                 return factory.isAcceptable(p);
             }
@@ -177,10 +183,9 @@
     }
 
     /**
-     * Does the factory support the given property ?
-     * 
+     * Does the factory support the given property ? This method check if the property is contained in the given property description array.
      * @param name : name of the property
-     * @param factory : factory to test
+     * @param props : list of property description
      * @return true if the factory support this property
      */
     private boolean containsProperty(String name, org.apache.felix.ipojo.architecture.PropertyDescription[] props) {
@@ -198,7 +203,7 @@
     public String getServiceSpecification() {
         return m_specification;
     }
-    
+
     /**
      * Get the map of used references [reference, component instance].
      * @return the map of used references.
@@ -207,22 +212,34 @@
         return m_matchingFactories;
     }
 
-    public void invalidate() {
-        m_handler.invalidate();
-        
-    }
-
+    /**
+     * On Dependency Reconfiguration notification method.
+     * @param departs : leaving service references.
+     * @param arrivals : new injected service references.
+     * @see org.apache.felix.ipojo.util.AbstractServiceDependency#onDependencyReconfiguration(org.osgi.framework.ServiceReference[], org.osgi.framework.ServiceReference[])
+     */
     public void onDependencyReconfiguration(ServiceReference[] departs, ServiceReference[] arrivals) {
-        // TODO Auto-generated method stub
+        for (int i = 0; departs != null && i < departs.length; i++) {
+            onServiceDeparture(departs[i]);
+        }
         
+        for (int i = 0; arrivals != null && i < arrivals.length; i++) {
+            onServiceArrival(arrivals[i]);
+        }
     }
 
+    /**
+     * A new service is injected.
+     * This method create the sub-service instance in the composite.
+     * @param ref : service reference.
+     * @see org.apache.felix.ipojo.util.AbstractServiceDependency#onServiceArrival(org.osgi.framework.ServiceReference)
+     */
     public void onServiceArrival(ServiceReference ref) {
         // The given factory matches.
         try {
-        Factory fact = (Factory) getService(ref);
-        ComponentInstance ci = createInstance(fact);
-        m_matchingFactories.put(ref, ci);
+            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();
@@ -233,20 +250,22 @@
             m_handler.error("A matching configuration is refuse by the instance : " + e.getMessage());
             m_handler.getCompositeManager().stop();
         }
-        
+
     }
 
+    
+    /**
+     * A used service is leaving.
+     * This method dispose the created instance.
+     * @param ref : leaving service reference.
+     * @see org.apache.felix.ipojo.util.AbstractServiceDependency#onServiceDeparture(org.osgi.framework.ServiceReference)
+     */
     public void onServiceDeparture(ServiceReference ref) {
         // Remove the reference is contained
         Object o = m_matchingFactories.remove(ref);
         if (o != null) {
             ((ComponentInstance) o).dispose();
         }
-    }
-
-    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=631196&r1=631195&r2=631196&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 Tue Feb 26 04:20:30 2008
@@ -54,7 +54,7 @@
      * Bundle Context.
      */
     private BundleContext m_context;
-    
+
     /**
      * Manipulation Metadata.
      */
@@ -85,14 +85,14 @@
 
         // Get implemented service specification
         String spec = description.getAttribute("specification");
-        m_specification = new SpecificationMetadata(spec, m_context, false, false, m_handler);        
+        m_specification = new SpecificationMetadata(spec, m_context, false, false, m_handler);
 
         Element[] mappings = description.getElements("delegation");
         for (int i = 0; mappings != null && i < mappings.length; i++) {
             String methodName = mappings[i].getAttribute("method");
             MethodMetadata method = m_specification.getMethodByName(methodName);
             if (method == null) {
-                m_handler.error( "The method " + methodName + " does not exist in the specicifation " + spec);
+                m_handler.error("The method " + methodName + " does not exist in the specicifation " + spec);
                 return;
             }
 
@@ -120,13 +120,13 @@
      */
     private void buildAvailableMappingList() throws CompositionException {
         int index = 0;
-        
+
         for (int i = 0; i < m_handler.getInstanceType().size(); i++) {
             String type = (String) m_handler.getInstanceType().get(i);
             try {
                 ServiceReference[] refs = m_context.getServiceReferences(Factory.class.getName(), "(factory.name=" + type + ")");
                 if (refs == null) {
-                    m_handler.error( "The factory " + type + " is not available, cannot check the composition");
+                    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");
@@ -139,9 +139,9 @@
                     index++;
                 }
             } catch (InvalidSyntaxException e) {
-                m_handler.error( "A LDAP filter is not valid : " + e.getMessage());
+                m_handler.error("A LDAP filter is not valid : " + e.getMessage());
             } catch (ClassNotFoundException e) {
-                m_handler.error( "The implementation class of a component cannot be loaded : " + e.getMessage());
+                m_handler.error("The implementation class of a component cannot be loaded : " + e.getMessage());
             }
         }
 
@@ -160,7 +160,6 @@
             index++;
         }
     }
-    
 
     /**
      * Build the delegation mapping.
@@ -178,7 +177,7 @@
             SpecificationMetadata spec = map.getSpecification();
             for (int j = 0; j < spec.getMethods().size(); j++) {
                 MethodMetadata method = (MethodMetadata) spec.getMethods().get(j);
-                if (spec.isInterface()) { 
+                if (spec.isInterface()) {
                     availableSvcMethods.put(method, map);
                 } else {
                     availableInstMethods.put(method, map);
@@ -218,9 +217,7 @@
                     }
                 }
             }
-            if (!found) {
-                throw new CompositionException("Inconsistent composition - the method " + method.getMethod() + " could not be delegated");
-            }
+            if (!found) { throw new CompositionException("Inconsistent composition - the method " + method.getMethod() + " could not be delegated"); }
         }
     }
 
@@ -259,7 +256,7 @@
         Attribute factory = new Attribute("factory", "false");
         elem.addAttribute(className);
         elem.addAttribute(factory);
-        
+
         // Add architecture for debug
         elem.addAttribute(new Attribute("architecture", "true"));
 
@@ -283,11 +280,11 @@
                 elem.addElement(dep);
             }
         }
-        
+
         Element properties = new Element("properties", "");
         for (int i = 0; i < fields.size(); i++) {
             FieldMetadata field = (FieldMetadata) fields.get(i);
-            if (field.isUseful() &&  ! field.getSpecification().isInterface()) {
+            if (field.isUseful() && !field.getSpecification().isInterface()) {
                 Element prop = new Element("Property", "");
                 prop.addAttribute(new Attribute("field", field.getName()));
                 properties.addElement(prop);
@@ -299,7 +296,7 @@
 
         // Insert information to metadata
         elem.addElement(m_manipulationMetadata);
-        
+
         return elem;
     }
 
@@ -323,7 +320,7 @@
     private List getMethodList() {
         return m_specification.getMethods();
     }
-    
+
     /**
      * Store links between Field and pointed Specification.
      */

Copied: felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/ExportDescription.java (from r629467, felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/importer/ExportDescription.java)
URL: http://svn.apache.org/viewvc/felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/ExportDescription.java?p2=felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/ExportDescription.java&p1=felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/importer/ExportDescription.java&r1=629467&r2=631196&rev=631196&view=diff
==============================================================================
--- felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/importer/ExportDescription.java (original)
+++ felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/ExportDescription.java Tue Feb 26 04:20:30 2008
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.felix.ipojo.composite.service.importer;
+package org.apache.felix.ipojo.composite.service.provides;
 
 import java.util.List;
 
@@ -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,9 +58,9 @@
         for (int i = 0; i < m_exports.size(); i++) {
             ServiceExporter exp = (ServiceExporter) m_exports.get(i);
             Element expo = new Element("Exports", "");
-            expo.addAttribute(new Attribute("Specification", exp.getSpecification()));
+            expo.addAttribute(new Attribute("Specification", exp.getSpecification().getName()));
             expo.addAttribute(new Attribute("Filter", exp.getFilter()));
-            if (exp.isSatisfied()) {
+            if (exp.getState() == AbstractServiceDependency.RESOLVED) {
                 expo.addAttribute(new Attribute("State", "resolved"));
             } else {
                 expo.addAttribute(new Attribute("State", "unresolved"));

Modified: felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/MethodMetadata.java
URL: http://svn.apache.org/viewvc/felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/MethodMetadata.java?rev=631196&r1=631195&r2=631196&view=diff
==============================================================================
--- felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/MethodMetadata.java (original)
+++ felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/MethodMetadata.java Tue Feb 26 04:20:30 2008
@@ -70,34 +70,36 @@
     public FieldMetadata getDelegation() {
         return m_delegation;
     }
-
+    
     /**
-     * Check if two method metadata are equals.
-     * @param mm : the method metadata to compare with the current method metadata.
-     * @return true if the two method are equals
+     * Equals method.
+     * This method check if two MethodMetadata are equals or if the current MemethodMetadata is equals with a Method object. 
+     * @param o : object.
+     * @return true if the current object and the given object are equals.
+     * @see java.lang.Object#equals(java.lang.Object)
      */
-    public boolean equals(MethodMetadata mm) {
-        Method met = mm.getMethod();
-        return equals(met);
-    }
-
-    /**
-     * Equals method for Method object.
-     * @param met : the method object to compare.
-     * @return true if the given method signature is equals to the current method metadata.
-     */
-    public boolean equals(Method met) {
-        if (! met.getName().equals(m_method.getName()) || met.getParameterTypes().length != m_method.getParameterTypes().length) {
-            return false;
+    public boolean equals(Object o) {
+        if (o instanceof MethodMetadata) {
+            Method met = ((MethodMetadata) o).getMethod();
+            return equals(met);
         }
-
-        for (int i = 0; i < m_method.getParameterTypes().length; i++) {
-            if (!m_method.getParameterTypes()[i].getName().equals(met.getParameterTypes()[i].getName())) {
+        
+        if (o instanceof Method) {
+            Method met = (Method) o;
+            if (! met.getName().equals(m_method.getName()) || met.getParameterTypes().length != m_method.getParameterTypes().length) {
                 return false;
             }
-        }
 
-        return true;
+            for (int i = 0; i < m_method.getParameterTypes().length; i++) {
+                if (!m_method.getParameterTypes()[i].getName().equals(met.getParameterTypes()[i].getName())) {
+                    return false;
+                }
+            }
+
+            return true;
+        }
+        
+        return false;
     }
 
     public int getPolicy() {

Modified: felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedService.java
URL: http://svn.apache.org/viewvc/felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedService.java?rev=631196&r1=631195&r2=631196&view=diff
==============================================================================
--- felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedService.java (original)
+++ felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedService.java Tue Feb 26 04:20:30 2008
@@ -30,14 +30,18 @@
 import org.apache.felix.ipojo.composite.CompositeManager;
 import org.apache.felix.ipojo.composite.instance.InstanceHandler;
 import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.util.AbstractServiceDependency;
+import org.apache.felix.ipojo.util.DependencyLifecycleListener;
 import org.apache.felix.ipojo.util.Logger;
 import org.osgi.framework.BundleContext;
+import org.osgi.framework.Filter;
+import org.osgi.framework.InvalidSyntaxException;
 
 /**
  * Composite Provided Service.
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public class ProvidedService {
+public class ProvidedService implements DependencyLifecycleListener {
 
     /**
      * Composite Manager.
@@ -83,7 +87,7 @@
      * Exporter.
      */
     private ServiceExporter m_exports;
-    
+
     /**
      * Created instance name.
      */
@@ -110,7 +114,7 @@
      */
     public void start() throws CompositionException {
         m_composition.buildMapping();
-        
+
         m_instanceName = m_composition.getSpecificationMetadata().getName() + "Provider-Gen";
         m_clazz = m_composition.buildPOJO();
         m_metadata = m_composition.buildMetadata(m_instanceName);
@@ -123,10 +127,16 @@
         }
         m_factory.start();
 
-        // Create the exports
-        m_exports = new ServiceExporter(m_composition.getSpecificationMetadata().getName(), "(instance.name=" + m_instanceName + ")", false, false,
-                m_scope, m_context, this);
-        m_exports.start();
+        try {
+            Class spec = AbstractServiceDependency.loadSpecification(m_composition.getSpecificationMetadata().getName(), m_context);
+            Filter filter = m_context.createFilter("(instance.name=" + m_instanceName + ")");
+            // Create the exports
+            m_exports = new ServiceExporter(spec, filter, false, false, null, AbstractServiceDependency.DYNAMIC_BINDING_POLICY, m_scope, m_context, this, m_manager);
+        } catch (InvalidSyntaxException e) {
+            throw new CompositionException("A provided service filter is invalid : " + e.getMessage());
+        } catch (ConfigurationException e) {
+            throw new CompositionException("The class " + m_composition.getSpecificationMetadata().getName() + " cannot be loaded : " + e.getMessage());
+        }
     }
 
     /**
@@ -156,53 +166,14 @@
      * The exporter becomes valid.
      * @param exporter : the exporter
      */
-    public void validating(ServiceExporter exporter) {
+    public void validate(AbstractServiceDependency exporter) {
     }
 
     /**
      * The exporter becomes invalid.
      * @param exporter : the exporter
      */
-    public void invalidating(ServiceExporter exporter) {
-    }
-
-    /**
-     * Unregister published service.
-     */
-    protected void unregister() {
-        if (m_instance != null) {
-            m_instance.dispose();
-            m_instance = null;
-        }
-    }
-
-    /**
-     * Register published service.
-     */
-    protected void register() {
-        if (m_exports != null) {
-            if (m_instance != null) { m_instance.dispose(); }
-            Properties p = new Properties();
-            p.put("name", m_instanceName);
-            List fields = m_composition.getFieldList();
-            for (int i = 0; i < fields.size(); i++) {
-                FieldMetadata fm = (FieldMetadata) fields.get(i);
-                if (fm.isUseful() && !fm.getSpecification().isInterface()) {
-                    String type = fm.getSpecification().getComponentType();
-                    Object o = getObjectByType(type);
-                    p.put(fm.getName(), o); 
-                }
-            }
-            try {
-                m_instance = m_factory.createComponentInstance(p, m_manager.getServiceContext());
-            } catch (UnacceptableConfiguration e) {
-                e.printStackTrace();
-            } catch (MissingHandlerException e) {
-                e.printStackTrace();
-            } catch (ConfigurationException e) {
-                e.printStackTrace();
-            }
-        }
+    public void invalidate(AbstractServiceDependency exporter) {
     }
 
     /**
@@ -217,7 +188,6 @@
             m_manager.getFactory().getLogger().log(Logger.ERROR, "An instance object cannot be found for the type : " + type);
         }
         return o;
-        
     }
 
     public String getSpecification() {
@@ -225,14 +195,49 @@
     }
 
     /**
-     * Check the provided service state.
-     * @return true if the exporter is publishing.
+     * Unregister the exposed service.
      */
-    public boolean getState() {
-        if (m_exports != null && m_exports.isPublishing()) {
-            return true;
+    public void unregister() {
+        m_exports.stop();
+    }
+
+    /**
+     * Register the exposed service.
+     */
+    public void register() {
+        Properties p = new Properties();
+        p.put("name", m_instanceName);
+        List fields = m_composition.getFieldList();
+        for (int i = 0; i < fields.size(); i++) {
+            FieldMetadata fm = (FieldMetadata) fields.get(i);
+            if (fm.isUseful() && !fm.getSpecification().isInterface()) {
+                String type = fm.getSpecification().getComponentType();
+                Object o = getObjectByType(type);
+                p.put(fm.getName(), o);
+            }
+        }
+
+        if (m_instance != null) {
+            // We have to reconfigure the instance in order to inject up to date glue component instance.
+            m_instance.reconfigure(p);
+        } else {
+            // Else we have to create the instance 
+            try {
+                m_instance = m_factory.createComponentInstance(p, m_manager.getServiceContext());
+            } catch (UnacceptableConfiguration e) {
+                throw new IllegalStateException("Cannot create the service implementation : " + e.getMessage());
+            } catch (MissingHandlerException e) {
+                throw new IllegalStateException("Cannot create the service implementation : " + e.getMessage());
+            } catch (ConfigurationException e) {
+                throw new IllegalStateException("Cannot create the service implementation : " + e.getMessage());
+            }
         }
-        return false;
+
+        m_exports.start();
+    }
+
+    public boolean isRegistered() {
+        return m_exports.getState() == AbstractServiceDependency.RESOLVED;
     }
 
 }