Files
Pilz/Pilz.Configuration/Settings.cs
Pilzinsel64 c7b2a07dd0 logging
2025-07-10 06:57:09 +02:00

133 lines
4.0 KiB
C#

using Castle.Core.Logging;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
namespace Pilz.Configuration;
public class Settings : ISettings
{
protected readonly Dictionary<string, JObject> settingsJson = [];
protected readonly Dictionary<string, ISettingsNode> settings = [];
protected JsonSerializerSettings serializerSettings;
public virtual IReadOnlyCollection<ISettingsNode> Childs => settings.Values;
public virtual ILogger Logger { get; set; } = NullLogger.Instance;
public virtual T Get<T>() where T : ISettingsNode, ISettingsIdentifier
{
// Find existing one
if (settings.TryGetValue(T.Identifier, out var valueExisting) && valueExisting is T settingsExisting)
return settingsExisting;
// Create new & reset
if (Activator.CreateInstance<T>() is T settingsNew)
settingsNew.Reset();
else
{
settingsNew = default;
Logger.WarnFormat("Not able to create new settings node instance {0}.", T.Identifier);
}
// Try deserialize
if (settingsJson.TryGetValue(T.Identifier, out var valueRaw))
{
var serializer = JsonSerializer.CreateDefault(serializerSettings);
// Populate
if (settingsNew != null)
{
try
{
serializer.Populate(valueRaw.CreateReader(), settingsNew);
Logger.InfoFormat("Populated settings node {0}.", T.Identifier);
}
catch (Exception ex)
{
Logger.Error("Error populating settings node instance.", ex);
}
}
// Deserialize (fallback)
else if (valueRaw.ToObject<T>() is T settingsDeserialized)
{
try
{
settingsNew = settingsDeserialized;
Logger.WarnFormat("Deserialied settings node {0} via fallback variant.", T.Identifier);
}
catch (Exception ex)
{
Logger.Error("Error deserializing settings node instance.", ex);
}
}
}
// Remember
if (settingsNew != null)
settings[T.Identifier] = settingsNew;
// Return
return settingsNew;
}
public void Reset()
{
foreach (var s in settings.Values)
s.Reset();
}
public virtual string Save(JsonSerializerSettings serializerSettings)
{
this.serializerSettings = serializerSettings;
var serializer = JsonSerializer.CreateDefault(serializerSettings);
foreach (var kvp in settings)
{
var raw = JObject.FromObject(kvp.Value, serializer);
if (!settingsJson.TryAdd(kvp.Key, raw))
settingsJson[kvp.Key] = raw;
}
var objList = new JObject();
foreach (var kvp in settingsJson)
objList.Add(kvp.Key, kvp.Value);
var objSettings = new JObject
{
{ "Settings", objList }
};
return objSettings.ToString(serializer.Formatting);
}
public virtual bool Load(JsonSerializerSettings serializerSettings, string raw)
{
this.serializerSettings = serializerSettings;
var objSettings = JObject.Parse(raw);
if (!objSettings.TryGetValue("Settings", out var tokenList) || tokenList is not JObject objList)
return false;
settingsJson.Clear();
settings.Clear();
foreach (var child in objList)
{
if (child.Value is not JObject value)
continue;
settingsJson.Add(child.Key, value);
}
return true;
}
protected virtual JToken Serialize(object o, JsonSerializer jsonSerializer)
{
using JTokenWriter jTokenWriter = new JTokenWriter();
jsonSerializer.Serialize(jTokenWriter, o, o.GetType());
return jTokenWriter.Token;
}
}