summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pom.xml6
-rw-r--r--src/main/java/org/openslx/util/Json.java122
2 files changed, 128 insertions, 0 deletions
diff --git a/pom.xml b/pom.xml
index a097104..5f10585 100644
--- a/pom.xml
+++ b/pom.xml
@@ -121,6 +121,12 @@
<version>0.0.3-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
+ <dependency>
+ <groupId>com.google.code.gson</groupId>
+ <artifactId>gson</artifactId>
+ <version>2.2.4</version>
+ <scope>compile</scope>
+ </dependency>
</dependencies>
</project>
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 <T> void registerThriftClass(Class<T> thriftClass) {
+ if (!TBase.class.isAssignableFrom(thriftClass))
+ throw new IllegalArgumentException(thriftClass.getName() + " is not a thrift struct.");
+ gsonThriftBuilder.registerTypeAdapter(thriftClass, new ThriftDeserializer<T>(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> T deserialize(String data, Class<T> classOfData) {
+ try {
+ return gson.fromJson(data, classOfData);
+ } catch (JsonSyntaxException e) {
+ LOGGER.warn("Cannot deserialize to " + classOfData.getSimpleName(), e);
+ return null;
+ }
+ }
+
+ public static <T> T deserializeThrift(String data, Class<T> 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 <code>object</code>
+ */
+ public static String serialize(Object object) {
+ return gson.toJson(object);
+ }
+
+ private static class ThriftDeserializer<T> implements JsonDeserializer<T> {
+ private final Class<T> clazz;
+
+ public ThriftDeserializer(Class<T> 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;
+ }
+
+ }
+
+}