[gson] Update jf gson

This commit is contained in:
Johannes Frohnmeyer 2022-05-17 21:55:44 +02:00
parent d3d7989a20
commit 03a121357c
Signed by: Johannes
GPG Key ID: E76429612C2929F4
9 changed files with 159 additions and 89 deletions

View File

@ -3,12 +3,13 @@ plugins {
} }
dependencies { dependencies {
shadow implementation('io.gitlab.jfronny:gson:+') shadow implementation('io.gitlab.jfronny:gson:2.9.1-20220517.194826-5')
} }
shadowJar { shadowJar {
configurations = [ project.configurations.shadow ] configurations = [ project.configurations.shadow ]
archiveClassifier = '' archiveClassifier = ''
relocate 'com.google.gson', 'io.gitlab.jfronny.gson'
} }
publishing { publishing {

View File

@ -1,40 +1,22 @@
package io.gitlab.jfronny.commons.serialize.gson; package io.gitlab.jfronny.commons.serialize.gson;
import io.gitlab.jfronny.commons.ComparableVersion; import com.google.gson.*;
import io.gitlab.jfronny.commons.serialize.Serializer;
import io.gitlab.jfronny.commons.serialize.SerializerHolder;
import io.gitlab.jfronny.gson.*;
import java.io.Reader; import java.lang.reflect.*;
import java.lang.reflect.Modifier; import java.util.function.*;
import java.lang.reflect.Type;
import java.util.function.Consumer;
/** /**
* Holds a common instance of the Gson object. * Holds a common instance of the Gson object.
* Supports registering type adapters/etc. as needed * Supports registering type adapters/etc. as needed
*/ */
@Deprecated(forRemoval = true)
public class GsonHolder { public class GsonHolder {
private static final GsonBuilder builder = new GsonBuilder()
.registerTypeAdapter(ComparableVersion.class, new ComparableVersionAdapter())
.excludeFieldsWithModifiers(Modifier.TRANSIENT)
.excludeFieldsWithModifiers(Modifier.PRIVATE)
.setExclusionStrategies(new GsonIgnoreExclusionStrategy())
.setPrettyPrinting();
private static boolean clean = false;
private static Gson gson;
/** /**
* Get the current gson instance or build it if needed * Get the current gson instance or build it if needed
* @return The Gson instance * @return The Gson instance
*/ */
public static Gson getGson() { public static Gson getGson() {
if (!clean) { return io.gitlab.jfronny.commons.serialize.gson.api.GsonHolder.getGson();
gson = builder.create();
clean = true;
}
return gson;
} }
/** /**
@ -43,8 +25,7 @@ public class GsonHolder {
* @param typeAdapter The adapter type * @param typeAdapter The adapter type
*/ */
public static void registerTypeAdapter(Type type, Object typeAdapter) { public static void registerTypeAdapter(Type type, Object typeAdapter) {
builder.registerTypeAdapter(type, typeAdapter); io.gitlab.jfronny.commons.serialize.gson.api.GsonHolder.registerTypeAdapter(type, typeAdapter);
clean = false;
} }
/** /**
@ -52,8 +33,7 @@ public class GsonHolder {
* @param factory The factory to register * @param factory The factory to register
*/ */
public static void registerTypeAdapterFactory(TypeAdapterFactory factory) { public static void registerTypeAdapterFactory(TypeAdapterFactory factory) {
builder.registerTypeAdapterFactory(factory); io.gitlab.jfronny.commons.serialize.gson.api.GsonHolder.registerTypeAdapterFactory(factory);
clean = false;
} }
/** /**
@ -61,42 +41,13 @@ public class GsonHolder {
* @param func The function to run * @param func The function to run
*/ */
public static void modifyBuilder(Consumer<GsonBuilder> func) { public static void modifyBuilder(Consumer<GsonBuilder> func) {
func.accept(builder); io.gitlab.jfronny.commons.serialize.gson.api.GsonHolder.modifyBuilder(func);
clean = false;
} }
/** /**
* Register this in {@code SerializerHolder} * Register this in {@code SerializerHolder}
*/ */
public static void register() { public static void register() {
SerializerHolder.setInstance(new Serializer() { io.gitlab.jfronny.commons.serialize.gson.api.GsonHolder.register();
@Override
public String serialize(Object o) {
return getGson().toJson(o);
}
@Override
public <T> T deserialize(Reader source, Type typeOfT) throws SerializeException {
try {
return getGson().fromJson(source, typeOfT);
} catch (JsonIOException | JsonSyntaxException e) {
throw new SerializeException(e);
}
}
@Override
public <T> T deserialize(String source, Type typeOfT) throws SerializeException {
try {
return getGson().fromJson(source, typeOfT);
} catch (JsonIOException | JsonSyntaxException e) {
throw new SerializeException(e);
}
}
@Override
public String getFormatMime() {
return "application/json";
}
});
} }
} }

View File

@ -9,6 +9,7 @@ import java.lang.annotation.Target;
* Mark a class/field to be ignored by Gson. * Mark a class/field to be ignored by Gson.
* May be used for metadata in serialized classes * May be used for metadata in serialized classes
*/ */
@Deprecated(forRemoval = true)
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.TYPE}) @Target({ElementType.FIELD, ElementType.TYPE})
public @interface GsonIgnore { public @interface GsonIgnore {

View File

@ -1,20 +0,0 @@
package io.gitlab.jfronny.commons.serialize.gson;
import io.gitlab.jfronny.gson.ExclusionStrategy;
import io.gitlab.jfronny.gson.FieldAttributes;
/**
* An exclusion strategy that ignores fields with the GsonIgnore attribute
*/
public class GsonIgnoreExclusionStrategy implements ExclusionStrategy {
@Override
public boolean shouldSkipClass(Class<?> clazz) {
return clazz.isAnnotationPresent(GsonIgnore.class);
}
@Override
public boolean shouldSkipField(FieldAttributes f) {
return f.getAnnotation(GsonIgnore.class) != null
|| f.getDeclaringClass().isAnnotationPresent(GsonIgnore.class);
}
}

View File

@ -0,0 +1,102 @@
package io.gitlab.jfronny.commons.serialize.gson.api;
import io.gitlab.jfronny.commons.*;
import io.gitlab.jfronny.commons.serialize.*;
import io.gitlab.jfronny.commons.serialize.gson.impl.*;
import com.google.gson.*;
import java.io.*;
import java.lang.reflect.*;
import java.util.function.*;
/**
* Holds a common instance of the Gson object.
* Supports registering type adapters/etc. as needed
*/
public class GsonHolder {
private static final GsonBuilder builder = new GsonBuilder()
.registerTypeAdapter(ComparableVersion.class, new ComparableVersionAdapter())
.excludeFieldsWithModifiers(Modifier.TRANSIENT)
.excludeFieldsWithModifiers(Modifier.PRIVATE)
.setExclusionStrategies(new GsonIgnoreExclusionStrategy())
.setLenient()
.setPrettyPrinting();
private static boolean clean = false;
private static Gson gson;
/**
* Get the current gson instance or build it if needed
* @return The Gson instance
*/
public static Gson getGson() {
if (!clean) {
gson = builder.create();
clean = true;
}
return gson;
}
/**
* Register a type adapter and mark the gson instance as unclean
* @param type The type for which to register the adapter
* @param typeAdapter The adapter type
*/
public static void registerTypeAdapter(Type type, Object typeAdapter) {
builder.registerTypeAdapter(type, typeAdapter);
clean = false;
}
/**
* Register a type adapter factory and mark the gson instance as unclean
* @param factory The factory to register
*/
public static void registerTypeAdapterFactory(TypeAdapterFactory factory) {
builder.registerTypeAdapterFactory(factory);
clean = false;
}
/**
* Run a function on the builder for modifying it and mark the gson instance as unclean
* @param func The function to run
*/
public static void modifyBuilder(Consumer<GsonBuilder> func) {
func.accept(builder);
clean = false;
}
/**
* Register this in {@code SerializerHolder}
*/
public static void register() {
SerializerHolder.setInstance(new Serializer() {
@Override
public String serialize(Object o) {
return getGson().toJson(o);
}
@Override
public <T> T deserialize(Reader source, Type typeOfT) throws SerializeException {
try {
return getGson().fromJson(source, typeOfT);
} catch (JsonIOException | JsonSyntaxException e) {
throw new SerializeException(e);
}
}
@Override
public <T> T deserialize(String source, Type typeOfT) throws SerializeException {
try {
return getGson().fromJson(source, typeOfT);
} catch (JsonIOException | JsonSyntaxException e) {
throw new SerializeException(e);
}
}
@Override
public String getFormatMime() {
return "application/json";
}
});
}
}

View File

@ -0,0 +1,12 @@
package io.gitlab.jfronny.commons.serialize.gson.api;
import java.lang.annotation.*;
/**
* Mark a class/field to be ignored by Gson.
* May be used for metadata in serialized classes
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.TYPE})
public @interface Ignore {
}

View File

@ -1,7 +1,7 @@
package io.gitlab.jfronny.commons.serialize.gson; package io.gitlab.jfronny.commons.serialize.gson.impl;
import io.gitlab.jfronny.commons.ComparableVersion; import io.gitlab.jfronny.commons.ComparableVersion;
import io.gitlab.jfronny.gson.*; import com.google.gson.*;
import java.lang.reflect.Type; import java.lang.reflect.Type;

View File

@ -0,0 +1,25 @@
package io.gitlab.jfronny.commons.serialize.gson.impl;
import io.gitlab.jfronny.commons.serialize.gson.*;
import io.gitlab.jfronny.commons.serialize.gson.api.*;
import com.google.gson.ExclusionStrategy;
import com.google.gson.FieldAttributes;
/**
* An exclusion strategy that ignores fields with the GsonIgnore attribute
*/
public class GsonIgnoreExclusionStrategy implements ExclusionStrategy {
@Override
public boolean shouldSkipClass(Class<?> clazz) {
return clazz.isAnnotationPresent(GsonIgnore.class)
|| clazz.isAnnotationPresent(Ignore.class);
}
@Override
public boolean shouldSkipField(FieldAttributes f) {
return f.getAnnotation(GsonIgnore.class) != null
|| f.getDeclaringClass().isAnnotationPresent(GsonIgnore.class)
|| f.getAnnotation(Ignore.class) != null
|| f.getDeclaringClass().isAnnotationPresent(Ignore.class);
}
}

View File

@ -1,11 +1,9 @@
package io.gitlab.jfronny.commons.test; package io.gitlab.jfronny.commons.test;
import io.gitlab.jfronny.commons.ComparableVersion; import io.gitlab.jfronny.commons.*;
import io.gitlab.jfronny.commons.serialize.SerializerHolder; import io.gitlab.jfronny.commons.serialize.*;
import io.gitlab.jfronny.commons.serialize.gson.GsonHolder; import io.gitlab.jfronny.commons.serialize.gson.api.*;
import io.gitlab.jfronny.commons.serialize.gson.GsonIgnore; import org.junit.jupiter.api.*;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
@ -40,14 +38,14 @@ public class GsonTest {
public static class ExampleType { public static class ExampleType {
String id = "Yes"; String id = "Yes";
@GsonIgnore @Ignore
String other = "No"; String other = "No";
Integer one = 1; Integer one = 1;
ExampleTypeHidden type = new ExampleTypeHidden(); ExampleTypeHidden type = new ExampleTypeHidden();
TransitiveHiddenType shown = new TransitiveHiddenType(); TransitiveHiddenType shown = new TransitiveHiddenType();
} }
@GsonIgnore @Ignore
public static class ExampleTypeHidden { public static class ExampleTypeHidden {
String someMetadata = "No"; String someMetadata = "No";
} }