/// <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); }
internal void WarningOccurred(IConflict warning) { if (_htmlContextGenerator == null) { _htmlContextGenerator = new SimpleHtmlGenerator(); } XmlMergeService.AddWarningToListener( EventListener, warning, _oursContext, _theirsContext, _ancestorContext, _htmlContextGenerator); }
internal void ConflictOccurred(IConflict conflict) { if (_htmlContextGenerator == null) { _htmlContextGenerator = new SimpleHtmlGenerator(); } XmlMergeService.AddConflictToListener( EventListener, conflict, _oursContext, _theirsContext, _ancestorContext, _htmlContextGenerator); }
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) { }
/// <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); }
/// <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); }
internal void WarningOccurred(IConflict warning) { if (_htmlContextGenerator == null) _htmlContextGenerator = new SimpleHtmlGenerator(); XmlMergeService.AddWarningToListener( EventListener, warning, _oursContext, _theirsContext, _ancestorContext, _htmlContextGenerator); }
/// <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. }
internal void ConflictOccurred(IConflict conflict) { if (_htmlContextGenerator == null) _htmlContextGenerator = new SimpleHtmlGenerator(); XmlMergeService.AddConflictToListener( EventListener, conflict, _oursContext, _theirsContext, _ancestorContext, _htmlContextGenerator); }
/// <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. }