package com.stripe.model;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.NoSuchElementException;
import com.stripe.Stripe;
import com.stripe.net.APIResource;
import com.stripe.net.RequestOptions;
public class PagingIterator<T extends HasId> extends APIResource implements Iterator<T> {
private final String url;
@SuppressWarnings("rawtypes")
private final Class<? extends StripeCollectionInterface> collectionType;
private StripeCollectionInterface<T> currentCollection;
private Iterator<T> currentDataIterator;
private String lastId;
PagingIterator(final StripeCollectionInterface<T> stripeCollection) {
this.url = Stripe.getApiBase() + stripeCollection.getURL();
this.collectionType = stripeCollection.getClass();
this.currentCollection = stripeCollection;
this.currentDataIterator = stripeCollection.getData().iterator();
}
@Override
public boolean hasNext() {
return currentDataIterator.hasNext() ||
currentCollection.getHasMore();
}
@Override
public T next() {
// if we've run out of data on the current page, try to fetch another
// one
if (!currentDataIterator.hasNext() && currentCollection.getHasMore()) {
try {
Map<String, Object> params = new HashMap<String, Object>();
// copy all the parameters from the initial request
Map<String, Object> initialParams = currentCollection.getRequestParams();
if (initialParams != null) {
params.putAll(initialParams);
}
// then put our new page start in
params.put("starting_after", lastId);
this.currentCollection = list(params, currentCollection.getRequestOptions());
this.currentDataIterator =
currentCollection.getData().iterator();
} catch (final Exception e) {
throw new RuntimeException("Unable to lazy-load stripe objects", e);
}
}
if (currentDataIterator.hasNext()) {
final T next = currentDataIterator.next();
this.lastId = next.getId();
return next;
}
throw new NoSuchElementException();
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
@SuppressWarnings("unchecked")
private StripeCollectionInterface<T> list(
final Map<String, Object> params,
final RequestOptions options
) throws Exception {
return APIResource.requestCollection(url, params, collectionType, options);
}
}