package org.edx.mobile.http;
import android.support.annotation.NonNull;
import java.io.IOException;
import retrofit2.Call;
import retrofit2.Response;
/**
* Abstract implementation of Retrofit's {@link retrofit2.Callback}
* interface, which provides (and delegates to) a simpler interface
* for subclasses, stripping out unnecessary parameters, and
* redirecting all responses with error codes to the failure
* callback method (as it used to be in the implementation in
* Retrofit 1).
*
* @param <T> The successful response body type.
*/
public abstract class Callback<T> implements retrofit2.Callback<T> {
/**
* Callback method for a successful HTTP response.
*
* @param responseBody The response body, converted to an instance of it's associated Java
* class.
*/
protected abstract void onResponse(@NonNull final T responseBody);
/**
* Callback method for when the HTTP response was not received successfully, whether due to a
* network failure, receiving an HTTP error status code, or encountering an unexpected exception
* or error during the request creation or response processing phase.
*
* @param error An {@link IOException} if the request failed due to a network failure, an
* {HttpResponseStatusException} if the failure was due to receiving an error code,
* or any {@link Throwable} implementation if one was thrown unexpectedly while
* creating the request or processing the response.
*/
protected void onFailure(@NonNull final Throwable error) {}
/**
* The original callback method invoked by Retrofit upon receiving an HTTP response. This method
* definition provides extra information that's not needed by most individual callback
* implementations, and is also invoked when HTTP error status codes are encountered (forcing
* the implementation to manually check for success in each case). Therefore this implementation
* only delegates to {@link #onResponse(Object)} in the case where it receives a successful HTTP
* status code, and to {@link #onFailure(Call, Throwable)} otherwise, passing an instance of
* {@link HttpResponseStatusException} with the relevant error status code. This method is
* declared as final, as subclasses are meant to be implementing the abstract
* {@link #onResponse(Object)} method instead of this one.
*
* @param call The Call object that was used to enqueue the request.
* @param response The HTTP response data.
*/
@Override
public final void onResponse(@NonNull final Call<T> call, @NonNull final Response<T> response) {
if (response.isSuccessful()) {
onResponse(response.body());
} else {
onFailure(call, new HttpResponseStatusException(response.code()));
}
}
/**
* The original callback method invoked by Retrofit upon failure to receive an HTTP response,
* whether due to encountering a network error while waiting for the response, or some other
* unexpected error while constructing the request or processing the response. It's also invoked
* by the {@link #onResponse(Call, Response)} implementation when it receives an HTTP error
* status code. However, this method definition provides extra information that's not needed by
* most individual callback implementation, so this implementation only delegates to
* {@link #onFailure(Throwable)}. This method is declared as final, as subclasses are meant to
* be implementing the abstract {@link #onFailure(Throwable)} method instead of this one.
*
* @param call The Call object that was used to enqueue the request.
* @param error An {@link IOException} if the request failed due to a network failure, an
* {HttpResponseStatusException} if the failure was due to receiving an error code,
* or any {@link Throwable} implementation if one was thrown unexpectedly while
* creating the request or processing the response.
*/
@Override
public final void onFailure(@NonNull final Call<T> call, @NonNull final Throwable error) {
onFailure(error);
}
/**
* A dummy implementation of Retrofit's {@link retrofit2.Callback} interface, to be used in one-
* off calls, where the caller doesn't care about the result of the enqueued {@link Call}.
*/
public static final retrofit2.Callback DUMMY_CALLBACK = new retrofit2.Callback() {
@Override
public void onResponse(@NonNull final Call call, @NonNull final Response response) {}
@Override
public void onFailure(@NonNull final Call call, @NonNull final Throwable t) {}
};
}