de.sonallux.spotify.api.http.ApiCall Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of spotify-web-api-java Show documentation
Show all versions of spotify-web-api-java Show documentation
A Java wrapper for Spotify's Web API
The newest version!
package de.sonallux.spotify.api.http;
import com.fasterxml.jackson.core.type.TypeReference;
import de.sonallux.spotify.api.SpotifyApiException;
import de.sonallux.spotify.api.models.Error;
import lombok.AccessLevel;
import lombok.RequiredArgsConstructor;
import okhttp3.Call;
import okhttp3.MediaType;
import okhttp3.ResponseBody;
import okio.Buffer;
import okio.BufferedSource;
import okio.ForwardingSource;
import okio.Okio;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
@RequiredArgsConstructor(access = AccessLevel.PACKAGE)
public class ApiCall {
private static final TypeReference ERROR_RESPONSE_TYPE = new TypeReference<>() {};
private final ApiClient apiClient;
private final Request request;
private final TypeReference responseType;
private volatile boolean canceled;
private Call rawCall;
private Throwable creationFailure; // RuntimeException | IOException
private boolean executed;
/**
* Returns the raw call, initializing it if necessary. Throws if initializing the raw call throws,
* or has thrown in previous attempts to create it.
*/
protected okhttp3.Call getRawCall() throws IOException {
if (rawCall != null) {
return rawCall;
}
// Re-throw previous failures if this isn't the first attempt.
if (creationFailure != null) {
if (creationFailure instanceof IOException) {
throw (IOException) creationFailure;
} else {
throw (RuntimeException) creationFailure;
}
}
// Create and remember either the success or the failure.
try {
var rawRequest = request.toOkHttpRequest(apiClient).build();
return rawCall = apiClient.getCallFactory().newCall(rawRequest);
} catch (RuntimeException | IOException e) {
creationFailure = e;
throw e;
}
}
public synchronized boolean isExecuted() {
return executed;
}
public Response executeCall() throws IOException {
okhttp3.Call call;
synchronized (this) {
if (executed) throw new IllegalStateException("Already executed.");
executed = true;
call = getRawCall();
}
if (canceled) {
call.cancel();
}
return parseResponse(call.execute());
}
public T execute() throws SpotifyApiException {
Response response;
try {
response = executeCall();
} catch (IOException e) {
throw new SpotifyApiException("Failed to make api call", e);
}
if (response.isSuccessful()) {
return response.body();
}
throw new SpotifyApiException("Api call failed", response.errorBody());
}
protected Response parseResponse(okhttp3.Response rawResponse) throws IOException {
try (ResponseBody rawBody = rawResponse.body()) {
if (rawResponse.isSuccessful()) {
var code = rawResponse.code();
if (responseType.getType() == Void.class || code == 204 || code == 205) {
return Response.success(null, rawResponse);
}
ExceptionCatchingResponseBody catchingBody = new ExceptionCatchingResponseBody(rawBody);
try {
T body = parseResponseBody(catchingBody, responseType);
return Response.success(body, rawResponse);
} catch (RuntimeException e) {
// If the underlying source threw an exception, propagate that rather than indicating it was
// a runtime exception.
catchingBody.throwIfCaught();
throw e;
}
}
Error error = getErrorBody(rawBody);
if (error == null) {
error = getErrorDetailsFromResponse(rawResponse);
}
return Response.error(error, rawResponse);
}
}
private
© 2015 - 2024 Weber Informatics LLC | Privacy Policy