1 /*
2  * Copyright (C) 2006 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.database;
18 
19 import android.compat.annotation.UnsupportedAppUsage;
20 
21 /**
22  * A base class for Cursors that store their data in {@link CursorWindow}s.
23  * <p>
24  * The cursor owns the cursor window it uses.  When the cursor is closed,
25  * its window is also closed.  Likewise, when the window used by the cursor is
26  * changed, its old window is closed.  This policy of strict ownership ensures
27  * that cursor windows are not leaked.
28  * </p><p>
29  * Subclasses are responsible for filling the cursor window with data during
30  * {@link #onMove(int, int)}, allocating a new cursor window if necessary.
31  * During {@link #requery()}, the existing cursor window should be cleared and
32  * filled with new data.
33  * </p><p>
34  * If the contents of the cursor change or become invalid, the old window must be closed
35  * (because it is owned by the cursor) and set to null.
36  * </p>
37  */
38 public abstract class AbstractWindowedCursor extends AbstractCursor {
39     /**
40      * The cursor window owned by this cursor.
41      */
42     protected CursorWindow mWindow;
43 
44     @Override
getBlob(int columnIndex)45     public byte[] getBlob(int columnIndex) {
46         checkPosition();
47         return mWindow.getBlob(mPos, columnIndex);
48     }
49 
50     @Override
getString(int columnIndex)51     public String getString(int columnIndex) {
52         checkPosition();
53         return mWindow.getString(mPos, columnIndex);
54     }
55 
56     @Override
copyStringToBuffer(int columnIndex, CharArrayBuffer buffer)57     public void copyStringToBuffer(int columnIndex, CharArrayBuffer buffer) {
58         checkPosition();
59         mWindow.copyStringToBuffer(mPos, columnIndex, buffer);
60     }
61 
62     @Override
getShort(int columnIndex)63     public short getShort(int columnIndex) {
64         checkPosition();
65         return mWindow.getShort(mPos, columnIndex);
66     }
67 
68     @Override
getInt(int columnIndex)69     public int getInt(int columnIndex) {
70         checkPosition();
71         return mWindow.getInt(mPos, columnIndex);
72     }
73 
74     @Override
getLong(int columnIndex)75     public long getLong(int columnIndex) {
76         checkPosition();
77         return mWindow.getLong(mPos, columnIndex);
78     }
79 
80     @Override
getFloat(int columnIndex)81     public float getFloat(int columnIndex) {
82         checkPosition();
83         return mWindow.getFloat(mPos, columnIndex);
84     }
85 
86     @Override
getDouble(int columnIndex)87     public double getDouble(int columnIndex) {
88         checkPosition();
89         return mWindow.getDouble(mPos, columnIndex);
90     }
91 
92     @Override
isNull(int columnIndex)93     public boolean isNull(int columnIndex) {
94         checkPosition();
95         return mWindow.getType(mPos, columnIndex) == Cursor.FIELD_TYPE_NULL;
96     }
97 
98     /**
99      * @deprecated Use {@link #getType}
100      */
101     @Deprecated
isBlob(int columnIndex)102     public boolean isBlob(int columnIndex) {
103         return getType(columnIndex) == Cursor.FIELD_TYPE_BLOB;
104     }
105 
106     /**
107      * @deprecated Use {@link #getType}
108      */
109     @Deprecated
isString(int columnIndex)110     public boolean isString(int columnIndex) {
111         return getType(columnIndex) == Cursor.FIELD_TYPE_STRING;
112     }
113 
114     /**
115      * @deprecated Use {@link #getType}
116      */
117     @Deprecated
isLong(int columnIndex)118     public boolean isLong(int columnIndex) {
119         return getType(columnIndex) == Cursor.FIELD_TYPE_INTEGER;
120     }
121 
122     /**
123      * @deprecated Use {@link #getType}
124      */
125     @Deprecated
isFloat(int columnIndex)126     public boolean isFloat(int columnIndex) {
127         return getType(columnIndex) == Cursor.FIELD_TYPE_FLOAT;
128     }
129 
130     @Override
getType(int columnIndex)131     public int getType(int columnIndex) {
132         checkPosition();
133         return mWindow.getType(mPos, columnIndex);
134     }
135 
136     @Override
checkPosition()137     protected void checkPosition() {
138         super.checkPosition();
139 
140         if (mWindow == null) {
141             throw new StaleDataException("Attempting to access a closed CursorWindow." +
142                     "Most probable cause: cursor is deactivated prior to calling this method.");
143         }
144     }
145 
146     @Override
getWindow()147     public CursorWindow getWindow() {
148         return mWindow;
149     }
150 
151     /**
152      * Sets a new cursor window for the cursor to use.
153      * <p>
154      * The cursor takes ownership of the provided cursor window; the cursor window
155      * will be closed when the cursor is closed or when the cursor adopts a new
156      * cursor window.
157      * </p><p>
158      * If the cursor previously had a cursor window, then it is closed when the
159      * new cursor window is assigned.
160      * </p>
161      *
162      * @param window The new cursor window, typically a remote cursor window.
163      */
setWindow(CursorWindow window)164     public void setWindow(CursorWindow window) {
165         if (window != mWindow) {
166             closeWindow();
167             mWindow = window;
168         }
169     }
170 
171     /**
172      * Returns true if the cursor has an associated cursor window.
173      *
174      * @return True if the cursor has an associated cursor window.
175      */
hasWindow()176     public boolean hasWindow() {
177         return mWindow != null;
178     }
179 
180     /**
181      * Closes the cursor window and sets {@link #mWindow} to null.
182      * @hide
183      */
184     @UnsupportedAppUsage
closeWindow()185     protected void closeWindow() {
186         if (mWindow != null) {
187             mWindow.close();
188             mWindow = null;
189         }
190     }
191 
192     /**
193      * If there is a window, clear it.
194      * Otherwise, creates a new window.
195      *
196      * @param name The window name.
197      * @hide
198      */
199     @UnsupportedAppUsage
clearOrCreateWindow(String name)200     protected void clearOrCreateWindow(String name) {
201         if (mWindow == null) {
202             mWindow = new CursorWindow(name);
203         } else {
204             mWindow.clear();
205         }
206     }
207 
208     /** @hide */
209     @Override
210     @UnsupportedAppUsage
onDeactivateOrClose()211     protected void onDeactivateOrClose() {
212         super.onDeactivateOrClose();
213         closeWindow();
214     }
215 }
216