// ======================================================================== // 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> _ContentMigrationErrors = new Dictionary>(); List _TransitionMigrationErrors = null; //private void AddContentMigrationError(Content fromCon,string errorMsg) //{ // if (!_ContentMigrationErrors.ContainsKey(fromCon.ContentID)) // _ContentMigrationErrors.Add(fromCon.ContentID,new List()); // _ContentMigrationErrors[fromCon.ContentID].Add(errorMsg); //} private string AddTrans(OleDbConnection cn, Content fromCon, DataRow dr, DataRow dr2, string pth) { List migrationErrors = new List(); string thekey = dr["TONUMBER"].ToString() + "|" + TextConvert.ConvertSeq(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).TrimEnd()); // 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() + "|" + TextConvert.ConvertSeq(dr2["TOSEQUENCE"].ToString()); // Range transitions that are type 2 are called 'AND' transitions. // Example: Continue with steps 5b, 5c and 5d. // if the second key is greater than the first key, then the transition terminates // at the location specified in the second key. // If the second key is less than or equal the first key, the transition extends // to the last sibling of the first key. // In data, these are represented with the SQL database field in the transitions // table 'IsRange' == 2, toid and rangeid. In the content record, the link is // TransitionRange:[type] [tranid] [toid] [rangeid]. if (itype == 2 && thekey.CompareTo(thekey2) >= 0) thekey2 = thekey; 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 \v0 ", tr.TranType, tr.TransitionID, tr.ToID); else results = string.Format(@"\v \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 RemoveFromDicTrans = new List(); // 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; } } if (prc != null) { // 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 transToChg = new List(); List transRgChg = new List(); 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(); } } } } }