zaaReloaded2/zaaReloaded2/Controller/SettingsRepository.cs

249 lines
8.8 KiB
C#
Executable File

/* 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
{
/// <summary>
/// A repository for zaaReloaded2.Controller.Settings.
/// </summary>
/// <remarks>
/// 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.
/// </remarks>
[Serializable]
public class SettingsRepository : ISerializable
{
#region Properties persistence
/// <summary>
/// Loads the SettingsRepository instance that was persisted in
/// the assembly properties.
/// </summary>
/// <returns>SettingsRepository that was last stored in the
/// assembly properties, or a newly created SettingsRepository
/// if no previously stored exists.</returns>
/// <remarks>
/// 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.
/// </remarks>
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;
}
}
/// <summary>
/// Stores the SettingsRepository in the assembly properties.
/// </summary>
/// <remarks>
/// 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.
/// </remarks>
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<Settings> SettingsList { get; protected set; }
#endregion
#region Constructors
/// <summary>
/// Creates a new instance of a settings repository that will
/// contain a default set of settings.
/// </summary>
public SettingsRepository()
{
SettingsList = new List<Settings>();
Reset();
}
#endregion
#region Serialization
protected SettingsRepository(SerializationInfo info, StreamingContext context)
{
int version = info.GetInt32("Version");
int settingsCount = info.GetInt32("SettingsCount");
SettingsList = new List<Settings>();
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
/// <summary>
/// Looks up a Settings object contained in this repository
/// by unique ID.
/// </summary>
/// <param name="uid">GUID to look for.</param>
/// <returns>Settings object with this GUID, or null if the
/// GUID was not found.</returns>
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
/// <summary>
/// Resets the Settings contained in this SettingsRepository
/// to the default set of settings.
/// </summary>
private void Reset()
{
SettingsList.Clear();
LoadDefaults();
}
/// <summary>
/// Loads default, built-in settings, replacing existing default
/// settings that might have been persisted.
/// </summary>
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
/// <summary>
/// Label that is appended to the default Settings' names.
/// </summary>
public const string BUILTIN_LABEL = " (eingebaut)";
/// <summary>
/// Constant GUID for the first default Settings.
/// </summary>
const string DEFAULT_SETTINGS_1_UID = "EA79DE6C-E999-44F1-9122-929A8AA404CB";
/// <summary>
/// Constant GUID for the second default Settings.
/// </summary>
const string DEFAULT_SETTINGS_2_UID = "783C63B5-A964-4368-B2D0-D4595DCCB952";
#endregion
}
}