You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by cl...@apache.org on 2008/03/28 16:35:29 UTC

svn commit: r642265 [6/11] - in /felix/trunk/ipojo: ./ annotations/ ant/ ant/src/main/java/org/apache/felix/ipojo/task/ arch/ arch/src/main/java/org/apache/felix/ipojo/arch/ arch/src/main/resources/ composite/ composite/src/ composite/src/main/ composi...

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?rev=642265&r1=642264&r2=642265&view=diff
==============================================================================
--- 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 Mar 28 08:33:36 2008
@@ -18,27 +18,30 @@
  */
 package org.apache.felix.ipojo.handlers.dependency;
 
-import java.util.ArrayList;
+import java.util.Comparator;
 import java.util.Dictionary;
-import java.util.List;
 
-import org.apache.felix.ipojo.ComponentInstance;
 import org.apache.felix.ipojo.ConfigurationException;
+import org.apache.felix.ipojo.IPojoContext;
 import org.apache.felix.ipojo.PolicyServiceContext;
 import org.apache.felix.ipojo.PrimitiveHandler;
 import org.apache.felix.ipojo.architecture.HandlerDescription;
 import org.apache.felix.ipojo.metadata.Element;
 import org.apache.felix.ipojo.parser.FieldMetadata;
-import org.apache.felix.ipojo.parser.ManipulationMetadata;
 import org.apache.felix.ipojo.parser.MethodMetadata;
-import org.apache.felix.ipojo.util.Logger;
+import org.apache.felix.ipojo.parser.PojoMetadata;
+import org.apache.felix.ipojo.util.DependencyModel;
+import org.apache.felix.ipojo.util.DependencyStateListener;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Filter;
+import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServiceReference;
 
 /**
  * The dependency handler manages a list of service dependencies.
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public class DependencyHandler extends PrimitiveHandler {
+public class DependencyHandler extends PrimitiveHandler implements DependencyStateListener {
 
     /**
      * List of dependencies of the component.
@@ -46,12 +49,6 @@
     private Dependency[] m_dependencies = new Dependency[0];
 
     /**
-     * State of the handler.
-     * Lifecycle controller.
-     */
-    private boolean m_state;
-
-    /**
      * Is the handler started.
      */
     private boolean m_started;
@@ -61,16 +58,18 @@
      * @param dep : the dependency to add
      */
     private void addDependency(Dependency dep) {
-        for (int i = 0; i < m_dependencies.length; i++) {
-            if (m_dependencies[i] == dep) { return; }
+        for (int i = 0; m_dependencies != null && i < m_dependencies.length; i++) {
+            if (m_dependencies[i] == dep) {
+                return;
+            }
         }
-        if (m_dependencies.length > 0) {
+        if (m_dependencies == null) {
+            m_dependencies = new Dependency[] { dep };
+        } else {
             Dependency[] newDep = new Dependency[m_dependencies.length + 1];
             System.arraycopy(m_dependencies, 0, newDep, 0, m_dependencies.length);
             newDep[m_dependencies.length] = dep;
             m_dependencies = newDep;
-        } else {
-            m_dependencies = new Dependency[] { dep };
         }
     }
 
@@ -83,36 +82,56 @@
     }
 
     /**
+     * Validate method. This method is invoked by an AbstractServiceDependency when this dependency becomes RESOLVED.
+     * @param dep : the dependency becoming RESOLVED.
+     * @see org.apache.felix.ipojo.util.DependencyStateListener#validate(org.apache.felix.ipojo.util.DependencyModel)
+     */
+    public void validate(DependencyModel dep) {
+        checkContext();
+    }
+
+    /**
+     * Invalidate method. This method is invoked by an AbstractServiceDependency when this dependency becomes UNRESOLVED or BROKEN.
+     * @param dep : the dependency becoming UNRESOLVED or BROKEN.
+     * @see org.apache.felix.ipojo.util.DependencyStateListener#invalidate(org.apache.felix.ipojo.util.DependencyModel)
+     */
+    public void invalidate(DependencyModel dep) {
+        setValidity(false);
+    }
+
+    /**
      * Check the validity of the dependencies.
      */
     protected void checkContext() {
-        if (! m_started) { return; }
+        if (!m_started) {
+            return;
+        }
         synchronized (m_dependencies) {
             // Store the initial state
-            boolean initialState = m_state;
+            boolean initialState = getValidity();
 
             boolean valid = true;
             for (int i = 0; i < m_dependencies.length; i++) {
                 Dependency dep = m_dependencies[i];
-                if (dep.getState() > Dependency.RESOLVED) { 
+                if (dep.getState() != Dependency.RESOLVED) {
                     valid = false;
                     break;
                 }
             }
-            
+
             // Check the component dependencies
             if (valid) {
                 // The dependencies are valid
                 if (!initialState) {
                     // There is a state change
-                    m_state = true;
+                    setValidity(true);
                 }
                 // Else do nothing, the component state stay VALID
             } else {
                 // The dependencies are not valid
                 if (initialState) {
                     // There is a state change
-                    m_state = false;
+                    setValidity(false);
                 }
                 // Else do nothing, the component state stay UNRESOLVED
             }
@@ -121,81 +140,113 @@
     }
 
     /**
-     * Check if the dependency given is valid in the sense that metadata are
-     * consistent.
+     * Check if the dependency given is valid in the sense that metadata are consistent.
      * @param dep : the dependency to check
      * @param manipulation : the component-type manipulation metadata
      * @return true if the dependency is valid
      * @throws ConfigurationException : the checked dependency is not correct
      */
-    private boolean checkDependency(Dependency dep, ManipulationMetadata manipulation) throws ConfigurationException {
+    private boolean checkDependency(Dependency dep, PojoMetadata manipulation) throws ConfigurationException {
         // Check the internal type of dependency
         String field = dep.getField();
         DependencyCallback[] callbacks = dep.getCallbacks();
 
-        for (int i = 0; i < callbacks.length; i++) {
+        if (callbacks == null && field == null) {
+            throw new ConfigurationException("A service requirement requires at least callbacks or a field");
+        }
+
+        for (int i = 0; callbacks != null && i < callbacks.length; i++) {
             MethodMetadata[] mets = manipulation.getMethods(callbacks[i].getMethodName());
-            if (mets.length != 0) {
+            if (mets.length == 0) {
+                info("A requirement callback " + callbacks[i].getMethodName() + " does not exist in the implementation, try the super classes");
+            } else {
                 if (mets[0].getMethodArguments().length > 2) {
-                    throw new ConfigurationException("Requirement Callback : A requirement callback " + callbacks[i].getMethodName() + " must have 0 or 1 or 2 arguments");
+                    throw new ConfigurationException("Requirement Callback : A requirement callback "
+                            + callbacks[i].getMethodName()
+                            + " must have 0 or 1 or 2 arguments");
                 }
-                
+
                 callbacks[i].setArgument(mets[0].getMethodArguments());
+
                 if (mets[0].getMethodArguments().length == 1) {
                     if (!mets[0].getMethodArguments()[0].equals(ServiceReference.class.getName())) {
-                        if (dep.getSpecification() == null) {
-                            dep.setSpecification(mets[0].getMethodArguments()[0]);
-                        }
-                        if (!dep.getSpecification().equals(mets[0].getMethodArguments()[0])) {
-                            log(Logger.WARNING, "[DependencyHandler on " + getInstanceManager().getInstanceName() + "] The field type [" + mets[0].getMethodArguments()[0] + "] and the needed service interface [" + dep.getSpecification() + "] are not the same");
-                            dep.setSpecification(mets[0].getMethodArguments()[0]);
-                        }
+                        // The callback receives the service object.
+                        setSpecification(dep, mets[0].getMethodArguments()[0], false); // Just warn if a mismatch is discovered.
                     }
                 } else if (mets[0].getMethodArguments().length == 2) {
-                    // Check that the second arguments is a service reference
+                    // The callback receives service object, service reference. Check that the second argument is a service reference
                     if (!mets[0].getMethodArguments()[1].equals(ServiceReference.class.getName())) {
-                        String message = "The requirement callback " + callbacks[i].getMethodName() + " must have a ServiceReference as the second arguments";
+                        String message =
+                                "The requirement callback " + callbacks[i].getMethodName() + " must have a ServiceReference as the second argument";
                         throw new ConfigurationException(message);
                     }
-                    if (dep.getSpecification() == null) {
-                        dep.setSpecification(mets[0].getMethodArguments()[0]);
-                    } else {
-                        if (!dep.getSpecification().equals(mets[0].getMethodArguments()[0])) {
-                            log(Logger.WARNING, "[DependencyHandler on " + getInstanceManager().getInstanceName() + "] The field type [" + mets[0].getMethodArguments()[0] + "] and the needed service interface [" + dep.getSpecification() + "] are not the same");
-                            dep.setSpecification(mets[0].getMethodArguments()[0]);
-                        }
-                    }
+                    setSpecification(dep, mets[0].getMethodArguments()[0], false); // Just warn if a mismatch is discovered.
                 }
-            } else {
-                log(Logger.INFO, "A requirement callback " + callbacks[i].getMethodName() + " does not exist in the implementation, try the super classes");
             }
 
         }
 
         if (field != null) {
-            FieldMetadata fm = manipulation.getField(field);
-            if (fm == null) {
-                throw new ConfigurationException("Requirement Callback : A requirement field " + field + " does not exist in the implementation class");
+            FieldMetadata meta = manipulation.getField(field);
+            if (meta == null) {
+                throw new ConfigurationException("Requirement Callback : A requirement field "
+                        + field
+                        + " does not exist in the implementation class");
             }
-            String type = fm.getFieldType();
+            String type = meta.getFieldType();
             if (type.endsWith("[]")) {
                 // Set the dependency to multiple
-                dep.setAggregate();
+                dep.setAggregate(true);
                 type = type.substring(0, type.length() - 2);
+            } else {
+                if (dep.isAggregate()) {
+                    throw new ConfigurationException("A required service is not correct : the field "
+                            + meta.getFieldName()
+                            + " must be an array to support aggregate injections");
+                }
             }
+            setSpecification(dep, type, true); // Throw an exception if the filed type mismatch.
+        }
 
-            if (dep.getSpecification() == null) {
-                dep.setSpecification(type);
-            }
+        // Check that all required info are set
+        return dep.getSpecification() != null;
+    }
 
-            if (!dep.getSpecification().equals(type)) {
-                log(Logger.WARNING, "[DependencyHandler on " + getInstanceManager().getInstanceName() + "] The field type [" + type + "] and the needed service interface [" + dep.getSpecification() + "] are not the same");
-                dep.setSpecification(type);
+    /**
+     * Check if we have to set the dependency specification with the given class name.
+     * @param dep : dependency to check
+     * @param className : class name
+     * @param error : set to true to throw an error if the set dependency specification and the given specification are different.
+     * @throws ConfigurationException : the specification class cannot be loaded correctly
+     */
+    private void setSpecification(Dependency dep, String className, boolean error) throws ConfigurationException {
+        // We have to set the dependency in two cases : either the dependency as no specification, or the specification is different from the given
+        // one
+        if (dep.getSpecification() == null || !dep.getSpecification().getName().equals(className)) {
+            if (dep.getSpecification() != null) {
+                if (error) {
+                    throw new ConfigurationException("A required service is not correct : the discoevered type ["
+                            + className
+                            + "] and the specified (or already discovered)  service interface ["
+                            + dep.getSpecification().getName()
+                            + "] are not the same");
+                } else {
+                    // If the specification is different, warn that we will overide it.
+                    warn("[DependencyHandler on "
+                            + getInstanceManager().getInstanceName()
+                            + "] The field type ["
+                            + className
+                            + "] and the needed service interface ["
+                            + dep.getSpecification()
+                            + "] are not the same");
+                }
+            }
+            try {
+                dep.setSpecification(getInstanceManager().getContext().getBundle().loadClass(className));
+            } catch (ClassNotFoundException e) {
+                throw new ConfigurationException("The required service interface cannot be loaded : " + e.getMessage());
             }
         }
-
-        //Check that all required info are set
-        return dep.getSpecification() != null;
     }
 
     /**
@@ -203,73 +254,83 @@
      * @param componentMetadata : the component type metadata
      * @param configuration : the instance configuration
      * @throws ConfigurationException : one dependency metadata is not correct.
-     * @see org.apache.felix.ipojo.Handler#configure(org.apache.felix.ipojo.InstanceManager, org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)
+     * @see org.apache.felix.ipojo.Handler#configure(org.apache.felix.ipojo.InstanceManager, org.apache.felix.ipojo.metadata.Element,
+     *      java.util.Dictionary)
      */
     public void configure(Element componentMetadata, Dictionary configuration) throws ConfigurationException {
-        m_dependencies = new Dependency[0];
-
-        ManipulationMetadata manipulation = new ManipulationMetadata(componentMetadata);
-        List fl = new ArrayList();
+        // getPojoMetadata();
+        PojoMetadata manipulation = getFactory().getPojoMetadata();
+        boolean atLeastOneField = false;
 
         // Create the dependency according to the component metadata
         Element[] deps = componentMetadata.getElements("Requires");
-
+        
         // Get instance filters.
         Dictionary filtersConfiguration = (Dictionary) configuration.get("requires.filters");
-        
-        for (int i = 0; i < deps.length; i++) {
+
+        for (int i = 0; deps != null && i < deps.length; i++) {
             // Create the dependency metadata
             String field = deps[i].getAttribute("field");
             String serviceSpecification = deps[i].getAttribute("interface");
             String filter = deps[i].getAttribute("filter");
             String opt = deps[i].getAttribute("optional");
             boolean optional = opt != null && opt.equalsIgnoreCase("true");
-            String di = deps[i].getAttribute("default-implementation");
-            
+            String defaultImplem = deps[i].getAttribute("default-implementation");
+
             String agg = deps[i].getAttribute("aggregate");
             boolean aggregate = agg != null && agg.equalsIgnoreCase("true");
-            String id = deps[i].getAttribute("id");
+            String identitity = deps[i].getAttribute("id");
 
-            int scopePolicy = -1;
-            String scope = deps[i].getAttribute("scope"); 
+            String scope = deps[i].getAttribute("scope");
+            BundleContext context = getInstanceManager().getContext(); // Get the default bundle context.
             if (scope != null) {
-                if (scope.equalsIgnoreCase("global")) {
-                    scopePolicy = PolicyServiceContext.GLOBAL;
+                // If we are not in a composite, the policy is set to global.
+                if (scope.equalsIgnoreCase("global") || ((((IPojoContext) getInstanceManager().getContext()).getServiceContext()) == null)) {
+                    context =
+                            new PolicyServiceContext(getInstanceManager().getGlobalContext(), getInstanceManager().getLocalServiceContext(),
+                                    PolicyServiceContext.GLOBAL);
                 } else if (scope.equalsIgnoreCase("composite")) {
-                    scopePolicy = PolicyServiceContext.LOCAL;
+                    context =
+                            new PolicyServiceContext(getInstanceManager().getGlobalContext(), getInstanceManager().getLocalServiceContext(),
+                                    PolicyServiceContext.LOCAL);
                 } else if (scope.equalsIgnoreCase("composite+global")) {
-                    scopePolicy = PolicyServiceContext.LOCAL_AND_GLOBAL;
+                    context =
+                            new PolicyServiceContext(getInstanceManager().getGlobalContext(), getInstanceManager().getLocalServiceContext(),
+                                    PolicyServiceContext.LOCAL_AND_GLOBAL);
                 }
             }
 
             // Get instance filter if available
-            if (filtersConfiguration != null && id != null && filtersConfiguration.get(id) != null) {
-                filter = (String) filtersConfiguration.get(id);
+            if (filtersConfiguration != null && identitity != null && filtersConfiguration.get(identitity) != null) {
+                filter = (String) filtersConfiguration.get(identitity);
             }
-            
-            
-            // Parse binding policy
-            int bindingPolicy = Dependency.DYNAMIC_POLICY;
-            String policy = deps[i].getAttribute("policy"); 
-            if (policy != null) {
-                if (policy.equalsIgnoreCase("static")) {
-                    bindingPolicy = Dependency.STATIC_POLICY;
-                } else if (policy.equalsIgnoreCase("dynamic")) {
-                    bindingPolicy = Dependency.DYNAMIC_POLICY;
-                } else if (policy.equalsIgnoreCase("dynamic-priority")) {
-                    bindingPolicy = Dependency.DYNAMIC_PRIORITY_POLICY;
+
+            Filter fil = null;
+            if (filter != null) {
+                try {
+                    fil = getInstanceManager().getContext().createFilter(filter);
+                } catch (InvalidSyntaxException e) {
+                    throw new ConfigurationException("A requirement filter is invalid : " + filter + " - " + e.getMessage());
                 }
             }
-            
-            Dependency dep = new Dependency(this, field, serviceSpecification, filter, optional, aggregate, id, scopePolicy, bindingPolicy, di);
+
+            Class spec = null;
+            if (serviceSpecification != null) {
+                spec = DependencyModel.loadSpecification(serviceSpecification, getInstanceManager().getContext());
+            }
+
+            int policy = DependencyModel.getPolicy(deps[i]);
+            Comparator cmp = DependencyModel.getComparator(deps[i], getInstanceManager().getGlobalContext());
+            Dependency dep = new Dependency(this, field, spec, fil, optional, aggregate, identitity, context, policy, cmp, defaultImplem);
 
             // Look for dependency callback :
-            for (int j = 0; j < (deps[i].getElements("Callback", "")).length; j++) {
-                if (!(deps[i].getElements("Callback", "")[j].containsAttribute("method") && deps[i].getElements("Callback", "")[j].containsAttribute("type"))) { 
-                    throw new ConfigurationException("Requirement Callback : a dependency callback must contain a method and a type attribute"); 
+            Element[] cbs = deps[i].getElements("Callback");
+            for (int j = 0; cbs != null && j < cbs.length; j++) {
+                if (!cbs[j].containsAttribute("method") && cbs[j].containsAttribute("type")) {
+                    throw new ConfigurationException("Requirement Callback : a dependency callback must contain a method and a type attribute");
                 }
-                String method = deps[i].getElements("Callback", "")[j].getAttribute("method");
-                String type = deps[i].getElements("Callback", "")[j].getAttribute("type");
+                String method = cbs[j].getAttribute("method");
+                String type = cbs[j].getAttribute("type");
                 int methodType = 0;
                 if ("bind".equalsIgnoreCase(type)) {
                     methodType = DependencyCallback.BIND;
@@ -277,74 +338,49 @@
                     methodType = DependencyCallback.UNBIND;
                 }
 
-                DependencyCallback dc = new DependencyCallback(dep, method, methodType);
-                dep.addDependencyCallback(dc);
+                DependencyCallback callback = new DependencyCallback(dep, method, methodType);
+                dep.addDependencyCallback(callback);
             }
 
             // Check the dependency :
             if (checkDependency(dep, manipulation)) {
                 addDependency(dep);
                 if (dep.getField() != null) {
-                    fl.add(manipulation.getField(dep.getField()));
+                    getInstanceManager().register(manipulation.getField(dep.getField()), dep);
+                    atLeastOneField = true;
                 }
             }
         }
 
-        if (deps.length > 0) {
-            getInstanceManager().register(this, (FieldMetadata[]) fl.toArray(new FieldMetadata[0]), manipulation.getMethods());
-        } else {
-            throw new ConfigurationException("No dependencies found in " + getInstanceManager().getInstanceName());
-        }
-    }
-
-    /**
-     * GetterCallback Method.
-     * @param fieldName : the field name.
-     * @param value : the value passed to the field (by the previous handler).
-     * @return the object that the dependency handler want to push.
-     * @see org.apache.felix.ipojo.Handler#getterCallback(java.lang.String, java.lang.Object)
-     */
-    public Object getterCallback(String fieldName, Object value) {
-        for (int i = 0; i < m_dependencies.length; i++) {
-            Dependency dep = m_dependencies[i];
-            String field = dep.getField();
-            if (field != null && field.equals(fieldName)) {
-                // The field name is a dependency, return the get
-                return dep.get();
-            }
-        }
-        // Else return the value
-        return value;
-    }
-
-    /**
-     * Method Entry callback.
-     * @param methodId : method Id.
-     * @see org.apache.felix.ipojo.Handler#entryCallback(java.lang.String)
-     */
-    public void entryCallback(String methodId) {
-        for (int i = 0; i < m_dependencies.length; i++) {
-            Dependency dep = m_dependencies[i];
-            if (dep.getField() != null) {
-                dep.entry(methodId);
+        if (atLeastOneField) { // Does register only if we have fields
+            MethodMetadata[] methods = manipulation.getMethods();
+            for (int i = 0; i < methods.length; i++) {
+                for (int j = 0; j < m_dependencies.length; j++) {
+                    getInstanceManager().register(methods[i], m_dependencies[j]);
+                }
             }
         }
     }
 
-    /**
-     * Method Exit callback.
-     * @param methodId : method id.
-     * @param returnedObj : returned object.
-     * @see org.apache.felix.ipojo.Handler#exitCallback(java.lang.String, java.lang.Object)
-     */
-    public void exitCallback(String methodId, Object returnedObj) {
-        for (int i = 0; i < m_dependencies.length; i++) {
-            Dependency dep = m_dependencies[i];
-            if (dep.getField() != null) {
-                dep.exit(methodId);
-            }
-        }
-    }
+//    /**
+//     * GetterCallback Method.
+//     * @param pojo : the pojo object on which the field is accessed
+//     * @param fieldName : the field name.
+//     * @param value : the value passed to the field (by the previous handler).
+//     * @return the object that the dependency handler want to push.
+//     * @see org.apache.felix.ipojo.Handler#onGet(Object, java.lang.String, java.lang.Object)
+//     */
+//    public Object onGet(Object pojo, String fieldName, Object value) {
+//        for (int i = 0; i < m_dependencies.length; i++) {
+//            Dependency dep = m_dependencies[i];
+//            if (fieldName.equals(dep.getField())) {
+//                // The field name is a dependency, return the get
+//                return dep.get();
+//            }
+//        }
+//        // Else return the value
+//        return value;
+//    }
 
     /**
      * Handler start method.
@@ -358,6 +394,7 @@
         }
         // Check the state
         m_started = true;
+        setValidity(false);
         checkContext();
     }
 
@@ -373,27 +410,13 @@
     }
 
     /**
-     * Handler createInstance method.
-     * This method is override to allow delayed callback invocation.
+     * Handler createInstance method. This method is override to allow delayed callback invocation.
      * @param instance : the created object
-     * @see org.apache.felix.ipojo.Handler#objectCreated(java.lang.Object)
+     * @see org.apache.felix.ipojo.Handler#onCreation(java.lang.Object)
      */
-    public void objectCreated(Object instance) {
+    public void onCreation(Object instance) {
         for (int i = 0; i < m_dependencies.length; i++) {
-            m_dependencies[i].callBindMethod(instance);
-        }
-    }
-    
-    /**
-     * The instance state changes. If the new state is valid, we need to activate dependencies.
-     * @param state : the new state
-     * @see org.apache.felix.ipojo.Handler#stateChanged(int)
-     */
-    public void stateChanged(int state) {
-        if (state == ComponentInstance.VALID) {
-            for (int i = 0; i < m_dependencies.length; i++) {
-                m_dependencies[i].activate();
-            }
+            m_dependencies[i].onObjectCreation(instance);
         }
     }
 
@@ -407,10 +430,11 @@
         for (int j = 0; j < getDependencies().length; j++) {
             Dependency dep = getDependencies()[j];
             // Create & add the dependency description
-            DependencyDescription dd = new DependencyDescription(dep.getSpecification(), dep.isAggregate(), dep.isOptional(), dep.getFilter(), dep.getState());
-            dd.setServiceReferences(dep.getServiceReferences());
-            dd.setUsedServices(dep.getUsedServices());
-            dhd.addDependency(dd);
+            DependencyDescription desc =
+                    new DependencyDescription(dep.getSpecification().getName(), dep.isAggregate(), dep.isOptional(), dep.getFilter(), dep.getState());
+            desc.setServiceReferences(dep.getServiceReferencesAsList());
+            desc.setUsedServices(dep.getUsedServiceReferences());
+            dhd.addDependency(desc);
         }
         return dhd;
     }

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?rev=642265&r1=642264&r2=642265&view=diff
==============================================================================
--- 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 Mar 28 08:33:36 2008
@@ -42,10 +42,10 @@
 
     /**
      * Constructor.
-     * @param h : Handler.
+     * @param handler : Handler.
      */
-    public DependencyHandlerDescription(Handler h) {
-        super(h);
+    public DependencyHandlerDescription(Handler handler) {
+        super(handler);
     }
 
     /**
@@ -94,7 +94,7 @@
             Element dep = new Element("Requires", "");
             dep.addAttribute(new Attribute("Specification", m_dependencies[i].getInterface()));
             
-            if (!"".equals(m_dependencies[i].getFilter())) {
+            if (m_dependencies[i].getFilter() != null) {
                 dep.addAttribute(new Attribute("Filter", m_dependencies[i].getFilter()));
             }
             
@@ -112,16 +112,18 @@
             
             dep.addAttribute(new Attribute("State", state));
             List set = m_dependencies[i].getUsedServices();
-            Iterator it = set.iterator();
-            while (it.hasNext()) {
-                Element use = new Element("Uses", "");
-                ServiceReference ref = (ServiceReference) it.next();
-                use.addAttribute(new Attribute("service.id", ref.getProperty(Constants.SERVICE_ID).toString()));                
-                String in = (String) ref.getProperty("instance.name");
-                if (in != null) {
-                    use.addAttribute(new Attribute("instance.name", in));
+            if (set != null) {
+                Iterator iterator = set.iterator();
+                while (iterator.hasNext()) {
+                    Element use = new Element("Uses", "");
+                    ServiceReference ref = (ServiceReference) iterator.next();
+                    use.addAttribute(new Attribute("service.id", ref.getProperty(Constants.SERVICE_ID).toString()));                
+                    String instance = (String) ref.getProperty("instance.name");
+                    if (instance != null) {
+                        use.addAttribute(new Attribute("instance.name", instance));
+                    }
+                    dep.addElement(use);
                 }
-                dep.addElement(use);
             }
             
             deps.addElement(dep);

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/NullableObject.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/NullableObject.java?rev=642265&r1=642264&r2=642265&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/NullableObject.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/NullableObject.java Fri Mar 28 08:33:36 2008
@@ -26,41 +26,42 @@
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
 public class NullableObject implements InvocationHandler {
-    
+
     /**
      * Default boolean value.
      */
     private static final Boolean DEFAULT_BOOLEAN = Boolean.FALSE;
+
     /**
      * Default byte value.
      */
     private static final Byte DEFAULT_BYTE = new Byte((byte) 0);
-    
+
     /**
      * Default short value.
      */
     private static final Short DEFAULT_SHORT = new Short((short) 0);
-    
+
     /**
      * Default integer value.
      */
     private static final Integer DEFAULT_INT = new Integer(0);
-    
+
     /**
      * Default long value.
      */
     private static final Long DEFAULT_LONG = new Long(0);
-    
+
     /**
      * Default float value.
      */
     private static final Float DEFAULT_FLOAT = new Float(0.0f);
-    
+
     /**
      * Default double value.
      */
     private static final Double DEFAULT_DOUBLE = new Double(0.0);
-    
+
     /**
      * Invokes a method on this null object. The method will return a default
      * value without doing anything.
@@ -72,19 +73,19 @@
      */
     public Object invoke(Object proxy, Method method, Object[] args) {
         Class returnType = method.getReturnType();
-        if (returnType.equals(Boolean.TYPE)) {
+        if (Boolean.TYPE.equals(returnType)) {
             return DEFAULT_BOOLEAN;
-        } else if (returnType.equals(Byte.TYPE)) {
+        } else if (Byte.TYPE.equals(returnType)) {
             return DEFAULT_BYTE;
-        } else if (returnType.equals(Short.TYPE)) {
+        } else if (Short.TYPE.equals(returnType)) {
             return DEFAULT_SHORT;
-        } else if (returnType.equals(Integer.TYPE)) {
+        } else if (Integer.TYPE.equals(returnType)) {
             return DEFAULT_INT;
-        } else if (returnType.equals(Long.TYPE)) {
+        } else if (Long.TYPE.equals(returnType)) {
             return DEFAULT_LONG;
-        } else if (returnType.equals(Float.TYPE)) {
+        } else if (Float.TYPE.equals(returnType)) {
             return DEFAULT_FLOAT;
-        } else if (returnType.equals(Double.TYPE)) {
+        } else if (Double.TYPE.equals(returnType)) {
             return DEFAULT_DOUBLE;
         } else {
             return null;

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/ServiceUsage.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/ServiceUsage.java?rev=642265&r1=642264&r2=642265&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/ServiceUsage.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/ServiceUsage.java Fri Mar 28 08:33:36 2008
@@ -18,8 +18,6 @@
  */
 package org.apache.felix.ipojo.handlers.dependency;
 
-import java.util.ArrayList;
-import java.util.List;
 
 /**
  * Object managing thread local copy of required services.
@@ -31,19 +29,40 @@
     /**
      * Structure contained in the Thread Local.
      */
-    private class Usage {
+    public class Usage {
+        
         /**
          * Stack Size.
          */
-        Integer m_stack = new Integer(0);
+        int m_stack = 0;
         /**
-         * List of used service references.
+         * List of used objects.
          */
-        List m_refs = new ArrayList();
+        Object[] m_objects;
+        
         /**
-         * List of used objects.
+         * Increment the statck level.
+         */
+        public void inc() {
+            m_stack++;
+        }
+        
+        /**
+         * Decrement the stack level.
+         * @return  true if the stack is 0 after the decrement.
          */
-        List m_objects = new ArrayList();
+        public boolean dec() {
+            m_stack--;
+            return m_stack == 0;
+        }
+        
+        /**
+         * Clear the service object array.
+         */
+        public void clear() {
+            m_objects = null;
+        }
+        
     }
     
     /**
@@ -53,45 +72,6 @@
      */
     public Object initialValue() {
         return new Usage();
-    }
-    
-    /**
-     * Get the list of stored references.
-     * @return the list of stored references.
-     */
-    public List getReferences() {
-        Usage use = (Usage) super.get();
-        return use.m_refs;
-    }
-    
-    /**
-     * Get the lost of stored object.
-     * @return the list of stored service objects.
-     */
-    public List getObjects() {
-        Usage use = (Usage) super.get();
-        return use.m_objects;
-    }
-    
-    /**
-     * Get the stack level.
-     * @return the stack level.
-     */
-    public int getStackLevel() {
-        Usage use = (Usage) super.get();
-        return use.m_stack.intValue();
-    }
-    
-    /**
-     * Set the stack level.
-     * @param level : the new stack level.
-     */
-    public void setStackLevel(int level) {
-        Usage use = (Usage) super.get();
-        use.m_stack = new Integer(level);
-    }
-    
-    
-    
+    }   
 
 }

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallback.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallback.java?rev=642265&r1=642264&r2=642265&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallback.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallback.java Fri Mar 28 08:33:36 2008
@@ -53,29 +53,29 @@
     /**
      * LifecycleCallback constructor.
      * 
-     * @param hh : the callback handler calling the callback
+     * @param handler : the callback handler calling the callback
      * @param transition : transition on which calling the callback
-     * @param mm : method metadata to invoke
+     * @param method : method metadata to invoke
      */
-    public LifecycleCallback(LifecycleCallbackHandler hh, int transition, MethodMetadata mm) {
+    public LifecycleCallback(LifecycleCallbackHandler handler, int transition, MethodMetadata method) {
         m_transition = transition;
-        m_callback = new Callback(mm, hh.getInstanceManager());
+        m_callback = new Callback(method, handler.getInstanceManager());
     }
     
     /**
      * LifecycleCallback constructor.
      * 
-     * @param hh : the callback handler calling the callback
+     * @param handler : the callback handler calling the callback
      * @param transition : transition on which calling the callback
-     * @param mm : method name to invoke
+     * @param method : method name to invoke
      */
-    public LifecycleCallback(LifecycleCallbackHandler hh, int transition, String mm) {
+    public LifecycleCallback(LifecycleCallbackHandler handler, int transition, String method) {
         m_transition = transition;
-        m_callback = new Callback(mm, new String[0], false, hh.getInstanceManager());
+        m_callback = new Callback(method, new String[0], false, handler.getInstanceManager());
     }
 
     /**
-     * Call the callback method when the transition from inital to final state is
+     * Call the callback method when the transition from inital tostate is
      * detected.
      * 
      * @throws NoSuchMethodException : Method is not found in the class

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallbackHandler.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallbackHandler.java?rev=642265&r1=642264&r2=642265&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallbackHandler.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallbackHandler.java Fri Mar 28 08:33:36 2008
@@ -26,9 +26,8 @@
 import org.apache.felix.ipojo.InstanceManager;
 import org.apache.felix.ipojo.PrimitiveHandler;
 import org.apache.felix.ipojo.metadata.Element;
-import org.apache.felix.ipojo.parser.ManipulationMetadata;
 import org.apache.felix.ipojo.parser.MethodMetadata;
-import org.apache.felix.ipojo.util.Logger;
+import org.apache.felix.ipojo.parser.PojoMetadata;
 
 /**
  * Lifecycle callback handler.
@@ -54,11 +53,11 @@
     /**
      * Add the given callback to the callback list.
      * 
-     * @param hk : the element to add
+     * @param callback : the element to add
      */
-    private void addCallback(LifecycleCallback hk) {
+    private void addCallback(LifecycleCallback callback) {
         for (int i = 0; (m_callbacks != null) && (i < m_callbacks.length); i++) {
-            if (m_callbacks[i] == hk) {
+            if (m_callbacks[i] == callback) {
                 return;
             }
         }
@@ -66,10 +65,10 @@
         if (m_callbacks.length > 0) {
             LifecycleCallback[] newHk = new LifecycleCallback[m_callbacks.length + 1];
             System.arraycopy(m_callbacks, 0, newHk, 0, m_callbacks.length);
-            newHk[m_callbacks.length] = hk;
+            newHk[m_callbacks.length] = callback;
             m_callbacks = newHk;
         } else {
-            m_callbacks = new LifecycleCallback[] { hk };
+            m_callbacks = new LifecycleCallback[] { callback };
         }
 
     }
@@ -87,38 +86,38 @@
         String imm = metadata.getAttribute("immediate");
         m_immediate = imm != null && imm.equalsIgnoreCase("true");
         
-        ManipulationMetadata mm = new ManipulationMetadata(metadata);
+        PojoMetadata meta = getFactory().getPojoMetadata();
 
         Element[] hooksMetadata = metadata.getElements("callback");
-        for (int i = 0; i < hooksMetadata.length; i++) {
+        for (int i = 0; hooksMetadata != null && i < hooksMetadata.length; i++) {
             String method = hooksMetadata[i].getAttribute("method");
             if (method == null) {
                 throw new ConfigurationException("Lifecycle callback : A callback needs to contains a method attribute");
             }
             
-            MethodMetadata met = mm.getMethod(method, new String[0]);
+            MethodMetadata met = meta.getMethod(method, new String[0]);
             
             int transition = -1;
             String trans = hooksMetadata[i].getAttribute("transition");
-            if (trans != null) {
+            if (trans == null) {
+                throw new ConfigurationException("Lifecycle callback : the transition attribute is missing");
+            } else {
                 if (trans.equalsIgnoreCase("validate")) {
                     transition = LifecycleCallback.VALIDATE;
                 } else if (trans.equalsIgnoreCase("invalidate")) {
                     transition = LifecycleCallback.INVALIDATE; 
                 } else {
-                    throw new ConfigurationException("Lifecycle callback : Unknown or malformed transition : " + transition);
+                    throw new ConfigurationException("Lifecycle callback : Unknown or malformed transition : " + trans);
                 }
-            } else {
-                throw new ConfigurationException("Lifecycle callback : Unknown or malformed transition");
             }
             
-            LifecycleCallback hk = null;
-            if (met != null) { 
-                hk = new LifecycleCallback(this, transition, met);
+            LifecycleCallback callback = null;
+            if (met == null) {
+                callback = new LifecycleCallback(this, transition, method);
             } else {
-                hk = new LifecycleCallback(this, transition, method);
+                callback = new LifecycleCallback(this, transition, met);
             }
-            addCallback(hk);
+            addCallback(callback);
         }
     }
 
@@ -127,7 +126,8 @@
      * @see org.apache.felix.ipojo.Handler#start()
      */
     public void start() {
-    } // Do nothing during the start
+     // Do nothing during the start
+    } 
 
     /**
      * Stop the handler.
@@ -162,13 +162,13 @@
                 try {
                     m_callbacks[i].call();
                 } catch (NoSuchMethodException e) {
-                    log(Logger.ERROR, "[" + getInstanceManager().getInstanceName() + "] The callback method " + m_callbacks[i].getMethod() + " is not found", e);
-                    getInstanceManager().stop();
+                    error("[" + getInstanceManager().getInstanceName() + "] The callback method " + m_callbacks[i].getMethod() + " is not found");
+                    throw new IllegalStateException(e.getMessage());
                 } catch (IllegalAccessException e) {
-                    log(Logger.ERROR, "[" + getInstanceManager().getInstanceName() + "] The callback method " + m_callbacks[i].getMethod() + " is not accessible", e);
-                    getInstanceManager().stop();
+                    error("[" + getInstanceManager().getInstanceName() + "] The callback method " + m_callbacks[i].getMethod() + " is not accessible");
+                    throw new IllegalStateException(e.getMessage());
                 } catch (InvocationTargetException e) {
-                    log(Logger.ERROR, "[" + getInstanceManager().getInstanceName() + "] The callback method " + m_callbacks[i].getMethod() + " has throws an exception : " + e.getTargetException().getMessage());
+                    error("[" + getInstanceManager().getInstanceName() + "] The callback method " + m_callbacks[i].getMethod() + " has throws an exception : " + e.getTargetException().getMessage(), e.getTargetException());
                     getInstanceManager().setState(ComponentInstance.INVALID);
                 }
             }

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/controller/ControllerHandler.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/controller/ControllerHandler.java?rev=642265&r1=642264&r2=642265&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/controller/ControllerHandler.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/controller/ControllerHandler.java Fri Mar 28 08:33:36 2008
@@ -24,11 +24,10 @@
 import org.apache.felix.ipojo.ConfigurationException;
 import org.apache.felix.ipojo.InstanceManager;
 import org.apache.felix.ipojo.PrimitiveHandler;
-import org.apache.felix.ipojo.architecture.ComponentDescription;
+import org.apache.felix.ipojo.architecture.ComponentTypeDescription;
 import org.apache.felix.ipojo.metadata.Element;
 import org.apache.felix.ipojo.parser.FieldMetadata;
-import org.apache.felix.ipojo.parser.ManipulationMetadata;
-import org.apache.felix.ipojo.util.Logger;
+import org.apache.felix.ipojo.parser.PojoMetadata;
 
 /**
  * Lifecycle Controller handler.
@@ -51,9 +50,9 @@
      * @see org.apache.felix.ipojo.Handler#configure(org.apache.felix.ipojo.InstanceManager, org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)
      */
     public void configure(Element metadata, Dictionary configuration) throws ConfigurationException {
-        Element[] lc = metadata.getElements("controller");
-        String field = lc[0].getAttribute("field");   
-        getInstanceManager().register(this, new FieldMetadata[] {new FieldMetadata(field, "boolean")}, null);
+        Element[] controller = metadata.getElements("controller");
+        String field = controller[0].getAttribute("field");   
+        getInstanceManager().register(new FieldMetadata(field, "boolean"), this);
     }
 
     /**
@@ -70,38 +69,42 @@
      * Nothing to do. 
      * @see org.apache.felix.ipojo.Handler#stop()
      */
-    public void stop() { }
+    public void stop() { 
+        // Nothing to do.
+    }
     
     /**
      * GetterCallback.
+     * @param pojo : the pojo object on which the field is accessed
      * Return the stored value.
      * @param field : field name.
-     * @param o : value given by the previous handler.
+     * @param value : value given by the previous handler.
      * @return : the handler state.
      */
-    public Object getterCallback(String field, Object o) {
+    public Object onGet(Object pojo, String field, Object value) {
         return new Boolean(m_state);
     }
     
     /**
      * SetterCallback.
+     * @param pojo : the pojo object on which the field is accessed
      * Store the new field value & invalidate / validate the handler is required.
      * @param field : field name.
-     * @param o : new value.
+     * @param value : new value.
      */
-    public void setterCallback(String field, Object o) {
-        if (o instanceof Boolean) {
-            boolean nv = ((Boolean) o).booleanValue();
-            if (nv != m_state) {
-                m_state = nv;
+    public void onSet(Object pojo, String field, Object value) {
+        if (value instanceof Boolean) {
+            boolean newValue = ((Boolean) value).booleanValue();
+            if (newValue != m_state) {
+                m_state = newValue;
                 if (m_state) {
-                    ((InstanceManager) getInstance()).setState(ComponentInstance.VALID);
+                    ((InstanceManager) getHandlerManager()).setState(ComponentInstance.VALID);
                 } else {
-                    ((InstanceManager) getInstance()).setState(ComponentInstance.INVALID);
+                    ((InstanceManager) getHandlerManager()).setState(ComponentInstance.INVALID);
                 }
             }
         } else {
-            log(Logger.ERROR, "Boolean expected for the lifecycle controller");
+            error("Boolean expected for the lifecycle controller");
             getInstanceManager().stop();
         }
     }
@@ -109,28 +112,28 @@
     /**
      * Initialize the component factory.
      * The controller field is checked to avoid configure check.
-     * @param cd : component description
+     * @param desc : component description
      * @param metadata : component type metadata
      * @throws ConfigurationException : occurs if the controller field is not in the POJO class or is not a boolean.
-     * @see org.apache.felix.ipojo.Handler#initializeComponentFactory(org.apache.felix.ipojo.architecture.ComponentDescription, org.apache.felix.ipojo.metadata.Element)
+     * @see org.apache.felix.ipojo.Handler#initializeComponentFactory(org.apache.felix.ipojo.architecture.ComponentTypeDescription, org.apache.felix.ipojo.metadata.Element)
      */
-    public void initializeComponentFactory(ComponentDescription cd, Element metadata) throws ConfigurationException {
+    public void initializeComponentFactory(ComponentTypeDescription desc, Element metadata) throws ConfigurationException {
         String field = null;
-        Element[] lc = metadata.getElements("controller");
+        Element[] controller = metadata.getElements("controller");
         // Use only the first controller
-        field = lc[0].getAttribute("field");
+        field = controller[0].getAttribute("field");
         if (field == null) {
             throw new ConfigurationException("Lifecycle controller : the controller element needs to have a field attribute");
         }
         
-        ManipulationMetadata mm = new ManipulationMetadata(metadata);
-        FieldMetadata fm = mm.getField(field);
-        if (fm == null) {
+        PojoMetadata method = getFactory().getPojoMetadata();
+        FieldMetadata fieldMetadata = method.getField(field);
+        if (fieldMetadata == null) {
             throw new ConfigurationException("Lifecycle controller : The field " + field + " does not exist in the class");
         }
         
-        if (!fm.getFieldType().equalsIgnoreCase("boolean")) {
-            throw new ConfigurationException("Lifecycle controller : The field " + field + " must be a boolean (" + fm.getFieldType() + " found)");
+        if (!fieldMetadata.getFieldType().equalsIgnoreCase("boolean")) {
+            throw new ConfigurationException("Lifecycle controller : The field " + field + " must be a boolean (" + fieldMetadata.getFieldType() + " found)");
         }
     }
 

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?rev=642265&r1=642264&r2=642265&view=diff
==============================================================================
--- 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 Mar 28 08:33:36 2008
@@ -22,8 +22,9 @@
 import java.util.Enumeration;
 import java.util.Properties;
 
+import org.apache.felix.ipojo.ConfigurationException;
 import org.apache.felix.ipojo.InstanceManager;
-import org.apache.felix.ipojo.util.Logger;
+import org.apache.felix.ipojo.util.Property;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.ServiceFactory;
 import org.osgi.framework.ServiceReference;
@@ -55,6 +56,11 @@
      * Factory policy : SERVICE_FACTORY.
      */
     public static final int SERVICE_FACTORY = 1;
+    
+    /**
+     * Factory policy : STATIC_FACTORY.
+     */
+    public static final int STATIC_FACTORY = 2;
 
     /**
      * At this time, it is only the java interface full name.
@@ -80,7 +86,7 @@
     /**
      * Properties Array.
      */
-    private Property[] m_properties = new Property[0];
+    private Property[] m_properties;
 
     /**
      * Construct a provided service object.
@@ -96,8 +102,12 @@
         m_factoryPolicy = factoryPolicy;
         
         // Add instance name & factory name
-        addProperty(new Property(this, "instance.name", handler.getInstanceManager().getInstanceName()));       
-        addProperty(new Property(this, "factory.name", handler.getInstanceManager().getFactory().getName()));
+        try {
+            addProperty(new Property("instance.name", null, null, handler.getInstanceManager().getInstanceName(), String.class.getName(), handler.getInstanceManager(), handler));       
+            addProperty(new Property("factory.name", null, null, handler.getInstanceManager().getFactory().getFactoryName(), String.class.getName(), handler.getInstanceManager(), handler));
+        } catch (ConfigurationException e) {
+            m_handler.error("An exception occurs when adding instance.name and factory.name property : " + e.getMessage());
+        }
     }
 
     /**
@@ -113,22 +123,22 @@
     /**
      * Add the given property to the property list.
      * 
-     * @param p : the element to add
+     * @param prop : the element to add
      */
-    private synchronized void addProperty(Property p) {
+    private synchronized void addProperty(Property prop) {
         for (int i = 0; (m_properties != null) && (i < m_properties.length); i++) {
-            if (m_properties[i] == p) {
+            if (m_properties[i] == prop) {
                 return;
             }
         }
 
-        if (m_properties.length > 0) {
+        if (m_properties == null) {
+            m_properties = new Property[] { prop };
+        } else {
             Property[] newProp = new Property[m_properties.length + 1];
             System.arraycopy(m_properties, 0, newProp, 0, m_properties.length);
-            newProp[m_properties.length] = p;
+            newProp[m_properties.length] = prop;
             m_properties = newProp;
-        } else {
-            m_properties = new Property[] { p };
         }
     }
 
@@ -148,7 +158,7 @@
 
         if (idx >= 0) {
             if ((m_properties.length - 1) == 0) {
-                m_properties = new Property[0];
+                m_properties = null;
             } else {
                 Property[] newPropertiesList = new Property[m_properties.length - 1];
                 System.arraycopy(m_properties, 0, newPropertiesList, 0, idx);
@@ -166,10 +176,10 @@
      * service is not published).
      */
     public ServiceReference getServiceReference() {
-        if (m_serviceRegistration != null) {
-            return m_serviceRegistration.getReference();
-        } else {
+        if (m_serviceRegistration == null) {
             return null;
+        } else {
+            return m_serviceRegistration.getReference();
         }
     }
 
@@ -189,9 +199,14 @@
             case SERVICE_FACTORY:
                 svc = m_handler.getInstanceManager().createPojoObject();
                 break;
+            case STATIC_FACTORY:
+                // In this case, we need to try to create a new pojo object, the factory method will handle the creation.
+                svc = m_handler.getInstanceManager().createPojoObject();
+                break;
             default:
-                m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "[" + m_handler.getInstanceManager().getClassName() + "] Unknown factory policy for " + m_serviceSpecification + " : " + m_factoryPolicy);
+                m_handler.error("[" + m_handler.getInstanceManager().getClassName() + "] Unknown factory policy for " + m_serviceSpecification + " : " + m_factoryPolicy);
                 getInstanceManager().stop();
+                break;
         }
         return svc;
     }
@@ -258,8 +273,8 @@
         // Contruct the service properties list
         Properties serviceProperties = new Properties();
         for (int i = 0; i < m_properties.length; i++) {
-            if (m_properties[i].get() != null) {
-                serviceProperties.put(m_properties[i].getName(), m_properties[i].get());
+            if (m_properties[i].getValue() != null) {
+                serviceProperties.put(m_properties[i].getName(), m_properties[i].getValue());
             }
         }
         return serviceProperties;
@@ -278,18 +293,9 @@
      * the service registry.
      */
     public synchronized void update() {
-        // Contruct the service properties list
-        Properties serviceProperties = getServiceProperties();
-
-        if (serviceProperties == null) {
-            m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "Cannot get the properties of the provided service");
-            getInstanceManager().stop();
-            return;
-        }
-
         // Update the service registration
         if (m_serviceRegistration != null) {
-            m_serviceRegistration.setProperties(serviceProperties);
+            m_serviceRegistration.setProperties(getServiceProperties());
         }
     }
 
@@ -302,8 +308,13 @@
         while (keys.hasMoreElements()) {
             String key = (String) keys.nextElement();
             Object value = props.get(key);
-            Property prop = new Property(this, key, value);
-            addProperty(prop);
+            Property prop;
+            try {
+                prop = new Property(key, null, null, value.toString(), value.getClass().getName(), getInstanceManager(), m_handler);
+                addProperty(prop);
+            } catch (ConfigurationException e) {
+                m_handler.error("The propagated property " + key + " cannot be pcreated correctly : " + e.getMessage());
+            }
         }
     }
 

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceDescription.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceDescription.java?rev=642265&r1=642264&r2=642265&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceDescription.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceDescription.java Fri Mar 28 08:33:36 2008
@@ -69,13 +69,13 @@
      * 
      * @param serviceSpecification : the provided contract
      * @param state : state (UNREGITRED | REGISTRED)
-     * @param sr : Service Registration (to obtain the reference), or null if
+     * @param ref : Service Registration (to obtain the reference), or null if
      * state is UNREGISTRED
      */
-    public ProvidedServiceDescription(String[] serviceSpecification, int state, ServiceReference sr) {
+    public ProvidedServiceDescription(String[] serviceSpecification, int state, ServiceReference ref) {
         m_serviceSpecification = serviceSpecification;
         m_state = state;
-        m_serviceReference = sr;
+        m_serviceReference = ref;
         // m_parent = parent;
     }
 

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?rev=642265&r1=642264&r2=642265&view=diff
==============================================================================
--- 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 Mar 28 08:33:36 2008
@@ -19,7 +19,6 @@
 package org.apache.felix.ipojo.handlers.providedservice;
 
 import java.lang.reflect.Field;
-import java.util.ArrayList;
 import java.util.Dictionary;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -28,10 +27,10 @@
 import java.util.Set;
 
 import org.apache.felix.ipojo.ConfigurationException;
-import org.apache.felix.ipojo.IPojoConfiguration;
+import org.apache.felix.ipojo.HandlerFactory;
 import org.apache.felix.ipojo.InstanceManager;
 import org.apache.felix.ipojo.PrimitiveHandler;
-import org.apache.felix.ipojo.architecture.ComponentDescription;
+import org.apache.felix.ipojo.architecture.ComponentTypeDescription;
 import org.apache.felix.ipojo.architecture.HandlerDescription;
 import org.apache.felix.ipojo.architecture.PropertyDescription;
 import org.apache.felix.ipojo.handlers.dependency.Dependency;
@@ -40,9 +39,10 @@
 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.parser.PojoMetadata;
+import org.apache.felix.ipojo.util.Property;
 import org.osgi.framework.Bundle;
 
 /**
@@ -60,21 +60,21 @@
     /**
      * Add a provided service to the list .
      * 
-     * @param ps : the provided service to add
+     * @param svc : the provided service to add
      */
-    private void addProvidedService(ProvidedService ps) {
+    private void addProvidedService(ProvidedService svc) {
         // Verify that the provided service is not already in the array.
         for (int i = 0; (m_providedServices != null) && (i < m_providedServices.length); i++) {
-            if (m_providedServices[i] == ps) { return; }
+            if (m_providedServices[i] == svc) { return; }
         }
 
         if (m_providedServices.length > 0) {
             ProvidedService[] newPS = new ProvidedService[m_providedServices.length + 1];
             System.arraycopy(m_providedServices, 0, newPS, 0, m_providedServices.length);
-            newPS[m_providedServices.length] = ps;
+            newPS[m_providedServices.length] = svc;
             m_providedServices = newPS;
         } else {
-            m_providedServices = new ProvidedService[] { ps };
+            m_providedServices = new ProvidedService[] { svc };
         }
     }
 
@@ -97,7 +97,6 @@
         m_providedServices = new ProvidedService[0];
         // Create the dependency according to the component metadata
         Element[] providedServices = componentMetadata.getElements("Provides");
-        List fields = new ArrayList();
         for (int i = 0; i < providedServices.length; i++) {
             String[] serviceSpecifications = ParseUtils.parseArrays(providedServices[i].getAttribute("interface")); // Set by the initialize component factory.
             
@@ -107,62 +106,54 @@
             if (fact != null && "service".equalsIgnoreCase(fact)) {
                 factory = ProvidedService.SERVICE_FACTORY;
             }
+            if (fact != null && "method".equalsIgnoreCase(fact)) {
+                factory = ProvidedService.STATIC_FACTORY;
+            }
 
             // Then create the provided service
-            ProvidedService ps = new ProvidedService(this, serviceSpecifications, factory);
+            ProvidedService svc = new ProvidedService(this, serviceSpecifications, factory);
 
             Element[] props = providedServices[i].getElements("Property");
-            Property[] properties = new Property[props.length];
-            for (int j = 0; j < props.length; j++) {
-                String name = props[j].getAttribute("name");
-                String value = props[j].getAttribute("value");
-                String type = props[j].getAttribute("type");
-                String field = props[j].getAttribute("field");
-
-                if (name != null && configuration.get(name) != null && configuration.get(name) instanceof String) {
-                    value = (String) configuration.get(name);
-                } else {
-                    if (field != null && configuration.get(field) != null && configuration.get(field) instanceof String) {
-                        value = (String) configuration.get(field);
+            if (props != null) {
+                //Property[] properties = new Property[props.length];
+                Property[] properties = new Property[props.length];
+                for (int j = 0; j < props.length; j++) {
+                    String name = props[j].getAttribute("name");
+                    String value = props[j].getAttribute("value");
+                    String type = props[j].getAttribute("type");
+                    String field = props[j].getAttribute("field");
+
+                    Property prop = new Property(name, field, null, value, type, getInstanceManager(), this);
+                    properties[j] = prop;
+
+                    // Check if the instance configuration has a value for this property                    
+                    Object object = configuration.get(prop.getName());
+                    if (object != null) {
+                        prop.setValue(object);
                     }
-                }
-
-                Property prop = new Property(ps, name, field, type, value);
-                properties[j] = prop;
-                
-                // Check if the instance configuration has a value for this property
-                Object o = configuration.get(prop.getName()); 
-                if (o != null && ! (o instanceof String)) {
-                    prop.set(o);
-                } else {
+                    
                     if (field != null) {
-                        o = configuration.get(field);
-                        if (o != null && !(o instanceof String)) {
-                            prop.set(configuration.get(field));
-                        }
+                        getInstanceManager().register(new FieldMetadata(field, type), this);
+                        // Cannot register the property as the interception is necessary to deal with registration update.
                     }
                 }
-                
-                if (field != null) {
-                    fields.add(new FieldMetadata(field, type));
-                }
-            }
 
-            // Attached to properties to the provided service
-            ps.setProperties(properties);
+                // Attach to properties to the provided service
+                svc.setProperties(properties);
+            }
 
-            if (checkProvidedService(ps)) {
-                addProvidedService(ps);
+            if (checkProvidedService(svc)) {
+                addProvidedService(svc);
             } else {
-                String itfs = "";
+                StringBuffer itfs = new StringBuffer();
                 for (int j = 0; j < serviceSpecifications.length; j++) {
-                    itfs = itfs + " " + serviceSpecifications[j];
+                    itfs.append(' ');
+                    itfs.append(serviceSpecifications[j]);
                 }
                 throw new ConfigurationException("[" + getInstanceManager().getInstanceName() + "] The provided service" + itfs + " is not valid");                
             }
 
         }
-        getInstanceManager().register(this, (FieldMetadata[]) fields.toArray(new FieldMetadata[fields.size()]), null);
     }
     
     /**
@@ -185,8 +176,8 @@
 
         // Look for parent class.
         if (parent != null) {
-            Class cl = bundle.loadClass(parent);
-            collectInterfacesFromClass(cl, result, bundle);
+            Class clazz = bundle.loadClass(parent);
+            collectInterfacesFromClass(clazz, result, bundle);
         }
 
         return result;
@@ -195,78 +186,78 @@
     /**
      * Look for inherited interfaces.
      * @param clazz : interface name to explore (class object)
-     * @param l : set (accumulator)
-     * @param b : bundle
+     * @param acc : set (accumulator)
+     * @param bundle : bundle
      * @throws ClassNotFoundException : occurs when an interface cannot be loaded.
      */
-    private void collectInterfaces(Class clazz, Set l, Bundle b) throws ClassNotFoundException {
+    private void collectInterfaces(Class clazz, Set acc, Bundle bundle) throws ClassNotFoundException {
         Class[] clazzes = clazz.getInterfaces();
         for (int i = 0; i < clazzes.length; i++) {
-            l.add(clazzes[i].getName());
-            collectInterfaces(clazzes[i], l, b);
+            acc.add(clazzes[i].getName());
+            collectInterfaces(clazzes[i], acc, bundle);
         }
     }
     
     /**
      * Collect interfaces for the given class.
      * This method explores super class to.
-     * @param cl : class object.
-     * @param l : set of implemented interface (accumulator)
-     * @param b : bundle.
+     * @param clazz : class object.
+     * @param acc : set of implemented interface (accumulator)
+     * @param bundle : bundle.
      * @throws ClassNotFoundException : occurs if an interface cannot be load.
      */
-    private void collectInterfacesFromClass(Class cl, Set l, Bundle b) throws ClassNotFoundException {
-        Class[] clazzes = cl.getInterfaces();
+    private void collectInterfacesFromClass(Class clazz, Set acc, Bundle bundle) throws ClassNotFoundException {
+        Class[] clazzes = clazz.getInterfaces();
         for (int i = 0; i < clazzes.length; i++) {
-            l.add(clazzes[i].getName());
-            collectInterfaces(clazzes[i], l, b);
+            acc.add(clazzes[i].getName());
+            collectInterfaces(clazzes[i], acc, bundle);
         }
         // Iterate on parent classes
-        Class sup = cl.getSuperclass();
+        Class sup = clazz.getSuperclass();
         if (sup != null) {
-            collectInterfacesFromClass(sup, l, b);
+            collectInterfacesFromClass(sup, acc, bundle);
         }
     }
 
     /**
      * Check the provided service given in argument in the sense that the metadata are consistent.
-     * @param ps : the provided service to check.
+     * @param svc : the provided service to check.
      * @return true if the provided service is correct
      * @throws ConfigurationException : the checked provided service is not correct.
      */
-    private boolean checkProvidedService(ProvidedService ps) throws ConfigurationException {        
-        for (int i = 0; i < ps.getServiceSpecification().length; i++) {
-            String specName = ps.getServiceSpecification()[i];
+    private boolean checkProvidedService(ProvidedService svc) throws ConfigurationException {        
+        for (int i = 0; i < svc.getServiceSpecification().length; i++) {
+            String specName = svc.getServiceSpecification()[i];
             
             // Check service level dependencies
             try {
                 Class spec = getInstanceManager().getFactory().loadClass(specName);
                 Field specField = spec.getField("specification");
-                Object o = specField.get(null);
-                if (o instanceof String) {
-                    Element specification = ManifestMetadataParser.parse((String) o);
+                Object specif = specField.get(null);
+                if (specif instanceof String) {
+                    Element specification = ManifestMetadataParser.parse((String) specif);
                     Element[] deps = specification.getElements("requires");
-                    for (int j = 0; j < deps.length; j++) {
-                        Dependency d = getAttachedDependency(deps[j]);
-                        if (d != null) {
+                    for (int j = 0; deps != null && j < deps.length; j++) {
+                        Dependency dep = getAttachedDependency(deps[j]);
+                        if (dep != null) {
                             // Fix service-level dependency flag
-                            d.setServiceLevelDependency();
+                            dep.setServiceLevelDependency();
                         }
-                        isDependencyCorrect(d, deps[j]);
+                        isDependencyCorrect(dep, deps[j]);
                     }
                 } else {
-                    throw new ConfigurationException("Provides  : The specification field of the service specification " + ps.getServiceSpecification()[i] + " need to be a String");
+                    throw new ConfigurationException("Provides  : The specification field of the service specification " + svc.getServiceSpecification()[i] + " need to be a String");
                 }
             } catch (NoSuchFieldException e) {
                 return true; // No specification field
             } catch (ClassNotFoundException e) {
-                throw new ConfigurationException("Provides  : The service specification " + ps.getServiceSpecification()[i] + " cannot be load");
+                throw new ConfigurationException("Provides  : The service specification " + svc.getServiceSpecification()[i] + " cannot be load");
             } catch (IllegalArgumentException e) {
-                throw new ConfigurationException("Provides  : The field 'specification' of the service specification " + ps.getServiceSpecification()[i] + " is not accessible : " + e.getMessage());
+                throw new ConfigurationException("Provides  : The field 'specification' of the service specification " + svc.getServiceSpecification()[i] + " is not accessible : " + e.getMessage());
             } catch (IllegalAccessException e) {
-                throw new ConfigurationException("Provides  : The field 'specification' of the service specification " + ps.getServiceSpecification()[i] + " is not accessible : " + e.getMessage());
+                throw new ConfigurationException("Provides  : The field 'specification' of the service specification " + svc.getServiceSpecification()[i] + " is not accessible : " + e.getMessage());
             } catch (ParseException e) {
-                throw new ConfigurationException("Provides  :  The field 'specification' of the service specification " + ps.getServiceSpecification()[i] + " does not contain a valid String : " + e.getMessage());
+                throw new ConfigurationException("Provides  :  The field 'specification' of the service specification " + svc.getServiceSpecification()[i] + " does not contain a valid String : " + e.getMessage());
             }
         }
 
@@ -279,20 +270,20 @@
      * @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) getHandler(IPojoConfiguration.IPOJO_NAMESPACE + ":requires");
-        if (dh == null) { return null; }
+        DependencyHandler handler = (DependencyHandler) getHandler(HandlerFactory.IPOJO_NAMESPACE + ":requires");
+        if (handler == null) { return null; }
 
-        String id = element.getAttribute("id");
-        if (id != null) {
+        String identity = element.getAttribute("id");
+        if (identity != null) {
             // Look for dependency Id
-            for (int i = 0; i < dh.getDependencies().length; i++) {
-                if (dh.getDependencies()[i].getId().equals(id)) { return dh.getDependencies()[i]; }
+            for (int i = 0; i < handler.getDependencies().length; i++) {
+                if (handler.getDependencies()[i].getId().equals(identity)) { return handler.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]; }
+        for (int i = 0; i < handler.getDependencies().length; i++) {
+            if (handler.getDependencies()[i].getSpecification().equals(requirement)) { return handler.getDependencies()[i]; }
         }
 
         return null;
@@ -334,6 +325,7 @@
      * @see org.apache.felix.ipojo.Handler#stop()
      */
     public void stop() {
+        //Nothing to do.
     }
 
     /**
@@ -341,31 +333,34 @@
      * 
      * @see org.apache.felix.ipojo.Handler#start()
      */
-    public void start() { }
+    public void start() {
+        // Nothing to do.
+    }
 
     /**
      * Setter Callback Method.
      * Check if the modified field is a property to update the value.
+     * @param pojo : the pojo object on which the field is accessed
      * @param fieldName : field name
      * @param value : new value
-     * @see org.apache.felix.ipojo.Handler#setterCallback(java.lang.String,
-     * java.lang.Object)
+     * @see org.apache.felix.ipojo.Handler#onSet(Object,
+     * java.lang.String, java.lang.Object)
      */
-    public void setterCallback(String fieldName, Object value) {
+    public void onSet(Object pojo, String fieldName, Object value) {
         // Verify that the field name correspond to a dependency
         for (int i = 0; i < m_providedServices.length; i++) {
-            ProvidedService ps = m_providedServices[i];
+            ProvidedService svc = m_providedServices[i];
             boolean update = false;
-            for (int j = 0; j < ps.getProperties().length; j++) {
-                Property prop = ps.getProperties()[j];
-                if (fieldName.equals(prop.getField())) {
+            for (int j = 0; j < svc.getProperties().length; j++) {
+                Property prop = svc.getProperties()[j];
+                if (fieldName.equals(prop.getField()) && ! prop.getValue().equals(value)) {
                     // it is the associated property
-                    prop.set(value);
+                    prop.setValue(value);
                     update = true;
                 }
             }
             if (update) {
-                ps.update();
+                svc.update();
             }
         }
         // Else do nothing
@@ -374,20 +369,21 @@
     /**
      * Getter Callback Method.
      * Check if the field is a property to push the stored value.
+     * @param pojo : the pojo object on which the field is accessed
      * @param fieldName : field name
      * @param value : value pushed by the previous handler
      * @return the stored value or the previous value.
-     * @see org.apache.felix.ipojo.Handler#getterCallback(java.lang.String,
-     * java.lang.Object)
+     * @see org.apache.felix.ipojo.Handler#onGet(Object,
+     * java.lang.String, java.lang.Object)
      */
-    public Object getterCallback(String fieldName, Object value) {
+    public Object onGet(Object pojo, String fieldName, Object value) {
         for (int i = 0; i < m_providedServices.length; i++) {
-            ProvidedService ps = m_providedServices[i];
-            for (int j = 0; j < ps.getProperties().length; j++) {
-                Property prop = ps.getProperties()[j];
+            ProvidedService svc = m_providedServices[i];
+            for (int j = 0; j < svc.getProperties().length; j++) {
+                Property prop = svc.getProperties()[j];
                 if (fieldName.equals(prop.getField())) {
                     // it is the associated property
-                    return prop.get();
+                    return prop.getValue();
                 }
             }
         }
@@ -452,12 +448,12 @@
         ProvidedServiceHandlerDescription pshd = new ProvidedServiceHandlerDescription(this);
 
         for (int j = 0; j < getProvidedService().length; j++) {
-            ProvidedService ps = getProvidedService()[j];
-            ProvidedServiceDescription psd = new ProvidedServiceDescription(ps.getServiceSpecification(), ps.getState(), ps.getServiceReference());
+            ProvidedService svc = getProvidedService()[j];
+            ProvidedServiceDescription psd = new ProvidedServiceDescription(svc.getServiceSpecification(), svc.getState(), svc.getServiceReference());
 
             Properties props = new Properties();
-            for (int k = 0; k < ps.getProperties().length; k++) {
-                Property prop = ps.getProperties()[k];
+            for (int k = 0; k < svc.getProperties().length; k++) {
+                Property prop = svc.getProperties()[k];
                 if (prop.getValue() != null) {
                     props.put(prop.getName(), prop.getValue().toString());
                 }
@@ -475,36 +471,32 @@
      */
     public void reconfigure(Dictionary dict) {
         for (int j = 0; j < getProvidedService().length; j++) {
-            ProvidedService ps = getProvidedService()[j];
-            Property[] props = ps.getProperties();
+            ProvidedService svc = getProvidedService()[j];
+            Property[] props = svc.getProperties();
             boolean update = false;
             for (int k = 0; k < props.length; k++) {
                 if (dict.get(props[k].getName()) != null) {
                     update = true;
-                    if (dict.get(props[k].getName()) instanceof String) {
-                        props[k].set((String) dict.get(props[k].getName()));
-                    } else {
-                        props[k].set(dict.get(props[k].getName()));
-                    }
+                    props[k].setValue(dict.get(props[k].getName()));
                 }
             }
             if (update) {
-                ps.update();
+                svc.update();
             }
         }
     }
 
     /**
      * Initialize the component type.
-     * @param cd : component type description to populate.
+     * @param desc : component type description to populate.
      * @param metadata : component type metadata.
      * @throws ConfigurationException : occurs when the POJO does not implement any interfaces.
-     * @see org.apache.felix.ipojo.Handler#initializeComponentFactory(org.apache.felix.ipojo.architecture.ComponentDescription, org.apache.felix.ipojo.metadata.Element)
+     * @see org.apache.felix.ipojo.Handler#initializeComponentFactory(org.apache.felix.ipojo.architecture.ComponentTypeDescription, org.apache.felix.ipojo.metadata.Element)
      */
-    public void initializeComponentFactory(ComponentDescription cd, Element metadata) throws ConfigurationException {
+    public void initializeComponentFactory(ComponentTypeDescription desc, Element metadata) throws ConfigurationException {
         // Change ComponentInfo
         Element[] provides = metadata.getElements("provides");
-        ManipulationMetadata manipulation = new ManipulationMetadata(metadata);
+        PojoMetadata manipulation = getFactory().getPojoMetadata();
 
         for (int i = 0; i < provides.length; i++) {
          // First : create the serviceSpecification list
@@ -512,7 +504,7 @@
             String parent = manipulation.getSuperClass();
             Set all = null;
             try {
-                all = computeInterfaces(serviceSpecification, parent, cd.getBundleContext().getBundle());
+                all = computeInterfaces(serviceSpecification, parent, desc.getBundleContext().getBundle());
             } catch (ClassNotFoundException e) {
                 throw new ConfigurationException("A interface cannot be loaded : " + e.getMessage());
             }
@@ -522,35 +514,37 @@
                 List itfs = ParseUtils.parseArraysAsList(serviceSpecificationStr);
                 for (int j = 0; j < itfs.size(); j++) {
                     if (! all.contains(itfs.get(j))) {
-                        throw new ConfigurationException("The specification " + itfs.get(j) + " is not implemented by " + cd.getClassName());
+                        throw new ConfigurationException("The specification " + itfs.get(j) + " is not implemented by " + desc.getClassName());
                     }
                 }
                 all = new HashSet(itfs);
             }
             
-            if (all.size() == 0) {
+            if (all.isEmpty()) {
                 throw new ConfigurationException("Provides  : Cannot instantiate a provided service : no specifications found (no interfaces implemented by the pojo)");
             }
 
-            String specs = null;
+            StringBuffer specs = null;
             Set set = new HashSet(all);
-            Iterator it = set.iterator(); 
-            while (it.hasNext()) {
-                String sp = (String) it.next();
-                cd.addProvidedServiceSpecification(sp);
+            Iterator iterator = set.iterator(); 
+            while (iterator.hasNext()) {
+                String spec = (String) iterator.next();
+                desc.addProvidedServiceSpecification(spec);
                 if (specs == null) {
-                    specs = "{" + sp;
+                    specs = new StringBuffer("{");
+                    specs.append(spec);
                 } else {
-                    specs += "," + sp;
+                    specs.append(',');
+                    specs.append(spec);
                 }
             }
             
-            specs += "}";
+            specs.append('}');
             
-            provides[i].addAttribute(new Attribute("interface", specs)); // Add interface attribute to avoid checking in the configure method
+            provides[i].addAttribute(new Attribute("interface", specs.toString())); // Add interface attribute to avoid checking in the configure method
 
             Element[] props = provides[i].getElements("property");
-            for (int j = 0; j < props.length; j++) {
+            for (int j = 0; props != null && j < props.length; j++) {
                 String name = props[j].getAttribute("name");
                 String value = props[j].getAttribute("value");
                 String type = props[j].getAttribute("type");
@@ -566,15 +560,22 @@
                     if (field == null) {
                         throw new ConfigurationException("The property " + name + " has neither type neither field.");
                     }
-                    FieldMetadata fm = manipulation.getField(field);
-                    if (fm == null) {
+                    FieldMetadata fieldMeta = manipulation.getField(field);
+                    if (fieldMeta == null) {
                         throw new ConfigurationException("A declared property was not found in the class : " + field);
                     }
-                    type = fm.getFieldType();
+                    type = fieldMeta.getFieldType();
                     props[j].addAttribute(new Attribute("type", type));
                 }
+                
+                // Is the property set to immutable
+                boolean immutable = false;
+                String imm = props[j].getAttribute("immutable");
+                if (imm != null && imm.equalsIgnoreCase("true")) {
+                    immutable = true;
+                }
 
-                cd.addProperty(new PropertyDescription(name, type, value));
+                desc.addProperty(new PropertyDescription(name, type, value, immutable));
             }
         }
     }