//Tuple: keyword | index | Application ID | GWA command | Set or Set At public List <ProxyGwaLine> GetGwaData(IEnumerable <string> keywords, bool nodeApplicationIdFilter) { var dataLock = new object(); var data = new List <ProxyGwaLine>(); var setKeywords = new List <string>(); var setAtKeywords = new List <string>(); var tempKeywordIndexCache = new Dictionary <string, List <int> >(); foreach (var keyword in keywords) { if (SetAtKeywordBeginnings.Any(b => keyword.StartsWith(b))) { setAtKeywords.Add(keyword); } else { setKeywords.Add(keyword); } } for (int i = 0; i < setKeywords.Count(); i++) { var newCommand = "GET_ALL\t" + setKeywords[i]; var isNode = setKeywords[i].Contains("NODE"); var isElement = setKeywords[i].StartsWith("EL."); string[] gwaRecords; try { gwaRecords = ExecuteWithLock(() => ((string)GSAObject.GwaCommand(newCommand)).Split(new string[] { "\n" }, StringSplitOptions.RemoveEmptyEntries)); } catch { gwaRecords = new string[0]; } Parallel.ForEach(gwaRecords, gwa => { ParseGeneralGwa(gwa, out string keyword, out int?foundIndex, out string foundStreamId, out string foundApplicationId, out string gwaWithoutSet, out GwaSetCommandType? gwaSetCommandType); var index = foundIndex ?? 0; var originalSid = ""; if (string.IsNullOrEmpty(foundStreamId)) { //Slight hardcoding for optimisation here: the biggest source of GetSidTagValue calls would be from nodes, and knowing //(at least in GSA v10 build 63) that GET_ALL NODE does return SID tags, the call is avoided for NODE keyword if (!isNode && !isElement) { try { foundStreamId = ExecuteWithLock(() => GSAObject.GetSidTagValue(keyword, index, SID_STRID_TAG)); } catch { } } } else { originalSid += FormatStreamIdSidTag(foundStreamId); } if (string.IsNullOrEmpty(foundApplicationId)) { //Again, the same optimisation as explained above if (!isNode && !isElement) { try { foundApplicationId = ExecuteWithLock(() => GSAObject.GetSidTagValue(keyword, index, SID_APPID_TAG)); } catch { } } } else { originalSid += FormatStreamIdSidTag(foundApplicationId); } var newSid = FormatStreamIdSidTag(foundStreamId) + FormatApplicationIdSidTag(foundApplicationId); if (!string.IsNullOrEmpty(originalSid) && !string.IsNullOrEmpty(newSid)) { gwaWithoutSet.Replace(originalSid, newSid); } if (!(nodeApplicationIdFilter == true && isNode && string.IsNullOrEmpty(foundApplicationId))) { var line = new ProxyGwaLine() { Keyword = keyword, Index = index, StreamId = foundStreamId, ApplicationId = foundApplicationId, GwaWithoutSet = gwaWithoutSet, GwaSetType = GwaSetCommandType.Set }; lock (dataLock) { if (!tempKeywordIndexCache.ContainsKey(keyword)) { tempKeywordIndexCache.Add(keyword, new List <int>()); } if (!tempKeywordIndexCache[keyword].Contains(index)) { data.Add(line); tempKeywordIndexCache[keyword].Add(index); } } } }
//Tuple: keyword | index | Application ID | GWA command | Set or Set At public List <ProxyGwaLine> GetGwaData(IEnumerable <string> keywords, bool nodeApplicationIdFilter, IProgress <int> incrementProgress = null) { var dataLock = new object(); var data = new List <ProxyGwaLine>(); var setKeywords = new List <string>(); var setAtKeywords = new List <string>(); var tempKeywordIndexCache = new Dictionary <string, List <int> >(); var versionRemovedKeywords = keywords.Select(kw => kw.Split('.').First()).Where(kw => !string.IsNullOrEmpty(kw)).ToList(); foreach (var keyword in versionRemovedKeywords) { if (SetAtKeywords.Any(b => keyword.Equals(b, StringComparison.InvariantCultureIgnoreCase))) { setAtKeywords.Add(keyword); } else { setKeywords.Add(keyword); } } for (int i = 0; i < setKeywords.Count(); i++) { var newCommand = "GET_ALL" + GSAProxy.GwaDelimiter + setKeywords[i]; var isNode = setKeywords[i].Contains("NODE"); var isElement = setKeywords[i].StartsWith("EL"); string[] gwaRecords; try { gwaRecords = ExecuteWithLock(() => ((string)GSAObject.GwaCommand(newCommand)).Split(new string[] { "\n" }, StringSplitOptions.RemoveEmptyEntries)); } catch { gwaRecords = new string[0]; } if (setKeywords[i].Equals("UNIT_DATA", StringComparison.InvariantCultureIgnoreCase)) { return(gwaRecords.Select(r => new ProxyGwaLine() { GwaWithoutSet = r, Keyword = "UNIT_DATA" }).ToList()); } Parallel.ForEach(gwaRecords, gwa => { ParseGeneralGwa(gwa, out string keywordWithVersion, out int?foundIndex, out string foundStreamId, out string foundApplicationId, out string gwaWithoutSet, out GwaSetCommandType? gwaSetCommandType, true); var index = foundIndex ?? 0; var originalSid = ""; var keyword = keywordWithVersion.Split('.').First(); //For some GET_ALL calls, records with other keywords are returned, too. Example: GET_ALL TASK returns TASK, TASK_TAG and ANAL records if (keyword.Equals(setKeywords[i], StringComparison.InvariantCultureIgnoreCase)) { if (string.IsNullOrEmpty(foundStreamId)) { //Slight hardcoding for optimisation here: the biggest source of GetSidTagValue calls would be from nodes, and knowing //(at least in GSA v10 build 63) that GET_ALL NODE does return SID tags, the call is avoided for NODE keyword if (!isNode && !isElement) { try { foundStreamId = ExecuteWithLock(() => GSAObject.GetSidTagValue(keyword, index, SID_STRID_TAG)); } catch { } } } else { originalSid += FormatStreamIdSidTag(foundStreamId); } if (string.IsNullOrEmpty(foundApplicationId)) { //Again, the same optimisation as explained above if (!isNode && !isElement) { try { foundApplicationId = ExecuteWithLock(() => GSAObject.GetSidTagValue(keyword, index, SID_APPID_TAG)); } catch { } } } else { originalSid += FormatStreamIdSidTag(foundApplicationId); } var newSid = FormatStreamIdSidTag(foundStreamId) + FormatApplicationIdSidTag(foundApplicationId); if (!string.IsNullOrEmpty(newSid)) { if (string.IsNullOrEmpty(originalSid)) { gwaWithoutSet = gwaWithoutSet.Replace(keywordWithVersion, keywordWithVersion + ":" + newSid); } else { gwaWithoutSet = gwaWithoutSet.Replace(originalSid, newSid); } } if (!(nodeApplicationIdFilter == true && isNode && string.IsNullOrEmpty(foundApplicationId))) { var line = new ProxyGwaLine() { Keyword = keyword, Index = index, StreamId = foundStreamId, ApplicationId = foundApplicationId, GwaWithoutSet = gwaWithoutSet, GwaSetType = GwaSetCommandType.Set }; lock (dataLock) { if (!tempKeywordIndexCache.ContainsKey(keyword)) { tempKeywordIndexCache.Add(keyword, new List <int>()); } if (!tempKeywordIndexCache[keyword].Contains(index)) { data.Add(line); tempKeywordIndexCache[keyword].Add(index); } } } } });