KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > oracle > toplink > essentials > descriptors > changetracking > DeferredChangeDetectionPolicy


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.descriptors.changetracking;
23
24 import java.util.*;
25 import oracle.toplink.essentials.internal.sessions.ObjectChangeSet;
26 import oracle.toplink.essentials.queryframework.*;
27 import oracle.toplink.essentials.internal.descriptors.*;
28 import oracle.toplink.essentials.internal.sessions.MergeManager;
29 import oracle.toplink.essentials.descriptors.ClassDescriptor;
30 import oracle.toplink.essentials.mappings.*;
31 import oracle.toplink.essentials.descriptors.DescriptorEvent;
32 import oracle.toplink.essentials.descriptors.DescriptorEventManager;
33 import oracle.toplink.essentials.internal.sessions.AbstractSession;
34 import oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl;
35 import oracle.toplink.essentials.internal.helper.IdentityHashtable;
36
37 /**
38  * PUBLIC:
39  * A DeferredChangeDetectionPolicy defers all change detection to the UnitOfWork's
40  * change detection process. Essentially, the calculateChanges() method will run
41  * for all objects in a UnitOfWork. This is the default ObjectChangePolicy.
42  *
43  * @author Tom Ware
44  */

45 public class DeferredChangeDetectionPolicy implements ObjectChangePolicy, java.io.Serializable JavaDoc {
46
47     /**
48      * INTERNAL:
49      * calculateChanges creates a change set for a particular object. In DeferredChangeDetectionPolicy
50      * all mappings will be compared against a backup copy of the object.
51      * @return oracle.toplink.essentials.changesets.ObjectChangeSet an object change set describing
52      * the changes to this object
53      * @param java.lang.Object clone the Object to compute a change set for
54      * @param java.lang.Object backUp the old version of the object to use for comparison
55      * @param oracle.toplink.essentials.internal.sessions.UnitOfWorkChangeSet the change set to add changes to
56      * @param Session the current session
57      * @param Descriptor the descriptor for this object
58      * @param shouldRiseEvent indicates whether PreUpdate event should be risen (usually true)
59      */

60     public ObjectChangeSet calculateChanges(Object JavaDoc clone, Object JavaDoc backUp, oracle.toplink.essentials.internal.sessions.UnitOfWorkChangeSet changeSet, AbstractSession session, ClassDescriptor descriptor, boolean shouldRiseEvent) {
61         boolean isNew = ((backUp == null) || ((((UnitOfWorkImpl)session).isObjectNew(clone)) && (!descriptor.isAggregateDescriptor())));
62  
63         // PERF: Avoid events if no listeners.
64
if (descriptor.getEventManager().hasAnyEventListeners() && shouldRiseEvent) {
65             // The query is built for compatability to old event mechanism.
66
WriteObjectQuery writeQuery = new WriteObjectQuery(clone.getClass());
67             writeQuery.setObject(clone);
68             writeQuery.setBackupClone(backUp);
69             writeQuery.setSession(session);
70             writeQuery.setDescriptor(descriptor);
71
72             descriptor.getEventManager().executeEvent(new DescriptorEvent(DescriptorEventManager.PreWriteEvent, writeQuery));
73
74             if (isNew) {
75                 descriptor.getEventManager().executeEvent(new DescriptorEvent(DescriptorEventManager.PreInsertEvent, writeQuery));
76             } else {
77                 descriptor.getEventManager().executeEvent(new DescriptorEvent(DescriptorEventManager.PreUpdateEvent, writeQuery));
78             }
79         }
80
81         ObjectChangeSet changes = createObjectChangeSet(clone, backUp, changeSet, isNew, session, descriptor);
82
83         changes.setShouldModifyVersionField((Boolean JavaDoc)((UnitOfWorkImpl)session).getOptimisticReadLockObjects().get(clone));
84
85         if (changes.hasChanges() || changes.hasForcedChanges()) {
86             return changes;
87         }
88         return null;
89     }
90
91     /**
92      * INTERNAL:
93      * This is a place holder for reseting the listener on one of the subclasses
94      */

95     public void clearChanges(Object JavaDoc object, UnitOfWorkImpl uow, ClassDescriptor descriptor) {
96     }
97
98     /**
99      * INTERNAL:
100      * Create ObjectChangeSet
101      */

102     public ObjectChangeSet createObjectChangeSet(Object JavaDoc clone, Object JavaDoc backUp, oracle.toplink.essentials.internal.sessions.UnitOfWorkChangeSet changeSet, boolean isNew, AbstractSession session, ClassDescriptor descriptor) {
103         return this.createObjectChangeSetThroughComparison(clone, backUp, changeSet, isNew, session, descriptor);
104     }
105
106     /**
107      * INTERNAL:
108      * Create ObjectChangeSet
109      */

110     public ObjectChangeSet createObjectChangeSetThroughComparison(Object JavaDoc clone, Object JavaDoc backUp, oracle.toplink.essentials.internal.sessions.UnitOfWorkChangeSet changeSet, boolean isNew, AbstractSession session, ClassDescriptor descriptor) {
111         ObjectBuilder builder = descriptor.getObjectBuilder();
112         ObjectChangeSet changes = builder.createObjectChangeSet(clone, changeSet, isNew, session);
113
114         // The following code deals with reads that force changes to the flag associated with optimistic locking.
115
if ((descriptor.usesOptimisticLocking()) && (changes.getPrimaryKeys() != null)) {
116             changes.setOptimisticLockingPolicyAndInitialWriteLockValue(descriptor.getOptimisticLockingPolicy(), session);
117         }
118
119         // PERF: Avoid synchronized enumerator as is concurrency bottleneck.
120
Vector mappings = descriptor.getMappings();
121         int mappingsSize = mappings.size();
122         for (int index = 0; index < mappingsSize; index++) {
123             DatabaseMapping mapping = (DatabaseMapping)mappings.get(index);
124             changes.addChange(mapping.compareForChange(clone, backUp, changes, session));
125         }
126
127         return changes;
128     }
129
130     /**
131      * INTERNAL:
132      * This method is used to dissable changetracking temporarily
133      */

134     public void dissableEventProcessing(Object JavaDoc changeTracker){
135         //no-op
136
}
137
138     /**
139      * INTERNAL:
140      * This method is used to enable changetracking temporarily
141      */

142     public void enableEventProcessing(Object JavaDoc changeTracker){
143         //no-op
144
}
145     
146     /**
147      * INTERNAL:
148      * Return true if the Object should be compared, false otherwise. In DeferredChangeDetectionPolicy,
149      * true is always returned since always allow the UnitOfWork to calculate changes.
150      * @param java.lang.Object object - the object that will be compared
151      * @param oracle.toplink.essentials.publicinterface.UnitOfWork unitOfWork - the active unitOfWork
152      * @param oracle.toplink.essentials.publicinterface.Descriptor descriptor - the descriptor for the current object
153      */

154     public boolean shouldCompareForChange(Object JavaDoc object, UnitOfWorkImpl unitOfWork, ClassDescriptor descriptor) {
155         return true;
156     }
157
158     /**
159      * INTERNAL:
160      * Build back up clone. Used if clone is new because listener should not be set.
161      */

162     public Object JavaDoc buildBackupClone(Object JavaDoc clone, ObjectBuilder builder, UnitOfWorkImpl uow) {
163         return builder.buildBackupClone(clone, uow);
164     }
165
166     /**
167      * INTERNAL:
168      * Assign Changelistner to an aggregate object
169      */

170     public void setAggregateChangeListener(Object JavaDoc parent, Object JavaDoc aggregate, UnitOfWorkImpl uow, ClassDescriptor descriptor, String JavaDoc mappingAttribute){
171         //no-op
172
}
173     
174     /**
175      * INTERNAL:
176      * Set ChangeListener for the clone
177      */

178     public void setChangeListener(Object JavaDoc clone, UnitOfWorkImpl uow, ClassDescriptor descriptor) {
179         //no-op
180
}
181
182     /**
183      * INTERNAL:
184      * Set the ObjectChangeSet on the Listener, initially used for aggregate support
185      */

186     public void setChangeSetOnListener(ObjectChangeSet objectChangeSet, Object JavaDoc clone){
187         //no-op
188
}
189     
190     /**
191      * INTERNAL:
192      * Clear changes in the ChangeListener of the clone
193      */

194     public void updateWithChanges(Object JavaDoc clone, ObjectChangeSet objectChangeSet, UnitOfWorkImpl uow, ClassDescriptor descriptor) {
195         if (objectChangeSet == null) {
196             return;
197         }
198         Object JavaDoc backupClone = uow.getCloneMapping().get(clone);
199         if (backupClone != null) {
200             MergeManager mergeManager = new MergeManager(uow);
201             mergeManager.setCascadePolicy(MergeManager.NO_CASCADE);
202             descriptor.getObjectBuilder().mergeChangesIntoObject(backupClone, objectChangeSet, clone, mergeManager);
203         }
204         clearChanges(clone, uow, descriptor);
205     }
206
207     /**
208      * INTERNAL:
209      * This may cause a property change event to be raised to a listner in the case that a listener exists.
210      * If there is no listener then this call is a no-op
211      */

212     public void raiseInternalPropertyChangeEvent(Object JavaDoc source, String JavaDoc propertyName, Object JavaDoc oldValue, Object JavaDoc newValue){
213         //no-op
214
}
215
216     /**
217      * INTERNAL:
218      * This method is used to revert an object within the unit of work
219      * @param cloneMapping may not be the same as whats in the uow
220      */

221     public void revertChanges(Object JavaDoc clone, ClassDescriptor descriptor, UnitOfWorkImpl uow, IdentityHashtable cloneMapping) {
222         cloneMapping.put(clone, buildBackupClone(clone, descriptor.getObjectBuilder(), uow));
223         clearChanges(clone, uow, descriptor);
224     }
225
226     /**
227      * INTERNAL:
228      * initialize the Policy
229      */

230     public void initialize(AbstractSession session, ClassDescriptor descriptor) {
231         //do nothing
232
}
233
234     /**
235      * Used to track instances of the change policies without doing an instance of check
236      */

237     public boolean isDeferredChangeDetectionPolicy(){
238         return true;
239     }
240
241     /**
242      * Used to track instances of the change policies without doing an instance of check
243      */

244     public boolean isObjectChangeTrackingPolicy(){
245         return false;
246     }
247
248     /**
249      * Used to track instances of the change policies without doing an instance of check
250      */

251     public boolean isAttributeChangeTrackingPolicy(){
252         return false;
253     }
254 }
255
Popular Tags