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 2013/04/29 20:12:08 UTC

svn commit: r1477244 - /felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java

Author: clement
Date: Mon Apr 29 18:12:06 2013
New Revision: 1477244

URL: http://svn.apache.org/r1477244
Log:
Fix FELIX-4041

Do not propagate properties starting with a .

Modified:
    felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java

Modified: felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java?rev=1477244&r1=1477243&r2=1477244&view=diff
==============================================================================
--- felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java (original)
+++ felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java Mon Apr 29 18:12:06 2013
@@ -18,8 +18,6 @@
  */
 package org.apache.felix.ipojo.handlers.configuration;
 
-import java.util.*;
-
 import org.apache.felix.ipojo.ConfigurationException;
 import org.apache.felix.ipojo.Factory;
 import org.apache.felix.ipojo.HandlerFactory;
@@ -40,8 +38,11 @@ import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceRegistration;
 import org.osgi.service.cm.ManagedService;
 
+import java.util.*;
+
 /**
  * Handler managing the Configuration Admin.
+ *
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
 public class ConfigurationHandler extends PrimitiveHandler implements ManagedService {
@@ -49,89 +50,81 @@ public class ConfigurationHandler extend
     /**
      * List of the configurable fields.
      */
-    private List/*<Property>*/ m_configurableProperties = new ArrayList(1);
-
+    private List<Property> m_configurableProperties = new ArrayList<Property>(1);
     /**
      * ProvidedServiceHandler of the component. It is useful to propagate
      * properties to service registrations.
      */
     private ProvidedServiceHandler m_providedServiceHandler;
-
     /**
      * Properties propagated during the last instance "update".
      */
     private Dictionary m_propagatedFromInstance = new Properties();
-
     /**
      * Properties to propagate.
      */
-    private Dictionary m_toPropagate = new Properties();
-
+    private Dictionary<String, Object> m_toPropagate = new Hashtable<String, Object>();
     /**
      * Properties propagated from the configuration admin.
      */
     private Dictionary m_propagatedFromCA;
-
     /**
      * Check if the instance was already reconfigured by the configuration admin.
      */
     private boolean m_configurationAlreadyPushed;
-
     /**
      * 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
      * with the Configuration Admin.
      */
     private String m_managedServicePID;
-
     /**
      * 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.
-     * @param desc : component type description to populate.
+     *
+     * @param desc     : component type description to populate.
      * @param metadata : component type metadata.
      * @throws ConfigurationException : metadata are incorrect.
      * @see org.apache.felix.ipojo.Handler#initializeComponentFactory(org.apache.felix.ipojo.architecture.ComponentTypeDescription, org.apache.felix.ipojo.metadata.Element)
      */
     public void initializeComponentFactory(ComponentTypeDescription desc, Element metadata) throws ConfigurationException {
         Element[] confs = metadata.getElements("Properties", "");
-        if (confs == null) { return; }
+        if (confs == null) {
+            return;
+        }
         Element[] configurables = confs[0].getElements("Property");
         for (int i = 0; configurables != null && i < configurables.length; i++) {
             String fieldName = configurables[i].getAttribute("field");
             String methodName = configurables[i].getAttribute("method");
             String paramIndex = configurables[i].getAttribute("constructor-parameter");
 
-            if (fieldName == null && methodName == null  && paramIndex == null) {
+            if (fieldName == null && methodName == null && paramIndex == null) {
                 throw new ConfigurationException("Malformed property : The property needs to contain" +
                         " at least a field, a method or a constructor-parameter");
             }
 
             String name = configurables[i].getAttribute("name");
             if (name == null) {
-                if (fieldName == null  && methodName != null) {
+                if (fieldName == null && methodName != null) {
                     name = methodName;
-                } else if (fieldName == null  && paramIndex != null) {
+                } else if (fieldName == null && paramIndex != null) {
                     name = paramIndex;
                 } else {
                     name = fieldName;
@@ -160,7 +153,9 @@ public class ConfigurationHandler extend
                 }
             } else if (fieldName != null) {
                 FieldMetadata field = manipulation.getField(fieldName);
-                if (field == null) { throw new ConfigurationException("Malformed property : The field " + fieldName + " does not exist in the implementation class"); }
+                if (field == null) {
+                    throw new ConfigurationException("Malformed property : The field " + fieldName + " does not exist in the implementation class");
+                }
                 type = field.getFieldType();
                 configurables[i].addAttribute(new Attribute("type", type)); // Add the type to avoid configure checking
             } else if (paramIndex != null) {
@@ -169,7 +164,7 @@ public class ConfigurationHandler extend
                 MethodMetadata[] cts = manipulation.getConstructors();
                 // If we don't have a type, try to get the first constructor and get the type of the parameter
                 // we the index 'index'.
-                if (type == null && cts.length > 0  && cts[0].getMethodArguments().length > index) {
+                if (type == null && cts.length > 0 && cts[0].getMethodArguments().length > index) {
                     type = cts[0].getMethodArguments()[index];
                 } else if (type == null) { // Applied only if type was not determined.
                     throw new ConfigurationException("Cannot determine the type of the property " + index +
@@ -185,7 +180,7 @@ public class ConfigurationHandler extend
 
             boolean mandatory = false;
             String man = configurables[i].getAttribute("mandatory");
-            mandatory =  man != null && man.equalsIgnoreCase("true");
+            mandatory = man != null && man.equalsIgnoreCase("true");
 
             PropertyDescription pd = null;
             if (value == null) {
@@ -207,7 +202,8 @@ public class ConfigurationHandler extend
      * Configures the handler.
      * Access to field does not require synchronization as this method is executed
      * before any thread access to this object.
-     * @param metadata the metadata of the component
+     *
+     * @param metadata      the metadata of the component
      * @param configuration the instance configuration
      * @throws ConfigurationException one property metadata is not correct
      * @see org.apache.felix.ipojo.Handler#configure(org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)
@@ -220,13 +216,17 @@ public class ConfigurationHandler extend
         // Check if the component is dynamically configurable
         // Propagation enabled by default.
         m_mustPropagate = true;
-        // We must create a copy as the Config Admin dictionary has some limitation
-        m_toPropagate = new Properties();
+        // We must create a copy as the Config Admin dictionary has some limitations
+        m_toPropagate = new Hashtable<String, Object>();
         if (configuration != null) {
             Enumeration keys = configuration.keys();
             while (keys.hasMoreElements()) {
                 String key = (String) keys.nextElement();
-                m_toPropagate.put(key, configuration.get(key));
+                // To conform with 'Property Propagation 104.4.4 (Config Admin spec)',
+                // we don't propagate properties starting with .
+                if (!key.startsWith(".")) {
+                    m_toPropagate.put(key, configuration.get(key));
+                }
             }
         }
 
@@ -254,7 +254,7 @@ public class ConfigurationHandler extend
                 m_updated = new Callback(upd, new Class[0], false, getInstanceManager());
             } else if (method.getMethodArguments().length == 1
                     && method.getMethodArguments()[0].equals(Dictionary.class.getName())) {
-                m_updated = new Callback(upd, new Class[] {Dictionary.class}, false, getInstanceManager());
+                m_updated = new Callback(upd, new Class[]{Dictionary.class}, false, getInstanceManager());
             } else {
                 throw new ConfigurationException("The updated method is found in the class "
                         + getInstanceManager().getClassName() + " must have either no argument or a Dictionary");
@@ -272,7 +272,7 @@ public class ConfigurationHandler extend
 
             String type = configurables[i].getAttribute("type"); // The initialize method has fixed the property name.
 
-            Property prop = null;
+            Property prop;
             if (paramIndex == null) {
                 prop = new Property(name, fieldName, methodName, value, type, getInstanceManager(), this);
             } else {
@@ -306,11 +306,12 @@ public class ConfigurationHandler extend
     }
 
     /**
-      * Stop method.
-      * This method is synchronized to avoid the configuration admin pushing a configuration during the un-registration.
-      * Do nothing.
-      * @see org.apache.felix.ipojo.Handler#stop()
-      */
+     * Stop method.
+     * This method is synchronized to avoid the configuration admin pushing a configuration during the un-registration.
+     * Do nothing.
+     *
+     * @see org.apache.felix.ipojo.Handler#stop()
+     */
     public synchronized void stop() {
         if (m_sr != null) {
             m_sr.unregister();
@@ -322,6 +323,7 @@ public class ConfigurationHandler extend
      * Start method.
      * This method is synchronized to avoid the config admin pushing a configuration before ending the method.
      * Propagate properties if the propagation is activated.
+     *
      * @see org.apache.felix.ipojo.Handler#start()
      */
     public synchronized void start() {
@@ -331,8 +333,7 @@ public class ConfigurationHandler extend
 
         // Propagation
         if (m_mustPropagate) {
-            for (int i = 0; i < m_configurableProperties.size(); i++) {
-                Property prop = (Property) m_configurableProperties.get(i);
+            for (Property prop : m_configurableProperties) {
                 if (prop.getValue() != Property.NO_VALUE && prop.getValue() != null) { // No injected value, or null
                     m_toPropagate.put(prop.getName(), prop.getValue());
                 }
@@ -342,8 +343,7 @@ public class ConfigurationHandler extend
 
 
         // Give initial values and reset the 'invoked' flag.
-        for (int i = 0; i < m_configurableProperties.size(); i++) {
-            Property prop = (Property) m_configurableProperties.get(i);
+        for (Property prop : m_configurableProperties) {
             prop.reset(); // Clear the invoked flag.
             if (prop.hasField() && prop.getValue() != Property.NO_VALUE && prop.getValue() != null) {
                 getInstanceManager().onSet(null, prop.getField(), prop.getValue());
@@ -351,7 +351,7 @@ public class ConfigurationHandler extend
         }
 
         if (m_managedServicePID != null && m_sr == null) {
-            Properties props = new Properties();
+            Hashtable<String, Object> props = new Hashtable<String, Object>();
             props.put(Constants.SERVICE_PID, m_managedServicePID);
             props.put(Factory.INSTANCE_NAME_PROPERTY, getInstanceManager().getInstanceName());
             props.put("factory.name", getInstanceManager().getFactory().getFactoryName());
@@ -359,7 +359,7 @@ public class ConfigurationHandler extend
             // Security Check
             if (SecurityHelper.hasPermissionToRegisterService(ManagedService.class.getName(),
                     getInstanceManager().getContext())) {
-                m_sr = getInstanceManager().getContext().registerService(ManagedService.class.getName(), this, (Dictionary) props);
+                m_sr = getInstanceManager().getContext().registerService(ManagedService.class.getName(), this, props);
             } else {
                 error("Cannot register the ManagedService - The bundle "
                         + getInstanceManager().getContext().getBundle().getBundleId()
@@ -378,22 +378,10 @@ public class ConfigurationHandler extend
     }
 
     /**
-     * Checks if the list contains the property.
-     *
-     * @param name : name of the property
-     * @return true if the property exist in the list
-     */
-    protected boolean containsProperty(String name) {
-        for (int i = 0; i < m_configurableProperties.size(); i++) {
-            if (((Property) m_configurableProperties.get(i)).getName().equals(name)) { return true; }
-        }
-        return false;
-    }
-
-    /**
      * Reconfigure the component instance.
      * Check if the new configuration modifies the current configuration.
      * Invokes the updated method is needed.
+     *
      * @param configuration : the new configuration
      * @see org.apache.felix.ipojo.Handler#reconfigure(java.util.Dictionary)
      */
@@ -415,6 +403,7 @@ public class ConfigurationHandler extend
     /**
      * 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
      */
@@ -426,8 +415,7 @@ public class ConfigurationHandler extend
             Object value = configuration.get(name);
             boolean found = false;
             // Check if the name is a configurable property
-            for (int i = 0; i < m_configurableProperties.size(); i++) {
-                Property prop = (Property) m_configurableProperties.get(i);
+            for (Property prop : m_configurableProperties) {
                 if (prop.getName().equals(name)) {
                     reconfigureProperty(prop, value);
                     found = true;
@@ -441,8 +429,7 @@ public class ConfigurationHandler extend
         }
 
         // Every removed configurable property gets reset to its default value
-        for (int i = 0; i < m_configurableProperties.size(); i++) {
-            Property prop = (Property) m_configurableProperties.get(i);
+        for (Property prop : m_configurableProperties) {
             if (configuration.get(prop.getName()) == null) {
                 reconfigureProperty(prop, prop.getDefaultValue());
             }
@@ -456,11 +443,12 @@ public class ConfigurationHandler extend
      * This methods handles {@link org.apache.felix.ipojo.InstanceManager#onSet(Object, String, Object)}
      * call and the callback invocation.
      * The reconfiguration occurs only if the value changes.
-     * @param prop the property object to reconfigure
+     *
+     * @param prop  the property object to reconfigure
      * @param value the new value.
      */
     public void reconfigureProperty(Property prop, Object value) {
-        if (prop.getValue() == null || ! prop.getValue().equals(value)) {
+        if (prop.getValue() == null || !prop.getValue().equals(value)) {
             prop.setValue(value);
             if (prop.hasField()) {
                 getInstanceManager().onSet(null, prop.getField(), prop.getValue()); // Notify other handler of the field value change.
@@ -475,6 +463,7 @@ public class ConfigurationHandler extend
 
     /**
      * Removes the old properties from the provided services and propagate new properties.
+     *
      * @param newProps : new properties to propagate
      * @param oldProps : old properties to remove
      */
@@ -489,6 +478,20 @@ public class ConfigurationHandler extend
                 newProps.remove("name");
                 newProps.remove("managed.service.pid");
                 newProps.remove(Constants.SERVICE_PID);
+
+                // Remove all properties starting with . (config admin specification)
+                Enumeration<String> keys = newProps.keys();
+                List<String> propertiesStartingWithDot = new ArrayList<String>();
+                while (keys.hasMoreElements()) {
+                    String key = keys.nextElement();
+                    if (key.startsWith(".")) {
+                        propertiesStartingWithDot.add(key);
+                    }
+                }
+                for (String k : propertiesStartingWithDot) {
+                    newProps.remove(k);
+                }
+
                 // Propagation of the properties to service registrations :
                 m_providedServiceHandler.addProperties(newProps);
             }
@@ -499,12 +502,12 @@ public class ConfigurationHandler extend
      * Handler createInstance method.
      * This method is override to allow delayed callback invocation.
      * Invokes the updated method is needed.
+     *
      * @param instance : the created object
      * @see org.apache.felix.ipojo.PrimitiveHandler#onCreation(Object)
      */
     public void onCreation(Object instance) {
-        for (int i = 0; i < m_configurableProperties.size(); i++) {
-            Property prop = (Property) m_configurableProperties.get(i);
+        for (Property prop : m_configurableProperties) {
             if (prop.hasMethod()) {
                 prop.invoke(instance);
             }
@@ -522,9 +525,10 @@ public class ConfigurationHandler extend
      * This method build the dictionary containing all valued properties,
      * as well as properties propagated to the provided service handler (
      * only if the propagation is enabled).
+     *
      * @param instance the instance on which the callback must be called.
-     * If <code>null</code> the callback is called on all the existing
-     * object.
+     *                 If <code>null</code> the callback is called on all the existing
+     *                 object.
      */
     private void notifyUpdated(Object instance) {
         if (m_updated == null) {
@@ -548,14 +552,14 @@ public class ConfigurationHandler extend
 
         // Else we must compute the properties.
         Properties props = new Properties();
-        for (int i = 0; i < m_configurableProperties.size(); i++) {
-            String n = ((Property) m_configurableProperties.get(i)).getName();
-            Object v = ((Property) m_configurableProperties.get(i)).getValue();
+        for (Property property : m_configurableProperties) {
+            String n = property.getName();
+            Object v = property.getValue();
             if (v != Property.NO_VALUE) {
                 props.put(n, v);
             }
         }
-        // add propagated properties to the list if propagation enable
+        // add propagate properties to the list if propagation is enabled
         if (m_mustPropagate) {
             // Start by properties from the configuration admin,
             if (m_propagatedFromCA != null) {
@@ -563,7 +567,7 @@ public class ConfigurationHandler extend
                 Enumeration e = m_propagatedFromCA.keys();
                 while (e.hasMoreElements()) {
                     String k = (String) e.nextElement();
-                    if (! k.equals(Factory.INSTANCE_NAME_PROPERTY)) {
+                    if (!k.equals(Factory.INSTANCE_NAME_PROPERTY)) {
                         props.put(k, m_propagatedFromCA.get(k));
                     }
                 }
@@ -573,7 +577,7 @@ public class ConfigurationHandler extend
                 Enumeration e = m_propagatedFromInstance.keys();
                 while (e.hasMoreElements()) {
                     String k = (String) e.nextElement();
-                    if (! k.equals(Factory.INSTANCE_NAME_PROPERTY)) { // Skip instance.name
+                    if (!k.equals(Factory.INSTANCE_NAME_PROPERTY)) { // Skip instance.name
                         props.put(k, m_propagatedFromInstance.get(k));
                     }
                 }
@@ -582,9 +586,9 @@ public class ConfigurationHandler extend
 
         try {
             if (instance == null) {
-                m_updated.call(new Object[] {props});
+                m_updated.call(new Object[]{props});
             } else {
-                m_updated.call(instance, new Object[] {props});
+                m_updated.call(instance, new Object[]{props});
             }
         } catch (Exception e) {
             error("Cannot call the updated method " + m_updated.getMethod() + " : " + e.getMessage());
@@ -595,12 +599,14 @@ public class ConfigurationHandler extend
      * Managed Service method.
      * This method is called when the instance is reconfigured by the ConfigurationAdmin.
      * When called, it must hold the monitor lock.
+     *
      * @param conf : pushed configuration.
-     * @throws org.osgi.service.cm.ConfigurationException the reconfiguration failed.
+     * @throws org.osgi.service.cm.ConfigurationException
+     *          the reconfiguration failed.
      * @see org.osgi.service.cm.ManagedService#updated(java.util.Dictionary)
      */
     public synchronized void updated(Dictionary conf) throws org.osgi.service.cm.ConfigurationException {
-        if (conf == null && ! m_configurationAlreadyPushed) {
+        if (conf == null && !m_configurationAlreadyPushed) {
             return; // First call
         } else if (conf != null) { // Configuration push
             Properties props = reconfigureProperties(conf);
@@ -624,6 +630,7 @@ public class ConfigurationHandler extend
 
     /**
      * Gets the configuration handler description.
+     *
      * @return the configuration handler description.
      * @see org.apache.felix.ipojo.Handler#getDescription()
      */