SourceCode/PROMS/DataLoader/Transitions.cs
2013-06-27 12:43:34 +00:00

429 lines
16 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.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Data.OleDb;
using System.Collections.Specialized;
using System.Collections.Generic;
using System.Xml;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using VEPROMS.CSLA.Library;
namespace DataLoader
{
public partial class Loader
{
Dictionary<int, List<string>> _ContentMigrationErrors = new Dictionary<int,List<string>>();
List<string> _TransitionMigrationErrors = null;
//private void AddContentMigrationError(Content fromCon,string errorMsg)
//{
// if (!_ContentMigrationErrors.ContainsKey(fromCon.ContentID))
// _ContentMigrationErrors.Add(fromCon.ContentID,new List<string>());
// _ContentMigrationErrors[fromCon.ContentID].Add(errorMsg);
//}
private string AddTrans(OleDbConnection cn, Content fromCon, DataRow dr, DataRow dr2, string pth)
{
List<string> migrationErrors = new List<string>();
string thekey = dr["TONUMBER"].ToString() + "|" + dr["TOSEQUENCE"].ToString();
if (thekey.EndsWith("0S"))
thekey = thekey.Substring(0, thekey.Length - 1);
string dti = dr["DTI"].ToString().PadRight(18, ' ');
string userid = dti.Substring(13, 5).Trim();
int itype = 0;
ConfigInfo ci = null;
//string otranskey = null;
// The transition type was stored as a character & also, when read in thru
// ado.net may have been converted into unicode. So in order to get the
// correct type, first, use the TextConvert to eliminate the conversion done
// by ado.net. Then convert to a number. The 'anding of 0x80' flags that it
// is a formatted transition (i.e. this was done for byron/braidwood to
// show the transition with a page number or not). The 'anding of 0x7f' gets
// the actual number when subtracted from 0x30 (the value of the 0 character).
try
{
char typech = TextConvert.ConvertSeq(dr["TYPE"].ToString())[0];
int tmpitype = Convert.ToInt32(typech);
if ((tmpitype & 0x80) > 0)
{
ci = new ConfigInfo(null);
ci.AddItem("Transition", "Formatted", "True");
}
itype = (tmpitype&0x7F) - 0x30;
}
catch (Exception ex)
{
frmMain.AddError(ex,"Error converting transition type '{0}'",dr["TYPE"].ToString());
log.Error("Error converting transition type");
log.ErrorFormat("type from database = {0}", dr["TYPE"].ToString());
log.ErrorFormat("{0}\r\n\r\n{1}", ex.Message, ex.InnerException);
itype = -1;
}
DateTime dts = GetDTS(MakeDate(dti.Substring(0, 8).Trim()), dti.Substring(8, 5).Trim());
// if it's in the dictionary of structure elements already migrated, just use this
// structure id, or if it's in the dictionary of structure elements that have
// not been migrated but a record was created from this code, use it. Otherwise
// create a new structure record and use its id, its data will be updated later.
// a structure record.
Item toItem = null;
Item toItem2 = null;
if (itype == 6) // Outside Transition
{
ItemInfo tmp = _OutTran.GetItem(thekey, migrationErrors);
if (tmp != null)
toItem = tmp.Get();
else
{
//toItem = Item.New(null, TransDummyCont, DateTime.Now, "Migration");
fromCon.Save();
migrationErrors.Add("Transition Error: Missing Data - " + _OutTran.GetDescription(thekey) + ". Converted to text");
if (!_ContentMigrationErrors.ContainsKey(fromCon.ContentID))
_ContentMigrationErrors.Add(fromCon.ContentID, migrationErrors);
return _OutTran.GetTransitionText(thekey);
}
toItem2 = toItem;
// the 32-bit program will no longer have a special type for outside transitions - make it a
// type of 0 (procedure with optional step).
itype = 0;
}
else
{
if (itype > 6) itype--; // Corrected to match transformat table (16-bit skips type 6 because it's an outside transition)
if (dicTrans_ItemDone.ContainsKey(thekey))
{
toItem = dicTrans_ItemDone[thekey];
if (toItem.ContentID == TransDummyCont.ContentID)
_TransitionMigrationErrors.Add(thekey);
}
else
{
if (dicTrans_ItemIds.ContainsKey(thekey))
{
toItem = dicTrans_ItemIds[thekey];
if (toItem.ContentID == TransDummyCont.ContentID)
_TransitionMigrationErrors.Add(thekey);
}
else
{
// note that parent is null right now - it will be filled in later.
//toItem = Item.MakeItem(null, fromCon, DateTime.Now, "Migration");
toItem = Item.New(null, TransDummyCont, DateTime.Now, "Migration");
dicTrans_ItemIds.Add(thekey, toItem);
_TransitionMigrationErrors.Add(thekey);
}
}
// if there is data in dr2, it means that it is a range transition. Get its item
// data too.
toItem2 = toItem;
if (dr2 != null)
{
string thekey2 = dr2["TONUMBER"].ToString() + "|" + dr2["TOSEQUENCE"].ToString();
// Range transitions that are type 2 are called 'and' transitions. These should extend to the
// last sibling. In data, these are represented with the SQL database field in the transitions
// table 'IsRange' == 2, and the toid == rangeid. In the content record, the link is
// TransitionRange:[type] [tranid] [toid] [rangeid] -> and the toid == rangeid
// The following was commented out for the Shearon Harris data migration because the
// migrated data did not match 16bit. One example can be found EOPS/ECA-0.0, step 47, RNO.
// 16bit had Steps 47b AND c; 32bit had Steps 47b, c, d, e, f AND g before this code was
// commented out (June 2013).
//if (itype == 2)
//{
// if (dr["TOSEQUENCE"].ToString().Length > 3 &&
// dr["TOSEQUENCE"].ToString().Substring(0, 2) == dr2["TOSEQUENCE"].ToString().Substring(0, 2))
// thekey2 = thekey;
// else
// thekey2 = dr2["TONUMBER"].ToString() + "|" + dr2["TOSEQUENCE"].ToString().Substring(0, 3);
//}
if (dicTrans_ItemDone.ContainsKey(thekey2))
{
toItem2 = dicTrans_ItemDone[thekey2];
if (toItem2.ContentID == TransDummyCont.ContentID)
_TransitionMigrationErrors.Add(thekey2);
}
else
{
if (dicTrans_ItemIds.ContainsKey(thekey2))
{
toItem2 = dicTrans_ItemIds[thekey2];
if (toItem2.ContentID == TransDummyCont.ContentID)
_TransitionMigrationErrors.Add(thekey2);
}
else
{
toItem2 = Item.MakeItem(null, TransDummyCont, DateTime.Now, "Migration");
dicTrans_ItemIds.Add(thekey2, toItem2);
_TransitionMigrationErrors.Add(thekey2);
}
}
}
}
if (userid == null || userid == "") userid = "Migration";
string results = null;
try
{
int isRange = 0;
if (toItem.ItemID != toItem2.ItemID)
isRange = 1;
else if (itype == 2)
isRange = 2;
using (Transition tr = Transition.New(fromCon, toItem, toItem2, isRange, itype, ci != null ? ci.ToString() : null, dts, userid))
{
//if (otranskey != null)
// tr.MyZTransition.Oldto = otranskey; // info to finish outside transition processing later
//else
tr.MyZTransition.Oldto = dr["OLDTO"].ToString();
if (!tr.IsSavable) ErrorRpt.ErrorReport(tr);
tr.Save();
if (migrationErrors.Count > 0)
_ContentMigrationErrors.Add(fromCon.ContentID, migrationErrors);
if (toItem.ItemID == toItem2.ItemID && itype != 2)
results = string.Format(@"\v <START]\v0 (Resolved Transition Text)\v #Link:Transition:{0} {1} {2}[END>\v0 ", tr.TranType, tr.TransitionID, tr.ToID);
else
results = string.Format(@"\v <START]\v0 (Resolved Transition Text)\v #Link:TransitionRange:{0} {1} {2} {3}[END>\v0 ", tr.TranType, tr.TransitionID, tr.ToID, tr.RangeID);
}
}
catch (Exception ex)
{
frmMain.AddError(ex, "Error addition transition record");
log.Error("Error addition transition record");
log.ErrorFormat("{0}\r\n\r\n{1}", ex.Message, ex.InnerException);
}
return results;
}
private string MigrateTrans(OleDbConnection cn, string textm, string seqcvt, Content content, string pth)
{
// TODO: BYRON DATA WILL GENERATE A TRANSITION ERROR WHEN IT IS USED IN PROMS 2010
StringBuilder trtxt = new StringBuilder();
int instance = 0;
int beg = 0;
DataTable dt = null;
DataSet ds = null;
OleDbDataAdapter da = null;
char[] chrtrn = { '\x252C', '\x2566' };
int tok = textm.IndexOfAny(chrtrn);
if (tok > -1)
{
string cmd = "SELECT * FROM [tran] WHERE [FROMNUMBER]='" + ProcNumber.Replace("'", "''") + "' AND [FROMSEQUEN] ='" + seqcvt + "' ORDER BY [FROMINSTAN]";
da = new OleDbDataAdapter(cmd, cn);
// get transition records for this step.
ds = new DataSet();
try
{
da.Fill(ds);
dt = ds.Tables[0];
dt.CaseSensitive = true;
}
catch (Exception ex)
{
frmMain.AddError(ex, "Error getting transitions '{0}' '{1}'", ProcNumber, seqcvt);
log.Error("Error getting transitions");
log.ErrorFormat("from number = {0} oldstepsequence = {1}", ProcNumber, seqcvt);
log.ErrorFormat("{0}\r\n\r\n{1}", ex.Message, ex.InnerException);
ds.Dispose();
da.Dispose();
return textm;
}
}
while (tok > -1)
{
// found a transition token, add the token and transition id into the string and
// add an transition record for it. Later there may be text added.
trtxt.Append(textm.Substring(beg, tok - beg));
// we have too many tokens and not enough usage records - report an error...
if (instance >= dt.Rows.Count)
{
log.ErrorFormat("Error - ran out of transition records for step, check data ");
log.ErrorFormat("from number = {0} oldstepsequence = {1}", ProcNumber, seqcvt);
}
else
{
DataRow dr = dt.Rows[instance];
// if type is 2 or 3, this is a range transition, need to get the next
// record too
bool trange = false;
if (dr["Type"].ToString() == "2" || dr["Type"].ToString() == "3")
trange = true;
string rectxt = null;
if (trange)
{
instance++;
DataRow dr2 = dt.Rows[instance];
rectxt = AddTrans(cn, content, dr, dr2, pth);
}
else
rectxt = AddTrans(cn, content, dr, null, pth);
//trtxt.Append(textm[tok]);
trtxt.Append(rectxt);
}
instance++;
beg = tok + 1;
if (beg > textm.Length)
{
tok = -1;
da.Dispose();
}
else
tok = textm.IndexOfAny(chrtrn, beg);
}
if (beg < textm.Length)
trtxt.Append(textm.Substring(beg, textm.Length - beg));
if (dt.Rows.Count > instance + 1)
{
log.ErrorFormat("Error - extra transition records for step, check data ");
log.ErrorFormat("from number = {0} oldstepsequence = {1}", ProcNumber, seqcvt);
}
ds.Dispose();
da.Dispose();
return trtxt.ToString();
}
private void ShowMissingTransitions(DocVersion docver)
{
if (dicTrans_ItemIds.Keys.Count > 0)
{
// see if any end in |A0, if so, point these to the procedure associated with it.
CleanupTransToNonExistentSectionA0(docver);
foreach (string s in dicTrans_ItemIds.Keys)
{
//log.WarnFormat("{0} - {1}", s, dicTrans_ItemIds[s]);
frmMain.AddError("Missing Transition Destination {0} - {1}", s, dicTrans_ItemIds[s].ItemID);
//AddItemAnnotation(dicTrans_ItemIds[s]);
}
}
foreach (string s in dicTrans_MigrationErrors.Keys)
{
foreach (Item itm in dicTrans_MigrationErrors[s])
{
ItemAnnotation ia = itm.ItemAnnotations.Add(MigrationErrorType);
ia.SearchText = "Transition Error: Destination Missing - " + s;
ia.UserID = "Migration";
itm.Save();
}
}
if (TransDummyCont.ContentItemCount > 0)
log.Warn("Bad transitions to 'dummy' content");
foreach (ContentItem itm in TransDummyCont.ContentItems)
{
log.WarnFormat("ItemID = {0}", itm.ItemID);
//AddItemAnnotation(itm.MyItem);
}
log.Info("End of Missing Transitions");
}
private void CleanupTransToNonExistentSectionA0(DocVersion docver)
{
List<string> RemoveFromDicTrans = new List<string>();
// see if any end in |A0, if so, point these to the procedure associated with it.
foreach (string s in dicTrans_ItemIds.Keys)
{
if (s.EndsWith("|A0"))
{
// make a list to store those that need changed because can't change data in
// a foreach:
RemoveFromDicTrans.Add(s);
Item item = dicTrans_ItemIds[s]; // to or range id.
//ItemInfo ii = ItemInfo.Get(item.ItemID);
//get the proc id that will become the new to or range id.
string procnum = s.Substring(0, s.IndexOf("|"));
DocVersionInfo dvi = DocVersionInfo.Get(docver.VersionID);
IList iprcs = dvi.GetChildren();
ItemInfo prc = null;
foreach (ItemInfo ii in iprcs)
{
if (ii.DisplayNumber == procnum)
{
prc = ii;
break;
}
}
// For each transition that points to the A0, make it point to the proc.
// First, find all of them by getting transitions with the A0 (dummy
// transition record). Then update the to or range id in the transition
// record & then update the content/from part.
List<int> transToChg = new List<int>();
List<int> transRgChg = new List<int>();
TransitionInfoList til = TransitionInfoList.GetByToID(item.ItemID);
foreach (TransitionInfo ti in til) UpdateTranDataForA0(prc, ti.TransitionID, false);
til = TransitionInfoList.GetByRangeID(item.ItemID);
foreach (TransitionInfo tir in til) UpdateTranDataForA0(prc, tir.TransitionID, true);
}
}
foreach (string str in RemoveFromDicTrans)
{
dicTrans_ItemIds.Remove(str);
dicTrans_MigrationErrors.Remove(str);
}
}
private static void UpdateTranDataForA0(ItemInfo procItem, int transid, bool isRange)
{
int type;
int oldto;
int oldrg;
int oldfrom;
using (Transition t = Transition.Get(transid))
{
type = t.TranType;
oldto = t.ToID;
oldrg = t.RangeID;
oldfrom = t.FromID;
if (!isRange)
{
t.MyItemToID = procItem.Get();
t.MyItemRangeID = procItem.Get();
}
else
t.MyItemRangeID = procItem.Get();
t.Save();
}
using (Content c = Content.Get(oldfrom))
{
string lookFor = (isRange || oldto != oldrg) ? string.Format(@"#Link:TransitionRange:{0} {1} {2} {3}", type, transid, oldto, oldrg) :
string.Format(@"#Link:Transition:{0} {1} {2}", type, transid, oldto);
string replaceWith = isRange ? string.Format(@"#Link:TransitionRange:{0} {1} {2} {3}", type, transid, oldto, procItem.ItemID) :
oldto != oldrg ? string.Format(@"#Link:TransitionRange:{0} {1} {2} {3}", type, transid, procItem.ItemID, oldrg) :
string.Format(@"#Link:Transition:{0} {1} {2}", type, transid, procItem.ItemID);
c.Text = c.Text.Replace(lookFor, replaceWith);
c.Save();
}
}
private void AddItemAnnotation(Item itm)
{
foreach (ItemTransition_ToID tmp in itm.ItemTransitions_ToID)
{
foreach (ContentItem ci in tmp.MyContent.ContentItems)
{
ItemAnnotation ia = ci.MyItem.ItemAnnotations.Add(MigrationErrorType);
ia.SearchText = "Transition Error: Missing end point";
ia.UserID = "Migration";
ci.MyItem.Save();
}
}
}
}
}