예제 #1
0
파일: DiffNode.cs 프로젝트: rfellers/pwiz
        public DiffNodeNamePair FindFirstMultiChildParent(DiffTree tree, PropertyName name, bool shortenName, bool allowReflection, DiffNode parentNode = null)
        {
            var oneNode = Nodes.Count == 1;

            var propertyNameString = Property.GetName(tree.Root, this, parentNode);

            // Collection elements should be referred to by their name or string representation
            var propName = IsCollectionElement
                ? new PropertyElementName(ObjectToString(allowReflection))
                : (Property.IsTab ? new PropertyTabName(propertyNameString) : new PropertyName(propertyNameString));

            // If the node can't be displayed and its name cant be ignored,
            // we can't go further down the tree. This can happen theoretically but hasn't occured anywhere yet
            if (propName.Name == null && !Property.IgnoreName)
            {
                return(new DiffNodeNamePair(parentNode?.ChangeExpanded(false), name, allowReflection));
            }

            var newName = name.SubProperty(propName);

            var elemName = Property.GetElementName();

            if (shortenName && Property.GetElementName() != null && !IsCollectionElement)
            {
                if (oneNode)
                {
                    // Remove everything from the path and replace it with the element name, e.g "Settings > DataSettings > GroupComparisons"
                    // becomes "GroupComparison:"
                    newName = PropertyName.ROOT.SubProperty(new PropertyElementName(elemName));
                }
                else
                {
                    // Multiple changes have been made to the collection
                    newName = propName;
                }
            }

            if (Property.IgnoreName && !IsCollectionElement)
            {
                newName = name;
            }

            var objects = Objects.Select(AuditLogObject.GetAuditLogObject)
                          .Where(o => o == null || o.IsName).ToArray();

            if (objects.Length == 2)
            {
                var type = Property.GetPropertyType(ObjectPair.Create(objects[1], objects[0]));
                if (((objects[0] != null) != (objects[1] != null) ||
                     (objects[0] != null && objects[1] != null && objects[0].AuditLogText != objects[1].AuditLogText && !typeof(DocNode).IsAssignableFrom(type))) &&
                    !Property.IsRoot)
                {
                    oneNode = false;     // Stop recursion, since in the undo-redo/summary log we don't want to go deeper for objects where the name changed
                }
            }

            return(oneNode && !IsFirstExpansionNode
                ? Nodes[0].FindFirstMultiChildParent(tree, newName, shortenName, allowReflection, this)
                : new DiffNodeNamePair(ChangeExpanded(false), newName, allowReflection));
        }
예제 #2
0
        /// <summary>
        /// Creates a log entry representing the changes in the diff tree
        /// </summary>
        /// <param name="document">Document changes were made to</param>
        /// <param name="tree">Tree that should be logged</param>
        /// <param name="extraInfo">Text that should be displayed when clicking the magnifying glass in the audit log form</param>
        /// <returns></returns>
        public static AuditLogEntry CreateSettingsChangeEntry(SrmDocument document, DiffTree tree, string extraInfo = null)
        {
            if (tree.Root == null)
            {
                return(null);
            }

            var result = new AuditLogEntry(document, tree.TimeStamp, string.Empty, true, extraInfo);

            var nodeNamePair = tree.Root.FindFirstMultiChildParent(tree, PropertyName.ROOT, true, false);

            // Remove "Settings" from property name if possible
            if (nodeNamePair.Name != null && nodeNamePair.Name.Parent != PropertyName.ROOT)
            {
                var name = nodeNamePair.Name;
                while (name.Parent.Parent != PropertyName.ROOT)
                {
                    name = name.Parent;
                }

                if (name.Parent.Name == "{0:Settings}") // Not L10N
                {
                    name         = RemoveTopmostParent(nodeNamePair.Name);
                    nodeNamePair = nodeNamePair.ChangeName(name);
                }
            }

            result.UndoRedo = nodeNamePair.ToMessage(LogLevel.undo_redo);
            result.Summary  = tree.Root.FindFirstMultiChildParent(tree, PropertyName.ROOT, false, false)
                              .ToMessage(LogLevel.summary);
            result.AllInfo = tree.Root.FindAllLeafNodes(tree, PropertyName.ROOT, true)
                             .Select(n => n.ToMessage(LogLevel.all_info)).ToArray();

            return(result);
        }
예제 #3
0
        public static string ToString(ObjectPair <object> rootPair, T obj, ToStringState state)
        {
            var objectInfo = new ObjectInfo <object>().ChangeNewObject(obj)
                             .ChangeRootObjectPair(rootPair ?? ObjectPair <object> .Create(null, null));
            var rootProp = RootProperty.Create(typeof(T));

            var enumerator = EnumerateDiffNodes(objectInfo, rootProp, true);

            return(ToString(objectInfo.ParentObjectPair, DiffTree.FromEnumerator(enumerator, DateTime.Now).Root, state));
        }
예제 #4
0
        /// <summary>
        /// Compares the settings objects of the given documents and creates an entry
        /// for the differences
        /// </summary>
        /// <param name="documentPair">The pair of documents to compare</param>
        /// <returns>A log entry containing the changes</returns>
        public static AuditLogEntry SettingsLogFunction(SrmDocumentPair documentPair)
        {
            var property = RootProperty.Create(typeof(SrmSettings), "Settings"); // Not L10N
            var objInfo  = new ObjectInfo <object>(documentPair.OldDoc.Settings, documentPair.NewDoc.Settings,
                                                   documentPair.OldDoc, documentPair.NewDoc, documentPair.OldDoc, documentPair.NewDoc);

            var tree = DiffTree.FromEnumerator(Reflector <SrmSettings> .EnumerateDiffNodes(objInfo, property, false));

            return(tree.Root != null?CreateSettingsChangeEntry(documentPair.OldDoc, tree) : null);
        }
예제 #5
0
        public static AuditLogEntry DiffDocNodes(MessageType action, SrmDocumentPair documentPair, params object[] actionParameters)
        {
            var property = RootProperty.Create(typeof(Targets));
            var objInfo  = new ObjectInfo <object>(documentPair.OldDoc.Targets, documentPair.NewDoc.Targets,
                                                   documentPair.OldDoc, documentPair.NewDoc, documentPair.OldDoc, documentPair.NewDoc);

            var diffTree = DiffTree.FromEnumerator(Reflector <Targets> .EnumerateDiffNodes(objInfo, property, false), DateTime.Now);

            if (diffTree.Root != null)
            {
                var message = new MessageInfo(action, actionParameters);
                var entry   = CreateSettingsChangeEntry(documentPair.OldDoc, diffTree)
                              .ChangeUndoRedo(message);
                return(entry);
            }

            return(null);
        }
예제 #6
0
        protected virtual AuditLogEntry CreateEntry(SrmDocumentPair docPair)
        {
            var baseEntry = CreateBaseEntry(docPair);
            var rootProp  = RootProperty.Create(typeof(T));

            var objectInfo = new ObjectInfo <object>()
                             .ChangeObjectPair(ObjectPair <object> .Create(null, this))
                             .ChangeRootObjectPair(docPair.ToObjectType());

            var diffTree =
                DiffTree.FromEnumerator(Reflector <T> .EnumerateDiffNodes(docPair.ToObjectType(), rootProp, (T)this), DateTime.Now);

            if (diffTree.Root == null)
            {
                return(baseEntry);
            }

            var settingsString = Reflector <T> .ToString(objectInfo.RootObjectPair, diffTree.Root,
                                                         ToStringState.DEFAULT.ChangeFormatWhitespace(true));

            var entry = AuditLogEntry.CreateSettingsChangeEntry(docPair.OldDoc, diffTree, settingsString);

            return(baseEntry.Merge(entry));
        }
예제 #7
0
파일: DiffNode.cs 프로젝트: rfellers/pwiz
        public List <DiffNodeNamePair> FindAllLeafNodes(DiffTree tree, PropertyName name, bool allowReflection, DiffNode parentNode = null)
        {
            var result = new List <DiffNodeNamePair>();

            var propertyNameString = Property.GetName(tree.Root, this, parentNode);

            var isName = false;
            // Collection elements should be referred to by their name or string representation
            var propName = IsCollectionElement
                ? new PropertyElementName(ObjectToString(allowReflection, Objects.FirstOrDefault(o => o != null), out isName))
                : (Property.IsTab ? new PropertyTabName(propertyNameString) : new PropertyName(propertyNameString));

            // The name can not be ignored if the node is a collection change (since then the child nodes of the collection change
            // have the same attribute as the collection change node)
            var canIgnoreName = (Property.IgnoreName && !IsCollectionElement);

            if (!canIgnoreName)
            {
                name = name != null?name.SubProperty(propName) : propName;
            }

            // We can't display sub changes of an element if it's unnamed, so we display its
            // string representation as a change
            if (IsCollectionElement && !isName && !canIgnoreName)
            {
                result.Add(new DiffNodeNamePair(this, name, allowReflection));
                return(result);
            }

            var obj           = Objects.FirstOrDefault();
            var isNamedChange = IsFirstExpansionNode || (obj != null && AuditLogObject.IsNameObject(obj)) &&
                                Expanded && !canIgnoreName;

            if (isNamedChange)
            {
                result.Add(new DiffNodeNamePair(this, name, allowReflection));
            }

            if (Nodes.Count == 0)
            {
                if (!isNamedChange)
                {
                    result.Add(new DiffNodeNamePair(this, name, allowReflection));
                }
            }
            else
            {
                var collectionPropDiffNode = this as CollectionPropertyDiffNode;
                if (collectionPropDiffNode != null && collectionPropDiffNode.RemovedAll)
                {
                    result.Add(new DiffNodeNamePair(this, name, allowReflection));
                }
                else
                {
                    foreach (var n in Nodes)
                    {
                        result.AddRange(n.FindAllLeafNodes(tree, name, allowReflection, this));
                    }
                }
            }

            return(result);
        }