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; } } }