This commit is contained in:
2009-01-27 15:36:38 +00:00
parent 20783cc178
commit 4dbbcf0478
7 changed files with 872 additions and 319 deletions

View File

@@ -16,347 +16,270 @@ using System.IO;
using System.Xml.Serialization;
using System.Xml;
using System.Xml.XPath;
using System.Text.RegularExpressions;
//using Config;
namespace VEPROMS.CSLA.Library
{
public partial class ROFST
public partial class ROFst
{
[NonSerialized]
private ROFSTLookup _ROFSTLookup;
public ROFSTLookup ROFSTLookup
{
get
{
if (_ROFSTLookup == null)
{
_ROFSTLookup = new ROFSTLookup(this);
}
return _ROFSTLookup;
}
}
}
public partial class ROFstInfo
{
#region Log4Net
private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
#endregion
[Serializable]
public struct roHdr
#region PropertiesAndData
private DocVersion _docVer;
public DocVersion docVer
{
public int hSize;
public int hYear;
public byte hMonth;
public byte hDay;
public int hcYear;
public byte hcMonth;
public byte hcDay;
public byte hcHour;
public byte hcMin;
public byte hcSec;
public byte hcHund;
public rodbi[] myDbs;
};
[Serializable]
public struct rodbi
{
public int dbiID;
public int dbiType;
public int dbiAW;
public string dbiTitle;
public string dbiAP;
public int ID;
public int ParentID;
public rochild[] children;
};
public struct rogrp
{
public int ID;
public int ParentID;
public rochild[] children;
public string value;
public string appid;
};
public struct rochild
{
public int ID;
public int ParentID;
public int type;
public string title;
public string roid;
public string appid;
public string value;
public rochild[] children;
};
public roHdr myHdr;
private int TableID;
private string fstPath;
private HybridDictionary dicRos;
private HybridDictionary dicRosIntIDs;
private DocVersionInfo docVerInfo = null;
public ROFST(string path, DocVersionInfo docverinfo)
{
docVerInfo = docverinfo;
fstPath = path;
if (!File.Exists(fstPath))
get
{
log.ErrorFormat("RO FST Does not exist: {0}", path);
return;
if (_docVer == null) _docVer = DocVersion.Get(this.ROFstAssociations[0].MyDocVersion.VersionID);
return _docVer;
}
dicRos = new HybridDictionary();
dicRosIntIDs = new HybridDictionary();
ParseIntoDictionary();
}
public void Close()
{
// remove the dictionary
dicRosIntIDs.Clear();
dicRosIntIDs = null;
dicRos.Clear();
dicRos = null;
}
// this only gets rochild values. Later we may want another
// dictionary to get groups.
public string GetRoValue(string ROID)
{
// Use the ROID to get the value from the dictionary
if (dicRos.Contains(ROID))
set
{
rochild rochld = (rochild)dicRos[ROID];
return rochld.value;
}
return null;
}
public rochild GetRoChild(string ROID)
{
// Use the ROID to get the value from the dictionary
if (dicRos.Contains(ROID))
{
rochild rochld = (rochild)dicRos[ROID];
return rochld;
}
rochild tmp = new rochild();
tmp.ID = -1;
return tmp;
}
public rochild GetRoChildFromID(int id)
{
// Use the id to get the value from the dictionary
if (dicRosIntIDs.Contains(id))
{
rochild rochld = (rochild)dicRosIntIDs[id];
return rochld;
}
rochild tmp = new rochild();
tmp.ID = -1;
return tmp;
}
public rodbi[] GetRODatabaseList()
{
return myHdr.myDbs;
}
private int StringLength(byte[] ab, int offset)
{
int i = 0;
while (ab[i + offset] != 0) i++;
return i;
}
private rogrp LoadGroup(byte[] ab, int offset)
{
rogrp myGrp = new rogrp();
myGrp.ID = BitConverter.ToInt32(ab, offset);
myGrp.ParentID = BitConverter.ToInt32(ab, offset + 4);
int howmany = BitConverter.ToInt16(ab, offset + 8);
if (howmany > 0)
{
myGrp.children = new rochild[howmany];
int myOffset = offset + 10;
for (int i = 0; i < myGrp.children.Length; i++)
{
int childOffset = BitConverter.ToInt32(ab, myOffset);
rochild tmp = new rochild();
//tmp.offset=BitConverter.ToInt32(ab,myOffset);
tmp.type = BitConverter.ToInt16(ab, myOffset + 4);
int slen = StringLength(ab, myOffset + 6);
tmp.title = Encoding.Default.GetString(ab, myOffset + 6, slen);
myOffset += (7 + slen);
rogrp tmpg = LoadGroup(ab, childOffset);
MultipleReturnValuesInheritType(ref tmpg, tmp.type);
tmp.ID = tmpg.ID;
tmp.ParentID = tmpg.ParentID;
tmp.children = tmpg.children;
tmp.value = tmpg.value;
tmp.appid = tmpg.appid;
tmp.roid = TableID.ToString("X4") + tmp.ID.ToString("X8");
dicRos.Add(tmp.roid, tmp);
if (!dicRosIntIDs.Contains(tmp.ID)) dicRosIntIDs.Add(tmp.ID, tmp);
int j;
for (j = i - 1; j >= 0 && tmp.ID < myGrp.children[j].ID; j--)
{
myGrp.children[j + 1] = myGrp.children[j];
}
myGrp.children[j + 1] = tmp;
}
}
else
{
int slen = StringLength(ab, offset + 12);
//myGrp.value = Encoding.Default.GetString(ab, offset + 12, slen);
ProcessROReturnValue(ref myGrp, Encoding.Default.GetString(ab, offset + 12, slen));
int slen2 = StringLength(ab, offset + 13 + slen);
myGrp.appid = Encoding.Default.GetString(ab, offset + 13 + slen, slen2);
}
return myGrp;
}
/// <summary>
/// This function will take the raw RO return value and resolve any macros, conditionals, and
/// generated the return value or a list of multiple return values.
/// </summary>
/// <param name="myGrp"></param>
/// <param name="rawvalue"></param>
private void ProcessROReturnValue(ref rogrp myGrp, string rawvalue)
{
List<string> lstROVals = GetROReturnValue(rawvalue);
if (lstROVals.Count > 1) // mulitple return values
{
myGrp.children = new rochild[lstROVals.Count];
for (int i = 0; i < lstROVals.Count; i++)
{
myGrp.children[i].value = lstROVals[i];
myGrp.children[i].roid = TableID.ToString("X4") + myGrp.ID.ToString("X8") + i.ToString("X4");
myGrp.children[i].type = -1; // Multiple return value inherit type from parent
myGrp.children[i].title = lstROVals[i];
}
}
else
myGrp.value = lstROVals[0];
return;
}
/// <summary>
/// Multiple return values need to get the type from the parent node.
/// </summary>
/// <param name="myGrp"></param>
/// <param name="parenttype"></param>
private void MultipleReturnValuesInheritType(ref rogrp myGrp, int parenttype)
{
if (myGrp.children != null)
{
for (int cnt = 0; cnt < myGrp.children.Length; cnt++ )
{
if (myGrp.children[cnt].type == -1)
{
myGrp.children[cnt].type = parenttype;
myGrp.children[cnt].appid = myGrp.appid;
}
}
}
}
private void ParseIntoDictionary()
{
FileStream fsIn = new FileStream(fstPath, 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);
r.Close();
myHdr.hSize = BitConverter.ToInt32(ab, 0);
myHdr.hYear = BitConverter.ToInt16(ab, 4);
myHdr.hMonth = ab[6];
myHdr.hDay = ab[7];
myHdr.hcYear = BitConverter.ToInt16(ab, 8);
myHdr.hcMonth = ab[10];
myHdr.hcDay = ab[11];
myHdr.hcHour = ab[12];
myHdr.hcMin = ab[13];
myHdr.hcSec = ab[14];
myHdr.hcHund = ab[15];
int hdrOffset = BitConverter.ToInt32(ab, 16);
int howbig = BitConverter.ToInt32(ab, hdrOffset);
int dbs = BitConverter.ToInt16(ab, hdrOffset + 4);
myHdr.myDbs = new rodbi[dbs];
for (int i = 0; i < dbs; i++)
{
int offset = hdrOffset + 6 + (i * 30);
myHdr.myDbs[i].dbiID = BitConverter.ToInt16(ab, offset + 0);
TableID = myHdr.myDbs[i].dbiID;
myHdr.myDbs[i].dbiType = BitConverter.ToInt16(ab, offset + 2);
myHdr.myDbs[i].dbiAW = BitConverter.ToInt16(ab, offset + 4);
rogrp tmp = LoadGroup(ab, BitConverter.ToInt32(ab, offset + 6));
myHdr.myDbs[i].ID = tmp.ID;
myHdr.myDbs[i].children = tmp.children;
int iPtr = BitConverter.ToInt32(ab, offset + 22) + hdrOffset + 6;
myHdr.myDbs[i].dbiTitle = Encoding.Default.GetString(ab, iPtr, StringLength(ab, iPtr));
iPtr = BitConverter.ToInt32(ab, offset + 26) + hdrOffset + 6;
myHdr.myDbs[i].dbiAP = Encoding.Default.GetString(ab, iPtr, StringLength(ab, iPtr));
}
}
public bool SaveToXml(string fname)
{
try
{
StreamWriter swxml = new StreamWriter(fname);
XmlSerializer mySer = new XmlSerializer(typeof(roHdr));
mySer.Serialize(swxml, myHdr);
swxml.Close();
_docVer = value;
}
catch (Exception ex)
}
[NonSerialized]
private ROFSTLookup _ROFSTLookup;
public ROFSTLookup ROFSTLookup
{
get
{
log.ErrorFormat("Error writing to file: {0}", ex.Message);
return false;
if (_ROFSTLookup == null)
{
_ROFSTLookup = new ROFSTLookup(this);
}
return _ROFSTLookup;
}
return true;
}
public XmlDocument GetXmlFromFile(string fname)
{
FileStream xmlIn = new FileStream(fname, FileMode.Open, FileAccess.Read, FileShare.Read);
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(xmlIn);
xmlIn.Close();
return xmlDoc;
}
public string GetValueFromXml(XmlDocument xmlDoc, string ROID)
{
// use roid as xpath to get data.
try
{
string xpath_roid = "//rochild[roid = \"" + ROID.Substring(0, 12) + "\"]/value";
XmlNode valnd = xmlDoc.SelectSingleNode(xpath_roid);
if (valnd == null) return null;
return valnd.InnerText;
}
catch (Exception ex)
{
log.ErrorFormat("Cannot find ro in XmlDocument ");
log.ErrorFormat("roid = {0}", ROID);
log.ErrorFormat("{0}\r\n\r\n{1}", ex.Message, ex.InnerException);
}
return null;
}
public string GetFstPath()
{
return fstPath;
}
public string GetDefaultGraphicExtension()
{
if (docVerInfo != null)
return docVerInfo.DocVersionConfig.Graphics_defaultext;
else
return "TIF"; // this is the Volian Default
}
#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 (docVerInfo != null)
return docVerInfo.DocVersionConfig.RODefaults_setpointprefix;
if (docVer != null)
return docVer.DocVersionConfig.RODefaults_setpointprefix;
else
return "SP1"; // Not Sure about this...
}
public string GetDefaultGraphicsPrefix()
{
if (docVerInfo != null)
return docVerInfo.DocVersionConfig.RODefaults_graphicsprefix;
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)
{
string rofstfilepath = rdi.FolderPath + @"\ro.fst";
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 with docversion.
ROFst rofst = ROFst.GetByRODbID_DTS(rdi.RODbID, di.LastWriteTime);
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 rd = RODb.Get(rdi.RODbID))
{
rofst = ROFst.MakeROFst(rd, ab, null, di.LastWriteTime, 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);
}
}
}
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)
{
// file validity checks are done before getting here - just do the import
// here.
string rofstfilepath = rdi.FolderPath + @"\ro.fst";
DirectoryInfo di = new DirectoryInfo(rdi.FolderPath);
// There may be more than 1 'ro' as the 'ROName' field (ROName is derived from the ropath).
// Get new name be incrementing, if so.
string newname = NewROName(di.Name);
// 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 rd = RODb.Get(rdi.RODbID))
{
ROFst rofst = ROFst.MakeROFst(rd, ab, null, di.LastWriteTime, 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
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);
}
}
}
return rofst;
}
}
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)
{
for (int i = 0; i < rochild.Length; i++)
{
if (rochild[i].type == 8) this.AddGraphic(rdi, rochild[i].value);
if (rochild[i].children != null) this.MigrateRoFstGraphics(rdi, rochild[i].children);
}
}
private void AddGraphic(RODbInfo rdi, string p)
{
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...
using (roImg = ROImage.GetByRODbID_FileName_DTS(rdi.RODbID, imgname,fi.LastWriteTime))
{
if (roImg == null)
{
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();
using (RODb rodb = RODb.Get(rdi.RODbID))
{
roImg = ROImage.MakeROImage(rodb, imgname, ab, null, fi.LastWriteTime, "Migration");
}
}
Figure figure = Figure.GetByROFstID_ImageID(this.ROFstID, roImg.ImageID);
if (figure != null) return;
using (ROFst rofst = ROFst.Get(this.ROFstID))
{
figure = Figure.MakeFigure(rofst, roImg, null);
}
}
}
else
Console.WriteLine(string.Format("{0}", imgfile), "Cannot Find Image File");
}
#endregion
#endregion
}
}