Hello, I'm considering a change to improve the flexibility of [configuration] with regard to the numbers conversions. Currently any Number put in a configuration can't be retrieved as another Number type, for example:

config.setProperty("number", new Byte(123));
config.getInteger("number");

throws a ClassCastException, but:

config.setProperty("number", "123");
config.getInteger("number");

works fine.

The change consists in testing in the getXXX methods if the object retrieved is a Number and call the Number.xxxValue() method to convert it to the appropriate type. I'm attaching a patch and a test case to illustrate this.

What do you think ?

Emmanuel Bourg
Index: src/java/org/apache/commons/configuration/AbstractConfiguration.java
===================================================================
RCS file: 
/home/cvspublic/jakarta-commons/configuration/src/java/org/apache/commons/configuration/AbstractConfiguration.java,v
retrieving revision 1.8
diff -u -r1.8 AbstractConfiguration.java
--- src/java/org/apache/commons/configuration/AbstractConfiguration.java        4 May 
2004 22:27:10 -0000       1.8
+++ src/java/org/apache/commons/configuration/AbstractConfiguration.java        13 Jun 
2004 12:39:20 -0000
@@ -588,6 +588,10 @@
         {
             return (Byte) value;
         }
+        else if (value instanceof Number)
+        {
+            return new Byte(((Number) value).byteValue());
+        }
         else if (value instanceof String)
         {
             Byte b = new Byte((String) value);
@@ -672,6 +676,10 @@
         {
             return (Double) value;
         }
+        else if (value instanceof Number)
+        {
+            return new Double(((Number) value).doubleValue());
+        }
         else if (value instanceof String)
         {
             Double d = new Double((String) value);
@@ -756,6 +764,10 @@
         {
             return (Float) value;
         }
+        else if (value instanceof Number)
+        {
+            return new Float(((Number) value).floatValue());
+        }
         else if (value instanceof String)
         {
             Float f = new Float((String) value);
@@ -847,6 +859,10 @@
         {
             return (Integer) value;
         }
+        else if (value instanceof Number)
+        {
+            return new Integer(((Number) value).intValue());
+        }
         else if (value instanceof String)
         {
             Integer i = new Integer((String) value);
@@ -931,6 +947,10 @@
         {
             return (Long) value;
         }
+        else if (value instanceof Number)
+        {
+            return new Long(((Number) value).longValue());
+        }
         else if (value instanceof String)
         {
             Long l = new Long((String) value);
@@ -1015,6 +1035,10 @@
         {
             return (Short) value;
         }
+        else if (value instanceof Number)
+        {
+            return new Short(((Number) value).shortValue());
+        }
         else if (value instanceof String)
         {
             Short s = new Short((String) value);
@@ -1051,6 +1075,10 @@
         {
             return (BigDecimal) value;
         }
+        else if (value instanceof Number)
+        {
+            return new BigDecimal(value.toString());
+        }
         else if (value instanceof String)
         {
             BigDecimal number = new BigDecimal((String) value);
@@ -1083,9 +1111,13 @@
     public BigInteger getBigInteger(String key, BigInteger defaultValue) {
         Object value = resolveContainerStore(key);
 
-        if (value instanceof BigDecimal)
+        if (value instanceof BigInteger)
         {
             return (BigInteger) value;
+        }
+        else if (value instanceof Number)
+        {
+            return new BigInteger(value.toString());
         }
         else if (value instanceof String)
         {

Index: src/test/org/apache/commons/configuration/TestBaseConfiguration.java
===================================================================
RCS file: 
/home/cvspublic/jakarta-commons/configuration/src/test/org/apache/commons/configuration/TestBaseConfiguration.java,v
retrieving revision 1.9
diff -u -r1.9 TestBaseConfiguration.java
--- src/test/org/apache/commons/configuration/TestBaseConfiguration.java        13 May 
2004 12:19:16 -0000      1.9
+++ src/test/org/apache/commons/configuration/TestBaseConfiguration.java        13 Jun 
2004 12:39:22 -0000
@@ -481,6 +481,31 @@
                fail("IllegalStateException should have been thrown for looped 
property references");
        }
 
-    
+    public void testNumberConversion()
+    {
+        // upcasting
+        config.setProperty("number", new Byte((byte) 123));
+        assertEquals("Byte to Short", new Short((short) 123), 
config.getShort("number", null));
+        assertEquals("Byte to Integer", new Integer(123), config.getInteger("number", 
null));
+        assertEquals("Byte to Long", new Long(123), config.getLong("number", null));
+        assertEquals("Byte to Float", new Float(123), config.getFloat("number", 
null));
+        assertEquals("Byte to Double", new Double(123), config.getDouble("number", 
null));
+        assertEquals("Byte to BigInteger", new BigInteger("123"), 
config.getBigInteger("number"));
+        assertEquals("Byte to BigDecimal", new BigDecimal(123), 
config.getBigDecimal("number"));
+
+        // downcasting
+        config.setProperty("number", new Long(Long.MAX_VALUE));
+        assertEquals("Long to Integer", -1, config.getInt("number"));
+        assertEquals("Long to Short", -1, config.getShort("number"));
+        assertEquals("Long to Byte", -1, config.getByte("number"));
+
+        // big numbers
+        String number = "10000000000000000000000";
+        config.setProperty("number", new BigInteger(number));
+        assertEquals("BigInteger to BigDecimal", new BigDecimal(number), 
config.getBigDecimal("number"));
+        config.setProperty("number", new BigDecimal(number));
+        assertEquals("BigDecimal to BigInteger", new BigInteger(number), 
config.getBigInteger("number"));
+    }
+
 }
 

Attachment: smime.p7s
Description: S/MIME Cryptographic Signature

Reply via email to