Last active
October 31, 2015 05:31
-
-
Save wischweh/c55265d0883c4e4ab350 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.twobox.evaluategson_jsonapi.deserialize; | |
import com.google.gson.Gson; | |
import com.google.gson.GsonBuilder; | |
import com.google.gson.JsonElement; | |
import com.google.gson.JsonObject; | |
import com.google.gson.TypeAdapter; | |
import com.google.gson.TypeAdapterFactory; | |
import com.google.gson.reflect.TypeToken; | |
import com.google.gson.stream.JsonReader; | |
import com.google.gson.stream.JsonToken; | |
import com.google.gson.stream.JsonWriter; | |
import org.json.JSONObject; | |
import java.io.IOException; | |
import java.lang.reflect.Type; | |
import java.util.HashMap; | |
import java.util.Map; | |
/** | |
* This is a implementation to unflatten JSON which is structured according to http://jsonapi.org/ specification (and hence is flat) | |
* and make it mappable to regular POJOs. | |
* | |
* The idea is based on http://stackoverflow.com/questions/11271375/gson-custom-seralizer-for-one-variable-of-many-in-an-object-using-typeadapter | |
* | |
* Created by wischweh1 on 02.07.15. | |
*/ | |
public class JSONApiTypeAdapterFactory<C> | |
implements TypeAdapterFactory { | |
private final Class<C> customizedClass; | |
public static final String JSONAPI_KEYWORD_ID="id"; | |
public static final String JSONAPI_KEYWORD_TYPE="type"; | |
public static final String JSONAPI_KEYWORD_ATTRIBUTES="attributes"; | |
public JSONApiTypeAdapterFactory(Class<C> customizedClass) { | |
this.customizedClass = customizedClass; | |
} | |
@SuppressWarnings("unchecked") // we use a runtime check to guarantee that 'C' and 'T' are equal | |
public final <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) { | |
return type.getRawType() == customizedClass | |
? (TypeAdapter<T>) customizeMyClassAdapter(gson, (TypeToken<C>) type) | |
: null; | |
} | |
private TypeAdapter<C> customizeMyClassAdapter(Gson gson, TypeToken<C> type) { | |
final TypeAdapter<C> delegate = gson.getDelegateAdapter(this, type); | |
final TypeAdapter<JsonElement> elementAdapter = gson.getAdapter(JsonElement.class); | |
return new TypeAdapter<C>() { | |
@Override public void write(JsonWriter out, C value) throws IOException { | |
JsonElement tree = delegate.toJsonTree(value); | |
beforeWrite(value, tree); | |
elementAdapter.write(out, tree); | |
} | |
@Override public C read(JsonReader in) throws IOException { | |
JsonElement tree = elementAdapter.read(in); | |
JsonElement unflattenedTree=unflatten(tree); | |
return delegate.fromJsonTree(unflattenedTree); | |
} | |
}; | |
} | |
/** | |
* Override this to muck with {@code toSerialize} before it is written to | |
* the outgoing JSON stream. | |
*/ | |
protected void beforeWrite(C source, JsonElement toSerialize) { | |
// TODO: Implement this | |
} | |
/** | |
* Override this to muck with {@code deserialized} before it parsed into | |
* the application type. | |
*/ | |
protected JsonElement unflatten(JsonElement deserialized) { | |
JsonObject result=new JsonObject(); | |
JsonObject dataNode=deserialized.getAsJsonObject(); | |
result.add(JSONAPI_KEYWORD_ID, dataNode.get(JSONAPI_KEYWORD_ID)); | |
JsonObject attributes=dataNode.getAsJsonObject(JSONAPI_KEYWORD_ATTRIBUTES); | |
for (Map.Entry<String, JsonElement> entry : attributes.entrySet()) { | |
result.add(entry.getKey(),entry.getValue()); | |
} | |
return result; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment