Free cookie consent management tool by TermsFeed Policy Generator

source: branches/3026_IntegrationIntoSymSpace/HeuristicLab.JsonInterface/JCInstantiator.cs @ 17354

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

#3026:

  • relocated BuildJsonItem from JCInstantiator into JsonItem
  • in JsonItem: removed JContainer usage in setter for Value (now in BuildJsonItem)
File size: 5.9 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 HeuristicLab.Core;
10using HeuristicLab.Data;
11using HeuristicLab.Optimization;
12using HeuristicLab.SequentialEngine;
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 JCInstantiator {
20    private struct InstData {
21      public JToken Template { get; set; }
22      public JArray Config { get; set; }
23      public Dictionary<string, string> TypeList { get; set; }
24      public IDictionary<string, JsonItem> ParameterizedItems { get; set; }
25      public IDictionary<string, JsonItem> ConfigurableItems { get; set; }
26    }
27
28    /// <summary>
29    /// Instantiate an IAlgorithm object with a template and config.
30    /// </summary>
31    /// <param name="templateFile">Template file (json), generated with JCGenerator.</param>
32    /// <param name="configFile">Config file (json) for the template.</param>
33    /// <returns>confugrated IAlgorithm object</returns>
34    public static IAlgorithm Instantiate(string templateFile, string configFile = "") {
35      InstData instData = new InstData() {
36        TypeList = new Dictionary<string, string>(),
37        ParameterizedItems = new Dictionary<string, JsonItem>(),
38        ConfigurableItems = new Dictionary<string, JsonItem>()
39      };
40
41      //1. Parse Template and Config files
42      instData.Template = JToken.Parse(File.ReadAllText(templateFile));
43      if(!string.IsNullOrEmpty(configFile))
44        instData.Config = JArray.Parse(File.ReadAllText(configFile));
45      instData.TypeList = instData.Template[Constants.Types].ToObject<Dictionary<string, string>>();
46      string algorithmName = instData.Template[Constants.Metadata][Constants.Algorithm].ToString();
47      string problemName = instData.Template[Constants.Metadata][Constants.Problem].ToString();
48
49      //2. Collect all parameterizedItems from template
50      CollectParameterizedItems(instData);
51
52      //3. select all ConfigurableItems
53      SelectConfigurableItems(instData);
54
55      //4. if config != null -> merge Template and Config
56      if (instData.Config != null)
57        MergeTemplateWithConfig(instData);
58
59      //5. resolve the references between parameterizedItems
60      ResolveReferences(instData);
61
62      //6. get algorthm data and object
63      JsonItem algorithmData = GetData(algorithmName, instData);
64      IAlgorithm algorithm = CreateObject<IAlgorithm>(algorithmData, instData);
65
66      //7. get problem data and object
67      JsonItem problemData = GetData(problemName, instData);
68      IProblem problem = CreateObject<IProblem>(problemData, instData);
69      algorithm.Problem = problem;
70
71      //8. inject configuration
72      JsonItemConverter.Inject(algorithm, algorithmData);
73      JsonItemConverter.Inject(problem, problemData);
74
75      // TODO: let the engine be configurable
76      if (algorithm is EngineAlgorithm)
77        algorithm.Cast<EngineAlgorithm>().Engine = new SequentialEngine.SequentialEngine();
78
79      return algorithm;
80    }
81
82    #region Helper
83    private static void CollectParameterizedItems(InstData instData) {
84      foreach (JObject item in instData.Template[Constants.Objects]) {
85        JsonItem data = JsonItem.BuildJsonItem(item, instData.TypeList);
86        instData.ParameterizedItems.Add(data.Path, data);
87      }
88    }
89
90    private static void SelectConfigurableItems(InstData instData) {
91      foreach (var item in instData.ParameterizedItems.Values) {
92        if (item.Parameters != null)
93          AddConfigurableItems(item.Parameters, instData);
94
95        if (item.Operators != null)
96          AddConfigurableItems(item.Operators, instData);
97      }
98    }
99
100    private static void AddConfigurableItems(IEnumerable<JsonItem> items, InstData instData) {
101      foreach (var item in items)
102        if (item.IsConfigurable)
103          instData.ConfigurableItems.Add(item.Path, item);
104    }
105
106    private static void ResolveReferences(InstData instData) {
107      foreach(var x in instData.ParameterizedItems.Values)
108        foreach (var p in x.Parameters)
109          if (p.Value is string) {
110            string key = p.Path;
111            if (p.Range != null)
112              key = $"{p.Path}.{p.Value.Cast<string>()}";
113
114            if (instData.ParameterizedItems.TryGetValue(key, out JsonItem value))
115              p.Reference = value;
116          }
117    }
118
119    private static void MergeTemplateWithConfig(InstData instData) {
120      foreach (JObject obj in instData.Config) {
121        // build item from config object
122        JsonItem item = JsonItem.BuildJsonItem(obj, instData.TypeList);
123        // override default value
124        if (instData.ConfigurableItems.TryGetValue(item.Path, out JsonItem param)) {
125          param.Value = item.Value;
126          // override ActualName (for LookupParameters)
127          if (param.ActualName != null)
128            param.ActualName = item.ActualName;
129        } else throw new InvalidDataException($"No {Constants.FreeParameters.Trim('s')} with path='{item.Path}' defined!");
130      }
131    }
132
133    private static JsonItem GetData(string key, InstData instData)
134    {
135      if (instData.ParameterizedItems.TryGetValue(key, out JsonItem value))
136        return value;
137      else
138        throw new InvalidDataException($"Type of item '{key}' is not defined!");
139    }
140
141    private static T CreateObject<T>(JsonItem data, InstData instData) {
142      if (instData.TypeList.TryGetValue(data.Name, out string typeName)) {
143        Type type = Type.GetType(typeName);
144        return (T)Activator.CreateInstance(type);
145      } else throw new TypeLoadException($"Cannot find AssemblyQualifiedName for {data.Name}.");
146    }
147    #endregion
148  }
149}
Note: See TracBrowser for help on using the repository browser.