/* SettingsRepository.cs * part of zaaReloaded2 * * Copyright 2015-2017 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.Collections.ObjectModel; using System.IO; using System.Linq; using System.Text; using System.Xml.Serialization; using System.Reflection; using zaaReloaded2.Controller.Elements; using System.Runtime.Serialization.Formatters.Soap; using System.Web; using System.Runtime.Serialization; namespace zaaReloaded2.Controller { /// /// A repository for zaaReloaded2.Controller.Settings. /// /// /// This class is derived from ApplicationSettingsBase to be able /// to simply store it in the assembly's properties. However, this /// causes some confusion because .NET's ApplicationSettings are /// different from zaaReloaded's Settings. /// [Serializable] public class SettingsRepository : ISerializable { #region Properties persistence /// /// Loads the SettingsRepository instance that was persisted in /// the assembly properties. /// /// SettingsRepository that was last stored in the /// assembly properties, or a newly created SettingsRepository /// if no previously stored exists. /// /// The SettingsRepository is serialized using a SoapFormatter, which /// creates SOAP XML. Since the assembly properties are stored as /// XML as well, the serialized SettingsRepository is converted to /// a base-64 string, which does not mess with the properties XML. /// public static SettingsRepository Load() { string s = UserSettings.Default.SettingsRepository; if (String.IsNullOrEmpty(s)) { return new SettingsRepository(); } else { MemoryStream stream = new MemoryStream(); string encoded = UserSettings.Default.SettingsRepository; byte[] bytes = Convert.FromBase64String(encoded); stream.Write(bytes, 0, bytes.Length); stream.Position = 0; SoapFormatter serializer = new SoapFormatter(); SettingsRepository repo = serializer.Deserialize(stream) as SettingsRepository; repo.LoadDefaults(); return repo; } } /// /// Stores the SettingsRepository in the assembly properties. /// /// /// The SettingsRepository is serialized using a SoapFormatter, which /// creates SOAP XML. Since the assembly properties are stored as /// XML as well, the serialized SettingsRepository is converted to /// a base-64 string, which does not mess with the properties XML. /// public void Store() { MemoryStream stream = new MemoryStream(); SoapFormatter serializer = new SoapFormatter(); serializer.Serialize(stream, this); stream.Position = 0; string encoded = Convert.ToBase64String(stream.ToArray()); UserSettings.Default.SettingsRepository = encoded; } #endregion #region Properties public IList SettingsList { get; protected set; } #endregion #region Constructors /// /// Creates a new instance of a settings repository that will /// contain a default set of settings. /// public SettingsRepository() { SettingsList = new List(); Reset(); } #endregion #region Serialization protected SettingsRepository(SerializationInfo info, StreamingContext context) { int version = info.GetInt32("Version"); int settingsCount = info.GetInt32("SettingsCount"); SettingsList = new List(); for (int i = 0; i < settingsCount; i++) { Type type = info.GetValue(SerializationSettingsName(i, "Type"), typeof(Type)) as Type; Settings s = info.GetValue(SerializationSettingsName(i, "Object"), typeof(Settings)) as Settings; SettingsList.Add(s); } } public void GetObjectData(SerializationInfo info, StreamingContext context) { info.AddValue("Version", Properties.Settings.Default.SerializationVersion); info.AddValue("SettingsCount", SettingsList.Count); int i = 0; foreach (Settings s in SettingsList) { info.AddValue(SerializationSettingsName(i, "Type"), s.GetType()); info.AddValue(SerializationSettingsName(i, "Object"), s); i++; } } string SerializationSettingsName(int index, string info) { return String.Format("Settings{0}{1}", index, info); } #endregion #region Public methods /// /// Looks up a Settings object contained in this repository /// by unique ID. /// /// GUID to look for. /// Settings object with this GUID, or null if the /// GUID was not found. public Settings FindByGuid(Guid uid) { return SettingsList.FirstOrDefault(s => s.Uid == uid); } public static bool IsDefaultSettings(Settings settings) { return (settings.Name == Properties.Settings.Default.SettingsNameClinic + BUILTIN_LABEL || settings.Name == Properties.Settings.Default.SettingsNameWard + BUILTIN_LABEL); } #endregion #region Private methods /// /// Resets the Settings contained in this SettingsRepository /// to the default set of settings. /// private void Reset() { SettingsList.Clear(); LoadDefaults(); } /// /// Loads default, built-in settings, replacing existing default /// settings that might have been persisted. /// private void LoadDefaults() { Assembly myAssembly = this.GetType().Assembly; SoapFormatter deserializer = new SoapFormatter(); Stream stream = myAssembly.GetManifestResourceStream("zaaReloaded2.Defaults.ward.zaaReloaded"); Settings settings = deserializer.Deserialize(stream) as Settings; settings.Name = Properties.Settings.Default.SettingsNameWard + BUILTIN_LABEL; settings.Uid = Guid.Parse(DEFAULT_SETTINGS_1_UID); ReplaceOrAdd(settings); stream = myAssembly.GetManifestResourceStream("zaaReloaded2.Defaults.clinic.zaaReloaded"); settings = deserializer.Deserialize(stream) as Settings; settings.Name = Properties.Settings.Default.SettingsNameClinic + BUILTIN_LABEL; settings.Uid = Guid.Parse(DEFAULT_SETTINGS_2_UID); ReplaceOrAdd(settings); } private void ReplaceOrAdd(Settings settings) { Settings existing = SettingsList.FirstOrDefault(s => s.Uid == settings.Uid); if (existing == null) { SettingsList.Add(settings); } else { int index = SettingsList.IndexOf(existing); SettingsList.RemoveAt(index); SettingsList.Insert(index, settings); } } #endregion #region Constants /// /// Label that is appended to the default Settings' names. /// public const string BUILTIN_LABEL = " (eingebaut)"; /// /// Constant GUID for the first default Settings. /// const string DEFAULT_SETTINGS_1_UID = "EA79DE6C-E999-44F1-9122-929A8AA404CB"; /// /// Constant GUID for the second default Settings. /// const string DEFAULT_SETTINGS_2_UID = "783C63B5-A964-4368-B2D0-D4595DCCB952"; #endregion } }