// ********************************************************************************************************** // MessageXmlDocument.cs // 5/18/2022 // NGI - Next Generation Interceptor // // Contract No. HQ0856-21-C-0003/1022000209 // // THIS DOCUMENT DOES NOT CONTAIN TECHNOLOGY OR TECHNICAL DATA CONTROLLED UNDER EITHER THE U.S. // INTERNATIONAL TRAFFIC IN ARMS REGULATIONS OR THE U.S. EXPORT ADMINISTRATION REGULATIONS. // // RAYTHEON PROPRIETARY: THIS DOCUMENT CONTAINS DATA OR INFORMATION PROPRIETARY TO RAYTHEON // COMPANY AND IS RESTRICTED TO USE ONLY BY PERSONS AUTHORIZED BY RAYTHEON COMPANY IN WRITING TO USE IT. // DISCLOSURE TO UNAUTHORIZED PERSONS WOULD LIKELY CAUSE SUBSTANTIAL COMPETITIVE HARM TO RAYTHEON // COMPANY'S BUSINESS POSITION. NEITHER SAID DOCUMENT NOR ITS CONTENTS SHALL BE FURNISHED OR DISCLOSED // TO OR COPIED OR USED BY PERSONS OUTSIDE RAYTHEON COMPANY WITHOUT THE EXPRESS WRITTEN APPROVAL OF // RAYTHEON COMPANY. // // UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY. // // DESTRUCTION NOTICE: FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN DOD 5220.22-M, // NATIONAL INDUSTRIAL SECURITY PROGRAM OPERATING MANUAL, FEBRUARY 2006, // INCORPORATING CHANGE 1, MARCH 28, 2013, CHAPTER 5, SECTION 7, OR DODM 5200.01-VOLUME 3, // DOD INFORMATION SECURITY PROGRAM: PROTECTION OF CLASSIFIED INFORMATION, ENCLOSURE 3, // SECTION 17. FOR CONTROLLED UNCLASSIFIED INFORMATION FOLLOW THE PROCEDURES IN DODM 5200.01-VOLUME 4, // INFORMATION SECURITY PROGRAM: CONTROLLED UNCLASSIFIED INFORMATION. // // CONTROLLED BY: MISSILE DEFENSE AGENCY // CONTROLLED BY: GROUND-BASED MIDCOURSE DEFENSE PROGRAM OFFICE // CUI CATEGORY: CTI // DISTRIBUTION/DISSEMINATION CONTROL: F // POC: Alex Kravchenko (1118268) // ********************************************************************************************************** using System; using System.Collections.Generic; using System.Diagnostics; using System.Text.RegularExpressions; using System.Threading; using System.Xml; using System.Xml.XPath; using NLog; namespace Raytheon.Common.Coe { public class MessageXmlDocument : XmlDocument { private readonly ILogger _logger; private readonly string _XmlFileName; private string BuiltXML = ""; private uint m_MaxMsgSize = 0; private readonly List m_IncludeList; public bool LogData { get; set; } private MessageXmlDocument() : base() { LogData = true; } public MessageXmlDocument(string Pathname, bool logData = true) : base() { LogData = logData; _logger = LogManager.GetCurrentClassLogger(); _XmlFileName = Pathname; m_IncludeList = new List(); RecurseProcessing(Pathname); BuiltXML = string.Concat(BuiltXML, ""); BytePackingXml addPacking = new BytePackingXml(BuiltXML); LoadXml(addPacking.OuterXml); } public Dictionary GetEnumerations(string Type) { Dictionary enumList = new Dictionary(); // Get XML nodes to parse the XML ICD document XPathNavigator Node = CreateNavigator(); XPathNodeIterator Nodeset = Node.Select("interface/enum/name"); while (Nodeset.MoveNext()) { // Find the enumeration with the name of the type if (Nodeset.Current.Value.Trim().Equals(Type.Trim())) { // Find all the enumeration items XPathNavigator enumNode = Nodeset.Current.Clone(); while (enumNode.MoveToNext()) { if (enumNode.Name.Trim().Equals("item") || enumNode.Name.Trim().Equals("enum_item")) { string name = null; string value = null; // Find all name nodes XPathNavigator childNode = enumNode.Clone(); childNode.MoveToFirstChild(); do { if (childNode.Name.Trim().Equals("name")) { name = childNode.Value.Trim(); } else if (childNode.Name.Trim().Equals("item_name")) { name = childNode.Value.Trim(); } if (childNode.Name.Trim().Equals("value")) { value = childNode.Value.Trim(); } // Once we find the name & value, add it to the list if ((name != null) && (value != null)) { enumList.Add(name, value); break; } } while (childNode.MoveToNext()); } } break; // We found the enumeration we wanted } } return enumList; } private void RecurseProcessing(string pathName) { string directory; string IncludePathname; XPathNodeIterator nodeset; // Only process each file once pathName = pathName.Replace('/', '\\'); if (m_IncludeList.Contains(pathName)) { return; // This file has already been processed } else { m_IncludeList.Add(pathName); } if (LogData) _logger.Info($"Loading File: {pathName}"); XPathDocument document = new XPathDocument(pathName); XPathNavigator navigator = document.CreateNavigator(); // Verify this is a COE XML ICD nodeset = navigator.Select("/interface"); if (nodeset.Count == 0) { // This is not an XML ICD throw new Exception($"Invalid COE XML Format. Unable to process {pathName}" + "\nEnsure this is a properly formatted ICD."); } nodeset = navigator.Select("/interface/include/file"); while (nodeset.MoveNext()) { try { directory = DirectoryOf(pathName); } catch { directory = ".\\"; } IncludePathname = nodeset.Current.Value.Trim(); if ((!IncludePathname.StartsWith("\\")) && (!IncludePathname.Contains(":"))) { while (IncludePathname.StartsWith(".")) { if ((IncludePathname.StartsWith("..\\")) || (IncludePathname.StartsWith("../"))) { directory = DirectoryOf(directory); IncludePathname = IncludePathname.Remove(0, 3); } else if ((IncludePathname.StartsWith(".\\")) || (IncludePathname.StartsWith("./"))) { IncludePathname = IncludePathname.Remove(0, 2); } } IncludePathname = string.Concat(directory, "\\", IncludePathname); } if (Regex.IsMatch(IncludePathname, @"\.xml", RegexOptions.IgnoreCase)) RecurseProcessing(IncludePathname); } nodeset = navigator.Select("/interface/packing|/interface/typedef|/interface/namespace/typedef|" + "/interface/constant|/interface/namespace/constant|interface/enum|interface/namespace/enum|" + "/interface/structure|/interface/namespace/structure|/interface/message|/interface/namespace/message"); while (nodeset.MoveNext()) { string item = nodeset.Current.OuterXml; int index; while ((index = item.IndexOf("")) != -1) { item = item.Remove(index, item.IndexOf("") + 14 - index); } while ((index = item.IndexOf("") + 3 - index); } while (item.IndexOf("> ") != -1) { item = item.Replace("> ", ">"); } while (item.IndexOf(" <") != -1) { item = item.Replace(" <", "<"); } //_logger.Log(LogLevel.Trace, $"Loading Node :\n{item}"); Thread.Sleep(1); BuiltXML = string.Concat(BuiltXML, item); } } private string DirectoryOf(string Pathname) { return Pathname.Remove(Pathname.LastIndexOf("\\")); } // // From the XML document, the definition of a single message can be identified // from the Message Name and returned as an XML string. // public string XmlFileName { get { return _XmlFileName; } } public string GetMessage(string messageName) { string message; messageName = messageName.Trim(); if (LogData) _logger.Info($"Searching for message : {messageName}"); try { message = SelectSingleNode($"/interface/message[name='{messageName}']").OuterXml; message = TranslateValue(message); string labelStr = Regex.Replace(message, @".+