Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 2994 was 2994, checked in by epitzer, 14 years ago

Make StorableClass attribute compulsory for StorableSerializer to work, add named property StorableClassType to choose between Empty and MarkedOnly, later other options will be added. (#548)

File size: 3.1 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  /// <summary>
12  /// Intended for serialization of all custom classes. Classes should have the
13  /// <code>[StorableClass(StorableClassType.Empty)]</code> attribute set and a serialization mode set.
14  /// Optionally selected fields and properties can be marked with the
15  /// <code>[Storable]</code> attribute.
16  /// </summary>
17  [StorableClass(StorableClassType.Empty)]   
18  public class StorableSerializer : ICompositeSerializer {
19
20    public int Priority {
21      get { return 200; }
22    }
23
24    public bool CanSerialize(Type type) {
25      if (!ReflectionTools.HasDefaultConstructor(type) &&
26        StorableConstructorAttribute.GetStorableConstructor(type) == null)
27        return false;
28      return StorableClassAttribute.IsStorableType(type, 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      return "class or one of its base classes is not empty and has no [StorableClass(StorableClassType.Empty)] attribute";
36    }
37
38    public IEnumerable<Tag> CreateMetaInfo(object o) {
39      StorableHookAttribute.InvokeHook(HookType.BeforeSerialization, o);
40      return new Tag[] { };
41    }
42
43    public IEnumerable<Tag> Decompose(object obj) {
44      foreach (var accessor in StorableAttribute.GetStorableAccessors(obj)) {
45        yield return new Tag(accessor.Name, accessor.Get());
46      }
47    }
48
49    private static readonly object[] defaultArgs = new object[] { true };
50
51    public object CreateInstance(Type type, IEnumerable<Tag> metaInfo) {
52      try {
53        ConstructorInfo constructor = StorableConstructorAttribute.GetStorableConstructor(type);
54        return constructor != null ? constructor.Invoke(defaultArgs) : Activator.CreateInstance(type, true);
55      } catch (TargetInvocationException x) {
56        throw new PersistenceException(
57          "Could not instantiate storable object: Encountered exception during constructor call",
58          x.InnerException);
59      }
60    }
61
62    public void Populate(object instance, IEnumerable<Tag> objects, Type type) {
63      var memberDict = new Dictionary<string, Tag>();
64      IEnumerator<Tag> iter = objects.GetEnumerator();
65      while (iter.MoveNext()) {
66        memberDict.Add(iter.Current.Name, iter.Current);
67      }     
68      foreach (var accessor in StorableAttribute.GetStorableAccessors(instance)) {
69        if (memberDict.ContainsKey(accessor.Name)) {
70          accessor.Set(memberDict[accessor.Name].Value);
71        } else if (accessor.DefaultValue != null) {
72          accessor.Set(accessor.DefaultValue);
73        }
74      }
75      StorableHookAttribute.InvokeHook(HookType.AfterDeserialization, instance);
76    }
77  }
78}
Note: See TracBrowser for help on using the repository browser.