using System; using System.Collections.Generic; using System.Linq; using HeuristicLab.Core; namespace HeuristicLab.JsonInterface { /// /// Class for handling json converters. /// public class JsonItemConverter : IJsonItemConverter { #region Properties private IDictionary Converters { get; set; } = new Dictionary(); private IDictionary InjectCache { get; set; } = new Dictionary(); private IDictionary ExtractCache { get; set; } = new Dictionary(); public int Priority => throw new NotImplementedException(); public Type ConvertableType => throw new NotImplementedException(); #endregion /// /// GetConverter a converter for a specific type. /// /// The type for which the converter will be selected. /// An IJsonItemConverter object. public IJsonItemConverter GetConverter(Type type) { IList possibleConverters = new List(); foreach (var x in Converters) if (CompareTypes(type, x.Key)) possibleConverters.Add(x.Value); if(possibleConverters.Count > 0) { IJsonItemConverter best = possibleConverters.First(); foreach (var x in possibleConverters) { if (x.Priority > best.Priority) best = x; } return best; } return null; } public void Inject(IItem item, IJsonItem data, IJsonItemConverter root) { if (item != null && !InjectCache.ContainsKey(item.GetHashCode())) { IJsonItemConverter converter = GetConverter(item.GetType()); if(converter != null) converter.Inject(item, data, root); InjectCache.Add(item.GetHashCode(), data); } } public IJsonItem Extract(IItem item, IJsonItemConverter root) { int hash = item.GetHashCode(); if (ExtractCache.TryGetValue(hash, out IJsonItem val)) return val; else { IJsonItemConverter converter = GetConverter(item.GetType()); if (converter == null) return new UnsupportedJsonItem(); IJsonItem tmp = converter.Extract(item, root); ExtractCache.Add(hash, tmp); return tmp; } } public static void Inject(IItem item, IJsonItem data) { IJsonItemConverter c = JsonItemConverterFactory.Create(); c.Inject(item, data, c); } public static IJsonItem Extract(IItem item) { IJsonItemConverter c = JsonItemConverterFactory.Create(); return c.Extract(item, c); } /// /// Static constructor for default converter configuration. /// internal JsonItemConverter(IDictionary converters) { Converters = converters; } private bool CompareGenericTypes(Type t1, Type t2) => (t1.IsGenericType && t1.GetGenericTypeDefinition() == t2) /*|| (t2.IsGenericType && t2.GetGenericTypeDefinition() == t1)*/; private bool CompareTypes(Type t1, Type t2) => t1 == t2 || /*t1.IsAssignableFrom(t2) ||*/ t1.GetInterfaces().Any( i => i == t2 || CompareGenericTypes(i, t2) ) || CompareGenericTypes(t1, t2); } }