Skip to content

Instantly share code, notes, and snippets.

@wischweh
Last active October 31, 2015 05:31
Show Gist options
  • Select an option

  • Save wischweh/c55265d0883c4e4ab350 to your computer and use it in GitHub Desktop.

Select an option

Save wischweh/c55265d0883c4e4ab350 to your computer and use it in GitHub Desktop.

Revisions

  1. wischweh revised this gist Jul 3, 2015. 1 changed file with 5 additions and 0 deletions.
    5 changes: 5 additions & 0 deletions JSONApiTypeAdapterFactory.java
    Original file line number Diff line number Diff line change
    @@ -20,6 +20,11 @@
    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>
  2. wischweh created this gist Jul 3, 2015.
    84 changes: 84 additions & 0 deletions JSONApiTypeAdapterFactory.java
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,84 @@
    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;

    /**
    * 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;
    }
    }