using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using HEAL.Attic; namespace HeuristicLab.JsonInterface { public readonly struct ValidationResult { public static ValidationResult Successful() => new ValidationResult(true, Enumerable.Empty()); public static ValidationResult Faulty(IEnumerable errors) => new ValidationResult(false, errors); public static ValidationResult Faulty(string error) => new ValidationResult(false, error); public ValidationResult(bool success, IEnumerable errors) { Success = success; Errors = errors; } public ValidationResult(bool success, string error) { Success = success; Errors = Enumerable.Repeat(error, 1); } public bool Success { get; } public IEnumerable Errors { get; } public Exception GenerateException() => new AggregateException(Errors.Select(x => new ArgumentException(x))); } [StorableType("B1270D98-B0D9-40FB-B089-F6E70C65CD65")] /// /// Main data class for json interface. /// public abstract class JsonItem : IJsonItem { public class JsonItemValidator : IJsonItemValidator { //private IDictionary Cache = new Dictionary(); private JsonItem Root { get; set; } public JsonItemValidator(JsonItem root) { Root = root; } public ValidationResult Validate() { List errors = new List(); bool success = true; foreach (var x in Root) { JsonItem item = x as JsonItem; if (item.Active) { var res = ((JsonItem)x).Validate(); //if one success is false -> whole validation is false success = success && res.Success; errors.AddRange(res.Errors); } } return new ValidationResult(success, errors); } } public virtual string Name { get; set; } public virtual string Description { get; set; } public virtual string Path { get { IJsonItem tmp = Parent; StringBuilder builder = new StringBuilder(this.Name); while (tmp != null) { builder.Insert(0, tmp.Name + "."); tmp = tmp.Parent; } return builder.ToString(); } } [JsonIgnore] public virtual IEnumerable Children { get; protected set; } [JsonIgnore] public virtual IJsonItem Parent { get; set; } [JsonIgnore] public virtual bool Active { get; set; } #region Constructors [StorableConstructor] protected JsonItem(StorableConstructorFlag _) { } public JsonItem() { } public JsonItem(IEnumerable childs) { AddChildren(childs); } #endregion #region Public Methods public void AddChildren(params IJsonItem[] childs) => AddChildren(childs as IEnumerable); public void AddChildren(IEnumerable childs) { if (childs == null) return; if (Children == null) Children = new List(); if (Children is IList list) { foreach (var child in childs) { list.Add(child); child.Parent = this; } } } public IJsonItemValidator GetValidator() => new JsonItemValidator(this); public virtual JObject GenerateJObject() => JObject.FromObject(this, new JsonSerializer() { TypeNameHandling = TypeNameHandling.None, NullValueHandling = NullValueHandling.Ignore, ReferenceLoopHandling = ReferenceLoopHandling.Ignore }); public virtual void SetJObject(JObject jObject) { Name = (jObject[nameof(IJsonItem.Name)]?.ToObject()); Description = (jObject[nameof(IJsonItem.Description)]?.ToObject()); } #endregion #region Abstract Methods protected abstract ValidationResult Validate(); #endregion #region IEnumerable Support public virtual IEnumerator GetEnumerator() { yield return this; if (Children != null) { foreach (var x in Children) { foreach (var c in x) { yield return c; } } } } IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); #endregion } }