Author: davidb Date: Tue Jul 11 14:51:56 2017 New Revision: 1801621 URL: http://svn.apache.org/viewvc?rev=1801621&view=rev Log: Felix Converter - better handling of rules with generics
Modified: felix/trunk/converter/converter/src/main/java/org/apache/felix/converter/impl/ConverterBuilderImpl.java felix/trunk/converter/converter/src/main/java/org/apache/felix/converter/impl/ConverterImpl.java felix/trunk/converter/converter/src/test/java/org/apache/felix/converter/impl/ConverterBuilderTest.java felix/trunk/converter/converter/src/test/java/org/apache/felix/converter/impl/ConverterTest.java Modified: felix/trunk/converter/converter/src/main/java/org/apache/felix/converter/impl/ConverterBuilderImpl.java URL: http://svn.apache.org/viewvc/felix/trunk/converter/converter/src/main/java/org/apache/felix/converter/impl/ConverterBuilderImpl.java?rev=1801621&r1=1801620&r2=1801621&view=diff ============================================================================== --- felix/trunk/converter/converter/src/main/java/org/apache/felix/converter/impl/ConverterBuilderImpl.java (original) +++ felix/trunk/converter/converter/src/main/java/org/apache/felix/converter/impl/ConverterBuilderImpl.java Tue Jul 11 14:51:56 2017 @@ -16,7 +16,9 @@ */ package org.apache.felix.converter.impl; +import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; +import java.lang.reflect.WildcardType; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -63,6 +65,24 @@ public class ConverterBuilderImpl implem public ConverterBuilder rule(TargetRule rule) { Type type = rule.getTargetType(); getRulesList(type).add(rule.getFunction()); + + if (type instanceof ParameterizedType) { + ParameterizedType pt = (ParameterizedType) type; + + boolean containsWildCard = false; + for (Type t : pt.getActualTypeArguments()) { + if (t instanceof WildcardType) { + containsWildCard = true; + break; + } + } + + // If the parameterized type is a wildcard (e.g. '?') then register also the raw + // type for the rule. I.e Class<?> will also be registered under bare Class. + if (containsWildCard) + getRulesList(pt.getRawType()).add(rule.getFunction()); + } + return this; } Modified: felix/trunk/converter/converter/src/main/java/org/apache/felix/converter/impl/ConverterImpl.java URL: http://svn.apache.org/viewvc/felix/trunk/converter/converter/src/main/java/org/apache/felix/converter/impl/ConverterImpl.java?rev=1801621&r1=1801620&r2=1801621&view=diff ============================================================================== --- felix/trunk/converter/converter/src/main/java/org/apache/felix/converter/impl/ConverterImpl.java (original) +++ felix/trunk/converter/converter/src/main/java/org/apache/felix/converter/impl/ConverterImpl.java Tue Jul 11 14:51:56 2017 @@ -25,7 +25,6 @@ import java.time.OffsetTime; import java.time.ZonedDateTime; import java.util.Calendar; import java.util.Date; -import java.util.List; import java.util.UUID; import java.util.regex.Pattern; @@ -33,7 +32,6 @@ import org.osgi.util.converter.Converter import org.osgi.util.converter.Converters; import org.osgi.util.converter.Functioning; import org.osgi.util.converter.Rule; -import org.osgi.util.converter.TypeReference; public class ConverterImpl implements InternalConverter { @Override @@ -76,13 +74,11 @@ public class ConverterImpl implements In cb.rule(new Rule<String, UUID>(UUID::fromString) {}); cb.rule(new Rule<String, ZonedDateTime>(ZonedDateTime::parse) {}); - // Special conversions between character arrays / list and String + // Special conversions between character arrays and String cb.rule(new Rule<char[], String>(ConverterImpl::charArrayToString) {}); cb.rule(new Rule<Character[], String>(ConverterImpl::characterArrayToString) {}); -// cb.rule(new Rule<List<Character>, String>(ConverterImpl::characterListToString) {}); cb.rule(new Rule<String, char[]>(ConverterImpl::stringToCharArray) {}); cb.rule(new Rule<String, Character[]>(ConverterImpl::stringToCharacterArray) {}); -// cb.rule(new Rule<String, List<Character>>(ConverterImpl::stringToCharacterList) {}); } private static String charArrayToString(char[] ca) { @@ -97,10 +93,6 @@ public class ConverterImpl implements In return charArrayToString(Converters.standardConverter().convert(ca).to(char[].class)); } - private static String characterListToString(List<Character> cl) { - return charArrayToString(Converters.standardConverter().convert(cl).to(char[].class)); - } - private static char[] stringToCharArray(String s) { char[] ca = new char[s.length()]; @@ -114,10 +106,6 @@ public class ConverterImpl implements In return Converters.standardConverter().convert(stringToCharArray(s)).to(Character[].class); } - private static List<Character> stringToCharacterList(String s) { - return Converters.standardConverter().convert(stringToCharArray(s)).to(new TypeReference<List<Character>>() {}); - } - private Class<?> loadClassUnchecked(String className) { try { return getClass().getClassLoader().loadClass(className); Modified: felix/trunk/converter/converter/src/test/java/org/apache/felix/converter/impl/ConverterBuilderTest.java URL: http://svn.apache.org/viewvc/felix/trunk/converter/converter/src/test/java/org/apache/felix/converter/impl/ConverterBuilderTest.java?rev=1801621&r1=1801620&r2=1801621&view=diff ============================================================================== --- felix/trunk/converter/converter/src/test/java/org/apache/felix/converter/impl/ConverterBuilderTest.java (original) +++ felix/trunk/converter/converter/src/test/java/org/apache/felix/converter/impl/ConverterBuilderTest.java Tue Jul 11 14:51:56 2017 @@ -36,6 +36,7 @@ import org.osgi.util.converter.Converter import org.osgi.util.converter.ConverterFunction; import org.osgi.util.converter.Converters; import org.osgi.util.converter.Rule; +import org.osgi.util.converter.TypeReference; import org.osgi.util.converter.TypeRule; import org.osgi.util.function.Function; @@ -198,7 +199,7 @@ public class ConverterBuilderTest { Converter ca = cb.build(); assertEquals(new ArrayList<>(Arrays.asList("c", "b", "a")), ca.convert( - new String [] {"a", "b", "c"}).to(ArrayList.class)); + new String [] {"a", "b", "c"}).to(new TypeReference<ArrayList<String>>() {})); assertEquals("Precondition", 0, snooped.size()); String[] sa0 = new String [] {"a", "b", "c"}; assertEquals(new LinkedList<>(Arrays.asList("a", "b", "c")), ca.convert( @@ -206,7 +207,7 @@ public class ConverterBuilderTest { assertEquals(1, snooped.size()); assertEquals(LinkedList.class, snooped.get(sa0)); assertEquals(new CopyOnWriteArrayList<>(Arrays.asList("c", "b", "a")), ca.convert( - new String [] {"a", "b", "c"}).to(List.class)); + new String [] {"a", "b", "c"}).to(new TypeReference<List<String>>() {})); snooped.clear(); String[] sa = new String [] {"a", "b", "c"}; Modified: felix/trunk/converter/converter/src/test/java/org/apache/felix/converter/impl/ConverterTest.java URL: http://svn.apache.org/viewvc/felix/trunk/converter/converter/src/test/java/org/apache/felix/converter/impl/ConverterTest.java?rev=1801621&r1=1801620&r2=1801621&view=diff ============================================================================== --- felix/trunk/converter/converter/src/test/java/org/apache/felix/converter/impl/ConverterTest.java (original) +++ felix/trunk/converter/converter/src/test/java/org/apache/felix/converter/impl/ConverterTest.java Tue Jul 11 14:51:56 2017 @@ -96,8 +96,8 @@ public class ConverterTest { assertEquals("" + Long.MAX_VALUE, converter.convert(Long.MAX_VALUE).to(String.class)); assertEquals("12.3", converter.convert(12.3f).to(String.class)); assertEquals("12.345", converter.convert(12.345d).to(String.class)); - assertEquals(null, converter.convert(null).to(String.class)); - assertEquals(null, converter.convert(Collections.emptyList()).to(String.class)); + assertNull(converter.convert(null).to(String.class)); + assertNull(converter.convert(Collections.emptyList()).to(String.class)); String bistr = "999999999999999999999"; // more than Long.MAX_VALUE assertEquals(bistr, converter.convert(new BigInteger(bistr)).to(String.class)); @@ -125,6 +125,7 @@ public class ConverterTest { // Conversions to Class assertEquals(BigDecimal.class, converter.convert("java.math.BigDecimal").to(Class.class)); + assertEquals(BigDecimal.class, converter.convert("java.math.BigDecimal").to(new TypeReference<Class<?>>() {})); assertNull(converter.convert(null).to(Class.class)); assertNull(converter.convert(Collections.emptyList()).to(Class.class)); @@ -141,19 +142,41 @@ public class ConverterTest { @Test public void testCharAggregateToString() { + Converter c = Converters.newConverterBuilder(). + rule(new Rule<List<Character>, String>(ConverterTest::characterListToString) {}). + rule(new Rule<String, List<Character>>(ConverterTest::stringToCharacterList) {}). + build(); + char[] ca = new char[] {'h', 'e', 'l', 'l', 'o'}; - assertEquals("hello", converter.convert(ca).to(String.class)); + assertEquals("hello", c.convert(ca).to(String.class)); - Character[] ca2 = converter.convert(ca).to(Character[].class); - assertEquals("hello", converter.convert(ca2).to(String.class)); + Character[] ca2 = c.convert(ca).to(Character[].class); + assertEquals("hello", c.convert(ca2).to(String.class)); -// List<Character> cl = converter.convert(ca).to(new TypeReference<List<Character>>() {}); -// assertEquals("hello", converter.convert(cl).to(String.class)); + List<Character> cl = c.convert(ca).to(new TypeReference<List<Character>>() {}); + assertEquals("hello", c.convert(cl).to(String.class)); // And back - assertArrayEquals(ca, converter.convert("hello").to(char[].class)); - assertArrayEquals(ca2, converter.convert("hello").to(Character[].class)); -// assertEquals(cl, converter.convert("hello").to(new TypeReference<List<Character>>() {})); + assertArrayEquals(ca, c.convert("hello").to(char[].class)); + assertArrayEquals(ca2, c.convert("hello").to(Character[].class)); + assertEquals(cl, c.convert("hello").to(new TypeReference<List<Character>>() {})); + } + + private static String characterListToString(List<Character> cl) { + StringBuilder sb = new StringBuilder(cl.size()); + for (char c : cl) { + sb.append(c); + } + return sb.toString(); + } + + private static List<Character> stringToCharacterList(String s) { + List<Character> lc = new ArrayList<>(); + + for (int i=0; i<s.length(); i++) { + lc.add(s.charAt(i)); + } + return lc; } enum TestEnum { FOO, BAR, BLAH, FALSE, X};