You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by da...@apache.org on 2016/04/14 16:41:41 UTC

svn commit: r1739124 - in /felix/trunk/converter/src: main/java/org/apache/felix/converter/impl/ConvertingImpl.java test/java/org/apache/felix/converter/impl/ConverterTest.java

Author: davidb
Date: Thu Apr 14 14:41:40 2016
New Revision: 1739124

URL: http://svn.apache.org/viewvc?rev=1739124&view=rev
Log:
Support various conversions to boolean.

Modified:
    felix/trunk/converter/src/main/java/org/apache/felix/converter/impl/ConvertingImpl.java
    felix/trunk/converter/src/test/java/org/apache/felix/converter/impl/ConverterTest.java

Modified: felix/trunk/converter/src/main/java/org/apache/felix/converter/impl/ConvertingImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/converter/src/main/java/org/apache/felix/converter/impl/ConvertingImpl.java?rev=1739124&r1=1739123&r2=1739124&view=diff
==============================================================================
--- felix/trunk/converter/src/main/java/org/apache/felix/converter/impl/ConvertingImpl.java (original)
+++ felix/trunk/converter/src/main/java/org/apache/felix/converter/impl/ConvertingImpl.java Thu Apr 14 14:41:40 2016
@@ -19,29 +19,56 @@ package org.apache.felix.converter.impl;
 import java.lang.reflect.Method;
 import java.lang.reflect.Type;
 import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
 
 import org.osgi.service.converter.Converter;
 import org.osgi.service.converter.Converting;
 import org.osgi.service.converter.TypeReference;
 
 public class ConvertingImpl implements Converting {
-    private Converter converter;
+    private static final Map<Class<?>, Class<?>> boxedClasses;
+    static {
+        Map<Class<?>, Class<?>> m = new HashMap<>();
+        m.put(int.class, Integer.class);
+        m.put(long.class, Long.class);
+        m.put(double.class, Double.class);
+        m.put(float.class, Float.class);
+        m.put(boolean.class, Boolean.class);
+        m.put(char.class, Character.class);
+        m.put(byte.class, Byte.class);
+        m.put(void.class, Void.class);
+        m.put(short.class, Short.class);
+        boxedClasses = Collections.unmodifiableMap(m);
+    }
+
+//    private Converter converter;
     private final Object object;
 
     ConvertingImpl(Converter c, Object obj) {
-        converter = c;
+//        converter = c;
         object = obj;
     }
 
     @SuppressWarnings("unchecked")
     @Override
     public <T> T to(Class<T> cls) {
+        Class<?> targetCls = cls;
+
         if (object == null)
-            return null;
-        if (cls.isAssignableFrom(object.getClass()))
+            return (T) handleNull(cls);
+
+        targetCls = primitiveToBoxed(targetCls);
+
+        if (targetCls.isAssignableFrom(object.getClass()))
             return (T) object;
 
-        if (String.class.equals(cls)) {
+        T res = (T) trySpecialCases(targetCls);
+        if (res != null)
+            return res;
+
+        if (String.class.equals(targetCls)) {
             if (object instanceof Object[]) {
                 return (T) ((Object[])object)[0];
             } else if (object instanceof Collection) {
@@ -51,14 +78,13 @@ public class ConvertingImpl implements C
                 }
             }
             return (T) object.toString();
-        } else if (String[].class.equals(cls)) {
-            String[] res = new String[1];
-            res[0] = object.toString();
-            return (T) res;
+        } else if (String[].class.equals(targetCls)) {
+            String[] sa = new String[1];
+            sa[0] = object.toString();
+            return (T) sa;
         }
 
-        T res = tryStandardMethods(cls);
-
+        res = (T) tryStandardMethods(targetCls);
         if (res != null) {
             return res;
         } else {
@@ -66,6 +92,26 @@ public class ConvertingImpl implements C
         }
     }
 
+    private Object handleNull(Class<?> cls) {
+        Class<?> boxed = boxedClasses.get(cls);
+        if (boxed == null) {
+            // This is not a primitive, just return null
+            return null;
+        }
+        if (cls.equals(boolean.class))
+            return false;
+        else
+            return 0;
+    }
+
+    private Class<?> primitiveToBoxed(Class<?> cls) {
+        Class<?> boxed = boxedClasses.get(cls);
+        if (boxed != null)
+            return boxed;
+        else
+            return cls;
+    }
+
     @Override
     public <T> T to(TypeReference<T> ref) {
         // TODO Auto-generated method stub
@@ -78,6 +124,27 @@ public class ConvertingImpl implements C
         return null;
     }
 
+    private Object trySpecialCases(Class<?> targetCls) {
+        if (Boolean.class.equals(targetCls)) {
+            if (object instanceof Character) {
+                return ((Character) object).charValue() != (char) 0;
+            } else if (object instanceof Number) {
+                return ((Number) object).longValue() != 0;
+            } else if (object instanceof Collection && ((Collection<?>) object).size() == 0) {
+                return Boolean.FALSE;
+            }
+        } else if (Character.class.equals(targetCls)) {
+            if (object instanceof Boolean) {
+                return ((Boolean) object).booleanValue() ? Character.valueOf((char) 1) : Character.valueOf((char) 0);
+            }
+        } else if (Integer.class.equals(targetCls)) {
+            if (object instanceof Boolean) {
+                return ((Boolean) object).booleanValue() ? Integer.valueOf(1) : Integer.valueOf(0);
+            }
+        }
+        return null;
+    }
+
     @SuppressWarnings("unchecked")
     private <T> T tryStandardMethods(Class<T> cls) {
         try {

Modified: felix/trunk/converter/src/test/java/org/apache/felix/converter/impl/ConverterTest.java
URL: http://svn.apache.org/viewvc/felix/trunk/converter/src/test/java/org/apache/felix/converter/impl/ConverterTest.java?rev=1739124&r1=1739123&r2=1739124&view=diff
==============================================================================
--- felix/trunk/converter/src/test/java/org/apache/felix/converter/impl/ConverterTest.java (original)
+++ felix/trunk/converter/src/test/java/org/apache/felix/converter/impl/ConverterTest.java Thu Apr 14 14:41:40 2016
@@ -29,7 +29,9 @@ import org.osgi.service.converter.Conver
 
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
 
 public class ConverterTest {
     private Converter converter;
@@ -46,6 +48,7 @@ public class ConverterTest {
 
     @Test
     public void testSimpleConversions() {
+        // Conversions to String
         assertEquals("abc", converter.convert("abc").to(String.class));
         assertEquals("true", converter.convert(Boolean.TRUE).to(String.class));
         assertEquals("c", converter.convert('c').to(String.class));
@@ -59,9 +62,22 @@ public class ConverterTest {
         String bistr = "999999999999999999999"; // more than Long.MAX_VALUE
         assertEquals(bistr, converter.convert(new BigInteger(bistr)).to(String.class));
 
+        // Conversions to boolean
+        assertTrue(converter.convert("true").to(boolean.class));
+        assertTrue(converter.convert("TRUE").to(boolean.class));
+        assertTrue(converter.convert('x').to(boolean.class));
+        assertTrue(converter.convert(Long.MIN_VALUE).to(boolean.class));
+        assertFalse(converter.convert("false").to(boolean.class));
+        assertFalse(converter.convert("bleh").to(boolean.class));
+        assertFalse(converter.convert((char) 0).to(boolean.class));
+        assertFalse(converter.convert(null).to(boolean.class));
+        assertFalse(converter.convert(Collections.emptyList()).to(boolean.class));
+
+        // Converstions to integer
+        assertEquals(Integer.valueOf(123), converter.convert("123").to(int.class));
+        assertEquals(1, (int) converter.convert(true).to(int.class));
 
         assertEquals(Integer.valueOf(123), converter.convert("123").to(Integer.class));
-        //assertEquals(Integer.valueOf(123), c.convert("123").to(int.class));
         assertEquals(Long.valueOf(123), converter.convert("123").to(Long.class));
 //        assertEquals(Character.valueOf(123), c.convert("123").to(Character.class));
         assertEquals(Byte.valueOf((byte) 123), converter.convert("123").to(Byte.class));