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