package com.richardradics.core.retrofit; import android.content.Context; import android.util.Log; import com.richardradics.commons.util.ConnectivityUtil; import org.androidannotations.annotations.EBean; import org.androidannotations.annotations.RootContext; import java.io.IOException; import java.net.SocketTimeoutException; import java.util.concurrent.atomic.AtomicInteger; import retrofit.RetrofitError; import retrofit.client.Client; import retrofit.client.Request; import retrofit.client.Response; /** * Created by mark on 2015. 03. 30.. */ @EBean public class ConnectivityAwareUrlClient implements Client { private static final String TAG = "BaseRetrofitClient"; protected AtomicInteger retries = new AtomicInteger(0); @RootContext Context context; private BaseRetryHandler retryHandler; private Client wrappedClient; public Client getWrappedClient() { return wrappedClient; } public void setWrappedClient(Client wrappedClient) { this.wrappedClient = wrappedClient; } public BaseRetryHandler getRetryHandler() { return retryHandler; } public void setRetryHandler(BaseRetryHandler retryHandler) { this.retryHandler = retryHandler; } @Override public Response execute(Request request) throws IOException { try { if (!ConnectivityUtil.isConnected(context)) { throw RetrofitError.unexpectedError("Nincs internet", new NoConnectivityException("No Internet")); } else { Response r = wrappedClient.execute(request); checkResult(r); return r; } } catch (RetrofitError retrofitError) { if (retry(retrofitError, retries)) { return execute(request); } else { throw new ConnectionError(); } } catch (Exception e) { throw new ConnectionError(); } } protected void checkResult(Response response) { int statusCode = response.getStatus(); if (statusCode == 404 || statusCode == 400 || statusCode == 500 || statusCode == 403 || statusCode == 401) { throw RetrofitError.httpError(response.getUrl(), response, null, null); } } protected boolean retry(RetrofitError error, AtomicInteger retries) { //increment retries retries.incrementAndGet(); Log.i(TAG, "request retry check: " + retries.get()); //no internet connection if (error.getCause() instanceof NoConnectivityException) { Log.v(TAG, "No internet!"); retryHandler.onNoInternet(); return false; } Response r = error.getResponse(); if (r != null && r.getStatus() == 400) { Log.v(TAG, "400 error! bad request!"); if (retries.get() < retryHandler.RETRY_400_BADREQUEST) { retryHandler.on400(); return true; } else { return false; } } if (r != null && r.getStatus() == 500) { Log.v(TAG, "500 error! internal server error!"); if (retries.get() < retryHandler.RETRY_500_ISE) { retryHandler.on500(); return true; } else { return false; } } if (r != null && r.getStatus() == 401) { Log.v(TAG, "401 error! unauthorized"); if (retries.get() < retryHandler.RETRY_401_UNAUTHORIZED) { retryHandler.on401(); return true; } else { return false; } } if (r != null && r.getStatus() == 403) { Log.v(TAG, "403 error! forbidden!"); if (retries.get() < retryHandler.RETRY_403_FORBIDDEN) { retryHandler.on403(); return true; } else { return false; } } if (r != null && r.getStatus() == 404) { Log.v(TAG, "404 hiba!"); if (retries.get() < retryHandler.RETRY_404_NOTFOUND) { // retry retryHandler.on404(); return true; } else { // no more retries.set(0); return false; } } //TODO other error check if (error.isNetworkError()) { //network error if (error.getCause() instanceof SocketTimeoutException) {//connection timeout check Log.v(TAG, "retry - socket timeout exception!"); if (retries.get() < retryHandler.DEFAULT_RETRY_COUNT) { // retry // retryHandler.onSocketTimeout(); return true; } else { // no more retries.set(0); return false; } } else {//no connection check Log.v(TAG, "retry - no connection check!"); if (retries.get() < retryHandler.DEFAULT_RETRY_COUNT) { // retry // retryHandler.onNoConnectivity(); return true; } else { // no more retries.set(0); return false; } } } else { //non network error check Log.v(TAG, "retry - non error check!"); retries.set(0); return false; } } }