Exemple #1
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);
        }
Exemple #2
0
 public AuditLogEntry ChangeParent(AuditLogEntry parent)
 {
     return(ChangeProp(ImClone(this), im =>
     {
         im.Parent = parent;
         im.Count = parent.Count + 1;
     }));
 }
Exemple #3
0
        /// <summary>
        /// Creates a simple entry only containing one message in each category with the given type and names and
        /// extra info
        /// </summary>
        public static AuditLogEntry CreateSingleMessageEntry(SrmDocument document,
                                                             MessageInfo info, string extraInfo = null)
        {
            var result = new AuditLogEntry(document, DateTime.Now, string.Empty, true, extraInfo)
            {
                UndoRedo = info.ToMessage(LogLevel.undo_redo),
                Summary  = info.ToMessage(LogLevel.summary),
                AllInfo  = new LogMessage[0]//new[] { info.ToMessage(LogLevel.all_info) }
            };

            return(result);
        }
Exemple #4
0
        /// <summary>
        /// Updates the document with the given AuditLogEntry. If the entry is non-null and logging is enabled,
        /// it is added to the document. If audit logging changed from being disabled to enabled and the document is different
        /// from the default document(no children, default settings) a "start from existing document" entry is added. If audit logging
        /// changes from being enabled to disabled, the log is cleared.
        /// </summary>
        /// <param name="entry">The entry to add</param>
        /// <param name="docPair">Document pair containing the new document the entry should get added to</param>
        /// <returns>A new document with this entry added</returns>
        public static SrmDocument UpdateDocument(AuditLogEntry entry, SrmDocumentPair docPair)
        {
            var newDoc = docPair.NewDoc;

            /*if (Settings.Default.AuditLogging || CountEntryType == MessageType.log_cleared)
             * {
             *  newDoc = newDoc.ChangeAuditLog(ChangeParent(docPair.NewDoc.AuditLog.AuditLogEntries));
             * }
             * else
             * {
             *  var entry = CreateUnloggedEntry(document, out var replace);
             *
             *  // This is the only property we have to copy over, since we don't care about the content of the log message
             *  // but still want the ability to undo unlogged entries. We only change the undo action for the first
             *  // unlogged message entry, otherwise clicking the undo button in the grid would undo the unlogged changes one-by-one
             *  // instead of in a single "batch undo." TODO: Is this how it should be?
             *  // (This one-by-one behavior can still be achieved by using the undo redo buffer)
             *  if (!replace)
             *      entry = entry.ChangeUndoAction(_undoAction);
             *
             *  var oldEntries = document.AuditLog.AuditLogEntries;
             *  var newEntries = replace
             *      ? entry.ChangeParent(oldEntries?.Parent)
             *      : entry.ChangeParent(oldEntries);
             *
             *  newDoc = document.ChangeAuditLog(newEntries);
             * }*/

            var oldLogging = docPair.OldDoc.Settings.DataSettings.AuditLogging;
            var newLogging = docPair.NewDoc.Settings.DataSettings.AuditLogging;

            if (oldLogging && !newLogging)
            {
                return(newDoc.ChangeAuditLog(ROOT));
            }
            else if (!oldLogging && newLogging)
            {
                var startEntry = GetAuditLoggingStartExistingDocEntry(newDoc);
                if (startEntry != null && entry != null)
                {
                    startEntry = startEntry.ChangeParent(entry);
                }
                entry = startEntry ?? entry;
            }

            if (newLogging)
            {
                newDoc = entry?.AppendEntryToDocument(newDoc) ?? newDoc;
            }

            return(newDoc);
        }
Exemple #5
0
        /// <summary>
        /// Creates a log entry indicating that logging was enabled or disabled
        /// </summary>
        public static AuditLogEntry CreateLogEnabledDisabledEntry(SrmDocument document)
        {
            var result = new AuditLogEntry(document, DateTime.Now, string.Empty);

            var type = Settings.Default.AuditLogging ? MessageType.log_enabled : MessageType.log_disabled;

            result.UndoRedo = new LogMessage(LogLevel.undo_redo, type, string.Empty, false);
            result.Summary  = new LogMessage(LogLevel.summary, type, string.Empty, false);
            result.AllInfo  = new List <LogMessage> {
                new LogMessage(LogLevel.all_info, type, string.Empty, false)
            };

            return(result);
        }
Exemple #6
0
        public void ReadXml(XmlReader reader)
        {
            var isEmpty = reader.IsEmptyElement;

            reader.ReadStartElement();

            AuditLogEntries = ReadEntries(reader);

            if (!isEmpty)
            {
                reader.ReadEndElement();
            }

            Validate();
        }
Exemple #7
0
        /// <summary>
        /// Merges two audit log entries, by adding the other entries
        /// all info messages and extra info to the current entry
        /// </summary>
        /// <param name="other">Entry to merge into the current one</param>
        /// <param name="append">true if all info and extra info should be appended, if false they are replaced</param>
        /// <returns>A new, merged entry</returns>
        public AuditLogEntry Merge(AuditLogEntry other, bool append = true)
        {
            if (other == null)
            {
                return(this);
            }

            var entry = append
                ? AppendAllInfo(other._mergeAllInfo)
                : ChangeAllInfo(other._mergeAllInfo.ToList());

            if (!string.IsNullOrEmpty(other.ExtraInfo))
            {
                entry = entry.ChangeExtraInfo(string.IsNullOrEmpty(ExtraInfo) || !append
                    ? other.ExtraInfo
                    : TextUtil.LineSeparate(ExtraInfo, other.ExtraInfo));
            }
            return(entry);
        }
Exemple #8
0
        public string GetHash()
        {
            // Surprisingly, the XmlTextWriter disposes the stream
            using (var stream = new MemoryStream())
            {
                using (var writer = new XmlTextWriter(stream, Encoding.UTF8)
                {
                    Formatting = Formatting.Indented
                })
                {
                    WriteToXmlWriter(writer);

                    stream.Seek(0, SeekOrigin.Begin);

                    // Leave stream open, otherwise XmlTextWriter will try to close it which causes an exception
                    using (var reader = new StreamReader(stream, Encoding.UTF8, true, 1024, true))
                    {
                        return(AuditLogEntry.Hash(reader.ReadToEnd()));
                    }
                }
            }
        }
Exemple #9
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));
        }
Exemple #10
0
 protected virtual AuditLogEntry CreateBaseEntry(SrmDocumentPair docPair)
 {
     return(MessageInfo.Type == MessageType.none
         ? AuditLogEntry.CreateEmptyEntry(docPair.OldDoc).ChangeAllInfo(new LogMessage[0])
         : AuditLogEntry.CreateSingleMessageEntry(docPair.OldDoc, MessageInfo));
 }
Exemple #11
0
 public AuditLogEntryAddedEventArgs(AuditLogEntry entry)
 {
     Entry = entry;
 }
Exemple #12
0
 public void Add(params MessageInfo[] allInfoMessages)
 {
     Add(docPair => AuditLogEntry.CreateEmptyEntry(docPair.OldDoc).ChangeAllInfo(allInfoMessages));
 }
Exemple #13
0
 public AuditLogList(AuditLogEntry entries)
 {
     AuditLogEntries = entries;
 }