// 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(); } } }