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

com.amazonaws.services.dynamodb.datamodeling.PaginatedList Maven / Gradle / Ivy

Go to download

The Amazon Web Services SDK for Java provides Java APIs for building software on AWS' cost-effective, scalable, and reliable infrastructure products. The AWS Java SDK allows developers to code against APIs for all of Amazon's infrastructure web services (Amazon S3, Amazon EC2, Amazon SQS, Amazon Relational Database Service, Amazon AutoScaling, etc).

The newest version!
/*
 * Copyright 2011-2014 Amazon Technologies, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *    http://aws.amazon.com/apache2.0
 *
 * This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
 * OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and
 * limitations under the License.
 */
package com.amazonaws.services.dynamodb.datamodeling;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.NoSuchElementException;

import com.amazonaws.services.dynamodb.AmazonDynamoDB;

/**
 * Unmodifiable list supporting paginated result sets from Amazon DynamoDB.
 * 

* Pages of results are fetched lazily from DynamoDB as they are needed. Some * methods, such as {@link PaginatedList#size()} and * {@link PaginatedList#toArray()}, require fetching the entire result set * eagerly. See the javadoc of individual methods for details on which are lazy. * * @param * The domain object type stored in this list. * * @deprecated Use {@link com.amazonaws.services.dynamodbv2.datamodeling.PaginatedList} instead. */ @Deprecated public abstract class PaginatedList implements List { private static final String UNMODIFIABLE_MESSAGE = "This is an unmodifiable list"; /** * Reference to the DynamoDB mapper for marshalling DynamoDB attributes back * into objects */ protected final DynamoDBMapper mapper; /** * The class annotated with DynamoDB tags declaring how to load/store * objects into DynamoDB */ protected final Class clazz; /** The client for working with DynamoDB */ protected final AmazonDynamoDB dynamo; /** Tracks if all results have been loaded yet or not */ protected boolean allResultsLoaded = false; /** All currently loaded results for this list */ protected final List allResults; /** Lazily loaded next results waiting to be added into allResults */ protected final List nextResults = new LinkedList(); public PaginatedList(DynamoDBMapper mapper, Class clazz, AmazonDynamoDB dynamo) { this.mapper = mapper; this.clazz = clazz; this.dynamo = dynamo; this.allResults = new ArrayList(); } /** * Eagerly loads all results for this list. */ public synchronized void loadAllResults() { if ( allResultsLoaded ) return; while ( nextResultsAvailable() ) { moveNextResults(); } allResultsLoaded = true; } /** * Returns whether there are more results available not yet included in the * allResults member field. These could already have been fetched and are * sitting in the nextResults buffer, or they could be fetched from the * service opportunistically at the time this method is called. A return * value of true guarantees that nextResults is non-empty. */ private boolean nextResultsAvailable() { return !nextResults.isEmpty() || loadNextResults(); } /** * Attempts to load the next batch of results, if there are any, into the * nextResults buffer. Returns whether there were any results to load. A * return value of true guarantees that nextResults had items added to it. */ private synchronized boolean loadNextResults() { if ( atEndOfResults() ) return false; do { nextResults.addAll(fetchNextPage()); } while ( !atEndOfResults() && nextResults.isEmpty() ); return !nextResults.isEmpty(); } /** * Moves the contents of the nextResults buffer into allResults and resets * the buffer. */ private void moveNextResults() { allResults.addAll(nextResults); nextResults.clear(); } /** * Fetches the next page of results (which may be empty) and returns any * items found. */ protected abstract List fetchNextPage(); /** * Returns whether we have reached the end of the result set. */ protected abstract boolean atEndOfResults(); /** * Returns an iterator over this list that lazily initializes results as * necessary. */ @Override public Iterator iterator() { /* * We make a copy of the allResults list to iterate over in order to * avoid ConcurrentModificationExceptions caused by other methods * loading more results into the list while someone iterates over it. * This is a more severe problem than it might seem, because even * innocuous-seeming operations such as contains() can modify the * underlying result set. */ final List allResultsCopy = new ArrayList(); allResultsCopy.addAll(allResults); final Iterator iter = allResultsCopy.iterator(); return new Iterator() { Iterator iterator = iter; int pos = 0; @Override public boolean hasNext() { return iterator.hasNext() || nextResultsAvailable(); } @Override public T next() { if ( !iterator.hasNext() ) { /* * Our private copy of the result list may be out of date * with the full one. If it is, we just need to update our * private copy to get more results. If it's not, we need to * fetch more results from the service. */ if ( allResults.size() == allResultsCopy.size() ) { if ( !nextResultsAvailable() ) { throw new NoSuchElementException(); } moveNextResults(); } if ( allResults.size() > allResultsCopy.size() ) allResultsCopy.addAll(allResults.subList(allResultsCopy.size(), allResults.size())); iterator = allResultsCopy.listIterator(pos); } pos++; return iterator.next(); } @Override public void remove() { throw new UnsupportedOperationException(UNMODIFIABLE_MESSAGE); } }; } /** * Returns whether the collection is empty. At most one (non-empty) page of * results is loaded to make the check. */ @Override public boolean isEmpty() { return !iterator().hasNext(); } /** * Returns the Nth element of the list. Results are loaded until N elements * are present, if necessary. */ @Override public T get(int n) { while ( allResults.size() <= n && nextResultsAvailable() ) { moveNextResults(); } return allResults.get(n); } /** * Returns whether the collection contains the given element. Results are * loaded and checked incrementally until a match is found or the end of the * result set is reached. */ @Override public boolean contains(Object arg0) { if ( allResults.contains(arg0) ) return true; while ( nextResultsAvailable() ) { boolean found = nextResults.contains(arg0); moveNextResults(); if ( found ) return true; } return false; } /** * Returns a sub-list in the range specified, loading more results as * necessary. */ @Override public List subList(int arg0, int arg1) { while ( allResults.size() < arg1 && nextResultsAvailable() ) { moveNextResults(); } return Collections.unmodifiableList(allResults.subList(arg0, arg1)); } /** * Returns the first index of the object given in the list. Additional * results are loaded incrementally as necessary. */ @Override public int indexOf(Object arg0) { int indexOf = allResults.indexOf(arg0); if ( indexOf >= 0 ) return indexOf; while ( nextResultsAvailable() ) { indexOf = nextResults.indexOf(arg0); int size = allResults.size(); moveNextResults(); if ( indexOf >= 0 ) return indexOf + size; } return -1; } // Operations requiring the entire result set @Override public int size() { loadAllResults(); return allResults.size(); } @Override public boolean containsAll(Collection arg0) { loadAllResults(); return allResults.containsAll(arg0); } @Override public int lastIndexOf(Object arg0) { loadAllResults(); return allResults.lastIndexOf(arg0); } @Override public Object[] toArray() { loadAllResults(); return allResults.toArray(); } @Override public X[] toArray(X[] a) { loadAllResults(); return allResults.toArray(a); } // Unsupported Operations @Override public ListIterator listIterator() { throw new UnsupportedOperationException("ListIterators are not supported for this list"); } @Override public ListIterator listIterator(int arg0) { throw new UnsupportedOperationException("ListIterators are not supported for this list"); } @Override public boolean remove(Object arg0) { throw new UnsupportedOperationException(UNMODIFIABLE_MESSAGE); } @Override public T remove(int arg0) { throw new UnsupportedOperationException(UNMODIFIABLE_MESSAGE); } @Override public boolean removeAll(Collection arg0) { throw new UnsupportedOperationException(UNMODIFIABLE_MESSAGE); } @Override public boolean retainAll(Collection arg0) { throw new UnsupportedOperationException(UNMODIFIABLE_MESSAGE); } @Override public T set(int arg0, T arg1) { throw new UnsupportedOperationException(UNMODIFIABLE_MESSAGE); } @Override public boolean add(T arg0) { throw new UnsupportedOperationException(UNMODIFIABLE_MESSAGE); } @Override public void add(int arg0, T arg1) { throw new UnsupportedOperationException(UNMODIFIABLE_MESSAGE); } @Override public boolean addAll(Collection arg0) { throw new UnsupportedOperationException(UNMODIFIABLE_MESSAGE); } @Override public boolean addAll(int arg0, Collection arg1) { throw new UnsupportedOperationException(UNMODIFIABLE_MESSAGE); } @Override public void clear() { throw new UnsupportedOperationException(UNMODIFIABLE_MESSAGE); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy