115a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root/*
215a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * Copyright (C) 2009 The Android Open Source Project
315a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root *
415a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * Licensed under the Apache License, Version 2.0 (the "License");
515a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * you may not use this file except in compliance with the License.
615a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * You may obtain a copy of the License at
715a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root *
815a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root *      http://www.apache.org/licenses/LICENSE-2.0
915a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root *
1015a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * Unless required by applicable law or agreed to in writing, software
1115a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * distributed under the License is distributed on an "AS IS" BASIS,
1215a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1315a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * See the License for the specific language governing permissions and
1415a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * limitations under the License.
1515a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root */
1615a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root
172ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintanapackage android.content;
182ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana
192ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintanaimport android.database.Cursor;
202ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintanaimport android.os.RemoteException;
212ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana
222ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana/**
232ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana * Abstract implementation of EntityIterator that makes it easy to wrap a cursor
242ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana * that can contain several consecutive rows for an entity.
252ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana * @hide
262ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana */
272ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintanapublic abstract class CursorEntityIterator implements EntityIterator {
282ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana    private final Cursor mCursor;
292ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana    private boolean mIsClosed;
302ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana
312ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana    /**
322ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana     * Constructor that makes initializes the cursor such that the iterator points to the
332ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana     * first Entity, if there are any.
342ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana     * @param cursor the cursor that contains the rows that make up the entities
352ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana     */
362ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana    public CursorEntityIterator(Cursor cursor) {
372ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana        mIsClosed = false;
382ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana        mCursor = cursor;
392ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana        mCursor.moveToFirst();
402ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana    }
412ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana
422ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana    /**
432ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana     * Returns the entity that the cursor is currently pointing to. This must take care to advance
442ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana     * the cursor past this entity. This will never be called if the cursor is at the end.
452ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana     * @param cursor the cursor that contains the entity rows
462ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana     * @return the entity that the cursor is currently pointing to
472ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana     * @throws RemoteException if a RemoteException is caught while attempting to build the Entity
482ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana     */
492ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana    public abstract Entity getEntityAndIncrementCursor(Cursor cursor) throws RemoteException;
502ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana
512ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana    /**
522ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana     * Returns whether there are more elements to iterate, i.e. whether the
532ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana     * iterator is positioned in front of an element.
542ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana     *
552ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana     * @return {@code true} if there are more elements, {@code false} otherwise.
56d5e4fdc8a4743abc0d9fe3cb952a78f9ad078c6bFred Quintana     * @see EntityIterator#next()
572ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana     */
58d5e4fdc8a4743abc0d9fe3cb952a78f9ad078c6bFred Quintana    public final boolean hasNext() {
592ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana        if (mIsClosed) {
602ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana            throw new IllegalStateException("calling hasNext() when the iterator is closed");
612ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana        }
622ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana
632ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana        return !mCursor.isAfterLast();
642ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana    }
652ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana
662ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana    /**
672ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana     * Returns the next object in the iteration, i.e. returns the element in
682ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana     * front of the iterator and advances the iterator by one position.
692ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana     *
702ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana     * @return the next object.
712ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana     * @throws java.util.NoSuchElementException
722ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana     *             if there are no more elements.
73d5e4fdc8a4743abc0d9fe3cb952a78f9ad078c6bFred Quintana     * @see EntityIterator#hasNext()
742ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana     */
75d5e4fdc8a4743abc0d9fe3cb952a78f9ad078c6bFred Quintana    public Entity next() {
762ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana        if (mIsClosed) {
772ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana            throw new IllegalStateException("calling next() when the iterator is closed");
782ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana        }
792ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana        if (!hasNext()) {
802ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana            throw new IllegalStateException("you may only call next() if hasNext() is true");
812ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana        }
822ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana
83d5e4fdc8a4743abc0d9fe3cb952a78f9ad078c6bFred Quintana        try {
84d5e4fdc8a4743abc0d9fe3cb952a78f9ad078c6bFred Quintana            return getEntityAndIncrementCursor(mCursor);
85d5e4fdc8a4743abc0d9fe3cb952a78f9ad078c6bFred Quintana        } catch (RemoteException e) {
86d5e4fdc8a4743abc0d9fe3cb952a78f9ad078c6bFred Quintana            throw new RuntimeException("caught a remote exception, this process will die soon", e);
87d5e4fdc8a4743abc0d9fe3cb952a78f9ad078c6bFred Quintana        }
88d5e4fdc8a4743abc0d9fe3cb952a78f9ad078c6bFred Quintana    }
89d5e4fdc8a4743abc0d9fe3cb952a78f9ad078c6bFred Quintana
90d5e4fdc8a4743abc0d9fe3cb952a78f9ad078c6bFred Quintana    public void remove() {
91d5e4fdc8a4743abc0d9fe3cb952a78f9ad078c6bFred Quintana        throw new UnsupportedOperationException("remove not supported by EntityIterators");
922ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana    }
932ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana
94d5e4fdc8a4743abc0d9fe3cb952a78f9ad078c6bFred Quintana    public final void reset() {
952ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana        if (mIsClosed) {
962ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana            throw new IllegalStateException("calling reset() when the iterator is closed");
972ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana        }
982ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana        mCursor.moveToFirst();
992ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana    }
1002ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana
1012ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana    /**
1022ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana     * Indicates that this iterator is no longer needed and that any associated resources
1032ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana     * may be released (such as a SQLite cursor).
1042ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana     */
1052ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana    public final void close() {
1062ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana        if (mIsClosed) {
1072ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana            throw new IllegalStateException("closing when already closed");
1082ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana        }
1092ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana        mIsClosed = true;
1102ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana        mCursor.close();
1112ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana    }
1122ec6c5699181316e5a5c2cd293c006ac4a8bb101Fred Quintana}
113