package io.itch.api;
import android.text.TextUtils;
import android.util.Log;
import com.google.gson.FieldNamingPolicy;
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 java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.util.Map;
import io.itch.api.responses.GraphsResponse;
import retrofit.RestAdapter;
import retrofit.converter.GsonConverter;
public class ItchApiClient {
private static final Object INSTANCE_LOCK = new Object();
private static ItchApi SHARED_INSTANCE;
private static String token;
public static ItchApi getClient() {
if (SHARED_INSTANCE == null) {
synchronized (INSTANCE_LOCK) {
if (SHARED_INSTANCE == null) {
Gson gson = new GsonBuilder()
.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
.setDateFormat("yyyy-MM-dd HH:mm:ss")
.registerTypeAdapter(GraphsResponse.class, new GraphsDeserializer())
.create();
String endPoint = "https://itch.io/api/1";
if (!TextUtils.isEmpty(token)) {
endPoint = endPoint + "/" + token;
}
RestAdapter adapter = new RestAdapter.Builder()
.setEndpoint(endPoint)
.setConverter(new GsonConverter(gson))
.build();
SHARED_INSTANCE = adapter.create(ItchApi.class);
}
}
}
return SHARED_INSTANCE;
}
public static void setToken(String token) {
ItchApiClient.token = token;
synchronized (INSTANCE_LOCK) {
SHARED_INSTANCE = null;
}
}
// This is needed because the graphs API returns inconsistent types.
// When there is data, it returns a json array. When there is no data, it returns an empty object
private static class GraphsDeserializer implements JsonDeserializer<GraphsResponse> {
@Override
public GraphsResponse deserialize(JsonElement json, Type typeOfJson, JsonDeserializationContext context)
throws JsonParseException {
GraphsResponse result = new GraphsResponse();
if (json.isJsonObject()) {
JsonObject object = json.getAsJsonObject();
for (Map.Entry<String, JsonElement> entry : object.entrySet()) {
try {
Field field = GraphsResponse.class.getDeclaredField(entry.getKey());
field.setAccessible(true);
Object value;
if (entry.getValue().isJsonArray()) {
value = context.deserialize(entry.getValue(), field.getGenericType());
} else {
value = null;
}
field.set(result, value);
} catch (Exception e) {
Log.e("Itch", "Invalid field: " + e);
}
}
}
return result;
}
}
}