1 /*
2  * Copyright (C) 2007 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.sqlite;
18 
19 import java.io.Closeable;
20 
21 /**
22  * An object created from a SQLiteDatabase that can be closed.
23  *
24  * This class implements a primitive reference counting scheme for database objects.
25  */
26 public abstract class SQLiteClosable implements Closeable {
27     private int mReferenceCount = 1;
28 
29     /**
30      * Called when the last reference to the object was released by
31      * a call to {@link #releaseReference()} or {@link #close()}.
32      */
onAllReferencesReleased()33     protected abstract void onAllReferencesReleased();
34 
35     /**
36      * Called when the last reference to the object was released by
37      * a call to {@link #releaseReferenceFromContainer()}.
38      *
39      * @deprecated Do not use.
40      */
41     @Deprecated
onAllReferencesReleasedFromContainer()42     protected void onAllReferencesReleasedFromContainer() {
43         onAllReferencesReleased();
44     }
45 
46     /**
47      * Acquires a reference to the object.
48      *
49      * @throws IllegalStateException if the last reference to the object has already
50      * been released.
51      */
acquireReference()52     public void acquireReference() {
53         synchronized(this) {
54             if (mReferenceCount <= 0) {
55                 throw new IllegalStateException(
56                         "attempt to re-open an already-closed object: " + this);
57             }
58             mReferenceCount++;
59         }
60     }
61 
62     /**
63      * Releases a reference to the object, closing the object if the last reference
64      * was released.
65      *
66      * @see #onAllReferencesReleased()
67      */
releaseReference()68     public void releaseReference() {
69         boolean refCountIsZero = false;
70         synchronized(this) {
71             refCountIsZero = --mReferenceCount == 0;
72         }
73         if (refCountIsZero) {
74             onAllReferencesReleased();
75         }
76     }
77 
78     /**
79      * Releases a reference to the object that was owned by the container of the object,
80      * closing the object if the last reference was released.
81      *
82      * @see #onAllReferencesReleasedFromContainer()
83      * @deprecated Do not use.
84      */
85     @Deprecated
releaseReferenceFromContainer()86     public void releaseReferenceFromContainer() {
87         boolean refCountIsZero = false;
88         synchronized(this) {
89             refCountIsZero = --mReferenceCount == 0;
90         }
91         if (refCountIsZero) {
92             onAllReferencesReleasedFromContainer();
93         }
94     }
95 
96     /**
97      * Releases a reference to the object, closing the object if the last reference
98      * was released.
99      *
100      * Calling this method is equivalent to calling {@link #releaseReference}.
101      *
102      * @see #releaseReference()
103      * @see #onAllReferencesReleased()
104      */
close()105     public void close() {
106         releaseReference();
107     }
108 }
109