Free cookie consent management tool by TermsFeed Policy Generator

source: branches/3026_IntegrationIntoSymSpace/HeuristicLab.JsonInterface/JCGenerator.cs @ 17353

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

#3026:

  • relocated GetMaxValue and GetMinValue from ValueTypeValueConverter into BaseConverter
  • fixed a bug in ConstrainedValueParameterConverter (from GetType().Name to ToString())
  • printing now PrettyNames for types
  • added comments
  • added StorableConverter.cs (not finished, maybe not a good converter)
  • added ValueRangeConverter.cs for DoubleRange and IntRange
  • added ParameterConverter.cs for default parameter conversion
File size: 5.5 KB
RevLine 
[17263]1using System;
2using System.Collections.Generic;
3using System.Linq;
[17353]4using HeuristicLab.Common;
[17263]5using HeuristicLab.Core;
6using HeuristicLab.Data;
7using HeuristicLab.Optimization;
8using Newtonsoft.Json;
9using Newtonsoft.Json.Linq;
10
[17284]11namespace HeuristicLab.JsonInterface {
[17353]12  /// <summary>
13  /// Static class to generate json interface templates.
14  /// </summary>
[17349]15  public static class JCGenerator {
16    private struct GenData {
17      public JObject Template { get; set; }
18      public IDictionary<string, string> TypeList { get; set; }
19      public JArray JsonItems { get; set; }
20    }
[17353]21   
[17349]22    public static string GenerateTemplate(IAlgorithm algorithm) {
23      // data container
24      GenData genData = new GenData() {
25        Template = JObject.Parse(Constants.Template),
26        TypeList = new Dictionary<string, string>(),
27        JsonItems = new JArray()
28      };
29
[17330]30      // 1.1. extract JsonItem, save the name in the metadata section of the
31      // template and save it an JArray incl. all parameters of the JsonItem,
32      // which have parameters aswell
[17349]33      AddInstantiableIItem(Constants.Algorithm, algorithm, genData);
[17353]34      //IsConvertable(algorithm, true);
35      if (algorithm.Problem != null) // 1.2. only when an problem exists
[17349]36        AddInstantiableIItem(Constants.Problem, algorithm.Problem, genData);
[17330]37
38      // 2. save the JArray with JsonItems (= IParameterizedItems)
[17349]39      genData.Template[Constants.Objects] = genData.JsonItems;
[17330]40      // 3. save the types of the JsonItems (for instatiation)
[17349]41      genData.Template[Constants.Types] = JObject.FromObject(genData.TypeList);
[17330]42      // 4. serialize template and return string
[17349]43      return CustomJsonWriter.Serialize(genData.Template);
[17330]44    }
[17349]45   
[17330]46    #region Helper
[17353]47    private static bool IsConvertable(object obj, bool throwException = false) {
[17349]48      bool tmp = ConvertableAttribute.IsConvertable(obj);
49      if (throwException && tmp)
[17353]50        throw new NotSupportedException($"Type {obj.GetType().GetPrettyName(false)} is not convertable!");
[17349]51      return tmp;
52    }
[17353]53
[17349]54    private static void AddInstantiableIItem(string metaDataTagName, IItem item, GenData genData) {
[17330]55      JsonItem jsonItem = JsonItemConverter.Extract(item);
[17349]56      genData.Template[Constants.Metadata][metaDataTagName] = item.ItemName;
57      PopulateJsonItems(jsonItem, genData);
[17330]58    }
59
[17349]60    // serializes ParameterizedItems and saves them in list "JsonItems".
61    private static void PopulateJsonItems(JsonItem item, GenData genData) {
[17283]62      if (item.Parameters != null) {
[17330]63        if (item.Range == null)
[17349]64          genData.JsonItems.Add(Serialize(item, genData));
[17283]65        foreach (var p in item.Parameters)
[17349]66          if (p.IsParameterizedItem)
67            PopulateJsonItems(p, genData);
[17280]68      }
69    }
70
[17349]71    private static JObject Serialize(JsonItem item, GenData genData) {
[17283]72      JObject obj = JObject.FromObject(item, Settings());
[17287]73      obj[Constants.StaticParameters] = obj[nameof(JsonItem.Parameters)];
74      obj[Constants.FreeParameters] = obj[nameof(JsonItem.Parameters)];
[17280]75
[17287]76      obj.Property(nameof(JsonItem.Parameters))?.Remove();
[17330]77      RefactorFreeParameters(obj);
[17280]78      RefactorStaticParameters(obj);
79
[17342]80      obj.Property(nameof(JsonItem.Value))?.Remove();
[17287]81      obj.Property(nameof(JsonItem.Type))?.Remove();
[17280]82
[17353]83      if(!genData.TypeList.ContainsKey(item.Path))
84        genData.TypeList.Add(item.Path, item.Type);
[17280]85      return obj;
86    }
87
[17349]88    // deletes unnecessary properties for free parameters.
89    private static void RefactorFreeParameters(JToken token) {
[17266]90      IList<JObject> objToRemove = new List<JObject>();
91      TransformNodes(x => {
[17283]92        var p = x.ToObject<JsonItem>();
[17353]93        x.Property(nameof(JsonItem.Type))?.Remove();
94        x.Property(nameof(JsonItem.Parameters))?.Remove();
95        /*
[17342]96        if ((p.Value == null || (p.Value != null && p.Value.GetType() == typeof(string) && p.Range == null) && p.ActualName == null)) {
[17266]97          objToRemove.Add(x);
98        } else {
[17287]99          x.Property(nameof(JsonItem.Type))?.Remove();
100          x.Property(nameof(JsonItem.Parameters))?.Remove();
[17353]101        }*/
[17287]102      }, token[Constants.FreeParameters]);
[17353]103      //foreach (var x in objToRemove) x.Remove();
[17263]104    }
105
[17349]106    // deletes unnecessary properties for static parameters.
107    private static void RefactorStaticParameters(JToken token) {
[17266]108      IList<JObject> objToRemove = new List<JObject>();
109      TransformNodes(x => {
[17283]110        var p = x.ToObject<JsonItem>();
[17287]111        x.Property(nameof(JsonItem.Range))?.Remove();
112        x.Property(nameof(JsonItem.Operators))?.Remove();
113        x.Property(nameof(JsonItem.Parameters))?.Remove();
114        x.Property(nameof(JsonItem.Type))?.Remove();
[17349]115        //TODO: maybe allow JsonItems with Value==null in static parameters too?
116        if (p.Value == null) objToRemove.Add(x);
[17287]117      }, token[Constants.StaticParameters]);
[17353]118      //foreach (var x in objToRemove) x.Remove();
[17263]119    }
120
[17349]121    /// <summary>
122    /// Settings for the json serialization.
123    /// </summary>
124    /// <returns>A configured JsonSerializer.</returns>
125    private static JsonSerializer Settings() => new JsonSerializer() {
[17263]126      TypeNameHandling = TypeNameHandling.None,
[17280]127      NullValueHandling = NullValueHandling.Ignore,
128      ReferenceLoopHandling = ReferenceLoopHandling.Serialize
[17263]129    };
130
[17349]131    private static void TransformNodes(Action<JObject> action, params JToken[] tokens) {
[17280]132      foreach(JObject obj in tokens.SelectMany(x => x.Children<JObject>()))
[17263]133        action(obj);
134    }
135    #endregion
136  }
137}
Note: See TracBrowser for help on using the repository browser.