From 8b5e7e01ad8be3c79d0914007adb6a6c6699a631 Mon Sep 17 00:00:00 2001 From: John Date: Fri, 24 Mar 2017 14:29:39 +0000 Subject: [PATCH] B2017-060 the update of RO usages of an imported procedure, if RO was not found in the ROUsage table, the import would be aborted instead of converting the invalid RO to text B2017-060 the update of RO usages of an imported procedure, if RO was not found in the ROUsage table, the import would be aborted instead of converting the invalid RO to text. Part of B2017-060 fix were we need to prevent the content text from being disposed when Item is used in a Using statement. --- .../VEPROMS User Interface/dlgExportImport.cs | 30 ++++++---- .../Extension/ContentExt.cs | 57 ++++++++++++------- .../VEPROMS.CSLA.Library/Extension/ItemExt.cs | 2 + PROMS/VEPROMS.CSLA.Library/Generated/Item.cs | 9 ++- 4 files changed, 68 insertions(+), 30 deletions(-) diff --git a/PROMS/VEPROMS User Interface/dlgExportImport.cs b/PROMS/VEPROMS User Interface/dlgExportImport.cs index f0087956..d320ecd4 100644 --- a/PROMS/VEPROMS User Interface/dlgExportImport.cs +++ b/PROMS/VEPROMS User Interface/dlgExportImport.cs @@ -3288,6 +3288,11 @@ namespace VEPROMS _DidConvertROsToText |= true; } private void AddROUsages(Content content, XmlNode xn) + { + AddROUsages(content, xn, false); + } + // part of bug fix B2017-060 added the isGrid parameter + private void AddROUsages(Content content, XmlNode xn, bool isGrid) { if (_ConvertROsToTextDuringImport) ConvertImportProcedureROsToText(content, xn); @@ -3307,7 +3312,7 @@ namespace VEPROMS if (roval == "?") { RoUsageInfo roui = RoUsageInfo.Get(int.Parse(rousageid)); - content.FixContentText(roui, roval, 0, MyDocVersion.DocVersionAssociations[0].MyROFst); + content.FixContentText(roui, roval, 0, MyDocVersion.DocVersionAssociations[0].MyROFst, null, rousageid); // + " " + roid); _DidConvertROsToText |= true; // B2016-225 (follow through) add annotation when RO is converted to text } else @@ -3322,9 +3327,20 @@ namespace VEPROMS content.Text = content.Text.Replace(lookFor, replaceWith); content.FixContentText(roui, roval, 0, MyDocVersion.DocVersionAssociations[0].MyROFst); } + if (isGrid) // B2017-060 when importing a grid, also update the grid's xml defination + { + string glookFor = string.Format("#Link:ReferencedObject:{0} {1} {2}[END>", rousageid, roid, oldRODbID.ToString()); + string greplaceWith = string.Format("#Link:ReferencedObject:{0} {1} {2}[END>", rou.ROUsageID.ToString(), roid, newRODbID.ToString()); + if (glookFor != greplaceWith) + { + content.MyGrid.Data = content.MyGrid.Data.Replace(glookFor, greplaceWith); + } + } } } content.Save(); + if (isGrid) + GridInfo.Refresh(content.MyGrid); // force the updated grid (table) to refresh } } @@ -3490,7 +3506,7 @@ namespace VEPROMS if (xn.SelectNodes("annotation").Count > 0) AddAnnotations(step.ItemID, xn); if (xc.SelectNodes("rousage").Count > 0) - AddROUsages(step.MyContent, xc); + AddROUsages(step.MyContent, xc, true); // part of bug fix: B2017060 to properly convert invalid RO to text if (xc.SelectNodes("transition").Count > 0) AddTransitions(step.MyContent, xc); prevInfo = StepInfo.Get(step.ItemID); @@ -4062,14 +4078,7 @@ namespace VEPROMS string ss = data.Substring(myIndex, myLength); if (ss != newvalue) { - int ii = data.Substring(0, mmg.Index).LastIndexOf(@"\v"); - int iil = data.Substring(mmg.Index + mg.Value.Length).IndexOf(@"\v0"); - string part1 = data.Substring(0, ii); // length up to \v - string part2 = data.Substring(ii + 2, mmg.Index - (ii + 2)); - string part3 = ss; - string part4 = data.Substring(mmg.Index + mg.Value.Length, iil); - string part5 = data.Substring(mmg.Index + (mg.Value.Length + iil + 3)); - data = part1 + part2 + part3 + part4 + part5; + data = Content.ConvertGridROsToText(data, mmg, mg, ss); // part of bug fix: B2017060 to properly convert invalid RO to text } } } @@ -4098,6 +4107,7 @@ namespace VEPROMS content.MyGrid = gg; } + // jsj 4-29-2016 appears to not be used //private Dictionary AddEntry(XmlReader xr) //{ diff --git a/PROMS/VEPROMS.CSLA.Library/Extension/ContentExt.cs b/PROMS/VEPROMS.CSLA.Library/Extension/ContentExt.cs index c42aef37..5781361f 100644 --- a/PROMS/VEPROMS.CSLA.Library/Extension/ContentExt.cs +++ b/PROMS/VEPROMS.CSLA.Library/Extension/ContentExt.cs @@ -75,6 +75,7 @@ namespace VEPROMS.CSLA.Library //Text = Text.Substring(0, myIndex - 14) + gg + Text.Substring(myIndex + myLength); using (Item myitem = this.ContentItems[0].MyItem) // so that myitem does not stay in cache B2016-153 { + myitem.DisposeOfContent = false; // don't dispose of the contents may be needed if more than one RO needs processed - part of B2017-060 // B2016-225 (follow through) added more descriptive Annotation Type when transition is converted to text Annotation.MakeAnnotation(myitem, AnnotationType.GetByNameOrCreate("Link Converted To Text"), "", string.Format("Transition ({0}) converted to text", ItemInfo.ConvertToDisplayText(gg)), null); } @@ -381,13 +382,20 @@ namespace VEPROMS.CSLA.Library return @"\v"; } public string ConvertROToText(RoUsageInfo rousg, string value, int rotype, ROFstInfo origROFstInfo) + { + return ConvertROToText(rousg, value, rotype, origROFstInfo, ""); + } + // B2017-060 added roidFrmImportStep to pass in a ROID to use when rousg is null (import procedure uses this) + public string ConvertROToText(RoUsageInfo rousg, string value, int rotype, ROFstInfo origROFstInfo, string roidFrmImportStep) { string retval = null; string newvalue = value; string findLink = @""; MatchCollection ms = Regex.Matches(Text, findLink); //string lookFor = string.Format(@"", rousg.ROUsageID); - string lookFor = string.Format(@"^$", rousg.ROUsageID); + //string lookFor = string.Format(@"^$", rousg.ROUsageID); + string strROUID = (rousg != null) ? rousg.ROUsageID.ToString() : roidFrmImportStep; + string lookFor = string.Format(@"^$", strROUID); int lastIndex = 0; string newText = Text; foreach (Match mm in ms) @@ -457,7 +465,7 @@ namespace VEPROMS.CSLA.Library } //Console.WriteLine("Text: {0} NewText: {1}", Text, newText); // see if there is a grid to update too. - if (rousg.MyContent.MyGrid != null) + if (_MyGrid != null) //(rousg.MyContent.MyGrid != null) { if (rotype == (int)E_ROValueType.Table) // if change in rotable data... { @@ -478,13 +486,12 @@ namespace VEPROMS.CSLA.Library // if it's an ro within a table, need to process into an flex grid to save the grid data: string findLinkXml = @"<START\].*?\[END>"; //string lookForXml = string.Format(@"<START\](\\[^v \\]+)*\\v0(\\[^v \\]+)* (.*?)(\\[^v '?\\]+)*\\v(\\[^v \\]+)* #Link:ReferencedObject:{0} .*?\[END>", rousg.ROUsageID); - string lookForXml = string.Format(@"^<START\](\\[^v \\]+)*\\v0(\\[^v '?{{}}\\]+)*( |\\u[0-9]{{1,4}}?|\\'[0-9a-fA-F]{{2}}|\\[{{}}~])(.*?)(\\[^v'?{{}} \\]+)*\\v(\\[^v \\]+)* #Link:ReferencedObject:{0} .*?\[END>$", rousg.ROUsageID); + string lookForXml = string.Format(@"^<START\](\\[^v \\]+)*\\v0(\\[^v '?{{}}\\]+)*( |\\u[0-9]{{1,4}}?|\\'[0-9a-fA-F]{{2}}|\\[{{}}~])(.*?)(\\[^v'?{{}} \\]+)*\\v(\\[^v \\]+)* #Link:ReferencedObject:{0} .*?\[END>$", strROUID); MatchCollection msg = Regex.Matches(MyGrid.Data, findLinkXml); int nmsg = msg.Count; for (int i = nmsg - 1; i >= 0; i--) { Match mmg = msg[i]; - int offset = 0; // crashed in substring line below if using mmg.Index; Set to 0 and it worked - KBR. Match mg = Regex.Match(mmg.Value, lookForXml);// Regex.Match(MyGrid.Data, lookForXml); if (mg != null && mg.Groups.Count > 1) { @@ -496,6 +503,8 @@ namespace VEPROMS.CSLA.Library myLength += mg.Groups[3].Length; } string gg = MyGrid.Data.Substring(myIndex, myLength); + if (value == "?") + newvalue = gg; // B2017-060 the text part of the RO link if (newvalue.Contains(@"\u8209?")) { Match m = Regex.Match(newvalue, @"(\\f[0-9]+)(\\u[0-9]{1,4}\?)(\\f[0-9]+ ?)"); @@ -512,38 +521,48 @@ namespace VEPROMS.CSLA.Library else newvalue = newvalue.Replace(@"\u9586?", m.Groups[1].Value + @"\u9586?" + m.Groups[3].Value); } - if (gg != newvalue) + if (value == "?" || gg != newvalue) { - MyGrid.Data = MyGrid.Data.Substring(0, myIndex) + newvalue + MyGrid.Data.Substring(myIndex + myLength); + MyGrid.Data = Content.ConvertGridROsToText(MyGrid.Data, mmg, mg, newvalue); // B2017-060 convert the RO in the grid (table) to text } - //System.Text.RegularExpressions.Group g = mg.Groups[3]; - //if (g.ToString() != newvalue) - //{ - // retval = g.Value; - // MyGrid.Data = MyGrid.Data.Substring(0, offset + mmg.Index + g.Index) + newvalue + MyGrid.Data.Substring(offset + mmg.Index + g.Index + g.Length); - //} } } } } return retval == null ? "" : retval; } - public string FixContentText(RoUsageInfo rousg, string value, int rotype, ROFstInfo origROFstInfo) // string newvalue) + // B2017-060 logic pulled from dlgExportImport to covert a RO in a table (grid) to text + public static string ConvertGridROsToText(string data, Match mmg, Match mg, string ss) { - return FixContentText(rousg, value, rotype, origROFstInfo, null); + int ii = data.Substring(0, mmg.Index).LastIndexOf(@"\v"); + int iil = data.Substring(mmg.Index + mg.Value.Length).IndexOf(@"\v0"); + string part1 = data.Substring(0, ii); // length up to \v + string part2 = data.Substring(ii + 2, mmg.Index - (ii + 2)); + string part3 = ss; + string part4 = data.Substring(mmg.Index + mg.Value.Length, iil); + string part5 = data.Substring(mmg.Index + (mg.Value.Length + iil + 3)); + data = part1 + part2 + part3 + part4 + part5; + return data; } - public string FixContentText(RoUsageInfo rousg, string value, int rotype, ROFstInfo origROFstInfo,string fileNameOnly) // string newvalue) + public string FixContentText(RoUsageInfo rousg, string value, int rotype, ROFstInfo origROFstInfo) + { + return FixContentText(rousg, value, rotype, origROFstInfo, null, ""); + } + // B2017-060 added roidFrmImportStep to pass in a ROID to use when rousg is null (import procedure uses this) + public string FixContentText(RoUsageInfo rousg, string value, int rotype, ROFstInfo origROFstInfo, string fileNameOnly, string roidFrmImportStep) { string retval = null; if (value == "?") { - retval = this.ConvertROToText(rousg, value, rotype, origROFstInfo); + retval = this.ConvertROToText(rousg, value, rotype, origROFstInfo, roidFrmImportStep); using (Item myitem = this.ContentItems[0].MyItem) // so that myitem does not stay in cache B2016-153 { + myitem.DisposeOfContent = false; // don't dispose of the contents may be needed if more than one RO needs processed - part of B2017-060 // B2016-225 (follow through) added more descriptive Annotation Type when RO is converted to text Annotation.MakeAnnotation(myitem, AnnotationType.GetByNameOrCreate("Link Converted To Text"), "", string.Format("RO value ({0}) converted to text", ItemInfo.ConvertToDisplayText(retval)), null); } - RoUsage.Delete(rousg.ROUsageID); + if (rousg != null) + RoUsage.Delete(rousg.ROUsageID); return retval; } string newvalue = value; @@ -595,8 +614,8 @@ namespace VEPROMS.CSLA.Library // if it's an ro within a table, need to process into an flex grid to save the grid data: string findLinkXml = @"<START\].*?\[END>"; //string lookForXml = string.Format(@"<START\](\\[^v \\]+)*\\v0(\\[^v \\]+)* (.*?)(\\[^v '?\\]+)*\\v(\\[^v \\]+)* #Link:ReferencedObject:{0} .*?\[END>", rousg.ROUsageID); - string lookForXml = string.Format(@"^<START\](\\[^v \\]+)*\\v0(\\[^v '?{{}}\\]+)*( |\\u[0-9]{{1,4}}?|\\'[0-9a-fA-F]{{2}}|\\[{{}}~])(.*?)(\\[^v'?{{}} \\]+)*\\v(\\[^v \\]+)* #Link:ReferencedObject:{0} .*?\[END>$", rousg.ROUsageID); - MatchCollection msg = Regex.Matches(MyGrid.Data, findLinkXml); + string lookForXml = string.Format(@"^<START\](\\[^v \\]+)*\\v0(\\[^v '?{{}}\\]+)*( |\\u[0-9]{{1,4}}?|\\'[0-9a-fA-F]{{2}}|\\[{{}}~])(.*?)(\\[^v'?{{}} \\]+)*\\v(\\[^v \\]+)* #Link:ReferencedObject:{0} .*?\[END>$", rousg.ROUsageID); + MatchCollection msg = Regex.Matches(MyGrid.Data, findLinkXml); foreach (Match mmg in msg) { Match mg = Regex.Match(mmg.Value, lookForXml);// Regex.Match(MyGrid.Data, lookForXml); diff --git a/PROMS/VEPROMS.CSLA.Library/Extension/ItemExt.cs b/PROMS/VEPROMS.CSLA.Library/Extension/ItemExt.cs index 15c80bb4..3a934e63 100644 --- a/PROMS/VEPROMS.CSLA.Library/Extension/ItemExt.cs +++ b/PROMS/VEPROMS.CSLA.Library/Extension/ItemExt.cs @@ -753,6 +753,7 @@ namespace VEPROMS.CSLA.Library oldText = content.ConvertROToText(rousage, roval, roch.type, rofstinfo); using (Item myitem = content.ContentItems[0].MyItem) // so that myitem does not stay in cache B2016-153 { + myitem.DisposeOfContent = false; // don't dispose of the contents may be needed if more than one RO needs processed - part of B2017-060 // B2016-225 (follow through) added more descriptive Annotation Type when RO is converted to text Annotation.MakeAnnotation(myitem, AnnotationType.GetByNameOrCreate("Link Converted To Text"), "", string.Format("RO value ({0}) converted to text", ItemInfo.ConvertToDisplayText(oldText)), null); } @@ -795,6 +796,7 @@ namespace VEPROMS.CSLA.Library oldText = content.ConvertROToText(rousage, roval, roch.type, rofstinfo); using (Item myitem = content.ContentItems[0].MyItem) // so that myitem does not stay in cache B2016-153 { + myitem.DisposeOfContent = false; // don't dispose of the contents may be needed if more than one RO needs processed - part of B2017-060 // B2016-225 (follow through) added more descriptive Annotation Type when RO is converted to text Annotation.MakeAnnotation(myitem, AnnotationType.GetByNameOrCreate("Link Converted To Text"), "", string.Format("RO value ({0}) converted to text", ItemInfo.ConvertToDisplayText(oldText)), null); } diff --git a/PROMS/VEPROMS.CSLA.Library/Generated/Item.cs b/PROMS/VEPROMS.CSLA.Library/Generated/Item.cs index fd46cf17..57a55d22 100644 --- a/PROMS/VEPROMS.CSLA.Library/Generated/Item.cs +++ b/PROMS/VEPROMS.CSLA.Library/Generated/Item.cs @@ -733,13 +733,20 @@ namespace VEPROMS.CSLA.Library { _CountFinalized++; } + private bool _DisposeOfContent = true; // part B2017-060 when Item is in a Using statement, the content was being freed after it's use, we needed the content to stick around + + public bool DisposeOfContent + { + get { return _DisposeOfContent; } + set { _DisposeOfContent = value; } + } public void Dispose() { if (_Disposed) return; _CountDisposed++; _Disposed = true; RemoveFromDictionaries(); - if (_MyContent != null) + if (_MyContent != null && DisposeOfContent) { _MyContent.Dispose(); _MyContent = null;