package jas.common.helper; import jas.common.helper.FileUtilities.FileReaderPlus; import jas.common.helper.FileUtilities.OptionalCloseable; import jas.spawner.modern.DefaultProps; import java.io.FileReader; import java.io.FileWriter; import java.lang.reflect.Constructor; import java.lang.reflect.Type; import com.google.common.base.Optional; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParseException; import com.google.gson.JsonPrimitive; import com.google.gson.JsonSyntaxException; public class GsonHelper { /** Custom Exception to extends JsonSyntaxException to include the FileName where the line/column is located */ public static class JsonSyntaxExceptionPlus extends JsonParseException { public JsonSyntaxExceptionPlus(String fileName, JsonSyntaxException cause) { super("Invalid JSON detected when processing file " + fileName, cause); } } public static Gson createGson(boolean prettyPrinting) { return createGson(prettyPrinting, new Type[0], new Object[0]); } public static Gson createGson(boolean prettyPrinting, Type[] types, Object[] adapters) { if (types.length != adapters.length) { throw new IllegalArgumentException("Type adapters mismatched arument length"); } GsonBuilder builder = new GsonBuilder().setVersion(DefaultProps.GSON_VERSION).disableHtmlEscaping(); if (prettyPrinting) { builder.setPrettyPrinting(); } for (int i = 0; i < adapters.length; i++) { builder.registerTypeAdapter(types[i], adapters[i]); } return builder.disableHtmlEscaping().create(); } public static <T> T readOrCreateFromGson(OptionalCloseable<FileReaderPlus> reader, Class<T> object, Gson gson, Object... creationArgs) { if (reader.isPresent()) { try { T instance = gson.fromJson(reader.get(), object); reader.close(); if (instance != null) { return instance; } } catch (JsonSyntaxException e) { throw new JsonSyntaxExceptionPlus(reader.get().file.getPath(), e); } } try { Class<?>[] classes = new Class<?>[creationArgs.length]; for (int i = 0; i < classes.length; i++) { classes[i] = creationArgs[i].getClass(); } Constructor<T> constructor = object.getDeclaredConstructor(classes); constructor.setAccessible(true); return constructor.newInstance(creationArgs); } catch (Exception e) { e.printStackTrace(); throw new IllegalArgumentException(String.format( "This should never be possible. Failed to instantiate class %s.", object)); } } public static <T> Optional<T> readFromGson(OptionalCloseable<FileReader> reader, Class<T> object, Gson gson) { if (reader.isPresent()) { T instance = gson.fromJson(reader.get(), object); reader.close(); if (instance != null) { return Optional.of(instance); } } return Optional.<T> absent(); } public static <T> Optional<T> readFromGson(OptionalCloseable<FileReader> reader, Type type, Gson gson) { if (reader.isPresent()) { T instance = gson.fromJson(reader.get(), type); reader.close(); if (instance != null) { return Optional.of(instance); } } return Optional.absent(); } public static <T> void writeToGson(OptionalCloseable<FileWriter> writer, T object, Gson gson) { if (writer.isPresent()) { gson.toJson(object, writer.get()); writer.close(); } } public static <T> void writeToGson(OptionalCloseable<FileWriter> writer, T object, Type type, Gson gson) { if (writer.isPresent()) { gson.toJson(object, type, writer.get()); writer.close(); } } /** * Helper for unwrapping JsonElements, returns empty JSON is provided element is not a JsonObject */ public static JsonObject getAsJsonObject(JsonElement element) { return getAsOrDefault(element, new JsonObject()); } /** * Helper for unwrapping JsonObject members, returns default value if element is absent or an invalid type */ public static JsonObject getAsOrDefault(JsonElement element, JsonObject defaultValue) { if (element != null && element.isJsonObject()) { return element.getAsJsonObject(); } return defaultValue; } /** * Helper for unwrapping JsonObject members, returns default value if element is absent or an invalid type */ public static int getAsOrDefault(JsonElement element, int defaultValue) { if (element != null && element.isJsonPrimitive() && element.getAsJsonPrimitive().isNumber()) { return element.getAsJsonPrimitive().getAsInt(); } return defaultValue; } /** * Helper for unwrapping JsonObject members, returns default value if element is absent or an invalid type */ public static String getAsOrDefault(JsonElement element, String defaultValue) { if (element != null && element.isJsonPrimitive() && element.getAsJsonPrimitive().isString()) { return element.getAsJsonPrimitive().getAsString(); } return defaultValue; } /** * Helper for unwrapping JsonObject members, returns default value if desired member is absent or an invalid type */ public static String getMemberOrDefault(JsonObject jsonObject, String memberName, String defaultIfAbsent) { JsonElement element = jsonObject.get(memberName); if (element != null && element.isJsonPrimitive()) { JsonPrimitive memberPrimitive = element.getAsJsonPrimitive(); if (memberPrimitive.isString()) { return memberPrimitive.getAsString(); } } return defaultIfAbsent; } /** * Helper for unwrapping JsonObject members, returns default value if desired member is absent or an invalid type */ public static int getMemberOrDefault(JsonObject jsonObject, String memberName, int defaultIfAbsent) { JsonElement element = jsonObject.get(memberName); if (element != null && element.isJsonPrimitive()) { JsonPrimitive memberPrimitive = element.getAsJsonPrimitive(); if (memberPrimitive.isNumber()) { return memberPrimitive.getAsInt(); } } return defaultIfAbsent; } /** * Helper for unwrapping JsonObject members, returns default value if desired member is absent or an invalid type */ public static float getMemberOrDefault(JsonObject jsonObject, String memberName, float defaultIfAbsent) { JsonElement element = jsonObject.get(memberName); if (element != null && element.isJsonPrimitive()) { JsonPrimitive memberPrimitive = element.getAsJsonPrimitive(); if (memberPrimitive.isNumber()) { return memberPrimitive.getAsFloat(); } } return defaultIfAbsent; } /** * Helper for unwrapping JsonObject members, returns default value if desired member is absent or an invalid type */ public static boolean getMemberOrDefault(JsonObject jsonObject, String memberName, boolean defaultIfAbsent) { JsonElement element = jsonObject.get(memberName); if (element != null && element.isJsonPrimitive()) { JsonPrimitive memberPrimitive = element.getAsJsonPrimitive(); if (memberPrimitive.isBoolean()) { return memberPrimitive.getAsBoolean(); } } return defaultIfAbsent; } /** * Helper for unwrapping JsonObject members, returns default value if desired member is absent or an invalid type */ public static JsonObject getMemberOrDefault(JsonObject jsonObject, String memberName, JsonObject defaultIfAbsent) { JsonElement element = jsonObject.get(memberName); if (element != null && element.isJsonObject()) { return element.getAsJsonObject(); } return defaultIfAbsent; } /** * Helper for unwrapping JsonObject members, returns default value if desired member is absent or an invalid type */ public static JsonArray getMemberOrDefault(JsonObject jsonObject, String memberName, JsonArray defaultIfAbsent) { JsonElement element = jsonObject.get(memberName); if (element != null && element.isJsonArray()) { return element.getAsJsonArray(); } return defaultIfAbsent; } }