// Copyright (C) Stichting Deltares 2019. All rights reserved.
//
// This file is part of the Dam Engine.
//
// The Dam Engine is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see .
//
// All names, logos, and references to "Deltares" are registered trademarks of
// Stichting Deltares and remain full property of Stichting Deltares at all times.
// All rights reserved.
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Xml;
namespace Deltares.DamEngine.Data.Standard.Language
{
///
/// Class LocalizationManager
///
public class LocalizationManager
{
///
/// The default language
///
private const LanguageType defaultLanguage = LanguageType.English;
private static LanguageType currentLanguageType = defaultLanguage;
private static CultureInfo currentCultureInfo = new CultureInfo(defaultLanguage.GetLanguageString());
private static readonly Dictionary> Translations
= new Dictionary>();
private static readonly Dictionary> TranslationLists
= new Dictionary>();
private static readonly List DirtyAssemblies
= new List();
///
/// Gets or sets the current language
///
public static LanguageType CurrentLanguage
{
get
{
return currentLanguageType;
}
set
{
if (value != currentLanguageType || currentCultureInfo == null)
{
currentLanguageType = value;
currentCultureInfo = new CultureInfo(value.GetLanguageString());
}
}
}
///
/// Gets the translated text.
///
/// The type.
/// The identifier.
///
public static string GetTranslatedText(Type type, string id)
{
if (type == null || string.IsNullOrEmpty(id))
{
return id;
}
var assembly = type.Assembly;
if (!Translations.ContainsKey(assembly))
{
CreateTables(assembly);
LoadLanguage(assembly);
}
if (Translations[assembly].ContainsKey(id))
{
return Translations[assembly][id][currentLanguageType];
}
if (!id.Equals(""))
{
UpdateTranslation(type, id, id);
}
return id;
}
///
/// Gets the translated text.
///
/// The target object.
/// The identifier.
///
public static string GetTranslatedText(object targetObject, string id)
{
return targetObject == null ?
id : GetTranslatedText(targetObject.GetType(), id);
}
///
/// Updates the translation.
///
/// The type.
/// The identifier.
/// The english.
private static void UpdateTranslation(Type type, string identifier, string english)
{
if (!Translations.ContainsKey(type.Assembly))
{
CreateTables(type.Assembly);
LoadLanguage(type.Assembly);
}
if (!Translations[type.Assembly].ContainsKey(identifier))
{
var translateInfo = new TranslateInfo
{
Id = identifier
};
foreach (LanguageType languageType in Enum.GetValues(typeof(LanguageType)))
{
if (languageType == LanguageType.English)
{
translateInfo[languageType] = english;
}
else
{
translateInfo[languageType] = languageType.GetShortLanguageString() + "-" + english;
}
}
Translations[type.Assembly][identifier] = translateInfo;
TranslationLists[type.Assembly].Add(translateInfo);
}
else
{
var translateInfo = Translations[type.Assembly][identifier];
foreach (LanguageType languageType in Enum.GetValues(typeof(LanguageType)))
{
if (languageType == LanguageType.English)
{
translateInfo[languageType] = english;
}
else
{
var translation = translateInfo[languageType];
var prefix = languageType.GetShortLanguageString() + "-";
var defaultTranslation = prefix + english;
if (string.IsNullOrEmpty(translation) || translation == defaultTranslation)
{
translateInfo[languageType] = prefix + english;
}
else if (!translation.StartsWith(prefix))
{
translateInfo[languageType] = translation;
}
}
}
}
if (!DirtyAssemblies.Contains(type.Assembly))
{
DirtyAssemblies.Add(type.Assembly);
}
}
private static void LoadLanguage(Assembly assembly)
{
var translationFiles = assembly
.GetManifestResourceNames()
.Where(res => res.EndsWith("Translations.xml"));
foreach (var resourceName in translationFiles)
{
var resource = assembly.GetManifestResourceStream(resourceName);
LoadDictionary(assembly, resource);
}
}
private static void LoadDictionary(Assembly assembly, Stream translatedXmlFilePath)
{
CreateTables(assembly);
var translationsTable = Translations[assembly];
var reader = XmlReader.Create(translatedXmlFilePath);
var xmlDocument = new XmlDocument();
xmlDocument.Load(reader);
xmlDocument.Normalize();
var xmlNodeList = xmlDocument.GetElementsByTagName(@"Translation");
//Validating the translated xml file against schema definition
//string errorString = "";
//XmlSchemaValidator.ValidXmlDoc(this.translatedXmlFilePath, this.xsdFilePath, ref errorString);
foreach (XmlNode node in xmlNodeList)
{
if (node.Attributes == null)
{
throw new ArgumentException("node has no attributes");
}
var attr = node.Attributes["ID"];
var id = attr.Value;
var translateInfo = new TranslateInfo
{
Id = id
};
foreach (LanguageType type in Enum.GetValues(typeof(LanguageType)))
{
var translation = node.Attributes[type.GetLanguageString()].Value;
if (translation != null)
{
translateInfo[type] = translation;
}
}
translationsTable[id] = translateInfo;
TranslationLists[assembly].Add(translateInfo);
}
reader.Close();
Translations[assembly] = translationsTable;
}
private static void CreateTables(Assembly assembly)
{
if (Translations.ContainsKey(assembly))
{
return;
}
Translations[assembly] = new Dictionary();
TranslationLists[assembly] = new List();
}
}
}