diff --git a/src/main/java/world/bentobox/bentobox/database/json/BentoboxTypeAdapterFactory.java b/src/main/java/world/bentobox/bentobox/database/json/BentoboxTypeAdapterFactory.java index 56c57f1ee..d6693a073 100644 --- a/src/main/java/world/bentobox/bentobox/database/json/BentoboxTypeAdapterFactory.java +++ b/src/main/java/world/bentobox/bentobox/database/json/BentoboxTypeAdapterFactory.java @@ -17,6 +17,7 @@ import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.api.flags.Flag; import world.bentobox.bentobox.database.json.adapters.BukkitObjectTypeAdapter; +import world.bentobox.bentobox.database.json.adapters.EnumTypeAdapter; import world.bentobox.bentobox.database.json.adapters.FlagTypeAdapter; import world.bentobox.bentobox.database.json.adapters.ItemStackTypeAdapter; import world.bentobox.bentobox.database.json.adapters.LocationTypeAdapter; @@ -44,13 +45,15 @@ public BentoboxTypeAdapterFactory(BentoBox plugin) { /* (non-Javadoc) * @see com.google.gson.TypeAdapterFactory#create(com.google.gson.Gson, com.google.gson.reflect.TypeToken) */ - @SuppressWarnings("unchecked") + @SuppressWarnings({ "unchecked", "rawtypes" }) @Override public TypeAdapter create(Gson gson, TypeToken type) { Class rawType = type.getRawType(); if (Location.class.isAssignableFrom(rawType)) { // Use our current location adapter for backward compatibility return (TypeAdapter) new LocationTypeAdapter(); + } else if (Enum.class.isAssignableFrom(rawType)) { + return new EnumTypeAdapter(rawType); } else if (ItemStack.class.isAssignableFrom(rawType)) { // Use our current location adapter for backward compatibility return (TypeAdapter) new ItemStackTypeAdapter(); diff --git a/src/main/java/world/bentobox/bentobox/database/json/adapters/EnumTypeAdapter.java b/src/main/java/world/bentobox/bentobox/database/json/adapters/EnumTypeAdapter.java new file mode 100644 index 000000000..edccf73b8 --- /dev/null +++ b/src/main/java/world/bentobox/bentobox/database/json/adapters/EnumTypeAdapter.java @@ -0,0 +1,61 @@ +package world.bentobox.bentobox.database.json.adapters; + +import java.io.IOException; +import java.util.Arrays; + +import com.google.common.collect.BiMap; +import com.google.common.collect.HashBiMap; +import com.google.gson.TypeAdapter; +import com.google.gson.annotations.SerializedName; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonToken; +import com.google.gson.stream.JsonWriter; + + +/** + * @author tastybento + * + * @param enum class to be serialized + */ +public final class EnumTypeAdapter> extends TypeAdapter { + + + /** + * Bimap to store name <-> enum references + */ + private final BiMap enumMap = HashBiMap.create(); + + + public EnumTypeAdapter(Class enumClass) { + for (T value : enumClass.getEnumConstants()) { + + String name = value.name(); + try { + SerializedName annotation = enumClass.getField(name).getAnnotation(SerializedName.class); + + if (annotation != null) { + Arrays.stream(annotation.alternate()).forEach(s -> enumMap.put(s, value)); + // Reset name + name = annotation.value(); + } + + } catch (NoSuchFieldException e) { + // Ignore + } + + enumMap.put(name, value); + } + } + + @Override public T read(JsonReader input) throws IOException { + if (JsonToken.NULL.equals(input.peek())) { + input.nextNull(); + return null; + } + return enumMap.get(input.nextString()); + } + + @Override public void write(JsonWriter output, T enumValue) throws IOException { + output.value(enumValue != null ? enumMap.inverse().get(enumValue) : null); + } +}