private static void SetupElementStrategies(XmlMerger merger)
        {
            merger.MergeStrategies.ElementToMergeStrategyKeyMapper = new BloomElementToStrategyKeyMapper();

            merger.MergeStrategies.SetStrategy("html", ElementStrategy.CreateSingletonElement());
            merger.MergeStrategies.SetStrategy("head", ElementStrategy.CreateSingletonElement());
            merger.MergeStrategies.SetStrategy("body", ElementStrategy.CreateSingletonElement());

            merger.MergeStrategies.SetStrategy("DataDiv", new ElementStrategy(true)
            {
                IsAtomic           = false,
                OrderIsRelevant    = false,
                MergePartnerFinder = new FindByKeyAttribute("id"),                 //yes, it's a singleton of sorts, but by the id, not the tag
            });

            merger.MergeStrategies.SetStrategy("BookDataItem", new ElementStrategy(true)
            {
                IsAtomic           = true,
                OrderIsRelevant    = false,
                MergePartnerFinder = new FindByMultipleKeyAttributes(new List <string>(new string[] { "data-book", "lang" }))
            });

            merger.MergeStrategies.SetStrategy("PageDiv", new ElementStrategy(true)
            {
                IsAtomic           = true,                                                                                               //we're not trying to merge inside pages
                MergePartnerFinder = new FindByKeyAttribute("id"),
            });
        }
        /// <summary>
        /// Do a 3-file merge, placing the result over the "ours" file and returning an error status
        /// </summary>
        /// <remarks>Implementations can exit with an exception, which the caller will catch and deal with.
        /// The must not have any UI, no interaction with the user.</remarks>
        public void Do3WayMerge(MergeOrder mergeOrder)
        {
            Guard.AgainstNull(mergeOrder, "mergeOrder");

            if (mergeOrder == null)
            {
                throw new ArgumentNullException("mergeOrder");
            }

            var merger = new XmlMerger(mergeOrder.MergeSituation);

            SetupElementStrategies(merger);

            merger.EventListener = mergeOrder.EventListener;

            using (var oursXml = new HtmlFileForMerging(mergeOrder.pathToOurs))
                using (var theirsXml = new HtmlFileForMerging(mergeOrder.pathToTheirs))
                    using (var ancestorXml = new HtmlFileForMerging(mergeOrder.pathToCommonAncestor))
                    {
                        var result = merger.MergeFiles(oursXml.GetPathToXHtml(), theirsXml.GetPathToXHtml(), ancestorXml.GetPathToXHtml());

                        CarefullyWriteOutResultingXml(oursXml, result);

                        //now convert back to html
                        oursXml.SaveHtml();
                    }
        }
Ejemplo n.º 3
0
 protected override void AddMergeStrategies(XmlMerger m)
 {
     m.MergeStrategies.ElementStrategies.Add("a", ElementStrategy.CreateForKeyedElementInList("key"));
     m.MergeStrategies.ElementStrategies.Add("b", ElementStrategy.CreateForKeyedElementInList("key"));
     m.MergeStrategies.ElementStrategies.Add("c", ElementStrategy.CreateForKeyedElementInList("key"));
     m.MergeStrategies.ElementStrategies.Add("d", ElementStrategy.CreateForKeyedElementInList("key"));
 }
Ejemplo n.º 4
0
        public static string DoMerge(
            MergeStrategies mergeStrategies,
            MergeSituation mergeSituation,
            string ancestorXml, string ourXml, string theirXml,
            IEnumerable <string> xpathQueriesThatMatchExactlyOneNode, IEnumerable <string> xpathQueriesThatReturnNull,
            int expectedConflictCount, List <Type> expectedConflictTypes,
            int expectedChangesCount, List <Type> expectedChangeTypes)
        {
            var doc          = new XmlDocument();
            var ourNode      = XmlUtilities.GetDocumentNodeFromRawXml(ourXml, doc);
            var theirNode    = XmlUtilities.GetDocumentNodeFromRawXml(theirXml, doc);
            var ancestorNode = XmlUtilities.GetDocumentNodeFromRawXml(ancestorXml, doc);

            var eventListener = new ListenerForUnitTests();
            var merger        = new XmlMerger(mergeSituation)
            {
                MergeStrategies = mergeStrategies
            };
            var retval = merger.Merge(eventListener, ourNode, theirNode, ancestorNode).OuterXml;

            Assert.AreSame(eventListener, merger.EventListener);             // Make sure it never changes it, while we aren't looking, since at least one Merge method does that very thing.

            CheckMergeResults(retval, eventListener,
                              xpathQueriesThatMatchExactlyOneNode, xpathQueriesThatReturnNull,
                              expectedConflictCount, expectedConflictTypes,
                              expectedChangesCount, expectedChangeTypes);

            return(retval);
        }
        /// <summary>
        /// Do a 3-file merge, placing the result over the "ours" file and returning an error status
        /// </summary>
        /// <remarks>Implementations can exit with an exception, which the caller will catch and deal with.
        /// The must not have any UI, no interaction with the user.</remarks>
        public void Do3WayMerge(MergeOrder mergeOrder)
        {
            if (mergeOrder == null)
            {
                throw new ArgumentNullException("mergeOrder");
            }

            bool addedCollationAttr;

            PreMergeFile(mergeOrder, out addedCollationAttr);

            var merger = new XmlMerger(mergeOrder.MergeSituation);

            SetupElementStrategies(merger);

            merger.EventListener = mergeOrder.EventListener;
            XmlMergeService.RemoveAmbiguousChildNodes = true;
            var result = merger.MergeFiles(mergeOrder.pathToOurs, mergeOrder.pathToTheirs, mergeOrder.pathToCommonAncestor);

            using (var writer = XmlWriter.Create(mergeOrder.pathToOurs, CanonicalXmlSettings.CreateXmlWriterSettings()))
            {
                var readerSettings = CanonicalXmlSettings.CreateXmlReaderSettings(ConformanceLevel.Auto);
                readerSettings.XmlResolver = null;
                readerSettings.ProhibitDtd = false;
                using (var nodeReader = XmlReader.Create(new MemoryStream(Encoding.UTF8.GetBytes(result.MergedNode.OuterXml)), readerSettings))
                {
                    writer.WriteNode(nodeReader, false);
                }
            }
        }
Ejemplo n.º 6
0
        public override void Run()
        {
            this.backupConfigGuid = this.BackupRepository.StoreFile((string)configuration.file);

            if (this.IsXml((string)configuration.file))
            {
                XmlDocument target = new XmlDocument();
                target.Load((string)configuration.file);

                XmlDocument source = new XmlDocument();
                source.LoadXml((string)configuration.content);

                XmlMerger xmlMerger = new XmlMerger(target, new Dictionary <string, object>());
                xmlMerger.ApplyChanges(source);

                target.Save((string)configuration.file);
            }
            else
            {
                JObject target = JObject.Parse(File.ReadAllText((string)this.configuration.file));
                JObject source = JObject.Parse((string)configuration.content);

                JsonMergeSettings jsonMergeSettings = new JsonMergeSettings
                {
                    MergeArrayHandling = MergeArrayHandling.Replace
                };

                target.Merge(source, jsonMergeSettings);

                File.WriteAllText((string)configuration.file, target.ToString());
            }
        }
        public void Run_WeAddedElement_ListenerGetsAdditionReport()
        {
            string ours     = @"<a><b>new</b></a>";
            string ancestor = @"<a/>";

            XmlMerger merger = new XmlMerger(new NullMergeSituation());

            TestCompare <XmlTextAddedReport>(merger, ours, ancestor, "//a");
        }
        public void Run_WeDeletedElement_ListenerGetsDeletionEditReport()
        {
            string ancestor = @"<a><b/></a>";
            string ours     = @"<a></a>";

            XmlMerger merger = new XmlMerger(new NullMergeSituation());

            TestCompare <XmlDeletionChangeReport>(merger, ours, ancestor, "//a");
        }
        /// <summary>
        /// Produce a string that represents the 3-way merger of the given three elements.
        /// </summary>
        public ChorusNotesAnnotationMergingStrategy(MergeOrder order)
        {
            _annotationMerger = new XmlMerger(order.MergeSituation)
            {
                EventListener = order.EventListener
            };

            SetupElementStrategies();
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Produce a string that represents the 3-way merger of the given three elements.
        /// </summary>
        public LiftEntryMergingStrategy(MergeOrder mergeOrder)
        {
            _entryMerger = new XmlMerger(mergeOrder.MergeSituation)
            {
                MergeStrategies = { ElementToMergeStrategyKeyMapper = new LiftElementToMergeStrategyKeyMapper() },
                EventListener   = mergeOrder.EventListener
            };

            LiftElementStrategiesMethod.AddLiftElementStrategies(_entryMerger.MergeStrategies);
        }
        public void FixtureSetup()
        {
            _mdc = MetadataCache.TestOnlyNewCache;
            var mergeOrder = new MergeOrder(null, null, null, new NullMergeSituation())
            {
                EventListener = new ListenerForUnitTests()
            };

            _merger = FieldWorksMergeServices.CreateXmlMergerForFieldWorksData(mergeOrder, _mdc);
        }
Ejemplo n.º 12
0
        internal static XmlMerger CreateXmlMergerForFieldWorksData(MergeOrder mergeOrder, MetadataCache mdc)
        {
            var merger = new XmlMerger(mergeOrder.MergeSituation)
            {
                EventListener = mergeOrder.EventListener
            };

            BootstrapSystem(mdc, merger);
            return(merger);
        }
Ejemplo n.º 13
0
        public void Do3WayMerge(MetadataCache mdc, MergeOrder mergeOrder)
        {
            var merger = new XmlMerger(mergeOrder.MergeSituation)
            {
                EventListener = mergeOrder.EventListener
            };

            CustomLayoutMergeStrategiesMethod.AddElementStrategies(merger.MergeStrategies);
            CustomLayoutMergeService.DoMerge(mergeOrder, merger);
        }
        public void Run_WeEditedTextElementInsideSingleton_ListenerGetsTextEditReport()
        {
            string ours     = @"<a><b>new</b></a>";
            string ancestor = @"<a><b>old</b></a>";

            XmlMerger merger = new XmlMerger(new NullMergeSituation());

            merger.MergeStrategies.SetStrategy("b", ElementStrategy.CreateSingletonElement());
            TestCompare <XmlTextChangedReport>(merger, ours, ancestor, "//a");
        }
Ejemplo n.º 15
0
        public void TextElement_WeEdittedTheyDeleted_KeepAncestor()
        {
            string ancestor = @"<t>original</t>";
            string ours = @"<t>mine</t>";
            string theirs = @"<t></t>";

            XmlMerger m = new XmlMerger();
            MergeResult result = m.Merge(ours, theirs, ancestor, false);
            XmlTestHelper.AssertXPathMatchesExactlyOne(result.MergedNode, "t[text()='original']");
        }
Ejemplo n.º 16
0
        /// <summary>
        /// Constructor
        /// </summary>
        public LiftRangesMergingStrategy(MergeOrder mergeOrder)
        {
            _merger = new XmlMerger(mergeOrder.MergeSituation)
            {
                EventListener = mergeOrder.EventListener
            };

            LiftBasicElementStrategiesMethod.AddLiftBasicElementStrategies(_merger.MergeStrategies);
            LiftRangesElementStrategiesMethod.AddLiftRangeElementStrategies(_merger.MergeStrategies);
        }
        public override void TestSetup()
        {
            base.TestSetup();
            Mdc.UpgradeToVersion(MetadataCache.MaximumModelVersion);
            var mergeOrder = new MergeOrder(null, null, null, new NullMergeSituation())
            {
                EventListener = new ListenerForUnitTests()
            };

            _merger = FieldWorksMergeServices.CreateXmlMergerForFieldWorksData(mergeOrder, Mdc);
        }
Ejemplo n.º 18
0
        /// <summary>
        /// Bootstrap a merger for the new-styled (nested) files.
        /// </summary>
        /// <remarks>
        /// 1. A generic 'header' element will be handled, although it may not appear in the file.
        /// 2. All classes will be included.
        /// 3. Merge strategies for class properties (regular or custom) will have keys of "classname+propname" to make them unique, system-wide.
        /// </remarks>
        private static void BootstrapSystem(MetadataCache metadataCache, XmlMerger merger)
        {
            merger.MergeStrategies.ElementToMergeStrategyKeyMapper = new FieldWorksElementToMergeStrategyKeyMapper();

            var sharedElementStrategies = new Dictionary <string, ElementStrategy>();

            CreateSharedElementStrategies(sharedElementStrategies);

            var strategiesForMerger = merger.MergeStrategies;

            ContextGen.MergeStrategies = strategiesForMerger;

            foreach (var sharedKvp in sharedElementStrategies)
            {
                strategiesForMerger.SetStrategy(sharedKvp.Key, sharedKvp.Value);
            }

            var customPropDefnStrat = new ElementStrategy(false)
            {
                MergePartnerFinder = new FindByMultipleKeyAttributes(new List <string> {
                    SharedConstants.Name, SharedConstants.Class
                }),
                ContextDescriptorGenerator = new FieldWorksCustomPropertyContextGenerator(),
                IsAtomic         = true,
                NumberOfChildren = NumberOfChildrenAllowed.Zero
            };

            strategiesForMerger.SetStrategy(SharedConstants.CustomField, customPropDefnStrat);

            var headerStrategy = CreateSingletonElementType(false);

            headerStrategy.ContextDescriptorGenerator = ContextGen;
            strategiesForMerger.SetStrategy(SharedConstants.Header, headerStrategy);

            // There are two abstract class names used: CmAnnotation and DsChart.
            // Chorus knows how to find the matching element for these, as they use <CmAnnotation class='concreteClassname'.
            // So, add a keyed strategy for each of them.
            var keyedStrat = ElementStrategy.CreateForKeyedElement(SharedConstants.GuidStr, false);

            keyedStrat.AttributesToIgnoreForMerging.Add(SharedConstants.Class);
            keyedStrat.AttributesToIgnoreForMerging.Add(SharedConstants.GuidStr);
            strategiesForMerger.SetStrategy(SharedConstants.CmAnnotation, keyedStrat);

            keyedStrat = ElementStrategy.CreateForKeyedElement(SharedConstants.GuidStr, false);
            keyedStrat.AttributesToIgnoreForMerging.Add(SharedConstants.Class);
            keyedStrat.AttributesToIgnoreForMerging.Add(SharedConstants.GuidStr);
            strategiesForMerger.SetStrategy(SharedConstants.DsChart, keyedStrat);

            foreach (var classInfo in metadataCache.AllConcreteClasses)
            {
                MakeClassStrategy(strategiesForMerger, classInfo, ContextGen);
                AddPropertyStrategiesForClass(strategiesForMerger, classInfo);
            }
        }
Ejemplo n.º 19
0
        /// <summary>
        /// Gets the collection of element merge strategies.
        /// </summary>
        public MergeStrategies GetStrategies()
        {
            var merger = new XmlMerger(new MergeSituation(null, null, null, null, null, MergeOrder.ConflictHandlingModeChoices.WeWin));
            var def    = new ElementStrategy(true)
            {
                MergePartnerFinder = new FindByEqualityOfTree()
            };

            merger.MergeStrategies.SetStrategy("def", def);
            return(merger.MergeStrategies);
        }
        internal static void DoMerge(MergeOrder mergeOrder, XmlMerger merger)
        {
            XmlNode ours;
            XmlNode theirs;
            XmlNode common;

            DoPreMerge(mergeOrder, out ours, out theirs, out common);
            var results = merger.Merge(ours, theirs, common);

            DoPostMerge(mergeOrder.pathToOurs, results.MergedNode);
        }
Ejemplo n.º 21
0
        public void TextElement_WeEdittedTheyDeleted_KeepAncestor()
        {
            string ancestor = @"<t>original</t>";
            string ours     = @"<t>mine</t>";
            string theirs   = @"<t></t>";

            XmlMerger   m      = new XmlMerger();
            MergeResult result = m.Merge(ours, theirs, ancestor, false);

            XmlTestHelper.AssertXPathMatchesExactlyOne(result.MergedNode, "t[text()='original']");
        }
        public void Run_WeEditedTextElementInsideOneOfTWoKeyedElements_ListenerGetsTextEditReport()
        {
            // Gets report from MergeTextNodesMethod
            string ours     = @"<a><b id='foo'>new</b>   <b id='gaa'>same</b></a>";
            string ancestor = @"<a><b id='foo'>old</b>   <b id='gaa'>same</b></a>";

            XmlMerger merger = new XmlMerger(new NullMergeSituation());

            merger.MergeStrategies.SetStrategy("b", ElementStrategy.CreateForKeyedElement("id", false));
            TestCompare <XmlTextChangedReport>(merger, ours, ancestor, "//a");
        }
Ejemplo n.º 23
0
        internal static void DoMerge(MergeOrder mergeOrder, XmlMerger merger)
        {
            XmlNode ours;
            XmlNode theirs;
            XmlNode common;

            DoPreMerge(mergeOrder, out ours, out theirs, out common);
            // The document element is being returned here, so our parent isn't relevant and won't be used by the merge
            var results = merger.Merge(null, ours, theirs, common);

            DoPostMerge(mergeOrder.pathToOurs, results.MergedNode);
        }
Ejemplo n.º 24
0
        public void XmlBothDeletionChangeReport_ReportsCorrectChangeWithoutCrashing()
        {
            // Setup
            var merger = new XmlMerger(new NullMergeSituation());

            // Exercise
            var result = merger.Merge("<r></r>", "<r></r>", "<r><s><t>hello</t></s></r>");

            // Verify
            Assert.That(result.Changes.Select(x => x.GetType()), Is.EqualTo(new[] { typeof(XmlBothDeletionChangeReport) }));
            Assert.That(result.Changes[0].ToString(), Is.EqualTo("Both deleted the <s>"));
            Assert.That(result.Changes[0].ActionLabel, Is.EqualTo("Deleted"));
        }
Ejemplo n.º 25
0
 private MergeResult CheckOneWay(string ours, string theirs, string ancestor, params string[] xpaths)
 {
     XmlMerger m = new XmlMerger();
     m._mergeStrategies._elementStrategies.Add("a", ElementStrategy.CreateForKeyedElement("key"));
     m._mergeStrategies._elementStrategies.Add("b", ElementStrategy.CreateForKeyedElement("key"));
     m._mergeStrategies._elementStrategies.Add("c", ElementStrategy.CreateForKeyedElement("key"));
     MergeResult result = m.Merge(ours, theirs, ancestor, false);
     foreach (string xpath in xpaths)
     {
         XmlTestHelper.AssertXPathMatchesExactlyOne(result.MergedNode, xpath);
     }
     return result;
 }
Ejemplo n.º 26
0
        public void Run_BothDeletedNonTextNodeHasChangeReport()
        {
            const string ancestor = @"<gloss lang='a'>
									<text id='me' />
								 </gloss>"                                ;
            const string ours     = @"<gloss lang='a'>
							</gloss>"                            ;
            const string theirs   = ours;

            var merger = new XmlMerger(new NullMergeSituation());

            TestMergeWithChange <XmlBothDeletionChangeReport>(merger, ours, theirs, ancestor, "//gloss");
        }
        private static XmlMerger GetMerger(out ListenerForUnitTests listener, bool isAtomic)
        {
            var elementStrategy = new ElementStrategy(false)
            {
                IsAtomic = isAtomic
            };
            var merger = new XmlMerger(new NullMergeSituation());

            merger.MergeStrategies.SetStrategy("topatomic", elementStrategy);
            listener             = new ListenerForUnitTests();
            merger.EventListener = listener;
            return(merger);
        }
        private static XmlMerger GetMerger(MergeSituation mergeSituation, out ListenerForUnitTests listener)
        {
            var elementStrategy = new ElementStrategy(false)
            {
                IsAtomic = true
            };
            var merger = new XmlMerger(mergeSituation);

            merger.MergeStrategies.SetStrategy("topatomic", elementStrategy);
            listener             = new ListenerForUnitTests();
            merger.EventListener = listener;
            return(merger);
        }
Ejemplo n.º 29
0
        public void Run_BothMovedDifferentKeyedNodes_OrderIrrelevant_NoDuplicatesCreated()
        {
            string ours = @"<foo><gloss lang='c'/><gloss lang='b'/><gloss lang='a'/></foo>";

            string theirs   = @"<foo><gloss lang='a'/><gloss lang='c'/><gloss lang='b'/></foo>";
            string ancestor = @"<foo><gloss lang='a'/><gloss lang='b'/><gloss lang='c'/></foo>";

            XmlMerger merger = new XmlMerger(new NullMergeSituation());

            merger.MergeStrategies.SetStrategy("foo", ElementStrategy.CreateSingletonElement());
            merger.MergeStrategies.SetStrategy("gloss", ElementStrategy.CreateForKeyedElement("lang", false));

            TestMergeWithoutConflicts(merger, ours, theirs, ancestor, "//foo");
        }
        private void TestCompare <TChangeReport>(XmlMerger merger, string ours, string ancestors, string xpathToElementsToMerge)
        {
            var listener = new ListenerForUnitTests();

            merger.EventListener = listener;

            var method = new MergeChildrenMethod(GetNode(ours, xpathToElementsToMerge),
                                                 GetNode(ancestors, xpathToElementsToMerge),
                                                 merger);

            method.Run();
            listener.AssertExpectedConflictCount(0);
            listener.AssertExpectedChangesCount(1);
            Assert.AreEqual(typeof(TChangeReport), listener.Changes[0].GetType());
        }
Ejemplo n.º 31
0
        private static XmlNode DoMerge(
            string ancestorXml, string ourXml, string theirXml,
            MergeSituation mergeSituation, IMergeEventListener listener, out XmlNode ours, out XmlNode theirs)
        {
            var merger = new XmlMerger(mergeSituation)
            {
                EventListener = listener
            };
            XmlNode ancestor;
            XmlNode ourParent;

            XmlTestHelper.CreateThreeNodes(ourXml, theirXml, ancestorXml, out ours, out ourParent, out theirs, out ancestor);
            ImmutableElementMergeService.DoMerge(merger, ourParent, ref ours, theirs, ancestor);
            return(ours);
        }
Ejemplo n.º 32
0
        public void Do3WayMerge(MetadataCache mdc, MergeOrder mergeOrder)
        {
            var merger = new XmlMerger(mergeOrder.MergeSituation)
            {
                EventListener = mergeOrder.EventListener
            };
            var rootStrategy = ElementStrategy.CreateSingletonElement();

            rootStrategy.IsAtomic = true;
            merger.MergeStrategies.SetStrategy("DictionaryConfiguration", rootStrategy);
            var mergeResults = merger.MergeFiles(mergeOrder.pathToOurs, mergeOrder.pathToTheirs, mergeOrder.pathToCommonAncestor);

            // Write merged data
            File.WriteAllText(mergeOrder.pathToOurs, mergeResults.MergedNode.OuterXml, Encoding.UTF8);
        }