提交 93c668a7 编写于 作者: K kimi

DUBBO-474 泛化实现在调用时不应改变用户原始数据

上级 17243e75
...@@ -27,13 +27,20 @@ import java.lang.reflect.Proxy; ...@@ -27,13 +27,20 @@ import java.lang.reflect.Proxy;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Hashtable;
import java.util.IdentityHashMap; import java.util.IdentityHashMap;
import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; 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.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ConcurrentSkipListMap;
/** /**
* PojoUtils. Travel object deeply, and convert complex type to simple type. * PojoUtils. Travel object deeply, and convert complex type to simple type.
...@@ -114,7 +121,7 @@ public class PojoUtils { ...@@ -114,7 +121,7 @@ public class PojoUtils {
} }
if (pojo instanceof Class) { if (pojo instanceof Class) {
return ((Class<?>)pojo).getName(); return ((Class)pojo).getName();
} }
Object o = history.get(pojo); Object o = history.get(pojo);
...@@ -145,7 +152,7 @@ public class PojoUtils { ...@@ -145,7 +152,7 @@ public class PojoUtils {
} }
if (pojo instanceof Map<?, ?>) { if (pojo instanceof Map<?, ?>) {
Map<Object, Object> src = (Map<Object, Object>)pojo; Map<Object, Object> src = (Map<Object, Object>)pojo;
Map<Object, Object> dest= new HashMap<Object, Object>(src.size()); Map<Object, Object> dest= createMap(src);
history.put(pojo, dest); history.put(pojo, dest);
for (Map.Entry<Object, Object> obj : src.entrySet()) { for (Map.Entry<Object, Object> obj : src.entrySet()) {
dest.put(generalize(obj.getKey(), history), generalize(obj.getValue(), history)); dest.put(generalize(obj.getKey(), history), generalize(obj.getValue(), history));
...@@ -174,7 +181,7 @@ public class PojoUtils { ...@@ -174,7 +181,7 @@ public class PojoUtils {
if (history.containsKey(pojo)) { if (history.containsKey(pojo)) {
Object pojoGenerilizedValue = history.get(pojo); Object pojoGenerilizedValue = history.get(pojo);
if (pojoGenerilizedValue instanceof Map if (pojoGenerilizedValue instanceof Map
&& ((Map<?, ?>)pojoGenerilizedValue).containsKey(field.getName())) { && ((Map)pojoGenerilizedValue).containsKey(field.getName())) {
continue; continue;
} }
} }
...@@ -244,6 +251,47 @@ public class PojoUtils { ...@@ -244,6 +251,47 @@ public class PojoUtils {
return new ArrayList<Object>(); return new ArrayList<Object>();
} }
private static Map createMap(Map src) {
Class<? extends Map> 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<Object, Object>();
}
return result;
}
@SuppressWarnings({ "unchecked", "rawtypes" }) @SuppressWarnings({ "unchecked", "rawtypes" })
private static Object realize0(Object pojo, Class<?> type, Type genericType, final Map<Object, Object> history) { private static Object realize0(Object pojo, Class<?> type, Type genericType, final Map<Object, Object> history) {
if (pojo == null) { if (pojo == null) {
...@@ -352,8 +400,8 @@ public class PojoUtils { ...@@ -352,8 +400,8 @@ public class PojoUtils {
} }
if (Map.class.isAssignableFrom(type) || type == Object.class) { if (Map.class.isAssignableFrom(type) || type == Object.class) {
final Map<Object, Object> dest = new HashMap<Object, Object>(map.size()); final Map<Object, Object> result = createMap(map);
history.put(pojo, dest); history.put(pojo, result);
for (Map.Entry<Object, Object> entry : map.entrySet()) { for (Map.Entry<Object, Object> entry : map.entrySet()) {
Type keyType = getGenericClassByIndex(genericType, 0); Type keyType = getGenericClassByIndex(genericType, 0);
Type valueType = getGenericClassByIndex(genericType, 1); Type valueType = getGenericClassByIndex(genericType, 1);
...@@ -372,9 +420,9 @@ public class PojoUtils { ...@@ -372,9 +420,9 @@ public class PojoUtils {
Object key = keyClazz == null ? entry.getKey() : realize0(entry.getKey(), keyClazz, keyType, history); Object key = keyClazz == null ? entry.getKey() : realize0(entry.getKey(), keyClazz, keyType, history);
Object value = valueClazz == null ? entry.getValue() : realize0(entry.getValue(), valueClazz, valueType, 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()) { } else if (type.isInterface()) {
Object dest = Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class<?>[]{type}, new PojoInvocationHandler(map)); Object dest = Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class<?>[]{type}, new PojoInvocationHandler(map));
history.put(pojo, dest); history.put(pojo, dest);
......
...@@ -27,6 +27,8 @@ import java.util.ArrayList; ...@@ -27,6 +27,8 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
...@@ -588,6 +590,30 @@ public class PojoUtilsTest { ...@@ -588,6 +590,30 @@ public class PojoUtilsTest {
Assert.assertEquals(data.getList().get(0).getAge(), realizadData.getList().get(0).getAge()); Assert.assertEquals(data.getList().get(0).getAge(), realizadData.getList().get(0).getAge());
} }
@Test
public void testRealize() throws Exception {
Map<String, String> inputMap = new LinkedHashMap<String, String>();
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<Person> input = new LinkedList<Person>();
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) { private static Child newChild(String name, int age) {
Child result = new Child(); Child result = new Child();
result.setName(name); result.setName(name);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册