Fix issue Felix-1114.
The previous fix was forgetting ManagedService. 
This one supports them, and improve ManagedService tests.


git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@771293 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java
index 98c2668..300482a 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java
@@ -1,4 +1,4 @@
-/* 
+/*
  * 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
@@ -18,7 +18,6 @@
  */
 package org.apache.felix.ipojo.handlers.configuration;
 
-import java.lang.reflect.InvocationTargetException;
 import java.util.ArrayList;
 import java.util.Dictionary;
 import java.util.Enumeration;
@@ -27,6 +26,7 @@
 
 import org.apache.felix.ipojo.ConfigurationException;
 import org.apache.felix.ipojo.HandlerFactory;
+import org.apache.felix.ipojo.InstanceManager;
 import org.apache.felix.ipojo.PrimitiveHandler;
 import org.apache.felix.ipojo.architecture.ComponentTypeDescription;
 import org.apache.felix.ipojo.architecture.HandlerDescription;
@@ -69,12 +69,12 @@
      * Properties to propagate.
      */
     private Dictionary m_toPropagate = new Properties();
-    
+
     /**
      * Properties propagated from the configuration admin.
      */
     private Dictionary m_propagatedFromCA;
-    
+
     /**
      * Check if the instance was already reconfigured by the configuration admin.
      */
@@ -84,30 +84,30 @@
      * should the component propagate configuration ?
      */
     private boolean m_mustPropagate;
-    
+
     /**
      * Service Registration to publish the service registration.
      */
     private ServiceRegistration m_sr;
-    
+
     /**
      * Managed Service PID.
-     * This PID must be different from the instance name if the instance was created 
+     * This PID must be different from the instance name if the instance was created
      * with the Configuration Admin.
      */
     private String m_managedServicePID;
-    
+
     /**
-     * the handler description. 
+     * the handler description.
      */
     private ConfigurationHandlerDescription m_description;
-    
+
     /**
      * Updated method.
      * This method is called when a reconfiguration is completed.
      */
     private Callback m_updated;
-   
+
 
     /**
      * Initialize the component type.
@@ -123,7 +123,7 @@
         for (int i = 0; configurables != null && i < configurables.length; i++) {
             String fieldName = configurables[i].getAttribute("field");
             String methodName = configurables[i].getAttribute("method");
-            
+
             if (fieldName == null && methodName == null) {
                 throw new ConfigurationException("Malformed property : The property needs to contain at least a field or a method");
             }
@@ -137,7 +137,7 @@
                 }
                 configurables[i].addAttribute(new Attribute("name", name)); // Add the type to avoid configure checking
             }
-            
+
             String value = configurables[i].getAttribute("value");
 
             // Detect the type of the property
@@ -163,30 +163,30 @@
                 type = field.getFieldType();
                 configurables[i].addAttribute(new Attribute("type", type)); // Add the type to avoid configure checking
             }
-            
+
             // Is the property set to immutable
             boolean immutable = false;
             String imm = configurables[i].getAttribute("immutable");
             immutable = imm != null && imm.equalsIgnoreCase("true");
-            
+
             boolean mandatory = false;
             String man = configurables[i].getAttribute("mandatory");
             mandatory =  man != null && man.equalsIgnoreCase("true");
-            
+
             PropertyDescription pd = null;
             if (value == null) {
                 pd = new PropertyDescription(name, type, null, false); // Cannot be immutable if we have no value.
             } else {
                 pd = new PropertyDescription(name, type, value, immutable);
             }
-            
+
             if (mandatory) {
                 pd.setMandatory();
             }
-            
+
             desc.addProperty(pd);
         }
-        
+
     }
 
     /**
@@ -195,7 +195,7 @@
      * before any thread access to this object.
      * @param metadata the metadata of the component
      * @param configuration the instance configuration
-     * @throws ConfigurationException one property metadata is not correct 
+     * @throws ConfigurationException one property metadata is not correct
      * @see org.apache.felix.ipojo.Handler#configure(org.apache.felix.ipojo.InstanceManager,
      * org.apache.felix.ipojo.metadata.Element)
      */
@@ -211,20 +211,20 @@
             m_mustPropagate = true;
             m_toPropagate = configuration; // Instance configuration to propagate.
         }
-        
+
         // Check if the component support ConfigurationADmin reconfiguration
         m_managedServicePID = confs[0].getAttribute("pid"); // Look inside the component type description
         String instanceMSPID = (String) configuration.get("managed.service.pid"); // Look inside the instance configuration.
         if (instanceMSPID != null) {
             m_managedServicePID = instanceMSPID;
         }
-        
+
         // updated method
         String upd = confs[0].getAttribute("updated");
         if (upd != null) {
             m_updated = new Callback(upd, new Class[] {Dictionary.class}, false, getInstanceManager());
         }
-        
+
         for (int i = 0; configurables != null && i < configurables.length; i++) {
             String fieldName = configurables[i].getAttribute("field");
             String methodName = configurables[i].getAttribute("method");
@@ -233,7 +233,7 @@
             String value = configurables[i].getAttribute("value");
 
             String type = configurables[i].getAttribute("type"); // The initialize method has fixed the property name.
-            
+
             Property prop = new Property(name, fieldName, methodName, value, type, getInstanceManager(), this);
             addProperty(prop);
 
@@ -245,13 +245,13 @@
             } else {
                 prop.setValue(configuration.get(name));
             }
-            
+
             if (fieldName != null) {
                 FieldMetadata field = new FieldMetadata(fieldName, type);
                 getInstanceManager().register(field, prop);
             }
         }
-        
+
         m_description = new ConfigurationHandlerDescription(this, m_configurableProperties);
 
     }
@@ -289,7 +289,7 @@
             }
             reconfigure(m_toPropagate);
         }
-        
+
         if (m_managedServicePID != null && m_sr == null) {
             Properties props = new Properties();
             props.put(Constants.SERVICE_PID, m_managedServicePID);
@@ -299,25 +299,9 @@
         }
     }
 
-//    /**
-//     * Handler state changed.
-//     * @param state : the new instance state.
-//     * @see org.apache.felix.ipojo.CompositeHandler#stateChanged(int)
-//     */
-//    public void stateChanged(int state) {
-//        if (state == InstanceManager.VALID) {
-//            start();
-//            return;
-//        }
-//        if (state == InstanceManager.INVALID) {
-//            stop();
-//            return;
-//        }
-//    }
-
     /**
      * Adds the given property metadata to the property metadata list.
-     * 
+     *
      * @param prop : property metadata to add
      */
     protected void addProperty(Property prop) {
@@ -326,7 +310,7 @@
 
     /**
      * Checks if the list contains the property.
-     * 
+     *
      * @param name : name of the property
      * @return true if the property exist in the list
      */
@@ -344,31 +328,28 @@
      * @param configuration : the new configuration
      * @see org.apache.felix.ipojo.Handler#reconfigure(java.util.Dictionary)
      */
-    public synchronized void reconfigure(Dictionary configuration) {  
+    public synchronized void reconfigure(Dictionary configuration) {
         info(getInstanceManager().getInstanceName() + " is reconfiguring the properties : " + configuration);
         Properties props = reconfigureProperties(configuration);
         propagate(props, m_propagatedFromInstance);
         m_propagatedFromInstance = props;
-        
+
         if (getInstanceManager().getPojoObjects() != null) {
             try {
                 notifyUpdated(null);
             } catch (Throwable e) {
-                System.out.println("=========");
-                e.printStackTrace();
-
-                System.out.println("=========");
+                error("Cannot call the updated method : " + e.getMessage(), e);
             }
         }
     }
-    
+
     /**
      * Reconfigured configuration properties and returns non matching properties.
      * When called, it must hold the monitor lock.
      * @param configuration : new configuration
      * @return the properties that does not match with configuration properties
      */
-    private Properties reconfigureProperties(Dictionary configuration) {        
+    private Properties reconfigureProperties(Dictionary configuration) {
         Properties toPropagate = new Properties();
         Enumeration keysEnumeration = configuration.keys();
         while (keysEnumeration.hasMoreElements()) {
@@ -384,7 +365,7 @@
                     break; // Exit the search loop
                 }
             }
-            if (!found) { 
+            if (!found) {
                 // The property is not a configurable property, aadd it to the toPropagate list.
                 toPropagate.put(name, value);
             }
@@ -415,7 +396,7 @@
             }
         }
     }
-    
+
     /**
      * Removes the old properties from the provided services and propagate new properties.
      * @param newProps : new properties to propagate
@@ -452,17 +433,14 @@
                 prop.invoke(instance);
             }
         }
-        
+
         try {
             notifyUpdated(instance);
         } catch (Throwable e) {
-            System.out.println("=========");
-            e.printStackTrace();
-
-            System.out.println("=========");
+            error("Cannot call the updated method : " + e.getMessage(), e);
         }
     }
-    
+
     /**
      * Invokes the updated method.
      * This method build the dictionary containing all valued properties.
@@ -514,8 +492,16 @@
             m_propagatedFromCA = null;
             m_configurationAlreadyPushed = false;
         }
+
+        if (getInstanceManager().getPojoObjects() != null) {
+            try {
+                notifyUpdated(null);
+            } catch (Throwable e) {
+                error("Cannot call the updated method : " + e.getMessage(), e);
+            }
+        }
     }
-    
+
     /**
      * Gets the configuration handler description.
      * @return the configuration handler description.
diff --git a/ipojo/tests/core/configuration/src/main/java/org/apache/felix/ipojo/test/scenarios/configuration/UpdatedMethodAndManagedService.java b/ipojo/tests/core/configuration/src/main/java/org/apache/felix/ipojo/test/scenarios/configuration/UpdatedMethodAndManagedService.java
index c089ada..fe70f31 100644
--- a/ipojo/tests/core/configuration/src/main/java/org/apache/felix/ipojo/test/scenarios/configuration/UpdatedMethodAndManagedService.java
+++ b/ipojo/tests/core/configuration/src/main/java/org/apache/felix/ipojo/test/scenarios/configuration/UpdatedMethodAndManagedService.java
@@ -1,4 +1,4 @@
-/* 

+/*

  * 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

@@ -22,7 +22,6 @@
 import java.util.Properties;

 

 import org.apache.felix.ipojo.ComponentInstance;

-import org.apache.felix.ipojo.PrimitiveHandler;

 import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

 import org.apache.felix.ipojo.test.scenarios.configuration.service.FooService;

 import org.apache.felix.ipojo.test.scenarios.util.Utils;

@@ -33,19 +32,19 @@
 public class UpdatedMethodAndManagedService extends OSGiTestCase {

 

 	/**

-	 * Instance where the ManagedServicePID is provided by the component type. 

+	 * Instance where the ManagedServicePID is provided by the component type.

 	 */

 	ComponentInstance instance1;

 	/**

-     * Instance where the ManagedServicePID is provided by the instance. 

+     * Instance where the ManagedServicePID is provided by the instance.

      */

 	ComponentInstance instance2;

-	

+

 	/**

-     * Instance without configuration. 

+     * Instance without configuration.

      */

     ComponentInstance instance3;

-	

+

 	public void setUp() {

 	    String type = "CONFIG-FooProviderType-4Updated";

         Properties p = new Properties();

@@ -55,7 +54,7 @@
         p.put("baz", "baz");

         instance1 = Utils.getComponentInstance(getContext(), type, p);

         assertEquals("instance1 created", ComponentInstance.VALID,instance1.getState());

-        

+

 		type = "CONFIG-FooProviderType-3Updated";

 		Properties p1 = new Properties();

 		p1.put("instance.name","instance-2");

@@ -64,14 +63,14 @@
 		p1.put("baz", "baz");

 		p1.put("managed.service.pid", "instance");

 		instance2 = Utils.getComponentInstance(getContext(), type, p1);

-		

+

 		type = "CONFIG-FooProviderType-3Updated";

         Properties p2 = new Properties();

         p2.put("instance.name","instance-3");

         p2.put("managed.service.pid", "instance-3");

         instance3 = Utils.getComponentInstance(getContext(), type, p2);

 	}

-	

+

 	public void tearDown() {

 		instance1.dispose();

 		instance2.dispose();

@@ -80,7 +79,7 @@
 		instance2 = null;

 		instance3 = null;

 	}

-	

+

 	public void testStaticInstance1() {

 		ServiceReference fooRef = Utils.getServiceReferenceByName(getContext(), FooService.class.getName(), instance1.getInstanceName());

 		assertNotNull("Check FS availability", fooRef);

@@ -90,10 +89,10 @@
 		assertEquals("Check foo equality -1", fooP, "foo");

 		assertEquals("Check bar equality -1", barP, new Integer(2));

 		assertEquals("Check baz equality -1", bazP, "baz");

-				

+

 		ServiceReference msRef = Utils.getServiceReferenceByPID(getContext(), ManagedService.class.getName(), "FooProvider-3");

 		assertNotNull("Check ManagedServiceFactory availability", msRef);

-		

+

 		// Configuration of baz

 		Properties conf = new Properties();

 		conf.put("baz", "zab");

@@ -103,7 +102,7 @@
 		try {

 			ms.updated(conf);

 		} catch (ConfigurationException e) { fail("Configuration Exception : " + e); }

-		

+

 		// Re-check props

 		fooRef = Utils.getServiceReferenceByName(getContext(), FooService.class.getName(), instance1.getInstanceName());

 		fooP = (String) fooRef.getProperty("foo");

@@ -112,19 +111,19 @@
 		assertEquals("Check foo equality -2", fooP, "foo");

 		assertEquals("Check bar equality -2", barP, new Integer(2));

 		assertEquals("Check baz equality -2", bazP, "zab");

-		

+

 		// Get Service

 		FooService fs = (FooService) context.getService(fooRef);

 		Integer updated = (Integer) fs.fooProps().get("updated");

         Dictionary dict = (Dictionary) fs.fooProps().get("lastupdated");

-        

+

         assertEquals("Check updated", 1, updated.intValue());

         assertEquals("Check last updated", 2, dict.size());

-		

+

         context.ungetService(fooRef);

 		getContext().ungetService(msRef);

 	}

-	

+

 	public void testStaticInstance2() {

         ServiceReference fooRef = Utils.getServiceReferenceByName(getContext(), FooService.class.getName(), instance2.getInstanceName());

         assertNotNull("Check FS availability", fooRef);

@@ -134,11 +133,11 @@
         assertEquals("Check foo equality -1", fooP, "foo");

         assertEquals("Check bar equality -1", barP, new Integer(2));

         assertEquals("Check baz equality -1", bazP, "baz");

-        

+

         ServiceReference msRef = Utils.getServiceReferenceByPID(getContext(), ManagedService.class.getName(), "instance");

         assertNotNull("Check ManagedService availability", msRef);

-        

-        

+

+

         // Configuration of baz

         Properties conf = new Properties();

         conf.put("baz", "zab");

@@ -148,7 +147,7 @@
         try {

             ms.updated(conf);

         } catch (ConfigurationException e) { fail("Configuration Exception : " + e); }

-        

+

         // Recheck props

         fooRef = Utils.getServiceReferenceByName(getContext(), FooService.class.getName(), instance2.getInstanceName());

         fooP = (String) fooRef.getProperty("foo");

@@ -157,34 +156,48 @@
         assertEquals("Check foo equality -2", fooP, "foo");

         assertEquals("Check bar equality -2", barP, new Integer(2));

         assertEquals("Check baz equality -2", bazP, "zab");

-        

+

         // Get Service

         FooService fs = (FooService) context.getService(fooRef);

         Integer updated = (Integer) fs.fooProps().get("updated");

         Dictionary dict = (Dictionary) fs.fooProps().get("lastupdated");

-        

+

         assertEquals("Check updated", 1, updated.intValue());

         assertEquals("Check last updated", 2, dict.size());

-        

+

+        conf.put("baz", "zab2");

+        conf.put("foo", "oof2");

+        conf.put("bar", new Integer(0));

+        ms = (ManagedService) getContext().getService(msRef);

+        try {

+            ms.updated(conf);

+        } catch (ConfigurationException e) { fail("Configuration Exception : " + e); }

+

+        updated = (Integer) fs.fooProps().get("updated");

+        dict = (Dictionary) fs.fooProps().get("lastupdated");

+

+        assertEquals("Check updated -2", 2, updated.intValue());

+        assertEquals("Check last updated", 2, dict.size());

+

         getContext().ungetService(fooRef);

         getContext().ungetService(msRef);

     }

-	

+

 	public void testDynamicInstance1() {

     	ServiceReference fooRef = Utils.getServiceReferenceByName(getContext(), FooService.class.getName(), instance1.getInstanceName());

     	assertNotNull("Check FS availability", fooRef);

-    	

+

     	String fooP = (String) fooRef.getProperty("foo");

     	Integer barP = (Integer) fooRef.getProperty("bar");

     	String bazP = (String) fooRef.getProperty("baz");

-    	

+

     	assertEquals("Check foo equality", fooP, "foo");

     	assertEquals("Check bar equality", barP, new Integer(2));

     	assertEquals("Check baz equality", bazP, "baz");

-    	

+

     	ServiceReference msRef = Utils.getServiceReferenceByPID(getContext(), ManagedService.class.getName(), "FooProvider-3");

     	assertNotNull("Check ManagedServiceFactory availability", msRef);

-    	

+

     	// Configuration of baz

     	Properties conf = new Properties();

     	conf.put("baz", "zab");

@@ -194,51 +207,67 @@
     	try {

     		ms.updated(conf);

     	} catch (ConfigurationException e) { fail("Configuration Exception : " + e); }

-    	

+

     	// Re-check props

     	fooRef = Utils.getServiceReferenceByName(getContext(), FooService.class.getName(), instance1.getInstanceName());

     	fooP = (String) fooRef.getProperty("foo");

     	barP = (Integer) fooRef.getProperty("bar");

     	bazP = (String) fooRef.getProperty("baz");

-    	

+

     	assertEquals("Check foo equality", fooP, "oof");

     	assertEquals("Check bar equality", barP, new Integer(0));

     	assertEquals("Check baz equality", bazP, "zab");

-    	

+

     	// Check field value

     	FooService fs = (FooService) getContext().getService(fooRef);

     	Properties p = fs.fooProps();

     	fooP = (String) p.get("foo");

     	barP = (Integer) p.get("bar");

-    	

+

     	assertEquals("Check foo field equality", fooP, "oof");

     	assertEquals("Check bar field equality", barP, new Integer(0));

-    	

+

         Integer updated = (Integer) fs.fooProps().get("updated");

         Dictionary dict = (Dictionary) fs.fooProps().get("lastupdated");

-        

-        assertEquals("Check updated", 1, updated.intValue());

+

+        assertEquals("Check updated -1", 1, updated.intValue());

         assertEquals("Check last updated", 2, dict.size());

-    	

+

+        conf.put("baz", "zab2");

+        conf.put("foo", "oof2");

+        conf.put("bar", new Integer(0));

+        ms = (ManagedService) getContext().getService(msRef);

+        try {

+            ms.updated(conf);

+        } catch (ConfigurationException e) { fail("Configuration Exception : " + e); }

+

+        updated = (Integer) fs.fooProps().get("updated");

+        dict = (Dictionary) fs.fooProps().get("lastupdated");

+

+        assertEquals("Check updated -2", 2, updated.intValue());

+        assertEquals("Check last updated", 2, dict.size());

+

+

     	getContext().ungetService(fooRef);

     	getContext().ungetService(msRef);

+

     }

-	

+

 	public void testDynamicInstance2() {

         ServiceReference fooRef = Utils.getServiceReferenceByName(getContext(), FooService.class.getName(), instance2.getInstanceName());

         assertNotNull("Check FS availability", fooRef);

-        

+

         String fooP = (String) fooRef.getProperty("foo");

         Integer barP = (Integer) fooRef.getProperty("bar");

         String bazP = (String) fooRef.getProperty("baz");

-        

+

         assertEquals("Check foo equality", fooP, "foo");

         assertEquals("Check bar equality", barP, new Integer(2));

         assertEquals("Check baz equality", bazP, "baz");

-        

+

         ServiceReference msRef = Utils.getServiceReferenceByPID(getContext(), ManagedService.class.getName(), "instance");

         assertNotNull("Check ManagedServiceFactory availability", msRef);

-        

+

         // Configuration of baz

         Properties conf = new Properties();

         conf.put("baz", "zab");

@@ -248,32 +277,46 @@
         try {

             ms.updated(conf);

         } catch (ConfigurationException e) { fail("Configuration Exception : " + e); }

-        

+

         // Recheck props

         fooRef = Utils.getServiceReferenceByName(getContext(), FooService.class.getName(), instance2.getInstanceName());

         fooP = (String) fooRef.getProperty("foo");

         barP = (Integer) fooRef.getProperty("bar");

         bazP = (String) fooRef.getProperty("baz");

-        

+

         assertEquals("Check foo equality", fooP, "oof");

         assertEquals("Check bar equality", barP, new Integer(0));

         assertEquals("Check baz equality", bazP, "zab");

-        

+

         // Check field value

         FooService fs = (FooService) getContext().getService(fooRef);

         Properties p = fs.fooProps();

         fooP = (String) p.get("foo");

         barP = (Integer) p.get("bar");

-        

+

         assertEquals("Check foo field equality", fooP, "oof");

         assertEquals("Check bar field equality", barP, new Integer(0));

-        

+

         Integer updated = (Integer) fs.fooProps().get("updated");

         Dictionary dict = (Dictionary) fs.fooProps().get("lastupdated");

-        

+

         assertEquals("Check updated", 1, updated.intValue());

-        assertEquals("Check last updated", 2, dict.size()); 

-        

+        assertEquals("Check last updated", 2, dict.size());

+

+        conf.put("baz", "zab2");

+        conf.put("foo", "oof2");

+        conf.put("bar", new Integer(0));

+        ms = (ManagedService) getContext().getService(msRef);

+        try {

+            ms.updated(conf);

+        } catch (ConfigurationException e) { fail("Configuration Exception : " + e); }

+

+        updated = (Integer) fs.fooProps().get("updated");

+        dict = (Dictionary) fs.fooProps().get("lastupdated");

+

+        assertEquals("Check updated -2", 2, updated.intValue());

+        assertEquals("Check last updated", 2, dict.size());

+

         getContext().ungetService(fooRef);

         getContext().ungetService(msRef);

     }