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

Last change on this file since 17478 was 17478, checked in by dpiringe, 14 months 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
Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using System.Threading.Tasks;
6using HeuristicLab.Core;
7using HeuristicLab.Data;
8using HeuristicLab.PluginInfrastructure;
9using HEAL.Attic;
10using System.Collections;
11
12namespace HeuristicLab.JsonInterface {
13  /// <summary>
14  /// Class for handling json converters.
15  /// </summary>
16  public class JsonItemConverter : IJsonItemConverter {
17   
18    #region Properties
19    private IDictionary<Type, IJsonItemConverter> Converters { get; set; }
20      = new Dictionary<Type, IJsonItemConverter>();
21
22    private IDictionary<int, IJsonItem> InjectCache { get; set; }
23      = new Dictionary<int, IJsonItem>();
24
25    private IDictionary<int, IJsonItem> ExtractCache { get; set; }
26      = new Dictionary<int, IJsonItem>();
27
28    public int Priority => throw new NotImplementedException();
29
30    public Type ConvertableType => throw new NotImplementedException();
31    #endregion
32
33    /// <summary>
34    /// GetConverter a converter for a specific type.
35    /// </summary>
36    /// <param name="type">The type for which the converter will be selected.</param>
37    /// <returns>An IJsonItemConverter object.</returns>
38    public IJsonItemConverter GetConverter(Type type) {
39      IList<IJsonItemConverter> possibleConverters = new List<IJsonItemConverter>();
40     
41      foreach (var x in Converters)
42        if (CompareTypes(type, x.Key))
43          possibleConverters.Add(x.Value);
44
45      if(possibleConverters.Count > 0) {
46        IJsonItemConverter best = possibleConverters.First();
47        foreach (var x in possibleConverters) {
48          if (x.Priority > best.Priority)
49            best = x;
50        }
51        return best;
52      }
53      return null;
54    }
55   
56    public void Inject(IItem item, IJsonItem data, IJsonItemConverter root) {
57      if (item != null && !InjectCache.ContainsKey(item.GetHashCode())) {
58        IJsonItemConverter converter = GetConverter(item.GetType());
59        if(converter != null) converter.Inject(item, data, root);
60        InjectCache.Add(item.GetHashCode(), data);
61      }
62    }
63
64    public IJsonItem Extract(IItem item, IJsonItemConverter root) {
65      int hash = item.GetHashCode();
66      if (ExtractCache.TryGetValue(hash, out IJsonItem val))
67        return val;
68      else {
69        IJsonItemConverter converter = GetConverter(item.GetType());
70        if (converter == null) return new UnsupportedJsonItem();
71        IJsonItem tmp = GetConverter(item.GetType()).Extract(item, root);
72        ExtractCache.Add(hash, tmp);
73        return tmp;
74      }
75    }
76   
77    public static void Inject(IItem item, IJsonItem data) {
78      IJsonItemConverter c = JsonItemConverterFactory.Create();
79      c.Inject(item, data, c);
80    }
81
82    public static IJsonItem Extract(IItem item) {
83      IJsonItemConverter c = JsonItemConverterFactory.Create();
84      return c.Extract(item, c);
85    }
86
87    /// <summary>
88    /// Static constructor for default converter configuration.
89    /// </summary>
90    internal JsonItemConverter(IDictionary<Type, IJsonItemConverter> converters) {
91      Converters = converters;
92    }
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);
104  }
105}
Note: See TracBrowser for help on using the repository browser.