Free cookie consent management tool by TermsFeed Policy Generator

source: branches/3026_IntegrationIntoSymSpace/HeuristicLab.JsonInterface/JsonTemplateInstantiator.cs @ 17410

Last change on this file since 17410 was 17410, checked in by dpiringe, 4 years ago

#3026:

  • deleted JsonItemArrayControl and JsonItemDefaultControl
  • redesigned architecture for JsonItem: now there are different types of JsonItem (IntJsonItem, BoolJsonItem, ...) -> for better type safety and expandability
  • fixed bug in BaseConverter for GetMinValue and GetMaxValue for IntValue, but ignored for other value types (DoubleValue, DateTimeValue, ...) because the redesign of JsonItem-Architecture can make these two methods obsolet soon
  • fixed bug in JsonItemConverter to prevent null pointer exceptions
  • refactored value and range converters -> removed complicated generic ValueTypeValueConverter and ValueRangeConverter and implemented the necessary methods directly in concrete classes (improves readability and removes the need of reflection)
  • redesigned view handling in OptimizerIntegration -> dynamically seaches for JsonItemVMBase implementations, which are connected with a view
    • this enables better scaling with more user controls
  • JsonItemVMBase implements MVVM architecture
File size: 5.8 KB
Line 
1using System;
2using System.Collections;
3using System.Collections.Generic;
4using System.IO;
5using System.Linq;
6using System.Reflection;
7using System.Text;
8using System.Threading.Tasks;
9using HEAL.Attic;
10using HeuristicLab.Core;
11using HeuristicLab.Data;
12using HeuristicLab.Optimization;
13using Newtonsoft.Json.Linq;
14
15namespace HeuristicLab.JsonInterface {
16  /// <summary>
17  /// Static class to instantiate an IAlgorithm object with a json interface template and config.
18  /// </summary>
19  public static class JsonTemplateInstantiator {
20    private struct InstData {
21      public JToken Template { get; set; }
22      public JArray Config { get; set; }
23      public IDictionary<string, IJsonItem> Objects { get; set; }
24      public IOptimizer Optimizer { get; set; }
25    }
26
27    /// <summary>
28    /// Instantiate an IAlgorithm object with a template and config.
29    /// </summary>
30    /// <param name="templateFile">Template file (json), generated with JCGenerator.</param>
31    /// <param name="configFile">Config file (json) for the template.</param>
32    /// <returns>confugrated IOptimizer object</returns>
33    public static IOptimizer Instantiate(string templateFile, string configFile = "") {
34      InstData instData = new InstData() {
35        Objects = new Dictionary<string, IJsonItem>()
36      };
37
38      // parse template and config files
39      instData.Template = JToken.Parse(File.ReadAllText(templateFile));
40      if(!string.IsNullOrEmpty(configFile))
41        instData.Config = JArray.Parse(File.ReadAllText(configFile));
42
43      // extract metadata information
44      string optimizerName = instData.Template[Constants.Metadata][Constants.Optimizer].ToString();
45      string hLFileLocation = instData.Template[Constants.Metadata][Constants.HLFileLocation].ToString();
46
47      // deserialize hl file
48      ProtoBufSerializer serializer = new ProtoBufSerializer();
49      IOptimizer optimizer = (IOptimizer)serializer.Deserialize(hLFileLocation);
50      instData.Optimizer = optimizer;
51
52      // collect all parameterizedItems from template
53      CollectParameterizedItems(instData);
54     
55      // if config != null -> merge Template and Config
56      if (instData.Config != null)
57        MergeTemplateWithConfig(instData);
58
59      // get algorthm data and object
60      IJsonItem optimizerData = instData.Objects[optimizerName];
61
62      // inject configuration
63      JsonItemConverter.Inject(optimizer, optimizerData);
64
65      return optimizer;
66    }
67
68    #region Helper
69
70    private static object GetValueFromJObject(JObject obj) {
71      object val = obj[nameof(IJsonItem.Value)]?.ToObject<object>();
72      if (val is JContainer jContainer) // for resolving array values
73        val = jContainer.ToObject<object[]>();
74
75      return val;
76    }
77
78    private static void CollectParameterizedItems(InstData instData) {
79      //JCGenerator generator = new JCGenerator();
80      //IEnumerable<IJsonItem> items = generator.FetchJsonItems(instData.Optimizer);
81      IJsonItem root = JsonItemConverter.Extract(instData.Optimizer);
82      instData.Objects.Add(root.Path, root);
83
84      foreach (JObject obj in instData.Template[Constants.Parameters]) {
85        string[] pathParts = obj.Property("Path").Value.ToString().Split('.');
86        IJsonItem tmp = root;
87        IJsonItem old = null;
88        for(int i = 1; i < pathParts.Length; ++i) {
89          foreach(var c in tmp.Children) {
90            if (c.Name == pathParts[i])
91              tmp = c;
92          }
93          if (old == tmp)
94            throw new Exception($"Invalid path '{string.Join(".", pathParts)}'");
95          else old = tmp;
96        }
97        tmp.Value = GetValueFromJObject(obj);
98        tmp.Range = obj[nameof(IJsonItem.Range)]?.ToObject<object[]>();
99        tmp.ActualName = obj[nameof(IJsonItem.ActualName)]?.ToString();
100        instData.Objects.Add(tmp.Path, tmp);
101      }
102
103
104      /*
105      foreach (JObject item in instData.Template[Constants.Parameters]) {
106        string[] pathParts = item.Property("Path").Value.ToString().Split('.');
107       
108        // rebuilds object tree
109        IJsonItem parent = null;
110        StringBuilder partialPath = new StringBuilder();
111        for(int i = 0; i < pathParts.Length-1; ++i) {
112          partialPath.Append(pathParts[i]);
113          IJsonItem tmp = null;
114          if (instData.Objects.TryGetValue(partialPath.ToString(), out IJsonItem value)) {
115            tmp = value;
116          } else {
117            tmp = new JsonItem() { Name = pathParts[i] };
118            if (parent != null) parent.AddChilds(tmp);
119            instData.Objects.Add(partialPath.ToString(), tmp);
120          }
121          partialPath.Append(".");
122          parent = tmp;
123        }
124
125        IJsonItem data = JsonItem.BuildJsonItem(item);
126        parent.AddChilds(data);
127        instData.Objects.Add(data.Path, data);
128      }*/
129    }
130   
131    private static void MergeTemplateWithConfig(InstData instData) {
132      foreach (JObject obj in instData.Config) {
133        // build item from config object
134        //IJsonItem item = JsonItem.BuildJsonItem(obj);
135        string path = obj.Property("Path").Value.ToString();
136        // override default value
137        if (instData.Objects.TryGetValue(path, out IJsonItem param)) {
138          param.Value = GetValueFromJObject(obj);
139          // override ActualName (for LookupParameters)
140          if (param.ActualName != null)
141            param.ActualName = obj[nameof(IJsonItem.ActualName)]?.ToString();
142        } else throw new InvalidDataException($"No parameter with path='{path}' defined!");
143      }
144    }
145
146    private static IJsonItem GetData(string key, InstData instData)
147    {
148      if (instData.Objects.TryGetValue(key, out IJsonItem value))
149        return value;
150      else
151        throw new InvalidDataException($"Type of item '{key}' is not defined!");
152    }
153    #endregion
154  }
155}
Note: See TracBrowser for help on using the repository browser.