Beispiel #1
0
        public XmlNode GetNodeToMerge(XmlNode nodeToMatch, XmlNode parentToSearchIn, HashSet <XmlNode> acceptableTargets)
        {
            if (parentToSearchIn == null || nodeToMatch == null)
            {
                return(null);
            }
            var keyVal = nodeToMatch.Attributes[_key];

            if (keyVal != null)
            {
                foreach (XmlNode node in parentToSearchIn.ChildNodes)
                {
                    if (!acceptableTargets.Contains(node) || !(node is XmlElement))
                    {
                        continue;
                    }
                    if (XmlUtilities.GetOptionalAttributeString(node, _key) == keyVal.Value)
                    {
                        return(node);
                    }
                }
            }

            return(_backup.GetNodeToMerge(nodeToMatch, parentToSearchIn, acceptableTargets));
        }
Beispiel #2
0
        private XmlNode FindMatchingNode(XmlNode node, XmlNode otherParent, HashSet <XmlNode> acceptableTargets)
        {
            IFindNodeToMerge finder = _merger.MergeStrategies.GetMergePartnerFinder(node);
            var result = finder.GetNodeToMerge(node, otherParent, acceptableTargets);

            // This check allows implementations where there is only one possible match to ignore acceptableTargets
            // and just give us the one match from otherParent. If we don't want it, we discard it.
            if (!acceptableTargets.Contains(result))
            {
                return(null);
            }
            return(result);
        }
Beispiel #3
0
        /// <summary>
        /// Remove from ancestorKeepers any node that does not correspond to anything (both deleted)
        /// Remove from ancestorKeepers and theirKeepers any pair that correspond to each other but not to anything in ours. Report conflict (delete/edit) if pair not identical.
        /// Remove from ancestorKeepers and ourKeepers any pair that correspond to each other and are identical, but don't correspond to anything in theirs (they deleted)
        /// Report conflict (edit/delete) on any pair that correspond in ours and ancestor, but nothing in theirs, and that are NOT identical. (but keep them...we win)
        /// </summary>
        private void DoDeletions()
        {
            // loop over a copy of the list, since we may modify ancestorKeepers.
            List <XmlNode> loopSource    = new List <XmlNode>(_childrenOfAncestorKeepers);
            var            ourChildSet   = new HashSet <XmlNode>(_ours == null ? new XmlNode[0] : _ours.ChildNodes.Cast <XmlNode>());
            var            theirChildSet = new HashSet <XmlNode>(_theirs == null ? new XmlNode[0] : _theirs.ChildNodes.Cast <XmlNode>());

            foreach (XmlNode ancestorChild in loopSource)
            {
                ElementStrategy  mergeStrategy = _merger.MergeStrategies.GetElementStrategy(ancestorChild);
                IFindNodeToMerge finder        = mergeStrategy.MergePartnerFinder;
                XmlNode          ourChild      = finder.GetNodeToMerge(ancestorChild, _ours, ourChildSet);
                XmlNode          theirChild    = finder.GetNodeToMerge(ancestorChild, _theirs, theirChildSet);

                var extantNode = ancestorChild ?? ourChild ?? theirChild;
                if (extantNode is XmlCharacterData)
                {
                    return;                     // Already done.
                }
                if (XmlUtilities.IsTextLevel(ourChild, theirChild, ancestorChild))
                {
                    new MergeTextNodesMethod(_merger, mergeStrategy, _skipInnerMergeFor,
                                             ref ourChild, _childrenOfOurKeepers,
                                             theirChild, _childrenOfTheirKeepers,
                                             ancestorChild, _childrenOfAncestorKeepers).DoDeletions();
                }
                else if (ourChild == null)
                {
                    // We deleted it.
                    if (theirChild == null)
                    {
                        // We both deleted it. Forget it ever existed.
                        // Route tested: MergeChildrenMethodTests.
                        _merger.EventListener.ChangeOccurred(new XmlBothDeletionChangeReport(_merger.MergeSituation.PathToFileInRepository, ancestorChild));
                        _childrenOfAncestorKeepers.Remove(ancestorChild);
                    }
                    else
                    {
                        if (!XmlUtilities.AreXmlElementsEqual(ancestorChild, theirChild))
                        {
                            // We deleted, they modified, report conflict.
                            if (theirChild.NodeType == XmlNodeType.Element)
                            {
                                // Route tested (XmlMergerTests).
                                _merger.ConflictOccurred(
                                    new RemovedVsEditedElementConflict(theirChild.Name, null,
                                                                       theirChild, ancestorChild,
                                                                       _merger.MergeSituation,
                                                                       _merger.MergeStrategies.GetElementStrategy(theirChild),
                                                                       _merger.MergeSituation.BetaUserId),
                                    theirChild);
                                _skipInnerMergeFor.Add(theirChild);
                            }
                            else
                            {
                                // Never used. But then, there isn't plain text in an xml file.
                                _merger.ConflictOccurred(
                                    new RemovedVsEditedTextConflict(null, theirChild,
                                                                    ancestorChild,
                                                                    _merger.MergeSituation,
                                                                    _merger.MergeSituation.BetaUserId));
                                _skipInnerMergeFor.Add(theirChild);
                            }
                            _childrenOfAncestorKeepers.Remove(ancestorChild);                            //review hatton added dec 2009, wanting whoever edited it to win (previously "we" always won)
                        }
                        else
                        {
                            //We deleted it, they didn't edit it. So just make it go away.
                            // Route tested in TextElementMergeTests, MergeChildrenMethod_DiffOnlyTests, XmlMergerTests
                            _merger.EventListener.ChangeOccurred(new XmlDeletionChangeReport(_merger.MergeSituation.PathToFileInRepository, ancestorChild, theirChild));
                            _childrenOfAncestorKeepers.Remove(ancestorChild);
                            _childrenOfTheirKeepers.Remove(theirChild);
                        }
                    }
                }
                else if (theirChild == null)
                {
                    // they deleted it (and we didn't)
                    if (XmlUtilities.AreXmlElementsEqual(ancestorChild, ourChild))
                    {
                        // We didn't touch it, allow their deletion to go forward, forget it existed.
                        // Route tested (XmlMergerTests).
                        _merger.EventListener.ChangeOccurred(new XmlDeletionChangeReport(_merger.MergeSituation.PathToFileInRepository, ancestorChild, ourChild));
                        _childrenOfAncestorKeepers.Remove(ancestorChild);
                        _childrenOfOurKeepers.Remove(ourChild);
                    }
                    else
                    {
                        // We changed it, ignore their deletion and report conflict.
                        if (ourChild.NodeType == XmlNodeType.Element)
                        {
                            // Route tested (XmlMergerTests).
                            _merger.ConflictOccurred(
                                new EditedVsRemovedElementConflict(ourChild.Name, ourChild, null, ancestorChild,
                                                                   _merger.MergeSituation, _merger.MergeStrategies.GetElementStrategy(ourChild), _merger.MergeSituation.AlphaUserId),
                                ourChild);
                            _skipInnerMergeFor.Add(ourChild);
                        }
                        else
                        {
                            // Never used. But then, there isn't plain text in an xml file.
                            _merger.ConflictOccurred(
                                new EditedVsRemovedTextConflict(ourChild, null, ancestorChild, _merger.MergeSituation, _merger.MergeSituation.AlphaUserId));
                            _skipInnerMergeFor.Add(ourChild);
                        }
                    }
                }
            }
        }