package com.alorma.github.sdk.services.client; import com.alorma.gitskarios.core.client.PaginationLink; import com.alorma.gitskarios.core.client.RelType; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import retrofit.Callback; import retrofit.RetrofitError; import retrofit.client.Header; import retrofit.client.Response; import rx.Observable; import rx.Subscriber; public abstract class BaseInfiniteCallback<K> implements Observable.OnSubscribe<K>, Callback<K> { protected Subscriber<? super K> subscriber; private List<K> ks; private int lastUsedPage; public BaseInfiniteCallback() { } @Override public void call(Subscriber<? super K> subscriber) { this.subscriber = subscriber; ks = new ArrayList<>(); execute(); } @Override public void success(K k, Response response) { int nextPage = getLinkData(response); subscriber.onNext(k); if (nextPage != -1) { lastUsedPage = nextPage; executePaginated(nextPage); } else { subscriber.onCompleted(); } } public abstract void execute(); protected abstract void executePaginated(int nextPage); @Override public void failure(RetrofitError error) { subscriber.onError(error); } public int getLinkData(Response r) { List<Header> headers = r.getHeaders(); Map<String, String> headersMap = new HashMap<String, String>(headers.size()); for (Header header : headers) { headersMap.put(header.getName(), header.getValue()); } String link = headersMap.get("Link"); if (link != null) { String[] parts = link.split(","); Map<RelType, PaginationLink> linkMap = new HashMap<>(); for (String part : parts) { PaginationLink paginationLink = new PaginationLink(part); linkMap.put(paginationLink.rel, paginationLink); } PaginationLink next = linkMap.get(RelType.next); if (next != null) { int nextPage = next.page; return lastUsedPage != nextPage ? nextPage : -1; } } return -1; } }