Free cookie consent management tool by TermsFeed Policy Generator

source: branches/3026_IntegrationIntoSymSpace/HeuristicLab.JsonInterface/JsonItemConverter.cs @ 17478

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

#3026:

  • removed type extension for type comparison (was a complicated comparison, which should not be a public extension method for Type)
    • comparison is now located (as private method) in JsonItemConverter
    • also simplified it a lot (did some tests to measure the relevance of specific checks -> last check got completely removed)
File size: 3.6 KB
RevLine 
[17263]1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using System.Threading.Tasks;
6using HeuristicLab.Core;
7using HeuristicLab.Data;
[17371]8using HeuristicLab.PluginInfrastructure;
9using HEAL.Attic;
10using System.Collections;
[17263]11
[17284]12namespace HeuristicLab.JsonInterface {
[17353]13  /// <summary>
[17394]14  /// Class for handling json converters.
[17353]15  /// </summary>
[17394]16  public class JsonItemConverter : IJsonItemConverter {
[17263]17   
[17394]18    #region Properties
19    private IDictionary<Type, IJsonItemConverter> Converters { get; set; }
20      = new Dictionary<Type, IJsonItemConverter>();
[17263]21
[17439]22    private IDictionary<int, IJsonItem> InjectCache { get; set; }
[17406]23      = new Dictionary<int, IJsonItem>();
[17371]24
[17439]25    private IDictionary<int, IJsonItem> ExtractCache { get; set; }
26      = new Dictionary<int, IJsonItem>();
27
[17394]28    public int Priority => throw new NotImplementedException();
[17371]29
[17394]30    public Type ConvertableType => throw new NotImplementedException();
31    #endregion
[17263]32
[17353]33    /// <summary>
[17394]34    /// GetConverter a converter for a specific type.
[17353]35    /// </summary>
36    /// <param name="type">The type for which the converter will be selected.</param>
37    /// <returns>An IJsonItemConverter object.</returns>
[17394]38    public IJsonItemConverter GetConverter(Type type) {
39      IList<IJsonItemConverter> possibleConverters = new List<IJsonItemConverter>();
[17353]40     
41      foreach (var x in Converters)
[17478]42        if (CompareTypes(type, x.Key))
[17282]43          possibleConverters.Add(x.Value);
[17266]44
[17282]45      if(possibleConverters.Count > 0) {
[17394]46        IJsonItemConverter best = possibleConverters.First();
[17282]47        foreach (var x in possibleConverters) {
48          if (x.Priority > best.Priority)
49            best = x;
[17266]50        }
[17394]51        return best;
[17266]52      }
[17394]53      return null;
[17263]54    }
[17394]55   
[17406]56    public void Inject(IItem item, IJsonItem data, IJsonItemConverter root) {
[17439]57      if (item != null && !InjectCache.ContainsKey(item.GetHashCode())) {
[17394]58        IJsonItemConverter converter = GetConverter(item.GetType());
59        if(converter != null) converter.Inject(item, data, root);
[17439]60        InjectCache.Add(item.GetHashCode(), data);
[17394]61      }
62    }
[17263]63
[17406]64    public IJsonItem Extract(IItem item, IJsonItemConverter root) {
[17394]65      int hash = item.GetHashCode();
[17439]66      if (ExtractCache.TryGetValue(hash, out IJsonItem val))
[17394]67        return val;
68      else {
69        IJsonItemConverter converter = GetConverter(item.GetType());
70        if (converter == null) return new UnsupportedJsonItem();
[17406]71        IJsonItem tmp = GetConverter(item.GetType()).Extract(item, root);
[17439]72        ExtractCache.Add(hash, tmp);
[17394]73        return tmp;
74      }
75    }
76   
[17406]77    public static void Inject(IItem item, IJsonItem data) {
[17394]78      IJsonItemConverter c = JsonItemConverterFactory.Create();
79      c.Inject(item, data, c);
80    }
[17263]81
[17406]82    public static IJsonItem Extract(IItem item) {
[17394]83      IJsonItemConverter c = JsonItemConverterFactory.Create();
84      return c.Extract(item, c);
85    }
[17263]86
[17353]87    /// <summary>
88    /// Static constructor for default converter configuration.
89    /// </summary>
[17394]90    internal JsonItemConverter(IDictionary<Type, IJsonItemConverter> converters) {
91      Converters = converters;
[17263]92    }
[17478]93
94    private bool CompareGenericTypes(Type t1, Type t2) =>
95      (t1.IsGenericType && t1.GetGenericTypeDefinition() == t2) ||
96      (t2.IsGenericType && t2.GetGenericTypeDefinition() == t1);
97
98    private bool CompareTypes(Type t1, Type t2) =>
99      t1 == t2 || t1.IsAssignableFrom(t2) ||
100      t1.GetInterfaces().Any(
101        i => i == t2 || CompareGenericTypes(i, t2)
102      ) ||
103      CompareGenericTypes(t1, t2);
[17263]104  }
105}
Note: See TracBrowser for help on using the repository browser.