Unverified Commit ad6d8d4f authored by nilchina's avatar nilchina Committed by GitHub
Browse files

Add implements Serializable to all model classes to support native image (GraalVM) (#1074)



---------

Co-authored-by: default avatarJeremie Bresson <jeremie.bresson@unblu.com>
parent f7441c79
...@@ -2,7 +2,10 @@ package org.gitlab4j.api.models; ...@@ -2,7 +2,10 @@ package org.gitlab4j.api.models;
import org.gitlab4j.api.utils.JacksonJson; import org.gitlab4j.api.utils.JacksonJson;
public class TaskCompletionStatus { import java.io.Serializable;
public class TaskCompletionStatus implements Serializable {
private static final long serialVersionUID = 1L;
private Integer count; private Integer count;
private Integer completedCount; private Integer completedCount;
......
...@@ -2,7 +2,10 @@ package org.gitlab4j.api.models; ...@@ -2,7 +2,10 @@ package org.gitlab4j.api.models;
import org.gitlab4j.api.utils.JacksonJson; import org.gitlab4j.api.utils.JacksonJson;
public class TimeStats { import java.io.Serializable;
public class TimeStats implements Serializable {
private static final long serialVersionUID = 1L;
private Integer timeEstimate; private Integer timeEstimate;
private Integer totalTimeSpent; private Integer totalTimeSpent;
......
package org.gitlab4j.api.models; package org.gitlab4j.api.models;
import java.io.IOException;
import java.util.Date;
import org.gitlab4j.api.Constants.TodoAction;
import org.gitlab4j.api.Constants.TodoState;
import org.gitlab4j.api.Constants.TodoType;
import org.gitlab4j.api.utils.JacksonJson;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
...@@ -16,8 +8,17 @@ import com.fasterxml.jackson.databind.JsonDeserializer; ...@@ -16,8 +8,17 @@ import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.ObjectNode;
import org.gitlab4j.api.Constants.TodoAction;
import org.gitlab4j.api.Constants.TodoState;
import org.gitlab4j.api.Constants.TodoType;
import org.gitlab4j.api.utils.JacksonJson;
import java.io.IOException;
import java.io.Serializable;
import java.util.Date;
public class Todo { public class Todo implements Serializable {
private static final long serialVersionUID = 1L;
private Long id; private Long id;
private Project project; private Project project;
......
...@@ -2,7 +2,10 @@ package org.gitlab4j.api.models; ...@@ -2,7 +2,10 @@ package org.gitlab4j.api.models;
import org.gitlab4j.api.utils.JacksonJson; import org.gitlab4j.api.utils.JacksonJson;
public class Topic { import java.io.Serializable;
public class Topic implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id; private Integer id;
......
...@@ -4,6 +4,7 @@ import org.gitlab4j.api.GitLabApiForm; ...@@ -4,6 +4,7 @@ import org.gitlab4j.api.GitLabApiForm;
import org.gitlab4j.api.TopicsApi; import org.gitlab4j.api.TopicsApi;
import java.io.File; import java.io.File;
import java.io.Serializable;
/** /**
* This class is utilized by the {@link TopicsApi#createTopic(TopicParams)} * This class is utilized by the {@link TopicsApi#createTopic(TopicParams)}
...@@ -12,7 +13,8 @@ import java.io.File; ...@@ -12,7 +13,8 @@ import java.io.File;
* *
* Avatar Upload has its own Upload in {@link TopicsApi#updateTopicAvatar(Integer,File)} * Avatar Upload has its own Upload in {@link TopicsApi#updateTopicAvatar(Integer,File)}
*/ */
public class TopicParams { public class TopicParams implements Serializable {
private static final long serialVersionUID = 1L;
private String name; private String name;
private String title; private String title;
......
...@@ -2,7 +2,10 @@ package org.gitlab4j.api.models; ...@@ -2,7 +2,10 @@ package org.gitlab4j.api.models;
import org.gitlab4j.api.utils.JacksonJson; import org.gitlab4j.api.utils.JacksonJson;
public class TreeItem { import java.io.Serializable;
public class TreeItem implements Serializable {
private static final long serialVersionUID = 1L;
public enum Type { public enum Type {
TREE, BLOB, COMMIT; TREE, BLOB, COMMIT;
......
package org.gitlab4j.api.models; package org.gitlab4j.api.models;
import java.io.Serializable;
import java.util.Date; import java.util.Date;
public class Trigger { public class Trigger implements Serializable {
private static final long serialVersionUID = 1L;
private Long id; private Long id;
private String description; private String description;
......
package org.gitlab4j.api.models; package org.gitlab4j.api.models;
import org.gitlab4j.api.utils.JacksonJson;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import org.gitlab4j.api.utils.JacksonJson;
public class User extends AbstractUser<User> { public class User extends AbstractUser<User> {
private static final long serialVersionUID = 1L;
private String bio; private String bio;
private Boolean bot; private Boolean bot;
......
package org.gitlab4j.api.models; package org.gitlab4j.api.models;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.gitlab4j.api.utils.JacksonJson;
import org.gitlab4j.api.utils.JacksonJsonEnumHelper;
import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonValue; import com.fasterxml.jackson.annotation.JsonValue;
import org.gitlab4j.api.utils.JacksonJson;
import org.gitlab4j.api.utils.JacksonJsonEnumHelper;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class Variable { public class Variable implements Serializable {
private static final long serialVersionUID = 1L;
/** /**
* Enum for the various Commit build status values. * Enum for the various Commit build status values.
......
...@@ -2,7 +2,10 @@ package org.gitlab4j.api.models; ...@@ -2,7 +2,10 @@ package org.gitlab4j.api.models;
import org.gitlab4j.api.utils.JacksonJson; import org.gitlab4j.api.utils.JacksonJson;
public class Version { import java.io.Serializable;
public class Version implements Serializable {
private static final long serialVersionUID = 1L;
private String version; private String version;
private String revision; private String revision;
......
...@@ -2,9 +2,13 @@ package org.gitlab4j.api.models; ...@@ -2,9 +2,13 @@ package org.gitlab4j.api.models;
import org.gitlab4j.api.utils.JacksonJson; import org.gitlab4j.api.utils.JacksonJson;
public class WikiAttachment { import java.io.Serializable;
public static class Link { public class WikiAttachment implements Serializable {
private static final long serialVersionUID = 1L;
public static class Link implements Serializable {
private static final long serialVersionUID = 1L;
private String url; private String url;
private String markdown; private String markdown;
...@@ -12,15 +16,15 @@ public class WikiAttachment { ...@@ -12,15 +16,15 @@ public class WikiAttachment {
public String getUrl() { public String getUrl() {
return url; return url;
} }
public void setUrl(String url) { public void setUrl(String url) {
this.url = url; this.url = url;
} }
public String getMarkdown() { public String getMarkdown() {
return markdown; return markdown;
} }
public void setMarkdown(String markdown) { public void setMarkdown(String markdown) {
this.markdown = markdown; this.markdown = markdown;
} }
......
...@@ -25,7 +25,10 @@ package org.gitlab4j.api.models; ...@@ -25,7 +25,10 @@ package org.gitlab4j.api.models;
import org.gitlab4j.api.utils.JacksonJson; import org.gitlab4j.api.utils.JacksonJson;
public class WikiPage { import java.io.Serializable;
public class WikiPage implements Serializable {
private static final long serialVersionUID = 1L;
private String title; private String title;
private String content; private String content;
......
package org.gitlab4j.api.services; package org.gitlab4j.api.services;
import java.io.Serializable;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
...@@ -9,7 +10,8 @@ import org.gitlab4j.api.utils.JacksonJson; ...@@ -9,7 +10,8 @@ import org.gitlab4j.api.utils.JacksonJson;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
public abstract class NotificationService { public abstract class NotificationService implements Serializable{
private static final long serialVersionUID = 1L;
public static final String NOTIFY_ONLY_BROKEN_PIPELINES_PROP = "notify_only_broken_pipelines"; public static final String NOTIFY_ONLY_BROKEN_PIPELINES_PROP = "notify_only_broken_pipelines";
public static final String NOTIFY_ONLY_DEFAULT_BRANCH_PROP = "notify_only_default_branch"; public static final String NOTIFY_ONLY_DEFAULT_BRANCH_PROP = "notify_only_default_branch";
......
...@@ -5,7 +5,8 @@ import org.gitlab4j.api.GitLabApiForm; ...@@ -5,7 +5,8 @@ import org.gitlab4j.api.GitLabApiForm;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
public class SlackService extends NotificationService { public class SlackService extends NotificationService {
private static final long serialVersionUID = 1L;
private String defaultChannel; private String defaultChannel;
/** /**
......
package org.gitlab4j.api.webhook; package org.gitlab4j.api.webhook;
import java.io.Serializable;
import java.util.List; import java.util.List;
import org.gitlab4j.api.models.Assignee; import org.gitlab4j.api.models.Assignee;
...@@ -7,7 +8,8 @@ import org.gitlab4j.api.models.User; ...@@ -7,7 +8,8 @@ import org.gitlab4j.api.models.User;
import org.gitlab4j.api.utils.JacksonJson; import org.gitlab4j.api.utils.JacksonJson;
import org.gitlab4j.api.webhook.MergeRequestEvent.ObjectAttributes; import org.gitlab4j.api.webhook.MergeRequestEvent.ObjectAttributes;
public class ExternalStatusCheckEvent { public class ExternalStatusCheckEvent implements Serializable {
private static final long serialVersionUID = 1L;
private String objectKind; private String objectKind;
private String eventType; private String eventType;
......
package org.gitlab4j.api; package org.gitlab4j.api;
import static org.junit.jupiter.api.Assertions.fail;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.IOException; import java.io.IOException;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.Reader; import java.io.Reader;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import org.gitlab4j.api.utils.JacksonJson; import org.gitlab4j.api.utils.JacksonJson;
import org.junit.jupiter.api.Assertions;
import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
...@@ -26,7 +37,7 @@ public class JsonUtils { ...@@ -26,7 +37,7 @@ public class JsonUtils {
} }
static JsonNode readTreeFromMap(Map<String, Object> map) throws JsonParseException, JsonMappingException, IOException { static JsonNode readTreeFromMap(Map<String, Object> map) throws JsonParseException, JsonMappingException, IOException {
String jsonString = jacksonJson.getObjectMapper().writeValueAsString(map); String jsonString = jacksonJson.getObjectMapper().writeValueAsString(map);
return (jacksonJson.readTree(jsonString)); return (jacksonJson.readTree(jsonString));
} }
...@@ -40,48 +51,120 @@ public class JsonUtils { ...@@ -40,48 +51,120 @@ public class JsonUtils {
} }
static <T> T unmarshalResource(Class<T> returnType, String filename) throws JsonParseException, JsonMappingException, IOException { static <T> T unmarshalResource(Class<T> returnType, String filename) throws JsonParseException, JsonMappingException, IOException {
checkSerializable(returnType);
InputStreamReader reader = new InputStreamReader(TestGitLabApiBeans.class.getResourceAsStream(filename)); InputStreamReader reader = new InputStreamReader(TestGitLabApiBeans.class.getResourceAsStream(filename));
return (jacksonJson.unmarshal(returnType, reader)); return (jacksonJson.unmarshal(returnType, reader));
} }
static <T> List<T> unmarshalResourceList(Class<T> returnType, String filename) throws JsonParseException, JsonMappingException, IOException { static <T> List<T> unmarshalResourceList(Class<T> returnType, String filename) throws JsonParseException, JsonMappingException, IOException {
checkSerializable(returnType);
InputStreamReader reader = new InputStreamReader(TestGitLabApiBeans.class.getResourceAsStream(filename)); InputStreamReader reader = new InputStreamReader(TestGitLabApiBeans.class.getResourceAsStream(filename));
return (JsonUtils.unmarshalList(returnType, reader)); return (JsonUtils.unmarshalList(returnType, reader));
} }
static <T> Map<String, T> unmarshalResourceMap(Class<T> returnType, String filename) throws JsonParseException, JsonMappingException, IOException { static <T> Map<String, T> unmarshalResourceMap(Class<T> returnType, String filename) throws JsonParseException, JsonMappingException, IOException {
checkSerializable(returnType);
InputStreamReader reader = new InputStreamReader(TestGitLabApiBeans.class.getResourceAsStream(filename)); InputStreamReader reader = new InputStreamReader(TestGitLabApiBeans.class.getResourceAsStream(filename));
return (jacksonJson.unmarshalMap(returnType, reader)); return (jacksonJson.unmarshalMap(returnType, reader));
} }
static <T> T unmarshal(Class<T> returnType, Reader reader) throws JsonParseException, JsonMappingException, IOException { static <T> T unmarshal(Class<T> returnType, Reader reader) throws JsonParseException, JsonMappingException, IOException {
checkSerializable(returnType);
return (jacksonJson.unmarshal(returnType, reader)); return (jacksonJson.unmarshal(returnType, reader));
} }
static <T> T unmarshal(Class<T> returnType, JsonNode tree) throws JsonParseException, JsonMappingException, IOException { static <T> T unmarshal(Class<T> returnType, JsonNode tree) throws JsonParseException, JsonMappingException, IOException {
checkSerializable(returnType);
return (jacksonJson.unmarshal(returnType, tree)); return (jacksonJson.unmarshal(returnType, tree));
} }
static <T> T unmarshal(Class<T> returnType, String json) throws JsonParseException, JsonMappingException, IOException { static <T> T unmarshal(Class<T> returnType, String json) throws JsonParseException, JsonMappingException, IOException {
checkSerializable(returnType);
return (jacksonJson.unmarshal(returnType, json)); return (jacksonJson.unmarshal(returnType, json));
} }
static <T> List<T> unmarshalList(Class<T> returnType, Reader reader) throws JsonParseException, JsonMappingException, IOException { static <T> List<T> unmarshalList(Class<T> returnType, Reader reader) throws JsonParseException, JsonMappingException, IOException {
checkSerializable(returnType);
return (jacksonJson.unmarshalList(returnType, reader)); return (jacksonJson.unmarshalList(returnType, reader));
} }
static <T> List<T> unmarshalList(Class<T> returnType, String json) throws JsonParseException, JsonMappingException, IOException { static <T> List<T> unmarshalList(Class<T> returnType, String json) throws JsonParseException, JsonMappingException, IOException {
checkSerializable(returnType);
return (jacksonJson.unmarshalList(returnType, json)); return (jacksonJson.unmarshalList(returnType, json));
} }
static <T> Map<String, T> unmarshalMap(Class<T> returnType, Reader reader) throws JsonParseException, JsonMappingException, IOException { static <T> Map<String, T> unmarshalMap(Class<T> returnType, Reader reader) throws JsonParseException, JsonMappingException, IOException {
checkSerializable(returnType);
return (jacksonJson.unmarshalMap(returnType, reader)); return (jacksonJson.unmarshalMap(returnType, reader));
} }
static <T> Map<String, T> unmarshalMap(Class<T> returnType, String json) throws JsonParseException, JsonMappingException, IOException { static <T> Map<String, T> unmarshalMap(Class<T> returnType, String json) throws JsonParseException, JsonMappingException, IOException {
checkSerializable(returnType);
return (jacksonJson.unmarshalMap(returnType, json)); return (jacksonJson.unmarshalMap(returnType, json));
} }
static <T> void checkSerializable(Class<T> cls) {
if(!isSerializable(cls, new HashSet<>())) {
fail("Class " + cls.getCanonicalName() + " or one of its member does not implement Serializable");
}
}
static <T> boolean isSerializable(Class<T> cls, Set<Class<?>> checkedTypes) {
if (checkedTypes.contains(cls)) {
return true;
}
checkedTypes.add(cls);
if (!Serializable.class.isAssignableFrom(cls)) {
return false;
}
Field[] fields = cls.getDeclaredFields();
for (Field field : fields) {
if (!Modifier.isStatic(field.getModifiers()) && !Modifier.isTransient(field.getModifiers())) {
Class<?> fieldClass = field.getType();
if (!isSimpleType(fieldClass) && !isSerializable(fieldClass, checkedTypes) && !isCollectionSerializable(field, checkedTypes)) {
return false;
}
}
}
return true;
}
private static boolean isSimpleType(Class<?> type) {
return type.isPrimitive() ||
type.equals(String.class) ||
type.equals(Integer.class) ||
type.equals(Long.class) ||
type.equals(Double.class) ||
type.equals(Float.class) ||
type.equals(Boolean.class) ||
type.equals(Character.class) ||
type.equals(Byte.class) ||
type.equals(Short.class);
}
private static boolean isCollectionSerializable(Field field, Set<Class<?>> checkedTypes) {
Class<?> fieldType = field.getType();
if (Collection.class.isAssignableFrom(fieldType) || Map.class.isAssignableFrom(fieldType)) {
Type genericType = field.getGenericType();
if (genericType instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) genericType;
Type[] typeArguments = parameterizedType.getActualTypeArguments();
for (Type typeArg : typeArguments) {
if (typeArg instanceof Class) {
Class<?> typeClass = (Class<?>) typeArg;
if (!isSimpleType(typeClass) && !isSerializable(typeClass, checkedTypes)) {
return false;
}
}
}
}
}
return true;
}
static <T> boolean compareJson(T apiObject, String filename) throws IOException { static <T> boolean compareJson(T apiObject, String filename) throws IOException {
InputStreamReader reader = new InputStreamReader(TestGitLabApiBeans.class.getResourceAsStream(filename)); InputStreamReader reader = new InputStreamReader(TestGitLabApiBeans.class.getResourceAsStream(filename));
return (compareJson(apiObject, reader)); return (compareJson(apiObject, reader));
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment