Free cookie consent management tool by TermsFeed Policy Generator

source: branches/3026_IntegrationIntoSymSpace/HeuristicLab.JsonInterface/JsonItem.cs @ 17379

Last change on this file since 17379 was 17379, checked in by dpiringe, 5 years ago

#3026:

  • removed classes:
    • CheckedItemListConverter: unnecessary
    • ItemCollectionConverter: unnecessary
    • PrimitiveConverter: not possible to implement because it needs to Extract/Inject from/into objects (but interfaces pretends IItem)
    • StorableConverter: unnecessary
    • ConfigurableConverter: unnecessary
  • removed graphviz code in Heuristiclab.ConfigStarter/Program.cs
  • updated Constants
  • some simple code refactors in BaseConverter
  • in JsonItem:
    • renamed Parameters -> Children
    • removed Properties: Operators, Type, Reference, IsConfigurable, IsParameterizedItem
    • removed unnecessary/old code
  • implemented a new way to get data from an object, which is a matrix, in ValueTypeMatrixConverter method: CopyMatrixData
    • converts the object into an array -> rows: from array.Length, cols: when the length is > 0 pick length of first array of index 0 (it is saved as an array of arrays)
  • created a binding flag const in ValueRangeConverter to prevent duplicates in code
File size: 4.8 KB
Line 
1using System;
2using System.Collections;
3using System.Collections.Generic;
4using System.IO;
5using System.Linq;
6using System.Text;
7using System.Threading.Tasks;
8using HeuristicLab.Core;
9using Newtonsoft.Json;
10using Newtonsoft.Json.Linq;
11
12namespace HeuristicLab.JsonInterface {
13  /// <summary>
14  /// Main data class for json interface.
15  /// </summary>
16  public class JsonItem {
17
18    #region Private Fields
19    private string name;
20    private object value;
21    private IEnumerable<object> range;
22    #endregion
23
24    public string Name {
25      get => name;
26      set {
27        if(Name != value) {
28          string oldName = Name;
29          name = value;
30          // replace name in path if path != null
31          if (Path != null) {
32            var parts = Path.Split('.');
33            parts[Array.IndexOf(parts, oldName)] = name;
34            Path = string.Join(".", parts);
35          } else
36            Path = Name;
37         
38          UpdatePath();
39        }
40      }
41    }
42    public string Path { get; set; }
43    public IList<JsonItem> Children { get; set; }
44    public object Value {
45      get => value;
46      set {
47        this.value = value;
48        CheckConstraints();
49      }
50    }
51    public IEnumerable<object> Range {
52      get => range;
53      set {
54        range = value;
55        CheckConstraints();
56      }
57    }
58    public string ActualName { get; set; }
59
60    #region Public Static Methods
61    public static void Merge(JsonItem target, JsonItem from) {
62      target.Name = from.Name ?? target.Name;
63      target.Range = from.Range ?? target.Range;
64      target.Path = from.Path ?? target.Path;
65      target.Value = from.Value ?? target.Value;
66      target.ActualName = from.ActualName ?? target.ActualName;
67      if(target.Children != null) {
68        if (from.Children != null)
69          ((List<JsonItem>)from.Children).AddRange(target.Children);
70      } else {
71        target.Children = from.Children;
72      }
73    }
74    #endregion
75
76    #region Public Methods
77    public void AddParameter(JsonItem item) {
78      if (Children == null)
79        Children = new List<JsonItem>();
80      Children.Add(item);
81      item.Path = $"{Path}.{item.Name}";
82      item.UpdatePath();
83    }
84
85    public void UpdatePath() {
86      if (Children != null)
87        UpdatePathHelper(Children);
88    }
89    #endregion
90
91    #region Helper
92    private void UpdatePathHelper(IEnumerable<JsonItem> items) {
93      foreach (var item in items) {
94        item.Path = $"{Path}.{item.Name}";
95        item.UpdatePath();
96      }
97    }
98
99    private void CheckConstraints() {
100      if (Range != null && Value != null && !IsInRange())
101        throw new ArgumentOutOfRangeException(nameof(Value), $"{nameof(Value)} is not in range.");
102    }
103
104    private bool IsInRange() {
105      bool b1 = true, b2 = true;
106      if (Value is IEnumerable && !(Value is string)) {
107        foreach (var x in (IEnumerable)Value) {
108          b1 = b1 ? IsInRangeList(x) : b1;
109          b2 = b2 ? IsInNumericRange(x) : b2;
110        }
111      }
112      else {
113        b1 = IsInRangeList(Value);
114        b2 = IsInNumericRange(Value);
115      }
116      return b1 || b2;
117    }
118
119    private bool IsInRangeList(object value) {
120      foreach (var x in Range)
121        if (x.Equals(value)) return true;
122      return false;
123    }
124
125    private bool IsInNumericRange(object value) =>
126      IsInNumericRange<ulong>(value)
127      || IsInNumericRange<uint>(value)
128      || IsInNumericRange<ushort>(value)
129      || IsInNumericRange<long>(value)
130      || IsInNumericRange<int>(value)
131      || IsInNumericRange<short>(value)
132      || IsInNumericRange<byte>(value)
133      || IsInNumericRange<float>(value)
134      || IsInNumericRange<double>(value)
135      || (value is float && float.IsNaN((float)value))
136      || (value is double && double.IsNaN((double)value));
137
138    private bool IsInNumericRange<T>(object value) where T : IComparable {
139      object min = Range.First(), max = Range.Last();
140      return
141        value != null && min != null && max != null && value is T && min is T && max is T &&
142        (((T)min).CompareTo(value) == -1 || ((T)min).CompareTo(value) == 0) &&
143        (((T)max).CompareTo(value) == 1 || ((T)max).CompareTo(value) == 0);
144    }
145    #endregion
146
147    #region BuildJsonItemMethods
148    public static JsonItem BuildJsonItem(JObject obj) {
149      object val = obj[nameof(Value)]?.ToObject<object>();
150      if (val is JContainer jContainer) // for resolving array values
151        val = jContainer.ToObject<object[]>();
152       
153      return new JsonItem() {
154        Name = obj[nameof(Name)]?.ToString(),
155        Path = obj[nameof(Path)]?.ToString(),
156        Value = val,
157        Range = obj[nameof(Range)]?.ToObject<object[]>(),
158        ActualName = obj[nameof(ActualName)]?.ToString()
159      };
160    }
161    #endregion
162  }
163}
Note: See TracBrowser for help on using the repository browser.