263 lines
10 KiB
C#
263 lines
10 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Globalization;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using Newtonsoft.Json;
|
|
|
|
namespace gehGassi.Domain.Localization
|
|
{
|
|
/// <summary>
|
|
/// Basis-Klasse für eine Entität die Übersetzungen für String-Felder ermöglicht
|
|
/// </summary>
|
|
public class LocalizableBase : ILocalizable
|
|
{
|
|
private string _language = string.Empty;
|
|
|
|
/// <summary>
|
|
/// In welcher Sprache sollen die übersetzbaren Felder abgerufen oder gesetzt werden?
|
|
/// </summary>
|
|
/// <param name="language">ISO2 codierte Sprache</param>
|
|
public void SetLanguage(string language)
|
|
{
|
|
if (GetAvailableLanguages().Contains(language.ToUpper()))
|
|
_language = language.ToUpper();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gibt die gewählte Sprache intern zurück.
|
|
/// Wenn diese nicht verfügbar ist, wird versucht die aktuelle Culture zu verwenden.
|
|
/// Wenn diese auch nicht verfügbar ist, wird die Default-Sprache verwendet
|
|
/// </summary>
|
|
/// <returns>Sprache als ISO2</returns>
|
|
protected string GetLanguage()
|
|
{
|
|
if (string.IsNullOrWhiteSpace(_language))
|
|
{
|
|
var lang = CultureInfo.CurrentCulture.TwoLetterISOLanguageName;
|
|
_language = GetAvailableLanguages().Contains(lang.ToUpper()) ? lang.ToUpper() : DefaultLanguage;
|
|
}
|
|
return _language;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Setzt eine Übersetzung direkt für ein Feld mittels Reflection
|
|
/// </summary>
|
|
/// <param name="property">Name der Eigenschaft</param>
|
|
/// <param name="language">ISO2 codierte Sprache</param>
|
|
/// <param name="value">Zu setzender Wert</param>
|
|
public void Set(string property, string language, string value)
|
|
{
|
|
property = property + "Localized";
|
|
language = language.ToUpper();
|
|
var serialized = GetPropValue(GetType(), property, this);
|
|
Dictionary<string, string> dictionary;
|
|
if (serialized != null)
|
|
{
|
|
try
|
|
{
|
|
dictionary = JsonConvert.DeserializeObject<Dictionary<string, string>>(serialized.ToString());
|
|
}
|
|
catch
|
|
{
|
|
dictionary = new Dictionary<string, string>();
|
|
}
|
|
}
|
|
else
|
|
dictionary = new Dictionary<string, string>();
|
|
if (dictionary.ContainsKey(language))
|
|
dictionary[language] = value;
|
|
else
|
|
dictionary.Add(language, value);
|
|
|
|
var serializedDict = JsonConvert.SerializeObject(dictionary);
|
|
SetPropValue(GetType(), property, serializedDict, this);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Setzt alle übersetzungen für ein Feld mittels Reflection.
|
|
/// Achtung: das gesamte Dictionary wird ersetzt
|
|
/// </summary>
|
|
/// <param name="property">Name der Eigenschaft</param>
|
|
/// <param name="dictionary">Zu setzendes Dictionary</param>
|
|
public void Set(string property, Dictionary<string, string> dictionary)
|
|
{
|
|
property = property + "Localized";
|
|
var serializedDict = JsonConvert.SerializeObject(dictionary);
|
|
SetPropValue(GetType(), property, serializedDict, this);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Ruft eine Übersetzung direkt für ein Feld mittels Reflection
|
|
/// </summary>
|
|
/// <param name="property">Name der Eigenschaft</param>
|
|
/// <param name="language">ISO2 codierte Sprache</param>
|
|
/// <param name="allowEmpty">Gibt an ob leer als Rückgabe gültig ist und nicht die Default-Werte genommen werden sollen wenn eine Übersetzung fehlt</param>
|
|
/// <returns>Wert</returns>
|
|
public string Get(string property, string language, bool allowEmpty = false)
|
|
{
|
|
property = property + "Localized";
|
|
language = language.ToUpper();
|
|
var serialized = GetPropValue(GetType(), property, this);
|
|
if (serialized != null)
|
|
{
|
|
try
|
|
{
|
|
var dictionary = JsonConvert.DeserializeObject<Dictionary<string, string>>(serialized.ToString());
|
|
if (dictionary != null)
|
|
{
|
|
if (dictionary.ContainsKey(language) && !string.IsNullOrWhiteSpace(dictionary[language]))
|
|
return dictionary[language];
|
|
|
|
if (allowEmpty)
|
|
return string.Empty;
|
|
|
|
if (dictionary.ContainsKey(DefaultLanguage))
|
|
return dictionary[DefaultLanguage];
|
|
return dictionary.First().Value;
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
// ignored
|
|
}
|
|
}
|
|
return string.Empty;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Ruft alle Übersetzungen direkt für ein Feld mittels Reflection
|
|
/// </summary>
|
|
/// <param name="property">Name der Eigenschaft</param>
|
|
/// <returns>Dictionary mit allen Übersetzungen</returns>
|
|
public Dictionary<string, string> Get(string property)
|
|
{
|
|
property = property + "Localized";
|
|
var serialized = GetPropValue(GetType(), property, this);
|
|
if (serialized != null)
|
|
{
|
|
try
|
|
{
|
|
var dictionary = JsonConvert.DeserializeObject<Dictionary<string, string>>(serialized.ToString());
|
|
if (dictionary != null)
|
|
{
|
|
return dictionary;
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
// ignored
|
|
}
|
|
}
|
|
return new Dictionary<string, string>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gibt eine Liste aller verfügbaren Sprachen für ein Feld zurück.
|
|
/// Basiert auf den bereits gesetzten Sprachen
|
|
/// </summary>
|
|
/// <param name="property">Name der Eigenschaft</param>
|
|
/// <returns>Liste verfügbarer Sprachen</returns>
|
|
public List<string> GetLanguages(string property)
|
|
{
|
|
property = property + "Localized";
|
|
var serialized = GetPropValue(GetType(), property, this);
|
|
if (serialized != null)
|
|
{
|
|
try
|
|
{
|
|
var dictionary = JsonConvert.DeserializeObject<Dictionary<string, string>>(serialized.ToString());
|
|
if (dictionary != null)
|
|
{
|
|
return dictionary.Select(c => c.Key).ToList();
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
// ignored
|
|
}
|
|
}
|
|
return new List<string>();
|
|
}
|
|
|
|
#region private
|
|
|
|
/// <summary>
|
|
/// Ruft die Liste aller verfügbaren Sprachen mittels App-Settings ab.
|
|
/// </summary>
|
|
/// <returns>Liste verfügbare Sprachen ISO2 codiert</returns>
|
|
protected static IEnumerable<string> GetAvailableLanguages()
|
|
{
|
|
var languages = LocalizableHelper.Languages;
|
|
if (string.IsNullOrWhiteSpace(languages))
|
|
{
|
|
return new[] { LocalizableHelper.DefaultLanguage };
|
|
}
|
|
|
|
return languages.ToUpper().Split(',');
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gibt die Standard-Sprache zurück
|
|
/// </summary>
|
|
protected static string DefaultLanguage => LocalizableHelper.DefaultLanguage;
|
|
|
|
/// <summary>
|
|
/// Hilfsfunktion die den Wert einer Eigenschaft aus einem Objekt sucht und zurückgibt
|
|
/// </summary>
|
|
/// <param name="baseType">Basis-Typ des Objekts</param>
|
|
/// <param name="propertyName">Gesuchte Eigenschaft</param>
|
|
/// <param name="targetObject">Objekt das die Eigenschaft beinhaltet</param>
|
|
/// <param name="depth">Tiefe der Rekursion</param>
|
|
/// <returns>Wert der Eigenschaft oder null, wenn nicht gefunden</returns>
|
|
protected static object GetPropValue(Type baseType, string propertyName, object targetObject, int depth = 0)
|
|
{
|
|
if (depth >= 100)
|
|
throw new Exception("Recursion detected.");
|
|
|
|
string[] parts = propertyName.Split('.');
|
|
|
|
if (parts.Length > 1)
|
|
return GetPropValue(baseType.GetProperty(parts[0])?.PropertyType, parts.Skip(1).Aggregate((a, i) => a + "." + i), baseType.GetProperty(parts[0])?.GetValue(targetObject, null), depth + 1);
|
|
|
|
var properties = baseType.GetProperties(BindingFlags.SetProperty | BindingFlags.GetProperty | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public).ToList();
|
|
if (properties.Count > 0)
|
|
{
|
|
var property = properties.FirstOrDefault(c => c.Name == propertyName);
|
|
if (property != null)
|
|
return property.GetValue(targetObject, null);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Hilfsfunktion die versucht den Wert einer Eigenschaft zu setzen
|
|
/// </summary>
|
|
/// <param name="baseType">Basis-Typ des Objektes</param>
|
|
/// <param name="propertyName">Name der Eigenschaft</param>
|
|
/// <param name="value">Zu setzender Wert</param>
|
|
/// <param name="targetObject">Ziel-Objekt</param>
|
|
/// <param name="depth">Tiefe der Rekursion</param>
|
|
protected static void SetPropValue(Type baseType, string propertyName, object value, object targetObject, int depth = 0)
|
|
{
|
|
if (depth >= 100)
|
|
throw new Exception("Recursion detected.");
|
|
|
|
string[] parts = propertyName.Split('.');
|
|
|
|
if (parts.Length > 1)
|
|
SetPropValue(baseType.GetProperty(parts[0])?.PropertyType, parts.Skip(1).Aggregate((a, i) => a + "." + i), value, baseType.GetProperty(parts[0])?.GetValue(targetObject, null), depth + 1);
|
|
|
|
var properties = baseType.GetProperties(BindingFlags.SetProperty | BindingFlags.GetProperty | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public).ToList();
|
|
if (properties.Count > 0)
|
|
{
|
|
var property = properties.FirstOrDefault(c => c.Name == propertyName);
|
|
if (property != null)
|
|
property.SetValue(targetObject, value);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|