From 5444deeeb52d415ca320ccfddd34dd2e9ac217de Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Tue, 8 Sep 2015 14:13:57 +0200 Subject: Add Json.java --- pom.xml | 6 ++ src/main/java/org/openslx/util/Json.java | 122 +++++++++++++++++++++++++++++++ 2 files changed, 128 insertions(+) create mode 100644 src/main/java/org/openslx/util/Json.java diff --git a/pom.xml b/pom.xml index a097104..5f10585 100644 --- a/pom.xml +++ b/pom.xml @@ -121,6 +121,12 @@ 0.0.3-SNAPSHOT compile + + com.google.code.gson + gson + 2.2.4 + compile + diff --git a/src/main/java/org/openslx/util/Json.java b/src/main/java/org/openslx/util/Json.java new file mode 100644 index 0000000..847514d --- /dev/null +++ b/src/main/java/org/openslx/util/Json.java @@ -0,0 +1,122 @@ +package org.openslx.util; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.lang.reflect.Type; + +import org.apache.log4j.Logger; +import org.apache.thrift.TBase; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; +import com.google.gson.JsonSyntaxException; + +public class Json { + + private static final Logger LOGGER = Logger.getLogger(Json.class); + + /** + * Global static instance. The Gson object is thread-safe. + */ + private static final Gson gson = new Gson(); + + private static final GsonBuilder gsonThriftBuilder = new GsonBuilder(); + + public static void registerThriftClass(Class thriftClass) { + if (!TBase.class.isAssignableFrom(thriftClass)) + throw new IllegalArgumentException(thriftClass.getName() + " is not a thrift struct."); + gsonThriftBuilder.registerTypeAdapter(thriftClass, new ThriftDeserializer(thriftClass)); + } + + /** + * Deserialize the given json string to an instance of T. + * This will deserialize all fields, except transient ones. + * + * @param data JSON formatted data + * @param classOfData class to instantiate + * @return instanceof T + */ + public static T deserialize(String data, Class classOfData) { + try { + return gson.fromJson(data, classOfData); + } catch (JsonSyntaxException e) { + LOGGER.warn("Cannot deserialize to " + classOfData.getSimpleName(), e); + return null; + } + } + + public static T deserializeThrift(String data, Class thriftClass) { + try { + return gsonThriftBuilder.create().fromJson(data, thriftClass); + } catch (JsonSyntaxException e) { + LOGGER.warn("Cannot deserialize to " + thriftClass.getSimpleName(), e); + return null; + } + } + + /** + * Serialize the given POJO. All fields except transient ones will be + * serialized. + * + * @param object some object to serialize + * @return JSON formatted represenatation of object + */ + public static String serialize(Object object) { + return gson.toJson(object); + } + + private static class ThriftDeserializer implements JsonDeserializer { + private final Class clazz; + + public ThriftDeserializer(Class classOfData) { + this.clazz = classOfData; + } + + @Override + public T deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) + throws JsonParseException { + if (!(json instanceof JsonObject)) + throw new JsonParseException("Need a json object, have " + json.getClass().getSimpleName()); + JsonObject obj = (JsonObject) json; + final T inst; + try { + inst = clazz.newInstance(); + } catch (InstantiationException | IllegalAccessException e) { + LOGGER.warn("Could not deserialize to class " + clazz.getName(), e); + throw new JsonParseException("Cannot instantiate class " + clazz.getSimpleName()); + } + for (Field field : clazz.getFields()) { + if (Modifier.isStatic(field.getModifiers()) || Modifier.isFinal(field.getModifiers())) + continue; + final String methodName = "set" + field.getName().substring(0, 1).toUpperCase() + + field.getName().substring(1); + final Method setter; + try { + setter = clazz.getMethod(methodName, field.getType()); + } catch (NoSuchMethodException e) { + LOGGER.warn(clazz.getSimpleName() + " has no method " + methodName); + continue; + } + JsonElement element = obj.get(field.getName()); + if (element == null || element.isJsonNull()) + continue; + try { + setter.invoke(inst, context.deserialize(element, field.getType())); + LOGGER.info("Called " + methodName + " on " + clazz.getSimpleName()); + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + LOGGER.warn("Could not call " + methodName + " on " + clazz.getSimpleName(), e); + } + } + return inst; + } + + } + +} -- cgit v1.2.3-55-g7522