Esempio n. 1
0
        /// <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);
        }
Esempio n. 2
0
        internal void WarningOccurred(IConflict warning)
        {
            if (_htmlContextGenerator == null)
            {
                _htmlContextGenerator = new SimpleHtmlGenerator();
            }

            XmlMergeService.AddWarningToListener(
                EventListener,
                warning,
                _oursContext,
                _theirsContext,
                _ancestorContext,
                _htmlContextGenerator);
        }
Esempio n. 3
0
        internal void ConflictOccurred(IConflict conflict)
        {
            if (_htmlContextGenerator == null)
            {
                _htmlContextGenerator = new SimpleHtmlGenerator();
            }

            XmlMergeService.AddConflictToListener(
                EventListener,
                conflict,
                _oursContext,
                _theirsContext,
                _ancestorContext,
                _htmlContextGenerator);
        }
Esempio n. 4
0
        internal void ConflictOccurred(IConflict conflict, XmlNode nodeToFindGeneratorFrom)
        {
            var contextDescriptorGenerator = GetContextDescriptorGenerator(nodeToFindGeneratorFrom);

            _htmlContextGenerator = (contextDescriptorGenerator as IGenerateHtmlContext) ?? new SimpleHtmlGenerator();

            XmlMergeService.AddConflictToListener(
                EventListener,
                conflict,
                _oursContext,
                _theirsContext,
                _ancestorContext,
                _htmlContextGenerator,
                this,
                nodeToFindGeneratorFrom);
        }
 public void MakeHtmlDetails(XmlNode oursContext, XmlNode theirsContext, XmlNode ancestorContext, IGenerateHtmlContext htmlMaker)
 {
 }
 public void MakeHtmlDetails(XmlNode oursContext, XmlNode theirsContext, XmlNode ancestorContext, IGenerateHtmlContext htmlMaker)
 {
 }
Esempio n. 7
0
        /// <summary>
        /// Add warning.
        /// </summary>
        public static void AddWarningToListener(IMergeEventListener listener, IConflict warning, XmlNode oursContext,
												XmlNode theirsContext, XmlNode ancestorContext,
												IGenerateHtmlContext htmlContextGenerator)
        {
            // NB: All three of these are crucially ordered.
            listener.RecordContextInConflict(warning);
            warning.MakeHtmlDetails(oursContext, theirsContext, ancestorContext, htmlContextGenerator);
            listener.WarningOccurred(warning);
        }
Esempio n. 8
0
        /// <summary>
        /// Add conflict.
        /// </summary>
        public static void AddConflictToListener(IMergeEventListener listener, IConflict conflict, XmlNode oursContext,
												 XmlNode theirsContext, XmlNode ancestorContext,
												 IGenerateHtmlContext htmlContextGenerator)
        {
            AddConflictToListener(listener, conflict, oursContext, theirsContext, ancestorContext, htmlContextGenerator, null, null);
        }
Esempio n. 9
0
        internal void WarningOccurred(IConflict warning)
        {
            if (_htmlContextGenerator == null)
                _htmlContextGenerator = new SimpleHtmlGenerator();

            XmlMergeService.AddWarningToListener(
                EventListener,
                warning,
                _oursContext,
                _theirsContext,
                _ancestorContext,
                _htmlContextGenerator);
        }
Esempio n. 10
0
        /// <summary>
        /// This method does the actual work for the various public entry points of XmlMerge
        /// and from the various Method-type classes, as it processes child nodes, if any.
        /// </summary>
        internal void MergeInner(ref XmlNode ours, XmlNode theirs, XmlNode ancestor)
        {
            SendMergeHeartbeat();
            _oursContext = ours;
            _theirsContext = theirs;
            _ancestorContext = ancestor;

            var elementStrat = MergeStrategies.GetElementStrategy(ours ?? theirs ?? ancestor);

            // Step 0: Do anything special the strategy wants to do before regular merging. This may modify the nodes.
            // For instance clinets may want to ensure 'our' and 'their' have the latest date stamp available.
            elementStrat.Premerger.Premerge(EventListener, ref ours, theirs, ancestor);

            // Step 0.1: Set up a context, if available.
            // Listeners are set to use NullContextDescriptor as the default context,
            var contextDescriptorGenerator = elementStrat.ContextDescriptorGenerator; // May be null, which is fine in code, below, that uses it.
            //review: question: does this not get called at levels below the entry?
            //this would seem to fail at, say, a sense. I'm confused. (JH 30june09)
            var descriptor = GetContextDescriptor(ours, contextDescriptorGenerator);
            EventListener.EnteringContext(descriptor); // TODO: If the context is ever redone as a stack, then this call with push the context onto the stack.
            _htmlContextGenerator = (contextDescriptorGenerator as IGenerateHtmlContext) ?? new SimpleHtmlGenerator();

            // Step 1: If the current set of nodes are immutable,
            // then make sure no changes took place (among a few other things).
            if (elementStrat.IsImmutable)
            {
                ImmutableElementMergeService.DoMerge(this, ref ours, theirs, ancestor);
                return; // Don't go any further, since it is immutable.
            }

            // Step 2: If the current set of elements is 'atomic'
            // (only one user can make changes to the node, or anything it contains),
            // then make sure only set of changes have been made.
            if (elementStrat.IsAtomic)
            {
                if (elementStrat.AllowAtomicTextMerge && XmlUtilities.IsTextLevel(ours, theirs, ancestor))
                {
                    DoTextMerge(ref ours, theirs, ancestor, elementStrat);
                    return;
                }
                MergeAtomicElementService.Run(this, ref ours, theirs, ancestor);
                return;
            }

            // Step 3: Go ahead and merge the attributes, as needed.
            MergeXmlAttributesService.MergeAttributes(this, ref ours, theirs, ancestor);

            // Step 4: Hmm, trouble is, a node might be required to have one or more child nodes.
            // I suppose a real validator would have picked up on that, and not allowed
            // the first commit, so we wouldn't then be doing a merge operation.
            // So, not to worry here, if the validator doesn't care enough to prevent the first commit.
            // It could be possible for the elements to have no children, in which case, there is nothing more to merge, so just return.
            if (ours != null && !ours.HasChildNodes && theirs != null && !theirs.HasChildNodes && ancestor != null && !ancestor.HasChildNodes)
                return;

            // Step 5: Do some kind of merge on the child node.
            if (XmlUtilities.IsTextLevel(ours, theirs, ancestor))
            {
                // Step 5A: Merge the text element.
                DoTextMerge(ref ours, theirs, ancestor, elementStrat);
            }
            else
            {
                switch (elementStrat.NumberOfChildren)
                {
                    case NumberOfChildrenAllowed.Zero:
                    case NumberOfChildrenAllowed.ZeroOrOne:
                        // Step 5B: Merge the "special needs" nodes.
                        MergeLimitedChildrenService.Run(this, elementStrat, ref ours, theirs, ancestor);
                        break;
                    case NumberOfChildrenAllowed.ZeroOrMore:
                        // Step 5B:
                        // Q: is this a level of the xml file that would consitute the minimal unit conflict-understanding
                        // from a user perspecitve?
                        // e.g., in a dictionary, this is the lexical entry.  In a text, it might be  a paragraph.
                        // A (RandyR): Definitely it may not be such a level of node.
                        new MergeChildrenMethod(ours, theirs, ancestor, this).Run();
                        break;
                }
            }

            // At some point, it may be necessary here to restore the pre-existing values of
            // _oursContext, _theirsContext, _ancestorContext, and _htmlContextGenerator.
            // and somehow restore the EventListener's Context.
            // Currently however no client generates further conflicts after calling MergeChildren.

            // Step 6: TODO: If the context is ever redone as a stack, then pop the stack here to return to the outer context via some new LeavingContext method on EventListener.
        }
Esempio n. 11
0
        internal void ConflictOccurred(IConflict conflict, XmlNode nodeToFindGeneratorFrom)
        {
            var contextDescriptorGenerator = GetContextDescriptorGenerator(nodeToFindGeneratorFrom);
            _htmlContextGenerator = (contextDescriptorGenerator as IGenerateHtmlContext) ?? new SimpleHtmlGenerator();

            XmlMergeService.AddConflictToListener(
                EventListener,
                conflict,
                _oursContext,
                _theirsContext,
                _ancestorContext,
                _htmlContextGenerator,
                this,
                nodeToFindGeneratorFrom);
        }
Esempio n. 12
0
        internal void ConflictOccurred(IConflict conflict)
        {
            if (_htmlContextGenerator == null)
                _htmlContextGenerator = new SimpleHtmlGenerator();

            XmlMergeService.AddConflictToListener(
                EventListener,
                conflict,
                _oursContext,
                _theirsContext,
                _ancestorContext,
                _htmlContextGenerator);
        }
Esempio n. 13
0
        /// <summary>
        /// This method does the actual work for the various public entry points of XmlMerge
        /// and from the various Method-type classes, as it processes child nodes, if any.
        /// </summary>
        internal void MergeInner(XmlNode ourParent, ref XmlNode ours, XmlNode theirs, XmlNode ancestor)
        {
            SendMergeHeartbeat();
            _oursContext     = ours;
            _theirsContext   = theirs;
            _ancestorContext = ancestor;

            var elementStrat = MergeStrategies.GetElementStrategy(ours ?? theirs ?? ancestor);

            // Step 0: Do anything special the strategy wants to do before regular merging. This may modify the nodes.
            // For instance clinets may want to ensure 'our' and 'their' have the latest date stamp available.
            elementStrat.Premerger.Premerge(EventListener, ref ours, theirs, ancestor);

            // Step 0.1: Set up a context, if available.
            // Listeners are set to use NullContextDescriptor as the default context,
            var contextDescriptorGenerator = elementStrat.ContextDescriptorGenerator;             // May be null, which is fine in code, below, that uses it.
            //review: question: does this not get called at levels below the entry?
            //this would seem to fail at, say, a sense. I'm confused. (JH 30june09)
            var descriptor = GetContextDescriptor(ours, contextDescriptorGenerator);

            EventListener.EnteringContext(descriptor);             // TODO: If the context is ever redone as a stack, then this call with push the context onto the stack.
            _htmlContextGenerator = (contextDescriptorGenerator as IGenerateHtmlContext) ?? new SimpleHtmlGenerator();

            // Step 1: If the current set of nodes are immutable,
            // then make sure no changes took place (among a few other things).
            if (elementStrat.IsImmutable)
            {
                ImmutableElementMergeService.DoMerge(this, ourParent, ref ours, theirs, ancestor);
                return;                 // Don't go any further, since it is immutable.
            }

            // Step 2: If the current set of elements is 'atomic'
            // (only one user can make changes to the node, or anything it contains),
            // then make sure only set of changes have been made.
            if (elementStrat.IsAtomic)
            {
                if (elementStrat.AllowAtomicTextMerge && XmlUtilities.IsTextLevel(ours, theirs, ancestor))
                {
                    DoTextMerge(ref ours, theirs, ancestor, elementStrat);
                    return;
                }
                MergeAtomicElementService.Run(this, ourParent, ref ours, theirs, ancestor);
                return;
            }

            // Step 3: Go ahead and merge the attributes, as needed.
            MergeXmlAttributesService.MergeAttributes(this, ref ours, theirs, ancestor);

            // Step 4: Hmm, trouble is, a node might be required to have one or more child nodes.
            // I suppose a real validator would have picked up on that, and not allowed
            // the first commit, so we wouldn't then be doing a merge operation.
            // So, not to worry here, if the validator doesn't care enough to prevent the first commit.
            // It could be possible for the elements to have no children, in which case, there is nothing more to merge, so just return.
            if (ours != null && !ours.HasChildNodes && theirs != null && !theirs.HasChildNodes && ancestor != null && !ancestor.HasChildNodes)
            {
                return;
            }

            // Step 5: Do some kind of merge on the child node.
            if (XmlUtilities.IsTextLevel(ours, theirs, ancestor))
            {
                // Step 5A: Merge the text element.
                DoTextMerge(ref ours, theirs, ancestor, elementStrat);
            }
            else
            {
                switch (elementStrat.NumberOfChildren)
                {
                case NumberOfChildrenAllowed.Zero:
                case NumberOfChildrenAllowed.ZeroOrOne:
                    // Step 5B: Merge the "special needs" nodes.
                    MergeLimitedChildrenService.Run(this, elementStrat, ref ours, theirs, ancestor);
                    break;

                case NumberOfChildrenAllowed.ZeroOrMore:
                    // Step 5B:
                    // Q: is this a level of the xml file that would consitute the minimal unit conflict-understanding
                    // from a user perspecitve?
                    // e.g., in a dictionary, this is the lexical entry.  In a text, it might be  a paragraph.
                    // A (RandyR): Definitely it may not be such a level of node.
                    new MergeChildrenMethod(ours, theirs, ancestor, this).Run();
                    break;
                }
            }

            // At some point, it may be necessary here to restore the pre-existing values of
            // _oursContext, _theirsContext, _ancestorContext, and _htmlContextGenerator.
            // and somehow restore the EventListener's Context.
            // Currently however no client generates further conflicts after calling MergeChildren.

            // Step 6: TODO: If the context is ever redone as a stack, then pop the stack here to return to the outer context via some new LeavingContext method on EventListener.
        }