* @param doMap (map of original do's (CS1) to their copy do's in (CS2))
*/
private void copyChangeSummary(ChangeSummary anOriginalCS, ChangeSummary aCopyCS,//
Map origDOCS1toCopyDOCS2Map) {
// cast interfaces to concrete classes in one place
SDOChangeSummary originalCS = (SDOChangeSummary)anOriginalCS;
SDOChangeSummary copyCS = (SDOChangeSummary)aCopyCS;
// handled by copy constructor
// map of copy of original ListWrapper (CS2) to its new copy of a copy (CS2) - link ValueStores to Elements
HashMap copyListWrapperCS2toCopyOfListCS2Map = new HashMap();
// in the absence of a ListWrapper.getProperty() we keep a map
HashMap propertyToOriginalListMap = new HashMap();
/**
* In 3 parts we add deleted objects to the global doMap and copy modified, created nodes
**/
// fields that need re-referencing from original to copy
DataObject anOriginalObject = null;
DataObject aCopyOfOriginalObject = null;
// iterate deleted objects
for (Iterator anIterator = originalCS.getDeleted().iterator(); anIterator.hasNext();) {
anOriginalObject = (DataObject)anIterator.next();
aCopyOfOriginalObject = copy(anOriginalObject, null);
// fix deletedList
copyCS.getDeleted().add(aCopyOfOriginalObject);
// Assumption check do map before a possible re-add - reset()
if (null == origDOCS1toCopyDOCS2Map.get(anOriginalObject)) {
// add temp map of original : copy of original
origDOCS1toCopyDOCS2Map.put(anOriginalObject, aCopyOfOriginalObject);
}
}
// iterate created objects
for (Iterator aIterator = originalCS.getCreated().iterator(); aIterator.hasNext();) {
copyCS.getCreated().add(origDOCS1toCopyDOCS2Map.get(aIterator.next()));
}
// add modified objects
for (Iterator anIterator = originalCS.getModified().iterator(); anIterator.hasNext();) {
copyCS.getModified().add(origDOCS1toCopyDOCS2Map.get(anIterator.next()));
}
/**
* Fix originalValueStores by deep copying the original dataObject:key and the original valueStore:value
* key is original deleted object in [deepCopies] - value is copy of the ValueStore
*/
ValueStore aVSCopy = null;
ValueStore aVSOriginal = null;
for (Iterator anIterator = originalCS.getOriginalValueStores().keySet().iterator();
anIterator.hasNext();) {
anOriginalObject = (DataObject)anIterator.next();
// deep copy to get corresponding copy DataObject (deleted objects were added to doMap)
aCopyOfOriginalObject = (DataObject)origDOCS1toCopyDOCS2Map.get(anOriginalObject);
/**
* Recursively shallow-copy elements (by iterating the ovs map and iterating the properties of each item)
* Fix the dataObject pointer
*/
aVSCopy = createValueStore();
aVSOriginal = (ValueStore)originalCS.getOriginalValueStores().get(anOriginalObject);
// changes made to the copy VS must not affect the original -hence the dataObject field must be a copy of the original
aVSCopy.initialize(aCopyOfOriginalObject);
Object aVSPropertyItem = null;
// get the # of non-opencontent properties for the object holding the CS - do not use DVS.getTypePropertyValues()
for (int size = anOriginalObject.getType().getDeclaredProperties().size(), i = 0;
i < size; i++) {
aVSPropertyItem = aVSOriginal.getDeclaredProperty(i);
// only iterate set properties
if (aVSOriginal.isSetDeclaredProperty(i)) {
// shallow copy the object values
// handle single case
SDOProperty currentProperty = (SDOProperty)anOriginalObject.getType().getDeclaredProperties().get(i);
if (currentProperty.isMany()) {
propertyToOriginalListMap.put(aVSPropertyItem, currentProperty);
// handle many case - handled by originalElements
// container DO must be in our reference map
SDODataObject copyContainer = (SDODataObject)origDOCS1toCopyDOCS2Map.get(anOriginalObject);
ListWrapper aCopyOfListCopy = (ListWrapper)((DataObject)copyContainer).getList(currentProperty);
// add reference of new copy of original List keyed on original List
copyListWrapperCS2toCopyOfListCS2Map.put((anOriginalObject).getList(currentProperty), aCopyOfListCopy);
aVSCopy.setDeclaredProperty(i, aCopyOfListCopy);
} else {
// COMPLEX SINGLE
if (!currentProperty.getType().isDataType()) {
// are we using the cast to DataObject as a sort of instance check that would throw a CCE?
aVSCopy.setDeclaredProperty(i, origDOCS1toCopyDOCS2Map.get(aVSPropertyItem));
} else {
// SIMPLE SINGLE
// skip changeSummary property
if (!currentProperty.getType().isChangeSummaryType()) {
// simple singles set
aVSCopy.setDeclaredProperty(i, aVSPropertyItem);
}
}
}
}
}
// create list of unset and current open content properties
List ocPropertiesList = new ArrayList();
ocPropertiesList.addAll(originalCS.getUnsetOCProperties(anOriginalObject));
// add existing properties
ocPropertiesList.addAll(((SDODataObject)anOriginalObject)._getOpenContentProperties());
ocPropertiesList.addAll(((SDODataObject)anOriginalObject)._getOpenContentPropertiesAttributes());
// iterate existing open content properties
for (Iterator i = ocPropertiesList.iterator(); i.hasNext();) {
Property ocProperty = (Property)i.next();
if (aVSOriginal.isSetOpenContentProperty(ocProperty)) {
// get oc value
Object anOCPropertyItem = aVSOriginal.getOpenContentProperty(ocProperty);
// get oc copy - shallow copy the object values
if (ocProperty.isMany()) {
// handle many case - handled by originalElements
// container DO must be in our reference map
SDODataObject copyContainer = (SDODataObject)origDOCS1toCopyDOCS2Map.get(anOriginalObject);
ListWrapper aCopyOfListCopy = (ListWrapper)((DataObject)copyContainer).getList(ocProperty);
// add reference of new copy of original List keyed on original List
copyListWrapperCS2toCopyOfListCS2Map.put((anOriginalObject).getList(ocProperty), aCopyOfListCopy);
aVSCopy.setOpenContentProperty(ocProperty, aCopyOfListCopy);
} else {
// handle complex single case
if (!ocProperty.getType().isDataType()) {
aVSCopy.setOpenContentProperty(ocProperty, origDOCS1toCopyDOCS2Map.get(aVSPropertyItem));
} else {
// simple singles set
aVSCopy.setOpenContentProperty(ocProperty, anOCPropertyItem);
}
}
}
}
// set the copy map entry keyed on copy with value a deep copy of the copy
copyCS.getOriginalValueStores().put(aCopyOfOriginalObject, aVSCopy);
}
// end originalValueStore iteration
/**
* Fix originalElements by deep copying the original dataObject:key and the original List:value
* key is original deleted object in [deepCopies] - value is copy of the elements
* The instances of ListWrapper inside the valueStores must be the same ones used in the originalElements
*/
ListWrapper anOriginalListKey = null;
ListWrapper aCopyListWrapper = null;
List aCopyList = null;
for (Iterator anIterator = originalCS.getOriginalElements().keySet().iterator();
anIterator.hasNext();) {
anOriginalListKey = (ListWrapper)anIterator.next();
// create a new ListWrapper
Property aProperty = (Property)propertyToOriginalListMap.get(anOriginalListKey);
aCopyListWrapper = (ListWrapper)copyListWrapperCS2toCopyOfListCS2Map.get(anOriginalListKey);
aCopyList = new ArrayList();
/**
* For each key:ListWrapper
* - shallow copy all the items in the currentElements list
* - replace the dataObject with its copy of the copy
* - leave the property as is
* For each value:ArrayList
* - replace all values with their copy
*/
Object aListItem = null;
Object aListItemCopy = null;
for (Iterator anItemIterator = anOriginalListKey.iterator(); anItemIterator.hasNext();) {
aListItem = anItemIterator.next();
// for simple many types we use the original in the copy
if (!aProperty.getType().isDataType()) {
// get the copy of the original (in the current valuestore) - we need do not make a copy of this copy
// we should have a copy of the copy for List items - ListWrapper.add(item) will remove the item from its original wrapper
aListItemCopy = origDOCS1toCopyDOCS2Map.get(aListItem);
} else {
aListItemCopy = aListItem;
}
aCopyList.add(aListItemCopy);
}
// add element list directly to the ListWrapper and bypass the cs element copy and containment updates
aCopyListWrapper.setCurrentElements(aCopyList);
List listValueCopy = new ArrayList();
// fix ArrayList value
List listValue = (List)originalCS.getOriginalElements().get(anOriginalListKey);
aListItem = null;
aListItemCopy = null;
for (Iterator aListIterator = listValue.iterator(); aListIterator.hasNext();) {
aListItem = aListIterator.next();
// for simple many types we use the original in the copy
if (!aProperty.getType().isDataType()) {
aListItemCopy = origDOCS1toCopyDOCS2Map.get(aListItem);
} else {
aListItemCopy = aListItem;
}
// don't add nulls to the listWrapper so an undoChanges will encounter an NPE later
if (aListItemCopy != null) {
listValueCopy.add(aListItemCopy);
}
}
// set the copy map entry keyed on copy with value a deep copy of the copy
copyCS.getOriginalElements().put(aCopyListWrapper, listValueCopy);
}
// end originalist Iteration
/**
* fields that are already set when logging is turned on but need to be fixed (deleted objects need references)
*/
Map oldContainersMap = originalCS.getOldContainers();
Map copyContainersMap = copyCS.getOldContainers();
DataObject oldContainerKey = null;
DataObject copyContainerKey = null;
// convert any existing entries in the Map - should normally be 0 - unless any OC properties were unset
for (Iterator anIterator = oldContainersMap.keySet().iterator(); anIterator.hasNext();) {
oldContainerKey = (DataObject)anIterator.next();
// get corresponding copy
copyContainerKey = (SDODataObject)origDOCS1toCopyDOCS2Map.get(oldContainerKey);
// check existing copyContainers for existing objects - should be 0 - add all objects when pauseLogging() used
DataObject oldContainerValue = null;
if (null == copyContainersMap.get(copyContainerKey)) {
oldContainerValue = (DataObject)oldContainersMap.get(oldContainerKey);
// set copy key:value pair on copy map directly
copyContainersMap.put(copyContainerKey, origDOCS1toCopyDOCS2Map.get(oldContainerValue));
}
}
Map oldContainmentPropertyMap = originalCS.getOldContainmentProperty();
Map copyContainmentPropertyMap = copyCS.getOldContainmentProperty();
DataObject oldContainmentPropertyKey = null;
DataObject copyContainmentPropertyKey = null;
// convert any existing entries in the Map - should normally be 0 - unless any OC properties were unset
for (Iterator iterContProp = oldContainmentPropertyMap.keySet().iterator();
iterContProp.hasNext();) {
oldContainmentPropertyKey = (DataObject)iterContProp.next();
// get corresponding copy
copyContainmentPropertyKey = (SDODataObject)origDOCS1toCopyDOCS2Map.get(oldContainmentPropertyKey);
// check existing copyContainers for existing objects - should be 0 - add all objects when pauseLogging() used
if (null == copyContainmentPropertyMap.get(copyContainmentPropertyKey)) {
// set copy key:value pair on copy map directly
copyContainmentPropertyMap.put(copyContainmentPropertyKey, oldContainmentPropertyMap.get(oldContainmentPropertyKey));
}
}
Map oldUnsetOCPropertyMap = originalCS.getUnsetOCPropertiesMap();
SDODataObject oldOCPropertyContainer = null;
// convert any existing entries in the Map - should normally be 0
for (Iterator iterContainer = oldUnsetOCPropertyMap.keySet().iterator();
iterContainer.hasNext();) {
// DataObject will be non-Null
oldOCPropertyContainer = (SDODataObject)iterContainer.next();
// check existing copyContainers for existing objects - should be 0 - add all objects when pauseLogging() used
for (Iterator iterUnset = ((List)oldUnsetOCPropertyMap.get(oldOCPropertyContainer)).iterator();
iterUnset.hasNext();) {
// set/create new list on copy Map with corresponding copy of container
copyCS.setUnsetOCProperty((SDODataObject)origDOCS1toCopyDOCS2Map.get(//
oldOCPropertyContainer), (Property)iterUnset.next());
}
}
// process sequences
/**
* Fix originalSequences by deep copying the original dataObject:key and the original Sequence:value
* key is original deleted object in [deepCopies] - value is copy of the settings in the sequence.
* The instances of Sequence inside the originalSequences must be the same ones used in the originalElements
*/
// iterate the map of <DataObject, Sequence>
for (Iterator aMapIterator = originalCS.getOriginalSequences().keySet().iterator();
aMapIterator.hasNext();) {
SDODataObject sequenceDataObjectKey = (SDODataObject)aMapIterator.next();
SDOSequence originalSequence = (SDOSequence)originalCS.getOriginalSequences().get(sequenceDataObjectKey);
// create a new Sequence with a pointer to the copy of the original DataObject backpointer
// assume that all dataObject backpointers are containment objects.
SDODataObject copyOriginalSequenceDataObject = (SDODataObject)origDOCS1toCopyDOCS2Map.get(originalSequence.getDataObject());
SDOSequence copySequence = new SDOSequence(copyOriginalSequenceDataObject);
replicateAndRereferenceSequenceCopyPrivate(originalSequence, copySequence, originalSequence.getDataObject(), copyOriginalSequenceDataObject, origDOCS1toCopyDOCS2Map, originalCS);
// set the copy map entry keyed on copy with value a deep copy of the copy
copyCS.getOriginalSequences().put(copyOriginalSequenceDataObject, copySequence);
}
/**
* fields to ignore
// aHelperContext SDOHelperContext (id=42)