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 = GetConverter(item.GetType()).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);
}
}