Home | History | Annotate | Download | only in content
      1 /*
      2  * Copyright (C) 2009 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.content;
     18 
     19 import android.database.Cursor;
     20 import android.os.RemoteException;
     21 
     22 /**
     23  * Abstract implementation of EntityIterator that makes it easy to wrap a cursor
     24  * that can contain several consecutive rows for an entity.
     25  * @hide
     26  */
     27 public abstract class CursorEntityIterator implements EntityIterator {
     28     private final Cursor mCursor;
     29     private boolean mIsClosed;
     30 
     31     /**
     32      * Constructor that makes initializes the cursor such that the iterator points to the
     33      * first Entity, if there are any.
     34      * @param cursor the cursor that contains the rows that make up the entities
     35      */
     36     public CursorEntityIterator(Cursor cursor) {
     37         mIsClosed = false;
     38         mCursor = cursor;
     39         mCursor.moveToFirst();
     40     }
     41 
     42     /**
     43      * Returns the entity that the cursor is currently pointing to. This must take care to advance
     44      * the cursor past this entity. This will never be called if the cursor is at the end.
     45      * @param cursor the cursor that contains the entity rows
     46      * @return the entity that the cursor is currently pointing to
     47      * @throws RemoteException if a RemoteException is caught while attempting to build the Entity
     48      */
     49     public abstract Entity getEntityAndIncrementCursor(Cursor cursor) throws RemoteException;
     50 
     51     /**
     52      * Returns whether there are more elements to iterate, i.e. whether the
     53      * iterator is positioned in front of an element.
     54      *
     55      * @return {@code true} if there are more elements, {@code false} otherwise.
     56      * @see EntityIterator#next()
     57      */
     58     public final boolean hasNext() {
     59         if (mIsClosed) {
     60             throw new IllegalStateException("calling hasNext() when the iterator is closed");
     61         }
     62 
     63         return !mCursor.isAfterLast();
     64     }
     65 
     66     /**
     67      * Returns the next object in the iteration, i.e. returns the element in
     68      * front of the iterator and advances the iterator by one position.
     69      *
     70      * @return the next object.
     71      * @throws java.util.NoSuchElementException
     72      *             if there are no more elements.
     73      * @see EntityIterator#hasNext()
     74      */
     75     public Entity next() {
     76         if (mIsClosed) {
     77             throw new IllegalStateException("calling next() when the iterator is closed");
     78         }
     79         if (!hasNext()) {
     80             throw new IllegalStateException("you may only call next() if hasNext() is true");
     81         }
     82 
     83         try {
     84             return getEntityAndIncrementCursor(mCursor);
     85         } catch (RemoteException e) {
     86             throw new RuntimeException("caught a remote exception, this process will die soon", e);
     87         }
     88     }
     89 
     90     public void remove() {
     91         throw new UnsupportedOperationException("remove not supported by EntityIterators");
     92     }
     93 
     94     public final void reset() {
     95         if (mIsClosed) {
     96             throw new IllegalStateException("calling reset() when the iterator is closed");
     97         }
     98         mCursor.moveToFirst();
     99     }
    100 
    101     /**
    102      * Indicates that this iterator is no longer needed and that any associated resources
    103      * may be released (such as a SQLite cursor).
    104      */
    105     public final void close() {
    106         if (mIsClosed) {
    107             throw new IllegalStateException("closing when already closed");
    108         }
    109         mIsClosed = true;
    110         mCursor.close();
    111     }
    112 }
    113