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};


Reply via email to