changeset 71:40c09e57d213

Fixes #31: Break out Translations for language to own class * Make Translation class use new extracted class objects
author IBBoard <dev@ibboard.co.uk>
date Tue, 06 Apr 2010 18:08:43 +0000
parents 753be4b6c3b0
children cec6c4c0892d
files Lang/Translation.cs
diffstat 1 files changed, 51 insertions(+), 155 deletions(-) [+]
line wrap: on
line diff
--- 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
 {
 	/// <summary>
-	/// 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")
 	/// </summary>
 	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<string, string> translationsLocal = new Dictionary<string, string>();
-		private static Dictionary<string, string> translationsDefault = new Dictionary<string, string>();
-		private static XmlReaderSettings settings;
+		private static AbstractTranslationSet translations;
+		private static TranslationXmlLoader loader;
 
 		/// <summary>
-		/// 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.
 		/// </summary>
 		/// <param name="appPath">
-		/// 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.
 		/// </param>
 		/// <param name="language">
-		/// The language to use as the load language
+		/// The language to use as the loaded language
 		/// </param>
 		public static void InitialiseTranslations(string appPath, string language)
 		{
+			InitialiseTranslations(appPath);
+			LoadTranslationForLanguage(language);
+		}
+		
+		/// <summary>
+		/// Initialises the translation class for an application or source.
+		/// </summary>
+		/// <param name="appPath">
+		/// The full path that the contains the "translations" folder - normally the application directory path.
+		/// </param>
+		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<string,string>();
-				translationsLocal = new Dictionary<string,string>();
+				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;
-		}
-		
 		/// <summary>
-		/// Lazy-getter for XML reader settings. May throw a <see cref="TranslationLoadException"/> if there is a problem with the translation schema.
-		/// </summary>
-		/// <returns>
-		/// A <see cref="XmlReaderSettings"/> with the default values for validating the translation document against the translation schema
-		/// </returns>
-		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<string, string> translationTable)
-		{
-			try
-			{
-				XmlNodeList translations = doc.GetElementsByTagName("translation");				
-				Dictionary<string, string> tempTranslationTable = new Dictionary<string,string>();
-
-				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);
-		}
-		
-		/// <summary>
-		/// Resets the loaded translations
+		/// Resets the loaded translations and reverts to no translations.
 		/// </summary>
 		public static void Reset()
 		{
-			translationsLocal.Clear();
-			translationsDefault.Clear();
+			translations = null;
 		}
 
 		/// <summary>
-		/// 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.
 		/// </summary>
 		/// <param name="translationLang">
@@ -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;
 		}
 
 		/// <summary>
@@ -278,7 +179,7 @@
 		/// </returns>
 		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 @@
 		/// </returns>
 		public static string GetTranslationLanguage()
 		{
-			return lang;
+			return (translations!=null ? translations.LanguageCode : "");
 		}
 	}
 }