KickJava   Java API By Example, From Geeks To Geeks.

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


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
26 import oracle.toplink.essentials.descriptors.ClassDescriptor;
27 import oracle.toplink.essentials.internal.ejb.cmp3.base.RepeatableWriteUnitOfWork;
28 import oracle.toplink.essentials.internal.identitymaps.*;
29 import oracle.toplink.essentials.internal.sessions.IdentityMapAccessor;
30 import oracle.toplink.essentials.expressions.*;
31 import oracle.toplink.essentials.exceptions.*;
32 import oracle.toplink.essentials.internal.queryframework.JoinedAttributeManager;
33 import oracle.toplink.essentials.queryframework.*;
34
35 /**
36  * INTERNAL:
37  * IdentityMapAccessor subclass for UnitOfWork
38  * Overrides some initialization functionality and some behavoir having to do with
39  * getting objects from identity maps.
40  */

41 public class UnitOfWorkIdentityMapAccessor extends IdentityMapAccessor {
42     public UnitOfWorkIdentityMapAccessor(AbstractSession session, IdentityMapManager identityMapManager) {
43         super(session, identityMapManager);
44     }
45
46     /**
47      * INTERNAL:
48      * Return if their is an object for the primary key.
49      */

50     public boolean containsObjectInIdentityMap(Vector primaryKey, Class JavaDoc theClass, ClassDescriptor descriptor) {
51         if (getIdentityMapManager().containsKey(primaryKey, theClass, descriptor)) {
52             return true;
53         }
54         return ((UnitOfWorkImpl)getSession()).getParent().getIdentityMapAccessorInstance().containsObjectInIdentityMap(primaryKey, theClass, descriptor);
55     }
56
57     /**
58      * INTERNAL:
59      * This method overrides the getAllFromIdentityMap method in Session. Invalidated Objects
60      * will always be returned from a UnitOfWork.
61      */

62     public Vector getAllFromIdentityMap(Expression selectionCriteria, Class JavaDoc theClass, AbstractRecord translationRow, InMemoryQueryIndirectionPolicy valueHolderPolicy, boolean shouldReturnInvalidatedObjects) throws QueryException {
63         return super.getAllFromIdentityMap(selectionCriteria, theClass, translationRow, valueHolderPolicy, true);
64     }
65
66     /**
67      * INTERNAL:
68      * Overide the getFromIdentityMapWithDeferredLock method on the session to ensure that
69      * invalidated objects are always returned since this is a UnitOfWork
70      */

71     public Object JavaDoc getFromIdentityMapWithDeferredLock(Vector primaryKey, Class JavaDoc theClass, boolean shouldReturnInvalidatedObjects, ClassDescriptor descriptor) {
72         return super.getFromIdentityMapWithDeferredLock(primaryKey, theClass, true, descriptor);
73     }
74
75     /**
76      * INTERNAL:
77      * Return the object from the identity map with the primary key and class.
78      * The parent's cache must be checked after the child's,
79      * if found in the parent, it must be registered/cloned (but must avoid looping).
80      * Note: in a UnitOfWork, invalidated objects will always be returned from the identity map
81      * In the parent session, only return the object if it has not been Invalidated
82      */

83     public Object JavaDoc getFromIdentityMap(Vector primaryKey, Class JavaDoc theClass, boolean shouldReturnInvalidatedObjects, ClassDescriptor descriptor, JoinedAttributeManager joinedAttributeManager) {
84         Object JavaDoc objectFromCache = super.getFromIdentityMap(primaryKey, theClass, true, descriptor, joinedAttributeManager);
85
86         if (objectFromCache != null) {
87             return objectFromCache;
88         }
89         //Bug#4613774 In the parent session, only return the object if it has not been Invalidated
90
return getAndCloneCacheKeyFromParent(primaryKey, theClass, shouldReturnInvalidatedObjects, descriptor, joinedAttributeManager);
91     }
92
93     /**
94      * INTERNAL:
95      * This method will return the object from the parent and clone it.
96      * If the uow is RepeatableWriteUnitOfWork and the original object
97      * from the parent corresponds to deleted unregistered object clone,
98      * then the latter returned.
99      */

100     protected Object JavaDoc getAndCloneCacheKeyFromParent(Vector primaryKey, Class JavaDoc theClass, boolean shouldReturnInvalidatedObjects, ClassDescriptor descriptor, JoinedAttributeManager joinedAttributeManager) {
101         // Note: Objects returned from the parent's identity map should include invalidated
102
// objects. This is important because this internal method is used in the existence
103
// check in the UnitOfWork.
104
CacheKey cacheKey = ((UnitOfWorkImpl)getSession()).getParent().getIdentityMapAccessorInstance().getCacheKeyForObject(primaryKey, theClass, descriptor);
105         if ((cacheKey == null) && ((UnitOfWorkImpl)getSession()).getParent().isUnitOfWork()) {//for nested unit of work
106
//make parent clone and register object
107
((UnitOfWorkIdentityMapAccessor)((UnitOfWorkImpl)getSession()).getParent().getIdentityMapAccessorInstance()).getAndCloneCacheKeyFromParent(primaryKey, theClass, shouldReturnInvalidatedObjects, descriptor, joinedAttributeManager);
108             //get the cachekey that was created in the parent.
109
cacheKey = ((UnitOfWorkImpl)getSession()).getParent().getIdentityMapAccessorInstance().getCacheKeyForObject(primaryKey, theClass, descriptor);
110         }
111
112         Object JavaDoc objectFromCache = null;
113
114         // this check could be simplfied to one line but would create a window
115
// in which GC could remove the object and we would end up with a null pointer
116
// as well we must inspect the cacheKey without locking on it.
117
if ((cacheKey != null) && (shouldReturnInvalidatedObjects || !descriptor.getCacheInvalidationPolicy().isInvalidated(cacheKey, System.currentTimeMillis()))) {
118             synchronized (cacheKey.getMutex()) {
119                 //if the object in the cachekey is null but the key is acquired then
120
//someone must be rebuilding it or creating a new one. Sleep until
121
// it's finished. A plain wait here would be more efficient but we may not
122
// get notified for quite some time (ie deadlock) if the other thread
123
//is building the object. Must wait and not sleep in order for the monitor to be released
124
objectFromCache = cacheKey.getObject();
125                 try {
126                     while (cacheKey.isAcquired() && (objectFromCache == null)) {
127                         cacheKey.getMutex().wait(5);
128                     }
129                 } catch (InterruptedException JavaDoc ex) {
130                 }
131                 if (objectFromCache == null) {
132                     return null;
133                 }
134             }
135         } else {
136             return null;
137         }
138
139         // Consider read-only class CR#4094
140
if (getSession().isClassReadOnly(theClass, descriptor)) {
141             // PERF: Just return the original object.
142
return objectFromCache;
143         }
144
145         if(getSession() instanceof RepeatableWriteUnitOfWork ) {
146             Object JavaDoc unregisteredDeletedClone = ((RepeatableWriteUnitOfWork)getSession()).getUnregisteredDeletedCloneForOriginal(objectFromCache);
147             if(unregisteredDeletedClone != null) {
148                 return unregisteredDeletedClone;
149             }
150         }
151         
152         return ((UnitOfWorkImpl)getSession()).cloneAndRegisterObject(objectFromCache, cacheKey, joinedAttributeManager);
153     }
154
155     /**
156      * INTERNAL:
157      * Reset the entire object cache,
158      * ** be careful using this.
159      * This method blows away both this session's and its parents caches,
160      * this includes the server cache or any other cache.
161      * This throws away any objects that have been read in.
162      * Extreme caution should be used before doing this because object identity will no longer
163      * be maintained for any objects currently read in. This should only be called
164      * if the application knows that it no longer has references to object held in the cache.
165      */

166     public void initializeAllIdentityMaps() {
167         super.initializeAllIdentityMaps();
168         ((UnitOfWorkImpl)getSession()).getParent().getIdentityMapAccessor().initializeAllIdentityMaps();
169     }
170 }
171
Popular Tags