private bool HasChanged(NonNativeObjectInfo nnoi1, NonNativeObjectInfo nnoi2, int objectRecursionLevel) { var hasChanged = false; // If the object is already being checked, return false, this second // check will not affect the check int n; _alreadyCheckingObjects.TryGetValue(nnoi2, out n); if (n != 0) return false; // Put the object in the temporary cache _alreadyCheckingObjects[nnoi1] = 1; _alreadyCheckingObjects[nnoi2] = 1; // Warning ID Start with 1 and not 0 for (var id = 1; id <= nnoi1.GetMaxNbattributes(); id++) { var value1 = nnoi1.GetAttributeValueFromId(id); // Gets the value by the attribute id to be sure // Problem because a new object info may not have the right ids ? // Check if // the new oiD is ok. var value2 = nnoi2.GetAttributeValueFromId(id); if (value2 == null) { // this means the object to have attribute id StoreChangedObject(nnoi1, nnoi2, id, objectRecursionLevel); hasChanged = true; continue; } if (value1 == null) { //throw new ODBRuntimeException("ObjectInfoComparator.hasChanged:attribute with id "+id+" does not exist on "+nnoi2); // This happens when this object was created with an version of ClassInfo (which has been refactored). // In this case,we simply tell that in place update is not supported so that the object will be rewritten with // new metamodel continue; } // If both are null, no effect if (value1.IsNull() && value2.IsNull()) continue; if (value2.IsNull()) { hasChanged = true; _nbChanges++; continue; } if (value1.IsNull() && value2.IsNonNativeObject()) { hasChanged = true; _nbChanges++; continue; } if (!ClassAreCompatible(value1, value2)) { var nativeObjectInfo = value2 as NativeObjectInfo; if (nativeObjectInfo != null) { StoreChangedObject(nnoi1, nnoi2, id, objectRecursionLevel); _nbChanges++; } var objectReference = value2 as ObjectReference; if (objectReference != null) { var nnoi = (NonNativeObjectInfo) value1; var oref = objectReference; if (!nnoi.GetOid().Equals(oref.GetOid())) { StoreChangedObject(nnoi1, nnoi2, id, objectRecursionLevel); _nbChanges++; } else continue; } hasChanged = true; continue; } if (value1.IsAtomicNativeObject()) { if (!value1.Equals(value2)) { _nbChanges++; hasChanged = true; } continue; } if (value1.IsArrayObject()) { var aoi1 = (ArrayObjectInfo) value1; var aoi2 = (ArrayObjectInfo) value2; var arrayHasChanged = ManageArrayChanges(nnoi1, nnoi2, id, aoi1, aoi2, objectRecursionLevel); hasChanged = hasChanged || arrayHasChanged; continue; } if (value1.IsEnumObject()) { var enoi1 = (EnumNativeObjectInfo) value1; var enoi2 = (EnumNativeObjectInfo) value2; var enumHasChanged = !enoi1.GetEnumClassInfo().ClassInfoId.Equals(enoi2.GetEnumClassInfo().ClassInfoId) || !enoi1.GetEnumValue().Equals(enoi2.GetEnumValue()); hasChanged = hasChanged || enumHasChanged; continue; } if (value1.IsNonNativeObject()) { var oi1 = (NonNativeObjectInfo) value1; var oi2 = (NonNativeObjectInfo) value2; // If oids are equal, they are the same objects if (oi1.GetOid() != null && oi1.GetOid().Equals(oi2.GetOid())) hasChanged = HasChanged(value1, value2, objectRecursionLevel + 1) || hasChanged; else { // This means that an object reference has changed. hasChanged = true; _nbChanges++; objectRecursionLevel++; } } } var i1 = _alreadyCheckingObjects[nnoi1]; var i2 = _alreadyCheckingObjects[nnoi2]; i1 = i1 - 1; i2 = i2 - 1; if (i1 == 0) _alreadyCheckingObjects.Remove(nnoi1); else _alreadyCheckingObjects.Add(nnoi1, i1); if (i2 == 0) _alreadyCheckingObjects.Remove(nnoi2); else _alreadyCheckingObjects.Add(nnoi2, i2); return hasChanged; }
private bool HasChanged(NonNativeObjectInfo nnoi1, NonNativeObjectInfo nnoi2, int objectRecursionLevel) { var hasChanged = false; // If the object is already being checked, return false, this second // check will not affect the check int n; _alreadyCheckingObjects.TryGetValue(nnoi2, out n); if (n != 0) { return(false); } // Put the object in the temporary cache _alreadyCheckingObjects[nnoi1] = 1; _alreadyCheckingObjects[nnoi2] = 1; // Warning ID Start with 1 and not 0 for (var id = 1; id <= nnoi1.GetMaxNbattributes(); id++) { var value1 = nnoi1.GetAttributeValueFromId(id); // Gets the value by the attribute id to be sure // Problem because a new object info may not have the right ids ? // Check if // the new oiD is ok. var value2 = nnoi2.GetAttributeValueFromId(id); if (value2 == null) { // this means the object to have attribute id StoreChangedObject(nnoi1, nnoi2, id, objectRecursionLevel); hasChanged = true; continue; } if (value1 == null) { //throw new ODBRuntimeException("ObjectInfoComparator.hasChanged:attribute with id "+id+" does not exist on "+nnoi2); // This happens when this object was created with an version of ClassInfo (which has been refactored). // In this case,we simply tell that in place update is not supported so that the object will be rewritten with // new metamodel continue; } // If both are null, no effect if (value1.IsNull() && value2.IsNull()) { continue; } if (value2.IsNull()) { hasChanged = true; _nbChanges++; continue; } if (value1.IsNull() && value2.IsNonNativeObject()) { hasChanged = true; _nbChanges++; continue; } if (!ClassAreCompatible(value1, value2)) { var nativeObjectInfo = value2 as NativeObjectInfo; if (nativeObjectInfo != null) { StoreChangedObject(nnoi1, nnoi2, id, objectRecursionLevel); _nbChanges++; } var objectReference = value2 as ObjectReference; if (objectReference != null) { var nnoi = (NonNativeObjectInfo)value1; var oref = objectReference; if (!nnoi.GetOid().Equals(oref.GetOid())) { StoreChangedObject(nnoi1, nnoi2, id, objectRecursionLevel); _nbChanges++; } else { continue; } } hasChanged = true; continue; } if (value1.IsAtomicNativeObject()) { if (!value1.Equals(value2)) { _nbChanges++; hasChanged = true; } continue; } if (value1.IsArrayObject()) { var aoi1 = (ArrayObjectInfo)value1; var aoi2 = (ArrayObjectInfo)value2; var arrayHasChanged = ManageArrayChanges(nnoi1, nnoi2, id, aoi1, aoi2, objectRecursionLevel); hasChanged = hasChanged || arrayHasChanged; continue; } if (value1.IsEnumObject()) { var enoi1 = (EnumNativeObjectInfo)value1; var enoi2 = (EnumNativeObjectInfo)value2; var enumHasChanged = !enoi1.GetEnumClassInfo().ClassInfoId.Equals(enoi2.GetEnumClassInfo().ClassInfoId) || !enoi1.GetEnumValue().Equals(enoi2.GetEnumValue()); hasChanged = hasChanged || enumHasChanged; continue; } if (value1.IsNonNativeObject()) { var oi1 = (NonNativeObjectInfo)value1; var oi2 = (NonNativeObjectInfo)value2; // If oids are equal, they are the same objects if (oi1.GetOid() != null && oi1.GetOid().Equals(oi2.GetOid())) { hasChanged = HasChanged(value1, value2, objectRecursionLevel + 1) || hasChanged; } else { // This means that an object reference has changed. hasChanged = true; _nbChanges++; objectRecursionLevel++; } } } var i1 = _alreadyCheckingObjects[nnoi1]; var i2 = _alreadyCheckingObjects[nnoi2]; i1 = i1 - 1; i2 = i2 - 1; if (i1 == 0) { _alreadyCheckingObjects.Remove(nnoi1); } else { _alreadyCheckingObjects.Add(nnoi1, i1); } if (i2 == 0) { _alreadyCheckingObjects.Remove(nnoi2); } else { _alreadyCheckingObjects.Add(nnoi2, i2); } return(hasChanged); }
private bool HasChanged(NonNativeObjectInfo nnoi1, NonNativeObjectInfo nnoi2, int objectRecursionLevel) { AbstractObjectInfo value1 = null; AbstractObjectInfo value2 = null; bool hasChanged = false; // If the object is already being checked, return false, this second // check will not affect the check int n = 0; alreadyCheckingObjects.TryGetValue(nnoi2, out n); if (n != 0) { return(false); } // Put the object in the temporary cache alreadyCheckingObjects[nnoi1] = 1; alreadyCheckingObjects[nnoi2] = 1; // Warning ID Start with 1 and not 0 for (int id = 1; id <= nnoi1.GetMaxNbattributes(); id++) { value1 = nnoi1.GetAttributeValueFromId(id); // Gets the value by the attribute id to be sure // Problem because a new object info may not have the right ids ? // Check if // the new oiD is ok. value2 = nnoi2.GetAttributeValueFromId(id); if (value2 == null) { // this means the object to have attribute id StoreChangedObject(nnoi1, nnoi2, id, objectRecursionLevel); hasChanged = true; continue; } if (value1 == null) { //throw new ODBRuntimeException("ObjectInfoComparator.hasChanged:attribute with id "+id+" does not exist on "+nnoi2); // This happens when this object was created with an version of ClassInfo (which has been refactored). // In this case,we simply tell that in place update is not supported so that the object will be rewritten with // new metamodel supportInPlaceUpdate = false; continue; } // If both are null, no effect if (value1.IsNull() && value2.IsNull()) { continue; } if (value1.IsNull() || value2.IsNull()) { supportInPlaceUpdate = false; hasChanged = true; StoreActionSetAttributetoNull(nnoi1, id, objectRecursionLevel); continue; } if (!ClassAreCompatible(value1, value2)) { if (value2 is NativeObjectInfo) { StoreChangedObject(nnoi1, nnoi2, id, objectRecursionLevel); StoreChangedAttributeAction(new ChangedNativeAttributeAction (nnoi1, nnoi2, nnoi1.GetHeader().GetAttributeIdentificationFromId(id), (NativeObjectInfo )value2, objectRecursionLevel, false, nnoi1.GetClassInfo().GetAttributeInfoFromId (id).GetName())); } if (value2 is ObjectReference) { NonNativeObjectInfo nnoi = (NonNativeObjectInfo )value1; ObjectReference oref = (ObjectReference )value2; if (!nnoi.GetOid().Equals(oref.GetOid())) { StoreChangedObject(nnoi1, nnoi2, id, objectRecursionLevel); int attributeIdThatHasChanged = id; // this is the exact position where the object reference // definition is stored long attributeDefinitionPosition = nnoi2.GetAttributeDefinitionPosition(attributeIdThatHasChanged ); StoreChangedAttributeAction(new ChangedObjectReferenceAttributeAction (attributeDefinitionPosition, (ObjectReference )value2, objectRecursionLevel)); } else { continue; } } hasChanged = true; continue; } if (value1.IsAtomicNativeObject()) { if (!value1.Equals(value2)) { // storeChangedObject(nnoi1, nnoi2, id, // objectRecursionLevel); StoreChangedAttributeAction(new ChangedNativeAttributeAction (nnoi1, nnoi2, nnoi1.GetHeader().GetAttributeIdentificationFromId(id), (NativeObjectInfo )value2, objectRecursionLevel, false, nnoi1.GetClassInfo().GetAttributeInfoFromId (id).GetName())); hasChanged = true; continue; } continue; } if (value1.IsCollectionObject()) { CollectionObjectInfo coi1 = (CollectionObjectInfo)value1; CollectionObjectInfo coi2 = (CollectionObjectInfo)value2; bool collectionHasChanged = ManageCollectionChanges(nnoi1, nnoi2, id, coi1, coi2, objectRecursionLevel); hasChanged = hasChanged || collectionHasChanged; continue; } if (value1.IsArrayObject()) { ArrayObjectInfo aoi1 = (ArrayObjectInfo)value1; ArrayObjectInfo aoi2 = (ArrayObjectInfo)value2; bool arrayHasChanged = ManageArrayChanges(nnoi1, nnoi2, id, aoi1, aoi2, objectRecursionLevel ); hasChanged = hasChanged || arrayHasChanged; continue; } if (value1.IsMapObject()) { MapObjectInfo moi1 = (MapObjectInfo)value1; MapObjectInfo moi2 = (MapObjectInfo)value2; bool mapHasChanged = ManageMapChanges(nnoi1, nnoi2, id, moi1, moi2, objectRecursionLevel ); hasChanged = hasChanged || mapHasChanged; continue; } if (value1.IsEnumObject()) { EnumNativeObjectInfo enoi1 = (EnumNativeObjectInfo)value1; EnumNativeObjectInfo enoi2 = (EnumNativeObjectInfo)value2; bool enumHasChanged = !enoi1.GetEnumClassInfo().GetId().Equals(enoi2.GetEnumClassInfo ().GetId()) || !enoi1.GetEnumName().Equals(enoi2.GetEnumName()); hasChanged = hasChanged || enumHasChanged; continue; } if (value1.IsNonNativeObject()) { NonNativeObjectInfo oi1 = (NonNativeObjectInfo)value1; NonNativeObjectInfo oi2 = (NonNativeObjectInfo)value2; // If oids are equal, they are the same objects if (oi1.GetOid() != null && oi1.GetOid().Equals(oi2.GetOid())) { hasChanged = HasChanged(value1, value2, objectRecursionLevel + 1) || hasChanged; } else { // This means that an object reference has changed. hasChanged = true; // keep track of the position where the reference must be // updated long positionToUpdateReference = nnoi1.GetAttributeDefinitionPosition(id); StoreNewObjectReference(positionToUpdateReference, oi2, objectRecursionLevel, nnoi1 .GetClassInfo().GetAttributeInfoFromId(id).GetName()); objectRecursionLevel++; // Value2 may have change too AddPendingVerification(value2); } continue; } } int i1 = (int)alreadyCheckingObjects[nnoi1]; int i2 = (int)alreadyCheckingObjects[nnoi2]; if (i1 != null) { i1 = i1 - 1; } if (i2 != null) { i2 = i2 - 1; } if (i1 == 0) { alreadyCheckingObjects.Remove(nnoi1); } else { alreadyCheckingObjects.Add(nnoi1, i1); } if (i2 == 0) { alreadyCheckingObjects.Remove(nnoi2); } else { alreadyCheckingObjects.Add(nnoi2, i2); } return(hasChanged); }