package tw.showang.recycleradapterbase.example.api.base; import android.support.annotation.Nullable; import android.util.Log; import com.bumptech.glide.load.model.GlideUrl; import com.bumptech.glide.load.model.ModelLoaderFactory; import com.google.gson.Gson; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.util.Map; import tw.showang.apiabstrationframework.Api; import tw.showang.apiabstrationframework.ApiCipher; import tw.showang.apiabstrationframework.RequestExecutor; import tw.showang.apiabstrationframework.error.RequestError; import tw.showang.apiabstrationframework.logger.Logger; import tw.showang.apiabstrationframework.support.glide.GlideLoaderFactory; import tw.showang.apiabstrationframework.util.AsyncManager; import tw.showang.apiabstrationframework.util.AsyncManager.AsyncWork; import tw.showang.apiabstrationframework.util.AsyncManager.PostWork; public abstract class ExampleApiBase<SubClass extends ExampleApiBase<SubClass, Result>, Result> implements Api { private static Gson sGson; private static Logger sLogger; private static RequestExecutor sExecutor; private static String sAccessToken; public static void init(String gitHubToken, RequestExecutor executor, Logger logger) { sExecutor = executor; sLogger = logger; sGson = new Gson(); sAccessToken = gitHubToken; } protected Gson getGson() { return sGson; } private ApiSuccessListener<Result> mSuccessListener; private ApiErrorListener mErrorListener; @Override public int getPriority() { return Priority.NORMAL; } @Override public String getProtocol() { return Protocol.HTTPS; } @Override public String getDomainName() { return "api.github.com"; } protected String getBaseUri() { return getProtocol() + getDomainName(); } @Override public void onRequestSuccess(final byte[] byteArrayResult) { String result; try { result = new String(byteArrayResult, "utf-8"); } catch (UnsupportedEncodingException e) { result = ""; sLogger.e(Log.getStackTraceString(e)); } sLogger.i("result: " + result); final String finalResult = result; new AsyncManager<MiddleResult<Result>>() .background(new AsyncWork<MiddleResult<Result>>() { @Override public MiddleResult<Result> doInBackground() { MiddleResult<Result> middleResult = new MiddleResult<>(); try { middleResult.result = parseResult(sGson, finalResult); } catch (Exception e) { sLogger.e(Log.getStackTraceString(e)); middleResult.exception = e; } return middleResult; } }) .post(new PostWork<MiddleResult<Result>>() { @Override public void onPostExecute(MiddleResult<Result> middleResult) { if (middleResult.exception == null && middleResult.result != null) { if (mSuccessListener != null) { mSuccessListener.onSuccess(middleResult.result); } } else { if (mErrorListener == null) { return; } mErrorListener.onFail(ExampleApiError.PARSE_DATA_ERROR, ""); } } }) .start(); } protected abstract Result parseResult(Gson gson, String result) throws ApiException; @Override public void onRequestFail(int cause, String errorMessage) { if (mErrorListener == null) { return; } int errorCode; switch (cause) { case RequestError.NETWORK_NOT_AVAILABLE: errorCode = ExampleApiError.NETWORK_NOT_AVAILABLE; break; case RequestError.TIMEOUT_ERROR: errorCode = ExampleApiError.REQUEST_TIMEOUT; break; case RequestError.DECODE_ERROR: case RequestError.UNKNOWN_SERVER_ERROR: default: errorCode = ExampleApiError.UNKNOWN_SERVER_ERROR; } mErrorListener.onFail(errorCode, errorMessage); } @Override final public byte[] getRequestBody() { String body = getBody(); return body == null ? new byte[0] : body.getBytes(); } protected String getBody() { return null; } @Override public String getContentType() { return "application/json"; } @Override public void getHeaders(Map<String, String> headerMap) { headerMap.put("Authorization", "token " + sAccessToken); } @Override public void getParameter(Map<String, String> parameterMap) {} @Override public int getTimeout() { return 10 * 1000; } @Override public int getRetryCount() { return 2; } @Override @Nullable public ApiCipher getApiCipher() { return null; } @Override public boolean isRequestBodyEncrypt() { return false; } @Override public boolean isResponseBodyDecrypt() { return false; } @SuppressWarnings("unchecked") public SubClass success(ApiSuccessListener<Result> successListener) { mSuccessListener = successListener; return (SubClass) this; } @SuppressWarnings("unchecked") public SubClass fail(ApiErrorListener errorListener) { mErrorListener = errorListener; return (SubClass) this; } public SubClass start() { return start(this); } @SuppressWarnings("unchecked") public SubClass start(Object tag) { sExecutor.request(this, tag); return (SubClass) this; } public void cancel() { sExecutor.cancel(this); } public void cancel(Object tag) { sExecutor.cancel(tag); } public static ModelLoaderFactory<GlideUrl, InputStream> createUrlLoaderFactory() { if(sExecutor instanceof GlideLoaderFactory) { return ((GlideLoaderFactory)sExecutor).createUrlLoaderFactory(); } return null; } public interface ApiSuccessListener<T> { void onSuccess(T response); } public interface ApiErrorListener { void onFail(int errorType, String message); } private class MiddleResult<T> { T result; Exception exception; } }