KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > oracle > toplink > essentials > descriptors > TimestampLockingPolicy


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.descriptors;
23
24 import oracle.toplink.essentials.internal.sessions.*;
25 import java.util.*;
26 import java.sql.Timestamp JavaDoc;
27 import oracle.toplink.essentials.expressions.*;
28 import oracle.toplink.essentials.internal.helper.*;
29 import oracle.toplink.essentials.queryframework.*;
30 import oracle.toplink.essentials.exceptions.*;
31 import oracle.toplink.essentials.internal.sessions.AbstractRecord;
32 import oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl;
33 import oracle.toplink.essentials.internal.sessions.AbstractSession;
34
35 /**
36  * <p><b>Purpose</b>: Used to allow a single version timestamp to be used for optimistic locking.
37  *
38  * @since TOPLink/Java 2.0
39  */

40 public class TimestampLockingPolicy extends VersionLockingPolicy {
41     protected int retrieveTimeFrom;
42     public final static int SERVER_TIME = 1;
43     public final static int LOCAL_TIME = 2;
44
45     /**
46      * PUBLIC:
47      * Create a new TimestampLockingPolicy.
48      * Defaults to using the time retrieved from the server.
49      */

50     public TimestampLockingPolicy() {
51         super();
52         this.useServerTime();
53     }
54
55     /**
56      * PUBLIC:
57      * Create a new TimestampLockingPolicy.
58      * Defaults to using the time retrieved from the server.
59      * @param fieldName the field where the write lock value will be stored.
60      */

61     public TimestampLockingPolicy(String JavaDoc fieldName) {
62         super(fieldName);
63         this.useServerTime();
64     }
65
66     /**
67      * INTERNAL:
68      * Create a new TimestampLockingPolicy.
69      * Defaults to using the time retrieved from the server.
70      * @param field the field where the write lock value will be stored.
71      */

72     public TimestampLockingPolicy(DatabaseField field) {
73         super(field);
74         this.useServerTime();
75     }
76     
77     /**
78      * INTERNAL:
79      * This method compares two writeLockValues.
80      * The writeLockValues should be non-null and of type java.sql.Timestamp.
81      * Returns:
82      * -1 if value1 is less (older) than value2;
83      * 0 if value1 equals value2;
84      * 1 if value1 is greater (newer) than value2.
85      * Throws:
86      * NullPointerException if the passed value is null;
87      * ClassCastException if the passed value is of a wrong type.
88      */

89     public int compareWriteLockValues(Object JavaDoc value1, Object JavaDoc value2) {
90         java.sql.Timestamp JavaDoc timestampValue1 = (java.sql.Timestamp JavaDoc)value1;
91         java.sql.Timestamp JavaDoc timestampValue2 = (java.sql.Timestamp JavaDoc)value2;
92         return timestampValue1.compareTo(timestampValue2);
93     }
94
95     /**
96      * INTERNAL:
97      * Return the default timestamp locking filed java type, default is Timestamp.
98      */

99     protected Class JavaDoc getDefaultLockingFieldType() {
100         return ClassConstants.TIMESTAMP;
101     }
102     
103     /**
104      * INTERNAL:
105      * This is the base value that is older than all other values, it is used in the place of
106      * null in some situations.
107      */

108     public Object JavaDoc getBaseValue(){
109         return new Timestamp JavaDoc(0);
110     }
111     
112     /**
113      * INTERNAL:
114      * returns the initial locking value
115      */

116     protected Object JavaDoc getInitialWriteValue(AbstractSession session) {
117         if (usesLocalTime()) {
118             return new Timestamp JavaDoc(System.currentTimeMillis());
119         }
120         if (usesServerTime()) {
121             AbstractSession readSession = session.getSessionForClass(getDescriptor().getJavaClass());
122             while (readSession.isUnitOfWork()) {
123                 readSession = ((UnitOfWorkImpl)readSession).getParent().getSessionForClass(getDescriptor().getJavaClass());
124             }
125
126             return readSession.getDatasourceLogin().getDatasourcePlatform().getTimestampFromServer(session, readSession.getName());
127         }
128         return null;
129
130     }
131
132     /**
133      * INTERNAL:
134      * Returns the new Timestamp value.
135      */

136     public Object JavaDoc getNewLockValue(ModifyQuery query) {
137         return getInitialWriteValue(query.getSession());
138     }
139
140     /**
141      * INTERNAL:
142      * Return the value that should be stored in the identity map. If the value
143      * is stored in the object, then return a null.
144      */

145     public Object JavaDoc getValueToPutInCache(AbstractRecord row, AbstractSession session) {
146         if (isStoredInCache()) {
147             return session.getDatasourcePlatform().convertObject(row.get(getWriteLockField()), ClassConstants.TIMESTAMP);
148         } else {
149             return null;
150         }
151     }
152
153     /**
154      * INTERNAL:
155      * Return the number of versions different between these objects.
156      */

157     public int getVersionDifference(Object JavaDoc currentValue, Object JavaDoc domainObject, Vector primaryKeys, AbstractSession session) {
158         java.sql.Timestamp JavaDoc writeLockFieldValue;
159         java.sql.Timestamp JavaDoc newWriteLockFieldValue = (java.sql.Timestamp JavaDoc)currentValue;
160         if (newWriteLockFieldValue == null) {
161             return 0;//merge it as either the object is new or being forced merged.
162
}
163         if (isStoredInCache()) {
164             writeLockFieldValue = (java.sql.Timestamp JavaDoc)session.getIdentityMapAccessor().getWriteLockValue(primaryKeys, domainObject.getClass());
165         } else {
166             writeLockFieldValue = (java.sql.Timestamp JavaDoc)lockValueFromObject(domainObject);
167         }
168         if ((writeLockFieldValue != null) && !(newWriteLockFieldValue.after(writeLockFieldValue))) {
169             return 0;
170         }
171
172         //if the new value is newer then perform the update. Eventually this will be changed to
173
//record the old version and compare that for equality
174
return 2;
175     }
176
177     /**
178      * INTERNAL:
179      * This method will return the optimistic lock value for the object
180      */

181     public Object JavaDoc getWriteLockValue(Object JavaDoc domainObject, java.util.Vector JavaDoc primaryKey, AbstractSession session) {
182         java.sql.Timestamp JavaDoc writeLockFieldValue = null;
183         if (isStoredInCache()) {
184             writeLockFieldValue = (java.sql.Timestamp JavaDoc)session.getIdentityMapAccessor().getWriteLockValue(primaryKey, domainObject.getClass());
185         } else {
186             //CR#2281 notStoredInCache prevent ClassCastException
187
Object JavaDoc lockValue = lockValueFromObject(domainObject);
188             if (lockValue != null) {
189                 if (lockValue instanceof java.sql.Timestamp JavaDoc) {
190                     writeLockFieldValue = (java.sql.Timestamp JavaDoc)lockValueFromObject(domainObject);
191                 } else {
192                     throw OptimisticLockException.needToMapJavaSqlTimestampWhenStoredInObject();
193                 }
194             }
195         }
196         return writeLockFieldValue;
197     }
198
199     /**
200      * INTERNAL:
201      * Retrun an expression that updates the write lock
202      */

203     public Expression getWriteLockUpdateExpression(ExpressionBuilder builder) {
204         return builder.value(getInitialWriteValue(builder.getSession()));
205     }
206
207     /**
208      * INTERNAL:
209      * Timestamp versioning should not be able to do this. Override the superclass behaviour.
210      */

211     protected Number JavaDoc incrementWriteLockValue(Number JavaDoc numberValue) {
212         return null;
213     }
214
215     /**
216      * INTERNAL:
217      * Update the parent write lock value if the objectChangeSet's is greater.
218      */

219     public boolean isChildWriteLockValueGreater(AbstractSession session, java.util.Vector JavaDoc primaryKey, Class JavaDoc original, ObjectChangeSet changeSet) {
220         if (isStoredInCache()) {
221             // If this uow changed the object the version must be updated,
222
// we can check this by ensuring our value is greater than our parent's.
223
java.sql.Timestamp JavaDoc writeLockValue = (java.sql.Timestamp JavaDoc)changeSet.getWriteLockValue();
224             java.sql.Timestamp JavaDoc parentValue = (java.sql.Timestamp JavaDoc)session.getIdentityMapAccessor().getWriteLockValue(primaryKey, original);
225             if (writeLockValue != null) {// This occurs if the object was deleted
226
if ((parentValue == null) || parentValue.before(writeLockValue)) {// Check parent value is less than child
227
return true;
228                 }
229             }
230         }
231
232         return false;
233     }
234
235     /**
236      * INTERNAL:
237      * Update the parent write lock value if the unit of works has been incremented.
238      */

239     public boolean isChildWriteLockValueGreater(UnitOfWorkImpl uow, java.util.Vector JavaDoc primaryKey, Class JavaDoc original) {
240         if (isStoredInCache()) {
241             // If this uow changed the object the version must be updated,
242
// we can check this by ensuring our value is greater than our parent's.
243
java.sql.Timestamp JavaDoc writeLockValue = (java.sql.Timestamp JavaDoc)uow.getIdentityMapAccessor().getWriteLockValue(primaryKey, original);
244             java.sql.Timestamp JavaDoc parentValue = (java.sql.Timestamp JavaDoc)uow.getParent().getIdentityMapAccessor().getWriteLockValue(primaryKey, original);
245             if (writeLockValue != null) {// This occurs if the object was deleted
246
if ((parentValue == null) || parentValue.before(writeLockValue)) {// Check parent value is less than child
247
return true;
248                 }
249             }
250         }
251
252         return false;
253     }
254
255     /**
256      * INTERNAL:
257      * Compares the value with the value from the object (or cache).
258      * Will return true if the object is newer.
259      */

260     public boolean isNewerVersion(Object JavaDoc currentValue, Object JavaDoc domainObject, java.util.Vector JavaDoc primaryKey, AbstractSession session) {
261         java.sql.Timestamp JavaDoc writeLockFieldValue;
262         java.sql.Timestamp JavaDoc newWriteLockFieldValue = (java.sql.Timestamp JavaDoc)currentValue;
263         if (isStoredInCache()) {
264             writeLockFieldValue = (java.sql.Timestamp JavaDoc)session.getIdentityMapAccessor().getWriteLockValue(primaryKey, domainObject.getClass());
265         } else {
266             writeLockFieldValue = (java.sql.Timestamp JavaDoc)lockValueFromObject(domainObject);
267         }
268         if ((writeLockFieldValue != null) && !(newWriteLockFieldValue.after(writeLockFieldValue))) {
269             return false;
270         }
271         return true;
272     }
273
274     /**
275      * INTERNAL:
276      * Compares the value from the row and from the object (or cache).
277      * Will return true if the object is newer than the row.
278      */

279     public boolean isNewerVersion(AbstractRecord databaseRow, Object JavaDoc domainObject, java.util.Vector JavaDoc primaryKey, AbstractSession session) {
280         java.sql.Timestamp JavaDoc writeLockFieldValue;
281         java.sql.Timestamp JavaDoc newWriteLockFieldValue = (java.sql.Timestamp JavaDoc)session.getDatasourcePlatform().convertObject(databaseRow.get(getWriteLockField()), ClassConstants.TIMESTAMP);
282         if (isStoredInCache()) {
283             writeLockFieldValue = (java.sql.Timestamp JavaDoc)session.getIdentityMapAccessor().getWriteLockValue(primaryKey, domainObject.getClass());
284         } else {
285             writeLockFieldValue = (java.sql.Timestamp JavaDoc)lockValueFromObject(domainObject);
286         }
287         if ((writeLockFieldValue != null) && !(newWriteLockFieldValue.after(writeLockFieldValue))) {
288             return false;
289         }
290         return true;
291     }
292
293     /**
294      * PUBLIC:
295      * Set if policy uses server time.
296      */

297     public void setUsesServerTime(boolean usesServerTime) {
298         if (usesServerTime) {
299             useServerTime();
300         } else {
301             useLocalTime();
302         }
303     }
304
305     /**
306      * PUBLIC:
307      * set this policy to get the time from the local machine.
308      */

309     public void useLocalTime() {
310         retrieveTimeFrom = LOCAL_TIME;
311     }
312
313     /**
314      * PUBLIC:
315      * set this policy to get the time from the server.
316      */

317     public void useServerTime() {
318         retrieveTimeFrom = SERVER_TIME;
319     }
320
321     /**
322      * PUBLIC:
323      * Return true if policy uses local time.
324      */

325     public boolean usesLocalTime() {
326         return (retrieveTimeFrom == LOCAL_TIME);
327     }
328
329     /**
330      * PUBLIC:
331      * Return true if policy uses server time.
332      */

333     public boolean usesServerTime() {
334         return (retrieveTimeFrom == SERVER_TIME);
335     }
336 }
337
Popular Tags