KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > oracle > toplink > essentials > internal > indirection > DatabaseValueHolder


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the "License"). You may not use this file except
5  * in compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * glassfish/bootstrap/legal/CDDLv1.0.txt or
9  * https://glassfish.dev.java.net/public/CDDLv1.0.html.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * HEADER in each file and include the License file at
15  * glassfish/bootstrap/legal/CDDLv1.0.txt. If applicable,
16  * add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your
18  * own identifying information: Portions Copyright [yyyy]
19  * [name of copyright owner]
20  */

21 // Copyright (c) 1998, 2005, Oracle. All rights reserved.
22
package oracle.toplink.essentials.internal.indirection;
23
24 import java.io.*;
25 import oracle.toplink.essentials.internal.helper.*;
26 import oracle.toplink.essentials.indirection.*;
27 import oracle.toplink.essentials.exceptions.*;
28 import oracle.toplink.essentials.internal.localization.*;
29 import oracle.toplink.essentials.internal.sessions.AbstractRecord;
30 import oracle.toplink.essentials.internal.sessions.AbstractSession;
31
32 /**
33  * DatabaseValueHolder wraps a database-stored object and implements
34  * behavior to access it. The object is read only once from database
35  * after which is cached for faster access.
36  *
37  * @see ValueHolderInterface
38  * @author Dorin Sandu
39  */

40 public abstract class DatabaseValueHolder implements ValueHolderInterface, Cloneable JavaDoc, Serializable {
41
42     /** Stores the object after it is read from the database. */
43     protected Object JavaDoc value;
44
45     /** Indicates whether the object has been read from the database or not. */
46     protected boolean isInstantiated;
47
48     /** Stores the session for the database that contains the object. */
49     protected transient AbstractSession session;
50
51     /** Stores the row representation of the object. */
52     protected AbstractRecord row;
53
54     public Object JavaDoc clone() {
55         try {
56             return super.clone();
57         } catch (CloneNotSupportedException JavaDoc exception) {
58             throw new InternalError JavaDoc();
59         }
60     }
61
62     /**
63      * Return the row.
64      */

65     public AbstractRecord getRow() {
66         return row;
67     }
68
69     /**
70      * Return the session.
71      */

72     public AbstractSession getSession() {
73         return session;
74     }
75
76     /**
77      * Return the object.
78      */

79     public synchronized Object JavaDoc getValue() {
80         if (!isInstantiated()) {
81             // The value must be set directly because the setValue can also cause instatiation under UOW.
82
privilegedSetValue(instantiate());
83             setInstantiated();
84             resetFields();
85         }
86         return value;
87     }
88
89     /**
90      * Instantiate the object.
91      */

92     protected abstract Object JavaDoc instantiate() throws DatabaseException;
93
94     /**
95      * Triggers UnitOfWork valueholders directly without triggering the wrapped
96      * valueholder (this).
97      * <p>
98      * When in transaction and/or for pessimistic locking the UnitOfWorkValueHolder
99      * needs to be triggered directly without triggering the wrapped valueholder.
100      * However only the wrapped valueholder knows how to trigger the indirection,
101      * i.e. it may be a batchValueHolder, and it stores all the info like the row
102      * and the query.
103      * Note: Implementations of this method are not necessarily thread-safe. They must
104      * be used in a synchronizaed manner
105      */

106     public abstract Object JavaDoc instantiateForUnitOfWorkValueHolder(UnitOfWorkValueHolder unitOfWorkValueHolder);
107
108     /**
109      * INTERNAL:
110      * Answers if this valueholder is easy to instantiate.
111      * @return true if getValue() won't trigger a database read.
112      */

113     public boolean isEasilyInstantiated() {
114         return isInstantiated();
115     }
116
117     /**
118      * Return a boolean indicating whether the object
119      * has been read from the database or not.
120      */

121     public boolean isInstantiated() {
122         return isInstantiated;
123     }
124
125     /**
126      * Answers if this valueholder is a pessimistic locking one. Such valueholders
127      * are special in that they can be triggered multiple times by different
128      * UnitsOfWork. Each time a lock query will be issued. Hence even if
129      * instantiated it may have to be instantiated again, and once instantatiated
130      * all fields can not be reset.
131      * Note: Implementations of this method are not necessarily thread-safe. They must
132      * be used in a synchronizaed manner
133      */

134     public abstract boolean isPessimisticLockingValueHolder();
135
136     /**
137      * Answers if this valueholder is referenced only by a UnitOfWork valueholder.
138      * I.e. it was built in valueFromRow which was called by buildCloneFromRow.
139      * <p>
140      * Sometimes in transaction a UnitOfWork clone, and all valueholders, are built
141      * directly from the row; however a UnitOfWorkValueHolder does not know how to
142      * instantiate itself so wraps this which does.
143      * <p>
144      * On a successful merge must be released to the session cache with
145      * releaseWrappedValueHolder.
146      */

147     protected boolean isTransactionalValueHolder() {
148         return ((session != null) && session.isUnitOfWork());
149     }
150     
151     /**
152      * Used to determine if this is a remote uow value holder that was serialized to the server.
153      * It has no reference to its wrapper value holder, so must find its original object to be able to instantiate.
154      */

155     public boolean isSerializedRemoteUnitOfWorkValueHolder() {
156         return false;
157     }
158
159     /**
160      * Set the object. This is used only by the privileged methods. One must be very careful in using this method.
161      */

162     public void privilegedSetValue(Object JavaDoc value) {
163         this.value = value;
164     }
165
166     /**
167      * Releases a wrapped valueholder privately owned by a particular unit of work.
168      * <p>
169      * When unit of work clones are built directly from rows no object in the shared
170      * cache points to this valueholder, so it can store the unit of work as its
171      * session. However once that UnitOfWork commits and the valueholder is merged
172      * into the shared cache, the session needs to be reset to the root session, ie.
173      * the server session.
174      */

175     public void releaseWrappedValueHolder() {
176         AbstractSession session = getSession();
177         if ((session != null) && session.isUnitOfWork()) {
178             setSession(session.getRootSession(null));
179         }
180     }
181
182     /**
183      * Reset all the fields that are not needed after instantiation.
184      */

185     protected void resetFields() {
186         setRow(null);
187         setSession(null);
188     }
189
190     /**
191      * Set the instantiated flag to true.
192      */

193     public void setInstantiated() {
194         isInstantiated = true;
195     }
196
197     /**
198      * Set the row.
199      */

200     public void setRow(AbstractRecord row) {
201         this.row = row;
202     }
203
204     /**
205      * Set the session.
206      */

207     public void setSession(AbstractSession session) {
208         this.session = session;
209     }
210
211     /**
212      * Set the instantiated flag to false.
213      */

214     public void setUninstantiated() {
215         isInstantiated = false;
216     }
217
218     /**
219      * Set the object.
220      */

221     public void setValue(Object JavaDoc value) {
222         this.value = value;
223         setInstantiated();
224     }
225
226     public String JavaDoc toString() {
227         if (isInstantiated()) {
228             return "{" + getValue() + "}";
229         } else {
230             return "{" + Helper.getShortClassName(getClass()) + ": " + ToStringLocalization.buildMessage("not_instantiated", (Object JavaDoc[])null) + "}";
231         }
232     }
233 }
234
Popular Tags