Rich 8567b1e7bf Bug B2015-126 Fixed
When Referenced Objects are updated, the RO values embedded in Step Text is updated.  Word sections are "flagged" (the temporary PDF records are deleted) which will cause the ROs to be "refreshed" when the procedure is printed.  Unfortunately, the process did not account for changes to RoImage content, with no change to the embedded "value."  PROMs has been changed to identify the Referenced Objects (ROIDs) which have been impacted by changes to the ROImages.
ROFSTs can be updated in one of two ways.  When an RO.FST is created in the ROEditor, this is a "new" RO.FST which can be used to create a unique ROFST record in the PROMS database.  When this happens, any "new" figures are also added to the PROMS database.  So, the first time this RO.FST is associated with PROMS database all of the figures are also created.  If you then associate the this RO.FST PROMS record with other procedure sets, the only change is the addition of an association record.
The important thing to remember is that the temporary PDF files used to improve performance with MS Word sections, have to be deleted when changes are made to the information used to describe the section, which can include RO Values and the RO Image Files.  This change automates the process of refreshing the temporary PDF
2015-09-15 21:41:17 +00:00

1110 lines
40 KiB
C#

// ========================================================================
// 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;
using Volian.Base.Library;
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<ROFst>(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);
cm.CommandTimeout = Database.DefaultTimeout;
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<string> ROFstInfoROTableUpdateEvent(object sender, ROFstInfoROTableUpdateEventArgs args);
public delegate void ROFstInfoProgressBarRefresh(int value, int max, string text);
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 DocVersionInfo _docVer;
// public DocVersionInfo docVer
// {
// get
// {
// if (_docVer == null)
// {
// if (ROFstAssociations.Count == 0) return null;
//// _docVer = DocVersion.Get(this.ROFstAssociations[0].MyDocVersion.VersionID);
// _docVer = this.ROFstAssociations[0].MyDocVersion;
// }
// return _docVer;
// }
// set
// {
// _docVer = value;
// }
// }
//[NonSerialized]
//private ROFSTLookup _ROFSTLookup;
//public ROFSTLookup ROFSTLookup
//{
// get
// {
// if (_ROFSTLookup == null)
// {
// _ROFSTLookup = new ROFSTLookup(this);
// }
// return _ROFSTLookup;
// }
//}
private Dictionary<string, ROFSTLookup> dicLookups = new Dictionary<string, ROFSTLookup>();
public ROFSTLookup GetROFSTLookup(DocVersionInfo dvi)
{
//string key = string.Format("{0}.{1}",dvi.DocVersionAssociations[0].ROFstID,dvi.DocVersionConfig.SelectedSlave);
string key = string.Format("{0}.{1}.{2}", ROFstID, dvi.DocVersionConfig.MaxSlaveIndex, dvi.DocVersionConfig.SelectedSlave);
if (!dicLookups.ContainsKey(key))
dicLookups.Add(key, new ROFSTLookup(this, dvi));
return dicLookups[key];
}
#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
/// <summary>
/// Adds an ro.fst into a sql database.
/// </summary>
/// <param name="rdi" - the Rodb to use as the path for updating the ro.fst, i.e.
/// import from there.
/// <param name="docver" - hook into this doc version></param>
/// <returns>ROFst: Returns the created rofst object</returns>
public static ROFst AddRoFst(RODbInfo rdi, DocVersion docver, ROFstInfoProgressBarRefresh myProgressBarRefresh)
{
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.GetJustRoDb(rdi.RODbID))
{
using (ROImageInfoList myROImages = ROImageInfoList.GetByRODbID(rdi.RODbID))
{
Dictionary<string, int> myExistingROImages = BuildROImagesList(myROImages);
List<int> myUnChangedROImages = new List<int>();
List<string> myAddedROImages = new List<string>();
List<string> MyChangedFigureROIDs = new List<string>();
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();
ROFSTLookup myLookup = ROFstInfo.GetJustROFst(rofst.ROFstID).GetROFSTLookup(DocVersionInfo.Get(docver.VersionID));
// Now load any images in... type 8 - integrated graphics ro type
for (int i = 0; i < myLookup.myHdr.myDbs.Length; i++)
{
// walk through the rofst 'database' searching for all nodes that are integrated graphics, type 8:
if (myLookup.myHdr.myDbs[i].children != null)
{
using (ROFstInfo rfi = ROFstInfo.Get(rofst.ROFstID))
{
rfi.MigrateRoFstGraphics(rdi, myLookup.myHdr.myDbs[i].children, rodb, rofst, myExistingROImages, myUnChangedROImages, myAddedROImages, MyChangedFigureROIDs, myProgressBarRefresh);// TODO: Need to add MyImages
}
}
}
if (myUnChangedROImages.Count > 0)
using (FigureInfoList fil = FigureInfoList.AddByROFstIDImageIDs(rofst.ROFstID, buildImageIDString(myUnChangedROImages))) ;
return rofst;
}
}
}
#endregion
#region Update Ro Values
/// <summary>
/// Updates an ro.fst into a sql database.
/// </summary>
/// <param name="rdi" - the Rodb to use as the path for updating the ro.fst, i.e.
/// import from there.
/// <param name="dva" - the association record to modify, i.e. make new rofst
/// the current one.
/// <param name="docver" - hook into this doc version></param>
/// <returns>ROFst: Returns the created rofst object</returns>
public static ROFst UpdateRoFst(RODbInfo rdi, DocVersionAssociation dva, DocVersion docver, ROFstInfo origROFst, ROFstInfoProgressBarRefresh myProgressBarRefresh)
{
if (myProgressBarRefresh != null) myProgressBarRefresh(0, 100, "Starting Update");
DirectoryInfo di = new DirectoryInfo(rdi.FolderPath);
string rofstfilepath = rdi.FolderPath + @"\ro.fst";
FileStream fsIn = new FileStream(rofstfilepath, FileMode.Open, FileAccess.Read, FileShare.Read);
FileInfo rofstFI = new FileInfo(rofstfilepath);
// 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, rofstFI.LastWriteTimeUtc);
if (rofst != null)
{
// Get a list of figures which have changed content (DTS)
List<string> changedFigures = GetChangedFigureROIDs(origROFst, ROFstInfo.GetJustROFst(rofst.ROFstID),DocVersionInfo.Get(docver.VersionID));
docver.DocVersionAssociations[0].MyROFst = rofst;
docver.Save();
if (!Volian.Base.Library.VlnSettings.GetCommandFlag("NOUPDATERO"))
UpdateROValuesText(origROFst, rofst, DocVersionInfo.Get(docver.VersionID),myProgressBarRefresh,changedFigures);
return rofst;
}
// Read in the rofst & make the rofst record.
// 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, rofstFI.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();
ROFSTLookup myLookup = ROFstInfo.GetJustROFst(rofst.ROFstID).GetROFSTLookup(DocVersionInfo.Get(docver.VersionID));
// Keep a list of ROIDs for Images that have changed.
List<string> MyChangedFigureROIDs = new List<string>();
// Now load any images in... type 8 - integrated graphics ro type
using (ROImageInfoList myROImages = ROImageInfoList.GetByRODbIDNoData(rdi.RODbID))
{
Dictionary<string, int> myExistingROImages = BuildROImagesList(myROImages);
List<int> myUnChangedROImages = new List<int>();
List<string> myAddedROImages = new List<string>();
using (ROFstInfo rfi = ROFstInfo.Get(rofst.ROFstID))
{
for (int i = 0; i < myLookup.myHdr.myDbs.Length; i++)
{
// walk through the rofst 'database' searching for all nodes that are integrated graphics, type 8:
if (myLookup.myHdr.myDbs[i].children != null)
{
rfi.MigrateRoFstGraphics(rdi, myLookup.myHdr.myDbs[i].children, rodb, rofst, myExistingROImages, myUnChangedROImages, myAddedROImages, MyChangedFigureROIDs,myProgressBarRefresh);
}
}
}
// Add references for existing RO Images to the Figure table (Figure table relates ro.fst with its images)
if (myUnChangedROImages.Count > 0)
using (FigureInfoList fil = FigureInfoList.AddByROFstIDImageIDs(rofst.ROFstID, buildImageIDString(myUnChangedROImages))) ;
}
// Now update the usages: compare old to new rofsts and update usages accordingly, i.e. modified
// values, deleted ros, etc.
if (!Volian.Base.Library.VlnSettings.GetCommandFlag("NOUPDATERO"))
UpdateROValuesText(origROFst, rofst, DocVersionInfo.Get(docver.VersionID),myProgressBarRefresh, MyChangedFigureROIDs);
return rofst;
}
}
/// <summary>
/// Get a list of ROIDs for figures that have changed content. This is only used when the contents of a figure
/// is changed without changing the filename.
/// </summary>
/// <param name="origROFst">Original ROFST Object</param>
/// <param name="rofst">Current ROFST Object</param>
/// <param name="docver">DocVersion (Working Draft)</param>
/// <returns>List of ROIDs which can be used to refresh MSWord PDFs</returns>
private static List<string> GetChangedFigureROIDs(ROFstInfo origROFst, ROFstInfo rofst, DocVersionInfo docver)
{
// Need to create a list of ROIDs for figures which have changed
List<string> ChangedFiles = GetChangedFigures(origROFst, rofst);
// Get ROID associated with FileNames
List<string> ROIDs = GetROIDsFromLookup(rofst,ChangedFiles,docver);
return ROIDs;
}
/// <summary>
/// Find all of the ROIDs associated with files that have changed
/// </summary>
/// <param name="rofst">Current ROFST Object</param>
/// <param name="ChangedFiles">List of Changed Files</param>
/// <param name="docver">DocVersion (Working Draft)</param>
/// <returns>List of FIleNames with changed content</returns>
private static List<string> GetROIDsFromLookup(ROFstInfo rofst, List<string> ChangedFiles, DocVersionInfo docver)
{
List<string> roids = new List<string>();
ROFSTLookup myLookup = rofst.GetROFSTLookup(docver);
for (int i = 0; i < myLookup.myHdr.myDbs.Length; i++)
{
if (myLookup.myHdr.myDbs[i].children != null)
{
FindChangedFiles(myLookup.myHdr.myDbs[i].children,ChangedFiles,roids);
}
}
return roids;
}
/// <summary>
/// Find the ROIDs in the ROLookup
/// </summary>
/// <param name="rochild">an RO or RO Group</param>
/// <param name="ChangedFiles">List of Files that have changed</param>
/// <param name="roids">List of ROIDs with changed figures</param>
private static void FindChangedFiles(ROFSTLookup.rochild[] rochild,List<string> ChangedFiles, List<string> roids)
{
for (int i = 0; i < rochild.Length; i++)
{
if (rochild[i].type == 8 && rochild[i].value != null)
{
string filename = rochild[i].value;
filename = filename.Substring(0, filename.IndexOf('\n'));
if(ChangedFiles.Contains(filename))
roids.Add(rochild[i].roid);
}
if (rochild[i].children != null) FindChangedFiles(rochild[i].children,ChangedFiles, roids);
}
}
/// <summary>
/// Get a List of figures which have changed
/// </summary>
/// <param name="origROFst">Original ROFST Object</param>
/// <param name="rofst">Current ROFST Object</param>
/// <returns>List of Files which have changed (DTS)</returns>
private static List<string> GetChangedFigures(ROFstInfo origROFst, ROFstInfo rofst)
{
Dictionary<string,int> orig = new Dictionary<string,int>();
foreach (FigureInfo fi in origROFst.ROFstFigures)
{
string key = fi.MyROImage.FileName;
if (!orig.ContainsKey(key)) orig.Add(key, fi.ImageID);
}
foreach (FigureInfo fi in rofst.ROFstFigures)
{
string key = fi.MyROImage.FileName;
if (orig.ContainsKey(key) && orig[key] == fi.ImageID)
orig.Remove(key);
}
List<string> changedFigures = new List<string>();
foreach (string key in orig.Keys)
changedFigures.Add(key);
return changedFigures;
}
private static Dictionary<string,int> BuildROImagesList(ROImageInfoList myROImages)
{
Dictionary<string,int> myRoImagesList = new Dictionary<string,int>();
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<int> 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, DocVersionInfo dvi, ROFstInfoProgressBarRefresh myProgressBarRefresh, List<string> MyChangedFigureROIDs)
{
if (myProgressBarRefresh != null) myProgressBarRefresh(0, 100, "Update Ro Values");
string versionList = dvi.VersionID.ToString();
//DateTime dtStart = DateTime.Now;
//DateTime dtLast = DateTime.Now;
ROFSTLookup origLU = new ROFSTLookup(origROFstInfo, dvi);
//dtLast = ShowDuration(dtLast, "origLU");
ROFSTLookup newLU = new ROFSTLookup(newROFst, dvi);
//dtLast = ShowDuration(dtLast, "newLU");
List<string> delList = new List<string>();
List<string> chgList = newLU.GetValueDifferences(origLU, ref delList);
// Any figures which have been changed will be included in the list of values that have changed.
foreach (string roid in MyChangedFigureROIDs)
if (!chgList.Contains(roid))
chgList.Add(roid);
//dtLast = ShowDuration(dtLast, "chgList");
string RoidList = GetRoidList(newROFst.RODbID, chgList);
//dtLast = ShowDuration(dtLast, "RoidList");
if (myProgressBarRefresh != null) myProgressBarRefresh(0, chgList.Count, "Getting List of ROs Used");
List<string> activeRoids = BuildActiveROIDsForRoUsages12(RoidList, versionList);
//dtLast = ShowDuration(dtLast, "activeRoids");
if (myProgressBarRefresh != null) myProgressBarRefresh(0, chgList.Count, "Updating RO Values");
int iCount = 0;
if (activeRoids.Count > 0)
{
foreach (string chg in chgList)
{
if (myProgressBarRefresh != null) myProgressBarRefresh(++iCount, chgList.Count, "Updating RO Values");
if (activeRoids.Contains(chg.Substring(0, 12)))
{
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", versionList))
{
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();
}
}
}
}
}
}
}
}
//dtLast = ShowDuration(dtLast, "chg loop");
if (myProgressBarRefresh != null) myProgressBarRefresh(0, chgList.Count, "Getting List of ROs Used");
List<string> activeDRoids = BuildActiveROIDsForDRoUsages12(RoidList, versionList);
//dtLast = ShowDuration(dtLast, "activeRoids Doc");
iCount = 0;
if (activeDRoids.Count > 0)
{
foreach (string chg in chgList)
{
string padroid = chg.Length <= 12 ? chg + "0000" : chg;
if (myProgressBarRefresh != null) myProgressBarRefresh(++iCount, chgList.Count, "Updating DRO Values");
if (activeDRoids.Contains(chg.Substring(0, 12)))
{
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.
using (DROUsageInfoList affected = DROUsageInfoList.GetAffected(origROFstInfo.MyRODb.RODbID, padroid, desc, "Changed", versionList))
{
foreach (DROUsageInfo droUsg in affected)
{
Pdf.DeleteAll(droUsg.DocID);
}
}
}
}
}
iCount = 0;
string RoidDelList = GetRoidList(newROFst.RODbID, delList);
if (myProgressBarRefresh != null) myProgressBarRefresh(0, chgList.Count, "Getting List of ROs Used");
activeRoids = BuildActiveROIDsForRoUsages12(RoidDelList, versionList);
if (activeRoids.Count > 0)
{
foreach (string del in delList)
{
string padroiddel = del.Length <= 12 ? del + "0000" : del;
if (myProgressBarRefresh != null) myProgressBarRefresh(++iCount, chgList.Count, "Removing Old RO Values");
string desc = string.Format("Deleted RO: Value = {0}", origLU.GetRoValue(del));
if (activeRoids.Contains(del.Substring(0, 12).ToUpper()))
{
using (RoUsageInfoList affected = RoUsageInfoList.GetAffected(origROFstInfo.MyRODb.RODbID, padroiddel, desc, "Deleted", versionList))
{
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();
}
}
}
}
}
}
}
if (myProgressBarRefresh != null) myProgressBarRefresh(0, chgList.Count, "Getting List of ROs Used");
activeDRoids = BuildActiveROIDsForDRoUsages12(RoidDelList, versionList);
iCount = 0;
if (activeDRoids.Count > 0)
{
foreach (string del in delList)
{
string padroiddel = del.Length <= 12 ? del + "0000" : del;
string desc = string.Format("Deleted RO: Value = {0}", origLU.GetRoValue(del));
if (activeDRoids.Contains(del.Substring(0, 12).ToUpper()))
{
using (DROUsageInfoList Daffected = DROUsageInfoList.GetAffected(origROFstInfo.MyRODb.RODbID, padroiddel, desc, "Deleted", versionList))
{
foreach (DROUsageInfo droUsg in Daffected)
{
if (myProgressBarRefresh != null) myProgressBarRefresh(++iCount, chgList.Count, "Removing Old DRO Values");
Pdf.DeleteAll(droUsg.DocID);
}
}
}
}
}
if (myProgressBarRefresh != null) myProgressBarRefresh(100,100, "RO Values Updated");
}
private static DateTime ShowDuration(DateTime dtLast, string message)
{
DateTime dtNext = DateTime.Now;
Console.WriteLine("{0,10:#####0.00},'{1}'", TimeSpan.FromTicks(dtNext.Ticks - dtLast.Ticks).TotalSeconds, message);
return dtNext;
}
private static List<string> BuildActiveROIDsForRoUsages(string RoidList)
{
List<string> activeRoids = new List<string>();
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<string> BuildActiveROIDsForRoUsages(string RoidList,string versions)
{
List<string> activeRoids = new List<string>();
using (RoUsageInfoList activeList = RoUsageInfoList.GetROUSagesByROIDsAndVersions(RoidList,versions))
{
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<string> BuildActiveROIDsForRoUsages12(string RoidList)
{
List<string> activeRoids = new List<string>();
using (RoUsageInfoList activeList = RoUsageInfoList.GetROUSagesByROIDs(RoidList))
{
foreach (RoUsageInfo roui in activeList)
{
string roid = roui.ROID.ToUpper().Substring(0, 12);
if (!activeRoids.Contains(roid))
activeRoids.Add(roid);
}
}
return activeRoids;
}
private static List<string> BuildActiveROIDsForRoUsages12(string RoidList, string versions)
{
List<string> activeRoids = new List<string>();
using (RoUsageInfoList activeList = RoUsageInfoList.GetROUSagesByROIDsAndVersions(RoidList, versions))
{
foreach (RoUsageInfo roui in activeList)
{
string roid = roui.ROID.ToUpper().Substring(0, 12);
if (!activeRoids.Contains(roid))
activeRoids.Add(roid);
}
}
return activeRoids;
}
private static List<string> BuildActiveROIDsForDRoUsages(string RoidList)
{
List<string> activeRoids = new List<string>();
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 List<string> BuildActiveROIDsForDRoUsages(string RoidList,string versions)
{
List<string> activeRoids = new List<string>();
using (DROUsageInfoList activeList = DROUsageInfoList.GetDROUsagesByROIDsAndVersions(RoidList,versions))
{
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 List<string> BuildActiveROIDsForDRoUsages12(string RoidList)
{
List<string> activeRoids = new List<string>();
using (DROUsageInfoList activeList = DROUsageInfoList.GetDROUsagesByROIDs(RoidList))
{
foreach (DROUsageInfo roui in activeList)
{
string roid = roui.ROID.Substring(0, 12);
if (!activeRoids.Contains(roid))
activeRoids.Add(roid);
}
}
return activeRoids;
}
private static List<string> BuildActiveROIDsForDRoUsages12(string RoidList, string versions)
{
List<string> activeRoids = new List<string>();
using (DROUsageInfoList activeList = DROUsageInfoList.GetDROUsagesByROIDsAndVersions(RoidList, versions))
{
foreach (DROUsageInfo roui in activeList)
{
string roid = roui.ROID.Substring(0, 12);
if (!activeRoids.Contains(roid))
activeRoids.Add(roid);
}
}
return activeRoids;
}
private static string GetRoidList(int dbid, List<string> 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<string, int> myExistingROImages, List<int> myUnChangedROImages, List<string> myAddedROImages, List<string> MyChangedFigureROIDs, ROFstInfoProgressBarRefresh myProgressBarRefresh)
{
for (int i = 0; i < rochild.Length; i++)
{
if (rochild[i].type == 8)this.AddGraphic(rdi, rochild[i], rodb, rofst, myExistingROImages, myUnChangedROImages, myAddedROImages, MyChangedFigureROIDs,myProgressBarRefresh);
if (rochild[i].children != null) this.MigrateRoFstGraphics(rdi, rochild[i].children, rodb, rofst, myExistingROImages, myUnChangedROImages, myAddedROImages, MyChangedFigureROIDs,myProgressBarRefresh);
}
}
private void AddGraphic(RODbInfo rdi, ROFSTLookup.rochild myRO, RODb rodb, ROFst rofst, Dictionary<string, int> myExistingROImages, List<int> myUnChangedROImages, List<string> myAddedROImages, List<string> MyChangedFigureROIDs, ROFstInfoProgressBarRefresh myProgressBarRefresh)
{
string p = myRO.value;
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 (!myUnChangedROImages.Contains(imageID))
myUnChangedROImages.Add(imageID);
}
else
{
if (!myAddedROImages.Contains(key))
{
myProgressBarRefresh(0, 100, "Loading " + imgname);
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();
byte[] cmp = ROImageInfo.Compress(ab);
int existingImageID = FindExisting(myExistingROImages, imgname, imgfile, cmp, ab);
if (existingImageID != 0)
{
if (!myUnChangedROImages.Contains(existingImageID))
myUnChangedROImages.Add(existingImageID);
return;
}
ROImageConfig rc = new ROImageConfig();
rc.Image_Size = ab.Length.ToString();
using (roImg = ROImage.MakeROImage(rodb, imgname, ROImageInfo.Compress(ab), rc.ToString(), fi.LastWriteTimeUtc, "Migration"))
{
using (Figure figure = Figure.GetByROFstID_ImageID(this.ROFstID, roImg.ImageID))
{
if (figure != null) return;
Figure.MakeFigure(rofst, roImg, null).Dispose();
myAddedROImages.Add(key);
MyChangedFigureROIDs.Add(myRO.roid); // Save the roid so that the related documents will be refeshed. (PDF will be deleted)
}
}
}
}
}
}
private int FindExisting(Dictionary<string, int> myExistingROImages, string imgname, string imgfile, byte[] cmpFileContents, byte[] fileContents)
{
// the reason the following check is necessary is that the DTS can be off by hours
// because of the way windows handles Daylight savings time for file DTS.
FileInfo fi = new FileInfo(imgfile);
DateTime dts = fi.LastWriteTimeUtc;
// loop through myExistingROImages looking for matching name.
foreach (string key in myExistingROImages.Keys)
{
// if found, compare the date/time stamp
string part1 = Regex.Replace(key, ":.*$", "");
string part2 = Regex.Replace(key, "^.*?:", "");
if (part1.ToUpper() == imgname.ToUpper())
{
// if date/time stamps matches date, minutes & seconds, compare contents
string cmp1 = Regex.Replace(dts.ToString(), " [0-9]*:", " x:");
cmp1 = Regex.Replace(cmp1, " [AP]", " x");
string cmp2 = Regex.Replace(part2, " [0-9]*:", " x:");
cmp2 = Regex.Replace(cmp2, " [AP]", " x");
if (cmp1==cmp2)
{
// compare contents
int imgId = myExistingROImages[key];
using (ROImageInfo roii = ROImageInfo.Get(imgId))
{
ROImageConfig roicfg = new ROImageConfig(roii);
int size = Convert.ToInt32(roicfg.Image_Size);
byte[] tmpb = ROImageInfo.Decompress(roii.Content, size);
if (ByteArrayCompare(roii.Content, cmpFileContents))
return imgId;
if (ByteArrayCompare(tmpb, fileContents))
return imgId;
}
}
}
}
return 0;
}
private bool ByteArrayCompare(byte[] ba1, byte[] ba2)
{
// we wrote our own byte array comparinson because the system's 'equals' did not work!
if (ba1.Length != ba2.Length) return false;
for (int i = 0; i < ba1.Length; i++)
if (ba1[i] != ba2[i]) return false;
return true;
}
private ROImageInfo GetMyImage(Dictionary<string, ROImageInfo> 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, DocVersionInfo dvi)
{
ROFSTLookup.rodbi[] dbs = GetROFSTLookup(dvi).GetRODatabaseList();
foreach (ROFSTLookup.rodbi rodbi in dbs)
{
if (id == rodbi.dbiID)
return (rodbi.dbiAP.StartsWith("SP"));
}
return false;
}
public ROFst GetJustROFst()
{
return ROFst.GetJustROFst(ROFstID);
}
public event ROFstInfoROTableUpdateEvent ROTableUpdate;
public List<string> 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<ROFstInfo>(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);
cm.CommandTimeout = Database.DefaultTimeout;
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 ROImageInfo GetROImageByFilename(string filename, ItemInfo myItemInfo)
{
ROImageInfoList images = ROImageInfoList.GetByRODbIDFilename(RODbID, filename);
if (images == null || images.Count == 0)
{
ROWarning(myItemInfo,"Referenced Object Image {0} Missing", filename);
return null;
}
ROImageInfo retval = null;
foreach (ROImageInfo image in images)
{
if (image.DTS > DTS && retval != null) break;
retval = image;
}
if(retval.DTS > DTS)
ROWarning(myItemInfo, "Referenced Object Image {0} newer {1} than RO.FST {2}", filename, retval.DTS.ToShortDateString(), DTS.ToShortDateString());
else
ROWarning(myItemInfo, "Referenced Object Image {0} older {1} then RO.FST {2}", filename, retval.DTS.ToShortDateString(), DTS.ToShortDateString());
return retval;
}
private static List<int> DocVersionsNeedingROUpdate = new List<int>();
private static void ROWarning(ItemInfo myItemInfo, string format, params object[] args)
{
int key = 0;
if(myItemInfo != null && myItemInfo.MyDocVersion != null) key = myItemInfo.MyDocVersion.VersionID;
if (!DocVersionsNeedingROUpdate.Contains(key))
{
if (myItemInfo == null)
{
string prefix = string.Format("\r\nNeed to Update RO Values\r\n");
_MyLog.WarnFormat(prefix + format, args);
DocVersionsNeedingROUpdate.Add(key);
}
else
{
string prefix = string.Format("\r\nNeed to Update RO Values for {0}\r\nProcedure {1}\r\n", myItemInfo.SearchDVPath, myItemInfo.MyProcedure.DisplayNumber);
_MyLog.WarnFormat(prefix + format, args);
DocVersionsNeedingROUpdate.Add(key);
}
}
}
}
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<ROFstInfoList>(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);
cm.CommandTimeout = Database.DefaultTimeout;
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;
}
}
}