Esempio n. 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);
            }
        }
		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;
		}