Modify a little automatic requirement resolution on composite when the service specification contains service requirement.(Felix-311)

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@563117 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/ServiceRegistry.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/ServiceRegistry.java
index 6b94ddc..dc1b75c 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/ServiceRegistry.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/ServiceRegistry.java
@@ -245,7 +245,7 @@
                     return refs[0];
                 } // If the refs != null we are sure that it exists one reference or more.
             } catch (InvalidSyntaxException ex) {
-                System.err.println("Scope Service Registry : Problem when look for service reference" + ex.getMessage());
+                System.err.println("Scope Service Registry : Problem when looking for service reference" + ex.getMessage());
             }
             return null;
         }
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/instance/InstanceHandler.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/instance/InstanceHandler.java
index cd71882..07b01a0 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/instance/InstanceHandler.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/instance/InstanceHandler.java
@@ -113,7 +113,7 @@
 
         /**
          * Return the used factory name.
-         * @return the factory
+         * @return the factory name
          */
         String getFactory() {
             return m_factoryName;
@@ -426,5 +426,17 @@
         }
         return new InstanceHandlerDescription(InstanceHandler.class.getName(), m_validity, l);
     }
+    
+    /**
+     * Get the list of used component type.
+     * @return the list containing the used component type
+     */
+    public List getUsedType() {
+        List result = new ArrayList();
+        for (int i = 0; i < m_configurations.length; i++) {
+            result.add(m_configurations[i].getConfiguration().get("component"));
+        }
+        return result;
+    }
 
 }
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorHandler.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorHandler.java
index babcf56..e998b2a 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorHandler.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorHandler.java
@@ -181,4 +181,8 @@
     protected CompositeManager getManager() {
         return m_manager;
     }
+    
+    public List getInstances() {
+        return m_instances;
+    }
 }
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/SvcInstance.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/SvcInstance.java
index 6570fa9..aa0d866 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/SvcInstance.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/SvcInstance.java
@@ -383,6 +383,14 @@
     public String getSpecification() {
         return m_specification;
     }
+    
+    public boolean isAggregate() {
+        return m_isAggregate;
+    }
+    
+    public boolean isOptional() {
+        return m_isOptional;
+    }
 
     /**
      * Get the map of used references [reference, component instance].
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandler.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandler.java
index 2a2844f..b0b93a2 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandler.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandler.java
@@ -28,8 +28,11 @@
 import org.apache.felix.ipojo.CompositeManager;
 import org.apache.felix.ipojo.PolicyServiceContext;
 import org.apache.felix.ipojo.architecture.HandlerDescription;
+import org.apache.felix.ipojo.composite.instance.InstanceHandler;
 import org.apache.felix.ipojo.composite.service.importer.ImportExportHandler;
 import org.apache.felix.ipojo.composite.service.importer.ServiceImporter;
+import org.apache.felix.ipojo.composite.service.instantiator.ServiceInstantiatorHandler;
+import org.apache.felix.ipojo.composite.service.instantiator.SvcInstance;
 import org.apache.felix.ipojo.metadata.Element;
 import org.apache.felix.ipojo.parser.ManifestMetadataParser;
 import org.apache.felix.ipojo.parser.ParseException;
@@ -102,8 +105,8 @@
         }
 
         // Compute imports and instances
-        computeAvailableServices(metadata);
-        computeAvailableTypes(metadata);
+        computeAvailableServices();
+        computeAvailableTypes();
 
         
         im.register(this);
@@ -186,48 +189,29 @@
     }
 
     /**
-     * Build available specification.
-     * 
-     * @param metadata : composite metadata
+     * Build the list of available specifications.
      */
-    private void computeAvailableServices(Element metadata) {
+    private void computeAvailableServices() {
         // Get instantiated services :
-        Element[] services = metadata.getElements("service", "");
-        for (int i = 0; i < services.length; i++) {
-            String itf = services[i].getAttribute("specification");
-            boolean agg = false;
-            boolean opt = false;
-            if (services[i].containsAttribute("aggregate") && services[i].getAttribute("aggregate").equalsIgnoreCase("true")) {
-                agg = true;
-            }
-            if (services[i].containsAttribute("optional") && services[i].getAttribute("optional").equalsIgnoreCase("true")) {
-                opt = true;
-            }
+        ImportExportHandler ih = (ImportExportHandler) m_manager.getCompositeHandler(ImportExportHandler.class.getName());
+        ServiceInstantiatorHandler sh = (ServiceInstantiatorHandler) m_manager.getCompositeHandler(ServiceInstantiatorHandler.class.getName());
+        
+        for (int i = 0; sh != null && i < sh.getInstances().size(); i++) {
+            SvcInstance svc = (SvcInstance) sh.getInstances().get(i);
+            String itf = svc.getSpecification();
+            boolean agg = svc.isAggregate();
+            boolean opt = svc.isOptional();
+            
             SpecificationMetadata sm = new SpecificationMetadata(itf, m_context, agg, opt, this);
             m_services.add(sm);
         }
 
-        Element[] imports = metadata.getElements("requires", "");
-        
-        // DEPRECATED BLOCK:
-        if (imports.length == 0) {
-            imports = metadata.getElements("import");
-            if (imports.length != 0) {
-                m_manager.getFactory().getLogger().log(Logger.WARNING, "Import is deprecated, please use 'requires' instead of 'import'");
-            }
-        }
-        // END OF DEPRECATED BLOCK
-        
-        for (int i = 0; i < imports.length; i++) {
-            String itf = imports[i].getAttribute("specification");
-            boolean agg = false;
-            boolean opt = false;
-            if (imports[i].containsAttribute("aggregate") && imports[i].getAttribute("aggregate").equalsIgnoreCase("true")) {
-                agg = true;
-            }
-            if (imports[i].containsAttribute("optional") && imports[i].getAttribute("optional").equalsIgnoreCase("true")) {
-                opt = true;
-            }
+        for (int i = 0; ih != null && i < ih.getRequirements().size(); i++) {
+            ServiceImporter si = (ServiceImporter) ih.getRequirements().get(i);
+            String itf = si.getSpecification();
+            boolean agg = si.isAggregate();
+            boolean opt = si.isOptional();
+            
             SpecificationMetadata sm = new SpecificationMetadata(itf, m_context, agg, opt, this);
             m_services.add(sm);
         }
@@ -321,24 +305,34 @@
     private boolean isRequirementCorrect(ServiceImporter imp, Element elem) {
         boolean opt = false;
         if (elem.containsAttribute("optional") && elem.getAttribute("optional").equalsIgnoreCase("true")) {
-            opt = false;
+            opt = true;
         }
         
         boolean agg = false;
         if (elem.containsAttribute("aggregate") && elem.getAttribute("aggregate").equalsIgnoreCase("true")) {
-            agg = false;
+            agg = true;
         }
 
-        if (imp == null && !opt) {
+        if (imp == null) {
+            //TODO do we need to add the requirement for optional service-level dependency ?
             // Add the missing requirement
             ImportExportHandler ih = (ImportExportHandler) m_manager.getCompositeHandler(ImportExportHandler.class.getName());
+            if (ih == null) {
+                // Add the importer handler 
+                ih = new ImportExportHandler();
+                ih.configure(m_manager, new Element("composite", "") , null); // Enter fake info in the configure method.
+                m_manager.register(ih);
+            }
             String spec = elem.getAttribute("specification");
-            String filter = null;
+            String filter = "(&(objectClass=" + spec + ")(!(service.pid=" + m_manager.getInstanceName() + ")))"; // Cannot import yourself
             if (elem.containsAttribute("filter")) {
-                filter = elem.getAttribute("filter");
+                if (!elem.getAttribute("filter").equals("")) {
+                    filter = "(&" + filter + elem.getAttribute("filter") + ")";
+                }
             }
             ServiceImporter si = new ServiceImporter(spec, filter, agg, opt, m_manager.getContext(), m_manager.getServiceContext(), PolicyServiceContext.LOCAL, null, ih);
             ih.getRequirements().add(si);
+            return true;
         }
         
         if (imp.isAggregate() && !agg) {
@@ -363,16 +357,14 @@
     }
     
     /**
-     * Build available instance type.
-     * 
-     * @param metadata : composite metadata
+     * Build available instance types.
      */
-    private void computeAvailableTypes(Element metadata) {
-        m_types = new ArrayList();
-        Element[] instances = metadata.getElements("instance", "");
-        for (int i = 0; i < instances.length; i++) {
-            String itf = instances[i].getAttribute("component");
-            m_types.add(itf);
+    private void computeAvailableTypes() {
+        InstanceHandler ih = (InstanceHandler) m_manager.getCompositeHandler(InstanceHandler.class.getName());       
+        if (ih == null) {
+            m_types = new ArrayList();
+        } else {
+            m_types = ih.getUsedType();
         }
     }
 
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java
index 2b15082..2860048 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java
@@ -326,12 +326,12 @@
     private boolean isDependencyCorrect(Dependency dep, Element elem) {
         boolean opt = false;
         if (elem.containsAttribute("optional") && elem.getAttribute("optional").equalsIgnoreCase("true")) {
-            opt = false;
+            opt = true;
         }
         
         boolean agg = false;
         if (elem.containsAttribute("aggregate") && elem.getAttribute("aggregate").equalsIgnoreCase("true")) {
-            agg = false;
+            agg = true;
         }
 
         if (dep == null && !opt) {
@@ -340,12 +340,12 @@
         }
         
         
-        if (dep.isAggregate() && !agg) {
+        if (dep != null && dep.isAggregate() && !agg) {
             m_manager.getFactory().getLogger().log(Logger.ERROR, "[" + m_manager.getClassName() + "] The requirement " + elem.getAttribute("specification") + " is aggregate in the implementation and is declared as a simple service-level requirement");
             return false;
         }
       
-        if (elem.containsAttribute("filter")) {
+        if (dep != null && elem.containsAttribute("filter")) {
             String filter = elem.getAttribute("filter");
             String filter2 = dep.getFilter();
             if (filter2 == null || !filter2.equalsIgnoreCase(filter)) {