/* XXL: The eXtensible and fleXible Library for data processing Copyright (C) 2000-2011 Prof. Dr. Bernhard Seeger Head of the Database Research Group Department of Mathematics and Computer Science University of Marburg Germany This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; If not, see <http://www.gnu.org/licenses/>. http://code.google.com/p/xxl/ */ package xxl.core.cursors.sources; import xxl.core.cursors.AbstractCursor; /** * An enumerator returns an ascending or descending sequence of integer objects * within an optional given range. There are three different ways to generate * integer objects with an enumerator: * <ul> * <li> * Specifying a range, i.e., the start- and end-position are user * defined. * </li> * <li> * Specifying only the end-position; <code>start =Bnbsp;0</code>. * </li> * <li> * Specifying no range; <code>start = 0</code>, * <code>end = {@link java.lang.Integer#MAX_VALUE}</code>. * </li> * </ul> * In the first case an ascending or a descending sequence can be generated * depending on the given start- and end-position.<br /> * <b>Note:</b> The start-position of the integer sequence will be returned by * the enumerator, but not the end-position! So only the integer elements of * the interval [<code>start</code>, <code>end</code>) will be returned by the * enumerator. * * <p><b>Example usage (1):</b> * <code><pre> * Enumerator enumerator = new Enumerator(0, 11); * * enumerator.open(); * * while (enumerator.hasNext()) * System.out.println(enumerator.next()); * * enumerator.close(); * </pre></code> * This example prints the numbers 0,...,10 to the output stream.</p> * * <p><b>Example usage (2):</b> * <code><pre> * enumerator = new Enumerator(10, -1); * * enumerator.open(); * * while (enumerator.hasNext()) * System.out.println(enumerator.next()); * * enumerator.close(); * </pre></code> * This example prints the numbers 10,...,0 to the output stream.</p> * * <p><b>Example usage (3):</b> * <code><pre> * enumerator = new Enumerator(11); * * enumerator.open(); * * while (enumerator.hasNext()) * System.out.println(enumerator.next()); * * enumerator.close(); * </pre></code> * This example prints the numbers 0,...,10 to the output stream using only a * specified end position.</p> * * @see java.util.Iterator * @see xxl.core.cursors.Cursor */ public class Enumerator extends AbstractCursor<Integer> { /** * The start of the returned integer sequence (inclusive). */ protected int from; /** * The end of the returned integer sequence (exclusive). */ protected int to; /** * The int value returned by the next call to <code>next</code> or * <code>peek</code>. */ protected int nextInt; /** * If <code>true</code> the sequence is ascending, else the sequence is * descending. */ protected boolean up; /** * Creates a new enumerator instance with a specified range, i.e., the * start- and an end-position must be defined. * * @param from start of the returned integer sequence (inclusive). * @param to end of the returned integer sequence (exclusive). */ public Enumerator(int from, int to) { this.from = from; this.to = to; this.up = from <= to; this.nextInt = from; } /** * Creates a new enumerator instance with a user defined end position, * i.e., the returned integer sequence starts with <code>0</code> and ends * with <code>number-1</code>. * * @param number the end of the returned integer sequence (exclusive). */ public Enumerator(int number) { this(0, number); } /** * Creates an enumerator instance. The returned integer sequence starts * with <code>0</code> and ends with * <code>{@link java.lang.Integer#MAX_VALUE}-1</code>. */ public Enumerator() { this(0, Integer.MAX_VALUE); } /** * Returns <code>true</code> if the iteration has more elements. (In other * words, returns <code>true</code> if <code>next</code> or * <code>peek</code> would return an element rather than throwing an * exception.) * * @return <code>true</code> if the enumerator has more elements. */ protected boolean hasNextObject() { return up ? nextInt < to : nextInt > to; } /** * Returns the next element in the iteration. This element will be * accessible by some of the enumerator's methods, e.g., * <code>update</code> or <code>remove</code>, until a call to * <code>next</code> or <code>peek</code> occurs. This is calling * <code>next</code> or <code>peek</code> proceeds the iteration and * therefore its previous element will not be accessible any more. * * @return the next element in the iteration. */ protected Integer nextObject() { return up ? nextInt++ : nextInt--; } /** * Resets the enumerator to its initial state such that the caller is able * to traverse the iteration again without constructing a new enumerator * (optional operation). * * <p>Note, that this operation is optional and might not work for all * cursors.</p> * * @throws UnsupportedOperationException if the <code>reset</code> * operation is not supported by the enumerator. */ public void reset() throws UnsupportedOperationException { super.reset(); nextInt = from; } /** * Returns <code>true</code> if the <code>reset</code> operation is * supported by the enumerator. Otherwise it returns <code>false</code>. * * @return <code>true</code> if the <code>reset</code> operation is * supported by the enumerator, otrwise <code>false</code>. */ public boolean supportsReset() { return true; } }