using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Globalization;
using Abp.Configuration.Startup;
using Abp.Dependency;
using Abp.Extensions;
using Castle.Core.Logging;
namespace Abp.Localization.Dictionaries
{
///
/// This class is used to build a localization source
/// which works on memory based dictionaries to find strings.
///
public class DictionaryBasedLocalizationSource : IDictionaryBasedLocalizationSource
{
///
/// Unique Name of the source.
///
public string Name { get; }
public ILocalizationDictionaryProvider DictionaryProvider { get; }
protected ILocalizationConfiguration LocalizationConfiguration { get; private set; }
private ILogger _logger;
///
///
///
///
///
public DictionaryBasedLocalizationSource(string name, ILocalizationDictionaryProvider dictionaryProvider)
{
Check.NotNullOrEmpty(name, nameof(name));
Check.NotNull(dictionaryProvider, nameof(dictionaryProvider));
Name = name;
DictionaryProvider = dictionaryProvider;
}
///
public virtual void Initialize(ILocalizationConfiguration configuration, IIocResolver iocResolver)
{
LocalizationConfiguration = configuration;
_logger = iocResolver.IsRegistered(typeof(ILoggerFactory))
? iocResolver.Resolve().Create(typeof(DictionaryBasedLocalizationSource))
: NullLogger.Instance;
DictionaryProvider.Initialize(Name);
}
///
public string GetString(string name)
{
return GetString(name, CultureInfo.CurrentUICulture);
}
///
public string GetString(string name, CultureInfo culture)
{
var value = GetStringOrNull(name, culture);
if (value == null)
{
return ReturnGivenNameOrThrowException(name, culture);
}
return value;
}
public string GetStringOrNull(string name, bool tryDefaults = true)
{
return GetStringOrNull(name, CultureInfo.CurrentUICulture, tryDefaults);
}
public string GetStringOrNull(string name, CultureInfo culture, bool tryDefaults = true)
{
var cultureName = culture.Name;
var dictionaries = DictionaryProvider.Dictionaries;
//Try to get from original dictionary (with country code)
ILocalizationDictionary originalDictionary;
if (dictionaries.TryGetValue(cultureName, out originalDictionary))
{
var strOriginal = originalDictionary.GetOrNull(name);
if (strOriginal != null)
{
return strOriginal.Value;
}
}
if (!tryDefaults)
{
return null;
}
//Try to get from same language dictionary (without country code)
if (cultureName.Contains("-")) //Example: "tr-TR" (length=5)
{
ILocalizationDictionary langDictionary;
if (dictionaries.TryGetValue(GetBaseCultureName(cultureName), out langDictionary))
{
var strLang = langDictionary.GetOrNull(name);
if (strLang != null)
{
return strLang.Value;
}
}
}
//Try to get from default language
var defaultDictionary = DictionaryProvider.DefaultDictionary;
if (defaultDictionary == null)
{
return null;
}
var strDefault = defaultDictionary.GetOrNull(name);
if (strDefault == null)
{
return null;
}
return strDefault.Value;
}
///
public IReadOnlyList GetAllStrings(bool includeDefaults = true)
{
return GetAllStrings(CultureInfo.CurrentUICulture, includeDefaults);
}
///
public IReadOnlyList GetAllStrings(CultureInfo culture, bool includeDefaults = true)
{
//TODO: Can be optimized (example: if it's already default dictionary, skip overriding)
var dictionaries = DictionaryProvider.Dictionaries;
//Create a temp dictionary to build
var allStrings = new Dictionary();
if (includeDefaults)
{
//Fill all strings from default dictionary
var defaultDictionary = DictionaryProvider.DefaultDictionary;
if (defaultDictionary != null)
{
foreach (var defaultDictString in defaultDictionary.GetAllStrings())
{
allStrings[defaultDictString.Name] = defaultDictString;
}
}
//Overwrite all strings from the language based on country culture
if (culture.Name.Contains("-"))
{
ILocalizationDictionary langDictionary;
if (dictionaries.TryGetValue(GetBaseCultureName(culture.Name), out langDictionary))
{
foreach (var langString in langDictionary.GetAllStrings())
{
allStrings[langString.Name] = langString;
}
}
}
}
//Overwrite all strings from the original dictionary
ILocalizationDictionary originalDictionary;
if (dictionaries.TryGetValue(culture.Name, out originalDictionary))
{
foreach (var originalLangString in originalDictionary.GetAllStrings())
{
allStrings[originalLangString.Name] = originalLangString;
}
}
return allStrings.Values.ToImmutableList();
}
///
/// Extends the source with given dictionary.
///
/// Dictionary to extend the source
public virtual void Extend(ILocalizationDictionary dictionary)
{
DictionaryProvider.Extend(dictionary);
}
protected virtual string ReturnGivenNameOrThrowException(string name, CultureInfo culture)
{
return LocalizationSourceHelper.ReturnGivenNameOrThrowException(
LocalizationConfiguration,
Name,
name,
culture,
_logger
);
}
private static string GetBaseCultureName(string cultureName)
{
return cultureName.Contains("-")
? cultureName.Left(cultureName.IndexOf("-", StringComparison.Ordinal))
: cultureName;
}
}
}