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

Last change on this file since 17435 was 17435, checked in by dpiringe, 2 years ago

#3026:

  • set read-only to false for name input (in JsonItemBaseControl)
  • result items now can be selected/deselected in export dialog
  • removed metadata.problem property and renamed metadata.optimizer property to TemplateName in json template
  • fixed bug with wrong description for result items in AlgorithmConverter
  • refactored a lot of code in JCGenerator and added the need for a directory path (location for the template files)
  • fixed a null reference bug in JsonItemValidator (cannot try to iterate through possible null referenced collections)
File size: 4.3 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.TemplateName].ToString();
45      string hLFileLocation = Path.GetFullPath(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      IJsonItem root = JsonItemConverter.Extract(instData.Optimizer);
75      instData.Objects.Add(root.Path, root);
76
77      foreach (JObject obj in instData.Template[Constants.Parameters]) {
78        string[] pathParts = obj.Property("Path").Value.ToString().Split('.');
79        IJsonItem tmp = root;
80        IJsonItem old = null;
81        for(int i = 1; i < pathParts.Length; ++i) {
82          foreach(var c in tmp.Children) {
83            if (c.Name == pathParts[i])
84              tmp = c;
85          }
86          if (old == tmp)
87            throw new Exception($"Invalid path '{string.Join(".", pathParts)}'");
88          else old = tmp;
89        }
90        tmp.Value = GetValueFromJObject(obj);
91        tmp.Range = obj[nameof(IJsonItem.Range)]?.ToObject<object[]>();
92        tmp.ActualName = obj[nameof(IJsonItem.ActualName)]?.ToString();
93        instData.Objects.Add(tmp.Path, tmp);
94      }
95    }
96   
97    private static void MergeTemplateWithConfig(InstData instData) {
98      foreach (JObject obj in instData.Config) {
99        // build item from config object
100        string path = obj.Property("Path").Value.ToString();
101        // override default value
102        if (instData.Objects.TryGetValue(path, out IJsonItem param)) {
103          param.Value = GetValueFromJObject(obj);
104          // override ActualName (for LookupParameters)
105          if (param.ActualName != null)
106            param.ActualName = obj[nameof(IJsonItem.ActualName)]?.ToString();
107        } else throw new InvalidDataException($"No parameter with path='{path}' defined!");
108      }
109    }
110    #endregion
111  }
112}
Note: See TracBrowser for help on using the repository browser.