From ee2c51f60a95d4f37e8c561165083962e0b2e127 Mon Sep 17 00:00:00 2001 From: OniBait Date: Wed, 13 Nov 2013 01:40:01 -0600 Subject: [PATCH] Add gson type factory adapter to handled modded enums --- src/com/massivecraft/mcore/MCore.java | 4 +- .../mcore/adapter/ModdedEnumTypeAdapter.java | 64 +++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 src/com/massivecraft/mcore/adapter/ModdedEnumTypeAdapter.java diff --git a/src/com/massivecraft/mcore/MCore.java b/src/com/massivecraft/mcore/MCore.java index 73fbd285..89eca6b8 100644 --- a/src/com/massivecraft/mcore/MCore.java +++ b/src/com/massivecraft/mcore/MCore.java @@ -16,6 +16,7 @@ import org.bukkit.inventory.PlayerInventory; import com.massivecraft.mcore.adapter.InventoryAdapter; import com.massivecraft.mcore.adapter.ItemStackAdapter; import com.massivecraft.mcore.adapter.JsonElementAdapter; +import com.massivecraft.mcore.adapter.ModdedEnumTypeAdapter; import com.massivecraft.mcore.adapter.ObjectIdAdapter; import com.massivecraft.mcore.adapter.PlayerInventoryAdapter; import com.massivecraft.mcore.adapter.UUIDAdapter; @@ -82,7 +83,8 @@ public class MCore extends MPlugin .registerTypeAdapter(ItemStack.class, ItemStackAdapter.get()) .registerTypeAdapter(Inventory.class, InventoryAdapter.get()) .registerTypeAdapter(PlayerInventory.class, PlayerInventoryAdapter.get()) - .registerTypeAdapter(PS.class, PSAdapter.get()); + .registerTypeAdapter(PS.class, PSAdapter.get()) + .registerTypeAdapterFactory(ModdedEnumTypeAdapter.ENUM_FACTORY); } public static String getServerId() { return ConfServer.serverid; } diff --git a/src/com/massivecraft/mcore/adapter/ModdedEnumTypeAdapter.java b/src/com/massivecraft/mcore/adapter/ModdedEnumTypeAdapter.java new file mode 100644 index 00000000..f26b569e --- /dev/null +++ b/src/com/massivecraft/mcore/adapter/ModdedEnumTypeAdapter.java @@ -0,0 +1,64 @@ +package com.massivecraft.mcore.adapter; + +import com.massivecraft.mcore.xlib.gson.Gson; +import com.massivecraft.mcore.xlib.gson.TypeAdapter; +import com.massivecraft.mcore.xlib.gson.TypeAdapterFactory; +import com.massivecraft.mcore.xlib.gson.annotations.SerializedName; +import com.massivecraft.mcore.xlib.gson.reflect.TypeToken; +import com.massivecraft.mcore.xlib.gson.stream.JsonReader; +import com.massivecraft.mcore.xlib.gson.stream.JsonToken; +import com.massivecraft.mcore.xlib.gson.stream.JsonWriter; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +public final class ModdedEnumTypeAdapter> extends TypeAdapter { + private final Map nameToConstant = new HashMap(); + private final Map constantToName = new HashMap(); + + public ModdedEnumTypeAdapter(Class classOfT) { + for (T constant : classOfT.getEnumConstants()) { + String name = constant.name(); + // Ignore when the field can't be found since modified enums won't have it + // which is fine, since it wouldn't have an annotation anyway (how could it?) + try { + SerializedName annotation = classOfT.getField(name).getAnnotation(SerializedName.class); + if (annotation != null) { + name = annotation.value(); + } + } catch (NoSuchFieldException ex) {} + nameToConstant.put(name, constant); + constantToName.put(constant, name); + } + } + public T read(JsonReader in) throws IOException { + if (in.peek() == JsonToken.NULL) { + in.nextNull(); + return null; + } + return nameToConstant.get(in.nextString()); + } + + public void write(JsonWriter out, T value) throws IOException { + out.value(value == null ? null : constantToName.get(value)); + } + + public static final TypeAdapterFactory ENUM_FACTORY = newEnumTypeHierarchyFactory(); + + public static TypeAdapterFactory newEnumTypeHierarchyFactory() { + return new TypeAdapterFactory() { + @SuppressWarnings({"rawtypes", "unchecked"}) + public TypeAdapter create(Gson gson, TypeToken typeToken) { + Class rawType = typeToken.getRawType(); + if (!Enum.class.isAssignableFrom(rawType) || rawType == Enum.class) { + return null; + } + if (!rawType.isEnum()) { + rawType = rawType.getSuperclass(); // handle anonymous subclasses + } + return (TypeAdapter) new ModdedEnumTypeAdapter(rawType); + } + }; + } +} \ No newline at end of file