FELIX-4967 handle char and char types in config annotations, and fix boolean handling

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1692034 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/helper/Coercions.java b/scr/src/main/java/org/apache/felix/scr/impl/helper/Coercions.java
index 8f18f09..13db81a 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/helper/Coercions.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/helper/Coercions.java
@@ -37,6 +37,7 @@
 //    | Double | Byte | Short
 //| Character | Boolean
     private static final byte byte0 = 0;
+    private static final char char0 = 0;
     private static final double double0 = 0;
     private static final float float0 = 0;
     private static final int int0 = 0;
@@ -53,6 +54,10 @@
         {
             return coerceToBoolean(raw);
         }
+        if (type == Character.class || type == char.class)
+        {
+            return coerceToChar(raw);
+        }
         if (type == Class.class)
         {
             return coerceToClass(raw, bundle);
@@ -123,7 +128,37 @@
         {
             return 0;
         }
-        throw new ComponentException( "Unrecognized input type: " + o);
+        throw new ComponentException( "Unrecognized input value: " + o + " of type: " + o.getClass());
+    }
+    
+    public static char coerceToChar(Object o)
+    {
+        o = multipleToSingle( o, byte0 );
+        if (o instanceof Character)
+        {
+            return (Character)o;
+        }
+        if (o instanceof String)
+        {
+            if (((String)o).length() > 0) 
+            {
+                return ((String)o).charAt(0);
+            }
+            return char0;
+        }
+        if (o instanceof Boolean)
+        {
+            return (Boolean)o? 1: char0;
+        }
+        if (o instanceof Number)
+        {
+            return (char)((Number)o).intValue();
+        }
+        if (o == null) 
+        {
+            return char0;
+        }
+        throw new ComponentException( "Unrecognized input value: " + o + " of type: " + o.getClass());
     }
     
     public static double coerceToDouble(Object o)
@@ -160,7 +195,7 @@
         {
             return 0;
         }
-        throw new ComponentException( "Unrecognized input type: " + o);
+        throw new ComponentException( "Unrecognized input value: " + o + " of type: " + o.getClass());
     }
     
     public static float coerceToFloat(Object o)
@@ -197,7 +232,7 @@
         {
             return 0;
         }
-        throw new ComponentException( "Unrecognized input type: " + o);
+        throw new ComponentException( "Unrecognized input value: " + o + " of type: " + o.getClass());
     }
     
     public static int coerceToInteger(Object o)
@@ -234,7 +269,7 @@
         {
             return 0;
         }
-        throw new ComponentException( "Unrecognized input type: " + o);
+        throw new ComponentException( "Unrecognized input value: " + o + " of type: " + o.getClass());
     }
     
     public static long coerceToLong(Object o)
@@ -271,7 +306,7 @@
         {
             return 0;
         }
-        throw new ComponentException( "Unrecognized input type: " + o);
+        throw new ComponentException( "Unrecognized input value: " + o + " of type: " + o.getClass());
     }
     
     public static short coerceToShort(Object o)
@@ -308,7 +343,7 @@
         {
             return 0;
         }
-        throw new ComponentException( "Unrecognized input type: " + o);
+        throw new ComponentException( "Unrecognized input value: " + o + " of type: " + o.getClass());
     }
     
     public static String coerceToString(Object o)
@@ -350,13 +385,13 @@
         }
         if (o instanceof Number)
         {
-            return ((Number)o).intValue() != 0;
+            return ((Number)o).doubleValue() != 0D;
         }
         if (o == null) 
         {
             return false;
         }
-        throw new ComponentException( "Unrecognized input type: " + o);
+        throw new ComponentException( "Unrecognized input value: " + o + " of type: " + o.getClass());
     }
     
     public static Class<?> coerceToClass(Object o, Bundle b)
@@ -377,7 +412,7 @@
                 throw new ComponentException(e);
             }
         }
-        throw new ComponentException( "Unrecognized input type: " + o);
+        throw new ComponentException( "Unrecognized input value: " + o + " of type: " + o.getClass());
     }
     
     public static <T extends Enum<T>> T coerceToEnum(Object o, Class<T> clazz)
@@ -398,7 +433,7 @@
         {
             return null;
         }
-        throw new ComponentException( "Unrecognized input type: " + o);
+        throw new ComponentException( "Unrecognized input value: " + o + " of type: " + o.getClass());
     }
     
     private static Object multipleToSingle(Object o, Object defaultValue)
diff --git a/scr/src/test/java/org/apache/felix/scr/impl/helper/AnnotationTest.java b/scr/src/test/java/org/apache/felix/scr/impl/helper/AnnotationTest.java
index c186bc1..4116e54 100644
--- a/scr/src/test/java/org/apache/felix/scr/impl/helper/AnnotationTest.java
+++ b/scr/src/test/java/org/apache/felix/scr/impl/helper/AnnotationTest.java
@@ -56,6 +56,7 @@
     public @interface A1 {
         boolean bool();
         byte byt();
+        char cha();
         Class<?> clas();
         E1 e1();
         double doubl();
@@ -90,6 +91,7 @@
     {
         assertEquals(true, a.bool());
         assertEquals((byte)12, a.byt());
+        assertEquals('c', a.cha());
         assertEquals(String.class, a.clas());
         assertEquals(E1.a, a.e1());
         assertEquals(3.14d, a.doubl());
@@ -122,9 +124,10 @@
 
     private Map<String, Object> allValues()
     {
-        Map<String, Object> values = new HashMap();
+        Map<String, Object> values = new HashMap<String, Object>();
         values.put("bool", "true");
         values.put("byt", 12l);
+        values.put("cha", 'c');
         values.put("clas", String.class.getName());
         values.put("e1", E1.a.toString());
         values.put("doubl", "3.14");
@@ -146,6 +149,7 @@
         A1 a = (A1) o;
         assertEquals(false, a.bool());
         assertEquals((byte)0, a.byt());
+        assertEquals((char)0, a.cha());
         assertEquals(null, a.clas());
         assertEquals(null, a.e1());
         assertEquals(0d, a.doubl());
@@ -159,6 +163,7 @@
     public @interface A2 {
         boolean bool() default true;
         byte byt() default 5;
+        char cha() default 'a';
         Class<?> clas() default Integer.class;
         E1 e1() default E1.b;
         double doubl() default -2;
@@ -179,6 +184,7 @@
         A2 a = (A2) o;
         assertEquals(true, a.bool());
         assertEquals((byte)12, a.byt());
+        assertEquals('c', a.cha());
         assertEquals(String.class, a.clas());
         assertEquals(E1.a, a.e1());
         assertEquals(3.14d, a.doubl());
@@ -192,6 +198,7 @@
     public @interface A1Arrays {
         boolean[] bool();
         byte[] byt();
+        char[] cha();
         Class<?>[] clas();
         E1[] e1();
         double[] doubl();
@@ -212,6 +219,7 @@
         A1Arrays a = (A1Arrays) o;
         assertEquals(null, a.bool());
         assertEquals(null, a.byt());
+        assertEquals(null, a.cha());
         assertEquals(null, a.clas());
         assertEquals(null, a.e1());
         assertEquals(null, a.doubl());
@@ -232,6 +240,7 @@
         A1Arrays a = (A1Arrays) o;
         assertArrayEquals(new boolean[] {true}, a.bool());
         assertArrayEquals(new byte[] {(byte)12}, a.byt());
+        assertArrayEquals(new char[] {'c'}, a.cha());
         assertArrayEquals(new Class<?>[] {String.class}, a.clas());
         assertArrayEquals(new E1[] {E1.a}, a.e1());
         assertArrayEquals(new double[] {3.14d}, a.doubl());
@@ -260,6 +269,7 @@
         Map<String, Object> values = new HashMap();
         values.put("bool", new boolean[] {true, false});
         values.put("byt", new byte[] {12, 3});
+        values.put("cha", new char[] {'c', 'h', 'a', 'r'});
         values.put("clas", new String[] {String.class.getName(), Integer.class.getName()});
         values.put("e1", new String[] {E1.a.name(), E1.b.name()});
         values.put("doubl", new double[] {3.14, 2.78, 9});
@@ -308,6 +318,7 @@
         A1Arrays a = (A1Arrays) o;
         assertArrayEquals(new boolean[] {true, false}, a.bool());
         assertArrayEquals(new byte[] {12, 3}, a.byt());
+        assertArrayEquals(new char[] {'c', 'h', 'a', 'r'}, a.cha());
         assertArrayEquals(new Class<?>[] {String.class, Integer.class}, a.clas());
         assertArrayEquals(new E1[] {E1.a, E1.b}, a.e1());
         assertArrayEquals(new double[] {3.14, 2.78, 9}, a.doubl());