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

jp.gopay.sdk.models.response.PaginatedListIterator Maven / Gradle / Ivy

There is a newer version: 0.11.17
Show newest version
package jp.gopay.sdk.models.response;

import com.google.gson.annotations.SerializedName;
import jp.gopay.sdk.builders.RetrofitRequestBuilderPaginated;
import jp.gopay.sdk.models.common.BaseId;
import jp.gopay.sdk.models.errors.GoPayException;
import jp.gopay.sdk.models.errors.TooManyRequestsException;
import jp.gopay.sdk.types.CursorDirection;
import jp.gopay.sdk.utils.Backoff;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.concurrent.TimeoutException;

public class PaginatedListIterator extends GoPayResponse implements GoPayPaginatedListIterator {

    public PaginatedListIterator(RetrofitRequestBuilderPaginated lastBuilder, long timeoutMilliSec, Backoff backoff) {
        this.items = new ArrayList<>();
        this.hasMore = true;
        this.lastBuilder = lastBuilder;
        this.nextCursor = lastBuilder.getCursor();
        this.timeoutMilliSec = timeoutMilliSec;
        this.backoff = backoff;
    }

    @SerializedName("items")
    private List items;

    @SerializedName("has_more")
    private Boolean hasMore;

    private RetrofitRequestBuilderPaginated lastBuilder;
    private BaseId nextCursor;
    private Backoff backoff;
    private long timeoutMilliSec;

    boolean isNotFirstTime() {
        return (!items.isEmpty() || !hasMore);
    }
    void setNextCursor(BaseId nextCursor) {
        this.nextCursor = nextCursor;
    }
    void setHasMore(boolean hasMore) {
        this.hasMore = hasMore;
    }

    @Override
    public boolean hasNext() {
        return hasMore;
    }

    /**
     * Get a next page from API if it has more pages.
     *
     * @return items
     */
    @Override
    public List next() {
        if (lastBuilder == null || backoff == null) {
            throw new UnsupportedOperationException("use 'RetrofitRequestBuilderPaginated.asIterable()' before use 'next()' ");
        }
        if (!hasMore) {
            throw new NoSuchElementException();
        }

        PaginatedList dispatchedList;
        if (isNotFirstTime()) {
            lastBuilder.setCursor(nextCursor);
        }
        dispatchedList = await();
        items = dispatchedList.getItems();
        hasMore = dispatchedList.getHasMore();
        if (!items.isEmpty()) {
            nextCursor = items.get(items.size() - 1).getId();
        }

        return items;
    }

    private PaginatedList await() {
        PaginatedList dispatchedList;

        backoff.reset();
        final long startTime = System.currentTimeMillis();

        do {
            if (System.currentTimeMillis() - startTime > timeoutMilliSec) {
                throw new IllegalStateException(
                        new TimeoutException(String.format("Retry timeout exceeded : %dms ", timeoutMilliSec)));
            }

            try {
                dispatchedList = (PaginatedList) lastBuilder.build().dispatch();
            } catch (TooManyRequestsException | IOException e) {
                dispatchedList = null;
                try {
                    Thread.sleep(backoff.next());
                } catch (InterruptedException  eb){
                    throw new IllegalStateException(eb);
                }
            } catch (GoPayException e) {
                throw new IllegalStateException(e);
            }
        } while(dispatchedList == null);

        return dispatchedList;
    }

    @Override
    public void remove() {
        throw new UnsupportedOperationException("remove");
    }

    public GoPayPaginatedListIterator reverse() {
        CursorDirection cursorDirection =
                (lastBuilder.getCursorDirection() == CursorDirection.ASC) ? CursorDirection.DESC : CursorDirection.ASC;
        lastBuilder.setCursorDirection(cursorDirection);

        if (isNotFirstTime()) {
            if (!items.isEmpty()) {
                nextCursor = items.get(0).getId();
            }
            lastBuilder.setCursor(nextCursor);
            hasMore = true;
        }

        return this;
    }

    public List getItems() {
        return Collections.unmodifiableList(items);
    }

    public Boolean getHasMore() {
        return hasMore;
    }

    public RetrofitRequestBuilderPaginated getLastBuilder() {
        return lastBuilder;
    }

    public BaseId getNextCursor() {
        return nextCursor;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy