/// <summary> /// Add conflict. If RecordContextInConflict fails to set a context, and nodeToFindGeneratorFrom is non-null, /// attempt to add a context based on the argument. /// </summary> public static void AddConflictToListener(IMergeEventListener listener, IConflict conflict, XmlNode oursContext, XmlNode theirsContext, XmlNode ancestorContext, IGenerateHtmlContext htmlContextGenerator, XmlMerger merger, XmlNode nodeToFindGeneratorFrom) { // NB: All these steps are crucially ordered. listener.RecordContextInConflict(conflict); if ((conflict.Context == null || conflict.Context is NullContextDescriptor) && nodeToFindGeneratorFrom != null) { // We are too far up the stack for the listener to have been told a context. // Make one out of the current node. conflict.Context = merger.GetContext(nodeToFindGeneratorFrom); } conflict.MakeHtmlDetails(oursContext, theirsContext, ancestorContext, htmlContextGenerator); listener.ConflictOccurred(conflict); }
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); }