Added comments and fixed indentation for ModdedEnumTypeAdapter.

This commit is contained in:
Olof Larsson 2013-11-13 10:48:07 +01:00
parent c746c305a8
commit bb259374e4
2 changed files with 70 additions and 45 deletions

View File

@ -13,6 +13,33 @@ import java.io.IOException;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
/**
* This type adapter and factory handles modified Java Enums.
* It's based upon: https://github.com/MassiveCraft/mcore/blob/91f9ec7c0c7d9a11a35db905be520f5cf6b6743e/src/com/massivecraft/mcore/xlib/gson/internal/bind/TypeAdapters.java#L670
* The only change is the try-catch around the annotation code.
*
* https://github.com/MassiveCraft/mcore/pull/62
*
* # Problem
* The problem that was occurring is Forge modifies Vanilla Minecraft Enums
* (see https://github.com/MinecraftForge/MinecraftForge/blob/master/common/net/minecraftforge/common/EnumHelper.java)
* the way that it modifies the Enum is pure Java hackery modifying $VALUES on the underlying Enum.
* This will update the calls to Class.getEnumContants but won't update any fields on the Enum.
* So when the built-in Gson EnumTypeAdaper tries to see if any SerializedName annotations are on the fields of the Enum,
* it can't find a field with the new names and throws an exception.
*
* # Reasoning
* There is really not any way that we could put any fix in on the MCPC+ side since we can't add fields to Java enums at runtime.
*
* # Solution
* This ModdedEnumTypeAdapter is basically just a straight copy of the built-in one,
* but ignores when it can't find the field/annotation (which is the desired behavior in this case anyways).
* I tested this with Factions on the latest MCPC+ release and it resolves the issue that was logged.
* Hopefully this will reduce the number of people opening issues on both sides.
* If you have any questions, feel free to hit me up on IRC.
*
* @author OniBait
*/
public final class ModdedEnumTypeAdapter<T extends Enum<T>> extends TypeAdapter<T> { public final class ModdedEnumTypeAdapter<T extends Enum<T>> extends TypeAdapter<T> {
private final Map<String, T> nameToConstant = new HashMap<String, T>(); private final Map<String, T> nameToConstant = new HashMap<String, T>();
private final Map<T, String> constantToName = new HashMap<T, String>(); private final Map<T, String> constantToName = new HashMap<T, String>();
@ -20,14 +47,12 @@ public final class ModdedEnumTypeAdapter<T extends Enum<T>> extends TypeAdapter<
public ModdedEnumTypeAdapter(Class<T> classOfT) { public ModdedEnumTypeAdapter(Class<T> classOfT) {
for (T constant : classOfT.getEnumConstants()) { for (T constant : classOfT.getEnumConstants()) {
String name = constant.name(); String name = constant.name();
// Ignore when the field can't be found since modified enums won't have it try { // MCore - 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); SerializedName annotation = classOfT.getField(name).getAnnotation(SerializedName.class);
if (annotation != null) { if (annotation != null) {
name = annotation.value(); name = annotation.value();
} }
} catch (NoSuchFieldException ex) {} } catch (NoSuchFieldException ex) {} // MCore
nameToConstant.put(name, constant); nameToConstant.put(name, constant);
constantToName.put(constant, name); constantToName.put(constant, name);
} }