CursorEntityIterator.java revision 328c0e7986aa6bb7752ec6de3da9c999920bb55f
1package android.content;
2
3import android.database.Cursor;
4import android.os.RemoteException;
5
6/**
7 * Abstract implementation of EntityIterator that makes it easy to wrap a cursor
8 * that can contain several consecutive rows for an entity.
9 * @hide
10 */
11public abstract class CursorEntityIterator implements EntityIterator {
12    private final Cursor mCursor;
13    private boolean mIsClosed;
14
15    /**
16     * Constructor that makes initializes the cursor such that the iterator points to the
17     * first Entity, if there are any.
18     * @param cursor the cursor that contains the rows that make up the entities
19     */
20    public CursorEntityIterator(Cursor cursor) {
21        mIsClosed = false;
22        mCursor = cursor;
23        mCursor.moveToFirst();
24    }
25
26    /**
27     * Returns the entity that the cursor is currently pointing to. This must take care to advance
28     * the cursor past this entity. This will never be called if the cursor is at the end.
29     * @param cursor the cursor that contains the entity rows
30     * @return the entity that the cursor is currently pointing to
31     * @throws RemoteException if a RemoteException is caught while attempting to build the Entity
32     */
33    public abstract Entity getEntityAndIncrementCursor(Cursor cursor) throws RemoteException;
34
35    /**
36     * Returns whether there are more elements to iterate, i.e. whether the
37     * iterator is positioned in front of an element.
38     *
39     * @return {@code true} if there are more elements, {@code false} otherwise.
40     * @see #next
41     */
42    public final boolean hasNext() throws RemoteException {
43        if (mIsClosed) {
44            throw new IllegalStateException("calling hasNext() when the iterator is closed");
45        }
46
47        return !mCursor.isAfterLast();
48    }
49
50    /**
51     * Returns the next object in the iteration, i.e. returns the element in
52     * front of the iterator and advances the iterator by one position.
53     *
54     * @return the next object.
55     * @throws java.util.NoSuchElementException
56     *             if there are no more elements.
57     * @see #hasNext
58     */
59    public Entity next() throws RemoteException {
60        if (mIsClosed) {
61            throw new IllegalStateException("calling next() when the iterator is closed");
62        }
63        if (!hasNext()) {
64            throw new IllegalStateException("you may only call next() if hasNext() is true");
65        }
66
67        return getEntityAndIncrementCursor(mCursor);
68    }
69
70    public final void reset() throws RemoteException {
71        if (mIsClosed) {
72            throw new IllegalStateException("calling reset() when the iterator is closed");
73        }
74        mCursor.moveToFirst();
75    }
76
77    /**
78     * Indicates that this iterator is no longer needed and that any associated resources
79     * may be released (such as a SQLite cursor).
80     */
81    public final void close() {
82        if (mIsClosed) {
83            throw new IllegalStateException("closing when already closed");
84        }
85        mIsClosed = true;
86        mCursor.close();
87    }
88}
89