1 | using System;
|
---|
2 | using System.Collections.Generic;
|
---|
3 | using System.Linq;
|
---|
4 | using System.Text;
|
---|
5 | using System.Threading.Tasks;
|
---|
6 | using HeuristicLab.Core;
|
---|
7 | using HeuristicLab.Data;
|
---|
8 | using HeuristicLab.PluginInfrastructure;
|
---|
9 | using HEAL.Attic;
|
---|
10 | using System.Collections;
|
---|
11 |
|
---|
12 | namespace HeuristicLab.JsonInterface {
|
---|
13 | /// <summary>
|
---|
14 | /// Static class for handling json converters.
|
---|
15 | /// </summary>
|
---|
16 | public static class JsonItemConverter {
|
---|
17 |
|
---|
18 | private struct ConverterPriorityContainer {
|
---|
19 | public IJsonItemConverter Converter { get; set; }
|
---|
20 | public int Priority { get; set; }
|
---|
21 | }
|
---|
22 |
|
---|
23 | private static IDictionary<Type, ConverterPriorityContainer> Converters { get; set; }
|
---|
24 | = new Dictionary<Type, ConverterPriorityContainer>();
|
---|
25 |
|
---|
26 | /// <summary>
|
---|
27 | /// Register a converter for a given type and priority.
|
---|
28 | /// </summary>
|
---|
29 | /// <param name="type">The type for which the converter will be selected.</param>
|
---|
30 | /// <param name="converter">The implemented converter.</param>
|
---|
31 | /// <param name="priority">The priority for the converter selection (when multiple converter match for a given type). Higher is better.</param>
|
---|
32 | public static void Register(Type type, IJsonItemConverter converter, int priority) {
|
---|
33 | if (!Converters.ContainsKey(type))
|
---|
34 | Converters.Add(type, new ConverterPriorityContainer() { Converter = converter, Priority = priority });
|
---|
35 | }
|
---|
36 |
|
---|
37 | public static void Register(string atticGuid, IJsonItemConverter converter, int priority) =>
|
---|
38 | Register(new Guid(atticGuid), converter, priority);
|
---|
39 |
|
---|
40 | public static void Register(Guid atticGuid, IJsonItemConverter converter, int priority) {
|
---|
41 | if (Mapper.StaticCache.TryGetType(atticGuid, out Type type)) {
|
---|
42 | Register(type, converter, priority);
|
---|
43 | }
|
---|
44 | }
|
---|
45 |
|
---|
46 | public static void Register<T>(IJsonItemConverter converter, int priority) =>
|
---|
47 | Register(typeof(T), converter, priority);
|
---|
48 |
|
---|
49 | /// <summary>
|
---|
50 | /// Deregister a converter (same object has to be already registered).
|
---|
51 | /// </summary>
|
---|
52 | /// <param name="converter">Converter to deregister.</param>
|
---|
53 | public static void Deregister(IJsonItemConverter converter) {
|
---|
54 | var types =
|
---|
55 | Converters
|
---|
56 | .Where(x => x.Value.Converter.GetHashCode() == converter.GetHashCode())
|
---|
57 | .Select(x => x.Key);
|
---|
58 | foreach (var x in types)
|
---|
59 | Converters.Remove(x);
|
---|
60 | }
|
---|
61 |
|
---|
62 | /// <summary>
|
---|
63 | /// Get a converter for a specific type.
|
---|
64 | /// </summary>
|
---|
65 | /// <param name="type">The type for which the converter will be selected.</param>
|
---|
66 | /// <returns>An IJsonItemConverter object.</returns>
|
---|
67 | public static IJsonItemConverter Get(Type type) {
|
---|
68 | IList<ConverterPriorityContainer> possibleConverters = new List<ConverterPriorityContainer>();
|
---|
69 |
|
---|
70 | foreach (var x in Converters)
|
---|
71 | if (type.IsEqualTo(x.Key))
|
---|
72 | possibleConverters.Add(x.Value);
|
---|
73 |
|
---|
74 | if(possibleConverters.Count > 0) {
|
---|
75 | ConverterPriorityContainer best = possibleConverters.First();
|
---|
76 | foreach (var x in possibleConverters) {
|
---|
77 | if (x.Priority > best.Priority)
|
---|
78 | best = x;
|
---|
79 | }
|
---|
80 | return best.Converter;
|
---|
81 | }
|
---|
82 | return new DummyConverter();
|
---|
83 | }
|
---|
84 |
|
---|
85 | internal static void Inject(IItem item, JsonItem data) =>
|
---|
86 | Get(item.GetType()).Inject(item, data);
|
---|
87 |
|
---|
88 | internal static JsonItem Extract(IItem item) =>
|
---|
89 | Get(item.GetType()).Extract(item);
|
---|
90 |
|
---|
91 |
|
---|
92 | /// <summary>
|
---|
93 | /// Static constructor for default converter configuration.
|
---|
94 | /// </summary>
|
---|
95 | static JsonItemConverter() {
|
---|
96 | Register<IntValue>(new ValueTypeValueConverter<IntValue, int>(), 1);
|
---|
97 | Register<DoubleValue>(new ValueTypeValueConverter<DoubleValue, double>(), 1);
|
---|
98 | Register<PercentValue>(new ValueTypeValueConverter<PercentValue, double>(), 2);
|
---|
99 | Register<BoolValue>(new ValueTypeValueConverter<BoolValue, bool>(), 1);
|
---|
100 | Register<DateTimeValue>(new ValueTypeValueConverter<DateTimeValue, DateTime>(), 1);
|
---|
101 | Register<StringValue>(new StringValueConverter(), 1);
|
---|
102 |
|
---|
103 | Register<IntArray>(new ValueTypeArrayConverter<IntArray, int>(), 1);
|
---|
104 | Register<DoubleArray>(new ValueTypeArrayConverter<DoubleArray, double>(), 1);
|
---|
105 | Register<PercentArray>(new ValueTypeArrayConverter<PercentArray, double>(), 2);
|
---|
106 | Register<BoolArray>(new ValueTypeArrayConverter<BoolArray, bool>(), 1);
|
---|
107 |
|
---|
108 | Register<IntMatrix>(new ValueTypeMatrixConverter<IntMatrix, int>(), 1);
|
---|
109 | Register<DoubleMatrix>(new ValueTypeMatrixConverter<DoubleMatrix, double>(), 1);
|
---|
110 | Register<PercentMatrix>(new ValueTypeMatrixConverter<PercentMatrix, double>(), 2);
|
---|
111 | Register<BoolMatrix>(new ValueTypeMatrixConverter<BoolMatrix, bool>(), 1);
|
---|
112 |
|
---|
113 | Register<DoubleRange>(new DoubleRangeConverter(), 1);
|
---|
114 | Register<IntRange>(new IntRangeConverter(), 1);
|
---|
115 |
|
---|
116 | Register(typeof(EnumValue<>), new EnumTypeConverter(), 1);
|
---|
117 |
|
---|
118 | Register<IValueParameter>(new ValueParameterConverter(), 2);
|
---|
119 | Register<IParameterizedItem>(new ParameterizedItemConverter(), 2);
|
---|
120 | Register<ILookupParameter>(new LookupParameterConverter(), 3);
|
---|
121 | Register<IValueLookupParameter>(new ValueLookupParameterConverter(), 4);
|
---|
122 |
|
---|
123 | Register(typeof(IConstrainedValueParameter<>), new ConstrainedValueParameterConverter(), 3);
|
---|
124 | Register(typeof(ICheckedMultiOperator<>), new MultiCheckedOperatorConverter(), 3);
|
---|
125 |
|
---|
126 | Register("EE612297-B1AF-42D2-BF21-AF9A2D42791C", new RegressionProblemDataConverter(), 20);
|
---|
127 | }
|
---|
128 | }
|
---|
129 | }
|
---|