KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > oracle > toplink > essentials > internal > sessions > IsolatedClientSessionIdentityMapAccessor


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, 2006, Oracle. All rights reserved.
22
package oracle.toplink.essentials.internal.sessions;
23
24 import java.util.*;
25 import oracle.toplink.essentials.internal.identitymaps.*;
26 import oracle.toplink.essentials.queryframework.*;
27 import oracle.toplink.essentials.expressions.*;
28 import oracle.toplink.essentials.exceptions.*;
29 import oracle.toplink.essentials.internal.sessions.AbstractSession;
30 import oracle.toplink.essentials.descriptors.ClassDescriptor;
31 import oracle.toplink.essentials.sessions.Record;
32 import oracle.toplink.essentials.logging.SessionLog;
33 import oracle.toplink.essentials.internal.helper.WriteLockManager;
34 import oracle.toplink.essentials.internal.queryframework.JoinedAttributeManager;
35
36 /**
37  * INTERNAL:
38  * Internal subclass that provides access to identity maps through the session.
39  * Implements the IdentityMapAccessor interface which provides all publicly available
40  * identity map functionality to users.
41  * This is the main class that should be used to access identity maps. In general, any
42  * function that accesses the identity map manager should go through this class
43  * Any session specific functionality appears in subclasses
44  */

45 public class IsolatedClientSessionIdentityMapAccessor extends oracle.toplink.essentials.internal.sessions.IdentityMapAccessor {
46
47     /**
48      * INTERNAL:
49      * An IdentityMapAccessor sits between the session and the identityMapManager
50      * It needs references in both directions
51      */

52     public IsolatedClientSessionIdentityMapAccessor(AbstractSession session, IdentityMapManager identityMapManager) {
53         super(session, identityMapManager);
54     }
55
56     /**
57      * INTERNAL:
58      * Deferred lock the identity map for the object, this is used for avoiding deadlock
59      * The return cacheKey should be used to release the deferred lock
60      */

61     public CacheKey acquireDeferredLock(Vector primaryKey, Class JavaDoc javaClass, ClassDescriptor descriptor) {
62         if (descriptor.isIsolated()) {
63             return getIdentityMapManager().acquireDeferredLock(primaryKey, javaClass, descriptor);
64         } else {
65             return ((IsolatedClientSession)session).getParent().getIdentityMapAccessorInstance().acquireDeferredLock(primaryKey, javaClass, descriptor);
66         }
67     }
68
69     /**
70      * INTERNAL:
71      * Provides access for setting a concurrency lock on an object in the IdentityMap.
72      * called with true from the merge process, if true then the refresh will not refresh the object
73      * @see IdentityMap#aquire
74      */

75     public CacheKey acquireLock(Vector primaryKey, Class JavaDoc domainClass, boolean forMerge, ClassDescriptor descriptor) {
76         if (descriptor.isIsolated()) {
77             return getIdentityMapManager().acquireLock(primaryKey, domainClass, forMerge, descriptor);
78         } else {
79             return ((IsolatedClientSession)session).getParent().getIdentityMapAccessorInstance().acquireLock(primaryKey, domainClass, forMerge, descriptor);
80         }
81     }
82
83     /**
84     * INTERNAL:
85     * Provides access for setting a concurrency lock on an object in the IdentityMap.
86     * called with true from the merge process, if true then the refresh will not refresh the object
87     * @see IdentityMap#aquire
88      */

89     public CacheKey acquireLockNoWait(Vector primaryKey, Class JavaDoc domainClass, boolean forMerge, ClassDescriptor descriptor) {
90         if (descriptor.isIsolated()) {
91             return getIdentityMapManager().acquireLockNoWait(primaryKey, domainClass, forMerge, descriptor);
92         } else {
93             return ((IsolatedClientSession)session).getParent().getIdentityMapAccessorInstance().acquireLockNoWait(primaryKey, domainClass, forMerge, descriptor);
94         }
95     }
96
97     /**
98      * INTERNAL:
99      * Find the cachekey for the provided primary key and place a readlock on it.
100      * This will allow multiple users to read the same object but prevent writes to
101      * the object while the read lock is held.
102      */

103     public CacheKey acquireReadLockOnCacheKey(Vector primaryKey, Class JavaDoc domainClass, ClassDescriptor descriptor) {
104         if (descriptor.isIsolated()) {
105             return getIdentityMapManager().acquireReadLockOnCacheKey(primaryKey, domainClass, descriptor);
106         } else {
107             return ((IsolatedClientSession)session).getParent().getIdentityMapAccessorInstance().acquireReadLockOnCacheKey(primaryKey, domainClass, descriptor);
108         }
109     }
110
111     /**
112      * INTERNAL:
113      * Find the cachekey for the provided primary key and place a readlock on it.
114      * This will allow multiple users to read the same object but prevent writes to
115      * the object while the read lock is held.
116      * If no readlock can be acquired then do not wait but return null.
117      */

118     public CacheKey acquireReadLockOnCacheKeyNoWait(Vector primaryKey, Class JavaDoc domainClass, ClassDescriptor descriptor) {
119         if (descriptor.isIsolated()) {
120             return getIdentityMapManager().acquireReadLockOnCacheKeyNoWait(primaryKey, domainClass, descriptor);
121         } else {
122             return ((IsolatedClientSession)session).getParent().getIdentityMapAccessorInstance().acquireReadLockOnCacheKeyNoWait(primaryKey, domainClass, descriptor);
123         }
124     }
125
126     /**
127     * INTERNAL:
128     * Lock the entire cache if the cache isolation requires.
129     * By default concurrent reads and writes are allowed.
130     * By write, unit of work merge is meant.
131     */

132     public boolean acquireWriteLock() {
133         getIdentityMapManager().acquireWriteLock();
134         // must lock the parents cache as well.
135
return ((IsolatedClientSession)session).getParent().getIdentityMapAccessorInstance().acquireWriteLock();
136     }
137
138     /**
139      * INTERNAL:
140      * Return whether the identity maps contain an item of the given class and key
141      */

142     public boolean containsKey(Vector key, Class JavaDoc theClass, ClassDescriptor descriptor) {
143         if (descriptor.isIsolated()) {
144             return getIdentityMapManager().containsKey(key, theClass, descriptor);
145         } else {
146             return ((IsolatedClientSession)session).getParent().getIdentityMapAccessorInstance().containsKey(key, theClass, descriptor);
147         }
148     }
149
150     /**
151      * ADVANCED:
152      * Return if their is an object for the primary key.
153      */

154     public boolean containsObjectInIdentityMap(Vector primaryKey, Class JavaDoc theClass, ClassDescriptor descriptor) {
155         if (descriptor.isIsolated()) {
156             return getIdentityMapManager().containsKey(primaryKey, theClass, descriptor);
157         } else {
158             return ((IsolatedClientSession)session).getParent().getIdentityMapAccessorInstance().containsObjectInIdentityMap(primaryKey, theClass, descriptor);
159         }
160     }
161
162     /**
163      * INTERNAL:
164      * This method is used to get a list of those classes with IdentityMaps in the Session.
165      */

166     public Vector getClassesRegistered() {
167         Vector results = getIdentityMapManager().getClassesRegistered();
168         results.addAll(((IsolatedClientSession)session).getParent().getIdentityMapAccessorInstance().getClassesRegistered());
169         return results;
170     }
171
172     /**
173      * ADVANCED:
174      * Query the cache in-memory.
175      * If the expression is too complex an exception will be thrown.
176      * Only return objects that are invalid in the cache if specified.
177      */

178     public Vector getAllFromIdentityMap(Expression selectionCriteria, Class JavaDoc theClass, Record translationRow, InMemoryQueryIndirectionPolicy valueHolderPolicy, boolean shouldReturnInvalidatedObjects) throws QueryException {
179         if (session.getDescriptor(theClass).isIsolated()) {
180             return getIdentityMapManager().getAllFromIdentityMap(selectionCriteria, theClass, translationRow, valueHolderPolicy, shouldReturnInvalidatedObjects);
181         } else {
182             return ((IsolatedClientSession)session).getParent().getIdentityMapAccessorInstance().getAllFromIdentityMap(selectionCriteria, theClass, translationRow, valueHolderPolicy, shouldReturnInvalidatedObjects);
183         }
184     }
185
186     /**
187      * INTERNAL:
188      * Retrieve the cache key for the given identity information
189      * @param Vector the primary key of the cache key to be retrieved
190      * @param Class the class of the cache key to be retrieved
191      * @return CacheKey
192      */

193     public CacheKey getCacheKeyForObject(Vector primaryKey, Class JavaDoc myClass, ClassDescriptor descriptor) {
194         if (descriptor.isIsolated()) {
195             return getIdentityMapManager().getCacheKeyForObject(primaryKey, myClass, descriptor);
196         } else {
197             return ((IsolatedClientSession)session).getParent().getIdentityMapAccessorInstance().getCacheKeyForObject(primaryKey, myClass, descriptor);
198         }
199     }
200
201     /**
202      * ADVANCED:
203      * Return the object from the identity with the primary and class.
204      */

205     public Object JavaDoc getFromIdentityMap(Vector primaryKey, Class JavaDoc theClass, ClassDescriptor descriptor, JoinedAttributeManager joinedAttributeManager) {
206         if (descriptor.isIsolated()) {
207             return getIdentityMapManager().getFromIdentityMap(primaryKey, theClass, descriptor);
208         } else {
209             return ((IsolatedClientSession)session).getParent().getIdentityMapAccessorInstance().getFromIdentityMap(primaryKey, theClass, descriptor, joinedAttributeManager);
210         }
211     }
212
213     /**
214      * INTERNAL:
215      * Query the cache in-memory.
216      * If the object is not found null is returned.
217      * If the expression is too complex an exception will be thrown.
218      */

219     public Object JavaDoc getFromIdentityMap(Expression selectionCriteria, Class JavaDoc theClass, Record translationRow, InMemoryQueryIndirectionPolicy valueHolderPolicy, boolean conforming, boolean shouldReturnInvalidatedObjects, ClassDescriptor descriptor) {
220         if (descriptor.isIsolated()) {
221             return getIdentityMapManager().getFromIdentityMap(selectionCriteria, theClass, translationRow, valueHolderPolicy, conforming, shouldReturnInvalidatedObjects, descriptor);
222         } else {
223             return ((IsolatedClientSession)session).getParent().getIdentityMapAccessorInstance().getFromIdentityMap(selectionCriteria, theClass, translationRow, valueHolderPolicy, conforming, shouldReturnInvalidatedObjects, descriptor);
224         }
225     }
226
227     /**
228      * INTERNAL:
229      * Return the object from the identity with the primary and class.
230      * Only return invalidated objects if requested
231      */

232     public Object JavaDoc getFromIdentityMapWithDeferredLock(Vector primaryKey, Class JavaDoc theClass, boolean shouldReturnInvalidatedObjects, ClassDescriptor descriptor) {
233         if (descriptor.isIsolated()) {
234             return getIdentityMapManager().getFromIdentityMapWithDeferredLock(primaryKey, theClass, shouldReturnInvalidatedObjects, descriptor);
235         } else {
236             return ((IsolatedClientSession)session).getParent().getIdentityMapAccessorInstance().getFromIdentityMapWithDeferredLock(primaryKey, theClass, shouldReturnInvalidatedObjects, descriptor);
237         }
238     }
239
240     /**
241      * INTERNAL:
242      * Get the IdentityMapManager for this IdentityMapAccessor
243      * This method should be used for all IdentityMapManager access since it may
244      * be overridden in sub classes.
245      */

246     public IdentityMapManager getIdentityMapManager() {
247         return identityMapManager;
248     }
249
250     /**
251      * INTERNAL:
252      * Get the identity map for the given class from the IdentityMapManager
253      */

254     public IdentityMap getIdentityMap(ClassDescriptor descriptor) {
255         if (descriptor.isIsolated()) {
256             return getIdentityMapManager().getIdentityMap(descriptor);
257         } else {
258             return ((IsolatedClientSession)session).getParent().getIdentityMapAccessorInstance().getIdentityMap(descriptor);
259         }
260     }
261
262     /**
263      * ADVANCED:
264      * Return the remaining life of this object. This method is associated with use of
265      * TopLink's cache invalidation feature and returns the difference between the next expiry
266      * time of the object and its read time. The method will return 0 for invalidated objects.
267      */

268     public long getRemainingValidTime(Object JavaDoc object) {
269         ClassDescriptor descriptor = getSession().getDescriptor(object);
270         CacheKey key = this.getCacheKeyForObject(object, descriptor);
271         if (key == null) {
272             throw QueryException.objectDoesNotExistInCache(object);
273         }
274         return descriptor.getCacheInvalidationPolicy().getRemainingValidTime(key);
275     }
276
277     /**
278      * INTERNAL:
279      * get the session associated with this IdentityMapAccessor
280      */

281     public AbstractSession getSession() {
282         return session;
283     }
284
285     /**
286      * INTERNAL:
287      * Get the wrapper object from the cache key associated with the given primary key,
288      * this is used for EJB.
289      */

290     public Object JavaDoc getWrapper(Vector primaryKey, Class JavaDoc theClass) {
291         if (session.getDescriptor(theClass).isIsolated()) {
292             return getIdentityMapManager().getWrapper(primaryKey, theClass);
293         } else {
294             return ((IsolatedClientSession)session).getParent().getIdentityMapAccessorInstance().getWrapper(primaryKey, theClass);
295         }
296     }
297
298     /**
299      * INTERNAL:
300      * Returns the single write Lock manager for this session
301      */

302     public WriteLockManager getWriteLockManager() {
303         // As there should only be one write lock manager per server session
304
// get the one from the parent.
305
return ((IsolatedClientSession)session).getParent().getIdentityMapAccessorInstance().getWriteLockManager();
306     }
307
308     /**
309      * ADVANCED:
310      * Extract the write lock value from the identity map.
311      */

312     public Object JavaDoc getWriteLockValue(Vector primaryKey, Class JavaDoc theClass, ClassDescriptor descriptor) {
313         if (descriptor.isIsolated()) {
314             return getIdentityMapManager().getWriteLockValue(primaryKey, theClass, descriptor);
315         } else {
316             return ((IsolatedClientSession)session).getParent().getIdentityMapAccessorInstance().getWriteLockValue(primaryKey, theClass, descriptor);
317         }
318     }
319
320     /**
321      * PUBLIC:
322      * Reset the entire object cache.
323      * <p> NOTE: be careful using this method. This method blows away both this session's and its parents caches,
324      * this includes the server cache or any other cache. This throws away any objects that have been read in.
325      * Extream caution should be used before doing this because object identity will no longer
326      * be maintained for any objects currently read in. This should only be called
327      * if the application knows that it no longer has references to object held in the cache.
328      */

329     public void initializeAllIdentityMaps() {
330         getSession().log(SessionLog.FINER, SessionLog.CACHE, "initialize_all_local_identitymaps");
331         getIdentityMapManager().initializeIdentityMaps();
332         ((IsolatedClientSession)session).getParent().getIdentityMapAccessorInstance().initializeIdentityMaps();
333     }
334
335     /**
336      * PUBLIC:
337      * Reset the identity map for only the instances of the class.
338      * For inheritance the user must make sure that they only use the root class.
339      * Caution must be used in doing this to ensure that the objects within the identity map
340      * are not referenced from other objects of other classes or from the application.
341      */

342     public void initializeIdentityMap(Class JavaDoc theClass) {
343         getSession().log(SessionLog.FINER, SessionLog.CACHE, "initialize_identitymap", theClass);
344         if (session.getDescriptor(theClass).isIsolated()) {
345             getIdentityMapManager().initializeIdentityMap(theClass);
346         } else {
347             ((IsolatedClientSession)session).getParent().getIdentityMapAccessorInstance().initializeIdentityMap(theClass);
348         }
349     }
350
351     /**
352      * PUBLIC:
353      * Reset the entire local object cache.
354      * This throws away any objects that have been read in.
355      * Extream caution should be used before doing this because object identity will no longer
356      * be maintained for any objects currently read in. This should only be called
357      * if the application knows that it no longer has references to object held in the cache.
358      */

359     public void initializeIdentityMaps() {
360         getSession().log(SessionLog.FINER, SessionLog.CACHE, "initialize_identitymaps");
361         getIdentityMapManager().initializeIdentityMaps();
362         getSession().getCommitManager().reinitialize();
363     }
364
365     /**
366      * PUBLIC:
367      * Used to print all the objects in the identity map of the passed in class.
368      * The output of this method will be logged to this session's SessionLog at SEVERE level.
369      */

370     public void printIdentityMap(Class JavaDoc businessClass) {
371         if (getSession().shouldLog(SessionLog.SEVERE, SessionLog.CACHE)) {
372             if (session.getDescriptor(businessClass).isIsolated()) {
373                 getIdentityMapManager().printIdentityMap(businessClass);
374             } else {
375                 ((IsolatedClientSession)session).getParent().getIdentityMapAccessorInstance().printIdentityMap(businessClass);
376             }
377         }
378     }
379
380     /**
381      * PUBLIC:
382      * Used to print all the objects in every identity map in this session.
383      * The output of this method will be logged to this session's SessionLog at SEVERE level.
384      */

385     public void printIdentityMaps() {
386         if (getSession().shouldLog(SessionLog.SEVERE, SessionLog.CACHE)) {
387             getIdentityMapManager().printIdentityMaps();
388             ((IsolatedClientSession)session).getParent().getIdentityMapAccessorInstance().printIdentityMaps();
389         }
390     }
391
392     /**
393      * PUBLIC:
394      * Used to print all the locks in every identity map in this session.
395      * The output of this method will be logged to this session's SessionLog at FINEST level.
396      */

397     public void printIdentityMapLocks() {
398         if (getSession().shouldLog(SessionLog.FINEST, SessionLog.CACHE)) {
399             getIdentityMapManager().printLocks();
400             ((IsolatedClientSession)session).getParent().getIdentityMapAccessorInstance().printIdentityMapLocks();
401         }
402     }
403
404     /**
405      * ADVANCED:
406      * Register the object with the identity map.
407      * The object must always be registered with its version number if optimistic locking is used.
408      * The readTime may also be included in the cache key as it is constructed.
409      */

410     public CacheKey internalPutInIdentityMap(Object JavaDoc domainObject, Vector key, Object JavaDoc writeLockValue, long readTime, ClassDescriptor descriptor) {
411         //no need to unwrap as the put will unwrap later anyway
412
if (descriptor.isIsolated()) {
413             return getIdentityMapManager().putInIdentityMap(domainObject, key, writeLockValue, readTime, descriptor);
414         } else {
415             return ((IsolatedClientSession)session).getParent().getIdentityMapAccessorInstance().internalPutInIdentityMap(domainObject, key, writeLockValue, readTime, descriptor);
416         }
417     }
418
419     /**
420     * INTERNAL:
421     * Lock the entire cache if the cache isolation requires.
422     * By default concurrent reads and writes are allowed.
423     * By write, unit of work merge is meant.
424     */

425     public void releaseWriteLock() {
426         //release in the oposite order of the acquire
427
((IsolatedClientSession)session).getParent().getIdentityMapAccessorInstance().releaseWriteLock();
428         getIdentityMapManager().releaseWriteLock();
429     }
430
431     /**
432      * ADVANCED:
433      * Remove the object from the object cache.
434      */

435     public Object JavaDoc removeFromIdentityMap(Vector key, Class JavaDoc theClass, ClassDescriptor descriptor) {
436         if (descriptor.isIsolated()) {
437             return getIdentityMapManager().removeFromIdentityMap(key, theClass, descriptor);
438         } else {
439             return ((IsolatedClientSession)session).getParent().getIdentityMapAccessorInstance().removeFromIdentityMap(key, theClass, descriptor);
440         }
441     }
442
443     /**
444      * INTERNAL:
445      * Set the IdentityMapManager for this IdentityMapAccessor
446      */

447     public void setIdentityMapManager(IdentityMapManager identityMapManager) {
448         this.identityMapManager = identityMapManager;
449     }
450
451     /**
452      * INTERNAL:
453      * Update the wrapper object the cache key associated with the given primary key,
454      * this is used for EJB.
455      */

456     public void setWrapper(Vector primaryKey, Class JavaDoc theClass, Object JavaDoc wrapper) {
457         if (getSession().getDescriptor(theClass).isIsolated()) {
458             getIdentityMapManager().setWrapper(primaryKey, theClass, wrapper);
459         } else {
460             ((IsolatedClientSession)session).getParent().getIdentityMapAccessorInstance().setWrapper(primaryKey, theClass, wrapper);
461         }
462     }
463
464     /**
465      * ADVANCED:
466      * Update the write lock value in the identity map.
467      */

468     public void updateWriteLockValue(Vector primaryKey, Class JavaDoc theClass, Object JavaDoc writeLockValue) {
469         if (getSession().getDescriptor(theClass).isIsolated()) {
470             getIdentityMapManager().setWriteLockValue(primaryKey, theClass, writeLockValue);
471         } else {
472             ((IsolatedClientSession)session).getParent().getIdentityMapAccessorInstance().updateWriteLockValue(primaryKey, theClass, writeLockValue);
473         }
474     }
475 }
476
Popular Tags