Free cookie consent management tool by TermsFeed Policy Generator

source: branches/3026_IntegrationIntoSymSpace/HeuristicLab.JsonInterface/Converters/StorableConverter.cs @ 17374

Last change on this file since 17374 was 17374, checked in by dpiringe, 4 years ago

#3026:

  • extended the BaseConverter class to set the type of the extracted value and removed the assignment of type in all other converters
  • fixed a bug in ConfigurableConverter -> now it correctly iterates through all items from an IEnumerable and calls the extract callback
  • MultiCheckedOperatorConverter:
    • deleted unnecessary code line
    • now adds operators to parameters (instead of operator list, because the operator list will get removed in a future commit)
    • does not set the path of its added items anymore
  • ParameterBaseConverter removed unnecessary code lines
  • deleted ParameterBaseConverter
  • reimplemented StorableConverter to test it again (still not really useable, because it bloats the template massively)
  • fixed a pathing bug in ValueParameterConverter (extended ValueRangeConverter, ValueTypeArrayConverter, ValueTypeMatrixConverter, ValueTypeValueConverter to archive this)
  • JCGenerator now only writes a single array with parameters (only FreeParameters) and saves a .hl File to test a new type of implementation of the whole JsonInterface
  • fixed a bug in JsonItem -> now it replaces the name in path of the item (not the whole path as it was before)
File size: 8.0 KB
Line 
1using System;
2using HEAL.Attic;
3using System.Collections.Generic;
4using HeuristicLab.Common;
5using System.Linq;
6using System.Text;
7using System.Threading.Tasks;
8using HeuristicLab.Core;
9using System.Reflection;
10using HeuristicLab.Data;
11using System.Collections;
12
13namespace HeuristicLab.JsonInterface {
14
15
16  public class StorableConverter {
17    private const BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly;
18
19    //private IDictionary<Type, >
20
21
22    private bool Filter(MemberInfo info) => info.Name != "ItemName" && info.Name != "ItemDescription" && info.Name != "name" && info.Name != "description";
23
24    private Stack<Tuple<JsonItem, object, Type, string>> stack = new Stack<Tuple<JsonItem, object, Type, string>>();
25    private IDictionary<int, JsonItem> hashToObject = new Dictionary<int, JsonItem>();
26
27    public JsonItem ExtractHelper(object obj, Type type, string name = "") {
28      JsonItem item = new JsonItem() {
29        Parameters = new List<JsonItem>()
30      };
31
32     
33
34      item.Type = type.AssemblyQualifiedName;
35
36      if (obj != null && obj is IItem)
37        item.Name = (obj as IItem).ItemName;
38      else if (!string.IsNullOrEmpty(name))
39        item.Name = name;
40      else
41        item.Name = type.Name;
42
43      hashToObject.Add(obj.GetHashCode(), item);
44
45      item.Path = item.Name;
46
47      if (obj == null) return item;
48
49      if (StorableTypeAttribute.IsStorableType(type)) {
50        do {
51          foreach (var property in type.GetProperties(flags)) {
52            if (StorableAttribute.IsStorable(property) && Filter(property)) {
53              object tmp = GetValue(property, obj);
54              if (tmp != null && !hashToObject.ContainsKey(tmp.GetHashCode()))
55                item.Parameters.Add(ExtractHelper(tmp, tmp != null ? tmp.GetType() : property.PropertyType, property.Name));
56            }
57          }
58
59          foreach (var field in type.GetFields(flags)) {
60            if (StorableAttribute.IsStorable(field) && Filter(field)) {
61              object tmp = GetValue(field, obj);
62              if (tmp != null && !hashToObject.ContainsKey(tmp.GetHashCode()))
63                item.Parameters.Add(ExtractHelper(tmp, tmp != null ? tmp.GetType() : field.FieldType, field.Name));
64            }
65          }
66
67          type = type.BaseType;
68        } while (type != null);
69      } else if (
70          type.IsEqualTo(typeof(short))
71          || type.IsEqualTo(typeof(int))
72          || type.IsEqualTo(typeof(long))
73          || type.IsEqualTo(typeof(ushort))
74          || type.IsEqualTo(typeof(uint))
75          || type.IsEqualTo(typeof(ulong))
76          || type.IsEqualTo(typeof(float))
77          || type.IsEqualTo(typeof(double))
78          || type.IsEqualTo(typeof(bool))
79      ) {
80        item.Value = obj;
81        item.Range = new object[] { GetMinValue(type), GetMaxValue(type) };
82      } else if (type.IsEqualTo(typeof(IDictionary))) {
83        if (obj != null) {
84          foreach (DictionaryEntry i in (IDictionary)obj) {
85            if (i.Key is string) {
86              if (!hashToObject.ContainsKey(i.Value.GetHashCode()))
87                item.Parameters.Add(ExtractHelper(i.Value, i.Value.GetType()));
88            }
89          }
90        }
91      } else if(type.IsEqualTo(typeof(IList))) {
92        foreach (var i in (IList)obj) {
93          if (!hashToObject.ContainsKey(i.GetHashCode()))
94            item.Parameters.Add(ExtractHelper(i, i.GetType()));
95        }
96      } else if(type.IsEqualTo(typeof(KeyValuePair<,>))) {
97        dynamic tmp = (dynamic)obj;
98        object key = (object)tmp.Key;
99        object value = (object)tmp.Value;
100        if (!hashToObject.ContainsKey(key.GetHashCode()))
101          item.Parameters.Add(ExtractHelper(key, key.GetType()));
102
103        if (!hashToObject.ContainsKey(value.GetHashCode()))
104          item.Parameters.Add(ExtractHelper(value, value.GetType()));
105
106      } else if(type.IsEqualTo(typeof(string))) {
107        item.Value = obj;
108
109      } else if(type.IsEqualTo(typeof(Array))) {
110        foreach (var i in (Array)obj) {
111          if (!hashToObject.ContainsKey(i.GetHashCode()))
112            item.Parameters.Add(ExtractHelper(i, i.GetType()));
113        }
114      } else if(type.IsEqualTo(typeof(Tuple<,>))) {
115        dynamic tmp = (dynamic)obj;
116        object key = (object)tmp.Item1;
117        object value = (object)tmp.Item2;
118        if (!hashToObject.ContainsKey(key.GetHashCode()))
119          item.Parameters.Add(ExtractHelper(key, key.GetType()));
120
121        if (!hashToObject.ContainsKey(value.GetHashCode()))
122          item.Parameters.Add(ExtractHelper(value, value.GetType()));
123
124      } else if (type.IsEqualTo(typeof(IEnumerable))) {
125        foreach (var i in (IEnumerable)obj) {
126          if (!hashToObject.ContainsKey(i.GetHashCode()))
127            item.Parameters.Add(ExtractHelper(i, i.GetType()));
128        }
129      }
130
131
132      item.UpdatePath();
133      return item;
134    }
135
136    public JsonItem Extract(object obj) {
137      return ExtractHelper(obj, obj.GetType());
138    }
139
140    /*
141    public override JsonItem ExtractData(IItem value) {
142      Type type = value.GetType();
143
144      JsonItem item = new JsonItem() {
145        Name = value.ItemName,
146        Path = value.ItemName,
147        Value = ".",
148        Type = value.GetType().AssemblyQualifiedName
149      };
150      item.Parameters = new List<JsonItem>();
151
152     
153      do {
154        foreach (var property in type.GetProperties(flags)) {
155          ExtractFromMemberInfo(property, value, item);
156        }
157
158        foreach (var field in type.GetFields(flags)) {
159          ExtractFromMemberInfo(field, value, item);
160        }
161
162        type = type.BaseType;
163      } while (type != null);
164
165
166      return item;
167    }
168   
169    public override void InjectData(IItem item, JsonItem data) {
170      throw new NotImplementedException();
171    }
172    */
173
174    private object GetValue(MemberInfo info, object obj) {
175      switch(info.MemberType) {
176        case MemberTypes.Field:
177          return ((FieldInfo)info).GetValue(obj);
178        case MemberTypes.Property:
179          return ((PropertyInfo)info).CanRead ? ((PropertyInfo)info).GetValue(obj) : null;
180        default: return null;
181      }
182    }
183
184    private object GetMaxValue(Type t) {
185      TypeCode typeCode = Type.GetTypeCode(t);
186
187      if (typeof(ValueType).IsEqualTo(typeof(PercentValue)))
188        return 1.0d;
189
190      switch (typeCode) {
191        case TypeCode.Int16: return Int16.MaxValue;
192        case TypeCode.Int32: return Int32.MaxValue;
193        case TypeCode.Int64: return Int64.MaxValue;
194        case TypeCode.UInt16: return UInt16.MaxValue;
195        case TypeCode.UInt32: return UInt32.MaxValue;
196        case TypeCode.UInt64: return UInt64.MaxValue;
197        case TypeCode.Single: return Single.MaxValue;
198        case TypeCode.Double: return Double.MaxValue;
199        case TypeCode.Decimal: return Decimal.MaxValue;
200        case TypeCode.Byte: return Byte.MaxValue;
201        case TypeCode.Boolean: return true;
202        default: return GetDefaultValue(t);
203      }
204    }
205
206    private object GetMinValue(Type t) {
207      TypeCode typeCode = Type.GetTypeCode(t);
208
209      if (typeof(ValueType).IsEqualTo(typeof(PercentValue)))
210        return 0.0d;
211
212      switch (typeCode) {
213        case TypeCode.Int16: return Int16.MinValue;
214        case TypeCode.Int32: return Int32.MinValue;
215        case TypeCode.Int64: return Int64.MinValue;
216        case TypeCode.UInt16: return UInt16.MinValue;
217        case TypeCode.UInt32: return UInt32.MinValue;
218        case TypeCode.UInt64: return UInt64.MinValue;
219        case TypeCode.Single: return Single.MinValue;
220        case TypeCode.Double: return Double.MinValue;
221        case TypeCode.Decimal: return Decimal.MinValue;
222        case TypeCode.Byte: return Byte.MinValue;
223        case TypeCode.Boolean: return false;
224        default: return GetDefaultValue(t);
225      }
226    }
227
228    private object GetDefaultValue(Type t) => t.IsValueType ? Activator.CreateInstance(t) : null;
229
230  }
231}
Note: See TracBrowser for help on using the repository browser.