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/15 12:52:19 UTC

svn commit: r1739279 - 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: Fri Apr 15 10:52:19 2016
New Revision: 1739279

URL: http://svn.apache.org/viewvc?rev=1739279&view=rev
Log:
Felix Converter Service - more support for collections and arrays.

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=1739279&r1=1739278&r2=1739279&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 Fri Apr 15 10:52:19 2016
@@ -16,13 +16,20 @@
  */
 package org.apache.felix.converter.impl;
 
+import java.lang.reflect.Array;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Method;
 import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import org.osgi.service.converter.Converter;
 import org.osgi.service.converter.Converting;
@@ -43,6 +50,14 @@ public class ConvertingImpl implements C
         m.put(short.class, Short.class);
         boxedClasses = Collections.unmodifiableMap(m);
     }
+    private static final Map<Class<?>, Class<?>> interfaceImplementations;
+    static {
+        Map<Class<?>, Class<?>> m = new HashMap<>();
+        m.put(Collection.class, ArrayList.class);
+        m.put(List.class, ArrayList.class);
+        m.put(Set.class, LinkedHashSet.class); // preserves insertion order
+        interfaceImplementations = Collections.unmodifiableMap(m);
+    }
 
     private Converter converter;
     private final Object object;
@@ -101,16 +116,64 @@ public class ConvertingImpl implements C
 
     @SuppressWarnings("unchecked")
     private <T> T convertToArray(Class<?> targetClass) {
-        String[] sa = new String[1];
-        sa[0] = object.toString();
-        return (T) sa;
+        Collection<?> collectionView = collectionView(object);
+        Iterator<?> itertor = collectionView.iterator();
+        try {
+            Object array = Array.newInstance(targetClass.getComponentType(), collectionView.size());
+            for (int i=0; i<collectionView.size() && itertor.hasNext(); i++) {
+                Object next = itertor.next();
+                Object converted = converter.convert(next).to(targetClass.getComponentType());
+                Array.set(array, i, converted);
+            }
+            return (T) array;
+        } catch (Exception e) {
+            return null;
+        }
     }
 
+    @SuppressWarnings({ "unchecked", "rawtypes" })
     private <T> T convertToCollection(Class<?> targetCls) {
-        // TODO Auto-generated method stub
+        Collection<?> collectionView = collectionView(object);
+
+        Class<?> ctrCls = interfaceImplementations.get(targetCls);
+        if (ctrCls != null)
+            targetCls = ctrCls;
+
+        Collection instance = createCollection(targetCls, collectionView);
+        if (instance == null)
+            return null;
+
+        for (Object o : collectionView) {
+            instance.add(o);
+        }
+
+        return (T) instance;
+    }
+
+    private static Collection<?> createCollection(Class<?> targetCls, Collection<?> collectionView) {
+        try {
+            Constructor<?> ctor = targetCls.getConstructor(int.class);
+            return (Collection<?>) ctor.newInstance(collectionView.size());
+        } catch (Exception e1) {
+            try {
+                Constructor<?> ctor2 = targetCls.getConstructor();
+                return (Collection<?>) ctor2.newInstance();
+            } catch (Exception e2) {
+                e2.printStackTrace();
+            }
+        }
         return null;
     }
 
+    private static Collection<?> collectionView(Object obj) {
+        if (obj instanceof Collection)
+            return (Collection<?>) obj;
+        else if (obj instanceof Object[])
+            return Arrays.asList((Object[]) obj);
+        else
+            return Collections.singleton(obj);
+    }
+
     private Object handleNull(Class<?> cls) {
         Class<?> boxed = boxedClasses.get(cls);
         if (boxed == null) {

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=1739279&r1=1739278&r2=1739279&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 Fri Apr 15 10:52:19 2016
@@ -22,6 +22,7 @@ import java.net.URL;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Set;
 import java.util.stream.Collectors;
@@ -29,7 +30,6 @@ import java.util.stream.Stream;
 
 import org.junit.After;
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.osgi.service.converter.Adapter;
 import org.osgi.service.converter.Converter;
@@ -169,12 +169,35 @@ public class ConverterTest {
         assertEquals(Float.valueOf(3.1412f), Float.valueOf(converter.convert(arr).to(float.class)));
     }
 
-    @Test @Ignore
+    @Test
     public void testFromListToSet() {
         List<Object> l = new ArrayList<>(Arrays.asList("A", 'B', 333));
 
         Set<?> s = converter.convert(l).to(Set.class);
         assertEquals(3, s.size());
+
+        for (Object o : s) {
+            Object expected = l.remove(0);
+            assertEquals(expected, o);
+        }
+    }
+
+    @Test
+    public void testFromSetToArray() {
+        Set<Integer> s = new LinkedHashSet<>();
+        s.add(Integer.MIN_VALUE);
+
+        long[] la = converter.convert(s).to(long[].class);
+        assertEquals(1, la.length);
+        assertEquals(Integer.MIN_VALUE, la[0]);
+    }
+
+    @Test
+    public void testStringArrayToIntegerArray() {
+        String[] sa = {"999", "111", "-909"};
+        Integer[] ia = converter.convert(sa).to(Integer[].class);
+        assertEquals(3, ia.length);
+        assertArrayEquals(new Integer[] {999, 111, -909}, ia);
     }
 
     @Test