felix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From clem...@apache.org
Subject svn commit: r562430 - in /felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo: ./ composite/service/importer/ composite/service/provides/ handlers/dependency/ handlers/providedservice/ parser/
Date Fri, 03 Aug 2007 12:24:54 GMT
Author: clement
Date: Fri Aug  3 05:24:51 2007
New Revision: 562430

URL: http://svn.apache.org/viewvc?view=rev&rev=562430
Log:
Add scoping features for service requirement resolving.
This feature can be used both for primitive component requirement and for composite requirement. A requirement can now be solved in the global (i.e. OSGi) service registry instead of inside the composite.
(Felix-311)

Added:
    felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/PolicyServiceContext.java
Modified:
    felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/ComponentFactory.java
    felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/CompositeManager.java
    felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoContext.java
    felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceManager.java
    felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportExportHandler.java
    felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ServiceImporter.java
    felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/CompositionMetadata.java
    felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandler.java
    felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java
    felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyDescription.java
    felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java
    felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandlerDescription.java
    felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedService.java
    felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java
    felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandlerDescription.java
    felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/ParseUtils.java

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/ComponentFactory.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/ComponentFactory.java?view=diff&rev=562430&r1=562429&r2=562430
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/ComponentFactory.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/ComponentFactory.java Fri Aug  3 05:24:51 2007
@@ -91,7 +91,7 @@
     private FactoryClassloader m_classLoader = null;
 
     /**
-     * Component Type provided by this factory. //TODO Should be keep this
+     * Component Type provided by this factory. //TODO Should we keep this ?
      * reference ?
      */
     private Element m_componentMetadata;
@@ -347,13 +347,13 @@
 
         // create a ghost component
         if (!m_isComposite) {
-            final InstanceManager ghost = new InstanceManager(this, m_context);
+            final InstanceManager ghost = new InstanceManager(this, new IPojoContext(m_context));
             final Properties p = new Properties();
             p.put("name", "ghost");
             ghost.configure(m_componentMetadata, p);
             m_componentDesc = ghost.getComponentDescription();
         } else {
-            final CompositeManager ghost = new CompositeManager(this, m_context);
+            final CompositeManager ghost = new CompositeManager(this, new IPojoContext(m_context));
             final Properties p = new Properties();
             p.put("name", "ghost");
             ghost.configure(m_componentMetadata, p);

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/CompositeManager.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/CompositeManager.java?view=diff&rev=562430&r1=562429&r2=562430
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/CompositeManager.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/CompositeManager.java Fri Aug  3 05:24:51 2007
@@ -521,4 +521,22 @@
     public ServiceContext getServiceContext() {
         return m_internalContext;
     }
+
+    /**
+     * Get the global bundle context.
+     * @return the global bundle context.
+     */
+    public BundleContext getGlobalContext() {
+        IPojoContext c = (IPojoContext) m_context;
+        return c.getGlobalContext();
+    }
+    
+    /**
+     * Get the parent service context.
+     * @return the parent service context.
+     */
+    public ServiceContext getParentServiceContext() {
+        IPojoContext c = (IPojoContext) m_context;
+        return c.getServiceContext();
+    }
 }

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoContext.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoContext.java?view=diff&rev=562430&r1=562429&r2=562430
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoContext.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoContext.java Fri Aug  3 05:24:51 2007
@@ -309,5 +309,13 @@
     public BundleContext getGlobalContext() {
         return m_bundleContext;
     }
+    
+    /**
+     * Get the service context, i.e. the composite context.
+     * @return the service context.
+     */
+    public ServiceContext getServiceContext() {
+        return m_serviceContext;
+    }
 
 }

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceManager.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceManager.java?view=diff&rev=562430&r1=562429&r2=562430
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceManager.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceManager.java Fri Aug  3 05:24:51 2007
@@ -851,6 +851,14 @@
     public BundleContext getContext() {
         return m_context;
     }
+    
+    public BundleContext getGlobalContext() {
+        return ((IPojoContext) m_context).getGlobalContext();
+    }
+    
+    public ServiceContext getLocalServiceContext() {
+        return ((IPojoContext) m_context).getServiceContext();
+    }
 
     /**
      * Check the state of all handlers.

Added: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/PolicyServiceContext.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/PolicyServiceContext.java?view=auto&rev=562430
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/PolicyServiceContext.java (added)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/PolicyServiceContext.java Fri Aug  3 05:24:51 2007
@@ -0,0 +1,297 @@
+/* 
+ * 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;
+
+import org.apache.felix.ipojo.composite.ServiceReferenceImpl;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+
+/**
+ * The policy service context is a service context aiming to solve service requirement.
+ * It's parameterized by a resolving policy. Three policies are managed : 
+ * - Local : services are only solve un the local service registry
+ * - Global : services are resolved only in the global (i.e. OSGi) service registry
+ * - Local and Global : services are resolved inside the local registry and the global registry  
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class PolicyServiceContext implements ServiceContext {
+    
+    /**
+     * Resolving policy, look only in the composite.
+     */
+    public static final int LOCAL = 0;
+    
+    /**
+     * Resolving policy, look inside the composite and in the global scope.
+     * This policy is the default one for implementation dependency.
+     */
+    public static final int LOCAL_AND_GLOBAL = 1;
+    
+    /**
+     * Resolving policy, look inside the global only.
+     */
+    public static final int GLOBAL = 2;
+    
+    /**
+     * Global service registry.
+     */
+    private BundleContext m_global;
+    
+    /**
+     * Local (Composite) Service Registry.
+     */
+    private ServiceContext m_local;
+    
+    /**
+     * Resolving policy.
+     */
+    private int m_policy = LOCAL_AND_GLOBAL;
+    
+    
+    /**
+     * Create a new PolicyServiceContext.
+     * @param global : global bundle context
+     * @param local : parent (local) service context
+     * @param policy : resolution policy
+     */
+    public PolicyServiceContext(BundleContext global, ServiceContext local, int policy) {
+        m_global = global;
+        m_local = local;
+        m_policy = policy;
+    }
+
+    /**
+     * Add a service listener according to the policy.
+     * @param listener : the listener to add
+     * @param filter : LDAP filter
+     * @throws InvalidSyntaxException occurs when the filter is malformed.
+     * @see org.apache.felix.ipojo.ServiceContext#addServiceListener(org.osgi.framework.ServiceListener, java.lang.String)
+     */
+    public void addServiceListener(ServiceListener listener, String filter) throws InvalidSyntaxException {
+        if (m_policy == LOCAL || m_policy == LOCAL_AND_GLOBAL) {
+            m_local.addServiceListener(listener, filter);
+        }
+        if (m_policy == GLOBAL || m_policy == LOCAL_AND_GLOBAL) {
+            m_global.addServiceListener(listener, filter);
+        }
+
+    }
+
+    /**
+     * Add a service listener according to the policy.
+     * @param listener : the listener to add
+     * @see org.apache.felix.ipojo.ServiceContext#addServiceListener(org.osgi.framework.ServiceListener)
+     */
+    public void addServiceListener(ServiceListener listener) {
+        if (m_policy == LOCAL || m_policy == LOCAL_AND_GLOBAL) {
+            m_local.addServiceListener(listener);
+        }
+        if (m_policy == GLOBAL || m_policy == LOCAL_AND_GLOBAL) {
+            m_global.addServiceListener(listener);
+        }
+    }
+
+    /**
+     * Get all service references. These reference are found inside the local registry, global registry or both according to the policy.
+     * @param clazz : required service specification.
+     * @param filter : LDAP filter
+     * @return the array of service reference, null if no service available
+     * @throws InvalidSyntaxException occurs when the LDAP filter is malformed 
+     * @see org.apache.felix.ipojo.ServiceContext#getAllServiceReferences(java.lang.String, java.lang.String)
+     */
+    public ServiceReference[] getAllServiceReferences(String clazz,
+            String filter) throws InvalidSyntaxException {
+        switch (m_policy) {
+            case LOCAL:
+                return m_local.getAllServiceReferences(clazz, filter);
+            case GLOBAL:
+                return m_global.getAllServiceReferences(clazz, filter);
+            case LOCAL_AND_GLOBAL:
+                ServiceReference[] refLocal = m_local.getAllServiceReferences(clazz, filter);
+                ServiceReference[] refGlobal = m_global.getAllServiceReferences(clazz, filter);
+                if (refLocal != null && refGlobal != null) {
+                    ServiceReference[] refs = new ServiceReference[refLocal.length + refGlobal.length];
+                    int j = 0;
+                    for (int i = 0; i < refLocal.length; i++) {
+                        refs[j] = refLocal[i];
+                        j++;
+                    }
+                    for (int i = 0; i < refGlobal.length; i++) {
+                        refs[j] = refGlobal[i];
+                        j++;
+                    }
+                    return refs;
+                } else if (refLocal != null && refGlobal == null) {
+                    return refLocal;
+                } else {
+                    return refGlobal;
+                }
+            default:
+                return null;
+        }
+    }
+
+    /**
+     * Get the service object for the given reference.
+     * @param ref : the service reference
+     * @return the service object
+     * @see org.apache.felix.ipojo.ServiceContext#getService(org.osgi.framework.ServiceReference)
+     */
+    public Object getService(ServiceReference ref) {
+        switch(m_policy) {
+            case LOCAL:
+                // The reference comes from the local scope
+                return m_local.getService(ref);
+            case GLOBAL:
+                // The reference comes from the global registry
+                return m_global.getService(ref);
+            case LOCAL_AND_GLOBAL:
+                if (ref instanceof org.apache.felix.ipojo.composite.ServiceReferenceImpl) {
+                    // The reference comes from a composite, i.e. necessary the local composite
+                    return m_local.getService(ref);
+                } else {
+                    return m_global.getService(ref);
+                }
+            default : 
+                return null;
+        }
+    }
+
+    /**
+     * Get a service reference for the required service specification.
+     * @param clazz : the required service specification
+     * @return a service reference or null if not consistent service available
+     * @see org.apache.felix.ipojo.ServiceContext#getServiceReference(java.lang.String)
+     */
+    public ServiceReference getServiceReference(String clazz) {
+        switch (m_policy) {
+            case LOCAL:
+                return m_local.getServiceReference(clazz);
+            case GLOBAL:
+                return m_global.getServiceReference(clazz);
+            case LOCAL_AND_GLOBAL:
+                ServiceReference refLocal = m_local.getServiceReference(clazz);
+                if (refLocal != null) {
+                    return refLocal;
+                } else {
+                    return m_global.getServiceReference(clazz); 
+                }
+            default:
+                return null;
+        }
+    }
+
+    /**
+     * Get a service reference for the required service specification.
+     * @param clazz : the required service specification
+     * @param filter : LDAP filter
+     * @return a service reference array or null if not consistent service available
+     * @throws InvalidSyntaxException occurs when the LDAP filter is malformed 
+     * @see org.apache.felix.ipojo.ServiceContext#getServiceReference(java.lang.String)
+     */
+    public ServiceReference[] getServiceReferences(String clazz, String filter) throws InvalidSyntaxException {
+        switch (m_policy) {
+            case LOCAL:
+                return m_local.getServiceReferences(clazz, filter);
+            case GLOBAL:
+                return m_global.getServiceReferences(clazz, filter);
+            case LOCAL_AND_GLOBAL:
+                ServiceReference[] refLocal = m_local.getServiceReferences(clazz, filter);
+                ServiceReference[] refGlobal = m_global.getServiceReferences(clazz, filter);
+                if (refLocal != null && refGlobal != null) {
+                    ServiceReference[] refs = new ServiceReference[refLocal.length + refGlobal.length];
+                    int j = 0;
+                    for (int i = 0; i < refLocal.length; i++) {
+                        refs[j] = refLocal[i];
+                        j++;
+                    }
+                    for (int i = 0; i < refGlobal.length; i++) {
+                        refs[j] = refGlobal[i];
+                        j++;
+                    }
+                    return refs;
+                } else if (refLocal != null && refGlobal == null) {
+                    return refLocal;
+                } else {
+                    return refGlobal;
+                }
+            default:
+                return null;
+        }
+
+    }
+
+    /**
+     * This method is not supported.
+     * @param clazzes : specifications
+     * @param service : service object
+     * @param properties : service properties
+     * @return : the service registration object
+     * @see org.apache.felix.ipojo.ServiceContext#registerService(java.lang.String[], java.lang.Object, java.util.Dictionary)
+     */
+    public ServiceRegistration registerService(String[] clazzes, Object service, Dictionary properties) {
+        throw new UnsupportedOperationException("PolicyServiceContext can only be used for service dependency and not service providing");
+    }
+
+    /**
+     * This method is not supported.
+     * @param clazz : specification
+     * @param service : service object
+     * @param properties : service properties
+     * @return : the service registration object
+     * @see org.apache.felix.ipojo.ServiceContext#registerService(java.lang.String, java.lang.Object, java.util.Dictionary)
+     */
+    public ServiceRegistration registerService(String clazz, Object service, Dictionary properties) {
+        throw new UnsupportedOperationException("PolicyServiceContext can only be used for service dependency and not service providing");
+    }
+
+    /**
+     * Remove a service listener.
+     * @param listener : the service listener to remove
+     * @see org.apache.felix.ipojo.ServiceContext#removeServiceListener(org.osgi.framework.ServiceListener)
+     */
+    public void removeServiceListener(ServiceListener listener) {
+        if (m_policy == LOCAL || m_policy == LOCAL_AND_GLOBAL) {
+            m_local.removeServiceListener(listener);
+        }
+        if (m_policy == GLOBAL || m_policy == LOCAL_AND_GLOBAL) {
+            m_global.removeServiceListener(listener);
+        }
+    }
+
+    /**
+     * Unget the service reference.
+     * @param reference : the service reference to unget.
+     * @return true if the unget is successful.
+     * @see org.apache.felix.ipojo.ServiceContext#ungetService(org.osgi.framework.ServiceReference)
+     */
+    public boolean ungetService(ServiceReference reference) {
+        if (reference instanceof ServiceReferenceImpl) {
+            return m_local.ungetService(reference);
+        } else {
+            return m_global.ungetService(reference);
+        }
+    }
+
+}

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportExportHandler.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportExportHandler.java?view=diff&rev=562430&r1=562429&r2=562430
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportExportHandler.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportExportHandler.java Fri Aug  3 05:24:51 2007
@@ -24,6 +24,7 @@
 
 import org.apache.felix.ipojo.CompositeHandler;
 import org.apache.felix.ipojo.CompositeManager;
+import org.apache.felix.ipojo.PolicyServiceContext;
 import org.apache.felix.ipojo.ServiceContext;
 import org.apache.felix.ipojo.architecture.HandlerDescription;
 import org.apache.felix.ipojo.metadata.Element;
@@ -116,7 +117,24 @@
                         filter = "(&" + filter + imp[i].getAttribute("filter") + ")";
                     }
                 }
-                ServiceImporter si = new ServiceImporter(specification, filter, aggregate, optional, m_context, m_scope, this);
+                
+                String id = null;
+                if (imp[i].containsAttribute("id")) {
+                    id = imp[i].getAttribute("id");
+                }
+                
+                int scopePolicy = -1;
+                if (imp[i].containsAttribute("scope")) {
+                    if (imp[i].getAttribute("scope").equalsIgnoreCase("global")) {
+                        scopePolicy = PolicyServiceContext.GLOBAL;
+                    } else if (imp[i].getAttribute("scope").equalsIgnoreCase("composite")) {
+                        scopePolicy = PolicyServiceContext.LOCAL;
+                    } else if (imp[i].getAttribute("scope").equalsIgnoreCase("composite+global")) {
+                        scopePolicy = PolicyServiceContext.LOCAL_AND_GLOBAL;
+                    }                
+                }
+                
+                ServiceImporter si = new ServiceImporter(specification, filter, aggregate, optional, m_context, m_scope, scopePolicy, id, this);
                 m_importers.add(si);
             }
         }
@@ -286,5 +304,9 @@
      */
     public HandlerDescription getDescription() {
         return new ImportExportDescription(this.getClass().getName(), isValid(), m_importers, m_exporters);
+    }
+    
+    public List getRequirements() {
+        return m_importers;
     }
 }

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ServiceImporter.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ServiceImporter.java?view=diff&rev=562430&r1=562429&r2=562430
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ServiceImporter.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ServiceImporter.java Fri Aug  3 05:24:51 2007
@@ -23,6 +23,7 @@
 import java.util.List;
 import java.util.Properties;
 
+import org.apache.felix.ipojo.PolicyServiceContext;
 import org.apache.felix.ipojo.ServiceContext;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
@@ -46,9 +47,9 @@
     private ServiceContext m_destination;
 
     /**
-     * Origin Context.
+     * Context where service need to be found. 
      */
-    private BundleContext m_origine;
+    private ServiceContext m_origin;
 
     /**
      * Imported Specification.
@@ -79,6 +80,11 @@
      * Is the importer valid?
      */
     private boolean m_isValid;
+    
+    /**
+     * Resolving policy.
+     */
+    private int m_policy;
 
     /**
      * Reference on the handler.
@@ -106,6 +112,16 @@
     private List/*<Record>*/m_records = new ArrayList()/* <Record> */;
 
     /**
+     * Requirement Id.
+     */
+    private String m_id;
+
+    /**
+     * Is this requirement attached to a service-level requirement.
+     */
+    private boolean m_isServiceLevelRequirement;
+
+    /**
      * Constructor.
      * 
      * @param specification : targeted specification
@@ -114,12 +130,13 @@
      * @param optional : is the import optional ?
      * @param from : parent context
      * @param to : internal context
+     * @param policy : resolving policy
+     * @param id : requirement id (may be null)
      * @param in : handler
      */
-    public ServiceImporter(String specification, String filter, boolean multiple, boolean optional, BundleContext from, ServiceContext to,
+    public ServiceImporter(String specification, String filter, boolean multiple, boolean optional, BundleContext from, ServiceContext to, int policy, String id,
             ImportExportHandler in) {
         this.m_destination = to;
-        this.m_origine = from;
         try {
             this.m_filter = from.createFilter(filter);
         } catch (InvalidSyntaxException e) {
@@ -130,6 +147,18 @@
         this.m_specification = specification;
         this.m_optional = optional;
         this.m_handler = in;
+        
+        if (m_id == null) {
+            m_id = m_specification;
+        } else {
+            m_id = id;
+        }
+        
+        if (policy == -1) {
+            m_policy = PolicyServiceContext.LOCAL_AND_GLOBAL;  
+        } else {
+            m_policy = policy;
+        }
     }
 
     /**
@@ -137,7 +166,8 @@
      */
     public void start() {
         try {
-            ServiceReference[] refs = m_origine.getServiceReferences(m_specification, null);
+            m_origin = new PolicyServiceContext(m_handler.getManager().getGlobalContext(), m_handler.getManager().getParentServiceContext(), m_policy);
+            ServiceReference[] refs = m_origin.getServiceReferences(m_specification, null);
             if (refs != null) {
                 for (int i = 0; i < refs.length; i++) {
                     if (m_filter.match(refs[i])) {
@@ -156,19 +186,19 @@
             if (m_aggregate) {
                 for (int i = 0; i < m_records.size(); i++) {
                     Record rec = (Record) m_records.get(i);
-                    rec.m_svcObject = m_origine.getService(rec.m_ref);
+                    rec.m_svcObject = m_origin.getService(rec.m_ref);
                     rec.m_reg = m_destination.registerService(m_specification, rec.m_svcObject, getProps(rec.m_ref));
                 }
             } else {
                 Record rec = (Record) m_records.get(0);
-                rec.m_svcObject = m_origine.getService(rec.m_ref);
+                rec.m_svcObject = m_origin.getService(rec.m_ref);
                 rec.m_reg = m_destination.registerService(m_specification, rec.m_svcObject, getProps(rec.m_ref));
             }
         }
 
         // Register service listener
         try {
-            m_origine.addServiceListener(this, "(" + Constants.OBJECTCLASS + "=" + m_specification + ")");
+            m_origin.addServiceListener(this, "(" + Constants.OBJECTCLASS + "=" + m_specification + ")");
         } catch (InvalidSyntaxException e) {
             e.printStackTrace();
         }
@@ -196,14 +226,14 @@
      */
     public void stop() {
 
-        m_origine.removeServiceListener(this);
+        m_origin.removeServiceListener(this);
 
         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_origine.ungetService(rec.m_ref);
+                m_origin.ungetService(rec.m_ref);
                 rec.m_ref = null;
             }
         }
@@ -286,7 +316,7 @@
             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_origine.getService(rec.m_ref);
+                rec.m_svcObject = m_origin.getService(rec.m_ref);
                 rec.m_reg = m_destination.registerService(m_specification, rec.m_svcObject, getProps(rec.m_ref));
             }
             // Compute the new state
@@ -310,7 +340,7 @@
                 rec.m_svcObject = null;
                 rec.m_reg.unregister();
                 rec.m_reg = null;
-                m_origine.ungetService(rec.m_ref);
+                m_origin.ungetService(rec.m_ref);
             }
         }
         m_records.removeAll(l);
@@ -321,7 +351,7 @@
             if (!m_aggregate) { // Import the next one
                 Record rec = (Record) m_records.get(0);
                 if (rec.m_svcObject == null) { // It is the first service which disappears - create the next one
-                    rec.m_svcObject = m_origine.getService(rec.m_ref);
+                    rec.m_svcObject = m_origin.getService(rec.m_ref);
                     rec.m_reg = m_destination.registerService(m_specification, rec.m_svcObject, getProps(rec.m_ref));
                 }
             }
@@ -352,6 +382,32 @@
 
     public String getFilter() {
         return m_filterStr;
+    }
+    
+    /**
+     * Set that this dependency is a service level dependency.
+     * This forces the scoping policy to be STRICT. 
+     * @param b
+     */
+    public void setServiceLevelDependency() {
+        m_isServiceLevelRequirement = true;
+        m_policy = PolicyServiceContext.LOCAL;
+    }
+
+    public String getId() {
+        return m_id;
+    }
+    
+    public boolean isServiceLevelRequirement() {
+        return m_isServiceLevelRequirement;
+    }
+    
+    public boolean isAggregate() {
+        return m_aggregate;
+    }
+    
+    public boolean isOptional() {
+        return m_optional;
     }
 
 }

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/CompositionMetadata.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/CompositionMetadata.java?view=diff&rev=562430&r1=562429&r2=562430
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/CompositionMetadata.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/CompositionMetadata.java Fri Aug  3 05:24:51 2007
@@ -88,7 +88,7 @@
 
         // 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; i < mappings.length; i++) {
@@ -270,6 +270,7 @@
             if (field.isUseful() && field.getSpecification().isInterface()) {
                 Element dep = new Element("requires", "");
                 dep.addAttribute(new Attribute("field", field.getName()));
+                dep.addAttribute(new Attribute("scope", "composite"));
                 if (field.getSpecification().isOptional()) {
                     dep.addAttribute(new Attribute("optional", "true"));
                 }

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandler.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandler.java?view=diff&rev=562430&r1=562429&r2=562430
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandler.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandler.java Fri Aug  3 05:24:51 2007
@@ -18,6 +18,7 @@
  */
 package org.apache.felix.ipojo.composite.service.provides;
 
+import java.lang.reflect.Field;
 import java.util.ArrayList;
 import java.util.Dictionary;
 import java.util.List;
@@ -25,8 +26,13 @@
 import org.apache.felix.ipojo.ComponentInstance;
 import org.apache.felix.ipojo.CompositeHandler;
 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.service.importer.ImportExportHandler;
+import org.apache.felix.ipojo.composite.service.importer.ServiceImporter;
 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.Logger;
 import org.osgi.framework.BundleContext;
 
@@ -84,22 +90,27 @@
         if (provides.length == 0) {
             return;
         }
-
-        // Compute imports and instances
-        computeAvailableServices(metadata);
-        computeAvailableTypes(metadata);
-
+        
         for (int i = 0; i < provides.length; i++) {
             ProvidedService ps = new ProvidedService(this, provides[i], "" + i);
             m_managedServices.add(ps);
+            // Check requirements against the service specification
+            if (!checkServiceSpecification(ps)) {
+                return;
+            }
             im.getComponentDescription().addProvidedServiceSpecification(ps.getSpecification());
         }
 
+        // Compute imports and instances
+        computeAvailableServices(metadata);
+        computeAvailableTypes(metadata);
+
+        
         im.register(this);
     }
 
     /**
-     * Start metod.
+     * Start method.
      * Start all managed provided service.
      * @see org.apache.felix.ipojo.CompositeHandler#start()
      */
@@ -128,7 +139,7 @@
 
     /**
      * Stop method.
-     * Stop all managedprovided service.
+     * Stop all managed provided service.
      * @see org.apache.felix.ipojo.CompositeHandler#stop()
      */
     public void stop() {
@@ -220,6 +231,131 @@
             SpecificationMetadata sm = new SpecificationMetadata(itf, m_context, agg, opt, this);
             m_services.add(sm);
         }
+    }
+    
+    /**
+     * Check composite requirement against service specification requirement is available.
+     * @param ps : the provided service to check
+     * @return true if the composite is a correct implementation of the service
+     */
+    private boolean checkServiceSpecification(ProvidedService ps) {
+        try {
+            Class spec = m_manager.getFactory().loadClass(ps.getSpecification());
+            Field specField = spec.getField("specification");     
+            Object o = specField.get(null);
+            if (!(o instanceof String)) {
+                m_manager.getFactory().getLogger().log(Logger.ERROR, "[" + m_manager.getInstanceName() + "] The specification field of the service specification " + ps.getSpecification() + " need to be a String");                                                                                                                                                                    
+                return false;
+            } else {
+                Element specification = ManifestMetadataParser.parse((String) o);
+                Element[] reqs = specification.getElements("requires");
+                for (int j = 0; j < reqs.length; j++) {
+                    ServiceImporter imp = getAttachedRequirement(reqs[j]);
+                    if (imp != null) {
+                        // Fix service-level dependency flag
+                        imp.setServiceLevelDependency();
+                    }
+                    if (!isRequirementCorrect(imp, reqs[j])) {
+                        return false;
+                    }
+                }
+            }
+        } catch (NoSuchFieldException e) {
+            return true;  // No specification field
+        } catch (ClassNotFoundException e) {
+            m_manager.getFactory().getLogger().log(Logger.ERROR, "[" + m_manager.getInstanceName() + "] The service specification " + ps.getSpecification() + " cannot be load");                                                                                                                                                                    
+            return false;
+        } catch (IllegalArgumentException e) {
+            m_manager.getFactory().getLogger().log(Logger.ERROR, "[" + m_manager.getInstanceName() + "] The field 'specification' of the service specification " + ps.getSpecification() + " is not accessible : " + e.getMessage());                                                                                                                                                                    
+            return false;
+        } catch (IllegalAccessException e) {
+            m_manager.getFactory().getLogger().log(Logger.ERROR, "[" + m_manager.getInstanceName() + "] The field 'specification' of the service specification " + ps.getSpecification() + " is not accessible : " + e.getMessage());                                                                                                                                                                    
+            return false;
+        } catch (ParseException e) {
+            m_manager.getFactory().getLogger().log(Logger.ERROR, "[" + m_manager.getInstanceName() + "] The field 'specification' of the service specification " + ps.getSpecification() + " does not contain a valid String : " + e.getMessage());                                                                                                                                                                    
+            return false;
+        }
+        return true;
+    }
+    
+    /**
+     * Look for the implementation (i.e. composite) requirement for the given service-level requirement metadata.
+     * @param element : the service-level requirement metadata
+     * @return the ServiceImporter object, null if not found or if the DependencyHandler is not plugged to the instance
+     */
+    private ServiceImporter getAttachedRequirement(Element element) {
+        ImportExportHandler ih = (ImportExportHandler) m_manager.getCompositeHandler(ImportExportHandler.class.getName());
+        if (ih == null) { 
+            return null;
+        }
+        
+        if (element.containsAttribute("id")) {
+            // Look for dependency Id
+            String id = element.getAttribute("id");
+            for (int i = 0; i < ih.getRequirements().size(); i++) {
+                ServiceImporter imp = (ServiceImporter) ih.getRequirements().get(i);
+                if (imp.getId().equals(id)) {
+                    return imp; 
+                }
+            }
+        }
+        
+        // If not found or no id, look for a dependency with the same specification
+        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; 
+            }
+        }
+        
+        return null;
+    }
+    
+    /**
+     * Check the correctness of the composite requirement against the service level dependency.
+     * @param imp : requirement to check
+     * @param elem : service-level dependency metadata
+     * @return true if the dependency is correct, false otherwise
+     */
+    private boolean isRequirementCorrect(ServiceImporter imp, Element elem) {
+        boolean opt = false;
+        if (elem.containsAttribute("optional") && elem.getAttribute("optional").equalsIgnoreCase("true")) {
+            opt = false;
+        }
+        
+        boolean agg = false;
+        if (elem.containsAttribute("aggregate") && elem.getAttribute("aggregate").equalsIgnoreCase("true")) {
+            agg = false;
+        }
+
+        if (imp == null && !opt) {
+            // Add the missing requirement
+            ImportExportHandler ih = (ImportExportHandler) m_manager.getCompositeHandler(ImportExportHandler.class.getName());
+            String spec = elem.getAttribute("specification");
+            String filter = null;
+            if (elem.containsAttribute("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);
+        }
+        
+        if (imp.isAggregate() && !agg) {
+            getManager().getFactory().getLogger().log(Logger.ERROR, "[" + getManager().getInstanceName() + "] 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")) {
+            String filter = elem.getAttribute("filter");
+            String filter2 = imp.getFilter();
+            if (filter2 == null || !filter2.equalsIgnoreCase(filter)) {
+                getManager().getFactory().getLogger().log(Logger.ERROR, "[" + getManager().getInstanceName() + "] The specification requirement " + elem.getAttribute("specification") + " as not the same filter as declared in the service-level requirement");
+                return false;
+            }
+        }
+        
+        return true;
     }
 
     public HandlerDescription getDescription() {

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java?view=diff&rev=562430&r1=562429&r2=562430
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java Fri Aug  3 05:24:51 2007
@@ -20,10 +20,14 @@
 
 import java.lang.reflect.Array;
 import java.lang.reflect.InvocationTargetException;
-import java.util.HashMap;
-import java.util.Map;
+import java.util.ArrayList;
+import java.util.List;
 
+import org.apache.felix.ipojo.IPojoContext;
 import org.apache.felix.ipojo.InstanceManager;
+import org.apache.felix.ipojo.PolicyServiceContext;
+import org.apache.felix.ipojo.ServiceContext;
+import org.apache.felix.ipojo.composite.CompositeServiceContext;
 import org.apache.felix.ipojo.util.Logger;
 import org.osgi.framework.Filter;
 import org.osgi.framework.InvalidSyntaxException;
@@ -67,6 +71,11 @@
      * 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 ?
@@ -82,6 +91,16 @@
      * 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 Objects. When cardinality = 1 : just the first element
@@ -91,13 +110,19 @@
     private Object[] m_services = new Object[0];
 
     /**
-     * Array of service references. m_ref : Array
+     * Array of service references.
+     * m_ref : Array
+     */
+    private List m_references = new ArrayList();
+    
+    /**
+     * Array of service reference containing used service references. 
      */
-    private ServiceReference[] m_ref = new ServiceReference[0];
+    private List m_usedReferences = new ArrayList();
 
     /**
-     * State of the dependency. 0 : stopped, 1 : valid, 2 : invalid. m_state :
-     * int
+     * State of the dependency. 0 : stopped, 1 : valid, 2 : invalid. 
+     * m_state : int
      */
     private int m_state;
 
@@ -108,8 +133,8 @@
     private boolean m_change;
 
     /**
-     * Class of the dependency. Usefull to create in the case of multiple
-     * dependency
+     * Class of the dependency. 
+     * Useful to create in the case of multiple dependency
      */
     private Class m_clazz;
 
@@ -117,9 +142,14 @@
      * LDAP Filter of the dependency.
      */
     private Filter m_filter;
+    
+    /**
+     * Service Context in which resolving the dependency.
+     */
+    private ServiceContext m_serviceContext;
 
     /**
-     * Dependency contructor. After the creation the dependency is not started.
+     * Dependency constructor. After the creation the dependency is not started.
      * 
      * @param dh : the dependency handler managing this dependency
      * @param field : field of the dependency
@@ -127,14 +157,29 @@
      * @param filter : LDAP filter of the dependency
      * @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 policy : resolution policy
      */
-    public Dependency(DependencyHandler dh, String field, String spec, String filter, boolean isOptional, boolean isAggregate) {
+    public Dependency(DependencyHandler dh, String field, String spec, String filter, boolean isOptional, boolean isAggregate, String id, int policy) {
         m_handler = dh;
         m_field = field;
         m_specification = spec;
         m_isOptional = isOptional;
         m_strFilter = filter;
         m_isAggregate = isAggregate;
+        if (m_id == null) {
+            m_id = m_specification;
+        } else {
+            m_id = id;
+        }
+        if (policy != -1) {
+            m_policy = policy;
+        }
+        // Fix the policy according to the level
+        if ((m_policy == PolicyServiceContext.LOCAL_AND_GLOBAL || m_policy == PolicyServiceContext.LOCAL) && ! ((((IPojoContext) m_handler.getInstanceManager().getContext()).getServiceContext()) instanceof CompositeServiceContext)) {
+            // We are not in a composite : BOTH | STRICT => GLOBAL
+            m_policy = PolicyServiceContext.GLOBAL;
+        }
     }
 
     public String getField() {
@@ -199,32 +244,29 @@
     }
 
     /**
-     * Build the map [service object, service reference] of used services.
+     * Build the List [service reference] of used services.
      * @return the used service.
      */
-    public Map getUsedServices() {
-        Map hm = new HashMap();
+    public List getUsedServices() {
+        List list = new ArrayList();
         if (m_isAggregate) {
-            for (int i = 0; i < m_ref.length; i++) {
-                if (i < m_services.length) {
-                    hm.put(((Object) m_services[i]).toString(), m_ref[i]);
-                }
-            }
+            list.addAll(m_usedReferences);
+            return list;
         } else {
-            if (m_ref.length != 0 && m_services.length != 0) {
-                hm.put((m_services[0]).toString(), m_ref[0]);
-            }
+            if (m_usedReferences.size() != 0 && m_services.length != 0) {
+                list.add(m_usedReferences.get(0));
+            } 
         }
-        return hm;
+        return list;
     }
 
     /**
-     * A dependency is satisfied if it is optional of ref.length != 0.
+     * A dependency is satisfied if it is optional or there is useful references.
      * 
-     * @return true is the dependency is satified
+     * @return true is the dependency is satisfied
      */
     protected boolean isSatisfied() {
-        return m_isOptional || m_ref.length != 0;
+        return m_isOptional || ! m_references.isEmpty();
     }
 
     /**
@@ -235,13 +277,7 @@
      * the dependency.
      */
     protected Object get() {
-        // m_handler.getInstanceManager().getFactory().getLogger().log(Logger.INFO,
-        // "[" + m_handler.getInstanceManager().getClassName() + "] Call get for
-        // a dependency on : " + m_metadata.getServiceSpecification()
-        // + " Multiple : " + m_metadata.isMultiple() + " Optional : " +
-        // m_metadata.isOptional());
         try {
-
             // 1 : Test if there is any change in the reference list :
             if (!m_change) {
                 if (!m_isAggregate) {
@@ -257,11 +293,9 @@
             // m_services array
             m_handler.getInstanceManager().getFactory().getLogger().log(Logger.INFO,
                     "[" + m_handler.getInstanceManager().getClassName() + "] Create a service array of " + m_clazz.getName());
-            m_services = (Object[]) Array.newInstance(m_clazz, m_ref.length);
+            
 
-            for (int i = 0; i < m_ref.length; i++) {
-                m_services[i] = m_handler.getInstanceManager().getContext().getService(m_ref[i]);
-            }
+            buildServiceObjectArray();
 
             m_change = false;
             // m_handler.getInstanceManager().getFactory().getLogger().log(Logger.INFO,
@@ -325,17 +359,36 @@
     }
 
     /**
-     * Method calld when a service event is throwed.
+     * Create the service object array according to the resolving policy.
+     */
+    private void buildServiceObjectArray() {
+        if (m_isAggregate) {
+            m_services = (Object[]) Array.newInstance(m_clazz, m_references.size());
+            for (int i = 0; i < m_references.size(); i++) {
+                m_services[i] = getService((ServiceReference) m_references.get(i));
+            }
+        } else {
+            if (m_references.size() == 0) {
+                m_services = new Object[0];
+            } else {
+                m_services = new Object[] { getService((ServiceReference) m_references.get(0)) };
+            }
+        }
+    }
+
+    /**
+     * Method called when a service event occurs.
      * 
      * @see org.osgi.framework.ServiceListener#serviceChanged(org.osgi.framework.ServiceEvent)
-     * @param event : the received service event
+     * @param event :
+     *            the received service event
      */
     public void serviceChanged(ServiceEvent event) {
         synchronized (this) {
 
             // If a service goes way.
             if (event.getType() == ServiceEvent.UNREGISTERING) {
-                if (containsSR(event.getServiceReference())) {
+                if (m_references.contains(event.getServiceReference())) {
                     departureManagement(event.getServiceReference());
                 }
                 return;
@@ -351,11 +404,11 @@
             // If a service is modified
             if (event.getType() == ServiceEvent.MODIFIED) {
                 if (m_filter.match(event.getServiceReference())) {
-                    if (!containsSR(event.getServiceReference())) {
+                    if (!m_references.contains(event.getServiceReference())) {
                         arrivalManagement(event.getServiceReference());
                     }
                 } else {
-                    if (containsSR(event.getServiceReference())) {
+                    if (m_references.contains(event.getServiceReference())) {
                         departureManagement(event.getServiceReference());
                     }
                 }
@@ -371,10 +424,10 @@
      * @param ref : the arriving service reference
      */
     private void arrivalManagement(ServiceReference ref) {
-        addReference(ref);
+        m_references.add(ref);
         if (isSatisfied()) {
             m_state = RESOLVED;
-            if (m_isAggregate || m_ref.length == 1) {
+            if (m_isAggregate || ! m_references.isEmpty()) {
                 m_change = true;
                 callBindMethod(ref);
             }
@@ -389,35 +442,35 @@
      */
     private void departureManagement(ServiceReference ref) {
         // Call unbind method
-        if (!m_isAggregate && ref == m_ref[0]) {
-            callUnbindMethod(ref);
-        }
-        if (m_isAggregate) {
+        boolean hasChanged = false;
+        if (m_usedReferences.contains(ref)) {
             callUnbindMethod(ref);
+            // Unget the service reference
+            ungetService(ref);
+            hasChanged = true;
         }
 
-        // Unget the service reference
-        m_handler.getInstanceManager().getContext().ungetService(ref);
-        int index = removeReference(ref);
+        // Remove from the list (remove on both to be sure.
+        m_references.remove(ref);
 
         // Is the state valid or invalid
-        if (m_ref.length == 0 && !m_isOptional) {
+        if (m_references.isEmpty() && !m_isOptional) {
             m_state = UNRESOLVED;
-        }
-        if (m_ref.length == 0 && m_isOptional) {
+        } else {
             m_state = RESOLVED;
         }
+
         // Is there any change ?
-        if (!m_isAggregate && index == 0) {
-            m_change = true;
-            if (m_ref.length != 0) {
-                callBindMethod(m_ref[0]);
+        if (!m_isAggregate) {
+            if (hasChanged) {
+                m_change = true;
+                if (!m_references.isEmpty()) {
+                    callBindMethod((ServiceReference) m_references.get(0));
+                }
+            } else {
+                m_change = false;
             }
-        }
-        if (!m_isAggregate && index != 0) {
-            m_change = false;
-        }
-        if (m_isAggregate) {
+        } else {
             m_change = true;
         }
 
@@ -435,7 +488,7 @@
             for (int i = 0; i < m_callbacks.length; i++) {
                 if (m_callbacks[i].getMethodType() == DependencyCallback.UNBIND) {
                     try {
-                        m_callbacks[i].call(ref, m_handler.getInstanceManager().getContext().getService(ref));
+                        m_callbacks[i].call(ref, getService(ref));
                     } catch (NoSuchMethodException e) {
                         m_handler.getInstanceManager().getFactory().getLogger().log(
                                 Logger.ERROR, "The method " + m_callbacks[i].getMethodName() + " does not exist in the class "
@@ -451,7 +504,7 @@
                         m_handler.getInstanceManager().getFactory().getLogger().log(
                                 Logger.ERROR,
                                 "The method " + m_callbacks[i].getMethodName() + " in the class " + m_handler.getInstanceManager().getClassName()
-                                        + "thorws an exception : " + e.getMessage());
+                                        + "throws an exception : " + e.getMessage());
                         return;
                     }
                 }
@@ -460,24 +513,43 @@
     }
 
     /**
+     * Get a service object for the given reference according to the resolving policy.
+     * @param ref : service reference
+     * @return the service object
+     */
+    private Object getService(ServiceReference ref) {
+        if (!m_usedReferences.contains(ref)) {
+            m_usedReferences.add(ref);
+        }
+        return m_serviceContext.getService(ref);
+    }
+    
+    /**
+     * Unget the given service reference according to the resolving policy.
+     * @param ref : service reference to unget
+     */
+    private void ungetService(ServiceReference ref) {
+        m_usedReferences.remove(ref);
+        m_serviceContext.ungetService(ref);
+    }
+
+    /**
      * Call the bind method.
      * 
      * @param instance : instance on which calling the bind method.
      */
     protected void callBindMethod(Object instance) {
-        // Check optional case : nullable object case : do not call bind on
-        // nullable object
-        if (m_isOptional && m_ref.length == 0) {
+        // Check optional case : nullable object case : do not call bind on nullable object
+        if (m_isOptional && m_references.isEmpty()) {
             return;
         }
 
         if (m_isAggregate) {
-            for (int i = 0; i < m_ref.length; i++) {
+            for (int i = 0; i < m_references.size(); i++) {
                 for (int j = 0; j < m_callbacks.length; j++) {
                     if (m_callbacks[j].getMethodType() == DependencyCallback.BIND) {
                         try {
-                            m_callbacks[j].callOnInstance(instance, m_ref[i], m_handler.getInstanceManager()
-                                    .getContext().getService(m_ref[i]));
+                            m_callbacks[j].callOnInstance(instance, (ServiceReference) m_references.get(i), getService((ServiceReference) m_references.get(i)));
                         } catch (NoSuchMethodException e) {
                             m_handler.getInstanceManager().getFactory().getLogger().log(
                                     Logger.ERROR, "The method " + m_callbacks[j].getMethodName() + " does not exist in the class "
@@ -503,7 +575,7 @@
             for (int j = 0; j < m_callbacks.length; j++) {
                 if (m_callbacks[j].getMethodType() == DependencyCallback.BIND) {
                     try {
-                        m_callbacks[j].callOnInstance(instance, m_ref[0], m_handler.getInstanceManager().getContext().getService(m_ref[0]));
+                        m_callbacks[j].callOnInstance(instance, (ServiceReference) m_references.get(0), getService((ServiceReference) m_references.get(0)));
                     } catch (NoSuchMethodException e) {
                         m_handler.getInstanceManager().getFactory().getLogger().log(
                                 Logger.ERROR, "The method " + m_callbacks[j].getMethodName() + " does not exist in the class "
@@ -538,7 +610,7 @@
             for (int i = 0; i < m_callbacks.length; i++) {
                 if (m_callbacks[i].getMethodType() == DependencyCallback.BIND) {
                     try {
-                        m_callbacks[i].call(ref, m_handler.getInstanceManager().getContext().getService(ref));
+                        m_callbacks[i].call(ref, getService(ref));
                     } catch (NoSuchMethodException e) {
                         m_handler.getInstanceManager().getFactory().getLogger().log(
                                 Logger.ERROR, "The method " + m_callbacks[i].getMethodName() + " does not exist in the class "
@@ -554,7 +626,7 @@
                         m_handler.getInstanceManager().getFactory().getLogger().log(
                                 Logger.ERROR,
                                 "The method " + m_callbacks[i].getMethodName() + " in the class " + m_handler.getInstanceManager().getClassName()
-                                        + "thorws an exception : " + e.getMessage());
+                                        + "throws an exception : " + e.getMessage());
                         return;
                     }
                 }
@@ -566,6 +638,9 @@
      * 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 classnamefilter = "(objectClass=" + m_specification + ")";
         String filter = "";
@@ -588,44 +663,61 @@
 
         try {
             // Look if the service is already present :
-            ServiceReference[] sr = m_handler.getInstanceManager().getContext().getServiceReferences(m_specification, filter);
-            if (sr != null) {
-                for (int i = 0; i < sr.length; i++) {
-                    addReference(sr[i]);
-                }
+            if (lookForServiceReferences(m_specification, filter)) {
                 m_state = RESOLVED;
             }
             // Register a listener :
-            m_handler.getInstanceManager().getContext().addServiceListener(this);
-            m_filter = m_handler.getInstanceManager().getContext().createFilter(filter); // Store
-                                                                                            // the
-                                                                                            // filter
-            m_handler.getInstanceManager().getFactory().getLogger().log(Logger.INFO,
-                    "[" + m_handler.getInstanceManager().getClassName() + "] Create a filter from : " + filter);
+            m_serviceContext.addServiceListener(this);
+         
+            m_filter = m_handler.getInstanceManager().getContext().createFilter(filter); // Store the filter
+            m_handler.getInstanceManager().getFactory().getLogger().log(Logger.INFO, "[" + m_handler.getInstanceManager().getClassName() + "] Create a filter from : " + filter);
             m_change = true;
         } catch (InvalidSyntaxException e1) {
             m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR,
-                    "[" + m_handler.getInstanceManager().getClassName() + "] A filter is malformed : " + filter);
-            e1.printStackTrace();
+                    "[" + m_handler.getInstanceManager().getClassName() + "] A filter is malformed : " + filter + " - " + e1.getMessage());
         }
     }
 
     /**
+     * Look for available service.
+     * @param specification : required specification.
+     * @param filter : LDAP Filter
+     * @return true if at least one service is found.
+     */
+    private boolean lookForServiceReferences(String specification, String filter) {
+        boolean success = false; // Are the query fulfilled ?
+        try {
+            ServiceReference[] refs = m_serviceContext.getServiceReferences(specification, filter);
+            if (refs != null) {
+                success = true;
+                for (int i = 0; i < refs.length; i++) {
+                    m_references.add(refs[i]);
+                }
+            }
+        } catch (InvalidSyntaxException e) {
+            m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR,
+                    "The requirement on " + m_specification + " does not have a vlid filter : " + e.getMessage());
+        }
+        return success;
+    }
+
+    /**
      * Stop the dependency.
      */
     public void stop() {
-        m_handler.getInstanceManager().getContext().removeServiceListener(this);
+        m_serviceContext.removeServiceListener(this);
         
         m_handler.getInstanceManager().getFactory().getLogger().log(Logger.INFO,
                 "[" + m_handler.getInstanceManager().getInstanceName() + "] Stop a dependency on : " + m_specification + " with " + m_strFilter + " (" + m_handler.getInstanceManager() + ")");
         m_state = UNRESOLVED;
 
         // Unget all services references
-        for (int i = 0; i < m_ref.length; i++) {
-            m_handler.getInstanceManager().getContext().ungetService(m_ref[i]);
+        for (int i = 0; i < m_usedReferences.size(); i++) {
+            ungetService((ServiceReference) m_usedReferences.get(i));
         }
 
-        m_ref = new ServiceReference[0];
+        m_references.clear();
+        m_usedReferences.clear();
         m_clazz = null;
         m_services = new Object[0];
     }
@@ -637,96 +729,43 @@
      */
     public int getState() {
         if (m_isOptional) { 
-            return 1;
+            return RESOLVED;
         } else { 
             return m_state;
         }
     }
 
     /**
-     * Return the list of service reference.
+     * Return the list of used service reference.
      * 
      * @return the service reference list.
      */
-    public ServiceReference[] getServiceReferences() {
-        return m_ref;
+    public List getServiceReferences() {
+        List refs = new ArrayList();
+        refs.addAll(m_references);
+        return refs;
     }
-
-    /**
-     * Add a service reference in the current list.
-     * 
-     * @param r : the new service reference to add
-     */
-    private void addReference(ServiceReference r) {
-        for (int i = 0; (m_ref != null) && (i < m_ref.length); i++) {
-            if (m_ref[i] == r) {
-                return;
-            }
-        }
-
-        if (m_ref != null) {
-            ServiceReference[] newSR = new ServiceReference[m_ref.length + 1];
-            System.arraycopy(m_ref, 0, newSR, 0, m_ref.length);
-            newSR[m_ref.length] = r;
-            m_ref = newSR;
-        } else {
-            m_ref = new ServiceReference[] { r };
-        }
+    
+    protected DependencyCallback[] getCallbacks() {
+        return m_callbacks;
     }
 
     /**
-     * Find if a service registration il already registred.
-     * 
-     * @param sr : the service registration to find.
-     * @return true if the service registration is already in the array
+     * Set that this dependency is a service level dependency.
+     * This forces the scoping policy to be STRICT. 
+     * @param b
      */
-    private boolean containsSR(ServiceReference sr) {
-        for (int i = 0; i < m_ref.length; i++) {
-            if (m_ref[i] == sr) {
-                return true;
-            }
-        }
-        return false;
+    public void setServiceLevelDependency() {
+        m_isServiceLevelRequirement = true;
+        m_policy = PolicyServiceContext.LOCAL;
     }
 
-    /**
-     * Remove a service reference in the current list.
-     * 
-     * @param r : the new service reference to remove
-     * @return the index of the founded element, or -1 if the element is not
-     * found
-     */
-    private int removeReference(ServiceReference r) {
-        if (m_ref == null) {
-            m_ref = new ServiceReference[0];
-        }
-
-        int idx = -1;
-        for (int i = 0; i < m_ref.length; i++) {
-            if (m_ref[i] == r) {
-                idx = i;
-                break;
-            }
-        }
-
-        if (idx >= 0) {
-            // If this is the module, then point to empty list.
-            if ((m_ref.length - 1) == 0) {
-                m_ref = new ServiceReference[0];
-            } else { // Otherwise, we need to do some array copying.
-                ServiceReference[] newSR = new ServiceReference[m_ref.length - 1];
-                System.arraycopy(m_ref, 0, newSR, 0, idx);
-                if (idx < newSR.length) {
-                    System.arraycopy(m_ref, idx + 1, newSR, idx, newSR.length - idx);
-                }
-                m_ref = newSR;
-            }
-        }
-        return idx;
+    public String getId() {
+        return m_id;
     }
     
-    protected DependencyCallback[] getCallbacks() {
-        return m_callbacks;
+    public boolean isServiceLevelRequirement() {
+        return m_isServiceLevelRequirement;
     }
 
 }

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyDescription.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyDescription.java?view=diff&rev=562430&r1=562429&r2=562430
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyDescription.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyDescription.java Fri Aug  3 05:24:51 2007
@@ -18,8 +18,8 @@
  */
 package org.apache.felix.ipojo.handlers.dependency;
 
-import java.util.HashMap;
-import java.util.Map;
+import java.util.ArrayList;
+import java.util.List;
 
 import org.osgi.framework.ServiceReference;
 
@@ -55,20 +55,20 @@
     private String m_filter;
 
     /**
-     * Map [Instance reference, service reference] of the used service.
+     * List[service reference] of the used service.
      */
-    private Map m_usedServices = new HashMap();
+    private List m_usedServices = new ArrayList();
 
     /**
      * The list of service reference.
      */
-    private ServiceReference[] m_serviceReferences;
+    private List m_serviceReferences;
 
     /**
      * Constructor.
-     * @param itf : the needed itf
+     * @param itf : the needed interface
      * @param multiple : is the dependency a multiple dependency ?
-     * @param optional : is the depdendency optional ?
+     * @param optional : is the dependency optional ?
      * @param filter : the filter
      * @param state : the state
      */
@@ -79,7 +79,7 @@
         m_optional = optional;
         m_filter = filter;
         m_state = state;
-        m_serviceReferences = new ServiceReference[0];
+        m_serviceReferences = new ArrayList();
     }
 
     public boolean isMultiple() { return m_multiple; }
@@ -93,34 +93,34 @@
     public int getState() { return m_state; }
 
     /**
-     * Get the service refrence array.
+     * Get the service reference list.
      * @return the array of service reference (only if the cardinality could be n).
      */
-    public ServiceReference[] getServiceReferences() { return m_serviceReferences; }
+    public List getServiceReferences() { return m_serviceReferences; }
 
     /**
      * Get the service reference if only 1 used.
      * @return the ServiceReference (only if the cardinality could be 1).
      */
-    public ServiceReference getServiceReference() { return m_serviceReferences[0]; }
+    public ServiceReference getServiceReference() { return (ServiceReference) m_serviceReferences.get(0); }
 
     /**
      * Set the service reference array.
-     * @param sr : the array of service reference
+     * @param sr : the list of service reference
      */
-    public void setServiceReferences(ServiceReference[] sr) { m_serviceReferences = sr; }
+    public void setServiceReferences(List sr) { m_serviceReferences = sr; }
 
     /**
-     * Get the used service map.
-     * @return the map [object reference, service reference] containing the used services
+     * Get the used service list.
+     * @return the list [service reference] containing the used services
      */
-    public Map getUsedServices() { return m_usedServices; }
+    public List getUsedServices() { return m_usedServices; }
 
     /**
      * Set the usedServices.
-     * @param hm : the new usedService
+     * @param hm : the list of used service reference.
      */
-    public void setUsedServices(Map hm) {
+    public void setUsedServices(List hm) {
         m_usedServices = hm;
     }
 

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java?view=diff&rev=562430&r1=562429&r2=562430
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java Fri Aug  3 05:24:51 2007
@@ -25,6 +25,7 @@
 
 import org.apache.felix.ipojo.Handler;
 import org.apache.felix.ipojo.InstanceManager;
+import org.apache.felix.ipojo.PolicyServiceContext;
 import org.apache.felix.ipojo.architecture.HandlerDescription;
 import org.apache.felix.ipojo.handlers.dependency.nullable.NullableObjectWriter;
 import org.apache.felix.ipojo.metadata.Element;
@@ -269,8 +270,24 @@
             if (deps[i].containsAttribute("aggregate") && deps[i].getAttribute("aggregate").equals("true")) {
                 aggregate = true;
             }
+            
+            String id = null;
+            if (deps[i].containsAttribute("id")) {
+                id = deps[i].getAttribute("id");
+            }
+            
+            int scopePolicy = -1;
+            if (deps[i].containsAttribute("scope")) {
+                if (deps[i].getAttribute("scope").equalsIgnoreCase("global")) {
+                    scopePolicy = PolicyServiceContext.GLOBAL;
+                } else if (deps[i].getAttribute("scope").equalsIgnoreCase("composite")) {
+                    scopePolicy = PolicyServiceContext.LOCAL;
+                } else if (deps[i].getAttribute("scope").equalsIgnoreCase("composite+global")) {
+                    scopePolicy = PolicyServiceContext.LOCAL_AND_GLOBAL;
+                }                
+            }
 
-            Dependency dep = new Dependency(this, field, serviceSpecification, filter, optional, aggregate);
+            Dependency dep = new Dependency(this, field, serviceSpecification, filter, optional, aggregate, id, scopePolicy);
             
             // Look for dependency callback :
             for (int j = 0; j < (deps[i].getElements("Callback", "")).length; j++) {

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandlerDescription.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandlerDescription.java?view=diff&rev=562430&r1=562429&r2=562430
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandlerDescription.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandlerDescription.java Fri Aug  3 05:24:51 2007
@@ -18,11 +18,13 @@
  */
 package org.apache.felix.ipojo.handlers.dependency;
 
-import java.util.Iterator;
+import java.util.List;
 
 import org.apache.felix.ipojo.architecture.HandlerDescription;
 import org.apache.felix.ipojo.metadata.Attribute;
 import org.apache.felix.ipojo.metadata.Element;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
 
 /**
  * Dependency Handler Description.
@@ -88,12 +90,30 @@
             Element dep = new Element("Requires", "");
             dep.addAttribute(new Attribute("Specification", m_dependencies[i].getInterface()));
             dep.addAttribute(new Attribute("Filter", m_dependencies[i].getFilter()));
+            
+            if (m_dependencies[i].isOptional()) {
+                dep.addAttribute(new Attribute("Optional", "true"));
+            } else {
+                dep.addAttribute(new Attribute("Optional", "false"));
+            }
+
+            if (m_dependencies[i].isMultiple()) {
+                dep.addAttribute(new Attribute("Aggregate", "true"));
+            } else {
+                dep.addAttribute(new Attribute("Aggregate", "false"));
+            }
+            
             dep.addAttribute(new Attribute("State", state));
             Element usages = new Element("Usages", "");
-            Iterator it = m_dependencies[i].getUsedServices().keySet().iterator();
-            while (it.hasNext()) {
+            List list = m_dependencies[i].getUsedServices();
+            for (int j = 0; j < list.size(); j++) {
                 Element use = new Element("Use", "");
-                use.addAttribute(new Attribute("object", it.next().toString()));
+                ServiceReference ref = (ServiceReference) list.get(i);
+                use.addAttribute(new Attribute("service.id", (String) ref.getProperty(Constants.SERVICE_ID)));
+                String pid = (String) ref.getProperty(Constants.SERVICE_PID);
+                if (pid != null) {
+                    use.addAttribute(new Attribute("service.pid", pid));
+                }
                 usages.addElement(use);
             }
             deps.addElement(dep);

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedService.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedService.java?view=diff&rev=562430&r1=562429&r2=562430
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedService.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedService.java Fri Aug  3 05:24:51 2007
@@ -100,8 +100,6 @@
         addProperty(new Property(this, "factory.pid", handler.getInstanceManager().getFactory().getName()));
     }
 
-    // TODO check if we need to erase previous props or add to the previous
-    // props.
     /**
      * Add properties to the provided service.
      * 

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java?view=diff&rev=562430&r1=562429&r2=562430
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java Fri Aug  3 05:24:51 2007
@@ -18,6 +18,7 @@
  */
 package org.apache.felix.ipojo.handlers.providedservice;
 
+import java.lang.reflect.Field;
 import java.util.Dictionary;
 import java.util.Properties;
 
@@ -26,9 +27,13 @@
 import org.apache.felix.ipojo.architecture.ComponentDescription;
 import org.apache.felix.ipojo.architecture.HandlerDescription;
 import org.apache.felix.ipojo.architecture.PropertyDescription;
+import org.apache.felix.ipojo.handlers.dependency.Dependency;
+import org.apache.felix.ipojo.handlers.dependency.DependencyHandler;
 import org.apache.felix.ipojo.metadata.Element;
 import org.apache.felix.ipojo.parser.FieldMetadata;
+import org.apache.felix.ipojo.parser.ManifestMetadataParser;
 import org.apache.felix.ipojo.parser.ManipulationMetadata;
+import org.apache.felix.ipojo.parser.ParseException;
 import org.apache.felix.ipojo.parser.ParseUtils;
 import org.apache.felix.ipojo.util.Logger;
 import org.osgi.framework.Constants;
@@ -226,42 +231,129 @@
      * metadata are consistent.
      * 
      * @param ps : the provided service to check.
-     * @param manipulation : componenet-type manipulation metadata.
+     * @param manipulation : component-type manipulation metadata.
      * @return true if the provided service is correct
      */
     private boolean checkProvidedService(ProvidedService ps, ManipulationMetadata manipulation) {
-
         for (int i = 0; i < ps.getServiceSpecification().length; i++) {
+            // Check the implementation of the specification
             if (! manipulation.isInterfaceImplemented(ps.getServiceSpecification()[i])) {
                 m_manager.getFactory().getLogger().log(Logger.ERROR, "[" + m_manager.getClassName() + "] The service specification " + ps.getServiceSpecification()[i]
                                 + " is not implemented by the component class");
                 return false;
             }
+            
+            // Check service level dependencies
+            try {
+                Class spec = m_manager.getFactory().loadClass(ps.getServiceSpecification()[i]);
+                Field specField = spec.getField("specification");     
+                Object o = specField.get(null);
+                if (!(o instanceof String)) {
+                    m_manager.getFactory().getLogger().log(Logger.ERROR, "[" + m_manager.getClassName() + "] The specification field of the service specification " + ps.getServiceSpecification()[i] + " need to be a String");                                                                                                                                                                    
+                    return false;
+                } else {
+                    Element specification = ManifestMetadataParser.parse((String) o);
+                    Element[] deps = specification.getElements("requires");
+                    for (int j = 0; j < deps.length; j++) {
+                        Dependency d = getAttachedDependency(deps[j]);
+                        if (d != null) {
+                            // Fix service-level dependency flag
+                            d.setServiceLevelDependency();
+                        }
+                        if (!isDependencyCorrect(d, deps[j])) {
+                            return false;
+                        }
+                    }
+                }
+            } catch (NoSuchFieldException e) {
+                return true;  // No specification field
+            } catch (ClassNotFoundException e) {
+                m_manager.getFactory().getLogger().log(Logger.ERROR, "[" + m_manager.getClassName() + "] The service specification " + ps.getServiceSpecification()[i] + " cannot be load");                                                                                                                                                                    
+                return false;
+            } catch (IllegalArgumentException e) {
+                m_manager.getFactory().getLogger().log(Logger.ERROR, "[" + m_manager.getClassName() + "] The field 'specification' of the service specification " + ps.getServiceSpecification()[i] + " is not accessible : " + e.getMessage());                                                                                                                                                                    
+                return false;
+            } catch (IllegalAccessException e) {
+                m_manager.getFactory().getLogger().log(Logger.ERROR, "[" + m_manager.getClassName() + "] The field 'specification' of the service specification " + ps.getServiceSpecification()[i] + " is not accessible : " + e.getMessage());                                                                                                                                                                    
+                return false;
+            } catch (ParseException e) {
+                m_manager.getFactory().getLogger().log(Logger.ERROR, "[" + m_manager.getClassName() + "] The field 'specification' of the service specification " + ps.getServiceSpecification()[i] + " does not contain a valid String : " + e.getMessage());                                                                                                                                                                    
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Look for the implementation (i.e. component) dependency for the given service-level requirement metadata.
+     * @param element : the service-level requirement metadata
+     * @return the Dependency object, null if not found or if the DependencyHandler is not plugged to the instance
+     */
+    private Dependency getAttachedDependency(Element element) {
+        DependencyHandler dh = (DependencyHandler) m_manager.getHandler(DependencyHandler.class.getName());
+        if (dh == null) { 
+            return null;
+        }
+        
+        if (element.containsAttribute("id")) {
+            // Look for dependency Id
+            String id = element.getAttribute("id");
+            for (int i = 0; i < dh.getDependencies().length; i++) {
+                if (dh.getDependencies()[i].getId().equals(id)) {
+                    return dh.getDependencies()[i]; 
+                }
+            }
+        }
+        
+        // If not found or no id, look for a dependency with the same specification
+        String requirement = element.getAttribute("specification");
+        for (int i = 0; i < dh.getDependencies().length; i++) {
+            if (dh.getDependencies()[i].getSpecification().equals(requirement)) {
+                return dh.getDependencies()[i]; 
+            }
+        }
+        
+        return null;
+    }
+
+    /**
+     * Check the correctness of the implementation dependency against the service level dependency.
+     * @param dep : dependency to check
+     * @param elem : service-level dependency metadata
+     * @return true if the dependency is correct, false otherwise
+     */
+    private boolean isDependencyCorrect(Dependency dep, Element elem) {
+        boolean opt = false;
+        if (elem.containsAttribute("optional") && elem.getAttribute("optional").equalsIgnoreCase("true")) {
+            opt = false;
+        }
+        
+        boolean agg = false;
+        if (elem.containsAttribute("aggregate") && elem.getAttribute("aggregate").equalsIgnoreCase("true")) {
+            agg = false;
         }
 
-//        // Fix internal property type
-//        for (int i = 0; i < ps.getProperties().length; i++) {
-//            Property prop = ps.getProperties()[i];
-//            String field = prop.getField();
-//
-//            if (field == null) {
-//                return true; // Static property -> Nothing to check
-//            } else {
-//                String type = null;
-//                for (int j = 0; j < manipulation.getElements("Field").length; j++) {
-//                    if (field.equals(manipulation.getElements("Field")[j].getAttribute("name"))) {
-//                        type = manipulation.getElements("Field")[j].getAttribute("type");
-//                        break;
-//                    }
-//                }
-//                if (type == null) {
-//                    m_manager.getFactory().getLogger().log(Logger.ERROR,
-//                            "[" + m_manager.getClassName() + "] A declared property was not found in the class : " + prop.getField());
-//                    return false;
-//                }
-//                prop.setType(type); // Set the type
-//            }
-//        }
+        if (dep == null && !opt) {
+            m_manager.getFactory().getLogger().log(Logger.ERROR, "[" + m_manager.getClassName() + "] The requirement " + elem.getAttribute("specification") + " is not present in the implementation and is declared as a mandatory service-level requirement");
+            return false;
+        }
+        
+        
+        if (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")) {
+            String filter = elem.getAttribute("filter");
+            String filter2 = dep.getFilter();
+            if (filter2 == null || !filter2.equalsIgnoreCase(filter)) {
+                m_manager.getFactory().getLogger().log(Logger.ERROR, "[" + m_manager.getClassName() + "] The specification requirement " + elem.getAttribute("specification") + " as not the same filter as declared in the service-level requirement");
+                return false;
+            }
+        }
+        
         return true;
     }
 

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandlerDescription.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandlerDescription.java?view=diff&rev=562430&r1=562429&r2=562430
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandlerDescription.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandlerDescription.java Fri Aug  3 05:24:51 2007
@@ -82,7 +82,7 @@
     public Element getHandlerInfo() {
         Element services = super.getHandlerInfo();
         for (int i = 0; i < m_providedServices.length; i++) {
-            Element service = new Element("service", "");
+            Element service = new Element("provides", "");
             String state = "unregistered";
             if (m_providedServices[i].getState() == ProvidedService.REGISTERED) {
                 state = "registered";

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/ParseUtils.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/ParseUtils.java?view=diff&rev=562430&r1=562429&r2=562430
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/ParseUtils.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/ParseUtils.java Fri Aug  3 05:24:51 2007
@@ -21,7 +21,7 @@
 import java.util.StringTokenizer;
 
 /**
- * Parse Utils Methods.
+ * Parse Utility Methods.
  * 
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
@@ -69,5 +69,4 @@
         }
         return result;
     }
-
 }



Mime
View raw message