#region License Information /* HeuristicLab * Copyright (C) 2002-2011 Heuristic and Evolutionary Algorithms Laboratory (HEAL) * * This file is part of HeuristicLab. * * HeuristicLab is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HeuristicLab is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with HeuristicLab. If not, see . */ #endregion using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; using HeuristicLab.Persistence.Core; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable.Descriptors; using HeuristicLab.Persistence.Interfaces; namespace HeuristicLab.Persistence.Default.CompositeSerializers.Storable { /// /// Intended for serialization of all custom classes. Classes should have the /// [StorableClass] attribute set. The default mode is to serialize /// members with the [Storable] attribute set. Alternatively the /// storable mode can be set to AllFields, AllProperties /// or AllFieldsAndAllProperties. /// [StorableClass] public sealed class StorableSerializer : ICompositeSerializer { public StorableSerializer() { } [StorableConstructor] private StorableSerializer(bool deserializing) : this() { } #region ICompositeSerializer implementation /// /// Priority 200, one of the first default composite serializers to try. /// /// public int Priority { get { return 200; } } /// /// Determines for every type whether the composite serializer is applicable. /// /// The type. /// /// true if this instance can serialize the specified type; otherwise, false. /// public bool CanSerialize(Type type) { TypeDescriptor desc = StorableClassAnalyzer.GetDescriptor(type); if (desc.IsInvalid) return false; if (desc.HasDefaultConstructor) return true; else if (desc.IsStorableClass) if (desc.HasDefaultConstructor || desc.HasStorableConstructor) return true; else throw new PersistenceException("[Storable] type has no default constructor and no [StorableConstructor]"); return false; } /// /// Give a reason if possibly why the given type cannot be serialized by this /// ICompositeSerializer. /// /// The type. /// /// A string justifying why type cannot be serialized. /// public string JustifyRejection(Type type) { StringBuilder sb = new StringBuilder(); TypeDescriptor desc = StorableClassAnalyzer.GetDescriptor(type); if (desc.IsInvalid) sb.Append("class is not marked [StorableClass] but has mutable members."); if (!desc.IsStorableClass) sb.Append("class is not marked [StorableClass]"); if (!desc.HasDefaultConstructor) sb.Append("class has no default constructor"); if (!desc.HasStorableConstructor) sb.Append("class has no [StorableConstructor]"); return sb.ToString(); } /// /// Creates the meta info. /// /// The object. /// A list of storable components. public IEnumerable CreateMetaInfo(object o) { return new Tag[] { }; } /// /// Decompose an object into s, the tag name can be null, /// the order in which elements are generated is guaranteed to be /// the same as they will be supplied to the Populate method. /// /// An object. /// An enumerable of s. public IEnumerable Decompose(object obj) { foreach (var kvp in StorableClassAnalyzer.GetDescriptor(obj.GetType()).Decompose(obj)) { yield return new Tag(kvp.Key, kvp.Value); } } /// /// Create an instance of the object using the provided meta information. /// /// A type. /// The meta information. /// A fresh instance of the provided type. public object CreateInstance(Type type, IEnumerable metaInfo) { try { return StorableClassAnalyzer.GetDescriptor(type).CreateInstance(); } catch (TargetInvocationException x) { throw new PersistenceException( "Could not instantiate storable object: Encountered exception during constructor call", x.InnerException); } } /// /// Populates the specified instance. /// /// The instance. /// The objects. /// The type. public void Populate(object instance, IEnumerable objects, Type type) { StorableClassAnalyzer.GetDescriptor(type).Populate(instance, objects.ToDictionary(kvp => kvp.Name, kvp => kvp.Value)); } #endregion } }