Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix IndexOutOfBoundsException when using an iterator #405

Merged
merged 5 commits into from
Oct 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>dev.katsute</groupId>
<artifactId>mal4j</artifactId>
<version>3.4.0</version>
<version>3.4.1</version>

<profiles>
<profile>
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/dev/katsute/mal4j/Logging.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public static Logger getLogger(){

// debug

private static boolean debug = false;
private static boolean debug = false; // do not edit this flag for tests, change in TestProvider

static void setDebug(final boolean debug){
Logging.debug = debug;
Expand Down
22 changes: 20 additions & 2 deletions src/main/java/dev/katsute/mal4j/MyAnimeListImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -969,6 +969,8 @@ private static class PagedIterator<T> extends PaginatedIterator<T> {

private final AtomicReference<Integer> nextOffset = new AtomicReference<>();

private JsonObject nextPage = null; // pre-fetch next page #404

PagedIterator(
final Integer offset,
final Function<Integer,Response<JsonObject>> fullPageSupplier,
Expand All @@ -991,13 +993,15 @@ final boolean hasNextPage(){
@SuppressWarnings("DataFlowIssue")
@Override
synchronized final List<T> getNextPage(){
final JsonObject response = handleResponse(() -> fullPageSupplier.apply(nextOffset.get()));
// use pre-fetched next page or fetch the first page
final JsonObject response = nextPage != null ? nextPage : handleResponse(() -> fullPageSupplier.apply(nextOffset.get()));

if(response == null){
nextOffset.set(-1);
return null;
}

// convert response to list
final List<T> list = new ArrayList<>();
for(final JsonObject data :
response.get("data") instanceof JsonObject && response.getJsonObject("data").containsKey("posts") // post iterator support
Expand All @@ -1006,11 +1010,25 @@ synchronized final List<T> getNextPage(){
)
list.add(listAdapter.apply(data));

// handle next offset
if(response.getJsonObject("paging").containsKey("next")){
final Integer b4 = nextOffset.get();
nextOffset.set((b4 == null ? 0 : b4) + list.size());
return list;

// peek into next page #404
nextPage = handleResponse(() -> fullPageSupplier.apply(nextOffset.get()));

if( // check if next page actually has any content
(nextPage.get("data") instanceof JsonObject && nextPage.getJsonObject("data").containsKey("posts") // post iterator support
? nextPage.getJsonObject("data").getJsonArray("posts")
: nextPage.getJsonArray("data"))
.length > 0
)
return list;
}

// last page
nextPage = null;
nextOffset.set(-1);

return list;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ static void beforeAll(){
final void testStatus(){
final List<AnimeListStatus> list =
mal.getUserAnimeListing()
.withStatus(AnimeStatus.Dropped)
.withStatus(AnimeStatus.Completed)
.withFields(Fields.Anime.list_status)
.withLimit(1)
.search();
assertEquals(AnimeStatus.Dropped, list.get(0).getStatus());
assertEquals(AnimeStatus.Completed, list.get(0).getStatus());
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ static void beforeAll(){
final void testStatus(){
final List<MangaListStatus> list =
mal.getUserMangaListing()
.withStatus(MangaStatus.PlanToRead)
.withStatus(MangaStatus.Completed)
.withLimit(1)
.withFields(Fields.Manga.list_status)
.search();
assertEquals(MangaStatus.PlanToRead, list.get(0).getStatus());
assertEquals(MangaStatus.Completed, list.get(0).getStatus());
}

@Test
Expand Down