diff --git a/src/Umbraco.Infrastructure/Services/Implement/LocalizedTextService.cs b/src/Umbraco.Infrastructure/Services/Implement/LocalizedTextService.cs
index 68fa4c37a5..24c37fbf76 100644
--- a/src/Umbraco.Infrastructure/Services/Implement/LocalizedTextService.cs
+++ b/src/Umbraco.Infrastructure/Services/Implement/LocalizedTextService.cs
@@ -8,63 +8,85 @@ using Microsoft.Extensions.Logging;
namespace Umbraco.Cms.Core.Services.Implement
{
+ ///
public class LocalizedTextService : ILocalizedTextService
{
private readonly ILogger _logger;
private readonly Lazy _fileSources;
- private IDictionary>> _dictionarySource => _dictionarySourceLazy.Value;
- private IDictionary> _noAreaDictionarySource => _noAreaDictionarySourceLazy.Value;
- private readonly Lazy>>> _dictionarySourceLazy;
- private readonly Lazy>> _noAreaDictionarySourceLazy;
- private readonly char[] _splitter = new[] { '/' };
+
+ private IDictionary>>> _dictionarySource =>
+ _dictionarySourceLazy.Value;
+
+ private IDictionary>> _noAreaDictionarySource =>
+ _noAreaDictionarySourceLazy.Value;
+
+ private readonly Lazy>>>>
+ _dictionarySourceLazy;
+
+ private readonly Lazy>>> _noAreaDictionarySourceLazy;
+
///
/// Initializes with a file sources instance
///
///
///
- public LocalizedTextService(Lazy fileSources, ILogger logger)
+ public LocalizedTextService(Lazy fileSources,
+ ILogger logger)
{
if (logger == null) throw new ArgumentNullException(nameof(logger));
_logger = logger;
if (fileSources == null) throw new ArgumentNullException(nameof(fileSources));
- _dictionarySourceLazy = new Lazy>>>(() => FileSourcesToAreaDictionarySources(fileSources.Value));
- _noAreaDictionarySourceLazy = new Lazy>>(() => FileSourcesToNoAreaDictionarySources(fileSources.Value));
+ _dictionarySourceLazy =
+ new Lazy>>>>(() =>
+ FileSourcesToAreaDictionarySources(fileSources.Value));
+ _noAreaDictionarySourceLazy =
+ new Lazy>>>(() =>
+ FileSourcesToNoAreaDictionarySources(fileSources.Value));
_fileSources = fileSources;
}
- private IDictionary> FileSourcesToNoAreaDictionarySources(LocalizedTextServiceFileSources fileSources)
+ private IDictionary>> FileSourcesToNoAreaDictionarySources(
+ LocalizedTextServiceFileSources fileSources)
{
var xmlSources = fileSources.GetXmlSources();
return XmlSourceToNoAreaDictionary(xmlSources);
}
- private IDictionary> XmlSourceToNoAreaDictionary(IDictionary> xmlSources)
+ private IDictionary>> XmlSourceToNoAreaDictionary(
+ IDictionary> xmlSources)
{
- var cultureNoAreaDictionary = new Dictionary>();
+ var cultureNoAreaDictionary = new Dictionary>>();
foreach (var xmlSource in xmlSources)
{
- var noAreaAliasValue = GetNoAreaStoredTranslations(xmlSources, xmlSource.Key);
+ var noAreaAliasValue =
+ new Lazy>(() => GetNoAreaStoredTranslations(xmlSources, xmlSource.Key));
cultureNoAreaDictionary.Add(xmlSource.Key, noAreaAliasValue);
}
+
return cultureNoAreaDictionary;
}
- private IDictionary>> FileSourcesToAreaDictionarySources(LocalizedTextServiceFileSources fileSources)
+ private IDictionary>>>
+ FileSourcesToAreaDictionarySources(LocalizedTextServiceFileSources fileSources)
{
var xmlSources = fileSources.GetXmlSources();
return XmlSourcesToAreaDictionary(xmlSources);
}
- private IDictionary>> XmlSourcesToAreaDictionary(IDictionary> xmlSources)
+ private IDictionary>>>
+ XmlSourcesToAreaDictionary(IDictionary> xmlSources)
{
- var cultureDictionary = new Dictionary>>();
+ var cultureDictionary =
+ new Dictionary>>>();
foreach (var xmlSource in xmlSources)
{
- var areaAliaValue = GetAreaStoredTranslations(xmlSources, xmlSource.Key);
+ var areaAliaValue =
+ new Lazy>>(() =>
+ GetAreaStoredTranslations(xmlSources, xmlSource.Key));
cultureDictionary.Add(xmlSource.Key, areaAliaValue);
-
}
+
return cultureDictionary;
}
@@ -73,14 +95,18 @@ namespace Umbraco.Cms.Core.Services.Implement
///
///
///
- public LocalizedTextService(IDictionary> source, ILogger logger)
+ public LocalizedTextService(IDictionary> source,
+ ILogger logger)
{
if (source == null) throw new ArgumentNullException(nameof(source));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
- _dictionarySourceLazy = new Lazy>>>(() => XmlSourcesToAreaDictionary(source));
- _noAreaDictionarySourceLazy = new Lazy>>(() => XmlSourceToNoAreaDictionary(source));
-
+ _dictionarySourceLazy =
+ new Lazy>>>>(() =>
+ XmlSourcesToAreaDictionary(source));
+ _noAreaDictionarySourceLazy =
+ new Lazy>>>(() =>
+ XmlSourceToNoAreaDictionary(source));
}
@@ -89,29 +115,44 @@ namespace Umbraco.Cms.Core.Services.Implement
///
///
///
- public LocalizedTextService(IDictionary>> source, ILogger logger)
+ public LocalizedTextService(
+ IDictionary>>> source,
+ ILogger logger)
{
var dictionarySource = source ?? throw new ArgumentNullException(nameof(source));
- _dictionarySourceLazy = new Lazy>>>(() => dictionarySource);
+ _dictionarySourceLazy =
+ new Lazy>>>>(() =>
+ dictionarySource);
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
- var cultureNoAreaDictionary = new Dictionary>();
+ var cultureNoAreaDictionary = new Dictionary>>();
foreach (var cultureDictionary in dictionarySource)
{
var areaAliaValue = GetAreaStoredTranslations(source, cultureDictionary.Key);
- var aliasValue = new Dictionary();
- foreach (var area in areaAliaValue)
+
+ cultureNoAreaDictionary.Add(cultureDictionary.Key,
+ new Lazy>(() => GetAliasValues(areaAliaValue)));
+ }
+
+ _noAreaDictionarySourceLazy =
+ new Lazy>>>(() => cultureNoAreaDictionary);
+ }
+
+ private static Dictionary GetAliasValues(
+ Dictionary> areaAliaValue)
+ {
+ var aliasValue = new Dictionary();
+ foreach (var area in areaAliaValue)
+ {
+ foreach (var alias in area.Value)
{
- foreach (var alias in area.Value)
+ if (!aliasValue.ContainsKey(alias.Key))
{
- if (!aliasValue.ContainsKey(alias.Key))
- {
- aliasValue.Add(alias.Key, alias.Value);
- }
+ aliasValue.Add(alias.Key, alias.Value);
}
}
- cultureNoAreaDictionary.Add(cultureDictionary.Key, aliasValue);
}
- _noAreaDictionarySourceLazy = new Lazy>>(() => cultureNoAreaDictionary);
+
+ return aliasValue;
}
public string Localize(string key, CultureInfo culture, IDictionary tokens = null)
@@ -122,12 +163,14 @@ namespace Umbraco.Cms.Core.Services.Implement
if (string.IsNullOrEmpty(key))
return string.Empty;
- var keyParts = key.Split(_splitter, StringSplitOptions.RemoveEmptyEntries);
+ var keyParts = key.Split(Constants.CharArrays.ForwardSlash, StringSplitOptions.RemoveEmptyEntries);
var area = keyParts.Length > 1 ? keyParts[0] : null;
var alias = keyParts.Length > 1 ? keyParts[1] : keyParts[0];
return Localize(area, alias, culture, tokens);
}
- public string Localize(string area, string alias, CultureInfo culture, IDictionary tokens = null)
+
+ public string Localize(string area, string alias, CultureInfo culture,
+ IDictionary tokens = null)
{
if (culture == null) throw new ArgumentNullException(nameof(culture));
@@ -153,12 +196,15 @@ namespace Umbraco.Cms.Core.Services.Implement
if (_dictionarySource.ContainsKey(culture) == false)
{
- _logger.LogWarning("The culture specified {Culture} was not found in any configured sources for this service", culture);
+ _logger.LogWarning(
+ "The culture specified {Culture} was not found in any configured sources for this service",
+ culture);
return new Dictionary(0);
}
+
IDictionary result = new Dictionary();
//convert all areas + keys to a single key with a '/'
- foreach (var area in _dictionarySource[culture])
+ foreach (var area in _dictionarySource[culture].Value)
{
foreach (var key in area.Value)
{
@@ -170,10 +216,12 @@ namespace Umbraco.Cms.Core.Services.Implement
}
}
}
+
return result;
}
- private Dictionary> GetAreaStoredTranslations(IDictionary> xmlSource, CultureInfo cult)
+ private IDictionary> GetAreaStoredTranslations(
+ IDictionary> xmlSource, CultureInfo cult)
{
var overallResult = new Dictionary>(StringComparer.InvariantCulture);
var areas = xmlSource[cult].Value.XPathSelectElements("//area");
@@ -189,6 +237,7 @@ namespace Umbraco.Cms.Core.Services.Implement
if (result.ContainsKey(dictionaryKey) == false)
result.Add(dictionaryKey, key.Value);
}
+
overallResult.Add(area.Attribute("alias").Value, result);
}
@@ -199,11 +248,13 @@ namespace Umbraco.Cms.Core.Services.Implement
var enUS = xmlSource[englishCulture].Value.XPathSelectElements("//area");
foreach (var area in enUS)
{
- IDictionary result = new Dictionary(StringComparer.InvariantCulture);
+ IDictionary
+ result = new Dictionary(StringComparer.InvariantCulture);
if (overallResult.ContainsKey(area.Attribute("alias").Value))
{
result = overallResult[area.Attribute("alias").Value];
}
+
var keys = area.XPathSelectElements("./key");
foreach (var key in keys)
{
@@ -213,15 +264,19 @@ namespace Umbraco.Cms.Core.Services.Implement
if (result.ContainsKey(dictionaryKey) == false)
result.Add(dictionaryKey, key.Value);
}
+
if (!overallResult.ContainsKey(area.Attribute("alias").Value))
{
overallResult.Add(area.Attribute("alias").Value, result);
}
}
}
+
return overallResult;
}
- private Dictionary GetNoAreaStoredTranslations(IDictionary> xmlSource, CultureInfo cult)
+
+ private Dictionary GetNoAreaStoredTranslations(
+ IDictionary> xmlSource, CultureInfo cult)
{
var result = new Dictionary(StringComparer.InvariantCulture);
var keys = xmlSource[cult].Value.XPathSelectElements("//key");
@@ -250,14 +305,18 @@ namespace Umbraco.Cms.Core.Services.Implement
result.Add(dictionaryKey, key.Value);
}
}
+
return result;
}
- private Dictionary> GetAreaStoredTranslations(IDictionary>> dictionarySource, CultureInfo cult)
+
+ private Dictionary> GetAreaStoredTranslations(
+ IDictionary>>> dictionarySource,
+ CultureInfo cult)
{
var overallResult = new Dictionary>(StringComparer.InvariantCulture);
var areaDict = dictionarySource[cult];
- foreach (var area in areaDict)
+ foreach (var area in areaDict.Value)
{
var result = new Dictionary(StringComparer.InvariantCulture);
var keys = area.Value.Keys;
@@ -267,8 +326,10 @@ namespace Umbraco.Cms.Core.Services.Implement
if (result.ContainsKey(key) == false)
result.Add(key, area.Value[key]);
}
+
overallResult.Add(area.Key, result);
}
+
return overallResult;
}
@@ -306,11 +367,14 @@ namespace Umbraco.Cms.Core.Services.Implement
return attempt ? attempt.Result : currentCulture;
}
- private string GetFromDictionarySource(CultureInfo culture, string area, string key, IDictionary tokens)
+ private string GetFromDictionarySource(CultureInfo culture, string area, string key,
+ IDictionary tokens)
{
if (_dictionarySource.ContainsKey(culture) == false)
{
- _logger.LogWarning("The culture specified {Culture} was not found in any configured sources for this service", culture);
+ _logger.LogWarning(
+ "The culture specified {Culture} was not found in any configured sources for this service",
+ culture);
return "[" + key + "]";
}
@@ -318,17 +382,18 @@ namespace Umbraco.Cms.Core.Services.Implement
string found = null;
if (string.IsNullOrWhiteSpace(area))
{
- _noAreaDictionarySource[culture].TryGetValue(key, out found);
+ _noAreaDictionarySource[culture].Value.TryGetValue(key, out found);
}
else
{
- if (_dictionarySource[culture].TryGetValue(area, out var areaDictionary))
+ if (_dictionarySource[culture].Value.TryGetValue(area, out var areaDictionary))
{
areaDictionary.TryGetValue(key, out found);
}
+
if (found == null)
{
- _noAreaDictionarySource[culture].TryGetValue(key, out found);
+ _noAreaDictionarySource[culture].Value.TryGetValue(key, out found);
}
}
@@ -341,6 +406,7 @@ namespace Umbraco.Cms.Core.Services.Implement
//NOTE: Based on how legacy works, the default text does not contain the area, just the key
return "[" + key + "]";
}
+
///
/// Parses the tokens in the value
///
@@ -370,20 +436,29 @@ namespace Umbraco.Cms.Core.Services.Implement
return value;
}
+ ///
+ /// Returns all key/values in storage for the given culture
+ ///
+ ///
public IDictionary> GetAllStoredValuesByAreaAndAlias(CultureInfo culture)
{
- if (culture == null) throw new ArgumentNullException("culture");
+ if (culture == null)
+ {
+ throw new ArgumentNullException("culture");
+ }
// TODO: Hack, see notes on ConvertToSupportedCultureWithRegionCode
culture = ConvertToSupportedCultureWithRegionCode(culture);
if (_dictionarySource.ContainsKey(culture) == false)
{
- _logger.LogWarning("The culture specified {Culture} was not found in any configured sources for this service", culture);
+ _logger.LogWarning(
+ "The culture specified {Culture} was not found in any configured sources for this service",
+ culture);
return new Dictionary>(0);
}
- return _dictionarySource[culture];
+ return _dictionarySource[culture].Value;
}
}
}
diff --git a/tests/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Services/LocalizedTextServiceTests.cs b/tests/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Services/LocalizedTextServiceTests.cs
index ea4c043aa2..497af66d63 100644
--- a/tests/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Services/LocalizedTextServiceTests.cs
+++ b/tests/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Services/LocalizedTextServiceTests.cs
@@ -23,10 +23,10 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Services
{
var culture = CultureInfo.GetCultureInfo("en-US");
var txtService = new LocalizedTextService(
- new Dictionary>>
+ new Dictionary>>>
{
{
- culture, new Dictionary>
+ culture, new Lazy>>(() => new Dictionary>
{
{
"testArea1", new Dictionary
@@ -42,7 +42,7 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Services
{ "blah2", "blahValue2" }
}
},
- }
+ })
}
}, s_loggerFactory.CreateLogger());
@@ -119,10 +119,10 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Services
{
var culture = CultureInfo.GetCultureInfo("en-US");
var txtService = new LocalizedTextService(
- new Dictionary>>
+ new Dictionary>>>
{
{
- culture, new Dictionary>
+ culture, new Lazy>>(() => new Dictionary>
{
{
"testArea", new Dictionary
@@ -130,7 +130,7 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Services
{ "testKey", "testValue" }
}
}
- }
+ })
}
}, s_loggerFactory.CreateLogger());
@@ -144,10 +144,10 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Services
{
var culture = CultureInfo.GetCultureInfo("en-US");
var txtService = new LocalizedTextService(
- new Dictionary>>
+ new Dictionary>>>
{
{
- culture, new Dictionary>
+ culture, new Lazy>>(() => new Dictionary>
{
{
"testArea", new Dictionary
@@ -155,7 +155,8 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Services
{ "testKey", "testValue" }
}
}
- }
+ })
+
}
}, s_loggerFactory.CreateLogger());
@@ -169,10 +170,10 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Services
{
var culture = CultureInfo.GetCultureInfo("en-US");
var txtService = new LocalizedTextService(
- new Dictionary>>
+ new Dictionary>>>
{
{
- culture, new Dictionary>
+ culture, new Lazy>>(() => new Dictionary>
{
{
"testArea", new Dictionary
@@ -180,7 +181,7 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Services
{ "testKey", "testValue" }
}
}
- }
+ })
}
}, s_loggerFactory.CreateLogger());
@@ -195,10 +196,10 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Services
{
var culture = CultureInfo.GetCultureInfo("en-US");
var txtService = new LocalizedTextService(
- new Dictionary>>
+ new Dictionary>>>
{
{
- culture, new Dictionary>
+ culture, new Lazy>>(() => new Dictionary>
{
{
"testArea", new Dictionary
@@ -206,7 +207,7 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Services
{ "testKey", "testValue" }
}
}
- }
+ })
}
}, s_loggerFactory.CreateLogger());
@@ -220,10 +221,10 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Services
{
var culture = CultureInfo.GetCultureInfo("en-US");
var txtService = new LocalizedTextService(
- new Dictionary>>
+ new Dictionary>>>
{
{
- culture, new Dictionary>
+ culture, new Lazy>>(() => new Dictionary>
{
{
"testArea", new Dictionary
@@ -231,7 +232,8 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Services
{ "testKey", "Hello %0%, you are such a %1% %2%" }
}
}
- }
+ })
+
}
}, s_loggerFactory.CreateLogger());
@@ -350,10 +352,10 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Services
{
var culture = CultureInfo.GetCultureInfo("en-US");
var txtService = new LocalizedTextService(
- new Dictionary>>
+ new Dictionary>>>
{
{
- culture, new Dictionary>
+ culture, new Lazy>>(() => new Dictionary>
{
{
"testArea", new Dictionary
@@ -361,7 +363,7 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Services
{ "testKey", "testValue" }
}
}
- }
+ })
}
}, s_loggerFactory.CreateLogger());