package com.rogansoft.tasksdemo.api; import java.io.IOException; import java.lang.reflect.Type; import java.text.ParseException; import java.util.Date; import java.util.List; import retrofit.RequestInterceptor; import retrofit.RestAdapter; import retrofit.converter.GsonConverter; 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.JsonParseException; import com.google.gson.TypeAdapter; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonWriter; import com.rogansoft.tasksdemo.Util; import com.rogansoft.tasksdemo.domain.Task; import com.rogansoft.tasksdemo.domain.TaskList; public class GoogleTaskApi implements TaskApi { //private static final String TAG = "TaskApi"; private RestAdapter mRestAdapter; private GoogleTaskApiService mService; class TaskTypeAdapter extends TypeAdapter<Task> { private long parseRFC3339Date(String dateStr) { long result = 0; try { Date date = Util.parseRFC3339Date(dateStr); result = date.getTime() / 1000; } catch (IndexOutOfBoundsException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); } return result; } @Override public Task read(JsonReader in) throws IOException { final Task task = new Task(); in.beginObject(); while(in.hasNext()) { //Log.d(TAG, "json peek: "+in.peek().toString()); String name = in.nextName(); //Log.d(TAG, "json name: "+name); if (name.equals("id")){ task.setServerId(in.nextString()); } else if (name.equals("title")) { task.setTitle(in.nextString()); } else if (name.equals("updated")) { task.setUpdated(parseRFC3339Date(in.nextString())); } else if (name.equals("status")) { task.setStatus(in.nextString()); } else if (name.equals("position")) { task.setPosition(in.nextString()); } else if (name.equals("deleted")) { //Log.d(TAG, "json deleted peek: "+in.peek().toString()); task.setDeleted(in.nextBoolean()); //Log.d(TAG, "task deleted:"+task.isDeleted()); } else { in.skipValue(); } } in.endObject(); return task; } @Override public void write(JsonWriter out, Task task) throws IOException { out.beginObject(); if (task.getServerId() != null) { out.name("id").value(task.getServerId()); } out.name("title").value(task.getTitle()); out.name("status").value(task.getStatus()); out.endObject(); } } class TaskListDeserializer<T> implements JsonDeserializer<T>{ @Override public T deserialize(JsonElement je, Type type, JsonDeserializationContext jdc) throws JsonParseException { // Get the "content" element from the parsed JSON JsonElement items = je.getAsJsonObject().get("items"); Gson gson = new GsonBuilder() .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) .registerTypeAdapter(Task.class, new TaskTypeAdapter()) .create(); // Deserialize it. You use a new instance of Gson to avoid infinite recursion // to this deserializer return gson.fromJson(items, type); } } public GoogleTaskApi(String authToken) { final String token = authToken; RequestInterceptor requestInterceptor = new RequestInterceptor() { @Override public void intercept(RequestFacade request) { request.addHeader("Authorization", "Bearer "+token); } }; Gson gson = new GsonBuilder() .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) .registerTypeAdapter(List.class, new TaskListDeserializer<List<TaskList>>()) .registerTypeAdapter(List.class, new TaskListDeserializer<List<Task>>()) .registerTypeAdapter(Task.class, new TaskTypeAdapter()) .create(); mRestAdapter = new RestAdapter.Builder() .setRequestInterceptor(requestInterceptor) .setEndpoint(GoogleTaskApiService.API_BASE_URL) .setConverter(new GsonConverter(gson)) .build(); //Log.d(TAG, "retrofit log level:"+mRestAdapter.getLogLevel()); //mRestAdapter.setLogLevel(LogLevel.FULL); //Log.d(TAG, "retrofit log level after setting full:"+mRestAdapter.getLogLevel()); mService = mRestAdapter.create(GoogleTaskApiService.class); } public List<TaskList> getTaskList(){ return mService.getTaskLists(); } @Override public Task get(String remoteId) { return mService.get(GoogleTaskApiService.GOOGLE_TASK_LIST_ID, remoteId); } @Override public List<Task> get() { return mService.get(GoogleTaskApiService.GOOGLE_TASK_LIST_ID); } @Override public Task post(Task t) { return mService.post(GoogleTaskApiService.GOOGLE_TASK_LIST_ID, t); } @Override public Task put(Task t) { return mService.put(GoogleTaskApiService.GOOGLE_TASK_LIST_ID, t.getRemoteId(), t); } }