From d79449cb7ad0174e0bd9d3f2ce5aa042d6f42280 Mon Sep 17 00:00:00 2001 From: GeKoppe Date: Tue, 31 Mar 2026 18:57:33 +0200 Subject: [PATCH 1/6] Documentation --- Readme.md | 106 +++++++++++++++++++---------------------------------- doc/use.md | 88 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 125 insertions(+), 69 deletions(-) create mode 100644 doc/use.md diff --git a/Readme.md b/Readme.md index 87e3c7b..6931120 100644 --- a/Readme.md +++ b/Readme.md @@ -12,93 +12,61 @@ Provides convenience functionality to query every endpoint in the Epub Library. # Using it -## Creating a client +See [usage description](/doc/use.md) for detailed examples. -Use the provided factory methods to initialise a new client. +## Gradle -```Java -EpubClient client = EpubClientFactory.newDefaultClient(""); -``` - -There are also other factory methods for different kinds of clients - -## Caching credentials - -Every entity queriable in the api is cacheable. Credentials are not special in this regard, though they are special in the way that caching them is highly recommended. - -The Epub Library API works with JSON Web Tokens. Those tokens expire after some time, not reusing them creates a lot of unnecessary traffic, as every operation needs a new login though. +First add the following in the `repositories` block in your `build.gradle`: -To make caching easier, the `EpubClient` does it automatically, if you configure it that way. - -The simples way to create a client that caches credentials is using the factory method `EpubClientFactory.newCredentialCacheClient(String)` and saving your credentials to the cache: - -```Java -EpubClient client = EpubClientFactory.newCredentialCacheClient(""); -client.cacheValue(CacheType.CREDENTIALS, CredentialCacheKeys.USER, "username"); -client.cacheValue(CacheType.CREDENTIALS, CredentialCacheKeys.PASSWORD, "pw"); +```Gradle +repositories { + maven { + name = "github" + url = 'https://maven.pkg.github.com/GeKoppe/epub_library-client' + credentials { + username = findProperty('gpr.user') ?: '' + password = findProperty('gpr.key') ?: '' + } +} ``` -Afterwards every operation will be automatically authenticated against the api. - -## Querying - -For every endpoint, there are two convenience methods in the EpubClient class to query said endpoint. One for clients that cache credentials, the other one for creating a new session every time. It is recommended to use a client that caches credentials in order to not create too many json web tokens. +Your GitHub credentials must be stored in the `~/.gradle/settings.gradle` file for this to work. -### Example of getting an entity +Then add the dependency: -Querying an entity is as simple as calling it's respective `.get` method in the `EpubClient`. This example will demonstrate that with an Epub, it works the same with every other entity though. - -To get an epub for a specified id, you can just call `EpubClient.getEpub(long, HttpQuery)`. Depending on whether your client caches credentials or not, you can also call `EpubClient.getEpub(String, String, long, HttpQuery)` and provide username and password. - -The `HttpQuery` parameter is used to define what parts of the given entity is returned (e.g. just the basics; authors; genres etc.). For every entity, a builder class for Http queries exist to simplify the filtering. - -This is an example for getting the epub with id 1, including all authors and genres, with a client that does not cache the credentials: - -```Java -EpubClient client = EpubClientFactory.newDefaultClient(""); - -HttpQuery query = new EpubQueryBuilder() - .withAuthors(true) - .withGenres(true) - .build(); - -try { - // Contains epub info, authors and genres - EpubDto epub = client.getEpub("user", "password", 1L, query); -} catch (Exception ex) { - // If the api call fails, an exception representing the reason is thrown +```Gradle +dependencies { + implementation 'org.koppe.epub.client:epub-lib-client:' } ``` -## Caching - -Caching has been discussed in the chapter [Caching Credentials](#caching-credentials). Other types of entities might be cached as well though. This will again be demonstrated with epubs but works the same with every other entity too. +## Maven -If you just want a default cache (15 minute retention of entities, no refresh except for credentials), just use the provided factory method: +Add the following to your `pom.xml`: -```Java -EpubClient cachingClient = EpubClientFactory.newCachingClient("url", new CacheType[]{ CacheType.EPUBS, CacheType.CREDENTIALS }); +```XML + + + github + https://maven.pkg.github.com/GeKoppe/epub_library-client + + ``` -Before and after every call, the client will check the corresponding cache to see, whether an entity already exists, needs to be updated or deleted. - -If you want custom caches in your client, you can also register a new cache manually: +Your GitHub credentials must be stored in the `~/.m2/settings.xml` file for this to work. -```Java -EpubClient client = EpubClientFactory.newDefaultClient("url"); +Then add the following dependency: -EpubCache cache = new EpubCache(); -cache.setMaxElements(10); // Set maximum number of elements in cache -cache.setRetention(10L, TimeUnit.MINUTES); // Set time after which elements are ejected or refreshed -cache.refreshFunction((key) -> { - // Some custom refresh logic -}); - -client.registerCache(CacheType.EPUBS, cache); +```XML + + + org.koppe.epub.client + epub-lib-client + [version-number] + + ``` -If you now do an epub operation, the client will use the cache you supplied. - # Changelog diff --git a/doc/use.md b/doc/use.md new file mode 100644 index 0000000..aa0e58c --- /dev/null +++ b/doc/use.md @@ -0,0 +1,88 @@ +# How to use + +## Creating a client + +Use the provided factory methods to initialise a new client. + +```Java +EpubClient client = EpubClientFactory.newDefaultClient(""); +``` + +There are also other factory methods for different kinds of clients + +## Caching credentials + +Every entity queriable in the api is cacheable. Credentials are not special in this regard, though they are special in the way that caching them is highly recommended. + +The Epub Library API works with JSON Web Tokens. Those tokens expire after some time, not reusing them creates a lot of unnecessary traffic, as every operation needs a new login though. + +To make caching easier, the `EpubClient` does it automatically, if you configure it that way. + +The simples way to create a client that caches credentials is using the factory method `EpubClientFactory.newCredentialCacheClient(String)` and saving your credentials to the cache: + +```Java +EpubClient client = EpubClientFactory.newCredentialCacheClient(""); +client.cacheValue(CacheType.CREDENTIALS, CredentialCacheKeys.USER, "username"); +client.cacheValue(CacheType.CREDENTIALS, CredentialCacheKeys.PASSWORD, "pw"); +``` + +Afterwards every operation will be automatically authenticated against the api. + +## Querying + +For every endpoint, there are two convenience methods in the EpubClient class to query said endpoint. One for clients that cache credentials, the other one for creating a new session every time. It is recommended to use a client that caches credentials in order to not create too many json web tokens. + +### Example of getting an entity + +Querying an entity is as simple as calling it's respective `.get` method in the `EpubClient`. This example will demonstrate that with an Epub, it works the same with every other entity though. + +To get an epub for a specified id, you can just call `EpubClient.getEpub(long, HttpQuery)`. Depending on whether your client caches credentials or not, you can also call `EpubClient.getEpub(String, String, long, HttpQuery)` and provide username and password. + +The `HttpQuery` parameter is used to define what parts of the given entity is returned (e.g. just the basics; authors; genres etc.). For every entity, a builder class for Http queries exist to simplify the filtering. + +This is an example for getting the epub with id 1, including all authors and genres, with a client that does not cache the credentials: + +```Java +EpubClient client = EpubClientFactory.newDefaultClient(""); + +HttpQuery query = new EpubQueryBuilder() + .withAuthors(true) + .withGenres(true) + .build(); + +try { + // Contains epub info, authors and genres + EpubDto epub = client.getEpub("user", "password", 1L, query); +} catch (Exception ex) { + // If the api call fails, an exception representing the reason is thrown +} +``` + +## Caching + +Caching has been discussed in the chapter [Caching Credentials](#caching-credentials). Other types of entities might be cached as well though. This will again be demonstrated with epubs but works the same with every other entity too. + +If you just want a default cache (15 minute retention of entities, no refresh except for credentials), just use the provided factory method: + +```Java +EpubClient cachingClient = EpubClientFactory.newCachingClient("url", new CacheType[]{ CacheType.EPUBS, CacheType.CREDENTIALS }); +``` + +Before and after every call, the client will check the corresponding cache to see, whether an entity already exists, needs to be updated or deleted. + +If you want custom caches in your client, you can also register a new cache manually: + +```Java +EpubClient client = EpubClientFactory.newDefaultClient("url"); + +EpubCache cache = new EpubCache(); +cache.setMaxElements(10); // Set maximum number of elements in cache +cache.setRetention(10L, TimeUnit.MINUTES); // Set time after which elements are ejected or refreshed +cache.refreshFunction((key) -> { + // Some custom refresh logic +}); + +client.registerCache(CacheType.EPUBS, cache); +``` + +If you now do an epub operation, the client will use the cache you supplied. \ No newline at end of file From 94d64406a689a9d4674a0169d21db0bb4a89eee3 Mon Sep 17 00:00:00 2001 From: GeKoppe Date: Thu, 2 Apr 2026 12:13:17 +0200 Subject: [PATCH 2/6] Unit tests --- .../org/koppe/epub/client/EpubAdapter.java | 12 ++++-- .../client/EpubClientCommunicationTest.java | 37 ++++++++++++++++++ .../org/koppe/epub/client/MockDispatcher.java | 33 ++++++++++++++++ lib/src/test/resources/epubs/test-cover.png | Bin 0 -> 5661 bytes 4 files changed, 79 insertions(+), 3 deletions(-) create mode 100644 lib/src/test/resources/epubs/test-cover.png diff --git a/lib/src/main/java/org/koppe/epub/client/EpubAdapter.java b/lib/src/main/java/org/koppe/epub/client/EpubAdapter.java index 695020c..e20c53c 100644 --- a/lib/src/main/java/org/koppe/epub/client/EpubAdapter.java +++ b/lib/src/main/java/org/koppe/epub/client/EpubAdapter.java @@ -563,6 +563,7 @@ public void upload(@NotNull String jwt, @NotNull String uploadGuid, @NotNull Fil throw new IOException(ex); } + logger.debug("Download file created, writing file stream into download file"); try (InputStream is = response.body().byteStream(); OutputStream os = new FileOutputStream(downloaded)) { byte[] buffer = new byte[8192]; int bytesRead; @@ -570,6 +571,7 @@ public void upload(@NotNull String jwt, @NotNull String uploadGuid, @NotNull Fil os.write(buffer, 0, bytesRead); } } + logger.info("Successfull wrote body into file " + downloaded); return downloaded; } catch (IOException ex) { // TODO throw sensible exceptions @@ -615,21 +617,25 @@ public void upload(@NotNull String jwt, @NotNull String uploadGuid, @NotNull Fil logger.info("Could not determine a file name, using default"); fileName = "epub.epub"; } - logger.debug("Determined file name \"" + fileName + "\""); - File dl = new File(downloadDirectory.getAbsolutePath() + "/" + fileName); + String extension = fileName.substring(fileName.lastIndexOf(".")); + fileName = fileName.substring(0, fileName.lastIndexOf(".")); + + File dl = new File(downloadDirectory.getAbsolutePath() + "/" + fileName + extension); if (dl.exists()) { + logger.debug("Filename already exists in download folder, adding iterator"); int iterator = 0; while (dl.exists()) { iterator++; if (iterator >= 1000) { throw new IOException("Too many epubs with given name downloaded"); } - dl = new File(downloadDirectory.getAbsolutePath() + "/" + fileName + "(" + iterator + ")"); + dl = new File(downloadDirectory.getAbsolutePath() + "/" + fileName + " (" + iterator + ")" + extension); } } dl.createNewFile(); + logger.info("File {} created", dl); return dl; } diff --git a/lib/src/test/java/org/koppe/epub/client/EpubClientCommunicationTest.java b/lib/src/test/java/org/koppe/epub/client/EpubClientCommunicationTest.java index e5edd32..da8c4a5 100644 --- a/lib/src/test/java/org/koppe/epub/client/EpubClientCommunicationTest.java +++ b/lib/src/test/java/org/koppe/epub/client/EpubClientCommunicationTest.java @@ -390,6 +390,43 @@ public void testUpload() { } } + // #region download + @Test + public void testDownload() { + server.setDispatcher(new MockDispatcher()); + EpubClient client = EpubClientFactory.newCredentialCacheClient(server.url("/").toString()); + + File downloadFolder = new File(System.getProperty("java.io.tmpdir")); + File epub = null; + File epub2 = null; + File cover = null; + File cover2 = null; + + try { + epub = client.download("admin", "admin", "123", downloadFolder, false); + epub2 = client.download("123", downloadFolder, false); + cover = client.download("123", downloadFolder, true); + cover2 = client.download("123", downloadFolder, true); + assertNotNull(epub); + assertNotNull(epub2); + assertNotNull(cover); + assertNotNull(cover2); + assertTrue(epub2.getName().contains("(1)")); + assertTrue(cover2.getName().contains("(1)")); + } catch (Exception ex) { + fail(); + } finally { + if (epub.exists()) + epub.delete(); + if (epub2.exists()) + epub2.delete(); + if (cover.exists()) + cover.delete(); + if (cover2.exists()) + cover2.delete(); + } + } + // #region add author @Test public void testAddAuthor() { diff --git a/lib/src/test/java/org/koppe/epub/client/MockDispatcher.java b/lib/src/test/java/org/koppe/epub/client/MockDispatcher.java index 11e3ddd..5856784 100644 --- a/lib/src/test/java/org/koppe/epub/client/MockDispatcher.java +++ b/lib/src/test/java/org/koppe/epub/client/MockDispatcher.java @@ -74,6 +74,13 @@ public MockResponse dispatch(RecordedRequest request) throws InterruptedExceptio default: return new MockResponse().setResponseCode(403); } + case "/epubs/download": + switch (request.getMethod()) { + case "GET": + return download(request); + default: + return new MockResponse().setResponseCode(403); + } case "/authors": switch (request.getMethod()) { case "POST": @@ -208,6 +215,7 @@ private MockResponse getAllEpubs(RecordedRequest r) { return new MockResponse().setResponseCode(200).setBody(mapper.writeValueAsString(response)); } + // #region uplaod private MockResponse upload(RecordedRequest r) { if (!r.getRequestUrl().queryParameter("upload-guid").equals("123")) { return new MockResponse().setResponseCode(400); @@ -251,6 +259,31 @@ private MockResponse upload(RecordedRequest r) { return new MockResponse().setResponseCode(400); } + // #region download + private MockResponse download(RecordedRequest r) { + if (!r.getRequestUrl().queryParameter("download-guid").equals("123")) { + return new MockResponse().setResponseCode(400); + } + + try { + if (r.getRequestUrl().queryParameter("cover") != null + && r.getRequestUrl().queryParameter("cover").equals("true")) { + byte[] fileContent = getClass().getClassLoader().getResourceAsStream("epubs/test-cover.png") + .readAllBytes(); + return new MockResponse().setResponseCode(200).setHeader("Content-Type", "application/octet-stream") + .setHeader("Content-Disposition", "attachment; filename=\"test-cover.png\"") + .setBody(new String(fileContent)); + } else { + byte[] fileContent = getClass().getClassLoader().getResourceAsStream("epubs/test.epub").readAllBytes(); + return new MockResponse().setResponseCode(200).setHeader("Content-Type", "application/octet-stream") + .setHeader("Content-Disposition", "attachment; filename=\"test.epub\"") + .setBody(new String(fileContent)); + } + } catch (Exception ex) { + return new MockResponse().setResponseCode(500); + } + } + // #region add author private MockResponse addAuthor(RecordedRequest r) { AuthorDto dto = getBody(r.getBody(), AuthorDto.class); diff --git a/lib/src/test/resources/epubs/test-cover.png b/lib/src/test/resources/epubs/test-cover.png new file mode 100644 index 0000000000000000000000000000000000000000..c5d5543992e7fe2d87aa1033ed95cb053fbde142 GIT binary patch literal 5661 zcmeHK`&ScJ5S|1S!b1@R6lsiF&^AhiD4@Io#RiL_q6DP~N+?kRDh(JYuV_W|7(m-9 zZ-S`R$|Hq<$fLjkbX7dq$cNfw`3!5ADpDkL!%z)rLQXe-8>v+X&u>d3OY91r)REt$BL z4CSe_syv)^*Mtd~xji?cD-=oTO&dbutWHSt_^ArV%d+mYb;zax#1Z6ut{NBS;G59o zNIh7yh>dP~A&yL3+dURnCpwkY@7xn1cJ|^;;;-EA2S+{2>V z=Gr_KYpL6wNbWchlcS#cX804orrP$?I@5+TXZB-W#MC{)M+>PUST%4;{A6wV6Q>KK85<43OA>{X(* zL%x8vV5~+YfesN8j+D8mnzIfW(_<@!tNU5^8y_ z)7MXSY!(+K*ZbVRcK*9AE{dayHnP-$MI~%L(t3PwBhgm1d)EROsh%s0dhA1ej-{Y(76JoPdRoZ@0mIeT89stZYR@&SJVG z=AtNVo$_}4eoFf1AV;ba`I+4Jla3%@&ALa1iKNkYY8YR_$7tU|OOq)!vz9s`J4n0R znLTa17oqj3kst>PyQqu@cKlckr(ZL`%@$W8kE85_Jx1i*vU>%YIH%l-y-cgC(hr*y z1N5-fkGhp(joCTPm1jsiBq(5VDYK>DQzFwu$@!G44T_|R+kwVV>Wk*ZXVgU>dM2pb z$!{0Ny*Gol-P+zfr#<9C{L2fqjt39TD`k}bg3^Z##t;%0OBYpIva)kdXC=vEJ+Q|a z7qtLl`wNEg`86_= TYE{sQ0tj2T1o&3@960$m?ADk7 literal 0 HcmV?d00001 From 6188dc3157d24032173d5a44f2a3d609d0349027 Mon Sep 17 00:00:00 2001 From: GeKoppe Date: Thu, 2 Apr 2026 12:32:29 +0200 Subject: [PATCH 3/6] Unit test --- .../org/koppe/epub/client/EpubClient.java | 21 +++++++++++++++ .../client/EpubClientCommunicationTest.java | 27 ++++++++++++++++++- .../org/koppe/epub/client/MockDispatcher.java | 21 +++++++++++++++ 3 files changed, 68 insertions(+), 1 deletion(-) diff --git a/lib/src/main/java/org/koppe/epub/client/EpubClient.java b/lib/src/main/java/org/koppe/epub/client/EpubClient.java index ad4e474..a425fc0 100644 --- a/lib/src/main/java/org/koppe/epub/client/EpubClient.java +++ b/lib/src/main/java/org/koppe/epub/client/EpubClient.java @@ -1096,6 +1096,27 @@ private void uploadEpub(@NotNull String jwt, @NotNull String uploadGuid, @NotNul } // #endregion get author + // #region delete author + public @Nullable AuthorDto deleteAuthor(@NotNull String username, @NotNull String password, long authorId, + boolean deleteWithBooks) + throws ApiCallException, SessionExpiredException, IllegalArgumentException, BadRequestException { + return deleteAuthor(getNewJwt(username, password), authorId, deleteWithBooks); + } + + public @Nullable AuthorDto deleteAuthor(long authorId, boolean deleteWithBooks) + throws CacheMissException, ApiCallException, SessionExpiredException, IllegalArgumentException, + BadRequestException { + return deleteAuthor(getCurrentJwt(), authorId, deleteWithBooks); + } + + private @Nullable AuthorDto deleteAuthor(@NotNull String jwt, long authorId, boolean deleteWithBooks) + throws IllegalArgumentException, SessionExpiredException, ApiCallException, BadRequestException { + if (authors == null) + authors = new AuthorAdapter(this); + return authors.deleteAuthor(jwt, authorId, deleteWithBooks); + } + // #endregion delete author + // #region register cache /** * Adds a new cache type to the clients internal caches, if such a cache type is diff --git a/lib/src/test/java/org/koppe/epub/client/EpubClientCommunicationTest.java b/lib/src/test/java/org/koppe/epub/client/EpubClientCommunicationTest.java index da8c4a5..1360587 100644 --- a/lib/src/test/java/org/koppe/epub/client/EpubClientCommunicationTest.java +++ b/lib/src/test/java/org/koppe/epub/client/EpubClientCommunicationTest.java @@ -466,6 +466,7 @@ public void testAddAuthor() { assertNotNull(added.getId()); } + // #region get author @Test public void testGetAuthor() { server.setDispatcher(new MockDispatcher()); @@ -485,7 +486,31 @@ public void testGetAuthor() { assertEquals("Test2", a2.getFirstName()); assertTrue(a2.getEpubs().size() == 0); } catch (Exception ex) { - fail(); + fail(ex.getMessage()); + } + } + + @Test + public void testDeleteAuthor() { + server.setDispatcher(new MockDispatcher()); + EpubClient client = EpubClientFactory.newCredentialCacheClient(server.url("/").toString()); + + try { + AuthorDto dto = null; + dto = client.deleteAuthor("admin", "admin", 3, false); + assertNull(dto); + + dto = client.deleteAuthor(1, false); + assertNotNull(dto); + assertEquals("Test", dto.getFirstName()); + + dto = client.deleteAuthor(2, true); + assertNotNull(dto); + assertEquals("Test2", dto.getFirstName()); + assertEquals(2, dto.getEpubs().size()); + } catch (IllegalArgumentException | ApiCallException | SessionExpiredException | BadRequestException + | CacheMissException e) { + fail(e.getMessage()); } } } diff --git a/lib/src/test/java/org/koppe/epub/client/MockDispatcher.java b/lib/src/test/java/org/koppe/epub/client/MockDispatcher.java index 5856784..da0ea3a 100644 --- a/lib/src/test/java/org/koppe/epub/client/MockDispatcher.java +++ b/lib/src/test/java/org/koppe/epub/client/MockDispatcher.java @@ -92,6 +92,8 @@ public MockResponse dispatch(RecordedRequest request) throws InterruptedExceptio switch (request.getMethod()) { case "GET": return getAuthor(request); + case "DELETE": + return deleteAuthor(request); default: return new MockResponse().setResponseCode(403); } @@ -328,6 +330,25 @@ else if (r.getRequestUrl().queryParameter("with_tags").equals("true")) { return new MockResponse().setResponseCode(200).setBody(mapper.writeValueAsString(dto)); } + // #region delete author + private MockResponse deleteAuthor(RecordedRequest r) { + AuthorDto dto = null; + if (r.getRequestUrl().toString().contains("/1")) + dto = DtoRecord.author1; + else if (r.getRequestUrl().toString().contains("/2")) + dto = DtoRecord.author2; + else + return new MockResponse().setResponseCode(404); + + if (r.getRequestUrl().queryParameter("with_epubs") != null + && r.getRequestUrl().queryParameter("with_epubs").equals("true")) { + dto.setEpubs(List.of(DtoRecord.epub1, DtoRecord.epub2)); + } else { + dto.setEpubs(new ArrayList<>()); + } + return new MockResponse().setResponseCode(200).setBody(mapper.writeValueAsString(dto)); + } + // #region get body private T getBody(Buffer buffer, Class expected) { try { From 0e757bfe528d779042120964887140600aca30ae Mon Sep 17 00:00:00 2001 From: GeKoppe Date: Wed, 15 Apr 2026 19:29:13 +0200 Subject: [PATCH 4/6] Added more tests and author actions --- .../org/koppe/epub/client/AuthorAdapter.java | 40 ++-- .../org/koppe/epub/client/EpubAdapter.java | 61 ++--- .../org/koppe/epub/client/EpubClient.java | 213 +++++++++++------- .../epub/client/cache/AbstractCache.java | 16 ++ .../koppe/epub/client/cache/AuthorCache.java | 4 + .../org/koppe/epub/client/cache/Cache.java | 11 + .../koppe/epub/client/cache/CacheFactory.java | 9 + .../koppe/epub/client/cache/CacheType.java | 55 ++++- ...ption.java => AuthorizationException.java} | 4 +- .../koppe/epub/client/AuthorAdapterTest.java | 6 +- .../koppe/epub/client/EpubAdapterTest.java | 12 +- .../client/EpubClientCommunicationTest.java | 22 +- 12 files changed, 291 insertions(+), 162 deletions(-) rename lib/src/main/java/org/koppe/epub/client/exceptions/{SessionExpiredException.java => AuthorizationException.java} (51%) diff --git a/lib/src/main/java/org/koppe/epub/client/AuthorAdapter.java b/lib/src/main/java/org/koppe/epub/client/AuthorAdapter.java index 64f5d23..876ebd8 100644 --- a/lib/src/main/java/org/koppe/epub/client/AuthorAdapter.java +++ b/lib/src/main/java/org/koppe/epub/client/AuthorAdapter.java @@ -14,7 +14,7 @@ import org.koppe.epub.client.exceptions.ForbiddenException; import org.koppe.epub.client.exceptions.NotFoundException; import org.koppe.epub.client.exceptions.ServerErrorException; -import org.koppe.epub.client.exceptions.SessionExpiredException; +import org.koppe.epub.client.exceptions.AuthorizationException; import org.koppe.epub.client.exceptions.UnexpectedStatusException; import org.koppe.epub.client.http.AuthorQueryBuilder; import org.koppe.epub.client.http.HttpQuery; @@ -66,11 +66,11 @@ protected AuthorAdapter(EpubClient client) { * @throws IllegalArgumentException If no jwt, author, author.firstName or * author.surname is given. * @throws ApiCallException General wrapper for all unexpected api error - * @throws SessionExpiredException If the jwt has expired + * @throws AuthorizationException If the jwt has expired * @throws BadRequestException If the author dto was invalid. */ protected @Nullable AuthorDto addAuthor(@NotNull String jwt, @NotNull AuthorDto author) - throws IllegalArgumentException, ApiCallException, SessionExpiredException, BadRequestException { + throws IllegalArgumentException, ApiCallException, AuthorizationException, BadRequestException { if (jwt == null || jwt.isBlank()) { logger.info("Invalid jwt given"); throw new IllegalArgumentException("Missing jwt"); @@ -93,7 +93,7 @@ protected AuthorAdapter(EpubClient client) { AuthorDto dto = null; try { dto = client.executeRequest(builder.build(), AuthorDto.class, null, true); - } catch (SessionExpiredException e) { + } catch (AuthorizationException e) { logger.warn("JWT has expired"); throw e; } catch (BadRequestException e) { @@ -123,11 +123,11 @@ protected AuthorAdapter(EpubClient client) { * @param query Defines attributes the api should return, for example whether * books should be returned as well * @return Queried author or null, if no such author exists - * @throws ApiCallException General wrapper for all unexpected api errors - * @throws SessionExpiredException If the jwt has expired + * @throws ApiCallException General wrapper for all unexpected api errors + * @throws AuthorizationException If the jwt has expired */ protected @Nullable AuthorDto getAuthorById(@NotNull String jwt, long authorId, @Nullable HttpQuery query) - throws ApiCallException, SessionExpiredException { + throws ApiCallException, AuthorizationException { if (jwt == null || jwt.isBlank()) { logger.info("Invalid jwt given"); throw new IllegalArgumentException("Missing jwt"); @@ -155,7 +155,7 @@ protected AuthorAdapter(EpubClient client) { | ServerErrorException | UnexpectedStatusException | IOException e) { logger.info("Request failed with an exception", e); throw new ApiCallException(null, e); - } catch (SessionExpiredException ex) { + } catch (AuthorizationException ex) { logger.info("Jwt expired"); throw ex; } catch (NotFoundException ex) { @@ -183,13 +183,13 @@ protected AuthorAdapter(EpubClient client) { * are deleted as well. USE WITH CAUTION. * @return The deleted author or null, if no author with given id exists * @throws IllegalArgumentException If no jwt is given - * @throws SessionExpiredException If the session has expired + * @throws AuthorizationException If the session has expired * @throws ApiCallException If an unexpected error occurred during the * api call. * @throws BadRequestException If the server returned 400 */ protected @Nullable AuthorDto deleteAuthor(@NotNull String jwt, long authorId, boolean deleteWithBooks) - throws IllegalArgumentException, SessionExpiredException, ApiCallException, BadRequestException { + throws IllegalArgumentException, AuthorizationException, ApiCallException, BadRequestException { if (jwt == null || jwt.isBlank()) { logger.info("Invalid jwt given"); throw new IllegalArgumentException("Missing jwt"); @@ -209,7 +209,7 @@ protected AuthorAdapter(EpubClient client) { AuthorDto dto = null; try { dto = client.executeRequest(builder.build(), AuthorDto.class, query, false); - } catch (SessionExpiredException e) { + } catch (AuthorizationException e) { logger.info("Session has expired", e); throw e; } catch (BadRequestException e) { @@ -235,16 +235,18 @@ protected AuthorAdapter(EpubClient client) { // #region get all authors /** + * Returns all authors matching the given query. If no query is given, all + * authors are returned (maximum 1000, pageable). * - * @param jwt - * @param query - * @return - * @throws IllegalArgumentException - * @throws ApiCallException - * @throws SessionExpiredException + * @param jwt JWT to authorize at the api. + * @param query Query to filter the authors + * @return All found authors + * @throws IllegalArgumentException If jwt is missing + * @throws ApiCallException General wrapper for all api exception + * @throws AuthorizationException If authorization failed */ public @Nullable PagedRequestDto getAllAuthors(@NotNull String jwt, @Nullable HttpQuery query) - throws IllegalArgumentException, ApiCallException, SessionExpiredException { + throws IllegalArgumentException, ApiCallException, AuthorizationException { if (jwt == null || jwt.isBlank()) { logger.info("No jwt given"); throw new IllegalArgumentException("Missing jwt"); @@ -273,7 +275,7 @@ protected AuthorAdapter(EpubClient client) { | ServerErrorException | UnexpectedStatusException | IOException e) { logger.info("Unexpected status returned by api", e); throw new ApiCallException(null, e); - } catch (SessionExpiredException ex) { + } catch (AuthorizationException ex) { logger.info("Session has expired"); throw ex; } diff --git a/lib/src/main/java/org/koppe/epub/client/EpubAdapter.java b/lib/src/main/java/org/koppe/epub/client/EpubAdapter.java index e20c53c..aa6e297 100644 --- a/lib/src/main/java/org/koppe/epub/client/EpubAdapter.java +++ b/lib/src/main/java/org/koppe/epub/client/EpubAdapter.java @@ -20,7 +20,7 @@ import org.koppe.epub.client.exceptions.IllegalFileTypeException; import org.koppe.epub.client.exceptions.NotFoundException; import org.koppe.epub.client.exceptions.ServerErrorException; -import org.koppe.epub.client.exceptions.SessionExpiredException; +import org.koppe.epub.client.exceptions.AuthorizationException; import org.koppe.epub.client.exceptions.UnexpectedStatusException; import org.koppe.epub.client.http.EpubQueryBuilder; import org.koppe.epub.client.http.HttpQuery; @@ -66,14 +66,14 @@ class EpubAdapter { * been given. * @throws ApiCallException If api call itself failed due to an * exception. - * @throws SessionExpiredException If session has expired. If you are working + * @throws AuthorizationException If session has expired. If you are working * without cache, call * {@link EpubClient#refreshLogin(String)} * again, otherwise a call to * {@link EpubClient#refreshLogin()} suffices. */ protected @Nullable EpubDto addEpub(@NotNull String jwt, @NotNull EpubDto epub) - throws IllegalArgumentException, ApiCallException, SessionExpiredException { + throws IllegalArgumentException, ApiCallException, AuthorizationException { if (epub == null || epub.getTitle() == null || epub.getTitle().isBlank()) { logger.info("No valid epub dto given"); throw new IllegalArgumentException("Invalid epub dto, title is missing"); @@ -102,7 +102,7 @@ class EpubAdapter { | IOException ex) { logger.info("Exception occurred in method call"); throw new ApiCallException(null, ex); - } catch (SessionExpiredException ex) { + } catch (AuthorizationException ex) { logger.info("Session has expired"); throw ex; } @@ -125,14 +125,14 @@ class EpubAdapter { * @return The deleted epub * @throws IllegalArgumentException If username or password are missing * @throws ApiCallException If an error occurred during call to the api - * @throws SessionExpiredException If session has expired. If you are working + * @throws AuthorizationException If session has expired. If you are working * without cache, call * {@link EpubClient#refreshLogin(String)} * again, otherwise a call to * {@link EpubClient#refreshLogin()} suffices. */ protected @Nullable EpubDto deleteEpub(@NotNull String jwt, long epubId) - throws IllegalArgumentException, ApiCallException, SessionExpiredException { + throws IllegalArgumentException, ApiCallException, AuthorizationException { if (jwt == null || jwt.isBlank()) { logger.info("Invalid jwt given"); throw new IllegalArgumentException("Jwt is missing"); @@ -154,7 +154,7 @@ class EpubAdapter { } catch (NotFoundException ex) { logger.info("Could not find requested resource"); return null; - } catch (SessionExpiredException ex) { + } catch (AuthorizationException ex) { logger.info("Session expired or login failed"); throw ex; } @@ -177,11 +177,11 @@ class EpubAdapter { * @param epubId Id of the epub to retrieve * @return Retrieved epub or null, if no epub with given id was found * @throws IllegalArgumentException If jwt is missing or blank - * @throws SessionExpiredException If the session credentials are invalid + * @throws AuthorizationException If the session credentials are invalid * @throws ApiCallException General api error exception */ protected @Nullable EpubDto getEpub(@NotNull String jwt, long epubId, HttpQuery query) - throws IllegalArgumentException, SessionExpiredException, ApiCallException { + throws IllegalArgumentException, AuthorizationException, ApiCallException { if (jwt == null || jwt.isBlank()) { logger.info("No jwt given"); throw new IllegalArgumentException("No jwt given"); @@ -213,7 +213,7 @@ class EpubAdapter { } catch (NotFoundException ex) { logger.info("Could not find requested resource"); return null; - } catch (SessionExpiredException ex) { + } catch (AuthorizationException ex) { logger.info("Session expired or login missing"); throw ex; } @@ -237,12 +237,12 @@ class EpubAdapter { * @throws IllegalArgumentException If no username, password, edition or * edition.versionName are given * @throws NotFoundException If no epub with given id exists - * @throws SessionExpiredException If the session has expired + * @throws AuthorizationException If the session has expired * @throws BadRequestException If the given edition is invalid * @throws ApiCallException General api error */ protected @Nullable EpubEditionDto addEpubEdition(@NotNull String jwt, long epubId, @NotNull EpubEditionDto edition) - throws IllegalArgumentException, NotFoundException, SessionExpiredException, BadRequestException, + throws IllegalArgumentException, NotFoundException, AuthorizationException, BadRequestException, ApiCallException { if (jwt == null || jwt.isBlank()) { @@ -268,7 +268,7 @@ class EpubAdapter { } catch (NotFoundException ex) { logger.info("Invalid epub id given"); throw ex; - } catch (SessionExpiredException ex) { + } catch (AuthorizationException ex) { throw ex; } catch (BadRequestException ex) { throw ex; @@ -293,11 +293,11 @@ class EpubAdapter { * @param jwt JWT for querying the api * @param query Http query * @return All epubs matching the specifications - * @throws ApiCallException If an error occurred while querying the api - * @throws SessionExpiredException If the session has expired + * @throws ApiCallException If an error occurred while querying the api + * @throws AuthorizationException If the session has expired */ protected @Nullable PagedRequestDto getEpubsPaged(@NotNull String jwt, @Nullable HttpQuery query) - throws ApiCallException, SessionExpiredException { + throws ApiCallException, AuthorizationException { if (jwt == null || jwt.isBlank()) { logger.info("No jwt given"); throw new IllegalArgumentException("Jwt missing"); @@ -325,7 +325,7 @@ class EpubAdapter { | ServerErrorException ex) { logger.info("Exception occurred during api call", ex); throw new ApiCallException("", ex); - } catch (SessionExpiredException e) { + } catch (AuthorizationException e) { logger.info("Session has expired"); throw e; } @@ -361,7 +361,7 @@ class EpubAdapter { * existing values on epub in the database. * @return Updated epub or null, if epub could not be updated * @throws IllegalArgumentException If no jwt or dto is given - * @throws SessionExpiredException If the session has expired + * @throws AuthorizationException If the session has expired * @throws BadRequestException If the request was malformed (i.e. * overwriteNulls is true but dto.title is * null, as every epub needs a title) @@ -370,7 +370,7 @@ class EpubAdapter { */ protected @Nullable EpubDto updateEpub(@NotNull String jwt, @NotNull EpubDto dto, long epubId, boolean overwriteNulls) - throws IllegalArgumentException, SessionExpiredException, BadRequestException, NotFoundException, + throws IllegalArgumentException, AuthorizationException, BadRequestException, NotFoundException, ApiCallException { if (jwt == null || jwt.isBlank()) { logger.info("No jwt given"); @@ -402,7 +402,7 @@ class EpubAdapter { | ServerErrorException | UnexpectedStatusException | IOException e) { logger.info("Exception occurred in api call", e); throw new ApiCallException(null, e); - } catch (SessionExpiredException ex) { + } catch (AuthorizationException ex) { logger.info("Session has expired", ex); throw ex; } catch (BadRequestException ex) { @@ -435,12 +435,12 @@ class EpubAdapter { * @throws IllegalArgumentException If no jwt, upload guid or file is given * @throws IllegalFileTypeException If file is not an epub * @throws ApiCallException General wrapper for api exception - * @throws SessionExpiredException if the session has expired + * @throws AuthorizationException if the session has expired * @throws BadRequestException If either an invalid file or invalid upload * guid has been given */ public void upload(@NotNull String jwt, @NotNull String uploadGuid, @NotNull File epubFile) - throws IllegalArgumentException, IllegalFileTypeException, ApiCallException, SessionExpiredException, + throws IllegalArgumentException, IllegalFileTypeException, ApiCallException, AuthorizationException, BadRequestException { if (jwt == null || jwt.isBlank()) { logger.info("No jwt given"); @@ -477,7 +477,7 @@ public void upload(@NotNull String jwt, @NotNull String uploadGuid, @NotNull Fil | ServerErrorException | UnexpectedStatusException | IOException e) { logger.info("Exception while querying the api", e); throw new ApiCallException(e.getMessage(), e); - } catch (SessionExpiredException e) { + } catch (AuthorizationException e) { logger.info("Session has expired"); throw e; } catch (BadRequestException e) { @@ -506,13 +506,14 @@ public void upload(@NotNull String jwt, @NotNull String uploadGuid, @NotNull Fil * meaning the download guid is invalid. * @throws ServerErrorException When the server could not provide the * download file. - * @throws SessionExpiredException - * @throws UnexpectedStatusException + * @throws AuthorizationException If the authorization at the api failed + * @throws UnexpectedStatusException If the server responded with an unexpected + * status code */ protected @Nullable File download(@NotNull String jwt, @NotNull String downloadGuid, @NotNull File downlaodDirectory, boolean downloadCover) - throws IllegalArgumentException, BadRequestException, ServerErrorException, SessionExpiredException, + throws IllegalArgumentException, BadRequestException, ServerErrorException, AuthorizationException, UnexpectedStatusException { if (jwt == null || jwt.isBlank()) { logger.info("No jwt given"); @@ -543,7 +544,7 @@ public void upload(@NotNull String jwt, @NotNull String uploadGuid, @NotNull Fil logger.info("Given download guid is invalid"); throw new BadRequestException("Invalid download guid", null); case 401: - throw new SessionExpiredException(); + throw new AuthorizationException(); case 500: logger.info("Server failed to provide download file"); throw new ServerErrorException("Server could not prepare download", null); @@ -649,14 +650,14 @@ public void upload(@NotNull String jwt, @NotNull String uploadGuid, @NotNull Fil * @param editionId Epub edition to be deleted * @return The deleted epub edition * @throws IllegalArgumentException If no jwt is given - * @throws SessionExpiredException If the jwt has expired + * @throws AuthorizationException If the jwt has expired * @throws ApiCallException General exception for all unexpected api * responses * @throws NotFoundException If either the epub edition id or the epub * with the given id do not exist */ protected @Nullable EpubEditionDto deleteEdition(@NotNull String jwt, long epubId, long editionId) - throws IllegalArgumentException, SessionExpiredException, ApiCallException, NotFoundException { + throws IllegalArgumentException, AuthorizationException, ApiCallException, NotFoundException { if (jwt == null || jwt.isBlank()) { logger.info("Invalid jwt given"); throw new IllegalArgumentException("Missing jwt"); @@ -674,7 +675,7 @@ public void upload(@NotNull String jwt, @NotNull String uploadGuid, @NotNull Fil EpubEditionDto deleted = null; try { deleted = client.executeRequest(builder.build(), EpubEditionDto.class, null, false); - } catch (SessionExpiredException e) { + } catch (AuthorizationException e) { logger.info("Session has expired"); throw e; } catch (BadRequestException | ForbiddenException | UnexpectedStatusException | IOException e) { diff --git a/lib/src/main/java/org/koppe/epub/client/EpubClient.java b/lib/src/main/java/org/koppe/epub/client/EpubClient.java index a425fc0..2b7515d 100644 --- a/lib/src/main/java/org/koppe/epub/client/EpubClient.java +++ b/lib/src/main/java/org/koppe/epub/client/EpubClient.java @@ -29,7 +29,7 @@ import org.koppe.epub.client.exceptions.IllegalFileTypeException; import org.koppe.epub.client.exceptions.NotFoundException; import org.koppe.epub.client.exceptions.ServerErrorException; -import org.koppe.epub.client.exceptions.SessionExpiredException; +import org.koppe.epub.client.exceptions.AuthorizationException; import org.koppe.epub.client.exceptions.UnexpectedStatusException; import org.koppe.epub.client.http.HttpQuery; import org.slf4j.Logger; @@ -329,12 +329,12 @@ private V removeFromCache(Cache cache, Object key) throws CachingEx * @param password Password of the user * @return Session credentials * @throws ApiCallException - * @throws SessionExpiredException + * @throws AuthorizationException * @throws IllegalArgumentException Thrown if username or password are not * given. */ public @Nullable CredentialDto login(String username, String password) - throws ApiCallException, SessionExpiredException, IllegalArgumentException { + throws ApiCallException, AuthorizationException, IllegalArgumentException { if (username == null || username.isBlank() || password == null || password.isBlank()) { logger.warn("Missing user name or password, cannot login"); throw new IllegalArgumentException("Username or password missing"); @@ -364,7 +364,7 @@ private V removeFromCache(Cache cache, Object key) throws CachingEx } catch (NotFoundException ex) { logger.info("Could not find requested resource"); return null; - } catch (SessionExpiredException ex) { + } catch (AuthorizationException ex) { logger.info("Could not log into the api"); throw ex; } @@ -385,10 +385,10 @@ private V removeFromCache(Cache cache, Object key) throws CachingEx * * @return The login credentials * @throws CacheMissException If user or password are not cached - * @throws SessionExpiredException + * @throws AuthorizationException * @throws ApiCallException */ - public @Nullable CredentialDto login() throws CacheMissException, ApiCallException, SessionExpiredException { + public @Nullable CredentialDto login() throws CacheMissException, ApiCallException, AuthorizationException { Object user = checkCache(CacheType.CREDENTIALS, CredentialCacheKeys.USER.getValue()); Object password = checkCache(CacheType.CREDENTIALS, CredentialCacheKeys.PASSWORD.getValue()); @@ -447,14 +447,14 @@ private V removeFromCache(Cache cache, Object key) throws CachingEx * cached. * @throws IllegalArgumentException If an invalid epub dto has been given. * @throws ApiCallException If the call to the api itself failed. - * @throws SessionExpiredException If session has expired. If you are working + * @throws AuthorizationException If session has expired. If you are working * without cache, call * {@link EpubClient#refreshLogin(String)} * again, otherwise a call to * {@link EpubClient#refreshLogin()} suffices. */ public @Nullable EpubDto addEpub(@NotNull EpubDto epub) - throws CacheMissException, IllegalArgumentException, ApiCallException, SessionExpiredException { + throws CacheMissException, IllegalArgumentException, ApiCallException, AuthorizationException { return addEpub(getCurrentJwt(), epub); } @@ -472,14 +472,14 @@ private V removeFromCache(Cache cache, Object key) throws CachingEx * @throws IllegalStateException If no jwt could be retrieved from the api * and the client is not logged in. * @throws ApiCallException If the call to the api itself failed. - * @throws SessionExpiredException If session has expired. If you are working + * @throws AuthorizationException If session has expired. If you are working * without cache, call * {@link EpubClient#refreshLogin(String)} * again, otherwise a call to * {@link EpubClient#refreshLogin()} suffices. */ public @Nullable EpubDto addEpub(@NotNull String username, @NotNull String password, @NotNull EpubDto epub) - throws IllegalArgumentException, IllegalStateException, ApiCallException, SessionExpiredException { + throws IllegalArgumentException, IllegalStateException, ApiCallException, AuthorizationException { return addEpub(getNewJwt(username, password), epub); } @@ -494,14 +494,14 @@ private V removeFromCache(Cache cache, Object key) throws CachingEx * been given. * @throws ApiCallException If api call itself failed due to an * exception. - * @throws SessionExpiredException If session has expired. If you are working + * @throws AuthorizationException If session has expired. If you are working * without cache, call * {@link EpubClient#refreshLogin(String)} * again, otherwise a call to * {@link EpubClient#refreshLogin()} suffices. */ private @Nullable EpubDto addEpub(@NotNull String jwt, @NotNull EpubDto epub) - throws IllegalArgumentException, ApiCallException, SessionExpiredException { + throws IllegalArgumentException, ApiCallException, AuthorizationException { if (epubs == null) { epubs = new EpubAdapter(this); } @@ -519,14 +519,14 @@ private V removeFromCache(Cache cache, Object key) throws CachingEx * @throws IllegalStateException If no session could be created * @throws IllegalArgumentException If username or password are missing * @throws ApiCallException If an error occurred during call to the api - * @throws SessionExpiredException If session has expired. If you are working + * @throws AuthorizationException If session has expired. If you are working * without cache, call * {@link EpubClient#refreshLogin(String)} * again, otherwise a call to * {@link EpubClient#refreshLogin()} suffices. */ public @Nullable EpubDto deleteEpub(@NotNull String username, @NotNull String password, long epubId) - throws IllegalStateException, IllegalArgumentException, ApiCallException, SessionExpiredException { + throws IllegalStateException, IllegalArgumentException, ApiCallException, AuthorizationException { return deleteEpub(getNewJwt(username, password), epubId); } @@ -539,14 +539,14 @@ private V removeFromCache(Cache cache, Object key) throws CachingEx * @throws CacheMissException If necessary values are not yet cached * @throws IllegalArgumentException If username or password are missing * @throws ApiCallException If an error occurred during call to the api - * @throws SessionExpiredException If session has expired. If you are working + * @throws AuthorizationException If session has expired. If you are working * without cache, call * {@link EpubClient#refreshLogin(String)} * again, otherwise a call to * {@link EpubClient#refreshLogin()} suffices. */ public @Nullable EpubDto deleteEpub(long epubId) - throws CacheMissException, IllegalArgumentException, ApiCallException, SessionExpiredException { + throws CacheMissException, IllegalArgumentException, ApiCallException, AuthorizationException { return deleteEpub(getCurrentJwt(), epubId); } @@ -558,14 +558,14 @@ private V removeFromCache(Cache cache, Object key) throws CachingEx * @return The deleted epub * @throws IllegalArgumentException If username or password are missing * @throws ApiCallException If an error occurred during call to the api - * @throws SessionExpiredException If session has expired. If you are working + * @throws AuthorizationException If session has expired. If you are working * without cache, call * {@link EpubClient#refreshLogin(String)} * again, otherwise a call to * {@link EpubClient#refreshLogin()} suffices. */ private @Nullable EpubDto deleteEpub(@NotNull String jwt, long epubId) - throws IllegalArgumentException, ApiCallException, SessionExpiredException { + throws IllegalArgumentException, ApiCallException, AuthorizationException { if (epubs == null) { logger.info("No epub adapter initialised, initialising now"); epubs = new EpubAdapter(this); @@ -582,11 +582,11 @@ private V removeFromCache(Cache cache, Object key) throws CachingEx * @param epubId Id of the epub to retrieve * @return Retrieved epub * @throws IllegalArgumentException - * @throws SessionExpiredException + * @throws AuthorizationException * @throws ApiCallException */ public @Nullable EpubDto getEpub(@NotNull String username, @NotNull String password, long epubId, HttpQuery query) - throws IllegalArgumentException, SessionExpiredException, ApiCallException { + throws IllegalArgumentException, AuthorizationException, ApiCallException { return getEpub(getNewJwt(username, password), epubId, query); } @@ -597,13 +597,13 @@ private V removeFromCache(Cache cache, Object key) throws CachingEx * @return Retrieved epub * @throws IllegalArgumentException If the jwt is token * @throws CacheMissException If credentials are missing in the cache - * @throws SessionExpiredException If the session has expired or the api + * @throws AuthorizationException If the session has expired or the api * returned 401 * @throws ApiCallException If a general error occurred while calling * the api */ public @Nullable EpubDto getEpub(long epubId, HttpQuery query) - throws IllegalArgumentException, CacheMissException, SessionExpiredException, ApiCallException { + throws IllegalArgumentException, CacheMissException, AuthorizationException, ApiCallException { return getEpub(getCurrentJwt(), epubId, query); } @@ -614,11 +614,11 @@ private V removeFromCache(Cache cache, Object key) throws CachingEx * @param epubId Id of the epub to retrieve * @return Retrieved epub or null, if no epub with given id was found * @throws IllegalArgumentException If jwt is missing or blank - * @throws SessionExpiredException If the session credentials are invalid + * @throws AuthorizationException If the session credentials are invalid * @throws ApiCallException General api error exception */ private @Nullable EpubDto getEpub(@NotNull String jwt, long epubId, HttpQuery query) - throws IllegalArgumentException, SessionExpiredException, ApiCallException { + throws IllegalArgumentException, AuthorizationException, ApiCallException { if (epubs == null) { logger.info("No epub adapter initialised, initialising now"); epubs = new EpubAdapter(this); @@ -636,14 +636,14 @@ private V removeFromCache(Cache cache, Object key) throws CachingEx * @return Added edition or null, if edition could not be added * @throws CacheMissException If no credentials are cached * @throws ApiCallException General api error - * @throws SessionExpiredException If cached credentials have expired + * @throws AuthorizationException If cached credentials have expired * @throws IllegalArgumentException If given edition is missing the version name * or is null * @throws NotFoundException If no epub with given id exists * @throws BadRequestException If the epub edition is invalid */ public @Nullable EpubEditionDto addEpubEdition(long epubId, @NotNull EpubEditionDto edition) - throws CacheMissException, ApiCallException, SessionExpiredException, IllegalArgumentException, + throws CacheMissException, ApiCallException, AuthorizationException, IllegalArgumentException, NotFoundException, BadRequestException { return addEpubEdition(getCurrentJwt(), epubId, edition); } @@ -657,7 +657,7 @@ private V removeFromCache(Cache cache, Object key) throws CachingEx * @param edition Edition of the epub to add * @return Added edition or null, if edition could not be added * @throws ApiCallException General api error - * @throws SessionExpiredException If the session has expired + * @throws AuthorizationException If the session has expired * @throws IllegalArgumentException If no username, password, edition or * edition.versionName are given * @throws NotFoundException If no epub with given id exists @@ -665,7 +665,7 @@ private V removeFromCache(Cache cache, Object key) throws CachingEx */ public @Nullable EpubEditionDto addEpubEdition(@NotNull String username, @NotNull String password, long epubId, @NotNull EpubEditionDto edition) - throws ApiCallException, SessionExpiredException, IllegalArgumentException, NotFoundException, + throws ApiCallException, AuthorizationException, IllegalArgumentException, NotFoundException, BadRequestException { return addEpubEdition(getNewJwt(username, password), epubId, edition); } @@ -680,12 +680,12 @@ private V removeFromCache(Cache cache, Object key) throws CachingEx * @throws IllegalArgumentException If no username, password, edition or * edition.versionName are given * @throws NotFoundException If no epub with given id exists - * @throws SessionExpiredException If the session has expired + * @throws AuthorizationException If the session has expired * @throws BadRequestException If the given edition is invalid * @throws ApiCallException General api error */ private @Nullable EpubEditionDto addEpubEdition(@NotNull String jwt, long epubId, @NotNull EpubEditionDto edition) - throws IllegalArgumentException, NotFoundException, SessionExpiredException, BadRequestException, + throws IllegalArgumentException, NotFoundException, AuthorizationException, BadRequestException, ApiCallException { if (epubs == null) { epubs = new EpubAdapter(this); @@ -703,10 +703,10 @@ private V removeFromCache(Cache cache, Object key) throws CachingEx * @param query Query with epub requirements. Can be null * @return All epubs meeting the requirements * @throws ApiCallException General api error - * @throws SessionExpiredException If the session has expired + * @throws AuthorizationException If the session has expired */ public @Nullable PagedRequestDto getAllEpubs(@NotNull String username, @NotNull String password, - @Nullable HttpQuery query) throws ApiCallException, SessionExpiredException { + @Nullable HttpQuery query) throws ApiCallException, AuthorizationException { return getAllEpubs(getNewJwt(username, password), query); } @@ -719,10 +719,10 @@ private V removeFromCache(Cache cache, Object key) throws CachingEx * @throws CacheMissException If no username or password are in the clients * internal cache * @throws ApiCallException General api error - * @throws SessionExpiredException If the session has expired + * @throws AuthorizationException If the session has expired */ public @Nullable PagedRequestDto getAllEpubs(@Nullable HttpQuery query) - throws CacheMissException, ApiCallException, SessionExpiredException { + throws CacheMissException, ApiCallException, AuthorizationException { return getAllEpubs(getCurrentJwt(), query); } @@ -734,10 +734,10 @@ private V removeFromCache(Cache cache, Object key) throws CachingEx * @param query Query with requirements for the epubs to be returned. * @return All epubs meeting the requirements * @throws ApiCallException General api error - * @throws SessionExpiredException If the session has expired + * @throws AuthorizationException If the session has expired */ private @Nullable PagedRequestDto getAllEpubs(@NotNull String jwt, - @Nullable HttpQuery query) throws ApiCallException, SessionExpiredException { + @Nullable HttpQuery query) throws ApiCallException, AuthorizationException { if (epubs == null) epubs = new EpubAdapter(this); @@ -755,11 +755,11 @@ private V removeFromCache(Cache cache, Object key) throws CachingEx * @throws IllegalArgumentException If one or more arguments are missing * @throws IllegalFileTypeException If the given file is not a .epub file. * @throws ApiCallException General api error - * @throws SessionExpiredException If the sessionhas expired + * @throws AuthorizationException If the sessionhas expired * @throws BadRequestException If the request was malformed in some way. */ public void uploadEpub(String username, String password, @NotNull String uploadGuid, @NotNull File epubFile) - throws IllegalArgumentException, IllegalFileTypeException, ApiCallException, SessionExpiredException, + throws IllegalArgumentException, IllegalFileTypeException, ApiCallException, AuthorizationException, BadRequestException { uploadEpub(getNewJwt(username, password), uploadGuid, epubFile); } @@ -773,13 +773,13 @@ public void uploadEpub(String username, String password, @NotNull String uploadG * @throws IllegalArgumentException If one or more arguments are missing * @throws IllegalFileTypeException If the given file is not a .epub file. * @throws ApiCallException General api error - * @throws SessionExpiredException If the sessionhas expired + * @throws AuthorizationException If the sessionhas expired * @throws BadRequestException If the request was malformed in some way. * @throws CacheMissException If no credentials are stored in the clients * cache */ public void uploadEpub(@NotNull String uploadGuid, @NotNull File epubFile) - throws IllegalArgumentException, IllegalFileTypeException, ApiCallException, SessionExpiredException, + throws IllegalArgumentException, IllegalFileTypeException, ApiCallException, AuthorizationException, BadRequestException, CacheMissException { uploadEpub(getCurrentJwt(), uploadGuid, epubFile); } @@ -794,11 +794,11 @@ public void uploadEpub(@NotNull String uploadGuid, @NotNull File epubFile) * @throws IllegalArgumentException If one or more arguments are missing * @throws IllegalFileTypeException If the given file is not a .epub file. * @throws ApiCallException General api error - * @throws SessionExpiredException If the sessionhas expired + * @throws AuthorizationException If the sessionhas expired * @throws BadRequestException If the request was malformed in some way. */ private void uploadEpub(@NotNull String jwt, @NotNull String uploadGuid, @NotNull File epubFile) - throws IllegalArgumentException, IllegalFileTypeException, ApiCallException, SessionExpiredException, + throws IllegalArgumentException, IllegalFileTypeException, ApiCallException, AuthorizationException, BadRequestException { if (epubs == null) epubs = new EpubAdapter(this); @@ -823,14 +823,14 @@ private void uploadEpub(@NotNull String jwt, @NotNull String uploadGuid, @NotNul * @throws ServerErrorException If the server failed in providing the * download. * @throws ApiCallException General api call exception. - * @throws SessionExpiredException If the client could not authenticate at the + * @throws AuthorizationException If the client could not authenticate at the * api. * @throws UnexpectedStatusException If the server responded with an unexpected * status. */ public @Nullable File download(@NotNull String username, @NotNull String password, @NotNull String downloadGuid, @NotNull File downloadDirectory, boolean downloadCover) throws IllegalArgumentException, - BadRequestException, ServerErrorException, ApiCallException, SessionExpiredException, + BadRequestException, ServerErrorException, ApiCallException, AuthorizationException, UnexpectedStatusException { return download(getNewJwt(username, password), downloadGuid, downloadDirectory, downloadCover); } @@ -849,7 +849,7 @@ private void uploadEpub(@NotNull String jwt, @NotNull String uploadGuid, @NotNul * @throws ServerErrorException If the server failed in providing the * download. * @throws ApiCallException General api call exception. - * @throws SessionExpiredException If the client could not authenticate at the + * @throws AuthorizationException If the client could not authenticate at the * api. * @throws CacheMissException If no credentials are stored in the clients * cache. @@ -858,7 +858,7 @@ private void uploadEpub(@NotNull String jwt, @NotNull String uploadGuid, @NotNul */ public @Nullable File download(@NotNull String downloadGuid, @NotNull File downloadDirectory, boolean downloadCover) throws IllegalArgumentException, BadRequestException, ServerErrorException, - CacheMissException, ApiCallException, SessionExpiredException, UnexpectedStatusException { + CacheMissException, ApiCallException, AuthorizationException, UnexpectedStatusException { return download(getCurrentJwt(), downloadGuid, downloadDirectory, downloadCover); } @@ -877,13 +877,13 @@ private void uploadEpub(@NotNull String jwt, @NotNull String uploadGuid, @NotNul * @throws BadRequestException If the download guid is invalid. * @throws ServerErrorException If the server failed in providing the * download. - * @throws SessionExpiredException If the jwt is invalid + * @throws AuthorizationException If the jwt is invalid * @throws UnexpectedStatusException If the server responded with an unexpected * status. */ private final @Nullable File download(@NotNull String jwt, @NotNull String downloadGuid, @NotNull File downloadDirectory, boolean downloadCover) - throws IllegalArgumentException, BadRequestException, ServerErrorException, SessionExpiredException, + throws IllegalArgumentException, BadRequestException, ServerErrorException, AuthorizationException, UnexpectedStatusException { if (epubs == null) { @@ -902,14 +902,14 @@ private void uploadEpub(@NotNull String jwt, @NotNull String uploadGuid, @NotNul * @param editionId Id of the edition to be deleted * @return The deleted epub edition * @throws ApiCallException If the api returned an unexpected status - * @throws SessionExpiredException If the credentials are incorrect + * @throws AuthorizationException If the credentials are incorrect * @throws IllegalArgumentException If username or password are not given * @throws NotFoundException If either the epub id or edition id do not * exist */ public @Nullable EpubEditionDto deleteEpubEdition(@NotNull String username, @NotNull String password, long epubId, long editionId) - throws ApiCallException, SessionExpiredException, IllegalArgumentException, NotFoundException { + throws ApiCallException, AuthorizationException, IllegalArgumentException, NotFoundException { return deleteEpubEdition(getNewJwt(username, password), epubId, editionId); } @@ -921,7 +921,7 @@ private void uploadEpub(@NotNull String jwt, @NotNull String uploadGuid, @NotNul * @param editionId Id of the edition to be deleted * @return The deleted epub edition * @throws ApiCallException If the api returned an unexpected status - * @throws SessionExpiredException If the credentials are incorrect + * @throws AuthorizationException If the credentials are incorrect * @throws IllegalArgumentException If username or password are not given * @throws NotFoundException If either the epub id or edition id do not * exist @@ -929,7 +929,7 @@ private void uploadEpub(@NotNull String jwt, @NotNull String uploadGuid, @NotNul * cache */ public @Nullable EpubEditionDto deleteEpubEdition(long epubId, - long editionId) throws CacheMissException, ApiCallException, SessionExpiredException, + long editionId) throws CacheMissException, ApiCallException, AuthorizationException, IllegalArgumentException, NotFoundException { return deleteEpubEdition(getCurrentJwt(), epubId, editionId); } @@ -942,13 +942,13 @@ private void uploadEpub(@NotNull String jwt, @NotNull String uploadGuid, @NotNul * @param editionId Id of the edition to be deleted * @return The deleted epub edition * @throws ApiCallException If the api returned an unexpected status - * @throws SessionExpiredException If the credentials are incorrect + * @throws AuthorizationException If the credentials are incorrect * @throws IllegalArgumentException If username or password are not given * @throws NotFoundException If either the epub id or edition id do not * exist */ private final @Nullable EpubEditionDto deleteEpubEdition(@NotNull String jwt, long epubId, long editionId) - throws IllegalArgumentException, SessionExpiredException, ApiCallException, NotFoundException { + throws IllegalArgumentException, AuthorizationException, ApiCallException, NotFoundException { if (epubs == null) epubs = new EpubAdapter(this); @@ -967,12 +967,12 @@ private void uploadEpub(@NotNull String jwt, @NotNull String uploadGuid, @NotNul * @throws IllegalArgumentException If username, password, author.firstName or * author.surname are not given. * @throws ApiCallException General wrapper for unexpected api behaviour - * @throws SessionExpiredException If authentication at the api did not work + * @throws AuthorizationException If authentication at the api did not work * @throws BadRequestException If the author dto was invalid. */ public @Nullable AuthorDto addAuthor(@NotNull String username, @NotNull String password, @NotNull AuthorDto author) - throws IllegalArgumentException, ApiCallException, SessionExpiredException, BadRequestException { + throws IllegalArgumentException, ApiCallException, AuthorizationException, BadRequestException { return addAuthor(getNewJwt(username, password), author); } @@ -985,13 +985,13 @@ private void uploadEpub(@NotNull String jwt, @NotNull String uploadGuid, @NotNul * @throws IllegalArgumentException If author.firstName or * author.surname are not given. * @throws ApiCallException General wrapper for unexpected api behaviour - * @throws SessionExpiredException If authentication at the api did not work + * @throws AuthorizationException If authentication at the api did not work * @throws BadRequestException If the author dto was invalid. * @throws CacheMissException If no credentials are cached within the * client. */ public @Nullable AuthorDto addAuthor(@NotNull AuthorDto author) throws IllegalArgumentException, ApiCallException, - SessionExpiredException, BadRequestException, CacheMissException { + AuthorizationException, BadRequestException, CacheMissException { return addAuthor(getCurrentJwt(), author); } @@ -1005,11 +1005,11 @@ private void uploadEpub(@NotNull String jwt, @NotNull String uploadGuid, @NotNul * @throws IllegalArgumentException If jwt author.firstName or * author.surname are not given. * @throws ApiCallException General wrapper for unexpected api behaviour - * @throws SessionExpiredException If authentication at the api did not work + * @throws AuthorizationException If authentication at the api did not work * @throws BadRequestException If the author dto was invalid. */ private @Nullable AuthorDto addAuthor(@NotNull String jwt, @NotNull AuthorDto author) - throws IllegalArgumentException, ApiCallException, SessionExpiredException, BadRequestException { + throws IllegalArgumentException, ApiCallException, AuthorizationException, BadRequestException { if (authors == null) authors = new AuthorAdapter(this); return authors.addAuthor(jwt, author); @@ -1036,10 +1036,10 @@ private void uploadEpub(@NotNull String jwt, @NotNull String uploadGuid, @NotNul * @return Requested author. * @throws IllegalArgumentException If username or password are missing * @throws ApiCallException General api error wrapper - * @throws SessionExpiredException If client could not authenticate + * @throws AuthorizationException If client could not authenticate */ public @Nullable AuthorDto getAuthor(@NotNull String username, @NotNull String password, long authorId, - @Nullable HttpQuery query) throws IllegalArgumentException, ApiCallException, SessionExpiredException { + @Nullable HttpQuery query) throws IllegalArgumentException, ApiCallException, AuthorizationException { return getAuthor(getNewJwt(username, password), authorId, query); } @@ -1061,10 +1061,10 @@ private void uploadEpub(@NotNull String jwt, @NotNull String uploadGuid, @NotNul * @return Requested author. * @throws CacheMissException * @throws ApiCallException General api error wrapper - * @throws SessionExpiredException If client could not authenticate + * @throws AuthorizationException If client could not authenticate */ public @Nullable AuthorDto getAuthor(long authorId, @Nullable HttpQuery query) - throws CacheMissException, ApiCallException, SessionExpiredException { + throws CacheMissException, ApiCallException, AuthorizationException { return getAuthor(getCurrentJwt(), authorId, query); } @@ -1086,10 +1086,10 @@ private void uploadEpub(@NotNull String jwt, @NotNull String uploadGuid, @NotNul * @return Requested author. * @throws IllegalArgumentException If username or password are missing * @throws ApiCallException General api error wrapper - * @throws SessionExpiredException If client could not authenticate + * @throws AuthorizationException If client could not authenticate */ private @Nullable AuthorDto getAuthor(@NotNull String jwt, long authorId, @Nullable HttpQuery query) - throws ApiCallException, SessionExpiredException { + throws ApiCallException, AuthorizationException { if (authors == null) authors = new AuthorAdapter(this); return authors.getAuthorById(jwt, authorId, query); @@ -1097,20 +1097,67 @@ private void uploadEpub(@NotNull String jwt, @NotNull String uploadGuid, @NotNul // #endregion get author // #region delete author + /** + * Deletes author with given id. If deleteWithBooks is true, epubs associated + * with the author are deleted as well. + * + * @param username Username to log into the api + * @param password password to log into the api + * @param authorId Id of the author to delete + * @param deleteWithBooks If set to true, all epubs associated with the author + * are deleted as well. + * @return Deleted author + * @throws ApiCallException General wrapper for all + * @throws AuthorizationException If authorization failed + * @throws IllegalArgumentException If username or password are missing + * @throws BadRequestException If the api returned 400 + */ public @Nullable AuthorDto deleteAuthor(@NotNull String username, @NotNull String password, long authorId, boolean deleteWithBooks) - throws ApiCallException, SessionExpiredException, IllegalArgumentException, BadRequestException { + throws ApiCallException, AuthorizationException, IllegalArgumentException, + BadRequestException { return deleteAuthor(getNewJwt(username, password), authorId, deleteWithBooks); } + /** + * Deletes author with given id. If deleteWithBooks is true, epubs associated + * with the author are deleted as well. Requires credentials to be stored in the + * clients cache. + * + * @param authorId Id of the author to delete + * @param deleteWithBooks If set to true, all epubs associated with the author + * are deleted as well. + * @return Deleted author + * @throws ApiCallException General wrapper for all + * @throws AuthorizationException If authorization failed + * @throws IllegalArgumentException If credentials are missing + * @throws BadRequestException If the api returned 400 + * @throws CacheMissException If no credentials are stored in the clients + * cache + */ public @Nullable AuthorDto deleteAuthor(long authorId, boolean deleteWithBooks) - throws CacheMissException, ApiCallException, SessionExpiredException, IllegalArgumentException, + throws CacheMissException, ApiCallException, AuthorizationException, + IllegalArgumentException, BadRequestException { return deleteAuthor(getCurrentJwt(), authorId, deleteWithBooks); } + /** + * Deletes author with given id. If deleteWithBooks is true, epubs associated + * with the author are deleted as well. + * + * @param jwt JWT to authorize at the api + * @param authorId Id of the author to delete + * @param deleteWithBooks If set to true, all epubs associated with the author + * are deleted as well. + * @return Deleted author + * @throws ApiCallException General wrapper for all + * @throws AuthorizationException If authorization failed + * @throws IllegalArgumentException If credentials are missing + * @throws BadRequestException If the api returned 400 + */ private @Nullable AuthorDto deleteAuthor(@NotNull String jwt, long authorId, boolean deleteWithBooks) - throws IllegalArgumentException, SessionExpiredException, ApiCallException, BadRequestException { + throws IllegalArgumentException, AuthorizationException, ApiCallException, BadRequestException { if (authors == null) authors = new AuthorAdapter(this); return authors.deleteAuthor(jwt, authorId, deleteWithBooks); @@ -1156,10 +1203,10 @@ protected final void addHeaders(@NotNull Request.Builder builder, @NotNull Strin * * @return The generated jwt * @throws CacheMissException If username or password are not in cache - * @throws SessionExpiredException + * @throws AuthorizationException * @throws ApiCallException */ - private String getCurrentJwt() throws CacheMissException, ApiCallException, SessionExpiredException { + private String getCurrentJwt() throws CacheMissException, ApiCallException, AuthorizationException { Object jwtObj = checkCache(CacheType.CREDENTIALS, CredentialCacheKeys.JWT.getValue()); String jwt; if (jwtObj == null || !(jwtObj instanceof String)) { @@ -1180,11 +1227,11 @@ private String getCurrentJwt() throws CacheMissException, ApiCallException, Sess * @param username Username to log into the api * @param password Password to log into the apui * @return Generated session token - * @throws SessionExpiredException + * @throws AuthorizationException * @throws ApiCallException */ private String getNewJwt(@NotNull String username, @NotNull String password) - throws ApiCallException, SessionExpiredException { + throws ApiCallException, AuthorizationException { CredentialDto dto = login(username, password); if (dto == null || dto.getJwt() == null || dto.getJwt().isBlank()) { logger.info("Could not acquire jwt for login"); @@ -1201,7 +1248,7 @@ private String getNewJwt(@NotNull String username, @NotNull String password) * @param request Request to be executed * @param type Expected type of the request body * @return The response body or null, if the server answered with 204 - * @throws SessionExpiredException If the server answered with 401 + * @throws AuthorizationException If the server answered with 401 * @throws BadRequestException If the server answered with 400 * @throws ForbiddenException If the server answered with 403 * @throws NotFoundException If the server answered with 404 @@ -1214,7 +1261,7 @@ private String getNewJwt(@NotNull String username, @NotNull String password) protected @Nullable T executeRequest(@NotNull Request request, @NotNull Class type, @Nullable HttpQuery query, boolean cacheRequest) - throws SessionExpiredException, BadRequestException, ForbiddenException, NotFoundException, + throws AuthorizationException, BadRequestException, ForbiddenException, NotFoundException, ServerErrorException, UnexpectedStatusException, IOException { T dto = null; @@ -1252,7 +1299,7 @@ private String getNewJwt(@NotNull String username, @NotNull String password) throw new BadRequestException(); case 401: logger.info("Session expired"); - throw new SessionExpiredException(); + throw new AuthorizationException(); case 403: logger.info("Action forbidden"); throw new ForbiddenException(); @@ -1282,7 +1329,7 @@ private String getNewJwt(@NotNull String username, @NotNull String password) * @param request Request to be executed * @param type Expected type of the request body * @return The response body or null, if the server answered with 204 - * @throws SessionExpiredException If the server answered with 401 + * @throws AuthorizationException If the server answered with 401 * @throws BadRequestException If the server answered with 400 * @throws ForbiddenException If the server answered with 403 * @throws NotFoundException If the server answered with 404 @@ -1295,7 +1342,7 @@ private String getNewJwt(@NotNull String username, @NotNull String password) protected PagedRequestDto executeRequestPaged(@NotNull Request request, @NotNull Class type, @Nullable HttpQuery query, boolean cacheRequest) - throws SessionExpiredException, BadRequestException, ForbiddenException, NotFoundException, + throws AuthorizationException, BadRequestException, ForbiddenException, NotFoundException, ServerErrorException, UnexpectedStatusException, IOException { PagedRequestDto dto = null; @@ -1320,7 +1367,7 @@ protected PagedRequestDto executeRequestPaged(@NotNull Request request, @ throw new BadRequestException(); case 401: logger.info("Session expired"); - throw new SessionExpiredException(); + throw new AuthorizationException(); case 403: logger.info("Action forbidden"); throw new ForbiddenException(); @@ -1348,7 +1395,7 @@ protected PagedRequestDto executeRequestPaged(@NotNull Request request, @ * * @param requestGuid * @return - * @throws SessionExpiredException + * @throws AuthorizationException * @throws BadRequestException * @throws ForbiddenException * @throws NotFoundException @@ -1357,7 +1404,7 @@ protected PagedRequestDto executeRequestPaged(@NotNull Request request, @ * @throws IOException * @throws IllegalArgumentException */ - public Object redoRequest(@NotNull String requestGuid) throws SessionExpiredException, BadRequestException, + public Object redoRequest(@NotNull String requestGuid) throws AuthorizationException, BadRequestException, ForbiddenException, NotFoundException, ServerErrorException, UnexpectedStatusException, IOException, IllegalArgumentException { if (requestGuid == null || requestGuid.isBlank()) { @@ -1382,7 +1429,7 @@ public Object redoRequest(@NotNull String requestGuid) throws SessionExpiredExce * {@link EpubClient#getLastRequestGuid()}. * @param expectedResponseType Type of the expected response * @return Response from the api or null, if the request is not paged. - * @throws SessionExpiredException Thrown if session has expired + * @throws AuthorizationException Thrown if session has expired * @throws BadRequestException Thrown if server returned 400 * @throws ForbiddenException Thrown if server returned 403 * @throws NotFoundException Thrown if server returned 404 @@ -1393,7 +1440,7 @@ public Object redoRequest(@NotNull String requestGuid) throws SessionExpiredExce */ public @Nullable PagedRequestDto nextPage(@NotNull String requestGuid, @NotNull Class expectedResponseType) - throws SessionExpiredException, BadRequestException, ForbiddenException, NotFoundException, + throws AuthorizationException, BadRequestException, ForbiddenException, NotFoundException, ServerErrorException, UnexpectedStatusException, IOException { RequestCacheEntity e = ((RequestCache) caches.get(CacheType.REQUEST)).getValue(requestGuid); if (!e.isPaged()) { diff --git a/lib/src/main/java/org/koppe/epub/client/cache/AbstractCache.java b/lib/src/main/java/org/koppe/epub/client/cache/AbstractCache.java index 5b54570..203c2ba 100644 --- a/lib/src/main/java/org/koppe/epub/client/cache/AbstractCache.java +++ b/lib/src/main/java/org/koppe/epub/client/cache/AbstractCache.java @@ -305,6 +305,9 @@ private static class CachedValue { private LocalDateTime addedAt; } + /** + * {@inheritDoc} + */ @Override public Map getAll() { Map all = new HashMap<>(); @@ -314,6 +317,11 @@ public Map getAll() { return all; } + /** + * Returns the newest entry to the cache. + * + * @return Newest entry to the cache. + */ public V getNewest() { K k = null; for (K x : cache.keySet()) { @@ -329,6 +337,11 @@ public V getNewest() { return cache.get(k).getValue(); } + /** + * Returns oldest entry to the cache. + * + * @return Oldest entry to the cache. + */ public V getOldest() { K k = null; for (K x : cache.keySet()) { @@ -344,6 +357,9 @@ public V getOldest() { return cache.get(k).getValue(); } + /** + * Unlocks the reentrant lock + */ private void unlock() { if (!lock.isHeldByCurrentThread()) return; diff --git a/lib/src/main/java/org/koppe/epub/client/cache/AuthorCache.java b/lib/src/main/java/org/koppe/epub/client/cache/AuthorCache.java index 5ca510a..e865dc4 100644 --- a/lib/src/main/java/org/koppe/epub/client/cache/AuthorCache.java +++ b/lib/src/main/java/org/koppe/epub/client/cache/AuthorCache.java @@ -2,6 +2,10 @@ import org.koppe.epub.client.dto.AuthorDto; +/** + * Cache for AuthorDto elements. Does not have a custom refresh algorithm, gets + * filled manually by the EpubClient. + */ public class AuthorCache extends AbstractCache { } diff --git a/lib/src/main/java/org/koppe/epub/client/cache/Cache.java b/lib/src/main/java/org/koppe/epub/client/cache/Cache.java index 5db7043..5c494ef 100644 --- a/lib/src/main/java/org/koppe/epub/client/cache/Cache.java +++ b/lib/src/main/java/org/koppe/epub/client/cache/Cache.java @@ -5,6 +5,12 @@ import org.koppe.epub.client.exceptions.CachingException; +/** + * Interface for all caches. + * + * @param Type of keys in the cache. + * @param Type of values in the cache. + */ public interface Cache { /** * Returns the cached value associated with the given key @@ -76,6 +82,11 @@ public interface Cache { */ public V removeFromCache(K key) throws CachingException; + /** + * Returns all elements in the cache. + * + * @return All elements in the cache. + */ public Map getAll(); /** diff --git a/lib/src/main/java/org/koppe/epub/client/cache/CacheFactory.java b/lib/src/main/java/org/koppe/epub/client/cache/CacheFactory.java index 6c1116f..d318645 100644 --- a/lib/src/main/java/org/koppe/epub/client/cache/CacheFactory.java +++ b/lib/src/main/java/org/koppe/epub/client/cache/CacheFactory.java @@ -82,6 +82,15 @@ public static EditionCache newDefaultEditionCache() { }; } + // #region default author cache + /** + * Creates a default cache for AuthorDtos. + * Retention: 10 minutes. + * Maximum elements: 100. + * No automatic refresh. + * + * @return The created cache. + */ public static AuthorCache newDefaultAuthorCache() { AuthorCache cache = new AuthorCache(); cache.setRetention(10, TimeUnit.MINUTES); diff --git a/lib/src/main/java/org/koppe/epub/client/cache/CacheType.java b/lib/src/main/java/org/koppe/epub/client/cache/CacheType.java index 8ad8c90..dd136ae 100644 --- a/lib/src/main/java/org/koppe/epub/client/cache/CacheType.java +++ b/lib/src/main/java/org/koppe/epub/client/cache/CacheType.java @@ -1,23 +1,62 @@ package org.koppe.epub.client.cache; +import org.koppe.epub.client.dto.AuthorDto; import org.koppe.epub.client.dto.CredentialDto; +import org.koppe.epub.client.dto.EpubDto; import org.koppe.epub.client.dto.EpubEditionDto; +import org.koppe.epub.client.dto.GenreDto; +import org.koppe.epub.client.dto.TagDto; import lombok.Getter; +/** + * All types of caches. + */ public enum CacheType { - CREDENTIALS(CredentialDto.class), - EPUBS(CredentialDto.class), - EDITIONS(EpubEditionDto.class), - AUTHORS(CredentialDto.class), - GENRES(CredentialDto.class), - REQUEST(RequestCacheEntity.class), - TAGS(CredentialDto.class); + /** + * Cache for credentials + */ + CREDENTIALS(String.class, CredentialDto.class), + /** + * Cache for epubs + */ + EPUBS(Long.class, EpubDto.class), + /** + * Cache for epub editions + */ + EDITIONS(Long.class, EpubEditionDto.class), + /** + * Cache for authors + */ + AUTHORS(Long.class, AuthorDto.class), + /** + * Cache for genres + */ + GENRES(Long.class, GenreDto.class), + /** + * Cache for requests + */ + REQUEST(String.class, RequestCacheEntity.class), + /** + * Cache for tags + */ + TAGS(Long.class, TagDto.class); + /** + * Type of elements the cache holds + */ @Getter private Class type; + @Getter + private Class keys; - private CacheType(Class type) { + /** + * Default constructor + * + * @param type Type of values the cache holds + */ + private CacheType(Class keys, Class type) { + this.keys = keys; this.type = type; } } diff --git a/lib/src/main/java/org/koppe/epub/client/exceptions/SessionExpiredException.java b/lib/src/main/java/org/koppe/epub/client/exceptions/AuthorizationException.java similarity index 51% rename from lib/src/main/java/org/koppe/epub/client/exceptions/SessionExpiredException.java rename to lib/src/main/java/org/koppe/epub/client/exceptions/AuthorizationException.java index ef0c070..f85a08f 100644 --- a/lib/src/main/java/org/koppe/epub/client/exceptions/SessionExpiredException.java +++ b/lib/src/main/java/org/koppe/epub/client/exceptions/AuthorizationException.java @@ -3,8 +3,8 @@ import lombok.NoArgsConstructor; @NoArgsConstructor -public class SessionExpiredException extends Exception { - public SessionExpiredException(String msg, Throwable cause) { +public class AuthorizationException extends Exception { + public AuthorizationException(String msg, Throwable cause) { super(msg, cause); } } diff --git a/lib/src/test/java/org/koppe/epub/client/AuthorAdapterTest.java b/lib/src/test/java/org/koppe/epub/client/AuthorAdapterTest.java index aa1ad96..1d52381 100644 --- a/lib/src/test/java/org/koppe/epub/client/AuthorAdapterTest.java +++ b/lib/src/test/java/org/koppe/epub/client/AuthorAdapterTest.java @@ -10,7 +10,7 @@ import org.koppe.epub.client.dto.AuthorDto; import org.koppe.epub.client.exceptions.ApiCallException; import org.koppe.epub.client.exceptions.BadRequestException; -import org.koppe.epub.client.exceptions.SessionExpiredException; +import org.koppe.epub.client.exceptions.AuthorizationException; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; @@ -33,7 +33,7 @@ public void testAddAuthorExceptions() { assertThrows(IllegalArgumentException.class, () -> adapter.addAuthor(" ", null)); server.enqueue(new MockResponse().setResponseCode(401)); - assertThrows(SessionExpiredException.class, () -> adapter.addAuthor("fake-jwt-123", dto)); + assertThrows(AuthorizationException.class, () -> adapter.addAuthor("fake-jwt-123", dto)); server.enqueue(new MockResponse().setResponseCode(400)); assertThrows(BadRequestException.class, () -> adapter.addAuthor("fake-jwt-123", dto)); @@ -70,7 +70,7 @@ public void testGetAuthor() { assertThrows(IllegalArgumentException.class, () -> adapter.getAuthorById(" ", 1L, null)); server.enqueue(new MockResponse().setResponseCode(401)); - assertThrows(SessionExpiredException.class, () -> adapter.getAuthorById("fake-jwt-123", 1L, null)); + assertThrows(AuthorizationException.class, () -> adapter.getAuthorById("fake-jwt-123", 1L, null)); server.enqueue(new MockResponse().setResponseCode(400)); assertThrows(ApiCallException.class, () -> adapter.getAuthorById("fake-jwt-123", 1L, null)); diff --git a/lib/src/test/java/org/koppe/epub/client/EpubAdapterTest.java b/lib/src/test/java/org/koppe/epub/client/EpubAdapterTest.java index ede8d58..68310f3 100644 --- a/lib/src/test/java/org/koppe/epub/client/EpubAdapterTest.java +++ b/lib/src/test/java/org/koppe/epub/client/EpubAdapterTest.java @@ -9,7 +9,7 @@ import org.koppe.epub.client.exceptions.ApiCallException; import org.koppe.epub.client.exceptions.BadRequestException; import org.koppe.epub.client.exceptions.NotFoundException; -import org.koppe.epub.client.exceptions.SessionExpiredException; +import org.koppe.epub.client.exceptions.AuthorizationException; import org.koppe.epub.client.http.HttpQuery; import okhttp3.mockwebserver.MockResponse; @@ -53,7 +53,7 @@ public void testAddEpubException() { assertThrows(ApiCallException.class, () -> adapter.addEpub("fake-jwt-123", DtoRecord.epub1)); server.enqueue(new MockResponse().setResponseCode(401)); - assertThrows(SessionExpiredException.class, () -> adapter.addEpub("fake-jwt-123", DtoRecord.epub1)); + assertThrows(AuthorizationException.class, () -> adapter.addEpub("fake-jwt-123", DtoRecord.epub1)); } catch (Exception ex) { fail(); @@ -72,7 +72,7 @@ public void testDeleteEpubException() { assertNull(adapter.deleteEpub("fake-jwt-123", 1)); server.enqueue(new MockResponse().setResponseCode(401)); - assertThrows(SessionExpiredException.class, () -> adapter.deleteEpub("fake-jwt-123", 1)); + assertThrows(AuthorizationException.class, () -> adapter.deleteEpub("fake-jwt-123", 1)); server.enqueue(new MockResponse().setResponseCode(403)); assertThrows(ApiCallException.class, () -> adapter.deleteEpub("fake-jwt-123", 1)); @@ -102,7 +102,7 @@ public void testGetEpubException() { assertNull(adapter.getEpub("fake-jwt-123", 1, null)); server.enqueue(new MockResponse().setResponseCode(401)); - assertThrows(SessionExpiredException.class, () -> adapter.getEpub("fake-jwt-123", 1, null)); + assertThrows(AuthorizationException.class, () -> adapter.getEpub("fake-jwt-123", 1, null)); server.enqueue(new MockResponse().setResponseCode(403)); assertThrows(ApiCallException.class, () -> adapter.getEpub("fake-jwt-123", 1, null)); @@ -132,7 +132,7 @@ public void testAddEditionExceptions() { assertNull(adapter.addEpubEdition("fake-jwt-123", 1, DtoRecord.edition1)); server.enqueue(new MockResponse().setResponseCode(401)); - assertThrows(SessionExpiredException.class, + assertThrows(AuthorizationException.class, () -> adapter.addEpubEdition("fake-jwt-123", 1, DtoRecord.edition1)); server.enqueue(new MockResponse().setResponseCode(404)); @@ -187,7 +187,7 @@ public void testGetPagedExceptions() { assertThrows(ApiCallException.class, () -> adapter.getEpubsPaged("fake-jwt-123", null)); server.enqueue(new MockResponse().setResponseCode(401)); - assertThrows(SessionExpiredException.class, () -> adapter.getEpubsPaged("fake-jwt-123", null)); + assertThrows(AuthorizationException.class, () -> adapter.getEpubsPaged("fake-jwt-123", null)); } catch (Exception ex) { fail(ex.getMessage()); } diff --git a/lib/src/test/java/org/koppe/epub/client/EpubClientCommunicationTest.java b/lib/src/test/java/org/koppe/epub/client/EpubClientCommunicationTest.java index 1360587..88fa22c 100644 --- a/lib/src/test/java/org/koppe/epub/client/EpubClientCommunicationTest.java +++ b/lib/src/test/java/org/koppe/epub/client/EpubClientCommunicationTest.java @@ -24,7 +24,7 @@ import org.koppe.epub.client.exceptions.IllegalFileTypeException; import org.koppe.epub.client.exceptions.NotFoundException; import org.koppe.epub.client.exceptions.ServerErrorException; -import org.koppe.epub.client.exceptions.SessionExpiredException; +import org.koppe.epub.client.exceptions.AuthorizationException; import org.koppe.epub.client.exceptions.UnexpectedStatusException; import org.koppe.epub.client.http.AuthorQueryBuilder; import org.koppe.epub.client.http.EpubQueryBuilder; @@ -49,9 +49,9 @@ public void testLogin() { assertThrows(IllegalArgumentException.class, () -> client.login(" ", null)); assertThrows(IllegalArgumentException.class, () -> client.login(null, " ")); assertThrows(IllegalArgumentException.class, () -> client.login(" ", " ")); - assertThrows(SessionExpiredException.class, () -> client.login("admin", "test")); + assertThrows(AuthorizationException.class, () -> client.login("admin", "test")); - assertThrows(SessionExpiredException.class, client::login); + assertThrows(AuthorizationException.class, client::login); CredentialDto dto = null; try { @@ -97,7 +97,7 @@ public void testAddEpub() { EpubDto response = null; try { response = client.addEpub(body); - } catch (IllegalArgumentException | CacheMissException | ApiCallException | SessionExpiredException e) { + } catch (IllegalArgumentException | CacheMissException | ApiCallException | AuthorizationException e) { fail(); } @@ -257,7 +257,7 @@ public void testExecuteRequest() { Void.class, null, false)); - } catch (SessionExpiredException | BadRequestException | ForbiddenException | NotFoundException + } catch (AuthorizationException | BadRequestException | ForbiddenException | NotFoundException | ServerErrorException | UnexpectedStatusException | IOException e) { fail(); } @@ -265,7 +265,7 @@ public void testExecuteRequest() { () -> client.executeRequest(new Request.Builder().url(server.url("/").toString()).get().build(), Void.class, null, false)); - assertThrows(SessionExpiredException.class, + assertThrows(AuthorizationException.class, () -> client.executeRequest(new Request.Builder().url(server.url("/").toString()).get().build(), Void.class, null, false)); @@ -306,7 +306,7 @@ public void testExecuteRequestPaged() { Void.class, null, false)); - } catch (SessionExpiredException | BadRequestException | ForbiddenException | NotFoundException + } catch (AuthorizationException | BadRequestException | ForbiddenException | NotFoundException | ServerErrorException | UnexpectedStatusException | IOException e) { fail(); } @@ -314,7 +314,7 @@ public void testExecuteRequestPaged() { () -> client.executeRequestPaged(new Request.Builder().url(server.url("/").toString()).get().build(), Void.class, null, false)); - assertThrows(SessionExpiredException.class, + assertThrows(AuthorizationException.class, () -> client.executeRequestPaged(new Request.Builder().url(server.url("/").toString()).get().build(), Void.class, null, false)); @@ -384,7 +384,7 @@ public void testUpload() { try { client.uploadEpub("admin", "admin", "123", epub); - } catch (IllegalArgumentException | IllegalFileTypeException | ApiCallException | SessionExpiredException + } catch (IllegalArgumentException | IllegalFileTypeException | ApiCallException | AuthorizationException | BadRequestException e) { fail(); } @@ -455,7 +455,7 @@ public void testAddAuthor() { try { added = client.addAuthor(toAdd); - } catch (IllegalArgumentException | ApiCallException | SessionExpiredException | BadRequestException + } catch (IllegalArgumentException | ApiCallException | AuthorizationException | BadRequestException | CacheMissException e) { fail(); } @@ -508,7 +508,7 @@ public void testDeleteAuthor() { assertNotNull(dto); assertEquals("Test2", dto.getFirstName()); assertEquals(2, dto.getEpubs().size()); - } catch (IllegalArgumentException | ApiCallException | SessionExpiredException | BadRequestException + } catch (IllegalArgumentException | ApiCallException | AuthorizationException | BadRequestException | CacheMissException e) { fail(e.getMessage()); } From 4db8af70d3dba58222cb0b32aa5fad5184a65f92 Mon Sep 17 00:00:00 2001 From: GeKoppe Date: Wed, 15 Apr 2026 20:20:09 +0200 Subject: [PATCH 5/6] Added more author actions --- .../org/koppe/epub/client/AuthorAdapter.java | 138 +++++++++++++++++- .../org/koppe/epub/client/EpubClient.java | 116 ++++++++++----- .../java/org/koppe/epub/client/dto/IdDto.java | 12 ++ 3 files changed, 226 insertions(+), 40 deletions(-) create mode 100644 lib/src/main/java/org/koppe/epub/client/dto/IdDto.java diff --git a/lib/src/main/java/org/koppe/epub/client/AuthorAdapter.java b/lib/src/main/java/org/koppe/epub/client/AuthorAdapter.java index 876ebd8..3bc23ee 100644 --- a/lib/src/main/java/org/koppe/epub/client/AuthorAdapter.java +++ b/lib/src/main/java/org/koppe/epub/client/AuthorAdapter.java @@ -8,6 +8,7 @@ import org.jetbrains.annotations.Nullable; import org.koppe.epub.client.cache.CacheType; import org.koppe.epub.client.dto.AuthorDto; +import org.koppe.epub.client.dto.IdDto; import org.koppe.epub.client.dto.PagedRequestDto; import org.koppe.epub.client.exceptions.ApiCallException; import org.koppe.epub.client.exceptions.BadRequestException; @@ -245,7 +246,7 @@ protected AuthorAdapter(EpubClient client) { * @throws ApiCallException General wrapper for all api exception * @throws AuthorizationException If authorization failed */ - public @Nullable PagedRequestDto getAllAuthors(@NotNull String jwt, @Nullable HttpQuery query) + protected @Nullable PagedRequestDto getAllAuthors(@NotNull String jwt, @Nullable HttpQuery query) throws IllegalArgumentException, ApiCallException, AuthorizationException { if (jwt == null || jwt.isBlank()) { logger.info("No jwt given"); @@ -292,4 +293,139 @@ protected AuthorAdapter(EpubClient client) { return authors; } + // #region update author + /** + * Updates author with given id. If overwrite nulls is set to true, at least + * first and surname must be given, as no author can be without them. If + * overwrite nulls is set to true and first or surname are missing, an exception + * is thrown. + * + * @param jwt Authorization token for the api + * @param author Author with updated values. If id in this object is + * given, it must match the given authorId + * @param authorId Id of the author to be updated + * @param overwriteNulls If set to true, null values in the given dto will + * overwrite the set values in the system. + * @return The updated author or null, if update did not work + * @throws IllegalArgumentException If an illegal combination of arguments are + * given. + * @throws ApiCallException Wrapper for all unhandled exceptions the api + * throws. + * @throws BadRequestException If the given dto is malformed + * @throws AuthorizationException If authorization at the api failed. + */ + protected @Nullable AuthorDto updateAuthor(@NotNull String jwt, @NotNull AuthorDto author, long authorId, + boolean overwriteNulls) + throws IllegalArgumentException, ApiCallException, BadRequestException, AuthorizationException { + if (jwt == null || jwt.isBlank()) { + logger.info("No jwt given"); + throw new IllegalArgumentException("Missing jwt"); + } + + if (author == null) { + logger.info("No author definition given"); + throw new IllegalArgumentException("No author definition given"); + } + + if (author.getId() != null && !author.getId().equals((Long) authorId)) { + logger.info("Id in dto and given author id do not match"); + throw new IllegalArgumentException("Id in dto and given author id do not match"); + } + + if (overwriteNulls && (author.getFirstName() == null || author.getFirstName().isBlank() + || author.getSurname() == null || author.getSurname().isBlank())) { + logger.info( + "Overwrite nulls is set to true but surname or first name are missing. Author cannot have empty first or surname, provide them if nulls are to be overwritten"); + throw new IllegalArgumentException("Missing first or surname with null overwrite"); + } + logger.debug("Initialising request to update author with id {}", authorId); + + HttpQuery query = new AuthorQueryBuilder().overwriteNulls(overwriteNulls).build(); + Request.Builder builder = new Request.Builder() + .url(String.format("%s/authors/%s%s", client.url(), "" + authorId, query.toQueryString())) + .patch(RequestBody.create(mapper.writeValueAsBytes(author), EpubClient.APPLICATION_JSON)); + + client.addHeaders(builder, jwt, EpubClient.APPLICATION_JSON_STRING, EpubClient.APPLICATION_JSON_STRING); + logger.debug("Request for updating author instantiated, executing"); + + AuthorDto dto = null; + try { + dto = client.executeRequest(builder.build(), AuthorDto.class, query, true); + } catch (ForbiddenException | UnexpectedStatusException | IOException | ServerErrorException e) { + logger.warn("Unexpected response from api received", e); + throw new ApiCallException(null, e); + } catch (AuthorizationException e) { + logger.info("Invalid credentials given or session expired"); + throw e; + } catch (BadRequestException e) { + logger.info("Given author was malformed"); + throw e; + } catch (NotFoundException e) { + logger.info("Author with given id does not exist"); + return null; + } + + if (dto == null) { + logger.info("No response received from api"); + return null; + } + logger.info("Author successfully updated", dto); + + client.cacheValue(CacheType.AUTHORS, (Long) authorId, dto); + return dto; + } + + // #region add epub to author + /** + * + * @param jwt + * @param authorId + * @param epubId + * @return + * @throws IllegalArgumentException + * @throws AuthorizationException + * @throws ApiCallException + */ + protected @Nullable AuthorDto addEpubToAuthor(@NotNull String jwt, long authorId, long epubId) + throws IllegalArgumentException, AuthorizationException, ApiCallException { + if (jwt == null || jwt.isBlank()) { + logger.info("No jwt given"); + throw new IllegalArgumentException("Missing jwt"); + } + + logger.debug("Instantiating request to add epub with id {} to author with id {}", authorId, epubId); + IdDto id = new IdDto(); + id.setId(epubId); + + Request.Builder builder = new Request.Builder() + .put(RequestBody.create(mapper.writeValueAsString(id), EpubClient.APPLICATION_JSON)) + .url(String.format("%/authors/%/epubs", client.url(), "" + authorId)); + + client.addHeaders(builder, jwt, EpubClient.APPLICATION_JSON_STRING, EpubClient.APPLICATION_JSON_STRING); + logger.debug("Instantiated request to add epub to author"); + + AuthorDto dto = null; + try { + dto = client.executeRequest(builder.build(), AuthorDto.class, null, true); + logger.info("Request successful, added epub to author"); + } catch (ForbiddenException | ServerErrorException | UnexpectedStatusException | IOException e) { + throw new ApiCallException(null, e); + } catch (BadRequestException ex) { + logger.info("Epub with given id does not exist"); + return null; + } catch (NotFoundException ex) { + logger.info("Author with given id does not exist"); + return null; + } catch (AuthorizationException ex) { + logger.info("Authorization at the api failed", ex); + throw ex; + } + + if (dto != null) { + client.cacheValue(CacheType.AUTHORS, (Long) authorId, dto); + } + + return dto; + } + } diff --git a/lib/src/main/java/org/koppe/epub/client/EpubClient.java b/lib/src/main/java/org/koppe/epub/client/EpubClient.java index 2b7515d..afcd157 100644 --- a/lib/src/main/java/org/koppe/epub/client/EpubClient.java +++ b/lib/src/main/java/org/koppe/epub/client/EpubClient.java @@ -384,7 +384,7 @@ private V removeFromCache(Cache cache, Object key) throws CachingEx * exception will be thrown. * * @return The login credentials - * @throws CacheMissException If user or password are not cached + * @throws CacheMissException If user or password are not cached * @throws AuthorizationException * @throws ApiCallException */ @@ -447,7 +447,7 @@ private V removeFromCache(Cache cache, Object key) throws CachingEx * cached. * @throws IllegalArgumentException If an invalid epub dto has been given. * @throws ApiCallException If the call to the api itself failed. - * @throws AuthorizationException If session has expired. If you are working + * @throws AuthorizationException If session has expired. If you are working * without cache, call * {@link EpubClient#refreshLogin(String)} * again, otherwise a call to @@ -472,7 +472,7 @@ private V removeFromCache(Cache cache, Object key) throws CachingEx * @throws IllegalStateException If no jwt could be retrieved from the api * and the client is not logged in. * @throws ApiCallException If the call to the api itself failed. - * @throws AuthorizationException If session has expired. If you are working + * @throws AuthorizationException If session has expired. If you are working * without cache, call * {@link EpubClient#refreshLogin(String)} * again, otherwise a call to @@ -494,7 +494,7 @@ private V removeFromCache(Cache cache, Object key) throws CachingEx * been given. * @throws ApiCallException If api call itself failed due to an * exception. - * @throws AuthorizationException If session has expired. If you are working + * @throws AuthorizationException If session has expired. If you are working * without cache, call * {@link EpubClient#refreshLogin(String)} * again, otherwise a call to @@ -519,7 +519,7 @@ private V removeFromCache(Cache cache, Object key) throws CachingEx * @throws IllegalStateException If no session could be created * @throws IllegalArgumentException If username or password are missing * @throws ApiCallException If an error occurred during call to the api - * @throws AuthorizationException If session has expired. If you are working + * @throws AuthorizationException If session has expired. If you are working * without cache, call * {@link EpubClient#refreshLogin(String)} * again, otherwise a call to @@ -539,7 +539,7 @@ private V removeFromCache(Cache cache, Object key) throws CachingEx * @throws CacheMissException If necessary values are not yet cached * @throws IllegalArgumentException If username or password are missing * @throws ApiCallException If an error occurred during call to the api - * @throws AuthorizationException If session has expired. If you are working + * @throws AuthorizationException If session has expired. If you are working * without cache, call * {@link EpubClient#refreshLogin(String)} * again, otherwise a call to @@ -558,7 +558,7 @@ private V removeFromCache(Cache cache, Object key) throws CachingEx * @return The deleted epub * @throws IllegalArgumentException If username or password are missing * @throws ApiCallException If an error occurred during call to the api - * @throws AuthorizationException If session has expired. If you are working + * @throws AuthorizationException If session has expired. If you are working * without cache, call * {@link EpubClient#refreshLogin(String)} * again, otherwise a call to @@ -597,7 +597,7 @@ private V removeFromCache(Cache cache, Object key) throws CachingEx * @return Retrieved epub * @throws IllegalArgumentException If the jwt is token * @throws CacheMissException If credentials are missing in the cache - * @throws AuthorizationException If the session has expired or the api + * @throws AuthorizationException If the session has expired or the api * returned 401 * @throws ApiCallException If a general error occurred while calling * the api @@ -614,7 +614,7 @@ private V removeFromCache(Cache cache, Object key) throws CachingEx * @param epubId Id of the epub to retrieve * @return Retrieved epub or null, if no epub with given id was found * @throws IllegalArgumentException If jwt is missing or blank - * @throws AuthorizationException If the session credentials are invalid + * @throws AuthorizationException If the session credentials are invalid * @throws ApiCallException General api error exception */ private @Nullable EpubDto getEpub(@NotNull String jwt, long epubId, HttpQuery query) @@ -636,7 +636,7 @@ private V removeFromCache(Cache cache, Object key) throws CachingEx * @return Added edition or null, if edition could not be added * @throws CacheMissException If no credentials are cached * @throws ApiCallException General api error - * @throws AuthorizationException If cached credentials have expired + * @throws AuthorizationException If cached credentials have expired * @throws IllegalArgumentException If given edition is missing the version name * or is null * @throws NotFoundException If no epub with given id exists @@ -657,7 +657,7 @@ private V removeFromCache(Cache cache, Object key) throws CachingEx * @param edition Edition of the epub to add * @return Added edition or null, if edition could not be added * @throws ApiCallException General api error - * @throws AuthorizationException If the session has expired + * @throws AuthorizationException If the session has expired * @throws IllegalArgumentException If no username, password, edition or * edition.versionName are given * @throws NotFoundException If no epub with given id exists @@ -680,7 +680,7 @@ private V removeFromCache(Cache cache, Object key) throws CachingEx * @throws IllegalArgumentException If no username, password, edition or * edition.versionName are given * @throws NotFoundException If no epub with given id exists - * @throws AuthorizationException If the session has expired + * @throws AuthorizationException If the session has expired * @throws BadRequestException If the given edition is invalid * @throws ApiCallException General api error */ @@ -702,7 +702,7 @@ private V removeFromCache(Cache cache, Object key) throws CachingEx * @param password Password for logging into the api * @param query Query with epub requirements. Can be null * @return All epubs meeting the requirements - * @throws ApiCallException General api error + * @throws ApiCallException General api error * @throws AuthorizationException If the session has expired */ public @Nullable PagedRequestDto getAllEpubs(@NotNull String username, @NotNull String password, @@ -716,9 +716,9 @@ private V removeFromCache(Cache cache, Object key) throws CachingEx * * @param query Query with epub requirements. Can be null * @return All epubs meeting the requirements - * @throws CacheMissException If no username or password are in the clients - * internal cache - * @throws ApiCallException General api error + * @throws CacheMissException If no username or password are in the clients + * internal cache + * @throws ApiCallException General api error * @throws AuthorizationException If the session has expired */ public @Nullable PagedRequestDto getAllEpubs(@Nullable HttpQuery query) @@ -733,7 +733,7 @@ private V removeFromCache(Cache cache, Object key) throws CachingEx * @param jwt Jwt for logging into the api * @param query Query with requirements for the epubs to be returned. * @return All epubs meeting the requirements - * @throws ApiCallException General api error + * @throws ApiCallException General api error * @throws AuthorizationException If the session has expired */ private @Nullable PagedRequestDto getAllEpubs(@NotNull String jwt, @@ -755,7 +755,7 @@ private V removeFromCache(Cache cache, Object key) throws CachingEx * @throws IllegalArgumentException If one or more arguments are missing * @throws IllegalFileTypeException If the given file is not a .epub file. * @throws ApiCallException General api error - * @throws AuthorizationException If the sessionhas expired + * @throws AuthorizationException If the sessionhas expired * @throws BadRequestException If the request was malformed in some way. */ public void uploadEpub(String username, String password, @NotNull String uploadGuid, @NotNull File epubFile) @@ -773,7 +773,7 @@ public void uploadEpub(String username, String password, @NotNull String uploadG * @throws IllegalArgumentException If one or more arguments are missing * @throws IllegalFileTypeException If the given file is not a .epub file. * @throws ApiCallException General api error - * @throws AuthorizationException If the sessionhas expired + * @throws AuthorizationException If the sessionhas expired * @throws BadRequestException If the request was malformed in some way. * @throws CacheMissException If no credentials are stored in the clients * cache @@ -794,7 +794,7 @@ public void uploadEpub(@NotNull String uploadGuid, @NotNull File epubFile) * @throws IllegalArgumentException If one or more arguments are missing * @throws IllegalFileTypeException If the given file is not a .epub file. * @throws ApiCallException General api error - * @throws AuthorizationException If the sessionhas expired + * @throws AuthorizationException If the sessionhas expired * @throws BadRequestException If the request was malformed in some way. */ private void uploadEpub(@NotNull String jwt, @NotNull String uploadGuid, @NotNull File epubFile) @@ -823,7 +823,7 @@ private void uploadEpub(@NotNull String jwt, @NotNull String uploadGuid, @NotNul * @throws ServerErrorException If the server failed in providing the * download. * @throws ApiCallException General api call exception. - * @throws AuthorizationException If the client could not authenticate at the + * @throws AuthorizationException If the client could not authenticate at the * api. * @throws UnexpectedStatusException If the server responded with an unexpected * status. @@ -849,7 +849,7 @@ private void uploadEpub(@NotNull String jwt, @NotNull String uploadGuid, @NotNul * @throws ServerErrorException If the server failed in providing the * download. * @throws ApiCallException General api call exception. - * @throws AuthorizationException If the client could not authenticate at the + * @throws AuthorizationException If the client could not authenticate at the * api. * @throws CacheMissException If no credentials are stored in the clients * cache. @@ -877,7 +877,7 @@ private void uploadEpub(@NotNull String jwt, @NotNull String uploadGuid, @NotNul * @throws BadRequestException If the download guid is invalid. * @throws ServerErrorException If the server failed in providing the * download. - * @throws AuthorizationException If the jwt is invalid + * @throws AuthorizationException If the jwt is invalid * @throws UnexpectedStatusException If the server responded with an unexpected * status. */ @@ -902,7 +902,7 @@ private void uploadEpub(@NotNull String jwt, @NotNull String uploadGuid, @NotNul * @param editionId Id of the edition to be deleted * @return The deleted epub edition * @throws ApiCallException If the api returned an unexpected status - * @throws AuthorizationException If the credentials are incorrect + * @throws AuthorizationException If the credentials are incorrect * @throws IllegalArgumentException If username or password are not given * @throws NotFoundException If either the epub id or edition id do not * exist @@ -921,7 +921,7 @@ private void uploadEpub(@NotNull String jwt, @NotNull String uploadGuid, @NotNul * @param editionId Id of the edition to be deleted * @return The deleted epub edition * @throws ApiCallException If the api returned an unexpected status - * @throws AuthorizationException If the credentials are incorrect + * @throws AuthorizationException If the credentials are incorrect * @throws IllegalArgumentException If username or password are not given * @throws NotFoundException If either the epub id or edition id do not * exist @@ -942,7 +942,7 @@ private void uploadEpub(@NotNull String jwt, @NotNull String uploadGuid, @NotNul * @param editionId Id of the edition to be deleted * @return The deleted epub edition * @throws ApiCallException If the api returned an unexpected status - * @throws AuthorizationException If the credentials are incorrect + * @throws AuthorizationException If the credentials are incorrect * @throws IllegalArgumentException If username or password are not given * @throws NotFoundException If either the epub id or edition id do not * exist @@ -967,7 +967,7 @@ private void uploadEpub(@NotNull String jwt, @NotNull String uploadGuid, @NotNul * @throws IllegalArgumentException If username, password, author.firstName or * author.surname are not given. * @throws ApiCallException General wrapper for unexpected api behaviour - * @throws AuthorizationException If authentication at the api did not work + * @throws AuthorizationException If authentication at the api did not work * @throws BadRequestException If the author dto was invalid. */ public @Nullable AuthorDto addAuthor(@NotNull String username, @NotNull String password, @@ -985,7 +985,7 @@ private void uploadEpub(@NotNull String jwt, @NotNull String uploadGuid, @NotNul * @throws IllegalArgumentException If author.firstName or * author.surname are not given. * @throws ApiCallException General wrapper for unexpected api behaviour - * @throws AuthorizationException If authentication at the api did not work + * @throws AuthorizationException If authentication at the api did not work * @throws BadRequestException If the author dto was invalid. * @throws CacheMissException If no credentials are cached within the * client. @@ -1005,7 +1005,7 @@ private void uploadEpub(@NotNull String jwt, @NotNull String uploadGuid, @NotNul * @throws IllegalArgumentException If jwt author.firstName or * author.surname are not given. * @throws ApiCallException General wrapper for unexpected api behaviour - * @throws AuthorizationException If authentication at the api did not work + * @throws AuthorizationException If authentication at the api did not work * @throws BadRequestException If the author dto was invalid. */ private @Nullable AuthorDto addAuthor(@NotNull String jwt, @NotNull AuthorDto author) @@ -1036,7 +1036,7 @@ private void uploadEpub(@NotNull String jwt, @NotNull String uploadGuid, @NotNul * @return Requested author. * @throws IllegalArgumentException If username or password are missing * @throws ApiCallException General api error wrapper - * @throws AuthorizationException If client could not authenticate + * @throws AuthorizationException If client could not authenticate */ public @Nullable AuthorDto getAuthor(@NotNull String username, @NotNull String password, long authorId, @Nullable HttpQuery query) throws IllegalArgumentException, ApiCallException, AuthorizationException { @@ -1060,7 +1060,7 @@ private void uploadEpub(@NotNull String jwt, @NotNull String uploadGuid, @NotNul * @param query Query for getting author. * @return Requested author. * @throws CacheMissException - * @throws ApiCallException General api error wrapper + * @throws ApiCallException General api error wrapper * @throws AuthorizationException If client could not authenticate */ public @Nullable AuthorDto getAuthor(long authorId, @Nullable HttpQuery query) @@ -1086,7 +1086,7 @@ private void uploadEpub(@NotNull String jwt, @NotNull String uploadGuid, @NotNul * @return Requested author. * @throws IllegalArgumentException If username or password are missing * @throws ApiCallException General api error wrapper - * @throws AuthorizationException If client could not authenticate + * @throws AuthorizationException If client could not authenticate */ private @Nullable AuthorDto getAuthor(@NotNull String jwt, long authorId, @Nullable HttpQuery query) throws ApiCallException, AuthorizationException { @@ -1108,7 +1108,7 @@ private void uploadEpub(@NotNull String jwt, @NotNull String uploadGuid, @NotNul * are deleted as well. * @return Deleted author * @throws ApiCallException General wrapper for all - * @throws AuthorizationException If authorization failed + * @throws AuthorizationException If authorization failed * @throws IllegalArgumentException If username or password are missing * @throws BadRequestException If the api returned 400 */ @@ -1129,7 +1129,7 @@ private void uploadEpub(@NotNull String jwt, @NotNull String uploadGuid, @NotNul * are deleted as well. * @return Deleted author * @throws ApiCallException General wrapper for all - * @throws AuthorizationException If authorization failed + * @throws AuthorizationException If authorization failed * @throws IllegalArgumentException If credentials are missing * @throws BadRequestException If the api returned 400 * @throws CacheMissException If no credentials are stored in the clients @@ -1152,7 +1152,7 @@ private void uploadEpub(@NotNull String jwt, @NotNull String uploadGuid, @NotNul * are deleted as well. * @return Deleted author * @throws ApiCallException General wrapper for all - * @throws AuthorizationException If authorization failed + * @throws AuthorizationException If authorization failed * @throws IllegalArgumentException If credentials are missing * @throws BadRequestException If the api returned 400 */ @@ -1164,6 +1164,44 @@ private void uploadEpub(@NotNull String jwt, @NotNull String uploadGuid, @NotNul } // #endregion delete author + // #region update author + /** + * Updates author with given author id. If overwrite nulls is set to true, first + * name and surname must be given, as all values not given are overwritten with + * null. + * + * @param username Name of the user to authenticate with at the api. + * @param password Password of the user. + * @param author Update author information + * @param authorId Id of the author + * @param overwriteNulls If set to true, all values not given are set to null. + * First name and surname cannot be overwriten with null. + * @return + * @throws IllegalArgumentException + * @throws ApiCallException + * @throws BadRequestException + * @throws AuthorizationException + */ + public @Nullable AuthorDto updateAuthor(@NotNull String username, @NotNull String password, + @NotNull AuthorDto author, long authorId, boolean overwriteNulls) + throws IllegalArgumentException, ApiCallException, BadRequestException, AuthorizationException { + return updateAuthor(getNewJwt(username, password), author, authorId, overwriteNulls); + } + + public @Nullable AuthorDto updateAuthor(@NotNull AuthorDto author, long authorId, boolean overwriteNulls) + throws IllegalArgumentException, ApiCallException, BadRequestException, AuthorizationException, + CacheMissException { + return updateAuthor(getCurrentJwt(), author, authorId, overwriteNulls); + } + + private @Nullable AuthorDto updateAuthor(@NotNull String jwt, @NotNull AuthorDto dto, long authorId, + boolean overwriteNulls) + throws IllegalArgumentException, ApiCallException, BadRequestException, AuthorizationException { + if (authors == null) + authors = new AuthorAdapter(this); + return authors.updateAuthor(jwt, dto, authorId, overwriteNulls); + } + // #region register cache /** * Adds a new cache type to the clients internal caches, if such a cache type is @@ -1202,7 +1240,7 @@ protected final void addHeaders(@NotNull Request.Builder builder, @NotNull Strin * by calling {@link EpubClient#login()}. * * @return The generated jwt - * @throws CacheMissException If username or password are not in cache + * @throws CacheMissException If username or password are not in cache * @throws AuthorizationException * @throws ApiCallException */ @@ -1248,7 +1286,7 @@ private String getNewJwt(@NotNull String username, @NotNull String password) * @param request Request to be executed * @param type Expected type of the request body * @return The response body or null, if the server answered with 204 - * @throws AuthorizationException If the server answered with 401 + * @throws AuthorizationException If the server answered with 401 * @throws BadRequestException If the server answered with 400 * @throws ForbiddenException If the server answered with 403 * @throws NotFoundException If the server answered with 404 @@ -1329,7 +1367,7 @@ private String getNewJwt(@NotNull String username, @NotNull String password) * @param request Request to be executed * @param type Expected type of the request body * @return The response body or null, if the server answered with 204 - * @throws AuthorizationException If the server answered with 401 + * @throws AuthorizationException If the server answered with 401 * @throws BadRequestException If the server answered with 400 * @throws ForbiddenException If the server answered with 403 * @throws NotFoundException If the server answered with 404 @@ -1429,7 +1467,7 @@ public Object redoRequest(@NotNull String requestGuid) throws AuthorizationExcep * {@link EpubClient#getLastRequestGuid()}. * @param expectedResponseType Type of the expected response * @return Response from the api or null, if the request is not paged. - * @throws AuthorizationException Thrown if session has expired + * @throws AuthorizationException Thrown if session has expired * @throws BadRequestException Thrown if server returned 400 * @throws ForbiddenException Thrown if server returned 403 * @throws NotFoundException Thrown if server returned 404 diff --git a/lib/src/main/java/org/koppe/epub/client/dto/IdDto.java b/lib/src/main/java/org/koppe/epub/client/dto/IdDto.java new file mode 100644 index 0000000..7c9b08c --- /dev/null +++ b/lib/src/main/java/org/koppe/epub/client/dto/IdDto.java @@ -0,0 +1,12 @@ +package org.koppe.epub.client.dto; + +import lombok.Data; + +/** + * Dto that just contains a single id. Mostly used to connect entities with each + * other, for example adding an epub to an author. + */ +@Data +public class IdDto { + private Long id; +} From f096e9bb04ddee7fcdcfae3f1cf349c42bf19e7f Mon Sep 17 00:00:00 2001 From: GeKoppe Date: Tue, 21 Apr 2026 17:49:44 +0200 Subject: [PATCH 6/6] Updated changelog --- doc/changelog.md | 18 ++++++++++++++++++ lib/build.gradle | 2 +- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/doc/changelog.md b/doc/changelog.md index 998fa7e..bc5829a 100644 --- a/doc/changelog.md +++ b/doc/changelog.md @@ -1,5 +1,23 @@ # Changelog +## 0.0.3 + +**Type**: Pre-release + +**Description**: Secondary test of publishing. This release was published to test implementation in another project. Don't use this! + +**Features**: + +More author functions have been added. + +**Fixes**: + +None + +**Known Issues**: + +- Many (as I said, don't use this.) + ## 0.0.2 **Type**: Pre-release diff --git a/lib/build.gradle b/lib/build.gradle index d4813b4..f961973 100644 --- a/lib/build.gradle +++ b/lib/build.gradle @@ -5,7 +5,7 @@ plugins { } group = 'org.koppe.epub.client' -version = '0.0.2' +version = '0.0.3' description = 'Client library for an epub library application' repositories {