Exemple #1
0
        public void ReportDifferencesToListener()
        {
            foreach (XmlNode node in _parentDom.SafeSelectNodes("lift/entry"))
            {
                string strId = LiftUtils.GetId(node);
                if (!_parentIdToNodeIndex.ContainsKey(strId))
                {
                    _parentIdToNodeIndex.Add(strId, node);
                }
                else
                {
                    System.Diagnostics.Debug.WriteLine(String.Format("Found ID multiple times: {0}", strId));
                }
            }

            foreach (XmlNode childNode in _childDom.SafeSelectNodes("lift/entry"))
            {
                try
                {
                    ProcessEntry(childNode);
                }
                catch (Exception error)
                {
                    EventListener.ChangeOccurred(new ErrorDeterminingChangeReport(_parentFileInRevision,
                                                                                  _childFileInRevision, null, childNode,
                                                                                  error));
                }
            }

            //now detect any removed (not just marked as deleted) elements
            foreach (XmlNode parentNode in _parentIdToNodeIndex.Values)            // _parentDom.SafeSelectNodes("lift/entry"))
            {
                try
                {
                    if (!_processedIds.Contains(LiftUtils.GetId(parentNode)))
                    {
                        EventListener.ChangeOccurred(new XmlDeletionChangeReport(_parentFileInRevision, parentNode,
                                                                                 null));
                    }
                }
                catch (Exception error)
                {
                    EventListener.ChangeOccurred(new ErrorDeterminingChangeReport(_parentFileInRevision,
                                                                                  _childFileInRevision,
                                                                                  parentNode,
                                                                                  null,
                                                                                  error));
                }
            }
        }
Exemple #2
0
        private void ProcessEntry(XmlNode child)
        {
            string  id     = LiftUtils.GetId(child);
            XmlNode parent = null;          // = LiftUtils.FindEntryById(_parentDom, id);

            _parentIdToNodeIndex.TryGetValue(id, out parent);

            string path = string.Empty;

            if (_childFileInRevision != null && !string.IsNullOrEmpty(_childFileInRevision.FullPath))
            {
                path = Path.GetFileName(_childFileInRevision.FullPath);
            }
            string url = LiftUtils.GetUrl(child, path);

            if (parent == null)             //it's new
            {
                //it's possible to create and entry, delete it, then checkin, leave us with this
                //spurious deletion messages
                if (string.IsNullOrEmpty(XmlUtilities.GetOptionalAttributeString(child, "dateDeleted")))
                {
                    EventListener.ChangeOccurred(new XmlAdditionChangeReport(_childFileInRevision, child, url));
                }
            }
            else if (LiftUtils.AreTheSame(child, parent))            //unchanged or both made same change
            {
            }
            else             //one or both changed
            {
                if (!string.IsNullOrEmpty(XmlUtilities.GetOptionalAttributeString(child, "dateDeleted")))
                {
                    EventListener.ChangeOccurred(new XmlDeletionChangeReport(_parentFileInRevision, parent, child));
                }
                else
                {
                    //enhance... we are only using this because it will conveniently find the differences
                    //and fire them off for us

                    //enhance: we can skip this and just say "something changed in this entry",
                    //until we really *need* the details (if ever), and have a way to call this then
                    //_mergingStrategy.MakeMergedEntry(this.EventListener, child, parent, parent);
                    EventListener.ChangeOccurred(new XmlChangedRecordReport(_parentFileInRevision, _childFileInRevision, parent, child, url));
                }
            }
            _processedIds.Add(id);
        }
Exemple #3
0
        public string GetMergedLift()
        {
//            string path = Path.Combine(System.Environment.GetEnvironmentVariable("temp"),
//                                    @"chorusMergeResult" + Path.GetFileName(_alphaLiftPath) + ".txt");
//
//            File.WriteAllText(path, "ENter GetMergedLift()");

            var ancestorDom = new XmlDocument();

            ancestorDom.LoadXml(_ancestorLift);
            //var comonIdToNodeIndex = new Dictionary<string, XmlNode>(StringComparer.OrdinalIgnoreCase);

            var alphaDom = new XmlDocument();

            alphaDom.LoadXml(_alphaLift);
            var alphaIdToNodeIndex = new Dictionary <string, XmlNode>(StringComparer.OrdinalIgnoreCase);

            var betaDom = new XmlDocument();

            betaDom.LoadXml(_betaLift);
            var betaIdToNodeIndex = new Dictionary <string, XmlNode>(StringComparer.OrdinalIgnoreCase);

            var processedIds = new HashSet <string>(StringComparer.OrdinalIgnoreCase);

            // The memory stream, rather than a string builder, is needed to avoid utf-16 coming out
            using (var memoryStream = new MemoryStream())
            {
                //foreach (XmlNode commonNode in _ancestorDom.SafeSelectNodes("lift/entry"))
                //	comonIdToNodeIndex[LiftUtils.GetId(commonNode)] = commonNode;
                foreach (XmlNode alphaNode in alphaDom.SafeSelectNodes("lift/entry"))
                {
                    alphaIdToNodeIndex[LiftUtils.GetId(alphaNode)] = alphaNode;
                }
                foreach (XmlNode betaNode in betaDom.SafeSelectNodes("lift/entry"))
                {
                    betaIdToNodeIndex[LiftUtils.GetId(betaNode)] = betaNode;
                }

                var settings = CanonicalXmlSettings.CreateXmlWriterSettings();
                settings.CloseOutput = false;
                using (var writer = XmlWriter.Create(memoryStream, settings))
                {
                    WriteStartOfLiftElement(writer, alphaDom);

                    ProcessHeaderNodeHACK(writer, alphaDom, betaDom);
                    // Process alpha's entries
                    ProcessEntries(writer, EventListener, _mergingStrategy, ancestorDom, processedIds,
                                   alphaDom, "alpha", _alphaLift,
                                   betaIdToNodeIndex, "beta", _betaLift);
                    // Process beta's entries
                    ProcessEntries(writer, EventListener, _mergingStrategy, ancestorDom, processedIds,
                                   betaDom, "beta", _betaLift,
                                   alphaIdToNodeIndex, "alpha", _alphaLift);
                    writer.WriteEndElement();
                    writer.Close();
                }

                // Don't use GetBuffer()!!! it pads the results with nulls:  return Encoding.UTF8.GetString(memoryStream.ToArray());
                // This works but doubles the ram use: return Encoding.UTF8.GetString(memoryStream.ToArray());
                return(Encoding.UTF8.GetString(memoryStream.GetBuffer(), 0, (int)memoryStream.Position));
            }
        }
Exemple #4
0
        private static void ProcessEntry(XmlWriter writer, IMergeEventListener eventListener, IMergeStrategy mergingStrategy,
                                         XmlNode ancestorDom, HashSet <string> processedIds,
                                         XmlNode sourceEntry, string sourceLabel, string sourcePath,
                                         IDictionary <string, XmlNode> otherIdNodeIndex, string otherLabel, string otherPath)
        {
            var id = LiftUtils.GetId(sourceEntry);

            if (processedIds.Contains(id))
            {
                return;                 // Already handled the id.
            }
            XmlNode otherEntry;
            var     commonEntry = FindEntry(ancestorDom, id);

            if (!otherIdNodeIndex.TryGetValue(id, out otherEntry))
            {
                // It is in source, but not in target, so it clearly has been deleted by target (new style deletion).
                if (LiftUtils.GetIsMarkedAsDeleted(sourceEntry))
                {
                    if (!LiftUtils.GetIsMarkedAsDeleted(commonEntry))
                    {
                        // source and target both deleted but in different ways, so make deletion change report.
                        // There is no need to write anything.
                        eventListener.ChangeOccurred(new XmlDeletionChangeReport(sourcePath, commonEntry, sourceEntry));
                    }
                    //else
                    //{
                    //    // Make it go away without fanfare by doing nothing to writer, since target actually removed the dead entry.
                    //}
                    processedIds.Add(id);
                    return;
                }

                if (commonEntry == null)
                {
                    // source added it
                    eventListener.ChangeOccurred(new XmlAdditionChangeReport(sourcePath, sourceEntry));
                    writer.WriteNode(sourceEntry.CreateNavigator(), false);
                }
                else
                {
                    if (AreTheSame(sourceEntry, commonEntry))
                    {
                        // target's deletion wins with a plain vanilla deletion report.
                        eventListener.ChangeOccurred(new XmlDeletionChangeReport(sourcePath, commonEntry, otherEntry));
                    }
                    else
                    {
                        // source wins over target's new style deletion on the least loss priciple.
                        // Add an edit vs remove conflict report.
                        eventListener.ConflictOccurred(new RemovedVsEditedElementConflict("entry", sourceEntry, otherEntry, commonEntry, new MergeSituation(sourcePath, sourceLabel, "", otherLabel, "", MergeOrder.ConflictHandlingModeChoices.WeWin), null, sourceLabel));
                        writer.WriteNode(sourceEntry.CreateNavigator(), false);
                    }
                    processedIds.Add(id);
                    return;
                }
            }
            else if (AreTheSame(sourceEntry, otherEntry))
            {
                //unchanged or both made same change
                writer.WriteNode(sourceEntry.CreateNavigator(), false);
            }
            else if (LiftUtils.GetIsMarkedAsDeleted(otherEntry))
            {
                // source edited, target deleted (old style deletion using dateDeleted attr).
                eventListener.ConflictOccurred(new RemovedVsEditedElementConflict("entry", sourceEntry, otherEntry, commonEntry, new MergeSituation(sourcePath, sourceLabel, "", otherLabel, "", MergeOrder.ConflictHandlingModeChoices.WeWin), null, sourceLabel));
            }
            else if (LiftUtils.GetIsMarkedAsDeleted(sourceEntry))
            {
                // source deleted (old style), but target edited.
                // target wins with the least loss principle.
                // But generate a conflict report.
                eventListener.ConflictOccurred(new RemovedVsEditedElementConflict("entry", otherEntry, sourceEntry, commonEntry, new MergeSituation(otherPath, otherLabel, "", sourceLabel, "", MergeOrder.ConflictHandlingModeChoices.TheyWin), null, sourceLabel));
                writer.WriteNode(otherEntry.CreateNavigator(), false);
            }
            else
            {
                // One or both of them edited it, so merge the hard way.
                using (var reader = XmlReader.Create(new StringReader(
                                                         mergingStrategy.MakeMergedEntry(eventListener, sourceEntry, otherEntry, commonEntry)
                                                         )))
                {
                    writer.WriteNode(reader, false);
                }
            }
            processedIds.Add(id);
        }