Free cookie consent management tool by TermsFeed Policy Generator

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

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

Merge StorableClassType.Empty into StorableClassType.MarkedOnly and make it the default if not specified (#548)

File size: 3.0 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  /// <c>[StorableClass]</c> attribute set and a serialization mode set.
14  /// Optionally selected fields and properties can be marked with the
15  /// <c>[Storable]</c> attribute.
16  /// </summary>
17  [StorableClass]   
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] 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.