package com.pahimar.ee3.util.serialize; import com.google.gson.*; import com.pahimar.ee3.api.exchange.EnergyValue; import com.pahimar.ee3.exchange.OreStack; import com.pahimar.ee3.exchange.WrappedStack; import net.minecraft.item.ItemStack; import net.minecraftforge.fluids.FluidStack; import java.lang.reflect.Type; import java.util.Iterator; import java.util.Map; import java.util.TreeMap; public class EnergyValueMapSerializer implements JsonSerializer>, JsonDeserializer> { private static final String ENERGY_VALUE = "energyValue"; private static final String TYPE_ITEM_STACK = "itemstack"; private static final String TYPE_ORE_STACK = "orestack"; private static final String TYPE_FLUID_STACK = "fluidstack"; @Override public Map deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { Map valueMap = new TreeMap<>(); if (json.isJsonArray()) { JsonArray jsonArray = json.getAsJsonArray(); Iterator jsonArrayIterator = jsonArray.iterator(); while (jsonArrayIterator.hasNext()) { JsonElement jsonElement = jsonArrayIterator.next(); if (validateValueMapping(jsonElement)) { JsonObject jsonValueMapping = jsonElement.getAsJsonObject(); WrappedStack wrappedStack = null; EnergyValue energyValue = null; if (jsonValueMapping.get(ENERGY_VALUE).isJsonPrimitive()) { if (jsonValueMapping.getAsJsonPrimitive(ENERGY_VALUE).isNumber()) { try { energyValue = new EnergyValue(jsonValueMapping.getAsJsonPrimitive(ENERGY_VALUE).getAsNumber()); } catch (NumberFormatException e) { // TODO Logging } } } if (jsonValueMapping.has(TYPE_ITEM_STACK)) { try { ItemStack itemStack = context.deserialize(jsonValueMapping.get(TYPE_ITEM_STACK), ItemStack.class); wrappedStack = WrappedStack.wrap(itemStack); } catch (JsonParseException e) { // TODO Logging } } else if (jsonValueMapping.has(TYPE_ORE_STACK)) { try { OreStack oreStack = context.deserialize(jsonValueMapping.get(TYPE_ORE_STACK), OreStack.class); wrappedStack = WrappedStack.wrap(oreStack); } catch (JsonParseException e) { // TODO Logging } } else if (jsonValueMapping.has(TYPE_FLUID_STACK)) { try { FluidStack fluidStack = context.deserialize(jsonValueMapping.get(TYPE_FLUID_STACK), FluidStack.class); wrappedStack = WrappedStack.wrap(fluidStack); } catch (JsonParseException e) { // TODO Logging } } if (wrappedStack != null && energyValue != null) { valueMap.put(wrappedStack, energyValue); } } } } return valueMap; } @Override public JsonElement serialize(Map src, Type typeOfSrc, JsonSerializationContext context) { JsonArray jsonArray = new JsonArray(); if (src != null) { src.keySet().stream() .filter(wrappedStack -> wrappedStack != null && wrappedStack.getWrappedObject() != null) .forEach(wrappedStack -> { JsonObject jsonMapping = new JsonObject(); JsonElement jsonElement = context.serialize(wrappedStack.getWrappedObject()); if (jsonElement.isJsonObject()) { jsonMapping.add(wrappedStack.getWrappedObject().getClass().getSimpleName().toLowerCase(), context.serialize(wrappedStack.getWrappedObject())); if (src.get(wrappedStack) != null) { jsonMapping.addProperty(ENERGY_VALUE, src.get(wrappedStack).getValue()); } else { jsonMapping.add(ENERGY_VALUE, JsonNull.INSTANCE); } jsonArray.add(jsonMapping); } }); } return jsonArray; } /*** * Validates whether or not the provided {@link JsonElement} is a valid json encoded {@link WrappedStack}:{@link EnergyValue} mapping * * @param jsonElement the {@link JsonElement} being validated * @return true if jsonElement is a valid json encoded {@link WrappedStack}:{@link EnergyValue} mapping, false otherwise */ private static boolean validateValueMapping(JsonElement jsonElement) { if (jsonElement.isJsonObject()) { JsonObject jsonObject = jsonElement.getAsJsonObject(); if (jsonObject.entrySet().size() == 2 && jsonObject.has(ENERGY_VALUE) && jsonObject.get(ENERGY_VALUE).isJsonPrimitive()) { return (jsonObject.has(TYPE_ITEM_STACK) && jsonObject.get(TYPE_ITEM_STACK).isJsonObject()) || (jsonObject.has(TYPE_ORE_STACK) && jsonObject.get(TYPE_ORE_STACK).isJsonObject()) || (jsonObject.has(TYPE_FLUID_STACK) && jsonObject.get(TYPE_FLUID_STACK).isJsonObject()); } } return false; } }