# HG changeset patch # User IBBoard # Date 1270577323 0 # Node ID 40c09e57d2134fa358a120332c57c67037d17491 # Parent 753be4b6c3b06ea7da82cfac5c4264e1135d6029 Fixes #31: Break out Translations for language to own class * Make Translation class use new extracted class objects diff -r 753be4b6c3b0 -r 40c09e57d213 Lang/Translation.cs --- a/Lang/Translation.cs Tue Apr 06 16:01:01 2010 +0000 +++ b/Lang/Translation.cs Tue Apr 06 18:08:43 2010 +0000 @@ -16,49 +16,57 @@ namespace IBBoard.Lang { /// - /// A basic string translator that loads a default language and a specified language and returns translated strings that correspond to translation IDs. - /// If the string doesn't exist in the specified language then the translator falls back to the default language. If the translation doesn't exist in the default language - /// then either a supplied value or a "no validation available" message is returned. + /// A basic string translator that a specified language and returns translated strings that correspond to translation IDs. + /// If the string doesn't exist in the specified language then the translator falls back defined 'super' languages. + /// If the translation doesn't exist in the hierarchy of languages then either a supplied value, null or a "no validation available" + /// message is returned, depending on the parameters supplied to the method. + /// + /// Loaded languages are referenced by two-character language code (e.g. "en" or "it") /// public class Translation - { - private static readonly string DEFAULT_LANGUAGE = "en"; + { private static readonly string DIVIDER_STRING = "-"; - private static string lang = ""; private static DirectoryInfo translationDir; - private static Dictionary translationsLocal = new Dictionary(); - private static Dictionary translationsDefault = new Dictionary(); - private static XmlReaderSettings settings; + private static AbstractTranslationSet translations; + private static TranslationXmlLoader loader; /// - /// Initialises the translations for the language specified and the default translations so that the Translation class can be used. + /// Initialises the translations and loads the specified language so that the Translation class can be used. /// Throws a TranslationLoadException if a problem occurred while loading translations. If this occurs then the translation methods can /// still be called but no translation will be performed. /// /// - /// The full path that the application is running from. Must contain the "translations" folder. + /// The full path that the contains the "translations" folder - normally the application directory path. /// /// - /// The language to use as the load language + /// The language to use as the loaded language /// public static void InitialiseTranslations(string appPath, string language) { + InitialiseTranslations(appPath); + LoadTranslationForLanguage(language); + } + + /// + /// Initialises the translation class for an application or source. + /// + /// + /// The full path that the contains the "translations" folder - normally the application directory path. + /// + public static void InitialiseTranslations(string appPath) + { InitialiseDefaults(appPath); - FileInfo file = GetTranslationFile(DEFAULT_LANGUAGE); - XmlDocument doc = LoadTranslationDocument(file); - LoadTranslationsFromDocument(doc, translationsDefault); - LoadTranslationForLanguage(language); } private static void InitialiseDefaults(string appPath) { - string translationPath = appPath.TrimEnd(Constants.DirectoryChar) + Constants.DirectoryString + "translations"; + string translationPath = Path.Combine(appPath, "translations"); if (Directory.Exists(translationPath)) { - translationsDefault = new Dictionary(); - translationsLocal = new Dictionary(); + translations = null; translationDir = new DirectoryInfo(translationPath); + loader = new TranslationXmlLoader(Path.Combine(appPath, "schemas/translation.xsd")); } else { @@ -66,133 +74,17 @@ } } - private static XmlDocument LoadTranslationDocument(FileInfo file) - { - XmlDocument doc = new XmlDocument(); - XmlReader valReader = XmlReader.Create(file.FullName, GetReaderSettings()); - - try - { - doc.Load(valReader); - } - catch (DirectoryNotFoundException ex) - { - throw new TranslationLoadException("Problem validating schema for translation: " + ex.Message, ex); - } - catch (XmlSchemaException ex) - { - throw new TranslationLoadException("Problem validating schema for translation: " + ex.Message, ex); - } - catch (XmlException ex) - { - throw new TranslationLoadException("Problem reading data for translation: " + ex.Message, ex); - } - finally - { - valReader.Close(); - } - - return doc; - } - /// - /// Lazy-getter for XML reader settings. May throw a if there is a problem with the translation schema. - /// - /// - /// A with the default values for validating the translation document against the translation schema - /// - private static XmlReaderSettings GetReaderSettings() - { - if (settings == null) - { - try - { - settings = new XmlReaderSettings(); - settings.ValidationType = ValidationType.Schema; - settings.ValidationFlags = XmlSchemaValidationFlags.ReportValidationWarnings; - settings.ValidationEventHandler+= new ValidationEventHandler(ValidationEventMethod); - XmlSchemaSet cache = new XmlSchemaSet(); - cache.Add("http://ibboard.co.uk/translation", translationDir.Parent.FullName + "/schemas/translation.xsd"); - settings.Schemas.Add(cache); - } - catch (DirectoryNotFoundException ex) - { - throw new TranslationLoadException("Problem validating schema for translation: " + ex.Message, ex); - } - catch (XmlSchemaException ex) - { - throw new TranslationLoadException("Problem validating schema for translation: " + ex.Message, ex); - } - catch (XmlException ex) - { - throw new TranslationLoadException("Problem reading data for schema: " + ex.Message, ex); - } - } - - return settings; - } - - private static FileInfo GetTranslationFile(string language) - { - FileInfo file = new FileInfo(translationDir.FullName + Constants.DirectoryString + language + ".translation"); - - if (!file.Exists) - { - throw new TranslationLoadException(language + ".translation could not be found in "+translationDir.FullName); - } - - return file; - } - - private static void LoadTranslationsFromDocument(XmlDocument doc, Dictionary translationTable) - { - try - { - XmlNodeList translations = doc.GetElementsByTagName("translation"); - Dictionary tempTranslationTable = new Dictionary(); - - foreach (XmlNode node in translations) - { - tempTranslationTable.Add(node.Attributes["id"].Value, node.InnerText); - } - - translationTable.Clear(); - - foreach (string key in tempTranslationTable.Keys) - { - string translation; - tempTranslationTable.TryGetValue(key, out translation); - translationTable.Add(key, translation); - } - } - catch(Exception ex) - { - throw new TranslationLoadException("Error while parsing " + GetLanguageOfDocument(doc)+" translation: "+ex.Message, ex); - } - } - - private static string GetLanguageOfDocument(XmlDocument doc) - { - return doc != null ? doc.DocumentElement.GetAttribute("lang") : ""; - } - - private static void ValidationEventMethod(object sender, ValidationEventArgs e) - { - throw new TranslationLoadException("Problem validating schema for translation: " + e.Exception.Message, e.Exception); - } - - /// - /// Resets the loaded translations + /// Resets the loaded translations and reverts to no translations. /// public static void Reset() { - translationsLocal.Clear(); - translationsDefault.Clear(); + translations = null; } /// - /// Loads translations for a given language and sets them as the local language. - /// hrows a TranslationLoadException if a problem occurred while loading translations. If this occurs then the translation methods can + /// Loads translations for a given language and sets them as the current language. + /// Throws a TranslationLoadException if a problem occurred while loading translations. If this occurs then the translation methods can /// still be called but all translations will fall back to the default translation. /// /// @@ -210,18 +102,27 @@ private static void LoadTranslationForLanguage(string translationLanguage) { - if (translationLanguage != DEFAULT_LANGUAGE && translationLanguage != "" && translationLanguage != null) + if (translationLanguage != "" && translationLanguage != null) { - FileInfo file = GetTranslationFile(translationLanguage); - XmlDocument doc = LoadTranslationDocument(file); - LoadTranslationsFromDocument(doc, translationsLocal); + translations = loader.LoadTranslations(GetTranslationFile(translationLanguage)); } else { - translationsLocal.Clear(); + translations = null; + } + } + + private static string GetTranslationFile(string language) + { + string translationFileName = language + ".translation"; + string path = Path.Combine(translationDir.FullName, translationFileName); + + if (!File.Exists(path)) + { + throw new TranslationLoadException(translationFileName +" could not be found in "+translationDir.FullName); } - lang = translationLanguage; + return path; } /// @@ -278,7 +179,7 @@ /// public static string GetTranslation(string translationID, string defaultTranslation, params object[] replacements) { - string trans = GetTranslationFromTables(translationID); + string trans = GetTranslationFromTranslationSet(translationID); if (trans == null) { @@ -290,18 +191,13 @@ return trans; } - private static string GetTranslationFromTables(string translationID) + private static string GetTranslationFromTranslationSet(string translationID) { string translation = null; - if (translationsLocal!=null) + if (translations!=null) { - translationsLocal.TryGetValue(translationID, out translation); - } - - if (translation == null) - { - translationsDefault.TryGetValue(translationID, out translation); + translation = translations[translationID]; } return translation; @@ -375,7 +271,7 @@ /// public static string GetTranslationLanguage() { - return lang; + return (translations!=null ? translations.LanguageCode : ""); } } }