// ======================================================================== // Copyright 2006 - Volian Enterprises, Inc. All rights reserved. // Volian Enterprises - Proprietary Information - DO NOT COPY OR DISTRIBUTE // ------------------------------------------------------------------------ // $Workfile: $ $Revision: $ // $Author: $ $Date: $ // // $History: $ // ======================================================================== using System; using System.Collections.Generic; using System.Collections.Specialized; using System.Text; using System.IO; using System.Xml.Serialization; using System.Xml; using System.Xml.XPath; using System.Text.RegularExpressions; using System.Data; using System.Data.SqlClient; using Csla; using Csla.Data; namespace VEPROMS.CSLA.Library { public partial class ROFst { // put in for debug //public static int CacheCountPrimaryKey //{ get { return _CacheByPrimaryKey.Count; } } //public static int CacheCountByRODbID_DTS //{ get { return _CacheByRODbID_DTS.Count; } } //public static int CacheCountList //{ get { return _CacheList.Count; } } [NonSerialized] private ROFSTLookup _ROFSTLookup; public ROFSTLookup ROFSTLookup { get { if (_ROFSTLookup == null) { _ROFSTLookup = new ROFSTLookup(this); } return _ROFSTLookup; } } public static ROFst GetJustROFst(int rOFstID) { if (!CanGetObject()) throw new System.Security.SecurityException("User not authorized to view a ROFst"); try { ROFst tmp = GetCachedByPrimaryKey(rOFstID); if (tmp == null) { tmp = DataPortal.Fetch(new PKCriteriaJustROFst(rOFstID)); AddToCache(tmp); } if (tmp.ErrorMessage == "No Record Found") { tmp.Dispose(); // Clean-up ROFst tmp = null; } return tmp; } catch (Exception ex) { throw new DbCslaException("Error on ROFst.Get", ex); } } [Serializable()] protected class PKCriteriaJustROFst { private int _ROFstID; public int ROFstID { get { return _ROFstID; } } public PKCriteriaJustROFst(int rOFstID) { _ROFstID = rOFstID; } } private void DataPortal_Fetch(PKCriteriaJustROFst criteria) { if (_MyLog.IsDebugEnabled) _MyLog.DebugFormat("[{0}] ROFst.DataPortal_Fetch", GetHashCode()); try { using (SqlConnection cn = Database.VEPROMS_SqlConnection) { ApplicationContext.LocalContext["cn"] = cn; using (SqlCommand cm = cn.CreateCommand()) { cm.CommandType = CommandType.StoredProcedure; cm.CommandText = "getJustROFst"; cm.Parameters.AddWithValue("@ROFstID", criteria.ROFstID); using (SafeDataReader dr = new SafeDataReader(cm.ExecuteReader())) { if (!dr.Read()) { _ErrorMessage = "No Record Found"; return; } ReadData(dr); // load child objects //dr.NextResult(); //_ROFstAssociations = ROFstAssociations.Get(dr); // load child objects //dr.NextResult(); //_ROFstFigures = ROFstFigures.Get(dr); } } // removing of item only needed for local data portal if (ApplicationContext.ExecutionLocation == ApplicationContext.ExecutionLocations.Client) ApplicationContext.LocalContext.Remove("cn"); } } catch (Exception ex) { if (_MyLog.IsErrorEnabled) _MyLog.Error("ROFst.DataPortal_Fetch", ex); _ErrorMessage = ex.Message; throw new DbCslaException("ROFst.DataPortal_Fetch", ex); } } } public delegate List ROFstInfoROTableUpdateEvent(object sender, ROFstInfoROTableUpdateEventArgs args); public partial class ROFstInfo { // put in for debug //public static int CacheCountPrimaryKey //{ get { return _CacheByPrimaryKey.Count; } } //public static int CacheCountList //{ get { return _CacheList.Count; } } #region Log4Net private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); #endregion #region PropertiesAndData private DocVersion _docVer; public DocVersion docVer { get { if (_docVer == null) { if (ROFstAssociations.Count == 0) return null; _docVer = DocVersion.Get(this.ROFstAssociations[0].MyDocVersion.VersionID); } return _docVer; } set { _docVer = value; } } [NonSerialized] private ROFSTLookup _ROFSTLookup; public ROFSTLookup ROFSTLookup { get { if (_ROFSTLookup == null) { _ROFSTLookup = new ROFSTLookup(this); } return _ROFSTLookup; } } #endregion #region AppSupport //public static ROImageInfo Get(RODbInfo rodbinfo, string filename) //{ // if (rodbinfo.RODbROImageCount != 0) // { // foreach (ROImageInfo ri in rodbinfo.RODbROImages) // { // if (ri.FileName == filename) return ri; // } // } // return null; //} public string GetDefaultROPrefix() { if (docVer != null) return docVer.DocVersionConfig.RODefaults_setpointprefix; else return "SP1"; // Not Sure about this... } public string GetDefaultGraphicsPrefix() { if (docVer != null) return docVer.DocVersionConfig.RODefaults_graphicsprefix; else return "IG1"; // Not Sure about this... } #region Add New Ro Fst /// /// Adds an ro.fst into a sql database. /// /// /// ROFst: Returns the created rofst object public static ROFst AddRoFst(RODbInfo rdi, DocVersion docver) { string rofstfilepath = rdi.FolderPath + @"\ro.fst"; DirectoryInfo di = new DirectoryInfo(rdi.FolderPath); if (!di.Exists) return null; if (!File.Exists(rofstfilepath)) return null; // check if this rofst has been loaded, i.e. dts on file versus dts in db... // if so, just make association with docversion. ROFst rofst = ROFst.GetByRODbID_DTS(rdi.RODbID, di.LastWriteTimeUtc); if (rofst != null) { docver.DocVersionAssociations.Add(rofst); docver.Save(); return rofst; } // Next read in the rofst & make the rofst record. FileStream fsIn = new FileStream(rofstfilepath, FileMode.Open, FileAccess.Read, FileShare.Read); // Create an instance of StreamReader that can read characters from the FileStream. BinaryReader r = new BinaryReader(fsIn); byte[] ab = r.ReadBytes((int)fsIn.Length); fsIn.Close(); using (RODb rodb = RODb.Get(rdi.RODbID)) { using (ROImageInfoList myROImages = ROImageInfoList.GetByRODbID(rdi.RODbID)) { Dictionary myExistingROImages = BuildROImagesList(myROImages); List myChangedROImages = new List(); List myAddedROImages = new List(); rofst = ROFst.MakeROFst(rodb, ab, null, di.LastWriteTimeUtc, rdi.UserID); // Hook this into the current docversion by replacing the rofstid field in the doc version // association object: docver.DocVersionAssociations.Add(rofst); docver.Save(); // Now load any images in... type 8 - integrated graphics ro type for (int i = 0; i < rofst.ROFSTLookup.myHdr.myDbs.Length; i++) { // walk through the rofst 'database' searching for all nodes that are integrated graphics, type 8: if (rofst.ROFSTLookup.myHdr.myDbs[i].children != null) { using (ROFstInfo rfi = ROFstInfo.Get(rofst.ROFstID)) { rfi.MigrateRoFstGraphics(rdi, rofst.ROFSTLookup.myHdr.myDbs[i].children, rodb, rofst, myExistingROImages, myChangedROImages,myAddedROImages);// TODO: Need to add MyImages } } } if(myChangedROImages.Count > 0) using(FigureInfoList fil = FigureInfoList.AddByROFstIDImageIDs(rofst.ROFstID,buildImageIDString(myChangedROImages))); return rofst; } } } #endregion #region Update Ro Values /// /// Updates an ro.fst into a sql database. /// /// /// ROFst: Returns the created rofst object public static ROFst UpdateRoFst(RODbInfo rdi, DocVersionAssociation dva, DocVersion docver, ROFstInfo origROFst) { DirectoryInfo di = new DirectoryInfo(rdi.FolderPath); // check if this rofst has been loaded, i.e. dts on file versus dts in db... // if so, just make association to existing with docversion. ROFst rofst = ROFst.GetByRODbID_DTS(rdi.RODbID, di.LastWriteTimeUtc); if (rofst != null) { docver.DocVersionAssociations[0].MyROFst = rofst; docver.Save(); return rofst; } // Read in the rofst & make the rofst record. string rofstfilepath = rdi.FolderPath + @"\ro.fst"; FileStream fsIn = new FileStream(rofstfilepath, FileMode.Open, FileAccess.Read, FileShare.Read); // Create an instance of StreamReader that can read characters from the FileStream. BinaryReader r = new BinaryReader(fsIn); byte[] ab = r.ReadBytes((int)fsIn.Length); fsIn.Close(); using (RODb rodb = RODb.GetJustRoDb(rdi.RODbID)) { rofst = ROFst.MakeROFst(rodb, ab, null, di.LastWriteTimeUtc, rdi.UserID); // Hook this into the current docversion by replacing the rofstid field in the doc version // association object: dva.MyROFst = rofst; docver.Save(); // Now load any images in... type 8 - integrated graphics ro type using (ROImageInfoList myROImages = ROImageInfoList.GetByRODbIDNoData(rdi.RODbID)) { Dictionary myExistingROImages = BuildROImagesList(myROImages); List myChangedROImages = new List(); List myAddedROImages = new List(); using (ROFstInfo rfi = ROFstInfo.Get(rofst.ROFstID)) { for (int i = 0; i < rofst.ROFSTLookup.myHdr.myDbs.Length; i++) { // walk through the rofst 'database' searching for all nodes that are integrated graphics, type 8: if (rofst.ROFSTLookup.myHdr.myDbs[i].children != null) { rfi.MigrateRoFstGraphics(rdi, rofst.ROFSTLookup.myHdr.myDbs[i].children, rodb, rofst, myExistingROImages, myChangedROImages,myAddedROImages); } } } if (myChangedROImages.Count > 0) using(FigureInfoList fil = FigureInfoList.AddByROFstIDImageIDs(rofst.ROFstID,buildImageIDString(myChangedROImages))); } // Now update the usages: compare old to new rofsts and update usages accordingly, i.e. modified // values, deleted ros, etc. UpdateROValuesText(origROFst, rofst); return rofst; } } private static Dictionary BuildROImagesList(ROImageInfoList myROImages) { Dictionary myRoImagesList = new Dictionary(); foreach (ROImageInfo myROImage in myROImages) myRoImagesList.Add(ROImageKey(myROImage.FileName, myROImage.DTS),myROImage.ImageID); return myRoImagesList; } private static string ROImageKey(string fileName, DateTime dts) { return string.Format("{0}:{1}", fileName, dts); } private static string buildImageIDString(List myROImageIDs) { StringBuilder sb = new StringBuilder(); string sep = ""; foreach (int imageID in myROImageIDs) { sb.Append(sep + imageID.ToString()); sep = ","; } return sb.ToString(); } private static void UpdateROValuesText(ROFstInfo origROFstInfo, ROFst newROFst) { ROFSTLookup origLU = new ROFSTLookup(origROFstInfo); ROFSTLookup newLU = new ROFSTLookup(newROFst); List delList = new List(); List chgList = newLU.GetValueDifferences(origLU, ref delList); string RoidList = GetRoidList(newROFst.RODbID, chgList); List activeRoids = BuildActiveROIDsForRoUsages(RoidList); foreach (string chg in chgList) { if (activeRoids.Contains(chg)) { ROFSTLookup.rochild roch = newLU.GetRoChild(chg); string desc = string.Format("Change in RO Values: Old value = {0}, New value = {1}", origLU.GetRoValue(chg), roch.value); // roid's are stored in database as 16 characters long in the rousages table. They may be stored // as 12 characters in the ro.fst. string padroid = chg.Length <= 12 ? chg + "0000" : chg; using (RoUsageInfoList affected = RoUsageInfoList.GetAffected(origROFstInfo.MyRODb.RODbID, padroid, desc, "Changed")) { foreach (RoUsageInfo roUsg in affected) { using (Content content = Content.Get(roUsg.MyContent.ContentID)) { foreach (ItemInfo ii in roUsg.MyContent.ContentItems) { string val = newLU.GetTranslatedRoValue(padroid, ii.ActiveFormat.PlantFormat.FormatData.SectData.ConvertCaretToDelta); content.FixContentText(roUsg, val, roch.type, origROFstInfo); if (content.IsDirty) { // Update UserID and DTS when RO Value is updated. content.UserID = Volian.Base.Library.VlnSettings.UserID; content.DTS = DateTime.Now; content.Save(); } } } } } } } activeRoids = BuildActiveROIDsForDRoUsages(RoidList); foreach (string chg in chgList) { if (activeRoids.Contains(chg)) { ROFSTLookup.rochild roch = newLU.GetRoChild(chg); string desc = string.Format("Change in RO Values: Old value = {0}, New value = {1}", origLU.GetRoValue(chg), roch.value); // roid's are stored in database as 16 characters long in the rousages table. They may be stored // as 12 characters in the ro.fst. string padroid = chg.Length <= 12 ? chg + "0000" : chg; using (DROUsageInfoList affected = DROUsageInfoList.GetAffected(origROFstInfo.MyRODb.RODbID, padroid.Substring(0,12), desc, "Changed")) { foreach (DROUsageInfo droUsg in affected) { Pdf.DeleteAll(droUsg.DocID); } } } } foreach (string del in delList) { string desc = string.Format("Deleted RO: Value = {0}", origLU.GetRoValue(del)); string padroiddel = del.Length <= 12 ? del + "0000" : del; using (RoUsageInfoList affected = RoUsageInfoList.GetAffected(origROFstInfo.MyRODb.RODbID, padroiddel, desc, "Deleted")) { foreach (RoUsageInfo roUsg in affected) { using (Content content = Content.Get(roUsg.MyContent.ContentID)) { content.FixContentText(roUsg, "?", 0, origROFstInfo); if (content.IsDirty) { // Update UserID and DTS when RO Value is updated. content.UserID = Volian.Base.Library.VlnSettings.UserID; content.DTS = DateTime.Now; content.Save(); } } } } using (DROUsageInfoList Daffected = DROUsageInfoList.GetAffected(origROFstInfo.MyRODb.RODbID, del.Substring(0,12), desc, "Deleted")) { foreach (DROUsageInfo droUsg in Daffected) { Pdf.DeleteAll(droUsg.DocID); } } } } private static List BuildActiveROIDsForRoUsages(string RoidList) { List activeRoids = new List(); using (RoUsageInfoList activeList = RoUsageInfoList.GetROUSagesByROIDs(RoidList)) { foreach (RoUsageInfo roui in activeList) { string roid = roui.ROID.ToUpper(); if (roid.EndsWith("0000")) roid = roid.Substring(0, 12); if (!activeRoids.Contains(roid)) activeRoids.Add(roid); } } return activeRoids; } private static List BuildActiveROIDsForDRoUsages(string RoidList) { List activeRoids = new List(); using (DROUsageInfoList activeList = DROUsageInfoList.GetDROUsagesByROIDs(RoidList)) { foreach (DROUsageInfo roui in activeList) { string roid = roui.ROID; if (roid.EndsWith("0000")) roid = roid.Substring(0, 12); if (!activeRoids.Contains(roid)) activeRoids.Add(roid); } } return activeRoids; } private static string GetRoidList(int dbid, List chgList) { StringBuilder sb = new StringBuilder(string.Format("{0}", dbid)); string sep=":"; foreach (string roid in chgList) { sb.Append(sep + roid); sep = ","; } return sb.ToString(); } private static string NewROName(string roName) { string retval = roName; int iSuffix = -1; RODbInfoList rodblist = RODbInfoList.Get(); foreach (RODbInfo rdi in rodblist) { if (rdi.ROName.StartsWith(roName)) { if (rdi.ROName == roName) iSuffix = 0; else if (Regex.IsMatch(rdi.ROName, roName + "[_][0-9]+")) { int ii = int.Parse(rdi.ROName.Substring(1 + roName.Length)); if (ii > iSuffix) iSuffix = ii; } } } if (iSuffix >= 0) retval = string.Format("{0}_{1}", roName, iSuffix + 1); return retval; } private void MigrateRoFstGraphics(RODbInfo rdi, ROFSTLookup.rochild[] rochild, RODb rodb, ROFst rofst, Dictionary myExistingROImages, List myChangedROImages, List myAddedROImages) { for (int i = 0; i < rochild.Length; i++) { if (rochild[i].type == 8) this.AddGraphic(rdi, rochild[i].value, rodb, rofst, myExistingROImages, myChangedROImages, myAddedROImages); if (rochild[i].children != null) this.MigrateRoFstGraphics(rdi, rochild[i].children, rodb, rofst, myExistingROImages, myChangedROImages, myAddedROImages); } } private void AddGraphic(RODbInfo rdi, string p, RODb rodb, ROFst rofst, Dictionary myExistingROImages, List myChangedROImages, List myAddedROImages) { if (p == null) return; string imgname = p.Substring(0, p.IndexOf('\n')); int thedot = imgname.LastIndexOf('.'); string fname = imgname; if (thedot == -1 || (thedot != (imgname.Length - 4))) { RODbConfig roDbCfg = new RODbConfig(rdi.Config); fname += string.Format(".{0}", roDbCfg.GetDefaultGraphicExtension()); } string imgfile = rdi.FolderPath + @"\" + fname; ROImage roImg = null; if (File.Exists(imgfile)) { FileInfo fi = new FileInfo(imgfile); // if the roimage record exists, don't create a new one... string key = ROImageKey(imgname, fi.LastWriteTimeUtc); if (myExistingROImages.ContainsKey(key)) { int imageID = myExistingROImages[key]; if(!myChangedROImages.Contains(imageID)) myChangedROImages.Add(imageID); } else { if (!myAddedROImages.Contains(key)) { FileStream fsIn = new FileStream(imgfile, FileMode.Open, FileAccess.Read, FileShare.Read); BinaryReader r = new BinaryReader(fsIn); byte[] ab = r.ReadBytes((int)fsIn.Length); r.Close(); fsIn.Close(); roImg = ROImage.MakeROImage(rodb, imgname, ab, null, fi.LastWriteTimeUtc, "Migration"); Figure figure = Figure.GetByROFstID_ImageID(this.ROFstID, roImg.ImageID); if (figure != null) return; figure = Figure.MakeFigure(rofst, roImg, null); myAddedROImages.Add(key); } } } } private ROImageInfo GetMyImage(Dictionary myImages, string imgname, DateTime dts) { string key = string.Format("{0}:{1}", imgname, dts); if(myImages.ContainsKey(key)) return myImages[key]; return null; } #endregion #endregion public bool IsSetpointDB(int id) { ROFSTLookup.rodbi[] dbs = ROFSTLookup.GetRODatabaseList(); foreach (ROFSTLookup.rodbi rodbi in dbs) { if (id == rodbi.dbiID) return (rodbi.dbiAP.StartsWith("SP")); } return false; } public event ROFstInfoROTableUpdateEvent ROTableUpdate; public List OnROTableUpdate(object sender, ROFstInfoROTableUpdateEventArgs args) { if (ROTableUpdate != null) return ROTableUpdate(sender, args); return null; } public static ROFstInfo GetJustROFst(int rOFstID) { //if (!CanGetObject()) // throw new System.Security.SecurityException("User not authorized to view a ROFst"); try { ROFstInfo tmp = GetCachedByPrimaryKey(rOFstID); if (tmp == null) { tmp = DataPortal.Fetch(new PKCriteriaJustROFst(rOFstID)); AddToCache(tmp); } if (tmp.ErrorMessage == "No Record Found") { tmp.Dispose(); // Clean-up ROFstInfo tmp = null; } return tmp; } catch (Exception ex) { throw new DbCslaException("Error on ROFstInfo.Get", ex); } } [Serializable()] protected class PKCriteriaJustROFst { private int _ROFstID; public int ROFstID { get { return _ROFstID; } } public PKCriteriaJustROFst(int rOFstID) { _ROFstID = rOFstID; } } private void DataPortal_Fetch(PKCriteriaJustROFst criteria) { if (_MyLog.IsDebugEnabled) _MyLog.DebugFormat("[{0}] ROFstInfo.DataPortal_Fetch", GetHashCode()); try { using (SqlConnection cn = Database.VEPROMS_SqlConnection) { ApplicationContext.LocalContext["cn"] = cn; using (SqlCommand cm = cn.CreateCommand()) { cm.CommandType = CommandType.StoredProcedure; cm.CommandText = "getJustROFst"; cm.Parameters.AddWithValue("@ROFstID", criteria.ROFstID); using (SafeDataReader dr = new SafeDataReader(cm.ExecuteReader())) { if (!dr.Read()) { _ErrorMessage = "No Record Found"; return; } ReadData(dr); } } // removing of item only needed for local data portal if (ApplicationContext.ExecutionLocation == ApplicationContext.ExecutionLocations.Client) ApplicationContext.LocalContext.Remove("cn"); } } catch (Exception ex) { if (_MyLog.IsErrorEnabled) _MyLog.Error("ROFstInfo.DataPortal_Fetch", ex); _ErrorMessage = ex.Message; throw new DbCslaException("ROFstInfo.DataPortal_Fetch", ex); } } } public class ROFstInfoROTableUpdateEventArgs { private string _ROText; public string ROText { get { return _ROText; } set { _ROText = value; } } private string _OldGridXml; public string OldGridXml { get { return _OldGridXml; } set { _OldGridXml = value; } } public ROFstInfoROTableUpdateEventArgs(string rotext, string oldgridxml) { _ROText = rotext; _OldGridXml = oldgridxml; } } public partial class ROFstInfoList { [Serializable()] private class RoFstSizeCriteria { public RoFstSizeCriteria(int roDbID, int len) { _RODbID = roDbID; _Len = len; } private int _RODbID; public int RODbID { get { return _RODbID; } set { _RODbID = value; } } private int _Len; public int Len { get { return _Len; } set { _Len = value; } } } public static ROFstInfoList GetBySize(int roDbID, int len) { try { ROFstInfoList tmp = DataPortal.Fetch(new RoFstSizeCriteria(roDbID, len)); ROFstInfo.AddList(tmp); tmp.AddEvents(); return tmp; } catch (Exception ex) { throw new DbCslaException("Error on RoFstInfoList.GetBySize", ex); } } private void DataPortal_Fetch(RoFstSizeCriteria criteria) { this.RaiseListChangedEvents = false; if (_MyLog.IsDebugEnabled) _MyLog.DebugFormat("[{0}] ROFstInfoList.DataPortal_FetchBySize", GetHashCode()); try { using (SqlConnection cn = Database.VEPROMS_SqlConnection) { using (SqlCommand cm = cn.CreateCommand()) { cm.CommandType = CommandType.StoredProcedure; cm.CommandText = "getRoFstBySize"; cm.Parameters.AddWithValue("@RODbID", criteria.RODbID); cm.Parameters.AddWithValue("@Len", criteria.Len); using (SafeDataReader dr = new SafeDataReader(cm.ExecuteReader())) { IsReadOnly = false; while (dr.Read()) this.Add(new ROFstInfo(dr)); IsReadOnly = true; } } } } catch (Exception ex) { if (_MyLog.IsErrorEnabled) _MyLog.Error("ROFstInfoList.DataPortal_FetchBySize", ex); throw new DbCslaException("ROFstInfoList.DataPortal_FetchBySize", ex); } this.RaiseListChangedEvents = true; } } }