diff --git a/src/main/java/me/goudham/APIWrapper.java b/src/main/java/me/goudham/APIWrapper.java index 40fae3a..a786ec1 100644 --- a/src/main/java/me/goudham/APIWrapper.java +++ b/src/main/java/me/goudham/APIWrapper.java @@ -32,388 +32,362 @@ import static me.goudham.APIUtils.paginationData; /** * Returns API information to {@link MyWaifuClient} - * */ -public class APIWrapper { - private final String version = "1.0"; - private static final String host = "https://mywaifulist.moe/api/v1/"; - private String apiKey; - - private APIMapper apiMapper; - private final HttpClient httpClient; - private final Executor executor = Executors.newFixedThreadPool(10); - - /** - * Instantiates an instance of {@link APIWrapper} to retrieve API Information. - * An instance of {@link APIMapper} is created to be able to {@code deserialize} JSON to - * Java objects - * - * @param apiKey API Key to authorise API request - * @param httpClient The underlying {@link HttpClient} to use for HttpRequests - * - */ - APIWrapper(String apiKey, HttpClient httpClient) { - this.apiKey = apiKey; - this.httpClient = httpClient; - apiMapper = new APIMapper(); - } - - /** - * Create base {@link HttpRequest.Builder} with custom url, default headers and timeout - * - * @param param The end of the endpoint appended onto the host - * @return {@link HttpRequest.Builder} - * - */ - private HttpRequest.Builder getBaseRequest(String param) { - return HttpRequest.newBuilder() - .uri(URI.create(host + param)) - .timeout(Duration.ofSeconds(20)) - .headers("Content-Type", "application/json", "apikey", apiKey); - } - - /** - * Separate method for sending GET requests - * - * @param param The end of the endpoint appended onto the host - * @return {@link Result} - * @throws APIResponseException If {@link #sendRequest(HttpRequest)} cannot retrieve the proper data from the API - * - */ - Result sendGetRequest(String param) throws APIResponseException { - HttpRequest request = getBaseRequest(param).GET().build(); - return sendRequest(request); - } - - /** - * Separate method for sending POST requests - * - * @param param The end of the endpoint appended onto the host - * @param headers Headers as Key/Value pairs for POST requests - * @return {@link Result} - * @throws APIResponseException If {@link #sendRequest(HttpRequest)} cannot retrieve the proper data from the API - * @throws APIMapperException If {@link APIMapper#getObjectAsString(Object)} cannot properly serialize object - * - */ - private Result sendPostRequest(String param, Map headers) throws APIResponseException, APIMapperException { - HttpRequest request = getBaseRequest(param) - .POST(HttpRequest.BodyPublishers.ofString(apiMapper.getObjectAsString(headers))) - .build(); - return sendRequest(request); - } - - /** - * Handles sending a request to the API asynchronously using {@link HttpRequest} - * and the underlying {@link HttpClient} - * - * @param httpRequest The {@link HttpRequest} to be sent by the {@link HttpClient} - * @return {@link Result} - * @throws APIResponseException If the {@link CompletableFuture Response} - * cannot be decoded or the thread was interrupted while waiting to receive the data - * - */ - private Result sendRequest(HttpRequest httpRequest) throws APIResponseException { - CompletableFuture futureResult = CompletableFuture.supplyAsync(() -> { - try { - return httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString()); - } catch (IOException | InterruptedException exp) { - exp.printStackTrace(); - } - return null; - }, executor).thenApply(httpResponse -> new Result(httpResponse.statusCode(), httpResponse.body())); - - try { - return futureResult.get(); - } catch (InterruptedException | ExecutionException exp) { - throw new APIResponseException(exp.getMessage(), exp); - } - } - - /** - * Retrieve detailed information about the {@link Waifu} by sending request to API - * - * @param waifuId The id of the {@link Waifu} - * @return {@link Response} of {@link Waifu} - * @throws APIResponseException If {@link APIWrapper} could not return information properly - * @throws APIMapperException If {@link APIMapper} could not correctly {@code deserialize} model - * - */ - Response getWaifu(String waifuId) throws APIResponseException, APIMapperException { - Result waifuResult = sendGetRequest("waifu/" + waifuId); - return apiMapper.deserialize(waifuResult, Waifu.class); - } - - /** - * Retrieve paginated images from the gallery, in sets of 10, by sending request to API - * - * @param waifuId The id of the {@link Waifu} - * @param pageNum The page number of the gallery - * @return {@link Response} of {@link WaifuImage} - * @throws APIResponseException If {@link APIWrapper} could not return information properly - * @throws APIMapperException If {@link APIMapper} could not correctly {@code deserialize} model - * - */ - Response> getWaifuImages(String waifuId, String pageNum) throws APIResponseException, APIMapperException { - Result waifuImagesResult = sendGetRequest("waifu/" + waifuId + "/images?page=" + pageNum); - return apiMapper.deserializeToPaginationData(waifuImagesResult, paginationData(WaifuImage.class)); - } - - /** - * Retrieve an array of {@link FilteredWaifu}'s, sorted alphabetically, by sending request to API - * - * @param pageNum The page number of the gallery - * @return {@link Response} of {@link PaginationData} with {@link FilteredWaifu} - * @throws APIResponseException If {@link APIWrapper} could not return information properly - * @throws APIMapperException If {@link APIMapper} could not correctly {@code deserialize} model - * - */ - Response> getWaifusByPage(String pageNum) throws APIResponseException, APIMapperException { - Result waifusByPageResult = sendGetRequest("waifu?page=" + pageNum); - return apiMapper.deserializeToPaginationData(waifusByPageResult, paginationData(FilteredWaifu.class)); - } - - /** - * Retrieve the Waifu of the Day by sending request to API - * - * @return {@link Response} of {@link FilteredWaifu} - * @throws APIResponseException If {@link APIWrapper} could not return information properly - * @throws APIMapperException If {@link APIMapper} could not correctly {@code deserialize} model - * - */ - Response getDailyWaifu() throws APIResponseException, APIMapperException { - Result dailyWaifuResult = sendGetRequest("meta/daily"); - return apiMapper.deserialize(dailyWaifuResult, FilteredWaifu.class); - } - - /** - * Retrieve a Random Waifu from the Website by sending request to API - * - * @return {@link Response} of {@link FilteredWaifu} - * @throws APIResponseException If {@link APIWrapper} could not return information properly - * @throws APIMapperException If {@link APIMapper} could not correctly {@code deserialize} model - * - */ - Response getRandomWaifu() throws APIResponseException, APIMapperException { - Result randomWaifuResult = sendGetRequest("meta/random"); - return apiMapper.deserialize(randomWaifuResult, FilteredWaifu.class); - } - - /** - * Retrieve a List of Currently Airing Anim by sending request to API - * - * @return {@link Response} of {@link List} with {@link FilteredSeries} - * @throws APIResponseException If {@link APIWrapper} could not return information properly - * @throws APIMapperException If {@link APIMapper} could not correctly {@code deserialize} model - * - */ - Response> getSeasonalAnime() throws APIResponseException, APIMapperException { - Result seasonalAnimeResult = sendGetRequest("airing"); - return apiMapper.deserializeToList(seasonalAnimeResult, listOf(FilteredSeries.class)); - } - - /** - * Retrieve the Best Waifus of the Current Season by sending request to API - * - * @return {@link Response} of {@link List} with {@link FilteredWaifu} - * @throws APIResponseException If {@link APIWrapper} could not return information properly - * @throws APIMapperException If {@link APIMapper} could not correctly {@code deserialize} model - * - */ - Response> getBestWaifus() throws APIResponseException, APIMapperException { - Result waifuResults = sendGetRequest("airing/best"); - return apiMapper.deserializeToList(waifuResults, listOf(FilteredWaifu.class)); - } - - /** - * Retrieve a List of Popular Waifus (Raw Count of Total Votes) of the Current Season - * by sending request to API - * - * @return {@link Response} of {@link List} with {@link FilteredWaifu} - * @throws APIResponseException If {@link APIWrapper} could not return information properly - * @throws APIMapperException If {@link APIMapper} could not correctly {@code deserialize} model - * - */ - Response> getPopularWaifus() throws APIResponseException, APIMapperException { - Result waifuResults = sendGetRequest("airing/popular"); - return apiMapper.deserializeToList(waifuResults, listOf(FilteredWaifu.class)); - } - - /** - * Retrieve the Most Disliked Waifus of the Current Season by sending request to API - * - * @return {@link Response} of {@link List} with {@link FilteredWaifu} - * @throws APIResponseException If {@link APIWrapper} could not return information properly - * @throws APIMapperException If {@link APIMapper} could not correctly {@code deserialize} model - * - */ - Response> getTrashWaifus() throws APIResponseException, APIMapperException { - Result waifuResults = sendGetRequest("airing/trash"); - return apiMapper.deserializeToList(waifuResults, listOf(FilteredWaifu.class)); - } - - /** - * Retrieve detailed information about a given {@link Series} by sending request to API - * - * @param seriesId The id of the {@link Series} - * @return {@link Response} of {@link Series} - * @throws APIResponseException If {@link APIWrapper} could not return information properly - * @throws APIMapperException If {@link APIMapper} could not correctly {@code deserialize} model - * - */ - Response getSeries(String seriesId) throws APIResponseException, APIMapperException { - Result seriesResult = sendGetRequest("series/" + seriesId); - return apiMapper.deserialize(seriesResult, Series.class); - } - - /** - * Retrieve paginated information about a Series by sending request to API - * - * @param pageNum The page number of the gallery - * @return {@link Response} of {@link PaginationData} with {@link FilteredSeries} - * @throws APIResponseException If {@link APIWrapper} could not return information properly - * @throws APIMapperException If {@link APIMapper} could not correctly {@code deserialize} model - * - */ - Response> getSeriesByPage(String pageNum) throws APIResponseException, APIMapperException { - Result seriesPageResult = sendGetRequest("series?page=" + pageNum); - return apiMapper.deserializeToPaginationData(seriesPageResult, paginationData(FilteredSeries.class)); - } - - /** - * Retrieve the List of Anime that Aired in a given Season and Year by sending request to API - * - * @param season The specified season from {@link Season} - * @param year The specified year - * @return {@link Response} of {@link List} with {@link FilteredSeries} - * @throws APIResponseException If {@link APIWrapper} could not return information properly - * @throws APIMapperException If {@link APIMapper} could not correctly {@code deserialize} model - * - */ - Response> getAllSeries(Season season, Integer year) throws APIResponseException, APIMapperException { - Result allSeriesResult = sendGetRequest("airing/" + season.getSeason() + "/" + year); - return apiMapper.deserializeToList(allSeriesResult, listOf(FilteredSeries.class)); - } - - /** - * Retrieve a set of Waifus for a given {@link Series} by sending request to API - * - * @param seriesId The id of the {@link Series} - * @return {@link Response} of {@link List} with {@link FilteredWaifu} - * @throws APIResponseException If {@link APIWrapper} could not return information properly - * @throws APIMapperException If {@link APIMapper} could not correctly {@code deserialize} model - * - */ - Response> getSeriesWaifus(String seriesId) throws APIResponseException, APIMapperException { - Result allWaifusFromSeriesResults = sendGetRequest("series/" + seriesId + "/waifus"); - return apiMapper.deserializeToList(allWaifusFromSeriesResults, listOf(FilteredWaifu.class)); - } - - /** - * Retrieve information about the {@link User} by sending request to API - * - * @param userId The id of the {@link User} - * @return {@link Response} of {@link User} - * @throws APIResponseException If {@link APIWrapper} could not return information properly - * @throws APIMapperException If {@link APIMapper} could not correctly {@code deserialize} model - * - */ - Response getUserProfile(String userId) throws APIResponseException, APIMapperException { - Result userProfileResult = sendGetRequest("user/" + userId); - return apiMapper.deserialize(userProfileResult, User.class); - } - - /** - * Retrieve the Waifus Created, Liked, or Trashed for the given {@link User} id by sending request to API - * - * @param userId The id of the {@link User} - * @param listType The specified action E.g {@link WaifuListType#LIKED} - * @param pageNum The page number of the gallery - * @return {@link Response} of {@link PaginationData} with {@link FilteredWaifu} - * @throws APIResponseException If {@link APIWrapper} could not return information properly - * @throws APIMapperException If {@link APIMapper} could not correctly {@code deserialize} model - * - */ - Response> getUserWaifus(String userId, String listType, String pageNum) throws APIResponseException, APIMapperException { - Result userWaifusResult = sendGetRequest("user/" + userId + "/" + listType + "?page=" + pageNum); - return apiMapper.deserializeToPaginationData(userWaifusResult, paginationData(FilteredWaifu.class)); - } - - /** - * Retrieve a List of all {@link UserList}'s shown by sending request to API - * - * @param userId The id of the {@link User} - * @return {@link Response} of {@link List} with {@link UserList} - * @throws APIResponseException If {@link APIWrapper} could not return information properly - * @throws APIMapperException If {@link APIMapper} could not correctly {@code deserialize} model - * - */ - Response> getUserLists(String userId) throws APIResponseException, APIMapperException { - Result userProfileResult = sendGetRequest("user/" + userId + "/lists"); - return apiMapper.deserializeToList(userProfileResult, listOf(UserList.class)); - } - - /** - * Retrieve the Specific {@link UserList}, with {@link Waifu}'s by sending request to API - * - * @param userId The id of the {@link User} - * @param listId The id of the {@link UserList} - * @return {@link Response} of {@link UserList} - * @throws APIResponseException If {@link APIWrapper} could not return information properly - * @throws APIMapperException If {@link APIMapper} could not correctly {@code deserialize} model - * - */ - Response getUserList(String userId, String listId) throws APIResponseException, APIMapperException { - Result userProfileResult = sendGetRequest("user/" + userId + "/lists/" + listId); - return apiMapper.deserialize(userProfileResult, UserList.class); - } - - /** - * Retrieve a {@link List} of {@link FilteredWaifu} with a search term by sending a POST request to the API - * - * @param searchString {@link String} that should be searched for - * @return {@link Response} of {@link List} with {@link FilteredWaifu} - * @throws APIResponseException If {@link APIWrapper} could not return information properly - * @throws APIMapperException If {@link APIMapper} could not correctly {@code deserialize} model - * - */ - Response> betaSearch(String searchString) throws APIMapperException, APIResponseException { - Result betaSearchResult = sendPostRequest("search/beta", Map.of("term", searchString)); - return apiMapper.deserializeToList(betaSearchResult, listOf(FilteredWaifu.class)); - } - - /** - * Retrieve a List of {@link FilteredWaifu}'s given a query, by sending POST request to API - * - * @param waifuName The name of the Waifu - * @return {@link Response} of {@link List} with {@link FilteredWaifu} - * @throws APIResponseException If {@link APIWrapper} could not return information properly - * @throws APIMapperException If {@link APIMapper} could not correctly {@code deserialize} model - * - */ - Response> searchWaifus(String waifuName) throws APIMapperException, APIResponseException { - Result searchWaifusResult = sendPostRequest("search/waifus", Map.of("term", waifuName)); - return apiMapper.deserializeToList(searchWaifusResult, listOf(FilteredWaifu.class)); - } - - /** - * Retrieve a List of {@link FilteredSeries}'s given a query, by sending POST request to API - * - * @param seriesName The name of the Series - * @return {@link Response} of {@link List} with {@link FilteredSeries} - * @throws APIResponseException If {@link APIWrapper} could not return information properly - * @throws APIMapperException If {@link APIMapper} could not correctly {@code deserialize} model - * - */ - Response> searchSeries(String seriesName) throws APIMapperException, APIResponseException { - Result searchSeriesResult = sendPostRequest("search/series", Map.of("term", seriesName)); - return apiMapper.deserializeToList(searchSeriesResult, listOf(FilteredSeries.class)); - } - - void setApiKey(String apiKey) { - this.apiKey = apiKey; - } - - void setApiMapper(APIMapper apiMapper) { - this.apiMapper = apiMapper; - } +class APIWrapper { + private final String version = "1.0"; + private static final String host = "https://mywaifulist.moe/api/v1/"; + private String apiKey; + + private APIMapper apiMapper; + private final HttpClient httpClient; + private final Executor executor = Executors.newFixedThreadPool(10); + + /** + * Instantiates an instance of {@link APIWrapper} to retrieve API Information. + * An instance of {@link APIMapper} is created to be able to {@code deserialize} JSON to + * Java objects + * + * @param apiKey API Key to authorise API request + * @param httpClient The underlying {@link HttpClient} to use for HttpRequests + */ + APIWrapper(String apiKey, HttpClient httpClient) { + this.apiKey = apiKey; + this.httpClient = httpClient; + apiMapper = new APIMapper(); + } + + /** + * Create base {@link HttpRequest.Builder} with custom url, default headers and timeout + * + * @param param The end of the endpoint appended onto the host + * @return {@link HttpRequest.Builder} + */ + private HttpRequest.Builder getBaseRequest(String param) { + return HttpRequest.newBuilder() + .uri(URI.create(host + param)) + .timeout(Duration.ofSeconds(20)) + .headers("Content-Type", "application/json", "apikey", apiKey); + } + + /** + * Separate method for sending GET requests + * + * @param param The end of the endpoint appended onto the host + * @return {@link Result} + * @throws APIResponseException If {@link #sendRequest(HttpRequest)} cannot retrieve the proper data from the API + */ + Result sendGetRequest(String param) throws APIResponseException { + HttpRequest request = getBaseRequest(param).GET().build(); + return sendRequest(request); + } + + /** + * Separate method for sending POST requests + * + * @param param The end of the endpoint appended onto the host + * @param headers Headers as Key/Value pairs for POST requests + * @return {@link Result} + * @throws APIResponseException If {@link #sendRequest(HttpRequest)} cannot retrieve the proper data from the API + * @throws APIMapperException If {@link APIMapper#getObjectAsString(Object)} cannot properly serialize object + */ + private Result sendPostRequest(String param, Map headers) throws APIResponseException, APIMapperException { + HttpRequest request = getBaseRequest(param) + .POST(HttpRequest.BodyPublishers.ofString(apiMapper.getObjectAsString(headers))) + .build(); + return sendRequest(request); + } + + /** + * Handles sending a request to the API asynchronously using {@link HttpRequest} + * and the underlying {@link HttpClient} + * + * @param httpRequest The {@link HttpRequest} to be sent by the {@link HttpClient} + * @return {@link Result} + * @throws APIResponseException If the {@link CompletableFuture Response} + * cannot be decoded or the thread was interrupted while waiting to receive the data + */ + private Result sendRequest(HttpRequest httpRequest) throws APIResponseException { + CompletableFuture futureResult = CompletableFuture.supplyAsync(() -> { + try { + return httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString()); + } catch (IOException | InterruptedException exp) { + exp.printStackTrace(); + } + return null; + }, executor).thenApply(httpResponse -> new Result(httpResponse.statusCode(), httpResponse.body())); + + try { + return futureResult.get(); + } catch (InterruptedException | ExecutionException exp) { + throw new APIResponseException(exp.getMessage(), exp); + } + } + + /** + * Retrieve detailed information about the {@link Waifu} by sending request to API + * + * @param waifuId The id of the {@link Waifu} + * @return {@link Response} of {@link Waifu} + * @throws APIResponseException If {@link APIWrapper} could not return information properly + * @throws APIMapperException If {@link APIMapper} could not correctly {@code deserialize} model + */ + Response getWaifu(String waifuId) throws APIResponseException, APIMapperException { + Result waifuResult = sendGetRequest("waifu/" + waifuId); + return apiMapper.deserialize(waifuResult, Waifu.class); + } + + /** + * Retrieve paginated images from the gallery, in sets of 10, by sending request to API + * + * @param waifuId The id of the {@link Waifu} + * @param pageNum The page number of the gallery + * @return {@link Response} of {@link WaifuImage} + * @throws APIResponseException If {@link APIWrapper} could not return information properly + * @throws APIMapperException If {@link APIMapper} could not correctly {@code deserialize} model + */ + Response> getWaifuImages(String waifuId, String pageNum) throws APIResponseException, APIMapperException { + Result waifuImagesResult = sendGetRequest("waifu/" + waifuId + "/images?page=" + pageNum); + return apiMapper.deserializeToPaginationData(waifuImagesResult, paginationData(WaifuImage.class)); + } + + /** + * Retrieve an array of {@link FilteredWaifu}'s, sorted alphabetically, by sending request to API + * + * @param pageNum The page number of the gallery + * @return {@link Response} of {@link PaginationData} with {@link FilteredWaifu} + * @throws APIResponseException If {@link APIWrapper} could not return information properly + * @throws APIMapperException If {@link APIMapper} could not correctly {@code deserialize} model + */ + Response> getWaifusByPage(String pageNum) throws APIResponseException, APIMapperException { + Result waifusByPageResult = sendGetRequest("waifu?page=" + pageNum); + return apiMapper.deserializeToPaginationData(waifusByPageResult, paginationData(FilteredWaifu.class)); + } + + /** + * Retrieve the Waifu of the Day by sending request to API + * + * @return {@link Response} of {@link FilteredWaifu} + * @throws APIResponseException If {@link APIWrapper} could not return information properly + * @throws APIMapperException If {@link APIMapper} could not correctly {@code deserialize} model + */ + Response getDailyWaifu() throws APIResponseException, APIMapperException { + Result dailyWaifuResult = sendGetRequest("meta/daily"); + return apiMapper.deserialize(dailyWaifuResult, FilteredWaifu.class); + } + + /** + * Retrieve a Random Waifu from the Website by sending request to API + * + * @return {@link Response} of {@link FilteredWaifu} + * @throws APIResponseException If {@link APIWrapper} could not return information properly + * @throws APIMapperException If {@link APIMapper} could not correctly {@code deserialize} model + */ + Response getRandomWaifu() throws APIResponseException, APIMapperException { + Result randomWaifuResult = sendGetRequest("meta/random"); + return apiMapper.deserialize(randomWaifuResult, FilteredWaifu.class); + } + + /** + * Retrieve a List of Currently Airing Anim by sending request to API + * + * @return {@link Response} of {@link List} with {@link FilteredSeries} + * @throws APIResponseException If {@link APIWrapper} could not return information properly + * @throws APIMapperException If {@link APIMapper} could not correctly {@code deserialize} model + */ + Response> getSeasonalAnime() throws APIResponseException, APIMapperException { + Result seasonalAnimeResult = sendGetRequest("airing"); + return apiMapper.deserializeToList(seasonalAnimeResult, listOf(FilteredSeries.class)); + } + + /** + * Retrieve the Best Waifus of the Current Season by sending request to API + * + * @return {@link Response} of {@link List} with {@link FilteredWaifu} + * @throws APIResponseException If {@link APIWrapper} could not return information properly + * @throws APIMapperException If {@link APIMapper} could not correctly {@code deserialize} model + */ + Response> getBestWaifus() throws APIResponseException, APIMapperException { + Result waifuResults = sendGetRequest("airing/best"); + return apiMapper.deserializeToList(waifuResults, listOf(FilteredWaifu.class)); + } + + /** + * Retrieve a List of Popular Waifus (Raw Count of Total Votes) of the Current Season + * by sending request to API + * + * @return {@link Response} of {@link List} with {@link FilteredWaifu} + * @throws APIResponseException If {@link APIWrapper} could not return information properly + * @throws APIMapperException If {@link APIMapper} could not correctly {@code deserialize} model + */ + Response> getPopularWaifus() throws APIResponseException, APIMapperException { + Result waifuResults = sendGetRequest("airing/popular"); + return apiMapper.deserializeToList(waifuResults, listOf(FilteredWaifu.class)); + } + + /** + * Retrieve the Most Disliked Waifus of the Current Season by sending request to API + * + * @return {@link Response} of {@link List} with {@link FilteredWaifu} + * @throws APIResponseException If {@link APIWrapper} could not return information properly + * @throws APIMapperException If {@link APIMapper} could not correctly {@code deserialize} model + */ + Response> getTrashWaifus() throws APIResponseException, APIMapperException { + Result waifuResults = sendGetRequest("airing/trash"); + return apiMapper.deserializeToList(waifuResults, listOf(FilteredWaifu.class)); + } + + /** + * Retrieve detailed information about a given {@link Series} by sending request to API + * + * @param seriesId The id of the {@link Series} + * @return {@link Response} of {@link Series} + * @throws APIResponseException If {@link APIWrapper} could not return information properly + * @throws APIMapperException If {@link APIMapper} could not correctly {@code deserialize} model + */ + Response getSeries(String seriesId) throws APIResponseException, APIMapperException { + Result seriesResult = sendGetRequest("series/" + seriesId); + return apiMapper.deserialize(seriesResult, Series.class); + } + + /** + * Retrieve paginated information about a Series by sending request to API + * + * @param pageNum The page number of the gallery + * @return {@link Response} of {@link PaginationData} with {@link FilteredSeries} + * @throws APIResponseException If {@link APIWrapper} could not return information properly + * @throws APIMapperException If {@link APIMapper} could not correctly {@code deserialize} model + */ + Response> getSeriesByPage(String pageNum) throws APIResponseException, APIMapperException { + Result seriesPageResult = sendGetRequest("series?page=" + pageNum); + return apiMapper.deserializeToPaginationData(seriesPageResult, paginationData(FilteredSeries.class)); + } + + /** + * Retrieve the List of Anime that Aired in a given Season and Year by sending request to API + * + * @param season The specified season from {@link Season} + * @param year The specified year + * @return {@link Response} of {@link List} with {@link FilteredSeries} + * @throws APIResponseException If {@link APIWrapper} could not return information properly + * @throws APIMapperException If {@link APIMapper} could not correctly {@code deserialize} model + */ + Response> getAllSeries(Season season, Integer year) throws APIResponseException, APIMapperException { + Result allSeriesResult = sendGetRequest("airing/" + season.getSeason() + "/" + year); + return apiMapper.deserializeToList(allSeriesResult, listOf(FilteredSeries.class)); + } + + /** + * Retrieve a set of Waifus for a given {@link Series} by sending request to API + * + * @param seriesId The id of the {@link Series} + * @return {@link Response} of {@link List} with {@link FilteredWaifu} + * @throws APIResponseException If {@link APIWrapper} could not return information properly + * @throws APIMapperException If {@link APIMapper} could not correctly {@code deserialize} model + */ + Response> getSeriesWaifus(String seriesId) throws APIResponseException, APIMapperException { + Result allWaifusFromSeriesResults = sendGetRequest("series/" + seriesId + "/waifus"); + return apiMapper.deserializeToList(allWaifusFromSeriesResults, listOf(FilteredWaifu.class)); + } + + /** + * Retrieve information about the {@link User} by sending request to API + * + * @param userId The id of the {@link User} + * @return {@link Response} of {@link User} + * @throws APIResponseException If {@link APIWrapper} could not return information properly + * @throws APIMapperException If {@link APIMapper} could not correctly {@code deserialize} model + */ + Response getUserProfile(String userId) throws APIResponseException, APIMapperException { + Result userProfileResult = sendGetRequest("user/" + userId); + return apiMapper.deserialize(userProfileResult, User.class); + } + + /** + * Retrieve the Waifus Created, Liked, or Trashed for the given {@link User} id by sending request to API + * + * @param userId The id of the {@link User} + * @param listType The specified action E.g {@link WaifuListType#LIKED} + * @param pageNum The page number of the gallery + * @return {@link Response} of {@link PaginationData} with {@link FilteredWaifu} + * @throws APIResponseException If {@link APIWrapper} could not return information properly + * @throws APIMapperException If {@link APIMapper} could not correctly {@code deserialize} model + */ + Response> getUserWaifus(String userId, String listType, String pageNum) throws APIResponseException, APIMapperException { + Result userWaifusResult = sendGetRequest("user/" + userId + "/" + listType + "?page=" + pageNum); + return apiMapper.deserializeToPaginationData(userWaifusResult, paginationData(FilteredWaifu.class)); + } + + /** + * Retrieve a List of all {@link UserList}'s shown by sending request to API + * + * @param userId The id of the {@link User} + * @return {@link Response} of {@link List} with {@link UserList} + * @throws APIResponseException If {@link APIWrapper} could not return information properly + * @throws APIMapperException If {@link APIMapper} could not correctly {@code deserialize} model + */ + Response> getUserLists(String userId) throws APIResponseException, APIMapperException { + Result userProfileResult = sendGetRequest("user/" + userId + "/lists"); + return apiMapper.deserializeToList(userProfileResult, listOf(UserList.class)); + } + + /** + * Retrieve the Specific {@link UserList}, with {@link Waifu}'s by sending request to API + * + * @param userId The id of the {@link User} + * @param listId The id of the {@link UserList} + * @return {@link Response} of {@link UserList} + * @throws APIResponseException If {@link APIWrapper} could not return information properly + * @throws APIMapperException If {@link APIMapper} could not correctly {@code deserialize} model + */ + Response getUserList(String userId, String listId) throws APIResponseException, APIMapperException { + Result userProfileResult = sendGetRequest("user/" + userId + "/lists/" + listId); + return apiMapper.deserialize(userProfileResult, UserList.class); + } + + /** + * Retrieve a {@link List} of {@link FilteredWaifu} with a search term by sending a POST request to the API + * + * @param searchString {@link String} that should be searched for + * @return {@link Response} of {@link List} with {@link FilteredWaifu} + * @throws APIResponseException If {@link APIWrapper} could not return information properly + * @throws APIMapperException If {@link APIMapper} could not correctly {@code deserialize} model + */ + Response> betaSearch(String searchString) throws APIMapperException, APIResponseException { + Result betaSearchResult = sendPostRequest("search/beta", Map.of("term", searchString)); + return apiMapper.deserializeToList(betaSearchResult, listOf(FilteredWaifu.class)); + } + + /** + * Retrieve a List of {@link FilteredWaifu}'s given a query, by sending POST request to API + * + * @param waifuName The name of the Waifu + * @return {@link Response} of {@link List} with {@link FilteredWaifu} + * @throws APIResponseException If {@link APIWrapper} could not return information properly + * @throws APIMapperException If {@link APIMapper} could not correctly {@code deserialize} model + */ + Response> searchWaifus(String waifuName) throws APIMapperException, APIResponseException { + Result searchWaifusResult = sendPostRequest("search/waifus", Map.of("term", waifuName)); + return apiMapper.deserializeToList(searchWaifusResult, listOf(FilteredWaifu.class)); + } + + /** + * Retrieve a List of {@link FilteredSeries}'s given a query, by sending POST request to API + * + * @param seriesName The name of the Series + * @return {@link Response} of {@link List} with {@link FilteredSeries} + * @throws APIResponseException If {@link APIWrapper} could not return information properly + * @throws APIMapperException If {@link APIMapper} could not correctly {@code deserialize} model + */ + Response> searchSeries(String seriesName) throws APIMapperException, APIResponseException { + Result searchSeriesResult = sendPostRequest("search/series", Map.of("term", seriesName)); + return apiMapper.deserializeToList(searchSeriesResult, listOf(FilteredSeries.class)); + } + + void setApiKey(String apiKey) { + this.apiKey = apiKey; + } + + void setApiMapper(APIMapper apiMapper) { + this.apiMapper = apiMapper; + } } diff --git a/src/main/java/me/goudham/exception/APIMapperException.java b/src/main/java/me/goudham/exception/APIMapperException.java index 9e5dd04..e44e225 100644 --- a/src/main/java/me/goudham/exception/APIMapperException.java +++ b/src/main/java/me/goudham/exception/APIMapperException.java @@ -1,10 +1,9 @@ package me.goudham.exception; -import me.goudham.APIWrapper; import me.goudham.Response; /** - * Thrown when {@link APIWrapper} fails to deserialize json into Java POJO's ({@link Response#getModel()}) + * Thrown when {@code APIWrapper} fails to deserialize json into Java POJO's ({@link Response#getModel()}) * */ public class APIMapperException extends Throwable { diff --git a/src/main/java/me/goudham/exception/APIResponseException.java b/src/main/java/me/goudham/exception/APIResponseException.java index f1a3439..018e513 100644 --- a/src/main/java/me/goudham/exception/APIResponseException.java +++ b/src/main/java/me/goudham/exception/APIResponseException.java @@ -1,9 +1,7 @@ package me.goudham.exception; -import me.goudham.APIWrapper; - /** - * Thrown when {@link APIWrapper} fails to return API information + * Thrown when {@code APIWrapper} fails to return API information * */ public class APIResponseException extends Throwable {