Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 18040 was 18040, checked in by dpiringe, 3 years ago

#3026

  • added some test cases for JsonInterface
  • deleted the HeuristicLab namespace part in a lot of test classes (this caused a lot of compile errors)
  • enhanced the OS path logic for absolute and relative path in JsonTemplateGenerator and JsonTemplateInstantiator
  • fixed a bug in ValueParameterConverter -> the injection logic was not working correctly
  • changed the folder determination in Main.cs for the HeadlessRun method
  • added a new abstract type of JsonItem IntervalRestrictedJsonItem for JsonItems with a need of Minimum and Maximum bounds but without a specific value
    • changed in RangedJsonItem the base class from IntervalRestrictedValueJsonItem to IntervalRestrictedJsonItem
File size: 5.5 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.IO;
4using System.Linq;
5using System.Text.RegularExpressions;
6using HEAL.Attic;
7using HeuristicLab.Optimization;
8using Newtonsoft.Json.Linq;
9
10namespace HeuristicLab.JsonInterface {
11  public readonly struct InstantiatorResult {
12    public InstantiatorResult(IOptimizer optimizer, IEnumerable<IResultJsonItem> configuredResultItems) {
13      Optimizer = optimizer;
14      ConfiguredResultItems = configuredResultItems;
15    }
16
17    public IOptimizer Optimizer { get; }
18    public IEnumerable<IResultJsonItem> ConfiguredResultItems { get; }
19  }
20
21
22  /// <summary>
23  /// Class to instantiate an IAlgorithm object with a json interface template and config.
24  /// </summary>
25  public class JsonTemplateInstantiator {
26
27    #region Constants
28    private const string RelativePathCurrentDirectoryRegex = @"^(\.)";
29    #endregion
30
31    #region Private Properties
32    private JToken Template { get; set; }
33    private JArray Config { get; set; }
34    private IDictionary<string, IJsonItem> Objects { get; set; } = new Dictionary<string, IJsonItem>();
35    #endregion
36
37    /// <summary>
38    /// Instantiate an IAlgorithm object with a template and config.
39    /// </summary>
40    /// <param name="templateFile">Template file (json), generated with JCGenerator.</param>
41    /// <param name="configFile">Config file (json) for the template.</param>
42    /// <returns>confugrated IOptimizer object</returns>
43    public static InstantiatorResult Instantiate(string templateFile, string configFile = null) {
44      JsonTemplateInstantiator instantiator = new JsonTemplateInstantiator();
45      return instantiator.ExecuteInstantiaton(templateFile, configFile);
46    }
47
48    #region Helper
49    private InstantiatorResult ExecuteInstantiaton(string templateFile, string configFile = null) {
50
51      #region Parse Files
52      string templateFileFullPath = Path.GetFullPath(templateFile);
53      Template = JToken.Parse(File.ReadAllText(templateFile));
54      if(!string.IsNullOrEmpty(configFile))
55        Config = JArray.Parse(File.ReadAllText(Path.GetFullPath(configFile)));
56      #endregion
57
58      // extract metadata information
59      string relativePath = Template[Constants.Metadata][Constants.HLFileLocation].ToString().Trim(); // get relative path
60      // convert to absolute path
61      if (Regex.IsMatch(relativePath, RelativePathCurrentDirectoryRegex))
62        relativePath = relativePath.Remove(0, 2); // remove first 2 chars -> indicates the current directory
63
64      string hLFileLocation = Path.Combine(Path.GetDirectoryName(templateFileFullPath), relativePath);
65      #region Deserialize HL File
66      ProtoBufSerializer serializer = new ProtoBufSerializer();
67      IOptimizer optimizer = (IOptimizer)serializer.Deserialize(hLFileLocation);
68      #endregion
69
70      // collect all parameterizedItems from template
71      CollectParameterizedItems(optimizer);
72     
73      if (Config != null)
74        MergeTemplateWithConfig();
75
76      // get algorithm root item
77      IJsonItem rootItem = Objects.First().Value;
78
79      // validation
80      ValidationResult validationResult = rootItem.GetValidator().Validate();
81      if (!validationResult.Success)
82        throw validationResult.GenerateException();
83
84      // inject configuration
85      JsonItemConverter.Inject(optimizer, rootItem);
86
87      return new InstantiatorResult(optimizer, CollectResults());
88    }
89
90    private IEnumerable<IResultJsonItem> CollectResults() {
91      IList<IResultJsonItem> res = new List<IResultJsonItem>();
92      foreach(JObject obj in Template[Constants.Results]) {
93        //string name = obj.Property("Name").Value.ToString();
94        var resultItem = new ResultJsonItem();
95        resultItem.SetJObject(obj);
96        res.Add(resultItem);
97        //res.Add(new ResultJsonItem() { Name = name });
98      }
99      return res;
100    }
101
102    private void CollectParameterizedItems(IOptimizer optimizer) {
103      IJsonItem root = JsonItemConverter.Extract(optimizer);
104      Objects.Add(root.Path, root);
105
106      foreach (JObject obj in Template[Constants.Parameters]) {
107        string path = obj.Property("Path").Value.ToString();
108        foreach(var tmp in root) {
109          if(tmp.Path == path) {
110            tmp.SetJObject(obj);
111            Objects.Add(tmp.Path, tmp);
112          }
113        }
114      }
115    }
116   
117    private void MergeTemplateWithConfig() {
118      foreach (JObject obj in Config) {
119        // build item from config object
120        var prop = obj.Property("Path");
121        if (prop == null)
122          throw new ArgumentException("Path property is missing.");
123        string path = prop.Value.ToString();
124        // override default value
125        if (Objects.TryGetValue(path, out IJsonItem param)) {
126          // remove fixed template parameter from config => dont allow to copy them from concrete config
127          // TODO: shift this into JsonItems?
128          obj.Property(nameof(IIntervalRestrictedJsonItem<int>.Minimum))?.Remove();
129          obj.Property(nameof(IIntervalRestrictedJsonItem<int>.Maximum))?.Remove();
130          obj.Property(nameof(IConcreteRestrictedJsonItem<string>.ConcreteRestrictedItems))?.Remove();
131          obj.Property(nameof(IMatrixJsonItem.ColumnsResizable))?.Remove();
132          obj.Property(nameof(IMatrixJsonItem.RowsResizable))?.Remove();
133          obj.Property(nameof(IArrayJsonItem.Resizable))?.Remove();
134          // merge
135          param.SetJObject(obj);
136        } else throw new InvalidDataException($"No parameter with path='{path}' defined!");
137      }
138    }
139    #endregion
140  }
141}
Note: See TracBrowser for help on using the repository browser.