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/01/27 01:02:24 UTC

svn commit: r615540 - in /felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers: configuration/ConfigurableProperty.java providedservice/Property.java

Author: clement
Date: Sat Jan 26 16:02:23 2008
New Revision: 615540

URL: http://svn.apache.org/viewvc?rev=615540&view=rev
Log:
Fix a bug when the configuration admin send configurations containing Strings (Objects was expected). In this case, the objects are re-created from the Strings (arrays are parsed by according to the iPOJO syntax). This change impacts both service properties and instance properties.

Modified:
    felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurableProperty.java
    felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/Property.java

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurableProperty.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurableProperty.java?rev=615540&r1=615539&r2=615540&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurableProperty.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurableProperty.java Sat Jan 26 16:02:23 2008
@@ -104,14 +104,14 @@
         }
 
     }
-    
+
     /**
      * The set type method fix the property type according to the given type name.
      * @param type : the type name
      * @throws ConfigurationException if an error occurs when loading the type class for non-primitive types.
      */
     private void setType(String type) throws ConfigurationException {
-     // Syntactic sugar to avoid writing java.lang.String
+        // Syntactic sugar to avoid writing java.lang.String
         if ("string".equals(type) || "String".equals(type)) {
             m_type = java.lang.String.class;
             return;
@@ -203,7 +203,7 @@
                 throw new ConfigurationException("Argument problem to call the constructor of the type " + internalType);
             }
         }
-        
+
         // Non array, complex type.
         try {
             m_type = m_handler.getInstanceManager().getContext().getBundle().loadClass(type);
@@ -459,7 +459,191 @@
      * @param value : the new value.
      */
     public void setValue(Object value) {
-        m_value = value;
+        // Is the object is directly assignable to the property, affect it.
+        if (isAssignable(m_type, value)) {
+            m_value = value;
+        } else {
+            // If the object is a String, we must recreate the object from the String form
+            if (value instanceof String) {
+                try {
+                    m_value = create(m_type, (String) value);
+                } catch (ConfigurationException e) {
+                    throw new ClassCastException("Incompatible type for the property " + m_name + " : " + e.getMessage());
+                }
+            } else {
+                // Error, the given property cannot be injected.
+                throw new ClassCastException("Incompatible type for the property " + m_name + " " + m_type.getName() + " expected, " + value.getClass() + " received");
+            }
+        }
+    }
+    
+    /**
+     * Test if the given value is assignable to the given type.
+     * @param type : class of the type
+     * @param value : object to check
+     * @return true if the object is assignable in the property of type 'type'.
+     */
+    public static boolean isAssignable(Class type, Object value) {
+        if (type.isInstance(value)) {
+            return true;
+        } else if (type.isPrimitive()) {
+            // Manage all boxing types.
+            if (value instanceof Boolean && type.equals(Boolean.TYPE)) {
+                return true;
+            }
+            if (value instanceof Byte && type.equals(Byte.TYPE)) {
+                return true;
+            }
+            if (value instanceof Short && type.equals(Short.TYPE)) {
+                return true;
+            }
+            if (value instanceof Integer && type.equals(Integer.TYPE)) {
+                return true;
+            }
+            if (value instanceof Long && type.equals(Long.TYPE)) {
+                return true;
+            }
+            if (value instanceof Float && type.equals(Float.TYPE)) {
+                return true;
+            }
+            if (value instanceof Double && type.equals(Double.TYPE)) {
+                return true;
+            }
+            if (value instanceof Character && type.equals(Character.TYPE)) {
+                return true;
+            }
+            return false;
+        } else {
+            // Else return false.
+            return false;
+        }
+    }
+
+    /**
+     * Create an object of the given type with the given String value.
+     * @param type : type of the returned object
+     * @param strValue : String value.
+     * @return the object of type 'type' created from the String 'value'
+     * @throws ConfigurationException occurs when the object cannot be created.
+     */
+    public static Object create(Class type, String strValue) throws ConfigurationException {
+        if (type.equals(Boolean.TYPE)) { return new Boolean(strValue); }
+        if (type.equals(Byte.TYPE)) { return new Byte(strValue); }
+        if (type.equals(Short.TYPE)) { return new Short(strValue); }
+        if (type.equals(Integer.TYPE)) { return new Integer(strValue); }
+        if (type.equals(Long.TYPE)) { return new Long(strValue); }
+        if (type.equals(Float.TYPE)) { return new Float(strValue); }
+        if (type.equals(Double.TYPE)) { return new Double(strValue); }
+        if (type.equals(Character.TYPE)) { return new Character(strValue.charAt(0)); }
+
+        // Array :
+        if (type.isArray()) { return createArrayObject(type.getComponentType(), ParseUtils.parseArrays(strValue)); }
+        // Else it is a neither a primitive type neither a String -> create
+        // the object by calling a constructor with a string in argument.
+        try {
+            Constructor cst = type.getConstructor(new Class[] { String.class });
+            return cst.newInstance(new Object[] { strValue });
+        } catch (SecurityException e) {
+            throw new ConfigurationException("Security exception in create on " + type + " : " + e.getMessage());
+        } catch (NoSuchMethodException e) {
+            throw new ConfigurationException("Constructor not found exception in create on " + type + " : " + e.getMessage());
+        } catch (IllegalArgumentException e) {
+            throw new ConfigurationException("Argument problem to call the constructor of the type " + type);
+        } catch (InstantiationException e) {
+            throw new ConfigurationException("Instantiation problem  " + type);
+        } catch (IllegalAccessException e) {
+            throw new ConfigurationException("Illegal Access " + type);
+        } catch (InvocationTargetException e) {
+            throw new ConfigurationException("Invocation problem " + type + " : " + e.getTargetException().getMessage());
+        }
+
+    }
+
+    /**
+     * Create an array object containing the type 'interntype' from the String array 'values'.
+     * @param interntype : internal type of the array.
+     * @param values : String array
+     * @return the array containing objects created from the 'values' array
+     * @throws ConfigurationException occurs when the array cannot be created correctly
+     */
+    public static Object createArrayObject(Class interntype, String[] values) throws ConfigurationException {
+        if (interntype.equals(Boolean.TYPE)) {
+            boolean[] bool = new boolean[values.length];
+            for (int i = 0; i < values.length; i++) {
+                bool[i] = new Boolean(values[i]).booleanValue();
+            }
+            return bool;
+        }
+        if (interntype.equals(Byte.TYPE)) {
+            byte[] byt = new byte[values.length];
+            for (int i = 0; i < values.length; i++) {
+                byt[i] = new Byte(values[i]).byteValue();
+            }
+            return byt;
+        }
+        if (interntype.equals(Short.TYPE)) {
+            short[] shor = new short[values.length];
+            for (int i = 0; i < values.length; i++) {
+                shor[i] = new Short(values[i]).shortValue();
+            }
+            return shor;
+        }
+        if (interntype.equals(Integer.TYPE)) {
+            int[] in = new int[values.length];
+            for (int i = 0; i < values.length; i++) {
+                in[i] = new Integer(values[i]).intValue();
+            }
+            return in;
+        }
+        if (interntype.equals(Long.TYPE)) {
+            long[] ll = new long[values.length];
+            for (int i = 0; i < values.length; i++) {
+                ll[i] = new Long(values[i]).longValue();
+            }
+            return ll;
+        }
+        if (interntype.equals(Float.TYPE)) {
+            float[] fl = new float[values.length];
+            for (int i = 0; i < values.length; i++) {
+                fl[i] = new Float(values[i]).floatValue();
+            }
+            return fl;
+        }
+        if (interntype.equals(Double.TYPE)) {
+            double[] dl = new double[values.length];
+            for (int i = 0; i < values.length; i++) {
+                dl[i] = new Double(values[i]).doubleValue();
+            }
+            return dl;
+        }
+        if (interntype.equals(Character.TYPE)) {
+            char[] dl = new char[values.length];
+            for (int i = 0; i < values.length; i++) {
+                dl[i] = values[i].toCharArray()[0];
+            }
+            return dl;
+        }
+
+        // Else it is a neither a primitive type -> create the
+        // object by calling a constructor with a string in argument.
+        try {
+            Constructor cst = interntype.getConstructor(new Class[] { String.class });
+            Object[] ob = (Object[]) Array.newInstance(interntype, values.length);
+            for (int i = 0; i < values.length; i++) {
+                ob[i] = cst.newInstance(new Object[] { values[i].trim() });
+            }
+            return ob;
+        } catch (NoSuchMethodException e) {
+            throw new ConfigurationException("Constructor not found exception in setValue on " + interntype.getName());
+        } catch (IllegalArgumentException e) {
+            throw new ConfigurationException("Argument problem to call the constructor of the type " + interntype.getName());
+        } catch (InstantiationException e) {
+            throw new ConfigurationException("Instantiation problem  " + interntype.getName());
+        } catch (IllegalAccessException e) {
+            throw new ConfigurationException("Illegal Access Exception in  " + interntype.getName());
+        } catch (InvocationTargetException e) {
+            throw new ConfigurationException("Invocation problem " + interntype.getName() + " : " + e.getTargetException().getMessage());
+        }
     }
 
     /**

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/Property.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/Property.java?rev=615540&r1=615539&r2=615540&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/Property.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/Property.java Sat Jan 26 16:02:23 2008
@@ -132,7 +132,18 @@
      * @param o : the new value of the property (object)
      */
     protected void set(Object o) {
-        m_value = o;
+        // Is the object is directly assignable to the property, affect it.
+        if (!(o instanceof String) || m_type.equals("java.lang.String")) {
+            m_value = o;
+        } else {
+            // If the object is a String, we must recreate the object from the String form
+            if (o instanceof String) {
+                setValue((String) o);
+            } else {
+                // Error, the given property cannot be injected.
+                throw new ClassCastException("Incompatible type for the property " + m_name + " " + m_type + " expected");
+            }
+        }
     }
 
     /**