Files
DDUtility/JWH/TIB/MessageParser.cs
T001084 68d51f64d0 Ver 2025.03.25.0
TibSimulator Patch:: AutoReply Enable의 경우, 텍스트박스에 출력하지 않고 메시지 즉시전송
2025-03-27 13:33:21 +09:00

454 lines
16 KiB
C#

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<MessageValue> MessageValues { get; set; } = new List<MessageValue>();
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 ] ----------------------------------------------
/// <summary>
/// 문자열로 XmlMessage를 생성한 후, 각 항목에 값을 설정한다
/// </summary>
/// <param name="xmlData"></param>
/// <returns></returns>
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;
}
}
/// <summary>
/// 응답메시지를 반환한다 (MessageName_*.xml)
/// </summary>
/// <param name="xmlRequest">Request Message</param>
/// <returns>Reply Message</returns>
public XmlMessage[] CreateSendReplyMessages(XmlMessage xmlRequest)
{
try
{
List<XmlMessage> lstReply = new List<XmlMessage>();
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 ] ------------------------------------------------
/// <summary>
/// CreateReply AreYouThereRequest
/// </summary>
/// <param name="xmlRequest"></param>
/// <returns></returns>
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;
}
/// <summary>
/// CreateReply Common
/// </summary>
/// <param name="xmlRequest"></param>
/// <returns></returns>
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 ] ====================================================
/// <summary>
/// 메시지의 각 항목에 값을 할당한다
/// <para>Step-1. Value of srcMessage</para>
/// <para>Step-2. Value of MessageValue</para>
/// </summary>
/// <param name="node"></param>
/// <param name="srcMessage">RequestMessage</param>
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);
}
}
/// <summary>
/// Call Function
/// </summary>
/// <param name="node"></param>
/// <param name="srcValue"></param>
/// <param name="srcMessage"></param>
/// <returns></returns>
private object CallFunction(XmlNode node, MessageValue srcValue, XmlMessage srcMessage = null)
{
try
{
string source = srcValue.Value;
string name = string.Empty;
string parameters = string.Empty;
List<object> lstParameter = new List<object>();
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;
}
}
/// <summary>
/// Call Macro
/// </summary>
/// <param name="node"></param>
/// <param name="srcValue"></param>
/// <param name="srcMessage"></param>
/// <returns></returns>
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<object> lstParameter = new List<object>();
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<XmlNode> lstPanel = new List<XmlNode>();
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<XmlNode> lstChilid = new List<XmlNode>();
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
}
}