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