This is an automated email from the ASF dual-hosted git repository.
albumenj pushed a commit to branch 3.2
in repository https://gitbox.apache.org/repos/asf/dubbo.git
The following commit(s) were added to refs/heads/3.2 by this push:
new 960f6523f9 pojoutil support generic (#11914)
960f6523f9 is described below
commit 960f6523f99eb0785f4d7495f43dc1ed7163fd8d
Author: Owen.Cai <[email protected]>
AuthorDate: Thu Mar 30 20:41:12 2023 +0800
pojoutil support generic (#11914)
* pojoutil support generic
* add test
* generic pojo
---------
Co-authored-by: caizhenqiu <[email protected]>
---
.../org/apache/dubbo/common/utils/PojoUtils.java | 67 +++++--
.../apache/dubbo/common/model/person/Ageneric.java | 38 ++++
.../apache/dubbo/common/model/person/Bgeneric.java | 38 ++++
.../apache/dubbo/common/model/person/Cgeneric.java | 56 ++++++
.../apache/dubbo/common/model/person/Dgeneric.java | 56 ++++++
.../apache/dubbo/common/utils/PojoUtilsTest.java | 208 +++++++++++++++++++++
6 files changed, 450 insertions(+), 13 deletions(-)
diff --git
a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/PojoUtils.java
b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/PojoUtils.java
index b290529ccb..60a78061f4 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/PojoUtils.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/PojoUtils.java
@@ -329,6 +329,10 @@ public class PojoUtils {
@SuppressWarnings({"unchecked", "rawtypes"})
private static Object realize0(Object pojo, Class<?> type, Type
genericType, final Map<Object, Object> history) {
+ return realize1(pojo, type, genericType, new HashMap<>(8), history);
+ }
+
+ private static Object realize1(Object pojo, Class<?> type, Type
genericType, final Map<String, Type> mapParent, final Map<Object, Object>
history) {
if (pojo == null) {
return null;
}
@@ -352,6 +356,19 @@ public class PojoUtils {
history.put(pojo, pojo);
+ Map<String, Type> mapGeneric = new HashMap<>(8);
+ mapGeneric.putAll(mapParent);
+ TypeVariable<? extends Class<?>>[] typeParameters =
type.getTypeParameters();
+ if(genericType instanceof ParameterizedType && typeParameters.length >
0) {
+ ParameterizedType parameterizedType =
(ParameterizedType)genericType;
+ Type[] actualTypeArguments =
parameterizedType.getActualTypeArguments();
+ for (int i = 0; i < typeParameters.length; i++) {
+ if(!(actualTypeArguments[i] instanceof TypeVariable)) {
+ mapGeneric.put(typeParameters[i].getTypeName(),
actualTypeArguments[i]);
+ }
+ }
+ }
+
if (pojo.getClass().isArray()) {
if (Collection.class.isAssignableFrom(type)) {
Class<?> ctype = pojo.getClass().getComponentType();
@@ -360,7 +377,7 @@ public class PojoUtils {
history.put(pojo, dest);
for (int i = 0; i < len; i++) {
Object obj = Array.get(pojo, i);
- Object value = realize0(obj, ctype, null, history);
+ Object value = realize1(obj, ctype, null, mapGeneric,
history);
dest.add(value);
}
return dest;
@@ -371,7 +388,7 @@ public class PojoUtils {
history.put(pojo, dest);
for (int i = 0; i < len; i++) {
Object obj = Array.get(pojo, i);
- Object value = realize0(obj, ctype, null, history);
+ Object value = realize1(obj, ctype, null, mapGeneric,
history);
Array.set(dest, i, value);
}
return dest;
@@ -387,7 +404,7 @@ public class PojoUtils {
history.put(pojo, dest);
int i = 0;
for (Object obj : src) {
- Object value = realize0(obj, ctype, null, history);
+ Object value = realize1(obj, ctype, null, mapGeneric,
history);
Array.set(dest, i, value);
i++;
}
@@ -403,7 +420,7 @@ public class PojoUtils {
if (keyType instanceof Class) {
keyClazz = (Class<?>) keyType;
}
- Object value = realize0(obj, keyClazz, keyType, history);
+ Object value = realize1(obj, keyClazz, keyType,
mapGeneric, history);
dest.add(value);
}
return dest;
@@ -486,8 +503,8 @@ public class PojoUtils {
valueClazz = entry.getValue() == null ? null :
entry.getValue().getClass();
}
- 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 key = keyClazz == null ? entry.getKey() :
realize1(entry.getKey(), keyClazz, keyType, mapGeneric, history);
+ Object value = valueClazz == null ? entry.getValue() :
realize1(entry.getValue(), valueClazz, valueType, mapGeneric, history);
result.put(key, value);
}
return result;
@@ -509,6 +526,7 @@ public class PojoUtils {
}
history.put(pojo, dest);
+
for (Map.Entry<Object, Object> entry : map.entrySet()) {
Object key = entry.getKey();
if (key instanceof String) {
@@ -521,8 +539,24 @@ public class PojoUtils {
if (!method.isAccessible()) {
method.setAccessible(true);
}
- Type ptype =
method.getGenericParameterTypes()[0];
- value = realize0(value,
method.getParameterTypes()[0], ptype, history);
+ Type containType =
mapGeneric.get(field.getGenericType().getTypeName());
+ if(containType != null) {
+ //is generic
+ if(containType instanceof
ParameterizedType) {
+ value = realize1(value, (Class<?>)
((ParameterizedType)containType).getRawType(), containType, mapGeneric,
history);
+ }
+ else if (containType instanceof Class){
+ value = realize1(value, (Class<?>)
containType, containType, mapGeneric, history);
+ }
+ else {
+ Type ptype =
method.getGenericParameterTypes()[0];
+ value = realize1(value,
method.getParameterTypes()[0], ptype, mapGeneric, history);
+ }
+ }
+ else {
+ Type ptype =
method.getGenericParameterTypes()[0];
+ value = realize1(value,
method.getParameterTypes()[0], ptype, mapGeneric, history);
+ }
try {
method.invoke(dest, value);
} catch (Exception e) {
@@ -532,7 +566,7 @@ public class PojoUtils {
throw new
RuntimeException(exceptionDescription, e);
}
} else if (field != null) {
- value = realize0(value, field.getType(),
field.getGenericType(), history);
+ value = realize1(value, field.getType(),
field.getGenericType(), mapGeneric, history);
try {
field.set(dest, value);
} catch (IllegalAccessException e) {
@@ -675,10 +709,16 @@ public class PojoUtils {
if (CLASS_FIELD_CACHE.containsKey(cls) &&
CLASS_FIELD_CACHE.get(cls).containsKey(fieldName)) {
return CLASS_FIELD_CACHE.get(cls).get(fieldName);
}
- try {
- result = cls.getDeclaredField(fieldName);
- result.setAccessible(true);
- } catch (NoSuchFieldException e) {
+ for(Class<?> acls = cls; acls != null; acls = acls.getSuperclass()) {
+ try {
+ result = acls.getDeclaredField(fieldName);
+ if (!Modifier.isPublic(result.getModifiers())) {
+ result.setAccessible(true);
+ }
+ } catch (NoSuchFieldException e) {
+ }
+ }
+ if(result == null) {
for (Field field : cls.getFields()) {
if (fieldName.equals(field.getName()) &&
ReflectUtils.isPublicInstanceField(field)) {
result = field;
@@ -686,6 +726,7 @@ public class PojoUtils {
}
}
}
+
if (result != null) {
ConcurrentMap<String, Field> fields =
CLASS_FIELD_CACHE.computeIfAbsent(cls, k -> new ConcurrentHashMap<>());
fields.putIfAbsent(fieldName, result);
diff --git
a/dubbo-common/src/test/java/org/apache/dubbo/common/model/person/Ageneric.java
b/dubbo-common/src/test/java/org/apache/dubbo/common/model/person/Ageneric.java
new file mode 100644
index 0000000000..2662f029ab
--- /dev/null
+++
b/dubbo-common/src/test/java/org/apache/dubbo/common/model/person/Ageneric.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.common.model.person;
+
+import java.io.Serializable;
+
+public class Ageneric<T> implements Serializable {
+ public static String NAME = "A";
+
+ private String name = NAME;
+ private T data;
+
+ public T getData() {
+ return data;
+ }
+
+ public void setData(T data) {
+ this.data = data;
+ }
+
+ public String getName() {
+ return name;
+ }
+}
diff --git
a/dubbo-common/src/test/java/org/apache/dubbo/common/model/person/Bgeneric.java
b/dubbo-common/src/test/java/org/apache/dubbo/common/model/person/Bgeneric.java
new file mode 100644
index 0000000000..1a4408cbb6
--- /dev/null
+++
b/dubbo-common/src/test/java/org/apache/dubbo/common/model/person/Bgeneric.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.common.model.person;
+
+import java.io.Serializable;
+
+public class Bgeneric<T> implements Serializable {
+ public static String NAME = "B";
+
+ private String name = NAME;
+ private T data;
+
+ public T getData() {
+ return data;
+ }
+
+ public void setData(T data) {
+ this.data = data;
+ }
+
+ public String getName() {
+ return name;
+ }
+}
diff --git
a/dubbo-common/src/test/java/org/apache/dubbo/common/model/person/Cgeneric.java
b/dubbo-common/src/test/java/org/apache/dubbo/common/model/person/Cgeneric.java
new file mode 100644
index 0000000000..2a47cc50ad
--- /dev/null
+++
b/dubbo-common/src/test/java/org/apache/dubbo/common/model/person/Cgeneric.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.common.model.person;
+
+import java.io.Serializable;
+
+public class Cgeneric<T> implements Serializable {
+ public static String NAME = "C";
+
+ private String name = NAME;
+ private T data;
+ private Ageneric<T> a;
+ private Bgeneric<PersonInfo> b;
+
+ public T getData() {
+ return data;
+ }
+
+ public void setData(T data) {
+ this.data = data;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public Ageneric<T> getA() {
+ return a;
+ }
+
+ public void setA(Ageneric<T> a) {
+ this.a = a;
+ }
+
+ public Bgeneric<PersonInfo> getB() {
+ return b;
+ }
+
+ public void setB(Bgeneric<PersonInfo> b) {
+ this.b = b;
+ }
+}
diff --git
a/dubbo-common/src/test/java/org/apache/dubbo/common/model/person/Dgeneric.java
b/dubbo-common/src/test/java/org/apache/dubbo/common/model/person/Dgeneric.java
new file mode 100644
index 0000000000..0aaabd87a5
--- /dev/null
+++
b/dubbo-common/src/test/java/org/apache/dubbo/common/model/person/Dgeneric.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.common.model.person;
+
+import java.io.Serializable;
+
+public class Dgeneric<T,Y,Z> implements Serializable {
+ public static String NAME = "D";
+
+ private String name = NAME;
+ private T t;
+ private Y y;
+ private Z z;
+
+ public T getT() {
+ return t;
+ }
+
+ public void setT(T t) {
+ this.t = t;
+ }
+
+ public Y getY() {
+ return y;
+ }
+
+ public void setY(Y y) {
+ this.y = y;
+ }
+
+ public Z getZ() {
+ return z;
+ }
+
+ public void setZ(Z z) {
+ this.z = z;
+ }
+
+ public String getName() {
+ return name;
+ }
+}
diff --git
a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/PojoUtilsTest.java
b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/PojoUtilsTest.java
index 9140168ecd..4c67a41d99 100644
---
a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/PojoUtilsTest.java
+++
b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/PojoUtilsTest.java
@@ -34,11 +34,16 @@ import java.util.List;
import java.util.Map;
import java.util.UUID;
+import com.alibaba.fastjson.JSON;
import org.apache.dubbo.common.model.Person;
import org.apache.dubbo.common.model.SerializablePerson;
import org.apache.dubbo.common.model.User;
+import org.apache.dubbo.common.model.person.Bgeneric;
import org.apache.dubbo.common.model.person.BigPerson;
+import org.apache.dubbo.common.model.person.Cgeneric;
+import org.apache.dubbo.common.model.person.Dgeneric;
import org.apache.dubbo.common.model.person.FullAddress;
+import org.apache.dubbo.common.model.person.Ageneric;
import org.apache.dubbo.common.model.person.PersonInfo;
import org.apache.dubbo.common.model.person.PersonMap;
import org.apache.dubbo.common.model.person.PersonStatus;
@@ -790,6 +795,209 @@ class PojoUtilsTest {
assertEquals(PersonMap.class, result.getClass());
}
+
+ protected PersonInfo createPersonInfoByName(String name) {
+ PersonInfo dataPerson = new PersonInfo();
+ dataPerson.setName(name);
+ return dataPerson;
+ }
+
+ protected Ageneric<PersonInfo> createAGenericPersonInfo(String name) {
+ Ageneric<PersonInfo> ret = new Ageneric();
+ ret.setData(createPersonInfoByName(name));
+ return ret;
+ }
+
+ protected Bgeneric<PersonInfo> createBGenericPersonInfo(String name) {
+ Bgeneric<PersonInfo> ret = new Bgeneric();
+ ret.setData(createPersonInfoByName(name));
+ return ret;
+ }
+
+ @Test
+ public void testPojoGeneric1() throws NoSuchMethodException {
+ String personName = "testName";
+
+ {
+ Ageneric<PersonInfo> genericPersonInfo =
createAGenericPersonInfo(personName);
+
+ Object o = JSON.toJSON(genericPersonInfo);
+ {
+ Ageneric personInfo = (Ageneric) PojoUtils.realize(o,
Ageneric.class);
+
+ assertEquals(Ageneric.NAME, personInfo.getName());
+ assertTrue(personInfo.getData() instanceof Map);
+ }
+ {
+ Type[] createGenericPersonInfos =
ReflectUtils.getReturnTypes(PojoUtilsTest.class.getDeclaredMethod("createAGenericPersonInfo",
String.class));
+ Ageneric personInfo = (Ageneric) PojoUtils.realize(o,
(Class)createGenericPersonInfos[0], createGenericPersonInfos[1]);
+
+ assertEquals(Ageneric.NAME, personInfo.getName());
+ assertEquals(personInfo.getData().getClass(),
PersonInfo.class);
+ assertEquals(personName,
((PersonInfo)personInfo.getData()).getName());
+ }
+ }
+ {
+ Bgeneric<PersonInfo> genericPersonInfo =
createBGenericPersonInfo(personName);
+
+ Object o = JSON.toJSON(genericPersonInfo);
+ {
+ Bgeneric personInfo = (Bgeneric) PojoUtils.realize(o,
Bgeneric.class);
+
+ assertEquals(Bgeneric.NAME, personInfo.getName());
+ assertTrue(personInfo.getData() instanceof Map);
+ }
+ {
+ Type[] createGenericPersonInfos =
ReflectUtils.getReturnTypes(PojoUtilsTest.class.getDeclaredMethod("createBGenericPersonInfo",
String.class));
+ Bgeneric personInfo = (Bgeneric) PojoUtils.realize(o,
(Class)createGenericPersonInfos[0], createGenericPersonInfos[1]);
+
+ assertEquals(Bgeneric.NAME, personInfo.getName());
+ assertEquals(personInfo.getData().getClass(),
PersonInfo.class);
+ assertEquals(personName,
((PersonInfo)personInfo.getData()).getName());
+ }
+ }
+ }
+
+ protected Ageneric<Ageneric<PersonInfo>> createAGenericLoop(String name) {
+ Ageneric<Ageneric<PersonInfo>> ret = new Ageneric();
+ ret.setData(createAGenericPersonInfo(name));
+ return ret;
+ }
+
+ protected Bgeneric<Ageneric<PersonInfo>> createBGenericWithAgeneric(String
name) {
+ Bgeneric<Ageneric<PersonInfo>> ret = new Bgeneric();
+ ret.setData(createAGenericPersonInfo(name));
+ return ret;
+ }
+
+ @Test
+ public void testPojoGeneric2() throws NoSuchMethodException {
+ String personName = "testName";
+
+ {
+ Ageneric<Ageneric<PersonInfo>> generic2PersonInfo =
createAGenericLoop(personName);
+ Object o = JSON.toJSON(generic2PersonInfo);
+ {
+ Ageneric personInfo = (Ageneric) PojoUtils.realize(o,
Ageneric.class);
+
+ assertEquals(Ageneric.NAME, personInfo.getName());
+ assertTrue(personInfo.getData() instanceof Map);
+ }
+ {
+ Type[] createGenericPersonInfos =
ReflectUtils.getReturnTypes(PojoUtilsTest.class.getDeclaredMethod("createAGenericLoop",
String.class));
+ Ageneric personInfo = (Ageneric) PojoUtils.realize(o,
(Class)createGenericPersonInfos[0], createGenericPersonInfos[1]);
+
+ assertEquals(Ageneric.NAME, personInfo.getName());
+ assertEquals(personInfo.getData().getClass(), Ageneric.class);
+ assertEquals(Ageneric.NAME,
((Ageneric)personInfo.getData()).getName());
+
assertEquals(((Ageneric)personInfo.getData()).getData().getClass(),
PersonInfo.class);
+ assertEquals(personName,
((PersonInfo)((Ageneric)personInfo.getData()).getData()).getName());
+ }
+ }
+ {
+
+ Bgeneric<Ageneric<PersonInfo>> generic =
createBGenericWithAgeneric(personName);
+ Object o = JSON.toJSON(generic);
+ {
+ Ageneric personInfo = (Ageneric) PojoUtils.realize(o,
Ageneric.class);
+
+ assertEquals(Bgeneric.NAME, personInfo.getName());
+ assertTrue(personInfo.getData() instanceof Map);
+ }
+ {
+ Type[] createGenericPersonInfos =
ReflectUtils.getReturnTypes(PojoUtilsTest.class.getDeclaredMethod("createBGenericWithAgeneric",
String.class));
+ Bgeneric personInfo = (Bgeneric) PojoUtils.realize(o,
(Class)createGenericPersonInfos[0], createGenericPersonInfos[1]);
+
+ assertEquals(Bgeneric.NAME, personInfo.getName());
+ assertEquals(personInfo.getData().getClass(), Ageneric.class);
+ assertEquals(Ageneric.NAME,
((Ageneric)personInfo.getData()).getName());
+
assertEquals(((Ageneric)personInfo.getData()).getData().getClass(),
PersonInfo.class);
+ assertEquals(personName,
((PersonInfo)((Ageneric)personInfo.getData()).getData()).getName());
+ }
+ }
+ }
+
+ protected Cgeneric<PersonInfo> createCGenericPersonInfo(String name) {
+ Cgeneric<PersonInfo> ret = new Cgeneric();
+ ret.setData(createPersonInfoByName(name));
+ ret.setA(createAGenericPersonInfo(name));
+ ret.setB(createBGenericPersonInfo(name));
+ return ret;
+ }
+
+ @Test
+ public void testPojoGeneric3() throws NoSuchMethodException {
+ String personName = "testName";
+
+ Cgeneric<PersonInfo> generic = createCGenericPersonInfo(personName);
+ Object o = JSON.toJSON(generic);
+ {
+ Cgeneric personInfo = (Cgeneric) PojoUtils.realize(o,
Cgeneric.class);
+
+ assertEquals(Cgeneric.NAME, personInfo.getName());
+ assertTrue(personInfo.getData() instanceof Map);
+ assertTrue(personInfo.getA().getData() instanceof Map);
+ assertTrue(personInfo.getB().getData() instanceof PersonInfo);
+
+ }
+ {
+ Type[] createGenericPersonInfos =
ReflectUtils.getReturnTypes(PojoUtilsTest.class.getDeclaredMethod("createCGenericPersonInfo",
String.class));
+ Cgeneric personInfo = (Cgeneric) PojoUtils.realize(o,
(Class)createGenericPersonInfos[0], createGenericPersonInfos[1]);
+
+ assertEquals(Cgeneric.NAME, personInfo.getName());
+ assertEquals(personInfo.getData().getClass(), PersonInfo.class);
+ assertEquals(personName,
((PersonInfo)personInfo.getData()).getName());
+
+ assertEquals(personInfo.getA().getClass(), Ageneric.class);
+ assertEquals(personInfo.getA().getData().getClass(),
PersonInfo.class);
+ assertEquals(personInfo.getB().getClass(), Bgeneric.class);
+ assertEquals(personInfo.getB().getData().getClass(),
PersonInfo.class);
+ }
+ }
+
+ protected Dgeneric<Ageneric<PersonInfo>, Bgeneric<PersonInfo>,
Cgeneric<PersonInfo>> createDGenericPersonInfo(String name) {
+ Dgeneric<Ageneric<PersonInfo>, Bgeneric<PersonInfo>,
Cgeneric<PersonInfo>> ret = new Dgeneric();
+ ret.setT(createAGenericPersonInfo(name));
+ ret.setY(createBGenericPersonInfo(name));
+ ret.setZ(createCGenericPersonInfo(name));
+ return ret;
+ }
+
+ @Test
+ public void testPojoGeneric4() throws NoSuchMethodException {
+ String personName = "testName";
+
+ Dgeneric generic = createDGenericPersonInfo(personName);
+ Object o = JSON.toJSON(generic);
+ {
+ Dgeneric personInfo = (Dgeneric) PojoUtils.realize(o,
Dgeneric.class);
+
+ assertEquals(Dgeneric.NAME, personInfo.getName());
+ assertTrue(personInfo.getT() instanceof Map);
+ assertTrue(personInfo.getY() instanceof Map);
+ assertTrue(personInfo.getZ() instanceof Map);
+ }
+ {
+ Type[] createGenericPersonInfos =
ReflectUtils.getReturnTypes(PojoUtilsTest.class.getDeclaredMethod("createDGenericPersonInfo",
String.class));
+ Dgeneric personInfo = (Dgeneric) PojoUtils.realize(o,
(Class)createGenericPersonInfos[0], createGenericPersonInfos[1]);
+
+ assertEquals(Dgeneric.NAME, personInfo.getName());
+
+ assertEquals(personInfo.getT().getClass(), Ageneric.class);
+ assertEquals(((Ageneric)personInfo.getT()).getData().getClass(),
PersonInfo.class);
+ assertEquals(personInfo.getY().getClass(), Bgeneric.class);
+ assertEquals(((Bgeneric)personInfo.getY()).getData().getClass(),
PersonInfo.class);
+ assertEquals(personInfo.getZ().getClass(), Cgeneric.class);
+ assertEquals(((Cgeneric)personInfo.getZ()).getData().getClass(),
PersonInfo.class);
+
+ assertEquals(personInfo.getZ().getClass(), Cgeneric.class);
+ assertEquals(((Cgeneric)personInfo.getZ()).getA().getClass(),
Ageneric.class);
+
assertEquals(((Cgeneric)personInfo.getZ()).getA().getData().getClass(),
PersonInfo.class);
+ assertEquals(((Cgeneric)personInfo.getZ()).getB().getClass(),
Bgeneric.class);
+
assertEquals(((Cgeneric)personInfo.getZ()).getB().getData().getClass(),
PersonInfo.class);
+ }
+ }
+
public enum Day {
SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY
}