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