All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ru.blizzed.openlastfm.methods.ApiRequest Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2017 BlizzedRu (Ivan Vlasov)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package ru.blizzed.openlastfm.methods;

import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Response;
import ru.blizzed.openlastfm.ApiRequestException;
import ru.blizzed.openlastfm.ApiResponseException;
import ru.blizzed.openlastfm.OpenLastFMContext;
import ru.blizzed.openlastfm.RequestsExecutor;
import ru.blizzed.openlastfm.models.ObjectModelParser;
import ru.blizzed.openlastfm.models.commons.Error;
import ru.blizzed.openlastfm.params.LastFMParams;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

/**
 * This class represents a request to LastFm API
 * 

Can be executed to call the API * * @param expected response model type * @author BlizzedRu */ public final class ApiRequest { /** * A common callback for request executing *

You must not override all methods, you can choose such as you want * * @param expected response model type */ public interface ApiRequestListener { /** * This method triggers you when call to API has been completed successfully * * @param response parsed {@link ApiResponse} */ default void onComplete(ApiResponse response) { } /** * This method triggers you when API has been called but response contains an error * * @param error parsed {@link ApiResponse} with {@link Error} */ default void onApiError(ApiResponse error) { } /** * This method triggers you when call to API cannot be established *

E.g. no internet connection * * @param exception an exception that contains initial message and {@link ApiRequest} */ default void onFailure(ApiRequestException exception) { } } private ApiMethod method; private ApiParams params; /** * @param method a {@link ApiMethod} that you want to call * @param params a {@link ApiParams} of method that you want to call with */ public ApiRequest(ApiMethod method, ApiParams params) { this.method = method; this.params = params; } /** * Returns initial {@link ApiMethod} of this request * * @return initial method */ public ApiMethod getMethod() { return method; } /** * Returns initial {@link ApiParams} of this request * * @return initial params */ public ApiParams getParams() { return params; } /** * Makes an enqueue call to the LastFM API * * @param listener {@link ApiRequestListener} to get callbacks * @see #execute(ApiRequestListener) */ public void executeEnqueue(ApiRequestListener listener) { RequestsExecutor.getInstance().executeEnqueue(this, getDefaultCallBack(listener)); } /** * Makes a call to the LastFM API *

*

That's the main variant to call the LastFM API *

If you don't want or can't deal with {@link ApiRequestListener} you can use {@link #execute()} method *

You can get callbacks using {@link ApiRequestListener} as a param * * @see ApiRequestListener * @see #execute() * * @param listener {@link ApiRequestListener} to get callbacks */ public void execute(ApiRequestListener listener) { RequestsExecutor.getInstance().execute(this, getDefaultCallBack(listener)); } /** * Makes a call to the LastFM API *

* This variant of execute method can be used if you don't want or can't deal with {@link ApiRequestListener} *

That's good for building coherent requests logic *

You can get errors by catching exceptions – {@link ApiResponseException} and {@link ApiRequestException} * * @see ApiResponseException * @see ApiRequestException * * @return parsed {@link ApiResponse} with expected result model type * @throws ApiResponseException when API has been called but response contains an error * @throws ApiRequestException when call to API cannot be established */ public ApiResponse execute() throws ApiResponseException, ApiRequestException { try (Response response = RequestsExecutor.getInstance().execute(this)) { return handleResponse(response); } catch (IOException e) { throw new ApiRequestException(e, this); } } /** * Cancels current request if it's executing or staying in queue */ public void cancel() { RequestsExecutor.getInstance().cancel(this); } private ApiResponse handleResponse(Response response) throws ApiResponseException, IOException { String body = response.body().string(); JsonObject root = getAsJson(body); if (!response.isSuccessful()) throw new ApiResponseException(buildErrorResponse(body, root)); return buildResultResponse(body, root); } private void handleResponse(ApiRequestListener listener, Response response) throws IOException { String originalResponse = response.body().string(); JsonObject root = getAsJson(originalResponse); if (response.isSuccessful()) notifyComplete(listener, buildResultResponse(originalResponse, root)); else notifyError(listener, buildErrorResponse(originalResponse, root)); } private JsonObject getAsJson(String body) { JsonParser parser = new JsonParser(); return parser.parse(body).getAsJsonObject(); } @SuppressWarnings("unchecked") private ApiResponse buildResultResponse(String originalResponse, JsonObject root) { return new ApiResponse<>(this, originalResponse, (ResultType) getMethod().getModelParser().parse(root)); } private ApiResponse buildErrorResponse(String originalResponse, JsonObject root) { return new ApiResponse<>(this, originalResponse, new ObjectModelParser<>("", Error.class).parse(root)); } private void notifyComplete(ApiRequestListener listener, ApiResponse response) { if (listener != null) listener.onComplete(response); } private void notifyError(ApiRequestListener listener, ApiResponse response) { if (listener != null) listener.onApiError(response); } private void notifyFailure(ApiRequestListener listener, IOException e) { if (listener != null) listener.onFailure(new ApiRequestException(e, this)); } private Callback getDefaultCallBack(ApiRequestListener listener) { return new Callback() { @Override public void onFailure(Call call, IOException e) { notifyFailure(listener, e); } @Override public void onResponse(Call call, Response response) throws IOException { handleResponse(listener, response); response.close(); } }; } /** * Returns this request as {@link String} *

It is full build request in URL format * @return built request in URL format */ public String asString() { StringBuilder request = new StringBuilder(OpenLastFMContext.getRootUrl()); request.append("&method=") .append(method.getFullAlias()) .append("&api_key=") .append(OpenLastFMContext.getApiKey()); params.asList() .forEach(param -> request .append("&") .append(param.name()) .append("=") .append(encode(param.getData().toString())) ); if (!params.asList().contains(LastFMParams.LANG)) request.append("&lang=").append(OpenLastFMContext.getLang()); return request.toString(); } /** * URL Encodes the given String str using the UTF-8 character encoding. * * @param str a String * @return url encoded string */ private static String encode(String str) { if(str == null) return null; try { return URLEncoder.encode(str, "UTF-8"); } catch (UnsupportedEncodingException e) { // UTF-8 is always available } return null; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy