/////////////////////////////////////////////////////////// // LocalizedTexts.cs // Implementation of Class LocalizedTexts // CSLA type: Editable root collection // Created on: 11-Oct-2004 // Object design: John // Coded: John 11-Oct-2004 /////////////////////////////////////////////////////////// using System; using System.Data; using CSLA.Data; using GZTW.Data; using CSLA; using System.Collections; using System.IO; using System.Runtime.Serialization.Formatters.Binary; using System.Runtime.Serialization; namespace GZTW.AyaNova.BLL { /// /// Collection of localized text editable root objects /// This is for editing, not read only display in a user interface, for that see instead. /// [Serializable] public class LocalizedTexts : BusinessCollectionBase { #region Constructor //Private constructor prevents direction instantiation private LocalizedTexts() { AllowSort=false; AllowFind=true; AllowEdit=true; AllowNew=true; AllowRemove=true; } #endregion #region Business properties and methods /// /// Locale key so that generic list editor /// UI code knows what title to give the list in a /// grid /// public string LocaleKey { get { return "LocalizedText.Label.List"; } } /// /// Retrieve LocalizedText by index /// /// Index public LocalizedText this[int Item] { get { return (LocalizedText) List[Item]; } } /// /// Remove LocalizedText by passing it in /// /// public void Remove(LocalizedText obj) { List.Remove(obj); } /// /// Remove all items from list /// public void RemoveAll() { List.Clear(); } /// /// Add a new LocalizedText to the collection /// public LocalizedText Add() { LocalizedText child=LocalizedText.NewItemChild(); List.Add(child); return child; } /// /// Add LocalizedText by passing it in /// /// public void Add(LocalizedText obj) { List.Add(obj); } /// /// /// /// protected override object OnAddNew() { LocalizedText child=LocalizedText.NewItemChild(); List.Add(child); return child; } #endregion #region Contains /// /// Check if item in collection /// /// public bool Contains(LocalizedText obj) { foreach (LocalizedText child in List) { if(child.Equals(obj)) return true; } return false; } /// /// Check if item in deleted collection /// /// public bool ContainsDeleted(LocalizedText obj) { foreach (LocalizedText child in deletedList) { if(child.Equals(obj)) return true; } return false; } #endregion #region Static methods /// /// NewItems /// /// internal static LocalizedTexts NewItems() { return new LocalizedTexts(); } /// /// Get item collection (Root collection style) /// Gets all localized text in database (no filter) /// /// /// public static LocalizedTexts GetItems() { LocalizedTexts col = new LocalizedTexts(); return (LocalizedTexts)DataPortal.Fetch(new Criteria("","",false,false)); } /// /// Get item collection (Root collection style) /// Gets all editable (non custom) localized text in database for locale specified /// /// /// public static LocalizedTexts GetItemsForLocale(string Locale) { LocalizedTexts col = new LocalizedTexts(); return (LocalizedTexts)DataPortal.Fetch(new Criteria("",Locale,false,false)); } /// /// Get item collection (Root collection style) /// Gets all localized text in database for locale specified /// including custom fields /// /// Used for export by this class only /// /// /// private static LocalizedTexts GetItemsForLocaleExport(string Locale) { LocalizedTexts col = new LocalizedTexts(); return (LocalizedTexts)DataPortal.Fetch(new Criteria("",Locale, true,false)); } /// /// Get custom field items only for object specified /// used when customizing custom fields for objects /// that have 'em (Root collection style) /// /// Object to retrieve the custom fiels for /// public static LocalizedTexts GetCustomItemsForSingleObject(string sObjectName) { LocalizedTexts col = new LocalizedTexts(); return (LocalizedTexts)DataPortal.Fetch(new Criteria(sObjectName,"",false,true)); } /// /// Create a new localized text collection for a new locale /// by copying the contents of an existing locale /// /// This method will throw an exception if there is a locale /// already present in the database with the same name as the /// newLocaleName parameter. /// /// 15 characters maximum. Longer strings will be truncated to 15 characters /// The name of an existing locale to act as the source locale public static void CopyLocale(string newLocaleName,string sourceLocale) { if(newLocaleName.Length>15) newLocaleName=newLocaleName.Substring(0,15); NewLocale.CreateNewLocale(newLocaleName,sourceLocale); } /// /// /// /// public static void DeleteLocale(string Locale) { if(Locale=="English") throw new ApplicationException("DeleteLocale: Can not delete default locale"); LocaleDeleter.DeleteLocale(Locale); } #endregion #region Serialization #region binary /// /// Export Locale localized text collection to an AyaNova Transportable /// Locale file (.AYL) at the path indicated /// /// Locale name (i.e. "English") /// Full path (including file name) to export to. NOTE: By convention, all AyaNova Locale file names end in the extension .AYL public static void Export(string Locale, string Path) { //Retrieve source collection LocalizedTexts source= LocalizedTexts.GetItemsForLocaleExport(Locale); if(source.Count<1) throw new ApplicationException("Error: Source locale doesn't appear to have any records or doesn't exist"); LocalePortable lp=new LocalePortable(); lp.Items=new ArrayList(source.Count); lp.Locale=source[0].Locale; foreach(LocalizedText l in source) { LocalizedTextPortable p=new LocalizedTextPortable(); p.DisplayText=l.DisplayText; p.Key=l.Key; lp.Items.Add(p); } FileStream fs = new FileStream(Path, FileMode.Create); // Construct a BinaryFormatter and use it to serialize the data to the stream. BinaryFormatter formatter = new BinaryFormatter(); formatter.AssemblyFormat=System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple; try { formatter.Serialize(fs, lp); } catch { //Console.WriteLine("Failed to serialize. Reason: " + e.Message); throw; } finally { fs.Close(); } } /// /// Import Locale from an AyaNova Transportable Locale file (.AYL) at the path indicated /// /// Full path (including file name) to import. /// NOTE: By convention, all AyaNova locale file names end in the extension .AYL /// False if Locale with that name already exists, true for any other result public static bool Import(string Path) { LocalePortable lp =null; FileStream fs = new FileStream(Path, FileMode.Open); try { // Construct a BinaryFormatter and use it to de-serialize the data from the stream. BinaryFormatter formatter = new BinaryFormatter(); formatter.AssemblyFormat=System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple; lp=(LocalePortable)formatter.Deserialize(fs); } catch { //Console.WriteLine("Failed to serialize. Reason: " + e.Message); throw; } finally { fs.Close(); } LocaleList ll=LocaleList.GetList(); if(ll.Contains(lp.Locale)) return false; if(lp.Items.Count<1) throw new ApplicationException("Import: file is missing localized text keys, nothing to import"); LocalizedTexts dest = LocalizedTexts.NewItems(); foreach(LocalizedTextPortable o in lp.Items) { LocalizedText l=dest.Add(); l.Locale=lp.Locale; l.Key=o.Key; l.DisplayText=o.DisplayText; } dest.Save(); return true; } #endregion binary #region XML /// /// Export Locale localized text collection to an XML file /// at the path indicated /// /// Locale name (i.e. "English") /// Full path (including file name) to export to. public static void ExportXML(string Locale, string Path) { DataTable dt=new DataTable("LT"); //setup the columns dt.Columns.Add("Locale",typeof(string)); dt.Columns.Add("Key",typeof(string)); dt.Columns.Add("DisplayText",typeof(string)); dt.PrimaryKey=new DataColumn[]{dt.Columns[0],dt.Columns[1]}; //Retrieve source collection LocalizedTexts source= LocalizedTexts.GetItemsForLocaleExport(Locale); if(source.Count<1) throw new ApplicationException("Error: Source locale doesn't appear to have any records or doesn't exist"); foreach(LocalizedText l in source) { dt.Rows.Add(new object[] {Locale,l.Key,l.DisplayText}); LocalizedTextPortable p=new LocalizedTextPortable(); } DataSet ds=new DataSet(); ds.Tables.Add(dt); ds.WriteXml(Path,XmlWriteMode.WriteSchema); } /// /// Import Locale from an XML file at the path indicated /// /// Full path (including file name) to import. /// False if Locale with that name already exists, true for any other result public static bool ImportXML(string Path) { DataSet ds=new DataSet(); ds.ReadXml(Path); if(ds.Tables[0].Rows.Count<1) throw new ApplicationException("Import: file is missing localized text keys, nothing to import"); string Locale=ds.Tables[0].Rows[0]["Locale"].ToString(); LocaleList ll=LocaleList.GetList(); if(ll.Contains(Locale)) return false; //case 1930 changed whole block below LocalizedTexts importList = LocalizedTexts.NewItems(); LocalizedTexts masterList = LocalizedTexts.GetItemsForLocaleExport("English"); //iterate the master or known good list and only import matching keys //if no matching key use the value in the master list foreach (LocalizedText master in masterList) { LocalizedText l = importList.Add(); //find row in import list DataRow[] foundRows; foundRows = ds.Tables[0].Select("Key = '"+ master.Key +"'"); if (foundRows.Length > 0)//found one (or more but will only take the first one { l.Locale = Locale; l.Key = foundRows[0]["Key"].ToString(); l.DisplayText = foundRows[0]["DisplayText"].ToString(); } else { //not found so use the master locale value instead l.Locale = Locale; l.Key=master.Key; l.DisplayText=master.DisplayText; } } //LocalizedTexts dest = LocalizedTexts.NewItems(); //foreach(DataRow r in ds.Tables[0].Rows) //{ // LocalizedText l=dest.Add(); // l.Locale=Locale; // l.Key=r["Key"].ToString(); // l.DisplayText=r["DisplayText"].ToString(); //} importList.Save(); return true; } #endregion xml #endregion #region DAL DATA ACCESS /// /// Fetch children root style /// /// protected override void DataPortal_Fetch(object Criteria) { Criteria crit = (Criteria)Criteria; SafeDataReader dr = null; try { //regular (fetch all) localized text fetch if(crit.ObjectName=="" && crit.Locale=="") dr=DBUtil.GetReaderFromSQLString("SELECT * FROM aLocalizedText");// else if(crit.ForCustomFields) {//Fetch for editing custom objects prompts DBCommandWrapper cm = DBUtil.DB.GetSqlStringCommandWrapper( @"SELECT * FROM aLocalizedText " + "WHERE aLocale=@aLocale AND aKey LIKE @ObjectName " + "ORDER BY aKey" ); cm.AddInParameter("@ObjectName",DbType.String,crit.ObjectName + ".Label.Custom_"); cm.AddInParameter("@aLocale",DbType.String,User.CurrentUserLanguage); dr=new SafeDataReader(DBUtil.DB.ExecuteReader(cm)); } else//All for a locale { if(crit.ForExport) { //For export, so include all fields even custom ones DBCommandWrapper cm = DBUtil.DB.GetSqlStringCommandWrapper( "SELECT * FROM aLocalizedText " + "WHERE aLocale=@aLocale " ); cm.AddInParameter("@aLocale",DbType.String,crit.Locale); dr=new SafeDataReader(DBUtil.DB.ExecuteReader(cm)); } else { //Not for export so don't bother including DBCommandWrapper cm = DBUtil.DB.GetSqlStringCommandWrapper( "SELECT * FROM aLocalizedText " + "WHERE aLocale=@aLocale AND aKey NOT LIKE @ObjectName " ); cm.AddInParameter("@aLocale",DbType.String,crit.Locale); cm.AddInParameter("@ObjectName",DbType.String,crit.ObjectName + "%.Label.Custom_"); dr=new SafeDataReader(DBUtil.DB.ExecuteReader(cm)); } } while(dr.Read()) { if (AyaBizUtils.Lite && ! crit.ForExport) { #region hidden keys from lite version LocalizedText lt = LocalizedText.GetItemChild(dr); if (lt.Key.StartsWith("AyaFile")) continue; if (lt.Key.StartsWith("Unit")) continue; if (lt.Key.StartsWith("AssignedDoc")) continue; if (lt.Key.StartsWith("ClientServiceRequest")) continue; if (lt.Key.StartsWith("Contract")) continue; if (lt.Key.StartsWith("CustomField")) continue; if (lt.Key.StartsWith("FormFieldDataTypes")) continue; if (lt.Key.StartsWith("HeadOffice")) continue; if (lt.Key.StartsWith("LoanItem")) continue; if (lt.Key.StartsWith("Memo")) continue; if (lt.Key.StartsWith("Notify")) continue; if (lt.Key.StartsWith("ObjectCustomField")) continue; if (lt.Key.StartsWith("PartByWarehouse")) continue; if (lt.Key.StartsWith("PartInventory")) continue; if (lt.Key.StartsWith("PartSerial")) continue; if (lt.Key.StartsWith("PartWarehouse")) continue; if (lt.Key.StartsWith("PurchaseOrder")) continue; if (lt.Key.StartsWith("Region")) continue; if (lt.Key.StartsWith("ScheduleableUserGroup")) continue; if (lt.Key.StartsWith("Security")) continue; if (lt.Key.StartsWith("ServiceBank")) continue; List.Add(lt); #endregion hidden items } else List.Add(LocalizedText.GetItemChild(dr)); } } finally { if(dr!=null) dr.Close(); } } /// /// Editable Root Collection Update /// protected override void DataPortal_Update() { using (IDbConnection connection = DBUtil.DB.GetConnection()) { connection.Open(); IDbTransaction tr = connection.BeginTransaction(); try { //update (thus deleting) any deleted child objects foreach (LocalizedText child in deletedList) { child.Update(tr); } //Now that they are deleted remove them from memory deletedList.Clear(); foreach (LocalizedText child in List) { child.Update(tr); } tr.Commit(); } catch { tr.Rollback(); throw;//WAS: throw(ex); } } } #endregion #region criteria /// /// Criteria for identifying existing object /// [Serializable] private class Criteria { public string ObjectName; public string Locale; public bool ForExport; public bool ForCustomFields; public Criteria(string _ObjectName, string _Locale,bool _ForExport, bool _ForCustomFields) { ObjectName=_ObjectName; Locale=_Locale; ForExport=_ForExport; ForCustomFields=_ForCustomFields; } } #endregion #region Create new locale /// /// Create a new locale by duplicating an existing one /// [Serializable(), System.ComponentModel.Browsable(false)] public class NewLocale//DO_NOT_OBFUSCATE { string _NewLocaleName; string _SourceLocale; /// /// Create a new locale with values copied from existing locale /// /// /// public NewLocale(string newLocaleName,string sourceLocale) { _NewLocaleName = newLocaleName; _SourceLocale=sourceLocale; } /// /// Create a new locale with values copied from existing locale /// /// /// public static void CreateNewLocale(string newLocaleName,string sourceLocale) { DataPortal.Update(new NewLocale(newLocaleName,sourceLocale)); } /// /// /// public void DataPortal_Update() { //See if the new name is kosher or not //throw an exception if it already exists DBCommandWrapper dbCommandWrapper = DBUtil.DB.GetSqlStringCommandWrapper( "SELECT TOP 1 aLocale FROM aLocalizedText WHERE (aLocale = @NewLocale);" ); dbCommandWrapper.AddInParameter("@NewLocale",DbType.String,_NewLocaleName); SafeDataReader r = new SafeDataReader(DBUtil.DB.ExecuteReader(dbCommandWrapper)); if(r.Read()) { r.Close(); throw new ApplicationException("Error: There is already a locale with this name"); } r.Close(); //Retrieve source collection LocalizedTexts source= LocalizedTexts.GetItemsForLocaleExport(_SourceLocale); if(source.Count<1) throw new ApplicationException("Error: Source locale doesn't appear to have any records or doesn't exist"); //Create new destination collection LocalizedTexts dest=LocalizedTexts.NewItems(); foreach(LocalizedText l in source) { LocalizedText ltNew=dest.Add(); ltNew.DisplayText=l.DisplayText; ltNew.DisplayTextCustom=l.DisplayTextCustom; ltNew.Key=l.Key; ltNew.Locale=_NewLocaleName; } dest.Save(); } } #endregion Create new locale #region Delete locale /// ///Delete an entire locale permanently. /// ///!!!! Danger danger danger !!!! /// ///Do not call this lightly. /// [Serializable(), System.ComponentModel.Browsable(false)] public class LocaleDeleter//DO_NOT_OBFUSCATE { string _Locale; /// /// /// /// public LocaleDeleter(string locale) { _Locale=locale; } /// /// /// /// public static void DeleteLocale(string locale) { DataPortal.Update(new LocaleDeleter(locale)); } /// /// /// public void DataPortal_Update() { //SELECT AID FROM AUSER WHERE AUSER.ALANGUAGE='ENGLISH' System.Text.StringBuilder sbUsersUsingLocaleToBeDeleted=new System.Text.StringBuilder(); DBCommandWrapper cmCheck = DBUtil.DB.GetSqlStringCommandWrapper( "SELECT ALASTNAME, AFIRSTNAME FROM AUSER WHERE (AUSER.ALANGUAGE = @aDELETE);" ); cmCheck.AddInParameter("@aDELETE", DbType.String, _Locale); using(SafeDataReader r = new SafeDataReader(DBUtil.DB.ExecuteReader(cmCheck))) { while(r.Read()) { sbUsersUsingLocaleToBeDeleted.AppendLine(r.GetString("AFIRSTNAME") + " " + r.GetString("ALASTNAME")); } r.Close(); } if(sbUsersUsingLocaleToBeDeleted.Length > 0) { throw new ApplicationException("Error: Locale is in use by the following users:\r\n" + sbUsersUsingLocaleToBeDeleted.ToString()); } DBCommandWrapper dbCommandWrapper = DBUtil.DB.GetSqlStringCommandWrapper( "DELETE FROM aLocalizedText WHERE (aLocale = @aDELETE);" ); dbCommandWrapper.AddInParameter("@aDELETE",DbType.String,_Locale); DBUtil.DB.ExecuteNonQuery(dbCommandWrapper); } } #endregion delete locale }//end LocalizedTexts }//end namespace GZTW.AyaNova.BLL