using System; using System.Collections.Generic; using System.Linq; namespace DelftTools.Utils.Validation { public class ValidationReport { /// /// Gets the severity of the report, eg the maximum severity of any of its issues. /// public ValidationSeverity Severity { get; private set; } public string Category { get; private set; } public IEnumerable Issues { get; private set; } public IEnumerable SubReports { get; private set; } public ValidationReport(string category, IEnumerable issues, IEnumerable subReports = null) { Category = category; Issues = AsList(issues ?? new ValidationIssue[0]); SubReports = AsList(subReports ?? new ValidationReport[0]); Severity = DetermineSeverity(); } public ValidationReport(string category, IEnumerable subReports) : this(category, null, subReports) { } /// /// Creates an empty validation report. Validation reports are read-only so they cannot be added to. /// public static ValidationReport Empty(string name) { return new ValidationReport(name, null); } /// /// IsEmpty is true when the report contains no issues and no subreports /// public bool IsEmpty { get { return !Issues.Any() && !SubReports.Any(); } } public IList GetAllIssuesRecursive() { var allIssues = new List(); allIssues.AddRange(Issues); foreach(var report in SubReports) { allIssues.AddRange(report.GetAllIssuesRecursive()); } return allIssues; } public IEnumerable AllErrors { get { return GetAllIssuesRecursive().Where(i => i.Severity == ValidationSeverity.Error); } } private ValidationSeverity DetermineSeverity() { var issueMax = Issues.Any() ? Issues.Max(i => i.Severity) : ValidationSeverity.None; var reportMax = SubReports.Any() ? SubReports.Max(i => i.Severity) : ValidationSeverity.None; return (ValidationSeverity) Math.Max((int) issueMax, (int) reportMax); } /// /// The total number of issues (recursive) with severity level 'Error' /// public int ErrorCount { get { return GetIssueCount(ValidationSeverity.Error); } } /// /// The total number of issues (recursive) with severity level 'Warning' /// public int WarningCount { get { return GetIssueCount(ValidationSeverity.Warning); } } /// /// The total number of issues (recursive) with severity level 'Info' /// public int InfoCount { get { return GetIssueCount(ValidationSeverity.Info); } } private int GetIssueCount(ValidationSeverity severity) { return SubReports.Sum(r => r.GetIssueCount(severity)) + Issues.Count(i => i.Severity == severity); } public override bool Equals(object obj) { if (obj is ValidationReport) { return Equals(obj as ValidationReport); } return false; } public bool Equals(ValidationReport other) { if (other == null) return false; if (ReferenceEquals(this, other)) return true; if (!Category.Equals(other.Category)) return false; var issues = Issues.ToList(); var otherIssues = other.Issues.ToList(); if (issues.Count != otherIssues.Count) return false; for (int i = 0; i < issues.Count; i++) { if (!issues[i].Equals(otherIssues[i])) { return false; } } var subreports = SubReports.ToList(); var otherSubreports = other.SubReports.ToList(); if (subreports.Count != otherSubreports.Count) return false; for (int i = 0; i < subreports.Count; i++) { if (!subreports[i].Equals(otherSubreports[i])) { return false; } } return true; } public override string ToString() { return string.Format("{0}, severity: {1} ({2} error(s), {3} warning(s), {4} info)", Category, Severity, ErrorCount, WarningCount, InfoCount); } private static IList AsList(IEnumerable enumerable) { return enumerable as IList ?? enumerable.ToList(); } } }