Example #1
0
        public NodeMergeResult Merge(XmlNode ourParent, XmlNode ours, XmlNode theirs, XmlNode ancestor)
        {
            SendMergeHeartbeat();
            if (ours == null && theirs == null && ancestor == null)
            {
                throw new InvalidOperationException("At least one node has to exist.");
            }

            var result   = new NodeMergeResult();
            var listener = EventListener as DispatchingMergeEventListener;

            if (listener == null)
            {
                var dispatcher = new DispatchingMergeEventListener();
                dispatcher.AddEventListener(result);
                if (EventListener != null)
                {
                    dispatcher.AddEventListener(EventListener);
                }
                EventListener = dispatcher;
            }
            else
            {
                listener.AddEventListener(result);
            }

            if (XmlMergeService.RemoveAmbiguousChildNodes)
            {
                // Remove any duplicate child nodes in all three.
                XmlMergeService.RemoveAmbiguousChildren(EventListener, MergeStrategies, ours);
                XmlMergeService.RemoveAmbiguousChildren(EventListener, MergeStrategies, theirs);
                XmlMergeService.RemoveAmbiguousChildren(EventListener, MergeStrategies, ancestor);
            }

            if (ancestor == null)
            {
                if (ours == null)
                {
                    // tested
                    EventListener.ChangeOccurred(new XmlAdditionChangeReport(MergeSituation.PathToFileInRepository, theirs));
                    result.MergedNode = theirs;
                }
                else if (theirs == null)
                {
                    // tested
                    EventListener.ChangeOccurred(new XmlAdditionChangeReport(MergeSituation.PathToFileInRepository, ours));
                    result.MergedNode = ours;
                }
                else
                {
                    // Both added.
                    if (XmlUtilities.AreXmlElementsEqual(ours, theirs))
                    {
                        // Same thing. (tested)
                        EventListener.ChangeOccurred(new XmlBothAddedSameChangeReport(MergeSituation.PathToFileInRepository, ours));
                        result.MergedNode = ours;
                    }
                    else
                    {
                        // But, not the same thing.
                        if (MergeSituation.ConflictHandlingMode == MergeOrder.ConflictHandlingModeChoices.WeWin)
                        {
                            // tested
                            ConflictOccurred(new BothAddedMainElementButWithDifferentContentConflict(ours.Name, ours, theirs, MergeSituation, MergeStrategies.GetElementStrategy(ours), MergeSituation.AlphaUserId));
                            result.MergedNode = ours;
                        }
                        else
                        {
                            // tested
                            ConflictOccurred(new BothAddedMainElementButWithDifferentContentConflict(theirs.Name, theirs, ours, MergeSituation, MergeStrategies.GetElementStrategy(ours), MergeSituation.BetaUserId));
                            result.MergedNode = theirs;
                        }
                    }
                }
                return(result);
            }

            // ancestor exists
            if (ours == null && theirs == null)
            {
                // tested
                EventListener.ChangeOccurred(new XmlBothDeletionChangeReport(MergeSituation.PathToFileInRepository, ancestor));
                result.MergedNode = null;
                return(result);
            }
            if (ours == null)
            {
                if (XmlUtilities.AreXmlElementsEqual(ancestor, theirs))
                {
                    // tested
                    EventListener.ChangeOccurred(new XmlDeletionChangeReport(MergeSituation.PathToFileInRepository, ancestor, theirs));
                    result.MergedNode = null;
                }
                else
                {
                    // tested
                    ConflictOccurred(new RemovedVsEditedElementConflict(ancestor.Name, null, theirs, ancestor, MergeSituation, MergeStrategies.GetElementStrategy(ancestor), MergeSituation.BetaUserId));
                    result.MergedNode = theirs;
                }
                return(result);
            }
            if (theirs == null)
            {
                if (XmlUtilities.AreXmlElementsEqual(ancestor, ours))
                {
                    // tested
                    EventListener.ChangeOccurred(new XmlDeletionChangeReport(MergeSituation.PathToFileInRepository, ancestor, ours));
                    result.MergedNode = null;
                }
                else
                {
                    // tested
                    ConflictOccurred(new EditedVsRemovedElementConflict(ancestor.Name, ours, null, ancestor, MergeSituation, MergeStrategies.GetElementStrategy(ancestor), MergeSituation.AlphaUserId));
                    result.MergedNode = ours;
                }
                return(result);
            }

            // All three nodes exist.
            MergeInner(ourParent, ref ours, theirs, ancestor);
            result.MergedNode = ours;

            return(result);
        }