package com.twilio.base; import com.twilio.http.TwilioRestClient; import java.util.Iterator; import java.util.NoSuchElementException; /** * A collection of resources. * * @param <E> type of the resource */ public class ResourceSet<E extends Resource> implements Iterable<E> { private final Reader<E> reader; private final TwilioRestClient client; private boolean autoPaging; private long pages = 1; private long pageLimit = Long.MAX_VALUE; private long processed = 0; private Page<E> page; private Iterator<E> iterator; /** * Initialize the resource set. * * @param reader reader used to fetch next page * @param client client used to make requests * @param page page of data */ public ResourceSet(final Reader<E> reader, final TwilioRestClient client, final Page<E> page) { this.reader = reader; this.client = client; this.page = page; this.iterator = page.getRecords().iterator(); this.autoPaging = true; if (reader.getLimit() != null) { this.pageLimit = (long)(Math.ceil((double)reader.getLimit() / (double)page.getPageSize())); } } public boolean isAutoPaging() { return autoPaging; } public ResourceSet setAutoPaging(final boolean autoPaging) { this.autoPaging = autoPaging; return this; } public Integer getPageSize() { return page.getPageSize(); } public ResourceSet<E> setPageSize(final int pageSize) { reader.pageSize(pageSize); return this; } public Long getLimit() { return reader.getLimit(); } public ResourceSet<E> setLimit(final long limit) { reader.limit(limit); return this; } public long getPageLimit() { return pageLimit; } @Override public Iterator<E> iterator() { return new ResourceSetIterator<>(this); } private void fetchNextPage() { if (!page.hasNextPage() || pages >= pageLimit) { return; } pages++; page = reader.nextPage(page, client); iterator = page.getRecords().iterator(); } private class ResourceSetIterator<E extends Resource> implements Iterator<E> { private final ResourceSet<E> resourceSet; public ResourceSetIterator(final ResourceSet<E> resourceSet) { this.resourceSet = resourceSet; } @Override public boolean hasNext() { if (resourceSet.getLimit() != null && resourceSet.processed >= resourceSet.getLimit()) { return false; } return resourceSet.iterator.hasNext(); } @Override public E next() { if (resourceSet == null || resourceSet.iterator == null) { throw new NoSuchElementException(); } E element = resourceSet.iterator.next(); if (resourceSet.isAutoPaging() && !resourceSet.iterator.hasNext()) { resourceSet.fetchNextPage(); } resourceSet.processed++; return element; } @Override public void remove() { if (resourceSet.iterator != null) { resourceSet.processed++; resourceSet.iterator.remove(); } } } }