示例#1
0
        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);
            }
        }