Ignore:
Timestamp:
01/07/20 16:25:39 (15 months ago)
Author:
dpiringe
Message:

#3026:

  • deleted: ConvertableAttribute, DummyConverter, ObjectExtensions
  • renamed: CustomJsonWriter -> SingleLineArrayJsonWriter, JCInstantiator -> JsonTemplateInstantiator
  • added: JsonItemConverterFactory, UnsupportedJsonItem
  • IJsonItemConverter:
    • added two new properties: Priority and ConvertableType -> because converters are automatically collected by plugin infrastructure now
    • Extract, Inject references a root converter now -> typically an instance of JsonItemConverter -> to prevent cycles
  • JsonItemConverter:
    • now implements the interface IJsonItemConverter
    • is now a dynamic class
    • is only instantiable with an factory (JsonItemConverterFactory)
    • still has the old (but now public) static methods Extract and Inject (without ref param IJsonItemConverter root) -> creates instance with factory and calls methods of instance
    • removed register and unregister methods, because the factory collects all converters automatically now (on first call of Create)
    • has cycle detection for Extract and Inject
    • renamed method Get to GetConverter
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/3026_IntegrationIntoSymSpace/HeuristicLab.JsonInterface/JsonItemConverter.cs

    r17379 r17394  
    1212namespace HeuristicLab.JsonInterface {
    1313  /// <summary>
    14   /// Static class for handling json converters.
     14  /// Class for handling json converters.
    1515  /// </summary>
    16   public static class JsonItemConverter {
     16  public class JsonItemConverter : IJsonItemConverter {
     17   
     18    #region Properties
     19    private IDictionary<Type, IJsonItemConverter> Converters { get; set; }
     20      = new Dictionary<Type, IJsonItemConverter>();
    1721
    18     private struct ConverterPriorityContainer {
    19       public IJsonItemConverter Converter { get; set; }
    20       public int Priority { get; set; }
    21     }
     22    private IDictionary<int, JsonItem> Cache { get; set; }
     23      = new Dictionary<int, JsonItem>();
    2224
    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     }
     25    public int Priority => throw new NotImplementedException();
    3626
    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);
     27    public Type ConvertableType => throw new NotImplementedException();
     28    #endregion
    4829
    4930    /// <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.
     31    /// GetConverter a converter for a specific type.
    6432    /// </summary>
    6533    /// <param name="type">The type for which the converter will be selected.</param>
    6634    /// <returns>An IJsonItemConverter object.</returns>
    67     public static IJsonItemConverter Get(Type type) {
    68       IList<ConverterPriorityContainer> possibleConverters = new List<ConverterPriorityContainer>();
     35    public IJsonItemConverter GetConverter(Type type) {
     36      IList<IJsonItemConverter> possibleConverters = new List<IJsonItemConverter>();
    6937     
    7038      foreach (var x in Converters)
     
    7341
    7442      if(possibleConverters.Count > 0) {
    75         ConverterPriorityContainer best = possibleConverters.First();
     43        IJsonItemConverter best = possibleConverters.First();
    7644        foreach (var x in possibleConverters) {
    7745          if (x.Priority > best.Priority)
    7846            best = x;
    7947        }
    80         return best.Converter;
     48        return best;
    8149      }
    82       return new DummyConverter();
     50      return null;
     51    }
     52   
     53    public void Inject(IItem item, JsonItem data, IJsonItemConverter root) {
     54      if(!Cache.ContainsKey(item.GetHashCode())) {
     55        IJsonItemConverter converter = GetConverter(item.GetType());
     56        if(converter != null) converter.Inject(item, data, root);
     57      }
    8358    }
    8459
    85     internal static void Inject(IItem item, JsonItem data) =>
    86       Get(item.GetType()).Inject(item, data);
     60    public JsonItem Extract(IItem item, IJsonItemConverter root) {
     61      int hash = item.GetHashCode();
     62      if (Cache.TryGetValue(hash, out JsonItem val))
     63        return val;
     64      else {
     65        IJsonItemConverter converter = GetConverter(item.GetType());
     66        if (converter == null) return new UnsupportedJsonItem();
     67        JsonItem tmp = GetConverter(item.GetType()).Extract(item, root);
     68        Cache.Add(hash, tmp);
     69        return tmp;
     70      }
     71    }
     72   
     73    public static void Inject(IItem item, JsonItem data) {
     74      IJsonItemConverter c = JsonItemConverterFactory.Create();
     75      c.Inject(item, data, c);
     76    }
    8777
    88     internal static JsonItem Extract(IItem item) =>
    89       Get(item.GetType()).Extract(item);
    90 
     78    public static JsonItem Extract(IItem item) {
     79      IJsonItemConverter c = JsonItemConverterFactory.Create();
     80      return c.Extract(item, c);
     81    }
    9182
    9283    /// <summary>
    9384    /// Static constructor for default converter configuration.
    9485    /// </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);
     86    internal JsonItemConverter(IDictionary<Type, IJsonItemConverter> converters) {
     87      Converters = converters;
    12788    }
    12889  }
Note: See TracChangeset for help on using the changeset viewer.