Added Json util file to avoid multiple identical instances of Gson object
This commit is contained in:
parent
f2bd13a18d
commit
218010e910
@ -19,10 +19,10 @@ import java.util.UUID;
|
|||||||
|
|
||||||
import com.google.common.base.MoreObjects;
|
import com.google.common.base.MoreObjects;
|
||||||
import com.google.common.base.MoreObjects.ToStringHelper;
|
import com.google.common.base.MoreObjects.ToStringHelper;
|
||||||
import com.google.gson.Gson;
|
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
|
|
||||||
import fr.pandacube.lib.core.util.EnumUtil;
|
import fr.pandacube.lib.core.util.EnumUtil;
|
||||||
|
import fr.pandacube.lib.core.util.Json;
|
||||||
import fr.pandacube.lib.core.util.Log;
|
import fr.pandacube.lib.core.util.Log;
|
||||||
|
|
||||||
public abstract class SQLElement<E extends SQLElement<E>> {
|
public abstract class SQLElement<E extends SQLElement<E>> {
|
||||||
@ -398,7 +398,7 @@ public abstract class SQLElement<E extends SQLElement<E>> {
|
|||||||
public JsonObject asJsonObject() {
|
public JsonObject asJsonObject() {
|
||||||
JsonObject json = new JsonObject();
|
JsonObject json = new JsonObject();
|
||||||
for (SQLField<E, ?> f : getFields().values()) {
|
for (SQLField<E, ?> f : getFields().values()) {
|
||||||
json.add(f.getName(), new Gson().toJsonTree(get(f)));
|
json.add(f.getName(), Json.gson.toJsonTree(get(f)));
|
||||||
}
|
}
|
||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
|
104
Core/src/main/java/fr/pandacube/lib/core/util/Json.java
Normal file
104
Core/src/main/java/fr/pandacube/lib/core/util/Json.java
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
package fr.pandacube.lib.core.util;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.RecordComponent;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
|
import com.google.gson.TypeAdapter;
|
||||||
|
import com.google.gson.TypeAdapterFactory;
|
||||||
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
import com.google.gson.stream.JsonReader;
|
||||||
|
import com.google.gson.stream.JsonToken;
|
||||||
|
import com.google.gson.stream.JsonWriter;
|
||||||
|
|
||||||
|
public class Json {
|
||||||
|
public static final Gson gson = build(b -> b);
|
||||||
|
public static final Gson gsonPrettyPrinting = build(b -> b.setPrettyPrinting());
|
||||||
|
public static final Gson gsonSerializeNulls = build(b -> b.serializeNulls());
|
||||||
|
public static final Gson gsonSerializeNullsPrettyPrinting = build(b -> b.serializeNulls().setPrettyPrinting());
|
||||||
|
|
||||||
|
|
||||||
|
private static Gson build(Function<GsonBuilder, GsonBuilder> builderModifier) {
|
||||||
|
return builderModifier
|
||||||
|
.apply(new GsonBuilder().registerTypeAdapterFactory(new RecordAdapterFactory()).setLenient()).create();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// from https://github.com/google/gson/issues/1794#issuecomment-812964421
|
||||||
|
private static class RecordAdapterFactory implements TypeAdapterFactory {
|
||||||
|
@Override
|
||||||
|
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
Class<T> clazz = (Class<T>) type.getRawType();
|
||||||
|
if (!clazz.isRecord() || clazz == Record.class) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return new RecordTypeAdapter<>(gson, this, type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class RecordTypeAdapter<T> extends TypeAdapter<T> {
|
||||||
|
private Gson gson;
|
||||||
|
private TypeAdapterFactory factory;
|
||||||
|
private TypeToken<T> type;
|
||||||
|
|
||||||
|
public RecordTypeAdapter(Gson gson, TypeAdapterFactory factory, TypeToken<T> type) {
|
||||||
|
this.gson = gson;
|
||||||
|
this.factory = factory;
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(JsonWriter out, T value) throws IOException {
|
||||||
|
gson.getDelegateAdapter(factory, type).write(out, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T read(JsonReader reader) throws IOException {
|
||||||
|
if (reader.peek() == JsonToken.NULL) {
|
||||||
|
reader.nextNull();
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
Class<T> clazz = (Class<T>) type.getRawType();
|
||||||
|
|
||||||
|
RecordComponent[] recordComponents = clazz.getRecordComponents();
|
||||||
|
Map<String, TypeToken<?>> typeMap = new HashMap<>();
|
||||||
|
for (int i = 0; i < recordComponents.length; i++) {
|
||||||
|
typeMap.put(recordComponents[i].getName(), TypeToken.get(recordComponents[i].getGenericType()));
|
||||||
|
}
|
||||||
|
var argsMap = new HashMap<String, Object>();
|
||||||
|
reader.beginObject();
|
||||||
|
while (reader.hasNext()) {
|
||||||
|
String name = reader.nextName();
|
||||||
|
argsMap.put(name, gson.getAdapter(typeMap.get(name)).read(reader));
|
||||||
|
}
|
||||||
|
reader.endObject();
|
||||||
|
|
||||||
|
var argTypes = new Class<?>[recordComponents.length];
|
||||||
|
var args = new Object[recordComponents.length];
|
||||||
|
for (int i = 0; i < recordComponents.length; i++) {
|
||||||
|
argTypes[i] = recordComponents[i].getType();
|
||||||
|
args[i] = argsMap.get(recordComponents[i].getName());
|
||||||
|
}
|
||||||
|
Constructor<T> constructor;
|
||||||
|
try {
|
||||||
|
constructor = clazz.getDeclaredConstructor(argTypes);
|
||||||
|
constructor.setAccessible(true);
|
||||||
|
return constructor.newInstance(args);
|
||||||
|
} catch (NoSuchMethodException | InstantiationException | SecurityException | IllegalAccessException
|
||||||
|
| IllegalArgumentException | InvocationTargetException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -7,14 +7,10 @@ import java.io.FileReader;
|
|||||||
import java.io.FileWriter;
|
import java.io.FileWriter;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import com.google.gson.GsonBuilder;
|
|
||||||
import com.google.gson.JsonSyntaxException;
|
import com.google.gson.JsonSyntaxException;
|
||||||
|
|
||||||
public class ServerPropertyFile {
|
public class ServerPropertyFile {
|
||||||
|
|
||||||
private static final Gson SERIALIZER = new GsonBuilder().setPrettyPrinting().create();
|
|
||||||
|
|
||||||
private transient File file;
|
private transient File file;
|
||||||
|
|
||||||
private String name = "default_name";
|
private String name = "default_name";
|
||||||
@ -39,7 +35,7 @@ public class ServerPropertyFile {
|
|||||||
public boolean loadFromFile() {
|
public boolean loadFromFile() {
|
||||||
try (BufferedReader in = new BufferedReader(new FileReader(file))) {
|
try (BufferedReader in = new BufferedReader(new FileReader(file))) {
|
||||||
|
|
||||||
ServerPropertyFile dataFile = SERIALIZER.fromJson(in, getClass());
|
ServerPropertyFile dataFile = Json.gsonPrettyPrinting.fromJson(in, getClass());
|
||||||
|
|
||||||
name = dataFile.name;
|
name = dataFile.name;
|
||||||
memory = dataFile.memory;
|
memory = dataFile.memory;
|
||||||
@ -61,7 +57,7 @@ public class ServerPropertyFile {
|
|||||||
|
|
||||||
public boolean save() {
|
public boolean save() {
|
||||||
try (BufferedWriter out = new BufferedWriter(new FileWriter(file, false))) {
|
try (BufferedWriter out = new BufferedWriter(new FileWriter(file, false))) {
|
||||||
SERIALIZER.toJson(this, out);
|
Json.gsonPrettyPrinting.toJson(this, out);
|
||||||
out.flush();
|
out.flush();
|
||||||
return true;
|
return true;
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
@ -5,7 +5,6 @@ import java.util.HashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -128,7 +127,7 @@ public class TypeConverter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (o instanceof JsonElement) {
|
if (o instanceof JsonElement) {
|
||||||
o = new Gson().fromJson((JsonElement)o, Object.class);
|
o = Json.gson.fromJson((JsonElement)o, Object.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (o instanceof Map) {
|
if (o instanceof Map) {
|
||||||
@ -175,7 +174,7 @@ public class TypeConverter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (o instanceof JsonElement) {
|
if (o instanceof JsonElement) {
|
||||||
o = new Gson().fromJson((JsonElement)o, Object.class);
|
o = Json.gson.fromJson((JsonElement)o, Object.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user