public override void AddInterface(Type type, NodeInterface nodeInterface)
 {
     if (!(nodeInterface is XmlOutputNodeInterface))
     {
         throw new ArgumentException("Node interfaces for the XmlOutputStructuredDiff must implement XmlOutputNodeInterface.");
     }
     base.AddInterface(type, nodeInterface);
 }
 protected override void WriteNodeChange(NodeInterface leftInterface, object left, NodeInterface rightInterface, object right)
 {
     ((XmlOutputNodeInterface)leftInterface).WriteBeginNode(left, right, (XmlWriter)output);
     output.WriteAttributeString("Status", "Changed");
     ((XmlOutputNodeInterface)leftInterface).WriteBeginNode(left, left, (XmlWriter)output);
     ((XmlOutputNodeInterface)leftInterface).WriteNodeChildren(left, (XmlWriter)output);
     output.WriteEndElement();
     ((XmlOutputNodeInterface)rightInterface).WriteBeginNode(right, right, (XmlWriter)output);
     ((XmlOutputNodeInterface)rightInterface).WriteNodeChildren(right, (XmlWriter)output);
     output.WriteEndElement();
     output.WriteEndElement();
 }
        internal NodeInterface GetInterface(object obj)
        {
            bool store = false;
            Type type  = obj.GetType();

            while (type != null)
            {
                NodeInterface ret = (NodeInterface)nodeInterfaces[type];
                if (ret != null)
                {
                    if (store)
                    {
                        nodeInterfaces[obj.GetType()] = ret;
                    }
                    return(ret);
                }
                type  = type.BaseType;
                store = true;
            }
            throw new ArgumentException("Node type has no interface defined: " + obj.GetType());
        }
        int IComparer.Compare(object left, object right)
        {
            float ret;

            Pair pair = new Pair(left, right, differ);

            if (left.GetType() != right.GetType())
            {
                ret = 1;
            }
            else if (useCache && differ.comparisonCache.ContainsKey(pair))
            {
                ret = (float)differ.comparisonCache[pair];
            }
            else
            {
                NodeInterface comparer = differ.GetInterface(left);
                ret = comparer.Compare(left, right, differ);
            }

            if (useCache)
            {
                differ.comparisonCache[pair] = ret;
            }

            if (ret < minimumDifference && ret > threshold)
            {
                minimumDifference = ret;
            }

            if (ret <= threshold)
            {
                return(0);
            }
            else
            {
                return(1);
            }
        }
        protected override void WriteNodeSame(NodeInterface nodeInterface, object left, object right)
        {
            bool deep = deepOutput;

            if (left is XmlNode && !deepOutput && !allContext)
            {
                if (!contextNodes.ContainsKey(((XmlNode)left).Name))
                {
                    return;
                }
                else
                {
                    deep = true;
                }
            }

            ((XmlOutputNodeInterface)nodeInterface).WriteBeginNode(left, left, (XmlWriter)output);
            output.WriteAttributeString("Status", "Same");
            if (deep)
            {
                ((XmlOutputNodeInterface)nodeInterface).WriteNodeChildren(left, (XmlWriter)output);
            }
            output.WriteEndElement();
        }
		protected override void WriteNodeChange(NodeInterface leftInterface, object left, NodeInterface rightInterface, object right) {
			((XmlOutputNodeInterface)leftInterface).WriteBeginNode(left, right, (XmlWriter)output);
			output.WriteAttributeString("Status", "Changed");
				((XmlOutputNodeInterface)leftInterface).WriteBeginNode(left, left, (XmlWriter)output);
					((XmlOutputNodeInterface)leftInterface).WriteNodeChildren(left, (XmlWriter)output);
				output.WriteEndElement();
				((XmlOutputNodeInterface)rightInterface).WriteBeginNode(right, right, (XmlWriter)output);
					((XmlOutputNodeInterface)rightInterface).WriteNodeChildren(right, (XmlWriter)output);
				output.WriteEndElement();
			output.WriteEndElement();
		}
		public override void AddInterface(Type type, NodeInterface nodeInterface) {
			if (!(nodeInterface is XmlOutputNodeInterface))
				throw new ArgumentException("Node interfaces for the XmlOutputStructuredDiff must implement XmlOutputNodeInterface.");
			base.AddInterface(type, nodeInterface);
		}
		protected override void WriteNodeSame(NodeInterface nodeInterface, object left, object right) {
			bool deep = deepOutput;
			
			if (left is XmlNode && !deepOutput && !allContext) {
				if (!contextNodes.ContainsKey(((XmlNode)left).Name)) {
					return;
				} else {
					deep = true;
				}
			}

			((XmlOutputNodeInterface)nodeInterface).WriteBeginNode(left, left, (XmlWriter)output);
			output.WriteAttributeString("Status", "Same");
			if (deep)
				((XmlOutputNodeInterface)nodeInterface).WriteNodeChildren(left, (XmlWriter)output);
			output.WriteEndElement();
		}
		protected abstract void WriteNodeSame(NodeInterface nodeInterface, object left, object right);
		protected abstract void WriteNodeChange(NodeInterface leftInterface, object left, NodeInterface rightInterface, object right);
        private float CompareLists(IList left, IList right, float threshold, bool output)
        {
            // Given two lists, find the elements in the list that correspond.
            // Two elements correspond if their 'difference metric' is less than
            // or equal to threshold.  For the hunks of correspondent items,
            // recursively descend into items not truly equal.  For hunks of
            // irreconsiliable material, raise the threshold to the next useful
            // level and rescan the items.

            if (left.Count == 0 && right.Count == 0)
            {
                return(0);
            }

            NodeComparerWrapper comparer = new NodeComparerWrapper(threshold, this);

            Diff diff = new Diff(left, right, comparer, comparer);

            int nitems = 0, ndiffs = 0;

            foreach (Diff.Hunk hunk in diff)
            {
                if (hunk.Same || (hunk.Left.Count == 1 && hunk.Right.Count == 1))
                {
                    // This comprises a block of correspondent items who
                    // differ by no more than the threshold value.

                    nitems += hunk.Left.Count;

                    bool inSameRegion = false;

                    for (int i = 0; i < hunk.Left.Count; i++)
                    {
                        object oleft  = hunk.Left[i];
                        object oright = hunk.Right[i];

                        NodeInterface ileft  = GetInterface(oleft);
                        NodeInterface iright = GetInterface(oright);

                        IList cleft = null, cright = null;
                        cleft  = ileft.GetChildren(oleft);
                        cright = iright.GetChildren(oright);

                        float comp = 0;
                        if (ileft == iright)
                        {
                            comp = ileft.Compare(oleft, oright, this);
                        }

                        // If the nodes are equal, emit one node.
                        if (ileft == iright && comp == 0)
                        {
                            if (output)
                            {
                                if (!inSameRegion)
                                {
                                    WritePushSame(); inSameRegion = true;
                                }
                                WriteNodeSame(ileft, oleft, oright);
                            }

                            // Recurse into the lists of each node.
                        }
                        else if (ileft == iright && cleft != null && cright != null && cleft.Count > 0 && cright.Count > 0 && comp <= 1.0)
                        {
                            if (output && inSameRegion)
                            {
                                WritePopSame(); inSameRegion = false;
                            }
                            if (output)
                            {
                                WritePushNode(ileft, oleft, oright);
                            }
                            float d = CompareLists(cleft, cright, 0, output);
                            d *= hunk.Left.Count;
                            if (d < 1)
                            {
                                d = 1;
                            }
                            ndiffs += (int)d;
                            if (output)
                            {
                                WritePopNode();
                            }

                            // The nodes are not equal, so emit removed and added nodes.
                        }
                        else
                        {
                            if (output && inSameRegion)
                            {
                                WritePopSame(); inSameRegion = false;
                            }
                            if (output)
                            {
                                WriteNodeChange(ileft, oleft, iright, oright);
                            }
                            ndiffs += hunk.Left.Count;
                        }
                    }

                    if (output && inSameRegion)
                    {
                        WritePopSame();
                    }
                }
                else
                {
                    int ct = hunk.Left.Count + hunk.Right.Count;
                    nitems += ct;
                    ndiffs += ct;

                    if (output)
                    {
                        bool noRecurse = comparer.minimumDifference >= 1;
                        if (hunk.Right.Count == 0 || (hunk.Left.Count > 0 && noRecurse))
                        {
                            WriteNodesRemoved(hunk.Left);
                        }
                        if (hunk.Left.Count == 0 || (hunk.Right.Count > 0 && noRecurse))
                        {
                            WriteNodesAdded(hunk.Right);
                        }
                        if (hunk.Right.Count != 0 && hunk.Left.Count != 0 && !noRecurse)
                        {
                            CompareLists(hunk.Left, hunk.Right, comparer.minimumDifference, output);
                        }
                    }
                }
            }

            return((float)ndiffs / (float)nitems);
        }
 public virtual void AddInterface(Type type, NodeInterface nodeInterface)
 {
     nodeInterfaces[type] = nodeInterface;
 }
 protected override void WritePushNode(NodeInterface nodeInterface, object left, object right)
 {
     ((XmlOutputNodeInterface)nodeInterface).WriteBeginNode(left, right, output);
 }
			protected override void WriteNodeChange(NodeInterface leftInterface, object left, NodeInterface rightInterface, object right) {
				AddHunk(((Node)left).count, ((Node)right).count, false);
			}
		protected override void WritePushNode(NodeInterface nodeInterface, object left, object right) {
			((XmlOutputNodeInterface)nodeInterface).WriteBeginNode(left, right, output);
		}
			protected override void WriteNodeSame(NodeInterface nodeInterface, object left, object right) {
				AddHunk(((Node)left).count, ((Node)right).count, true);
			}
示例#17
0
 protected override void WriteNodeChange(NodeInterface leftInterface, object left, NodeInterface rightInterface, object right)
 {
     AddHunk(((Node)left).count, ((Node)right).count, false);
 }
 protected abstract void WriteNodeChange(NodeInterface leftInterface, object left, NodeInterface rightInterface, object right);
 protected abstract void WriteNodeSame(NodeInterface nodeInterface, object left, object right);
示例#20
0
 protected override void WritePushNode(NodeInterface nodeInterface, object left, object right)
 {
 }
示例#21
0
 protected override void WriteNodeSame(NodeInterface nodeInterface, object left, object right)
 {
     AddHunk(((Node)left).count, ((Node)right).count, true);
 }
		public virtual void AddInterface(Type type, NodeInterface nodeInterface) {
			nodeInterfaces[type] = nodeInterface;
		}
			protected override void WritePushNode(NodeInterface nodeInterface, object left, object right) {
			}