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/08/17 10:15:07 UTC

svn commit: r1756607 - in /felix/trunk/converter/src: main/java/org/apache/felix/converter/impl/ConvertingImpl.java test/java/org/apache/felix/converter/impl/ConverterServiceTest.java test/java/org/apache/felix/converter/impl/MyDTO.java

Author: davidb
Date: Wed Aug 17 10:15:07 2016
New Revision: 1756607

URL: http://svn.apache.org/viewvc?rev=1756607&view=rev
Log:
FELIX-5325 Support embedded DTOs

Patch applied on behalf of David Leangen with many thanks!

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/ConverterServiceTest.java
    felix/trunk/converter/src/test/java/org/apache/felix/converter/impl/MyDTO.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=1756607&r1=1756606&r2=1756607&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 Wed Aug 17 10:15:07 2016
@@ -222,7 +222,7 @@ public class ConvertingImpl implements C
 
     @SuppressWarnings({ "rawtypes", "unchecked" })
     private <T> T convertToDTO(Class<T> targetCls) {
-        Map m = mapView(object);
+        Map m = mapView(object, converter);
 
         try {
             T dto = targetCls.newInstance();
@@ -230,7 +230,11 @@ public class ConvertingImpl implements C
             for (Map.Entry entry : (Set<Map.Entry>) m.entrySet()) {
                 try {
                     Field f = targetCls.getField(entry.getKey().toString());
-                    f.set(dto, entry.getValue());
+                    Object fVal = entry.getValue();
+                    if(DTO.class.isAssignableFrom( f.getType()))
+                        fVal = converter.convert(fVal).to(f.getType());
+                    // TODO convert other embedded objects that require conversion
+                    f.set(dto, fVal);
                 } catch (NoSuchFieldException e) {
                 }
             }
@@ -243,7 +247,7 @@ public class ConvertingImpl implements C
 
     @SuppressWarnings({ "rawtypes", "unchecked" })
     private Map convertToMap(Class<?> targetCls, Type[] typeArguments) {
-        Map m = mapView(object);
+        Map m = mapView(object, converter);
         if (m == null)
             return null;
         Class<?> targetKeyType = null, targetValueType = null;
@@ -287,7 +291,7 @@ public class ConvertingImpl implements C
 
     private Object createJavaBean(Class<?> targetCls) {
         @SuppressWarnings("rawtypes")
-        Map m = mapView(object);
+        Map m = mapView(object, converter);
         try {
             Object res = targetCls.getConstructor().newInstance();
             for (Method setter : getSetters(targetCls)) {
@@ -308,7 +312,7 @@ public class ConvertingImpl implements C
 
     @SuppressWarnings("rawtypes")
     private Object createProxy(Class<?> targetCls) {
-        Map m = mapView(object);
+        Map m = mapView(object, converter);
         return Proxy.newProxyInstance(targetCls.getClassLoader(), new Class[] {targetCls},
             new InvocationHandler() {
                 @Override
@@ -476,7 +480,7 @@ public class ConvertingImpl implements C
     }
 
     @SuppressWarnings({ "rawtypes", "unchecked" })
-    private static Map createMapFromDTO(Object obj) {
+    private static Map createMapFromDTO(Object obj, Converter converter) {
         Map result = new HashMap();
 
         for (Field f : obj.getClass().getFields()) {
@@ -484,7 +488,11 @@ public class ConvertingImpl implements C
                 continue;
 
             try {
-                result.put(f.getName(), f.get(obj)); // TODO handle escaping
+                Object fVal = f.get(obj);
+                if(fVal instanceof DTO)
+                    fVal = converter.convert(fVal).to(Map.class);
+                // TODO test for other embedded types that need conversion
+                result.put(f.getName(), fVal);
             } catch (Exception e) {
             }
         }
@@ -607,20 +615,20 @@ public class ConvertingImpl implements C
         }
     }
 
-    private static Map<?,?> mapView(Object obj) {
+    private static Map<?,?> mapView(Object obj, Converter converter) {
         if (obj instanceof Map)
             return (Map<?,?>) obj;
         else if (obj instanceof Dictionary)
             return null; // TODO
         else if (obj instanceof DTO)
-            return createMapFromDTO(obj);
+            return createMapFromDTO(obj, converter);
         else if (obj.getClass().getInterfaces().length > 0)
             return createMapFromInterface(obj);
         else
             return createMapFromBeanAccessors(obj);
     }
 
-    private boolean isWriteableJavaBean(Class<?> cls) {
+    private static boolean isWriteableJavaBean(Class<?> cls) {
         boolean hasNoArgCtor = false;
         for (Constructor<?> ctor : cls.getConstructors()) {
             if (ctor.getParameterTypes().length == 0)
@@ -632,7 +640,7 @@ public class ConvertingImpl implements C
         return getSetters(cls).size() > 0;
     }
 
-    private Set<Method> getSetters(Class<?> cls) {
+    private static Set<Method> getSetters(Class<?> cls) {
         Set<Method> setters = new HashSet<>();
         while (!Object.class.equals(cls)) {
             Set<Method> methods = new HashSet<>();

Modified: felix/trunk/converter/src/test/java/org/apache/felix/converter/impl/ConverterServiceTest.java
URL: http://svn.apache.org/viewvc/felix/trunk/converter/src/test/java/org/apache/felix/converter/impl/ConverterServiceTest.java?rev=1756607&r1=1756606&r2=1756607&view=diff
==============================================================================
--- felix/trunk/converter/src/test/java/org/apache/felix/converter/impl/ConverterServiceTest.java (original)
+++ felix/trunk/converter/src/test/java/org/apache/felix/converter/impl/ConverterServiceTest.java Wed Aug 17 10:15:07 2016
@@ -40,6 +40,8 @@ import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
+import org.apache.felix.converter.impl.MyDTO.Count;
+import org.apache.felix.converter.impl.MyEmbeddedDTO.Alpha;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -50,6 +52,7 @@ import org.osgi.service.converter.TypeRe
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNotSame;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertSame;
@@ -388,15 +391,29 @@ public class ConverterServiceTest {
 
     @Test
     public void testDTO2Map() {
+        MyEmbeddedDTO embedded = new MyEmbeddedDTO();
+        embedded.marco = "hohoho";
+        embedded.polo = Long.MAX_VALUE;
+        embedded.alpha = Alpha.A;
+        
         MyDTO dto = new MyDTO();
         dto.ping = "lalala";
         dto.pong = Long.MIN_VALUE;
+        dto.count = Count.ONE;
+        dto.embedded = embedded;
 
         @SuppressWarnings("rawtypes")
         Map m = converter.convert(dto).to(Map.class);
-        assertEquals(2, m.size());
+        assertEquals(4, m.size());
         assertEquals("lalala", m.get("ping"));
         assertEquals(Long.MIN_VALUE, m.get("pong"));
+        assertEquals(Count.ONE, m.get("count"));
+        assertNotNull(m.get("embedded"));
+        @SuppressWarnings("rawtypes")
+        Map e = (Map)m.get("embedded");
+        assertEquals("hohoho", e.get("marco"));
+        assertEquals(Long.MAX_VALUE, e.get("polo"));
+        assertEquals(Alpha.A, e.get("alpha"));
     }
 
     @Test
@@ -404,10 +421,21 @@ public class ConverterServiceTest {
         Map<String, Object> m = new HashMap<>();
         m.put("ping", "abc xyz");
         m.put("pong", 42L);
+        m.put("count", Count.ONE);
+        Map<String, Object> e = new HashMap<>();
+        e.put("marco", "ichi ni san");
+        e.put("polo", 64L);
+        e.put("alpha", Alpha.A);
+        m.put("embedded", e);
 
         MyDTO dto = converter.convert(m).to(MyDTO.class);
         assertEquals("abc xyz", dto.ping);
         assertEquals(42L, dto.pong);
+        assertEquals(Count.ONE, dto.count);
+        assertNotNull(dto.embedded);
+        assertEquals(dto.embedded.marco, "ichi ni san");
+        assertEquals(dto.embedded.polo, 64L);
+        assertEquals(dto.embedded.alpha, Alpha.A);
     }
 
     static class MyClass2 {

Modified: felix/trunk/converter/src/test/java/org/apache/felix/converter/impl/MyDTO.java
URL: http://svn.apache.org/viewvc/felix/trunk/converter/src/test/java/org/apache/felix/converter/impl/MyDTO.java?rev=1756607&r1=1756606&r2=1756607&view=diff
==============================================================================
--- felix/trunk/converter/src/test/java/org/apache/felix/converter/impl/MyDTO.java (original)
+++ felix/trunk/converter/src/test/java/org/apache/felix/converter/impl/MyDTO.java Wed Aug 17 10:15:07 2016
@@ -19,7 +19,13 @@ package org.apache.felix.converter.impl;
 import org.osgi.dto.DTO;
 
 public class MyDTO extends DTO {
+    public enum Count { ONE, TWO, THREE }
+
+    public Count count;
+
     public String ping;
 
     public long pong;
+
+    public MyEmbeddedDTO embedded;
 }