From 93c668a704b3356cbc8c8b5e7665c6db162afb1e Mon Sep 17 00:00:00 2001 From: kimi Date: Wed, 18 Jul 2012 15:00:40 +0800 Subject: [PATCH] =?UTF-8?q?DUBBO-474=20=E6=B3=9B=E5=8C=96=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0=E5=9C=A8=E8=B0=83=E7=94=A8=E6=97=B6=E4=B8=8D=E5=BA=94?= =?UTF-8?q?=E6=94=B9=E5=8F=98=E7=94=A8=E6=88=B7=E5=8E=9F=E5=A7=8B=E6=95=B0?= =?UTF-8?q?=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../alibaba/dubbo/common/utils/PojoUtils.java | 62 ++++++++++++++++--- .../dubbo/common/utils/PojoUtilsTest.java | 26 ++++++++ 2 files changed, 81 insertions(+), 7 deletions(-) diff --git a/dubbo-common/src/main/java/com/alibaba/dubbo/common/utils/PojoUtils.java b/dubbo-common/src/main/java/com/alibaba/dubbo/common/utils/PojoUtils.java index 4046d1861..9b4f7c51e 100644 --- a/dubbo-common/src/main/java/com/alibaba/dubbo/common/utils/PojoUtils.java +++ b/dubbo-common/src/main/java/com/alibaba/dubbo/common/utils/PojoUtils.java @@ -27,13 +27,20 @@ import java.lang.reflect.Proxy; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; +import java.util.Hashtable; import java.util.IdentityHashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Properties; +import java.util.TreeMap; +import java.util.WeakHashMap; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.ConcurrentSkipListMap; /** * PojoUtils. Travel object deeply, and convert complex type to simple type. @@ -114,7 +121,7 @@ public class PojoUtils { } if (pojo instanceof Class) { - return ((Class)pojo).getName(); + return ((Class)pojo).getName(); } Object o = history.get(pojo); @@ -145,7 +152,7 @@ public class PojoUtils { } if (pojo instanceof Map) { Map src = (Map)pojo; - Map dest= new HashMap(src.size()); + Map dest= createMap(src); history.put(pojo, dest); for (Map.Entry obj : src.entrySet()) { dest.put(generalize(obj.getKey(), history), generalize(obj.getValue(), history)); @@ -174,7 +181,7 @@ public class PojoUtils { if (history.containsKey(pojo)) { Object pojoGenerilizedValue = history.get(pojo); if (pojoGenerilizedValue instanceof Map - && ((Map)pojoGenerilizedValue).containsKey(field.getName())) { + && ((Map)pojoGenerilizedValue).containsKey(field.getName())) { continue; } } @@ -244,6 +251,47 @@ public class PojoUtils { return new ArrayList(); } + private static Map createMap(Map src) { + Class cl = src.getClass(); + Map result = null; + if (HashMap.class == cl) { + result = new HashMap(); + } else if (Hashtable.class == cl) { + result = new Hashtable(); + } else if (IdentityHashMap.class == cl) { + result = new IdentityHashMap(); + } else if (LinkedHashMap.class == cl) { + result = new LinkedHashMap(); + } else if (Properties.class == cl) { + result = new Properties(); + } else if (TreeMap.class == cl) { + result = new TreeMap(); + } else if (WeakHashMap.class == cl) { + return new WeakHashMap(); + } else if (ConcurrentHashMap.class == cl) { + result = new ConcurrentHashMap(); + } else if (ConcurrentSkipListMap.class == cl) { + result = new ConcurrentSkipListMap(); + } else { + try { + result = cl.newInstance(); + } catch (Exception e) { /* ignore */ } + + if (result == null) { + try { + Constructor constructor = cl.getConstructor(Map.class); + result = (Map)constructor.newInstance(Collections.EMPTY_MAP); + } catch (Exception e) { /* ignore */ } + } + } + + if (result == null) { + result = new HashMap(); + } + + return result; + } + @SuppressWarnings({ "unchecked", "rawtypes" }) private static Object realize0(Object pojo, Class type, Type genericType, final Map history) { if (pojo == null) { @@ -352,8 +400,8 @@ public class PojoUtils { } if (Map.class.isAssignableFrom(type) || type == Object.class) { - final Map dest = new HashMap(map.size()); - history.put(pojo, dest); + final Map result = createMap(map); + history.put(pojo, result); for (Map.Entry entry : map.entrySet()) { Type keyType = getGenericClassByIndex(genericType, 0); Type valueType = getGenericClassByIndex(genericType, 1); @@ -372,9 +420,9 @@ public class PojoUtils { Object key = keyClazz == null ? entry.getKey() : realize0(entry.getKey(), keyClazz, keyType, history); Object value = valueClazz == null ? entry.getValue() : realize0(entry.getValue(), valueClazz, valueType, history); - dest.put(key, value); + result.put(key, value); } - return dest; + return result; } else if (type.isInterface()) { Object dest = Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class[]{type}, new PojoInvocationHandler(map)); history.put(pojo, dest); diff --git a/dubbo-common/src/test/java/com/alibaba/dubbo/common/utils/PojoUtilsTest.java b/dubbo-common/src/test/java/com/alibaba/dubbo/common/utils/PojoUtilsTest.java index f84f3cea4..dc346389d 100644 --- a/dubbo-common/src/test/java/com/alibaba/dubbo/common/utils/PojoUtilsTest.java +++ b/dubbo-common/src/test/java/com/alibaba/dubbo/common/utils/PojoUtilsTest.java @@ -27,6 +27,8 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.UUID; @@ -588,6 +590,30 @@ public class PojoUtilsTest { Assert.assertEquals(data.getList().get(0).getAge(), realizadData.getList().get(0).getAge()); } + @Test + public void testRealize() throws Exception { + Map inputMap = new LinkedHashMap(); + inputMap.put("key", "value"); + Object obj = PojoUtils.generalize(inputMap); + Assert.assertTrue(obj instanceof LinkedHashMap); + Object outputObject = PojoUtils.realize(inputMap, LinkedHashMap.class); + System.out.println(outputObject.getClass().getName()); + Assert.assertTrue(outputObject instanceof LinkedHashMap); + } + + @Test + public void testRealizeLinkedList() throws Exception { + LinkedList input = new LinkedList(); + Person person = new Person(); + person.setAge(37); + input.add(person); + Object obj = PojoUtils.generalize(input); + Assert.assertTrue(obj instanceof List); + Assert.assertTrue(input.get(0) instanceof Person); + Object output = PojoUtils.realize(obj, LinkedList.class); + Assert.assertTrue(output instanceof LinkedList); + } + private static Child newChild(String name, int age) { Child result = new Child(); result.setName(name); -- GitLab