Free cookie consent management tool by TermsFeed Policy Generator

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

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

#3026:

  • added initial VM (ArrayValueVM) and control for array values (JsonItemArrayValueControl)
  • new types of JsonItems for better type safety:
    • for arrays: DoubleArrayJsonItem, IntArrayJsonItem, BoolArrayJsonItem
    • for matrix: DoubleMatrixJsonItem, IntMatrixJsonItem, BoolMatrixJsonItem
  • refactored ValueTypeArrayConverter and ValueTypeMatrixConverter -> better type safety with new JsonItems
  • enhanced StringValueVM and implemented JsonItemValidValuesControl with MVVM architecture
  • the VM of JsonItemBaseControl is now protected (was private)
  • improved JsonItem<V,R> -> now handles JTokens correctly
File size: 5.7 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      obj[nameof(IJsonItem.Value)]?.ToObject<object>();
72
73    private static void CollectParameterizedItems(InstData instData) {
74      //JCGenerator generator = new JCGenerator();
75      //IEnumerable<IJsonItem> items = generator.FetchJsonItems(instData.Optimizer);
76      IJsonItem root = JsonItemConverter.Extract(instData.Optimizer);
77      instData.Objects.Add(root.Path, root);
78
79      foreach (JObject obj in instData.Template[Constants.Parameters]) {
80        string[] pathParts = obj.Property("Path").Value.ToString().Split('.');
81        IJsonItem tmp = root;
82        IJsonItem old = null;
83        for(int i = 1; i < pathParts.Length; ++i) {
84          foreach(var c in tmp.Children) {
85            if (c.Name == pathParts[i])
86              tmp = c;
87          }
88          if (old == tmp)
89            throw new Exception($"Invalid path '{string.Join(".", pathParts)}'");
90          else old = tmp;
91        }
92        tmp.Value = GetValueFromJObject(obj);
93        tmp.Range = obj[nameof(IJsonItem.Range)]?.ToObject<object[]>();
94        tmp.ActualName = obj[nameof(IJsonItem.ActualName)]?.ToString();
95        instData.Objects.Add(tmp.Path, tmp);
96      }
97
98
99      /*
100      foreach (JObject item in instData.Template[Constants.Parameters]) {
101        string[] pathParts = item.Property("Path").Value.ToString().Split('.');
102       
103        // rebuilds object tree
104        IJsonItem parent = null;
105        StringBuilder partialPath = new StringBuilder();
106        for(int i = 0; i < pathParts.Length-1; ++i) {
107          partialPath.Append(pathParts[i]);
108          IJsonItem tmp = null;
109          if (instData.Objects.TryGetValue(partialPath.ToString(), out IJsonItem value)) {
110            tmp = value;
111          } else {
112            tmp = new JsonItem() { Name = pathParts[i] };
113            if (parent != null) parent.AddChilds(tmp);
114            instData.Objects.Add(partialPath.ToString(), tmp);
115          }
116          partialPath.Append(".");
117          parent = tmp;
118        }
119
120        IJsonItem data = JsonItem.BuildJsonItem(item);
121        parent.AddChilds(data);
122        instData.Objects.Add(data.Path, data);
123      }*/
124    }
125   
126    private static void MergeTemplateWithConfig(InstData instData) {
127      foreach (JObject obj in instData.Config) {
128        // build item from config object
129        //IJsonItem item = JsonItem.BuildJsonItem(obj);
130        string path = obj.Property("Path").Value.ToString();
131        // override default value
132        if (instData.Objects.TryGetValue(path, out IJsonItem param)) {
133          param.Value = GetValueFromJObject(obj);
134          // override ActualName (for LookupParameters)
135          if (param.ActualName != null)
136            param.ActualName = obj[nameof(IJsonItem.ActualName)]?.ToString();
137        } else throw new InvalidDataException($"No parameter with path='{path}' defined!");
138      }
139    }
140
141    private static IJsonItem GetData(string key, InstData instData)
142    {
143      if (instData.Objects.TryGetValue(key, out IJsonItem value))
144        return value;
145      else
146        throw new InvalidDataException($"Type of item '{key}' is not defined!");
147    }
148    #endregion
149  }
150}
Note: See TracBrowser for help on using the repository browser.