/* Settings.cs * part of zaaReloaded2 * * Copyright 2015-2018 Daniel Kraus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; using System.Collections.Generic; using System.Linq; using zaaReloaded2; using zaaReloaded2.Formatter; using zaaReloaded2.Controller.Elements; using System.IO; using System.Text.RegularExpressions; using System.Runtime.Serialization; using YamlDotNet.Serialization; namespace zaaReloaded2.Controller { /// /// Holds settings related to controlling laboratory output. /// [Serializable] public class Settings : ICloneable, ISerializable { #region Auxiliary factories for YamlDotNet public static ISerializer BuildSerializer() { SerializerBuilder builder = new SerializerBuilder() .WithCommonTagMappings() .EnsureRoundtrip(); return builder.Build(); } public static IDeserializer BuildDeserializer() { DeserializerBuilder builder = new DeserializerBuilder().WithCommonTagMappings(); return builder.Build(); } #endregion #region Persistence /// /// Deserializes a Settings object from SOAP XML that is read from a file. /// /// File to read. /// Deserialized Settings object with new unique ID. /// if the file does not contain /// SOAP XML that can be deserialized to a Settings object. public static Settings LoadFromFile(string fileName) { Logger.Info("LoadFromFile: {0}", fileName); StreamReader reader = new StreamReader(fileName); IDeserializer deserializer = BuildDeserializer(); Settings settings; try { settings = deserializer.Deserialize(reader); } catch (Exception e) { Logger.Fatal("LoadFromFile: Exception during deserialization"); Logger.Fatal(e); throw; } // SoapFormatter formatter = new SoapFormatter(); // Settings settings = formatter.Deserialize(reader.BaseStream) as Settings; if (settings == null) { throw new InvalidDataException("Datei enthält keine Stil-Daten oder ist beschädigt."); } Logger.Info("LoadFromFile: Successfully loaded '{0}", settings.Name); settings.Uid = Guid.NewGuid(); Logger.Debug("LoadFromFile: new GUID is '{0}", settings.Uid); return settings; } /// /// Serializes a Settings object to SOAP XML that is written to a file. /// /// File to write to. public void SaveToFile(string fileName) { Logger.Info("SaveToFile: Settings name: {0}", Name); using (StreamWriter writer = new StreamWriter(fileName)) { ISerializer serializer = BuildSerializer(); serializer.Serialize(writer, this); } Logger.Info("SaveToFile: Successfully saved to file '{0}'", fileName); // SoapFormatter formatter = new SoapFormatter(); // formatter.Serialize(writer.BaseStream, this); } #endregion #region Properties /// /// Gets or sets the name of these settings. /// public string Name { get; set; } /// /// Gets or sets the reference style. /// public ReferenceStyle ReferenceStyle { get; set; } /// /// Gets or sets the style in which abnormal values /// are formatted. /// public AbnormalStyle AbnormalStyle { get; set; } /// /// Indicates whether to prefer the more verbose "mmol/l" over "mM". /// public bool PreferVerboseMolar { get; set; } /// /// Gets the list of controlling elements. /// public IList Elements { get; private set; } /// /// Gets the unique ID of this Settings object. The unique /// ID is not included in deep-copying (cloning). /// public Guid Uid { get; internal set; } #endregion #region Constructors public Settings() : this(string.Empty, null) { } public Settings(string name) : this(name, null) { } /// /// Creates a new Settings object with an initial /// set of elements. /// /// Set of ElementBase /// object (or derived ones). public Settings(IList initialElements) : this(String.Empty, initialElements) { } /// /// Creates a new Settings object with an initial /// set of elements and a name. /// /// Set of ElementBase /// object (or derived ones). /// Name of these settings. public Settings(string name, IList initialElements) { Uid = Guid.NewGuid(); Name = name; Elements = initialElements; ReferenceStyle = Properties.Settings.Default.ReferenceStyle; if (Elements == null) { Elements = new List(); } } /// /// Creates a new Settings object with an initial /// set of elements, a name, and a unique ID. /// /// Set of ElementBase /// object (or derived ones). /// Name of these settings. /// Unique ID for this Settings object. public Settings(string name, IList initialElements, Guid uid) : this(name, initialElements) { Uid = uid; } /// /// Deserialization constructor. /// protected Settings(SerializationInfo info, StreamingContext context) { int version = info.GetInt32("Version"); Uid = (Guid)info.GetValue("Uid", typeof(Guid)); Name = info.GetString("Name"); ReferenceStyle = (ReferenceStyle)info.GetValue("ReferenceStyle", typeof(ReferenceStyle)); if (version >= 2) { AbnormalStyle = (AbnormalStyle)info.GetValue("AbnormalStyle", typeof(AbnormalStyle)); } int elementsCount = info.GetInt32("ElementsCount"); Elements = new List(); for (int i = 0; i < elementsCount; i++) { Type type = info.GetValue(SerializationElementName(i, "Type"), typeof(Type)) as Type; ElementBase element = info.GetValue(SerializationElementName(i, "Object"), type) as ElementBase; Elements.Add(element); } } #endregion #region Public methods /// /// Adds an element to the list of Elements. /// /// Element to add. public void AddElement(ElementBase element) { Elements.Add(element); } #endregion #region Implementation of ICloneable public object Clone() { Settings clone = new Settings( String.Format("Kopie von {0}", Name), Elements.Select(e => e.Clone() as ElementBase).ToList() ); clone.ReferenceStyle = ReferenceStyle; clone.AbnormalStyle = AbnormalStyle; return clone; } #endregion #region Implementation of ISerializable public void GetObjectData(SerializationInfo info, StreamingContext context) { info.AddValue("Version", Properties.Settings.Default.SerializationVersion); info.AddValue("Uid", Uid); info.AddValue("Name", Name); info.AddValue("ReferenceStyle", ReferenceStyle); info.AddValue("AbnormalStyle", AbnormalStyle); info.AddValue("ElementsCount", Elements.Count); int i = 0; foreach (ElementBase e in Elements) { info.AddValue(SerializationElementName(i, "Type"), e.GetType()); info.AddValue(SerializationElementName(i, "Object"), e); i++; } } string SerializationElementName(int index, string info) { return String.Format("Element{0}{1}", index, info); } #endregion #region Fields // Defines header lines for the persistence file: "[My name]" and so on. static readonly Regex _persistenceHeaderRegex = new Regex(@"^\[(?.+?)]$"); #endregion #region Class logger private static NLog.Logger Logger { get { return _logger.Value; } } private static readonly Lazy _logger = new Lazy(() => NLog.LogManager.GetCurrentClassLogger()); #endregion } }