Esempio n. 1
0
        public NodeMergeResult Merge(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(ref ours, theirs, ancestor);
            result.MergedNode = ours;

            return result;
        }
        private static void CarefullyWriteOutResultingXml(HtmlFileForMerging oursXml, NodeMergeResult result)
        {
            //REVIEW: it's not clear whether we need all this fancy xml cannonicalization, when we're going to run
            //it through html tidy to make html anyhow. This is just from the code we copied from.
            //Note it also is doing something careful with unicode.

            using (var writer = XmlWriter.Create(oursXml.GetPathToXHtml(), CanonicalXmlSettings.CreateXmlWriterSettings()))
            {
                var nameSpaceManager = new XmlNamespaceManager(new NameTable());
                //nameSpaceManager.AddNamespace("palaso", "urn://palaso.org/ldmlExtensions/v1");

                var readerSettings = new XmlReaderSettings
                                        {
                                            NameTable = nameSpaceManager.NameTable,
                                            IgnoreWhitespace = true,
                                            ConformanceLevel = ConformanceLevel.Auto,
                                            ValidationType = ValidationType.None,
                                            XmlResolver = null,
                                            CloseInput = true,
                                            DtdProcessing = DtdProcessing.Prohibit,
                                        };
                using (
                    var nodeReader = XmlReader.Create(new MemoryStream(Encoding.UTF8.GetBytes(result.MergedNode.OuterXml)),
                                                      readerSettings))
                {
                    writer.WriteNode(nodeReader, false);
                }
            }
        }
Esempio n. 3
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);
        }