All Downloads are FREE. Search and download functionalities are using the official Maven repository.

oracle.toplink.essentials.internal.sessions.DirectCollectionChangeRecord Maven / Gradle / Ivy

There is a newer version: 2.1-60f
Show newest version
/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 * 
 * // Copyright (c) 1998, 2007, Oracle. All rights reserved.
 * 
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License. You can obtain
 * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
 * or glassfish/bootstrap/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 * 
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
 * Sun designates this particular file as subject to the "Classpath" exception
 * as provided by Sun in the GPL Version 2 section of the License file that
 * accompanied this code.  If applicable, add the following below the License
 * Header, with the fields enclosed by brackets [] replaced by your own
 * identifying information: "Portions Copyrighted [year]
 * [name of copyright owner]"
 * 
 * Contributor(s):
 * 
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 */
package oracle.toplink.essentials.internal.sessions;

import java.util.*;
import oracle.toplink.essentials.internal.queryframework.ContainerPolicy;
import oracle.toplink.essentials.internal.sessions.AbstractSession;

/**
 * 

* Purpose: This class holds the record of the changes made to a collection attribute of * an object. *

* Description: Collections must be compared to each other and added and removed objects must * be recorded seperately * @see OtherRelatedClasses prototype.changeset.DirectToFieldChangeRecord,prototype.changeset.SingleObjectChangeRecord */ public class DirectCollectionChangeRecord extends ChangeRecord implements oracle.toplink.essentials.changesets.DirectCollectionChangeRecord { protected java.util.HashMap addObjectMap; protected java.util.HashMap removeObjectMap; //contains the number of objects that must be inserted to once the value is removed //in the database as a delete where value = "value" will remove all instances //of that value in the database not just one. protected java.util.HashMap commitAddMap; /** * Used for change tracking when customer sets entire collection */ protected transient Object originalCollection; /** * Used for change tracking when customer sets entire collection */ protected transient Object latestCollection; public static NULL Null = new NULL(); /** * This defaul constructor is reference internally by SDK XML project to mapp this class */ public DirectCollectionChangeRecord() { super(); } /** * This constructor returns a changeRecord representing the DirectCollection mapping * @param owner prototype.changeset.ObjectChangeSet that ObjectChangeSet that uses this record */ public DirectCollectionChangeRecord(ObjectChangeSet owner) { this.owner = owner; } /** * This method takes a hastable of primitive objects and adds them to the add list. * the hashtable stores the number of times the object is in the list * @param objectChanges prototype.changeset.ObjectChangeSet */ public void addAdditionChange(HashMap additions, HashMap databaseCount) { Iterator enumtr = additions.keySet().iterator(); while (enumtr.hasNext()) { Object object = enumtr.next(); if (databaseCount.containsKey(object)){ getCommitAddMap().put(object, databaseCount.get(object)); } addAdditionChange(object, (Integer)additions.get(object)); } } /** * This method takes a single addition value and records it. */ public void addAdditionChange(Object key, Integer count){ if (getRemoveObjectMap().containsKey(key)){ int removeValue = ((Integer)getRemoveObjectMap().get(key)).intValue(); int addition = count.intValue(); int result = removeValue - addition; if (result > 0 ) { // more removes still getRemoveObjectMap().put(key, new Integer(result)); }else if (result < 0) { // more adds now getRemoveObjectMap().remove(key); getAddObjectMap().put(key, new Integer(Math.abs(result))); }else{ // equal getRemoveObjectMap().remove(key); } }else{ if (this.getAddObjectMap().containsKey(key)){ int addValue = ((Integer)this.getAddObjectMap().get(key)).intValue(); addValue += count.intValue(); this.getAddObjectMap().put(key, new Integer(addValue)); }else{ this.getAddObjectMap().put(key, count); } } // this is an attribute change track add keep count int addValue = count.intValue(); int commitValue = 0; if (getCommitAddMap().containsKey(key)){ commitValue = ((Integer)getCommitAddMap().get(key)).intValue(); } getCommitAddMap().put(key, new Integer(addValue+commitValue)); } /** * This method takes a hashtable of primitive objects and adds them to the remove list. * Each reference in the hashtable lists the number of this object that needs to be removed from the * collection. * @param objectChanges prototype.changeset.ObjectChangeSet */ public void addRemoveChange(HashMap additions, HashMap databaseCount) { Iterator enumtr = additions.keySet().iterator(); while (enumtr.hasNext()) { Object object = enumtr.next(); if (databaseCount.containsKey(object)){ getCommitAddMap().put(object, databaseCount.get(object)); } addRemoveChange(object, (Integer)additions.get(object)); } } /** * This method takes a single remove change and integrates it with this changeset */ public void addRemoveChange(Object key, Integer count){ if (getAddObjectMap().containsKey(key)){ int removeValue = ((Integer)getAddObjectMap().get(key)).intValue(); int addition = count.intValue(); int result = removeValue - addition; if (result > 0 ) { // more removes still getAddObjectMap().put(key, new Integer(result)); }else if (result < 0) { // more adds now getAddObjectMap().remove(key); getRemoveObjectMap().put(key, new Integer(Math.abs(result))); }else{ // equal getAddObjectMap().remove(key); } }else{ if (this.getRemoveObjectMap().containsKey(key)){ int addValue = ((Integer)this.getRemoveObjectMap().get(key)).intValue(); addValue += count.intValue(); this.getRemoveObjectMap().put(key, new Integer(addValue)); }else{ this.getRemoveObjectMap().put(key, count); } } int removeValue = count.intValue(); int commitValue = 0; if (getCommitAddMap().containsKey(key)){ commitValue = ((Integer)getCommitAddMap().get(key)).intValue(); } getCommitAddMap().put(key, new Integer(commitValue - removeValue)); } /** * This method takes a hashtable of primitives and adds them to the commit list. * This count value provided is the number of instances that will need to be * inserted into the database once a remove has occured. This is only set * once for each object type */ public void setCommitAddition(Hashtable additions){ Enumeration enumtr = additions.keys(); while (enumtr.hasMoreElements()) { Object object = enumtr.nextElement(); getCommitAddMap().put(object, additions.get(object)); } } /** * Used for change tracking when cutomer sets entire collection * This is the last collection that was set on the object */ public void setLatestCollection(Object latestCollection) { this.latestCollection = latestCollection; } /** * Used for change tracking when cutomer sets entire collection * This is the original collection that was set on the object when it was cloned */ public void setOriginalCollection(Object originalCollection) { this.originalCollection = originalCollection; } /** * This method will iterate over the collection and store the database counts for * the objects within the collection, this is used for minimal updates */ public void storeDatabaseCounts(Object collection, ContainerPolicy containerPolicy, AbstractSession session){ Object iterator = containerPolicy.iteratorFor(collection); while (containerPolicy.hasNext(iterator)){ Object object = containerPolicy.next(iterator, session); if (getCommitAddMap().containsKey(object)){ int count = ((Integer)getCommitAddMap().get(object)).intValue(); getCommitAddMap().put(object, new Integer(++count)); }else{ getCommitAddMap().put(object, new Integer(1)); } } } /** * ADVANCED: * This method returns the list of added objects */ public Vector getAddObjectList(){ Vector vector = new Vector(); for (Iterator iterator = getAddObjectMap().keySet().iterator(); iterator.hasNext();){ Object object = iterator.next(); int count = ((Integer)getAddObjectMap().get(object)).intValue(); while (count > 0){ vector.add(object); --count; } } return vector; } /** * INTERNAL: * This method sets the list of added objects. It should only be used in RCM */ public void setAddObjectList(Vector list){ for (Iterator iterator = list.iterator(); iterator.hasNext();){ Object object = iterator.next(); this.addAdditionChange(object, new Integer(1)); } } /** * ADVANCED: * This method returns the collection of objects that were added to the collection. * @return java.util.Vector */ public java.util.HashMap getAddObjectMap() { if (this.addObjectMap == null) { this.addObjectMap = new HashMap(1); } return addObjectMap; } /** * ADVANCED: * This method returns the collection of objects that were added to the collection. * @return java.util.Vector */ public java.util.HashMap getCommitAddMap() { if (this.commitAddMap == null) { this.commitAddMap = new HashMap(1); } return commitAddMap; } /** * Used for change tracking when cutomer sets entire collection * This is the last collection that was set on the object */ public Object getLatestCollection() { return latestCollection; } /** * Used for change tracking when cutomer sets entire collection * This is the original collection that was set on the object when it was cloned */ public Object getOriginalCollection() { return originalCollection; } /** * ADVANCED: * This method returns the list of removed objects */ public Vector getRemoveObjectList(){ Vector vector = new Vector(); for (Iterator iterator = getRemoveObjectMap().keySet().iterator(); iterator.hasNext();){ Object object = iterator.next(); int count = ((Integer)getRemoveObjectMap().get(object)).intValue(); while (count > 0){ vector.add(object); --count; } } return vector; } /** * INTERNAL: * This method sets the list of added objects. It should only be used in RCM */ public void setRemoveObjectList(Vector list){ for (Iterator iterator = list.iterator(); iterator.hasNext();){ Object object = iterator.next(); this.addRemoveChange(object, new Integer(1)); } } /** * ADVANCED: * This method returns the collection of objects that were removed from the collection. * @return java.util.Vector */ public java.util.HashMap getRemoveObjectMap() { if (this.removeObjectMap == null) { removeObjectMap = new HashMap(1); } return removeObjectMap; } /** * returns true if the change set has changes */ public boolean hasChanges() { return (!(getAddObjectMap().isEmpty() && getRemoveObjectMap().isEmpty())) || getOwner().isNew(); } /** * INTERNAL: * This method will be used to merge one record into another */ public void mergeRecord(ChangeRecord mergeFromRecord, UnitOfWorkChangeSet mergeToChangeSet, UnitOfWorkChangeSet mergeFromChangeSet) { HashMap addMapToMerge = ((DirectCollectionChangeRecord)mergeFromRecord).getAddObjectMap(); HashMap removeMapToMerge = ((DirectCollectionChangeRecord)mergeFromRecord).getRemoveObjectMap(); //merge additions for (Iterator iterator = addMapToMerge.keySet().iterator(); iterator.hasNext();){ Object added = iterator.next(); if (!((DirectCollectionChangeRecord)mergeFromRecord).getCommitAddMap().containsKey(added)){ // we have not recorded a change of this type in this class before so add it this.getCommitAddMap().put(added, ((DirectCollectionChangeRecord)mergeFromRecord).getCommitAddMap().get(added)); } this.addAdditionChange(added, (Integer)addMapToMerge.get(added)); } //merge removals for (Iterator iterator = removeMapToMerge.keySet().iterator(); iterator.hasNext();){ Object removed = iterator.next(); if (!((DirectCollectionChangeRecord)mergeFromRecord).getCommitAddMap().containsKey(removed)){ // we have not recorded a change of this type in this class before so add it this.getCommitAddMap().put(removed, ((DirectCollectionChangeRecord)mergeFromRecord).getCommitAddMap().get(removed)); } this.addRemoveChange(removed, (Integer)addMapToMerge.get(removed)); } } /** * INTERNAL: * This method will be used to update the objectsChangeSets references */ public void updateReferences(UnitOfWorkChangeSet mergeToChangeSet, UnitOfWorkChangeSet mergeFromChangeSet) { //nothing for this record type to do as it does not reference any changesets } public static class NULL { // This is a placeholder for null instances. public NULL(){ } public boolean equals(Object object){ return object instanceof NULL; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy