Skip to content
This repository has been archived by the owner on Oct 23, 2023. It is now read-only.

Commit

Permalink
pushing i18n format #64
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexTeixeira committed Apr 25, 2020
1 parent 367407b commit 72ea4fc
Show file tree
Hide file tree
Showing 37 changed files with 631 additions and 81 deletions.
@@ -1,19 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">

<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFrameworks>netcoreapp3.0;netcoreapp3.1</TargetFrameworks>
<PackageId>Askmethat.Aspnet.JsonLocalizer</PackageId>
<PackageVersion>$(Version)</PackageVersion>
<Authors>TEIXEIRA Alexandre</Authors>
<Description>Json Localizer library for .NetStandard and .NetCore Asp.net projects</Description>
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
<PackageReleaseNotes></PackageReleaseNotes>
<PackageReleaseNotes>See associated version in https://github.com/AlexTeixeira/Askmethat-Aspnet-JsonLocalizer/releases</PackageReleaseNotes>
<PackageLicenseUrl>https://github.com/AlexTeixeira/Askmethat-Aspnet-JsonLocalizer/blob/master/LICENSE</PackageLicenseUrl>
<PackageProjectUrl>https://github.com/AlexTeixeira/Askmethat-Aspnet-JsonLocalizer</PackageProjectUrl>
<Copyright>Copyright 2019 (c) Alexandre TEIXEIRA.</Copyright>
<PackageTags>Json Localizer Globalization netcore netstandard</PackageTags>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Version>3.1.0</Version>
<Version>3.0.0</Version>
<RepositoryUrl>https://github.com/AlexTeixeira/Askmethat-Aspnet-JsonLocalizer</RepositoryUrl>
<RepositoryType>Git</RepositoryType>
</PropertyGroup>
Expand Down
Expand Up @@ -2,6 +2,7 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Localization;
using System;
using Askmethat.Aspnet.JsonLocalizer.JsonOptions;

namespace Askmethat.Aspnet.JsonLocalizer.Extensions
{
Expand Down
Expand Up @@ -2,11 +2,12 @@
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using Askmethat.Aspnet.JsonLocalizer.Extensions;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Localization;

namespace Askmethat.Aspnet.JsonLocalizer.Extensions
namespace Askmethat.Aspnet.JsonLocalizer.JsonOptions
{
public class JsonLocalizationOptions : LocalizationOptions
{
Expand Down Expand Up @@ -114,5 +115,10 @@ public HashSet<CultureInfo> SupportedCultureInfos
/// Define logging behavior when a translation is not found.
/// </summary>
public MissingTranslationLogBehavior MissingTranslationLogBehavior { get; set; } = MissingTranslationLogBehavior.LogConsoleError;

/// <summary>
/// Define JSON Files management. See documentation for more information
/// </summary>
public LocalizationMode LocalizationMode { get; set; } = LocalizationMode.Basic;
}
}
@@ -0,0 +1,8 @@
namespace Askmethat.Aspnet.JsonLocalizer.JsonOptions
{
public enum LocalizationMode
{
Basic,
I18n
}
}
Expand Up @@ -8,6 +8,7 @@
using System.Globalization;
using System.IO;
using System.Linq;
using Askmethat.Aspnet.JsonLocalizer.JsonOptions;

namespace Askmethat.Aspnet.JsonLocalizer.Localizer
{
Expand Down
Expand Up @@ -7,6 +7,8 @@
using Askmethat.Aspnet.JsonLocalizer.Caching;
using Askmethat.Aspnet.JsonLocalizer.Extensions;
using Askmethat.Aspnet.JsonLocalizer.Format;
using Askmethat.Aspnet.JsonLocalizer.JsonOptions;
using Askmethat.Aspnet.JsonLocalizer.Localizer.Modes;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;

Expand All @@ -31,6 +33,11 @@ public JsonStringLocalizerBase(IOptions<JsonLocalizationOptions> localizationOpt
_baseName = CleanBaseName(baseName);
_localizationOptions = localizationOptions;

if (_localizationOptions.Value.LocalizationMode == LocalizationMode.I18n && _localizationOptions.Value.UseBaseName)
{
throw new ArgumentException("UseBaseName can't be activated with I18n localisation mode");
}

_memCache = _localizationOptions.Value.DistributedCache != null ?
new CacheHelper(_localizationOptions.Value.DistributedCache) :
new CacheHelper(_localizationOptions.Value.Caching);
Expand Down Expand Up @@ -105,29 +112,8 @@ private void ConstructLocalizationObject(string jsonPath, CultureInfo currentCul

IEnumerable<string> myFiles = GetMatchingJsonFiles(jsonPath);

foreach (string file in myFiles)
{
ConcurrentDictionary<string, JsonLocalizationFormat> tempLocalization = JsonConvert.DeserializeObject<ConcurrentDictionary<string, JsonLocalizationFormat>>(File.ReadAllText(file, _localizationOptions.Value.FileEncoding));
if (tempLocalization == null)
{
continue;
}
foreach (KeyValuePair<string, JsonLocalizationFormat> temp in tempLocalization)
{
LocalizatedFormat localizedValue = GetLocalizedValue(currentCulture, temp);
if (!(localizedValue.Value is null))
{
if (!localization.ContainsKey(temp.Key))
{
localization.TryAdd(temp.Key, localizedValue);
}
else if (localization[temp.Key].IsParent)
{
localization[temp.Key] = localizedValue;
}
}
}
}
localization = LocalizationModeFactory.GetLocalisationFromMode(_localizationOptions.Value.LocalizationMode)
.ConstructLocalization(myFiles, currentCulture, _localizationOptions.Value);
}

private IEnumerable<string> GetMatchingJsonFiles(string jsonPath)
Expand Down Expand Up @@ -215,29 +201,5 @@ private string CleanBaseName(string baseName)
}
}
#endregion

private LocalizatedFormat GetLocalizedValue(CultureInfo currentCulture, KeyValuePair<string, JsonLocalizationFormat> temp)
{
bool isParent = false;
string value = temp.Value.Values.FirstOrDefault(s => string.Equals(s.Key, currentCulture.Name, StringComparison.OrdinalIgnoreCase)).Value;
if (value is null)
{
isParent = true;
value = temp.Value.Values.FirstOrDefault(s => string.Equals(s.Key, currentCulture.Parent.Name, StringComparison.OrdinalIgnoreCase)).Value;
if (value is null)
{
value = temp.Value.Values.FirstOrDefault(s => string.IsNullOrWhiteSpace(s.Key)).Value;
if (value is null && _localizationOptions.Value.DefaultCulture != null)
{
value = temp.Value.Values.FirstOrDefault(s => string.Equals(s.Key, _localizationOptions.Value.DefaultCulture.Name, StringComparison.OrdinalIgnoreCase)).Value;
}
}
}
return new LocalizatedFormat()
{
IsParent = isParent,
Value = value
};
}
}
}
Expand Up @@ -3,6 +3,7 @@
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Options;
using System;
using Askmethat.Aspnet.JsonLocalizer.JsonOptions;

namespace Askmethat.Aspnet.JsonLocalizer.Localizer
{
Expand Down
@@ -1,4 +1,4 @@
using Askmethat.Aspnet.JsonLocalizer.Extensions;
using Askmethat.Aspnet.JsonLocalizer.JsonOptions;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Options;
Expand Down
@@ -0,0 +1,15 @@
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Globalization;
using Askmethat.Aspnet.JsonLocalizer.Format;
using Askmethat.Aspnet.JsonLocalizer.JsonOptions;

namespace Askmethat.Aspnet.JsonLocalizer.Localizer.Modes
{
internal interface ILocalisationModeGenerator
{
ConcurrentDictionary<string, LocalizatedFormat> ConstructLocalization(
IEnumerable<string> myFiles, CultureInfo currentCulture, JsonLocalizationOptions options);

}
}
@@ -0,0 +1,83 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using Askmethat.Aspnet.JsonLocalizer.Format;
using Askmethat.Aspnet.JsonLocalizer.JsonOptions;
using Newtonsoft.Json;

namespace Askmethat.Aspnet.JsonLocalizer.Localizer.Modes
{
internal class LocalisationBasicModeGenerator : ILocalisationModeGenerator
{
private ConcurrentDictionary<string, LocalizatedFormat> localization =
new ConcurrentDictionary<string, LocalizatedFormat>();

private JsonLocalizationOptions _options;

public ConcurrentDictionary<string, LocalizatedFormat> ConstructLocalization(
IEnumerable<string> myFiles, CultureInfo currentCulture, JsonLocalizationOptions options)
{
_options = options;

foreach (string file in myFiles)
{
ConcurrentDictionary<string, JsonLocalizationFormat> tempLocalization = LocalisationModeHelpers.ReadAndDeserializeFile<string,JsonLocalizationFormat>(file, options.FileEncoding);

if (tempLocalization == null)
{
continue;
}

foreach (KeyValuePair<string, JsonLocalizationFormat> temp in tempLocalization)
{
LocalizatedFormat localizedValue = GetLocalizedValue(currentCulture, temp);
if (!(localizedValue.Value is null))
{
if (!localization.ContainsKey(temp.Key))
{
localization.TryAdd(temp.Key, localizedValue);
}
else if (localization[temp.Key].IsParent)
{
localization[temp.Key] = localizedValue;
}
}
}
}

return localization;
}

private LocalizatedFormat GetLocalizedValue(CultureInfo currentCulture,
KeyValuePair<string, JsonLocalizationFormat> temp)
{
bool isParent = false;
string value = temp.Value.Values.FirstOrDefault(s =>
string.Equals(s.Key, currentCulture.Name, StringComparison.OrdinalIgnoreCase)).Value;
if (value is null)
{
isParent = true;
value = temp.Value.Values.FirstOrDefault(s =>
string.Equals(s.Key, currentCulture.Parent.Name, StringComparison.OrdinalIgnoreCase)).Value;
if (value is null)
{
value = temp.Value.Values.FirstOrDefault(s => string.IsNullOrWhiteSpace(s.Key)).Value;
if (value is null && _options.DefaultCulture != null)
{
value = temp.Value.Values.FirstOrDefault(s => string.Equals(s.Key,
_options.DefaultCulture.Name, StringComparison.OrdinalIgnoreCase)).Value;
}
}
}

return new LocalizatedFormat()
{
IsParent = isParent,
Value = value
};
}
}
}
@@ -0,0 +1,96 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using Askmethat.Aspnet.JsonLocalizer.Format;
using Askmethat.Aspnet.JsonLocalizer.JsonOptions;
using Newtonsoft.Json;

namespace Askmethat.Aspnet.JsonLocalizer.Localizer.Modes
{
internal class LocalisationI18nModeGenerator : ILocalisationModeGenerator
{
private ConcurrentDictionary<string, LocalizatedFormat> localization =
new ConcurrentDictionary<string, LocalizatedFormat>();

private JsonLocalizationOptions _options;

public ConcurrentDictionary<string, LocalizatedFormat> ConstructLocalization(IEnumerable<string> myFiles,
CultureInfo currentCulture,
JsonLocalizationOptions options)
{
_options = options;

var neutralFile = myFiles.FirstOrDefault(file => file.Split("/")
.Last().Count(s => s.CompareTo('.') == 0) == 1);

var cultureExistInFiles = myFiles.Any(file => file.Split("/").Any(
s => s.Contains(currentCulture.Name, StringComparison.OrdinalIgnoreCase)
|| s.Contains(currentCulture.Parent.Name, StringComparison.OrdinalIgnoreCase)
)) && currentCulture.DisplayName != CultureInfo.InvariantCulture.ThreeLetterISOLanguageName;

if (cultureExistInFiles)
{
foreach (string file in myFiles)
{
var splittedFiles = file.Split("/");
var fileCulture = new CultureInfo(splittedFiles[^1].Split(".")[1]);

var isParent =
fileCulture.Name.Equals(currentCulture.Parent.Name, StringComparison.OrdinalIgnoreCase);

if (fileCulture.Name.Equals(currentCulture.Name, StringComparison.OrdinalIgnoreCase) ||
isParent && fileCulture.Name != "json")
{
AddValueToLocalization(options, file, isParent);
}
}
}
else
{
AddValueToLocalization(options, neutralFile, true);
}

return localization;
}

private void AddValueToLocalization(JsonLocalizationOptions options, string file, bool isParent)
{
ConcurrentDictionary<string, string> tempLocalization =
LocalisationModeHelpers.ReadAndDeserializeFile<string, string>(file, options.FileEncoding);

if (tempLocalization == null)
{
return;
}

foreach (var temp in tempLocalization)
{
LocalizatedFormat localizedValue = GetLocalizedValue(temp, isParent);

if (!(localizedValue.Value is null))
{
if (!localization.ContainsKey(temp.Key))
{
localization.TryAdd(temp.Key, localizedValue);
}
else if (localization[temp.Key].IsParent)
{
localization[temp.Key] = localizedValue;
}
}
}
}

private LocalizatedFormat GetLocalizedValue(KeyValuePair<string, string> temp, bool isParent)
{
return new LocalizatedFormat()
{
IsParent = isParent,
Value = temp.Value
};
}
}
}
@@ -0,0 +1,18 @@
using System.Collections.Concurrent;
using System.IO;
using System.Text;
using Askmethat.Aspnet.JsonLocalizer.JsonOptions;
using Newtonsoft.Json;

namespace Askmethat.Aspnet.JsonLocalizer.Localizer.Modes
{
public static class LocalisationModeHelpers
{
public static ConcurrentDictionary<T, U> ReadAndDeserializeFile<T,U>(string file, Encoding encoding)
{
return
JsonConvert.DeserializeObject<ConcurrentDictionary<T, U>>(
File.ReadAllText(file, encoding));
}
}
}

0 comments on commit 72ea4fc

Please sign in to comment.