KickJava   Java API By Example, From Geeks To Geeks.

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


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.sessions;
23
24 import java.util.*;
25 import oracle.toplink.essentials.internal.queryframework.ContainerPolicy;
26 import oracle.toplink.essentials.internal.sessions.AbstractSession;
27
28 /**
29  * <p>
30  * <b>Purpose</b>: This class holds the record of the changes made to a collection attribute of
31  * an object.
32  * <p>
33  * <b>Description</b>: Collections must be compared to each other and added and removed objects must
34  * be recorded seperately
35  * @see OtherRelatedClasses prototype.changeset.DirectToFieldChangeRecord,prototype.changeset.SingleObjectChangeRecord
36  */

37 public class DirectCollectionChangeRecord extends ChangeRecord implements oracle.toplink.essentials.changesets.DirectCollectionChangeRecord {
38     protected java.util.HashMap JavaDoc addObjectMap;
39     protected java.util.HashMap JavaDoc removeObjectMap;
40     //contains the number of objects that must be inserted to once the value is removed
41
//in the database as a delete where value = "value" will remove all instances
42
//of that value in the database not just one.
43
protected java.util.HashMap JavaDoc commitAddMap;
44     
45     /**
46      * Used for change tracking when customer sets entire collection
47      */

48     protected transient Object JavaDoc originalCollection;
49
50     /**
51      * Used for change tracking when customer sets entire collection
52      */

53     protected transient Object JavaDoc latestCollection;
54
55     public static NULL Null = new NULL();
56
57     /**
58      * This defaul constructor is reference internally by SDK XML project to mapp this class
59      */

60     public DirectCollectionChangeRecord() {
61         super();
62     }
63
64     /**
65      * This constructor returns a changeRecord representing the DirectCollection mapping
66      * @param owner prototype.changeset.ObjectChangeSet that ObjectChangeSet that uses this record
67      */

68     public DirectCollectionChangeRecord(ObjectChangeSet owner) {
69         this.owner = owner;
70     }
71
72     /**
73      * This method takes a hastable of primitive objects and adds them to the add list.
74      * the hashtable stores the number of times the object is in the list
75      * @param objectChanges prototype.changeset.ObjectChangeSet
76      */

77     public void addAdditionChange(HashMap additions, HashMap databaseCount) {
78         Iterator enumtr = additions.keySet().iterator();
79         while (enumtr.hasNext()) {
80             Object JavaDoc object = enumtr.next();
81             if (databaseCount.containsKey(object)){
82                 getCommitAddMap().put(object, databaseCount.get(object));
83             }
84             addAdditionChange(object, (Integer JavaDoc)additions.get(object));
85         }
86     }
87
88     /**
89      * This method takes a single addition value and records it.
90      */

91     public void addAdditionChange(Object JavaDoc key, Integer JavaDoc count){
92         if (getRemoveObjectMap().containsKey(key)){
93             int removeValue = ((Integer JavaDoc)getRemoveObjectMap().get(key)).intValue();
94             int addition = count.intValue();
95             int result = removeValue - addition;
96             if (result > 0 ) { // more removes still
97
getRemoveObjectMap().put(key, new Integer JavaDoc(result));
98             }else if (result < 0) { // more adds now
99
getRemoveObjectMap().remove(key);
100                 getAddObjectMap().put(key, new Integer JavaDoc(Math.abs(result)));
101             }else{ // equal
102
getRemoveObjectMap().remove(key);
103             }
104         }else{
105             if (this.getAddObjectMap().containsKey(key)){
106                 int addValue = ((Integer JavaDoc)this.getAddObjectMap().get(key)).intValue();
107                 addValue += count.intValue();
108                 this.getAddObjectMap().put(key, new Integer JavaDoc(addValue));
109             }else{
110                 this.getAddObjectMap().put(key, count);
111             }
112         }
113         // this is an attribute change track add keep count
114
int addValue = count.intValue();
115         int commitValue = 0;
116         if (getCommitAddMap().containsKey(key)){
117             commitValue = ((Integer JavaDoc)getCommitAddMap().get(key)).intValue();
118         }
119         getCommitAddMap().put(key, new Integer JavaDoc(addValue+commitValue));
120     }
121     /**
122      * This method takes a hashtable of primitive objects and adds them to the remove list.
123      * Each reference in the hashtable lists the number of this object that needs to be removed from the
124      * collection.
125      * @param objectChanges prototype.changeset.ObjectChangeSet
126      */

127     public void addRemoveChange(HashMap additions, HashMap databaseCount) {
128         Iterator enumtr = additions.keySet().iterator();
129         while (enumtr.hasNext()) {
130             Object JavaDoc object = enumtr.next();
131             if (databaseCount.containsKey(object)){
132                 getCommitAddMap().put(object, databaseCount.get(object));
133             }
134             addRemoveChange(object, (Integer JavaDoc)additions.get(object));
135         }
136     }
137     
138     /**
139      * This method takes a single remove change and integrates it with this changeset
140      */

141     public void addRemoveChange(Object JavaDoc key, Integer JavaDoc count){
142         if (getAddObjectMap().containsKey(key)){
143             int removeValue = ((Integer JavaDoc)getAddObjectMap().get(key)).intValue();
144             int addition = count.intValue();
145             int result = removeValue - addition;
146             if (result > 0 ) { // more removes still
147
getAddObjectMap().put(key, new Integer JavaDoc(result));
148             }else if (result < 0) { // more adds now
149
getAddObjectMap().remove(key);
150                 getRemoveObjectMap().put(key, new Integer JavaDoc(Math.abs(result)));
151             }else{ // equal
152
getAddObjectMap().remove(key);
153             }
154         }else{
155             if (this.getRemoveObjectMap().containsKey(key)){
156                 int addValue = ((Integer JavaDoc)this.getRemoveObjectMap().get(key)).intValue();
157                 addValue += count.intValue();
158                 this.getRemoveObjectMap().put(key, new Integer JavaDoc(addValue));
159             }else{
160                 this.getRemoveObjectMap().put(key, count);
161             }
162         }
163         int removeValue = count.intValue();
164         int commitValue = 0;
165         if (getCommitAddMap().containsKey(key)){
166             commitValue = ((Integer JavaDoc)getCommitAddMap().get(key)).intValue();
167         }
168         getCommitAddMap().put(key, new Integer JavaDoc(commitValue - removeValue));
169         
170     }
171
172     /**
173      * This method takes a hashtable of primitives and adds them to the commit list.
174      * This count value provided is the number of instances that will need to be
175      * inserted into the database once a remove has occured. This is only set
176      * once for each object type
177      */

178     public void setCommitAddition(Hashtable additions){
179         Enumeration enumtr = additions.keys();
180         while (enumtr.hasMoreElements()) {
181             Object JavaDoc object = enumtr.nextElement();
182             getCommitAddMap().put(object, additions.get(object));
183         }
184     }
185
186     /**
187      * Used for change tracking when cutomer sets entire collection
188      * This is the last collection that was set on the object
189      */

190     public void setLatestCollection(Object JavaDoc latestCollection) {
191         this.latestCollection = latestCollection;
192     }
193
194     /**
195      * Used for change tracking when cutomer sets entire collection
196      * This is the original collection that was set on the object when it was cloned
197      */

198     public void setOriginalCollection(Object JavaDoc originalCollection) {
199         this.originalCollection = originalCollection;
200     }
201
202     /**
203      * This method will iterate over the collection and store the database counts for
204      * the objects within the collection, this is used for minimal updates
205      */

206     public void storeDatabaseCounts(Object JavaDoc collection, ContainerPolicy containerPolicy, AbstractSession session){
207         Object JavaDoc iterator = containerPolicy.iteratorFor(collection);
208         while (containerPolicy.hasNext(iterator)){
209             Object JavaDoc object = containerPolicy.next(iterator, session);
210             if (getCommitAddMap().containsKey(object)){
211                 int count = ((Integer JavaDoc)getCommitAddMap().get(object)).intValue();
212                 getCommitAddMap().put(object, new Integer JavaDoc(++count));
213             }else{
214                 getCommitAddMap().put(object, new Integer JavaDoc(1));
215             }
216         }
217     }
218
219     /**
220      * ADVANCED:
221      * This method returns the list of added objects
222      */

223     public Vector getAddObjectList(){
224         Vector vector = new Vector();
225         for (Iterator iterator = getAddObjectMap().keySet().iterator(); iterator.hasNext();){
226             Object JavaDoc object = iterator.next();
227             int count = ((Integer JavaDoc)getAddObjectMap().get(object)).intValue();
228             while (count > 0){
229                 vector.add(object);
230                 --count;
231             }
232         }
233         return vector;
234     }
235
236     /**
237      * INTERNAL:
238      * This method sets the list of added objects. It should only be used in RCM
239      */

240     public void setAddObjectList(Vector list){
241         for (Iterator iterator = list.iterator(); iterator.hasNext();){
242             Object JavaDoc object = iterator.next();
243             this.addAdditionChange(object, new Integer JavaDoc(1));
244         }
245     }
246
247     /**
248      * ADVANCED:
249      * This method returns the collection of objects that were added to the collection.
250      * @return java.util.Vector
251      */

252     public java.util.HashMap JavaDoc getAddObjectMap() {
253         if (this.addObjectMap == null) {
254             this.addObjectMap = new HashMap(1);
255         }
256         return addObjectMap;
257     }
258
259     /**
260      * ADVANCED:
261      * This method returns the collection of objects that were added to the collection.
262      * @return java.util.Vector
263      */

264     public java.util.HashMap JavaDoc getCommitAddMap() {
265         if (this.commitAddMap == null) {
266             this.commitAddMap = new HashMap(1);
267         }
268         return commitAddMap;
269     }
270
271     /**
272      * Used for change tracking when cutomer sets entire collection
273      * This is the last collection that was set on the object
274      */

275     public Object JavaDoc getLatestCollection() {
276         return latestCollection;
277     }
278
279     /**
280      * Used for change tracking when cutomer sets entire collection
281      * This is the original collection that was set on the object when it was cloned
282      */

283     public Object JavaDoc getOriginalCollection() {
284         return originalCollection;
285     }
286
287     /**
288      * ADVANCED:
289      * This method returns the list of removed objects
290      */

291     public Vector getRemoveObjectList(){
292         Vector vector = new Vector();
293         for (Iterator iterator = getRemoveObjectMap().keySet().iterator(); iterator.hasNext();){
294             Object JavaDoc object = iterator.next();
295             int count = ((Integer JavaDoc)getRemoveObjectMap().get(object)).intValue();
296             while (count > 0){
297                 vector.add(object);
298                 --count;
299             }
300         }
301         return vector;
302     }
303
304     /**
305      * INTERNAL:
306      * This method sets the list of added objects. It should only be used in RCM
307      */

308     public void setRemoveObjectList(Vector list){
309         for (Iterator iterator = list.iterator(); iterator.hasNext();){
310             Object JavaDoc object = iterator.next();
311             this.addRemoveChange(object, new Integer JavaDoc(1));
312         }
313     }
314
315     /**
316      * ADVANCED:
317      * This method returns the collection of objects that were removed from the collection.
318      * @return java.util.Vector
319      */

320     public java.util.HashMap JavaDoc getRemoveObjectMap() {
321         if (this.removeObjectMap == null) {
322             removeObjectMap = new HashMap(1);
323         }
324         return removeObjectMap;
325     }
326
327     /**
328      * returns true if the change set has changes
329      */

330     public boolean hasChanges() {
331         return (!(getAddObjectMap().isEmpty() && getRemoveObjectMap().isEmpty())) || getOwner().isNew();
332     }
333
334     /**
335      * INTERNAL:
336      * This method will be used to merge one record into another
337      */

338     public void mergeRecord(ChangeRecord mergeFromRecord, UnitOfWorkChangeSet mergeToChangeSet, UnitOfWorkChangeSet mergeFromChangeSet) {
339         HashMap addMapToMerge = ((DirectCollectionChangeRecord)mergeFromRecord).getAddObjectMap();
340         HashMap removeMapToMerge = ((DirectCollectionChangeRecord)mergeFromRecord).getRemoveObjectMap();
341         //merge additions
342
for (Iterator iterator = addMapToMerge.keySet().iterator(); iterator.hasNext();){
343             Object JavaDoc added = iterator.next();
344             if (!((DirectCollectionChangeRecord)mergeFromRecord).getCommitAddMap().containsKey(added)){
345                 // we have not recorded a change of this type in this class before so add it
346
this.getCommitAddMap().put(added, ((DirectCollectionChangeRecord)mergeFromRecord).getCommitAddMap().get(added));
347             }
348             this.addAdditionChange(added, (Integer JavaDoc)addMapToMerge.get(added));
349         }
350         //merge removals
351
for (Iterator iterator = removeMapToMerge.keySet().iterator(); iterator.hasNext();){
352             Object JavaDoc removed = iterator.next();
353             if (!((DirectCollectionChangeRecord)mergeFromRecord).getCommitAddMap().containsKey(removed)){
354                 // we have not recorded a change of this type in this class before so add it
355
this.getCommitAddMap().put(removed, ((DirectCollectionChangeRecord)mergeFromRecord).getCommitAddMap().get(removed));
356             }
357             this.addRemoveChange(removed, (Integer JavaDoc)addMapToMerge.get(removed));
358         }
359    }
360
361     /**
362      * INTERNAL:
363      * This method will be used to update the objectsChangeSets references
364      */

365     public void updateReferences(UnitOfWorkChangeSet mergeToChangeSet, UnitOfWorkChangeSet mergeFromChangeSet) {
366         //nothing for this record type to do as it does not reference any changesets
367
}
368     
369     public static class NULL {
370         // This is a placeholder for null instances.
371
public NULL(){
372         }
373         
374         public boolean equals(Object JavaDoc object){
375             return object instanceof NULL;
376         }
377         
378     }
379 }
380
Popular Tags