package feign.example.wikipedia; import com.google.gson.TypeAdapter; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonWriter; import java.io.IOException; abstract class ResponseAdapter<X> extends TypeAdapter<WikipediaExample.Response<X>> { /** * name of the key inside the {@code query} dict which holds the elements desired. ex. {@code * pages}. */ protected abstract String query(); /** * Parses the contents of a result object. <p/> <br> ex. If {@link #query()} is {@code pages}, * then this would parse the value of each key in the dict {@code pages}. In the example below, * this would first start at line {@code 3}. <p/> * <pre> * "pages": { * "2576129": { * "pageid": 2576129, * "title": "Burchell's zebra", * --snip-- * </pre> */ protected abstract X build(JsonReader reader) throws IOException; /** * the wikipedia api doesn't use json arrays, rather a series of nested objects. */ @Override public WikipediaExample.Response<X> read(JsonReader reader) throws IOException { WikipediaExample.Response<X> pages = new WikipediaExample.Response<X>(); reader.beginObject(); while (reader.hasNext()) { String nextName = reader.nextName(); if ("query".equals(nextName)) { reader.beginObject(); while (reader.hasNext()) { if (query().equals(reader.nextName())) { reader.beginObject(); while (reader.hasNext()) { // each element is in form: "id" : { object } // this advances the pointer to the value and skips the key reader.nextName(); reader.beginObject(); pages.add(build(reader)); reader.endObject(); } reader.endObject(); } else { reader.skipValue(); } } reader.endObject(); } else if ("continue".equals(nextName)) { reader.beginObject(); while (reader.hasNext()) { if ("gsroffset".equals(reader.nextName())) { pages.nextOffset = reader.nextLong(); } else { reader.skipValue(); } } reader.endObject(); } else { reader.skipValue(); } } reader.endObject(); return pages; } @Override public void write(JsonWriter out, WikipediaExample.Response<X> response) throws IOException { throw new UnsupportedOperationException(); } }