Example #1
0
        ///<summary>
        /// Given the complete parent and child xml,
        /// this method compares 'records' (main xml elements) in the parent and child data sets
        /// at a high level of difference detection.
        ///
        /// Low-level xml differences are handed to XmlUtilities.AreXmlElementsEqual for processing differences
        /// of each 'record'.
        ///</summary>
        public Dictionary <string, byte[]> ReportDifferencesToListener()
        {
            Dictionary <string, byte[]> childIndex;
            Dictionary <string, byte[]> parentIndex;

            switch (_diffingMode)
            {
            default:
                throw new InvalidEnumArgumentException("Diffing mode not recognized.");

            case DiffingMode.FromFileInRevisions:
                PrepareIndicesUsingFilesInRepositorySource(out parentIndex, out childIndex);
                break;

            case DiffingMode.FromPathnames:
                PrepareIndicesUsingPathNameSource(out parentIndex, out childIndex);
                break;

            case DiffingMode.FromMixed:
                parentIndex = _parentIndex;
                PrepareIndexUsingPathNameSource(out childIndex);
                break;
            }

            foreach (var difference in Xml2WayDiffService.ReportDifferences(
                         _parentFileInRevision, parentIndex,
                         _childFileInRevision, childIndex))
            {
                _eventListener.ChangeOccurred(difference);
            }
            return(parentIndex);
        }
Example #2
0
        public void ReportDifferencesToListener()
        {
            foreach (XmlNode node in _parentDom.SafeSelectNodes("lift/entry"))
            {
                string strId = LiftUtils.GetId(node);
                if (!_parentIdToNodeIndex.ContainsKey(strId))
                {
                    _parentIdToNodeIndex.Add(strId, node);
                }
                else
                {
                    System.Diagnostics.Debug.WriteLine(String.Format("Found ID multiple times: {0}", strId));
                }
            }

            foreach (XmlNode childNode in _childDom.SafeSelectNodes("lift/entry"))
            {
                try
                {
                    ProcessEntry(childNode);
                }
                catch (Exception error)
                {
                    EventListener.ChangeOccurred(new ErrorDeterminingChangeReport(_parentFileInRevision,
                                                                                  _childFileInRevision, null, childNode,
                                                                                  error));
                }
            }

            //now detect any removed (not just marked as deleted) elements
            foreach (XmlNode parentNode in _parentIdToNodeIndex.Values)            // _parentDom.SafeSelectNodes("lift/entry"))
            {
                try
                {
                    if (!_processedIds.Contains(LiftUtils.GetId(parentNode)))
                    {
                        EventListener.ChangeOccurred(new XmlDeletionChangeReport(_parentFileInRevision, parentNode,
                                                                                 null));
                    }
                }
                catch (Exception error)
                {
                    EventListener.ChangeOccurred(new ErrorDeterminingChangeReport(_parentFileInRevision,
                                                                                  _childFileInRevision,
                                                                                  parentNode,
                                                                                  null,
                                                                                  error));
                }
            }
        }
Example #3
0
        private static void ProcessEntry(XmlWriter writer, IMergeEventListener eventListener, IMergeStrategy mergingStrategy,
			XmlNode ancestorDom, HashSet<string> processedIds,
			XmlNode sourceEntry, string sourceLabel, string sourcePath,
			IDictionary<string, XmlNode> otherIdNodeIndex, string otherLabel, string otherPath)
        {
            var id = LiftUtils.GetId(sourceEntry);
            if (processedIds.Contains(id))
                return; // Already handled the id.
            XmlNode otherEntry;
            var commonEntry = FindEntry(ancestorDom, id);
            if (!otherIdNodeIndex.TryGetValue(id, out otherEntry))
            {
                // It is in source, but not in target, so it clearly has been deleted by target (new style deletion).
                if (LiftUtils.GetIsMarkedAsDeleted(sourceEntry))
                {
                    if (!LiftUtils.GetIsMarkedAsDeleted(commonEntry))
                    {
                        // source and target both deleted but in different ways, so make deletion change report.
                        // There is no need to write anything.
                        eventListener.ChangeOccurred(new XmlDeletionChangeReport(sourcePath, commonEntry, sourceEntry));
                    }
                    //else
                    //{
                    //    // Make it go away without fanfare by doing nothing to writer, since target actually removed the dead entry.
                    //}
                    processedIds.Add(id);
                    return;
                }

                if (commonEntry == null)
                {
                    // source added it
                    eventListener.ChangeOccurred(new XmlAdditionChangeReport(sourcePath, sourceEntry));
                    writer.WriteNode(sourceEntry.CreateNavigator(), false);
                }
                else
                {
                    if (AreTheSame(sourceEntry, commonEntry))
                    {
                        // target's deletion wins with a plain vanilla deletion report.
                        eventListener.ChangeOccurred(new XmlDeletionChangeReport(sourcePath, commonEntry, otherEntry));
                    }
                    else
                    {
                        // source wins over target's new style deletion on the least loss priciple.
                        // Add an edit vs remove conflict report.
                        eventListener.ConflictOccurred(new RemovedVsEditedElementConflict("entry", sourceEntry, otherEntry, commonEntry, new MergeSituation(sourcePath, sourceLabel, "", otherLabel, "", MergeOrder.ConflictHandlingModeChoices.WeWin), null, sourceLabel));
                        writer.WriteNode(sourceEntry.CreateNavigator(), false);
                    }
                    processedIds.Add(id);
                    return;
                }
            }
            else if (AreTheSame(sourceEntry, otherEntry))
            {
                //unchanged or both made same change
                writer.WriteNode(sourceEntry.CreateNavigator(), false);
            }
            else if (LiftUtils.GetIsMarkedAsDeleted(otherEntry))
            {
                // source edited, target deleted (old style deletion using dateDeleted attr).
                eventListener.ConflictOccurred(new RemovedVsEditedElementConflict("entry", sourceEntry, otherEntry, commonEntry, new MergeSituation(sourcePath, sourceLabel, "", otherLabel, "", MergeOrder.ConflictHandlingModeChoices.WeWin), null, sourceLabel));
            }
            else if (LiftUtils.GetIsMarkedAsDeleted(sourceEntry))
            {
                // source deleted (old style), but target edited.
                // target wins with the least loss principle.
                // But generate a conflict report.
                eventListener.ConflictOccurred(new RemovedVsEditedElementConflict("entry", otherEntry, sourceEntry, commonEntry, new MergeSituation(otherPath, otherLabel, "", sourceLabel, "", MergeOrder.ConflictHandlingModeChoices.TheyWin), null, sourceLabel));
                writer.WriteNode(otherEntry.CreateNavigator(), false);
            }
            else
            {
                // One or both of them edited it, so merge the hard way.
                using (var reader = XmlReader.Create(new StringReader(
                    mergingStrategy.MakeMergedEntry(eventListener, sourceEntry, otherEntry, commonEntry)
                )))
                {
                    writer.WriteNode(reader, false);
                }
            }
            processedIds.Add(id);
        }
Example #4
0
        private static void ProcessEntry(XmlWriter writer, IMergeEventListener eventListener, IMergeStrategy mergingStrategy,
                                         XmlNode ancestorDom, HashSet <string> processedIds,
                                         XmlNode sourceEntry, string sourceLabel, string sourcePath,
                                         IDictionary <string, XmlNode> otherIdNodeIndex, string otherLabel, string otherPath)
        {
            var id = LiftUtils.GetId(sourceEntry);

            if (processedIds.Contains(id))
            {
                return;                 // Already handled the id.
            }
            XmlNode otherEntry;
            var     commonEntry = FindEntry(ancestorDom, id);

            if (!otherIdNodeIndex.TryGetValue(id, out otherEntry))
            {
                // It is in source, but not in target, so it clearly has been deleted by target (new style deletion).
                if (LiftUtils.GetIsMarkedAsDeleted(sourceEntry))
                {
                    if (!LiftUtils.GetIsMarkedAsDeleted(commonEntry))
                    {
                        // source and target both deleted but in different ways, so make deletion change report.
                        // There is no need to write anything.
                        eventListener.ChangeOccurred(new XmlDeletionChangeReport(sourcePath, commonEntry, sourceEntry));
                    }
                    //else
                    //{
                    //    // Make it go away without fanfare by doing nothing to writer, since target actually removed the dead entry.
                    //}
                    processedIds.Add(id);
                    return;
                }

                if (commonEntry == null)
                {
                    // source added it
                    eventListener.ChangeOccurred(new XmlAdditionChangeReport(sourcePath, sourceEntry));
                    writer.WriteNode(sourceEntry.CreateNavigator(), false);
                }
                else
                {
                    if (AreTheSame(sourceEntry, commonEntry))
                    {
                        // target's deletion wins with a plain vanilla deletion report.
                        eventListener.ChangeOccurred(new XmlDeletionChangeReport(sourcePath, commonEntry, otherEntry));
                    }
                    else
                    {
                        // source wins over target's new style deletion on the least loss priciple.
                        // Add an edit vs remove conflict report.
                        eventListener.ConflictOccurred(new RemovedVsEditedElementConflict("entry", sourceEntry, otherEntry, commonEntry, new MergeSituation(sourcePath, sourceLabel, "", otherLabel, "", MergeOrder.ConflictHandlingModeChoices.WeWin), null, sourceLabel));
                        writer.WriteNode(sourceEntry.CreateNavigator(), false);
                    }
                    processedIds.Add(id);
                    return;
                }
            }
            else if (AreTheSame(sourceEntry, otherEntry))
            {
                //unchanged or both made same change
                writer.WriteNode(sourceEntry.CreateNavigator(), false);
            }
            else if (LiftUtils.GetIsMarkedAsDeleted(otherEntry))
            {
                // source edited, target deleted (old style deletion using dateDeleted attr).
                eventListener.ConflictOccurred(new RemovedVsEditedElementConflict("entry", sourceEntry, otherEntry, commonEntry, new MergeSituation(sourcePath, sourceLabel, "", otherLabel, "", MergeOrder.ConflictHandlingModeChoices.WeWin), null, sourceLabel));
            }
            else if (LiftUtils.GetIsMarkedAsDeleted(sourceEntry))
            {
                // source deleted (old style), but target edited.
                // target wins with the least loss principle.
                // But generate a conflict report.
                eventListener.ConflictOccurred(new RemovedVsEditedElementConflict("entry", otherEntry, sourceEntry, commonEntry, new MergeSituation(otherPath, otherLabel, "", sourceLabel, "", MergeOrder.ConflictHandlingModeChoices.TheyWin), null, sourceLabel));
                writer.WriteNode(otherEntry.CreateNavigator(), false);
            }
            else
            {
                // One or both of them edited it, so merge the hard way.
                using (var reader = XmlReader.Create(new StringReader(
                                                         mergingStrategy.MakeMergedEntry(eventListener, sourceEntry, otherEntry, commonEntry)
                                                         )))
                {
                    writer.WriteNode(reader, false);
                }
            }
            processedIds.Add(id);
        }