///<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); }
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)); } } }
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); }
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); }