using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.Text; using System.Xml; using JWH; namespace JWH.TIB { public class MessageParser { public string Subject { get; set; } = string.Empty; public string SendSubject { get; set; } = string.Empty; public string XmlData { get; set; } = string.Empty; public bool SendRequest { get; set; } = false; public string PathMessageReply { get; set; } = string.Empty; public List MessageValues { get; set; } = new List(); public MessageParser() { } public MessageParser(string xmlData, bool sendRequest = false) { this.XmlData = xmlData; this.SendRequest = sendRequest; } public MessageParser(string subject, string xmlData, bool sendRequest = false) { this.Subject = subject; this.XmlData = xmlData; this.SendRequest = sendRequest; } #region [ CreateMessage ] ---------------------------------------------- /// /// 문자열로 XmlMessage를 생성한 후, 각 항목에 값을 설정한다 /// /// /// public XmlMessage CreateSendMessage(string xmlData, bool isValueSetting = true) { try { if (string.IsNullOrEmpty(xmlData)) return null; XmlMessage xmlMessage = new XmlMessage(xmlData); if (isValueSetting) { this.SetMessageBodyValue(xmlMessage.XmlData.Header); this.SetMessageBodyValue(xmlMessage.XmlData.Body); } return xmlMessage; } catch (Exception ex) { XLogger.Instance.Fatal(ex); return null; } } /// /// 응답메시지를 반환한다 (MessageName_*.xml) /// /// Request Message /// Reply Message public XmlMessage[] CreateSendReplyMessages(XmlMessage xmlRequest) { try { List lstReply = new List(); XmlMessage xmlReply = null; string strReply = string.Empty; // ReplyFile Processing... DirectoryInfo directoryInfo = new DirectoryInfo(this.PathMessageReply); foreach (FileInfo fileInfo in directoryInfo.GetFiles($"{xmlRequest.XmlData.MessageName}_*.xml")) { StreamReader reader = new StreamReader(fileInfo.FullName, Encoding.Default, true); strReply = reader.ReadToEnd(); xmlReply = new XmlMessage(strReply); xmlReply.SetSubjectName(xmlRequest); this.SetMessageBodyValue(xmlReply.XmlData.Body, xmlRequest); lstReply.Add(xmlReply); } if (lstReply.Count > 0) return lstReply.ToArray(); // Dynamic Processing if (string.Compare(xmlRequest.XmlData.MessageName, "AreYouThereRequest", true) == 0) xmlReply = this.CreateReply_AreYouThereRequest(xmlRequest); else xmlReply = this.CreateReply_Common(xmlRequest); lstReply.Add(xmlReply); return lstReply.ToArray(); } catch (Exception ex) { XLogger.Instance.Fatal(ex); return null; } } #endregion #region [ CreateReply ] ------------------------------------------------ /// /// CreateReply AreYouThereRequest /// /// /// private XmlMessage CreateReply_AreYouThereRequest(XmlMessage xmlRequest) { if (xmlRequest == null) return null; XmlMessage xmlReply = new XmlMessage(xmlRequest.XmlData.GetText()); xmlReply.XmlData.MessageName += "Reply"; xmlReply.XmlData.SendRequestFlag = false; xmlReply.XmlData.ReplySubjectName = xmlRequest.XmlData.SendSubjectName; xmlReply.XmlData.SendSubjectName = xmlRequest.XmlData.ReplySubjectName; xmlReply.SendSubject = xmlReply.XmlData.SendSubjectName; xmlReply.SendRequestFlag = xmlReply.XmlData.SendRequestFlag; xmlReply.RequestMessage = xmlRequest; if (xmlRequest.SendRequestFlag) xmlReply.IsReply = true; return xmlReply; } /// /// CreateReply Common /// /// /// private XmlMessage CreateReply_Common(XmlMessage xmlRequest) { if (xmlRequest == null) return null; XmlMessage xmlReply = new XmlMessage(xmlRequest.XmlData.GetText()); xmlReply.XmlData.MessageName += "Reply"; xmlReply.XmlData.SendRequestFlag = false; xmlReply.XmlData.ReplySubjectName = xmlRequest.XmlData.SendSubjectName; xmlReply.XmlData.SendSubjectName = xmlRequest.XmlData.ReplySubjectName; xmlReply.SendSubject = xmlReply.XmlData.SendSubjectName; xmlReply.SendRequestFlag = xmlReply.XmlData.SendRequestFlag; XmlNode nodeReturn = xmlReply.XmlData.Message.CreateChildNode("return"); nodeReturn.CreateChildNode("returncode", "0"); nodeReturn.CreateChildNode("returnmessage", "TibSimulator"); xmlReply.RequestMessage = xmlRequest; if (xmlRequest.SendRequestFlag) xmlReply.IsReply = true; return xmlReply; } #endregion #region [ Method ] ==================================================== /// /// 메시지의 각 항목에 값을 할당한다 /// Step-1. Value of srcMessage /// Step-2. Value of MessageValue /// /// /// RequestMessage private void SetMessageBodyValue(XmlNode node, XmlMessage srcMessage = null) { // MessageValue(UI) if (node.GetText() == string.Empty) { string name = node.Name; XmlAttribute attribute = node.GetAttribute("Name"); if (attribute != null) { name = attribute.Value; node.Attributes.Remove(attribute); } string srcValue = srcMessage?.XmlData.GetValue(name); MessageValue msgValue = this.GetMessageValue(name); if (string.IsNullOrEmpty(srcValue)) { if (msgValue != null) { object value = string.Empty; if (msgValue.Format.ToUpper() == "FUNCTION") value = this.CallFunction(node, msgValue, srcMessage); else if (msgValue.Format.ToUpper() == "MACRO") value = this.CallMacro(node, msgValue, srcMessage); else value = msgValue.Value; if (value != null) { if (value.GetType() == typeof(string)) node.SetText((string)value); else if (value.GetType() == typeof(XmlNode[])) { foreach (XmlNode child in value as XmlNode[]) node.AppendChild(child); } } } } else { node.SetText(srcValue); } } foreach (XmlNode child in node.ChildNodes) { if (child.GetType() == typeof(XmlText)) continue; this.SetMessageBodyValue(child, srcMessage); } } /// /// Call Function /// /// /// /// /// private object CallFunction(XmlNode node, MessageValue srcValue, XmlMessage srcMessage = null) { try { string source = srcValue.Value; string name = string.Empty; string parameters = string.Empty; List lstParameter = new List(); int length = source.Length - 1; int indexStart = source.IndexOf('('); int indexEnd = source.IndexOf(')'); if (indexStart >= 0) length = indexStart; name = source.Substring(0, length); parameters = source.Substring(indexStart + 1, indexEnd - indexStart - 1); MethodInfo methodInfo = this.GetType().GetMethod(name); if (methodInfo == null) return string.Empty; lstParameter.AddRange(this.GetMethodParameters(methodInfo, node, parameters, srcMessage)); object result = methodInfo.Invoke(this, lstParameter.ToArray()); if (methodInfo.Name == "GetIncrement" && srcValue != null) srcValue.Value = $"{name}({(int)result + 1})"; return result; } catch (Exception ex) { XLogger.Instance.Fatal(ex); return string.Empty; } } /// /// Call Macro /// /// /// /// /// private object CallMacro(XmlNode node, MessageValue srcValue, XmlMessage srcMessage = null) { string source = srcValue.Value; try { string macro = source; string name = string.Empty; string value = string.Empty; int indexStart = -1; int indexEnd = -1; indexStart = macro.IndexOf('%', 0); while (indexStart >= 0) { indexStart = macro.IndexOf('%', indexStart); indexEnd = macro.IndexOf('%', indexStart + 1); if (indexStart < 0) break; name = macro.Substring(indexStart + 1, indexEnd - indexStart - 1); value = string.Empty; if (srcMessage != null) value = srcMessage.XmlData.GetValue(name); if (string.IsNullOrEmpty(value)) { MessageValue msgValue = this.GetMessageValue(name); if (msgValue != null) value = msgValue.Value; } macro = $"{macro.Substring(0, indexStart)}{value}{macro.Substring(indexEnd + 1)}"; indexStart = 0; } return macro; } catch (Exception ex) { XLogger.Instance.Fatal(ex); return source; } } private object[] GetMethodParameters(MethodInfo method, XmlNode node, string arguments, XmlMessage srcMessage = null) { string[] parameters = arguments.Split(','); List lstParameter = new List(); string name = string.Empty; object value = string.Empty; for (int i = 0; i < method.GetParameters().Length; i++) { if (parameters[i].StartsWith("%") && parameters[i].EndsWith("%")) name = parameters[i].Replace("%", ""); if (name.ToUpper() == "XMLNODE") { lstParameter.Add(node); continue; } if (name.ToUpper() == "XMLMESSAGE") { lstParameter.Add(srcMessage); continue; } if (srcMessage != null) value = srcMessage.XmlData.GetValue(name); if (value == null || value.GetType() == typeof(string) ? string.IsNullOrEmpty((string)value) : false) { MessageValue msgValue = this.GetMessageValue(name); if (msgValue != null) { if (msgValue.Format.ToUpper() == "FUNCTION") value = this.CallFunction(node, msgValue, srcMessage); else if (msgValue.Format.ToUpper() == "MACRO") value = this.CallMacro(node, msgValue, srcMessage); else value = msgValue.Value; } } if (value == null) value = parameters[i]; var obj = Convert.ChangeType(value, method.GetParameters()[i].ParameterType); lstParameter.Add(obj); } return lstParameter.ToArray(); } private MessageValue GetMessageValue(string name) { return this.MessageValues.Where(item => item.Name.ToUpper() == name.ToUpper()).FirstOrDefault(); } #endregion #region [ Function Method ] ============================================ public string GetDateTime() { return DateTime.Now.ToString("yyyyMMddHHmmss"); } public string GetTransactionID() { return Guid.NewGuid().ToString(); } public string GetIPAddress() { return "127.0.0.1"; } public object[] GetPanelList(XmlNode node, string lotID, int qty) { List lstPanel = new List(); for (int i = qty; i > 0; i--) { XmlNode panelInfo = node.OwnerDocument.CreateNode("element", "PANELINFO", ""); XmlNode panelID = node.OwnerDocument.CreateNode("element", "PANELID", ""); panelID.SetText($"{lotID}_{i.ToString("00")}"); XmlNode panelSeq = node.OwnerDocument.CreateNode("element", "PANELSEQ", ""); panelSeq.SetText($"{i}"); panelInfo.AppendChild(panelID); panelInfo.AppendChild(panelSeq); lstPanel.Add(panelInfo); } return lstPanel.ToArray(); } public object[] GetChilds(XmlNode node, XmlMessage srcMessage) { if (srcMessage == null) return null; List lstChilid = new List(); XmlNode xmlNode = srcMessage.XmlData.GetNode(node.Name); foreach (XmlNode child in xmlNode.ChildNodes) { XmlNode importNode = node.OwnerDocument.ImportNode(child, true); node.AppendChild(importNode); } return null; } public int GetIncrement(Int32 value) { return value; } public string ChangeLotID() { MessageValue msgValueText = this.GetMessageValue("LotText"); MessageValue msgValueSeq = this.GetMessageValue("LotSeq"); MessageValue msgValueID = this.GetMessageValue("LotID"); if (msgValueText == null || msgValueSeq == null || msgValueID == null) return String.Empty; int seq = 0; int.TryParse(msgValueSeq.Value, out seq); string value = $"{msgValueText.Value}{seq.ToString("00")}"; msgValueID.Value = value; msgValueSeq.Value = (seq + 1).ToString(); return value; } public string ChangeCarrierID() { MessageValue msgValueText = this.GetMessageValue("CarrierText"); MessageValue msgValueSeq = this.GetMessageValue("CarrierSeq"); MessageValue msgValueID = this.GetMessageValue("CarrierID"); if (msgValueText == null || msgValueSeq == null || msgValueID == null) return String.Empty; int seq = 0; int.TryParse(msgValueSeq.Value, out seq); string value = $"{msgValueText.Value}{seq.ToString("00")}"; msgValueID.Value = value; msgValueSeq.Value = (seq + 1).ToString(); return value; } #endregion } }