Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Storable/StorableSerializer.cs @ 2993

Last change on this file since 2993 was 2993, checked in by epitzer, 15 years ago

add justifications for rejecting a type for serialization in ICompositeSerializer (#548)

File size: 3.2 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using HeuristicLab.Persistence.Interfaces;
5using HeuristicLab.Persistence.Core;
6using System.Reflection;
7using HeuristicLab.Persistence.Auxiliary;
8
9namespace HeuristicLab.Persistence.Default.CompositeSerializers.Storable {
10
11  [EmptyStorableClass]
12  public class StorableSerializer : ICompositeSerializer {
13
14    public int Priority {
15      get { return 200; }
16    }
17
18    public bool CanSerialize(Type type) {
19      if (!ReflectionTools.HasDefaultConstructor(type) &&
20        StorableConstructorAttribute.GetStorableConstructor(type) == null)
21        return false;
22      while (type != null) {
23        if (StorableAttribute.GetStorableMembers(type, false).Count() == 0 &&
24            !EmptyStorableClassAttribute.IsEmptyStorable(type))
25          return false;
26        type = type.BaseType;
27      }
28      return true;
29    }
30
31    public string JustifyRejection(Type type) {
32      if (!ReflectionTools.HasDefaultConstructor(type) &&
33        StorableConstructorAttribute.GetStorableConstructor(type) == null)
34        return "no default constructor and no storable constructor";
35      while (type != null) {
36        if (StorableAttribute.GetStorableMembers(type, false).Count() == 0 &&
37            !EmptyStorableClassAttribute.IsEmptyStorable(type))
38          return string.Format("{0} has no storable members and is not marked [EmtpyStorableClass]",
39            type);
40        type = type.BaseType;
41      }
42      return "no reason";
43    }
44
45    public IEnumerable<Tag> CreateMetaInfo(object o) {
46      StorableHookAttribute.InvokeHook(HookType.BeforeSerialization, o);
47      return new Tag[] { };
48    }
49
50    public IEnumerable<Tag> Decompose(object obj) {
51      foreach (var accessor in StorableAttribute.GetStorableAccessors(obj)) {
52        yield return new Tag(accessor.Name, accessor.Get());
53      }
54    }
55
56    private static readonly object[] defaultArgs = new object[] { true };
57
58    public object CreateInstance(Type type, IEnumerable<Tag> metaInfo) {
59      try {
60        ConstructorInfo constructor = StorableConstructorAttribute.GetStorableConstructor(type);
61        return constructor != null ? constructor.Invoke(defaultArgs) :  Activator.CreateInstance(type, true);       
62      } catch (TargetInvocationException x) {
63        throw new PersistenceException(
64          "Could not instantiate storable object: Encountered exception during constructor call",
65          x.InnerException);
66      }
67    }
68
69    public void Populate(object instance, IEnumerable<Tag> objects, Type type) {
70      var memberDict = new Dictionary<string, Tag>();
71      IEnumerator<Tag> iter = objects.GetEnumerator();
72      while (iter.MoveNext()) {
73        memberDict.Add(iter.Current.Name, iter.Current);
74      }
75      foreach (var accessor in StorableAttribute.GetStorableAccessors(instance)) {
76        if (memberDict.ContainsKey(accessor.Name)) {
77          accessor.Set(memberDict[accessor.Name].Value);
78        } else if (accessor.DefaultValue != null) {
79          accessor.Set(accessor.DefaultValue);
80        }
81      }
82      StorableHookAttribute.InvokeHook(HookType.AfterDeserialization, instance);
83    }
84  }
85}
Note: See TracBrowser for help on using the repository browser.