コード例 #1
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);
        }
コード例 #2
0
ファイル: AuditLogEntry.cs プロジェクト: CMRI-ProCan/pwiz
        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);
        }
コード例 #3
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));
        }
コード例 #4
0
        // TODO: make this function and its overloads in nongeneric Reflector class simpler by introducing new class storing parameters
        private static IEnumerator <DiffNode> EnumerateDiffNodes(ObjectInfo <object> objectInfo, Property thisProperty,
                                                                 bool expand, PropertyPath propertyPath, object elementKey, IList <object> defaults, Func <DiffNode, bool> nodeSelector, DiffNode resultNode, int stackDepth)
        {
            nodeSelector = nodeSelector ?? (n => true);
            if (objectInfo.ObjectPair.ReferenceEquals() && !expand)
            {
                yield break;
            }

            resultNode = resultNode ?? (thisProperty.IsCollectionElement
                ? new ElementPropertyDiffNode(thisProperty, propertyPath, objectInfo.ObjectPair, elementKey, null, expand)
                : new PropertyDiffNode(thisProperty, propertyPath, objectInfo.ObjectPair, null, expand));

            var expandAnyways = false;

            var auditObjPair = objectInfo.ObjectPair.Transform(AuditLogObject.GetAuditLogObject);
            var nameChanged  = auditObjPair.OldObject.IsName && auditObjPair.NewObject.IsName &&
                               auditObjPair.OldObject.AuditLogText != auditObjPair.NewObject.AuditLogText;

            if (ReferenceEquals(objectInfo.OldObject, null) && !ReferenceEquals(objectInfo.NewObject, null) &&
                auditObjPair.NewObject.IsName || nameChanged &&
                // IIdentiyContainer name changes are actually displayed, since we match IIdentiyContainers by their global indices
                !typeof(IIdentiyContainer).IsAssignableFrom(thisProperty.GetPropertyType(objectInfo.ObjectPair)))
            {
                if (!thisProperty.IsRoot)
                {
                    if (!expand)
                    {
                        resultNode.IsFirstExpansionNode = true;
                    }

                    expandAnyways = expand = true;
                }
            }

            // If the object is an IAuditLogObject but not a name one, we don't care about subproperties
            //if (expand && typeof(IAuditLogObject).IsAssignableFrom(thisProperty.GetPropertyType(objectInfo.ObjectPair)) &&
            //    !auditObjPair.OldObject.IsName && !auditObjPair.NewObject.IsName)
            //    expand = false;

            defaults = defaults ?? new List <object>();
            if (expand && Reflector.ProcessDefaults(objectInfo, thisProperty, ref defaults, out var ignore))
            {
                // Don't expand if we changed to a default object
                if (expandAnyways && !ignore && nodeSelector(resultNode)) // Only show this object if it shouldn't be fully ignored if it's a default object (for instance: small molecule only properties)
                {
                    yield return(resultNode);
                }
                yield break;
            }

            // We only compare sub properties if both objects are non null, unless we're expanding
            // and only the old object is null
            if (ReferenceEquals(objectInfo.OldObject, null) && !expand || ReferenceEquals(objectInfo.NewObject, null))
            {
                if (nodeSelector(resultNode))
                {
                    yield return(resultNode);
                }
                yield break;
            }

            // Deal with Collections
            var collection = Reflector.GetCollectionInfo(thisProperty.GetPropertyType(objectInfo.ObjectPair),
                                                         objectInfo.ObjectPair);

            if (collection != null)
            {
                var nodeIter = Reflector.EnumerateCollectionDiffNodes(objectInfo.ChangeObjectPair(collection.Collections), collection,
                                                                      thisProperty, propertyPath, expand, defaults, nodeSelector, resultNode, stackDepth);

                while (nodeIter.MoveNext())
                {
                    yield return(nodeIter.Current);
                }

                yield break;
            }

            // Properties that should directly be checked for equality -- stop recursion
            if (!thisProperty.DiffProperties)
            {
                // Properties that are not TrackParents and not collections are simply compared
                // Also make sure that new val doesn't equal any of the default objects
                if (nodeSelector(resultNode) && (!objectInfo.ObjectPair.Equals() || expand) &&
                    (!expand || thisProperty.IgnoreDefaultParent || !defaults.Any(d => Equals(d, objectInfo.ObjectPair.NewObject))))
                {
                    yield return(resultNode);
                }
                yield break;
            }

            objectInfo = objectInfo.ChangeParentPair(objectInfo.ObjectPair);

            // Compare properties
            foreach (var property in _properties)
            {
                var newPropertyPath = property.AddProperty(propertyPath);

                var newObjectInfo = objectInfo
                                    .ChangeOldObject(ReferenceEquals(objectInfo.OldObject, null)
                        ? null
                        : property.GetValue(objectInfo.OldObject))
                                    .ChangeNewObject(property.GetValue(objectInfo.NewObject));

                var valType  = property.GetPropertyType(newObjectInfo.ObjectPair);
                var nodeIter = Reflector.EnumerateDiffNodes(valType, newObjectInfo, property, expand, newPropertyPath,
                                                            null, defaults, nodeSelector, null, stackDepth);

                DiffNode current = null;
                while (nodeIter.MoveNext())
                {
                    current = nodeIter.Current;
                    yield return(current);
                }

                if (current != null)
                {
                    resultNode.Nodes.Add(current);
                }
            }

            // If there are child nodes, we always want to return the parent node,
            // but if it's just the root node or a diffparent (meaning only the object reference changed)
            // we return null (meaning the objects are equivalent)
            if (resultNode.Nodes.Count == 0 && thisProperty.DiffProperties && !expandAnyways)
            {
                yield break;
            }

            if (nodeSelector(resultNode))
            {
                yield return(resultNode);
            }
        }