internal ObjectDiff GetDiff(object oldStatus, object newStatus) { PropertyDiff[] propChanges = GetPropertyDiff(currentStatusAdaptor, oldStatus, newStatusAdaptor, newStatus); PropertyDiff[] signalChanges = GetSignalDiff(currentStatusAdaptor, oldStatus, newStatusAdaptor, newStatus); ArrayList changes = new ArrayList(); Hashtable foundChildren = new Hashtable(); // Register changed and deleted child elements foreach (object oldChild in currentStatusAdaptor.GetChildren(oldStatus)) { string cid = currentStatusAdaptor.GetUndoId(oldChild); if (cid != null && cid.Length > 0) { object newChild = newStatusAdaptor.FindChild(newStatus, cid); if (newChild != null) { // ChildCreate will work even if the packing element is null ObjectDiff odiff = GetChildDiff(oldChild, newChild); if (odiff != null) { ChildDiff cdiff = new ChildDiff(); cdiff.Id = cid; cdiff.Operation = DiffOperation.Update; cdiff.Diff = odiff; changes.Add(cdiff); } foundChildren [cid] = cid; } else { ChildDiff cdiff = new ChildDiff(); cdiff.Id = cid; cdiff.Operation = DiffOperation.Remove; changes.Add(cdiff); } } else { throw new InvalidOperationException("Found an element of type '" + oldChild.GetType() + "' without ID"); } } // Register new elements string lastWidgetId = null; foreach (object newChildElem in newStatusAdaptor.GetChildren(newStatus)) { string cid = newStatusAdaptor.GetUndoId(newChildElem); if (cid.Length > 0) { if (!foundChildren.ContainsKey(cid)) { ChildDiff cdiff = new ChildDiff(); cdiff.Id = cid; cdiff.Operation = DiffOperation.Add; cdiff.AddContent = newStatusAdaptor.SerializeChild(newChildElem); cdiff.InsertAfter = lastWidgetId; changes.Add(cdiff); } } else { throw new InvalidOperationException("Found an element of type '" + newChildElem.GetType() + "' without ID"); } lastWidgetId = cid; } ChildDiff[] childChanges = null; if (changes.Count > 0) { childChanges = (ChildDiff[])changes.ToArray(typeof(ChildDiff)); } if (childChanges != null || propChanges != null || signalChanges != null) { ObjectDiff dif = new ObjectDiff(); dif.PropertyChanges = propChanges; dif.SignalChanges = signalChanges; dif.ChildChanges = childChanges; return(dif); } else { return(null); } }
internal ObjectDiff GetDiff (object oldStatus, object newStatus) { PropertyDiff[] propChanges = GetPropertyDiff (currentStatusAdaptor, oldStatus, newStatusAdaptor, newStatus); PropertyDiff[] signalChanges = GetSignalDiff (currentStatusAdaptor, oldStatus, newStatusAdaptor, newStatus); ArrayList changes = new ArrayList (); Hashtable foundChildren = new Hashtable (); // Register changed and deleted child elements foreach (object oldChild in currentStatusAdaptor.GetChildren (oldStatus)) { string cid = currentStatusAdaptor.GetUndoId (oldChild); if (cid != null && cid.Length > 0) { object newChild = newStatusAdaptor.FindChild (newStatus, cid); if (newChild != null) { // ChildCreate will work even if the packing element is null ObjectDiff odiff = GetChildDiff (oldChild, newChild); if (odiff != null) { ChildDiff cdiff = new ChildDiff (); cdiff.Id = cid; cdiff.Operation = DiffOperation.Update; cdiff.Diff = odiff; changes.Add (cdiff); } foundChildren [cid] = cid; } else { ChildDiff cdiff = new ChildDiff (); cdiff.Id = cid; cdiff.Operation = DiffOperation.Remove; changes.Add (cdiff); } } else { throw new InvalidOperationException ("Found an element of type '" + oldChild.GetType () + "' without ID"); } } // Register new elements string lastWidgetId = null; foreach (object newChildElem in newStatusAdaptor.GetChildren (newStatus)) { string cid = newStatusAdaptor.GetUndoId (newChildElem); if (cid.Length > 0) { if (!foundChildren.ContainsKey (cid)) { ChildDiff cdiff = new ChildDiff (); cdiff.Id = cid; cdiff.Operation = DiffOperation.Add; cdiff.AddContent = newStatusAdaptor.SerializeChild (newChildElem); cdiff.InsertAfter = lastWidgetId; changes.Add (cdiff); } } else throw new InvalidOperationException ("Found an element of type '" + newChildElem.GetType () + "' without ID"); lastWidgetId = cid; } ChildDiff[] childChanges = null; if (changes.Count > 0) childChanges = (ChildDiff[]) changes.ToArray (typeof(ChildDiff)); if (childChanges != null || propChanges != null || signalChanges != null) { ObjectDiff dif = new ObjectDiff (); dif.PropertyChanges = propChanges; dif.SignalChanges = signalChanges; dif.ChildChanges = childChanges; return dif; } else return null; }