Skip to content

Commit c5dd96d

Browse files
committed
Make sure the tests using "unmarshalResource" are checking if the model class is Serializable
1 parent 70cb8d3 commit c5dd96d

File tree

1 file changed

+85
-2
lines changed

1 file changed

+85
-2
lines changed

src/test/java/org/gitlab4j/api/JsonUtils.java

+85-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,24 @@
11
package org.gitlab4j.api;
22

3+
import static org.junit.jupiter.api.Assertions.fail;
4+
35
import java.io.BufferedReader;
46
import java.io.IOException;
57
import java.io.InputStreamReader;
68
import java.io.Reader;
9+
import java.io.Serializable;
10+
import java.lang.reflect.Field;
11+
import java.lang.reflect.Modifier;
12+
import java.lang.reflect.ParameterizedType;
13+
import java.lang.reflect.Type;
14+
import java.util.Collection;
15+
import java.util.HashSet;
716
import java.util.List;
817
import java.util.Map;
18+
import java.util.Set;
919

1020
import org.gitlab4j.api.utils.JacksonJson;
21+
import org.junit.jupiter.api.Assertions;
1122

1223
import com.fasterxml.jackson.core.JsonParseException;
1324
import com.fasterxml.jackson.core.JsonProcessingException;
@@ -26,7 +37,7 @@ public class JsonUtils {
2637
}
2738

2839
static JsonNode readTreeFromMap(Map<String, Object> map) throws JsonParseException, JsonMappingException, IOException {
29-
String jsonString = jacksonJson.getObjectMapper().writeValueAsString(map);
40+
String jsonString = jacksonJson.getObjectMapper().writeValueAsString(map);
3041
return (jacksonJson.readTree(jsonString));
3142
}
3243

@@ -40,48 +51,120 @@ static JsonNode readTreeFromResource(String filename) throws JsonParseException,
4051
}
4152

4253
static <T> T unmarshalResource(Class<T> returnType, String filename) throws JsonParseException, JsonMappingException, IOException {
54+
checkSerializable(returnType);
4355
InputStreamReader reader = new InputStreamReader(TestGitLabApiBeans.class.getResourceAsStream(filename));
4456
return (jacksonJson.unmarshal(returnType, reader));
4557
}
4658

47-
static <T> List<T> unmarshalResourceList(Class<T> returnType, String filename) throws JsonParseException, JsonMappingException, IOException {
59+
static <T> List<T> unmarshalResourceList(Class<T> returnType, String filename) throws JsonParseException, JsonMappingException, IOException {
60+
checkSerializable(returnType);
4861
InputStreamReader reader = new InputStreamReader(TestGitLabApiBeans.class.getResourceAsStream(filename));
4962
return (JsonUtils.unmarshalList(returnType, reader));
5063
}
5164

5265
static <T> Map<String, T> unmarshalResourceMap(Class<T> returnType, String filename) throws JsonParseException, JsonMappingException, IOException {
66+
checkSerializable(returnType);
5367
InputStreamReader reader = new InputStreamReader(TestGitLabApiBeans.class.getResourceAsStream(filename));
5468
return (jacksonJson.unmarshalMap(returnType, reader));
5569
}
5670

5771
static <T> T unmarshal(Class<T> returnType, Reader reader) throws JsonParseException, JsonMappingException, IOException {
72+
checkSerializable(returnType);
5873
return (jacksonJson.unmarshal(returnType, reader));
5974
}
6075

6176
static <T> T unmarshal(Class<T> returnType, JsonNode tree) throws JsonParseException, JsonMappingException, IOException {
77+
checkSerializable(returnType);
6278
return (jacksonJson.unmarshal(returnType, tree));
6379
}
6480

6581
static <T> T unmarshal(Class<T> returnType, String json) throws JsonParseException, JsonMappingException, IOException {
82+
checkSerializable(returnType);
6683
return (jacksonJson.unmarshal(returnType, json));
6784
}
6885

6986
static <T> List<T> unmarshalList(Class<T> returnType, Reader reader) throws JsonParseException, JsonMappingException, IOException {
87+
checkSerializable(returnType);
7088
return (jacksonJson.unmarshalList(returnType, reader));
7189
}
7290

7391
static <T> List<T> unmarshalList(Class<T> returnType, String json) throws JsonParseException, JsonMappingException, IOException {
92+
checkSerializable(returnType);
7493
return (jacksonJson.unmarshalList(returnType, json));
7594
}
7695

7796
static <T> Map<String, T> unmarshalMap(Class<T> returnType, Reader reader) throws JsonParseException, JsonMappingException, IOException {
97+
checkSerializable(returnType);
7898
return (jacksonJson.unmarshalMap(returnType, reader));
7999
}
80100

81101
static <T> Map<String, T> unmarshalMap(Class<T> returnType, String json) throws JsonParseException, JsonMappingException, IOException {
102+
checkSerializable(returnType);
82103
return (jacksonJson.unmarshalMap(returnType, json));
83104
}
84105

106+
static <T> void checkSerializable(Class<T> cls) {
107+
if(!isSerializable(cls, new HashSet<>())) {
108+
fail("Class " + cls.getCanonicalName() + " or one of its member does not implement Serializable");
109+
}
110+
}
111+
static <T> boolean isSerializable(Class<T> cls, Set<Class<?>> checkedTypes) {
112+
if (checkedTypes.contains(cls)) {
113+
return true;
114+
}
115+
checkedTypes.add(cls);
116+
117+
if (!Serializable.class.isAssignableFrom(cls)) {
118+
return false;
119+
}
120+
121+
Field[] fields = cls.getDeclaredFields();
122+
for (Field field : fields) {
123+
if (!Modifier.isStatic(field.getModifiers()) && !Modifier.isTransient(field.getModifiers())) {
124+
Class<?> fieldClass = field.getType();
125+
if (!isSimpleType(fieldClass) && !isSerializable(fieldClass, checkedTypes) && !isCollectionSerializable(field, checkedTypes)) {
126+
return false;
127+
}
128+
}
129+
}
130+
return true;
131+
}
132+
133+
private static boolean isSimpleType(Class<?> type) {
134+
return type.isPrimitive() ||
135+
type.equals(String.class) ||
136+
type.equals(Integer.class) ||
137+
type.equals(Long.class) ||
138+
type.equals(Double.class) ||
139+
type.equals(Float.class) ||
140+
type.equals(Boolean.class) ||
141+
type.equals(Character.class) ||
142+
type.equals(Byte.class) ||
143+
type.equals(Short.class);
144+
}
145+
146+
private static boolean isCollectionSerializable(Field field, Set<Class<?>> checkedTypes) {
147+
Class<?> fieldType = field.getType();
148+
if (Collection.class.isAssignableFrom(fieldType) || Map.class.isAssignableFrom(fieldType)) {
149+
Type genericType = field.getGenericType();
150+
151+
if (genericType instanceof ParameterizedType) {
152+
ParameterizedType parameterizedType = (ParameterizedType) genericType;
153+
Type[] typeArguments = parameterizedType.getActualTypeArguments();
154+
155+
for (Type typeArg : typeArguments) {
156+
if (typeArg instanceof Class) {
157+
Class<?> typeClass = (Class<?>) typeArg;
158+
if (!isSimpleType(typeClass) && !isSerializable(typeClass, checkedTypes)) {
159+
return false;
160+
}
161+
}
162+
}
163+
}
164+
}
165+
return true;
166+
}
167+
85168
static <T> boolean compareJson(T apiObject, String filename) throws IOException {
86169
InputStreamReader reader = new InputStreamReader(TestGitLabApiBeans.class.getResourceAsStream(filename));
87170
return (compareJson(apiObject, reader));

0 commit comments

Comments
 (0)