/*********************************************************************
*	 All Rights reserved,Copyright (c) K-Opticom 
**********************************************************************
*＜プログラム内容＞
*   システム名      ：eo顧客基幹システム
*   モジュール名    ：JKKBatKKCashPostBase
*   ソースファイル名：JKKBatKKCashPostBase.java
*   作成者          ：富士通
*   日付            ：2019年10月11日
*＜機能概要＞
*   主処理(共通)<BR>
*   CASHPOST送金対象連携API処理部品（基底）です。
*＜修正履歴＞
*   バージョン  修正日      修正者      修正内容
*   v1.00       2019/10/11  富士通      新規作成
*
**********************************************************************/

package eo.business.common;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URL;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import javax.xml.ws.http.HTTPException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import eo.common.constant.JPCBatchMessageConstant;
import eo.framework.item.JBSbatCommonItem;
import eo.framework.log.JBSbatLogPrintControl;

/**
 * <p>
 * CASHPOST送金対象連携API独自処理部品（基底）クラスです。
 * </p>
 * @author 富士通
 */
public abstract class JKKBatKKCashPostBase
{
	/** 部品ID*/
	private static final String PGID = "JKKBatKKCashPostBase";

	/** パラメータセパレート文字:=*/
	protected static final String S_SEP_EQ = JKKBatConst.S_SEP_EQ;

	/** パラメータセパレート文字:&*/
	protected static final String S_SEP_AN = JKKBatConst.S_SEP_AN;

	/** 通信方式パラメータ*/
	protected static final String S_SSL = JKKBatConst.S_SSL;

	/** リクエスト種別パラメータ*/
	protected static final String S_POST = JKKBatConst.S_POST;

	/** 文字コード*/
//	protected static final String S_CHR_CODE = "Shift_JIS";
	protected static final String S_CHR_CODE = "MS932";

	/** APIシステムエラー*/
	protected static final String S_AUTH_SYSERR = JKKBatConst.S_AUTH_SYSERR;

	/** レスポンス区切り文字*/
	protected static final String S_DELIM_TAB = JKKBatConst.S_DELIM_TAB;

	/** 通信方式SSL*/
	protected static final String S_HTTPS = "https";

	/** ログ用インスタンス */
	protected JBSbatLogPrintControl log = null;

	/**
	 * レコード ※現状、SOAP通信で設定されている
	 */
	public static final String RECORD = "record";

	/**
	 * サービスIF ※現状、SOAP通信で設定されている
	 */
	public static final String SERVICEIF = "service_if";

	/**
	 * タグ属性(=TYPE)
	 */
	private static final String[] typeValues = { "service_if", "service_if_list" };

	/**
	 * タグ名
	 * SOAP通信:"Envelope","Body","Header","initResponse"
	 * CASHPOST:"result"
	 */
	private static final String[] tagNames = { "Envelope", "Body", "Header", "initResponse", "result" };

	/**
	 * SOAPFAULT[SOAP通信用]（処理例外）
	 */
	private static final String SOAP_FAULT = "fault";

	/**
	 * SOAPFAULT[SOAP通信用]（エラーコード）
	 */
	private static final String SOAP_FAULT_CODE = "reason";

	/**
	 * SOAPFAULT[SOAP通信用]（エラー詳細）
	 */
	private static final String SOAP_FAULT_STRING = "detail";

	/** CASHPOST実行結果 レスポンスコード（パラメータ不正時は、S_AUTH_SYSERR） */
	public static final String EXE_STATUS = "status";

	/**
	 * コマンド実行結果 0:正常、1：パラメータエラー、2：エラー、9：その他（SOAP通信エラー）
	 */
	public static final String CMD_RESULT_CD = "CMD_RESULT_CD";
	/** コマンド実行結果 0:正常 */
	public static final String CMD_RESULT_CD_NORMAL = "0";
	/** コマンド実行結果 2：パラメータエラー */
	public static final String CMD_RESULT_CD_ERR_PARAM = "1";
	/** コマンド実行結果 9：エラー */
	public static final String CMD_RESULT_CD_ERR = "2";
	/** コマンド実行結果 1：SOAP通信エラー（現状、判定不要） */
	public static final String CMD_RESULT_CD_ERR_SOAP = "9";

	/**
	 * コマンド実行結果（エラー）
	 */
	public static final String CMD_ERROR_MESSAGE = "CMD_ERROR_MESSAGE";

	/**
	 * ロガー設定
	 * 
	 * @param commonItem
	 */
	protected void setlogger(JBSbatCommonItem commonItem)
	{
		log = commonItem.getLogPrint();
	}

	/**
	 * HTTPSリクエスト独自処理部品です。
	 * @param inMap メッセージ
	 * @throws Exception エラー全般
	 */
	@SuppressWarnings("unchecked")
	protected void execute(HashMap inMap) throws Exception
	{
		printInfoLog(PGID + "#execute start");
		// 情報ログを出力する
		log.printBusinessErrorLog(JPCBatchMessageConstant.EKKB1140AI, new String[] {});

		HttpURLConnection conn = null;
		BufferedReader reader = null;
		URL url = null;
		String strUrl = null;
		int timeout = 0;
		int retryCount = 0;
		int retryInterval = 0;
		inMap.put(CMD_RESULT_CD, CMD_RESULT_CD_ERR);
		/*-----------------------------
		 * パラメータ設定
		 *----------------------------*/
		try
		{
			//system.properties設定値取得
			strUrl = JCCBatCommon.getApplicationConst("KK_CASHPOST_URL");

			timeout = Integer.parseInt(JCCBatCommon.getApplicationConst("KK_CASHPOST_TIMEOUT"));
			retryCount = Integer.parseInt(JCCBatCommon.getApplicationConst("KK_CASHPOST_RETRYCOUNT"));
			retryInterval = Integer.parseInt(JCCBatCommon.getApplicationConst("KK_CASHPOST_RETRYINTERVAL"));

			// アプリケーションプロパティ設定チェック
			if (isNullBlunk(strUrl))
			{
				inMap.put(EXE_STATUS, S_AUTH_SYSERR);
				inMap.put(CMD_RESULT_CD, CMD_RESULT_CD_ERR_PARAM);
				printInfoLog(PGID + "#Properties Error");
				return;
			}
		}
		catch (NumberFormatException ne)
		{
			inMap.put(EXE_STATUS, S_AUTH_SYSERR);
			inMap.put(CMD_RESULT_CD, CMD_RESULT_CD_ERR_PARAM);
			printInfoLog(PGID + "#NumberFormatException");
			return;
		}

		/*-----------------------------
		 * ＳＳＬ通信設定
		 *----------------------------*/
		// 通信方式判定
		boolean bSslFlg = false;
		if (strUrl.startsWith(S_HTTPS))
		{
			bSslFlg = true;
		}

		// SSL通信の場合、キーマネージャを生成
		if (bSslFlg)
		{
			KeyManager[] km = null;
			TrustManager[] tm = { new X509TrustManager()
			{

				/**
				 * X509Certificateスタブメソッド
				 * @return null
				 */
				public java.security.cert.X509Certificate[] getAcceptedIssuers()
				{
					return null;
				}

				/**
				 * checkClientTrustedスタブメソッド
				 * @param arg0
				 * @param arg1
				 * @throws CertificateException
				 */
				public void checkClientTrusted(java.security.cert.X509Certificate[] arg0, String arg1) throws CertificateException
				{
					// 自動生成されたメソッドスタブ
				}

				/**
				 * checkServerTrustedスタブメソッド
				 * @param arg0
				 * @param arg1
				 * @throws CertificateException
				 */
				public void checkServerTrusted(java.security.cert.X509Certificate[] arg0, String arg1) throws CertificateException
				{
					// 自動生成されたメソッドスタブ
				}
			} };
			SSLContext sslcontext = SSLContext.getInstance(S_SSL);
			sslcontext.init(km, tm, new SecureRandom());
			HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier()
			{

				/**
				 * verifyスタブメソッド
				 * @param aHostname
				 * @param aSession
				 * @return CASHPOSTAPIへのリクエストパラメータ
				 */
				public boolean verify(String aHostname, SSLSession aSession)
				{
					return true;
				}
			});
			HttpsURLConnection.setDefaultSSLSocketFactory(sslcontext.getSocketFactory());
		}

		/*-----------------------------
		 * CASHPOST呼び出し
		 *----------------------------*/
		// URL生成
		url = new URL(strUrl);
		printInfoLog(PGID + "#送信URLパラメータ" + url);
		// リクエスト結果読込用ストリーム
		InputStream inputStream = null;
		InputStreamReader isReader = null;
		String reqStr = "";

		for (int i = 0; i < retryCount; i++)
		{
			try
			{
				reqStr = "";
				// アプリケーションプロパティよりProxy設定値を取得
				String strPrxyHost = JCCBatCommon.getApplicationConst("KK_CASHPOST_HTTPS_PROXY_HOST");
				String strPrxyPort = JCCBatCommon.getApplicationConst("KK_CASHPOST_HTTPS_PROXY_PORT");

				int intProxyPort = 0;
				if (strPrxyHost != null && !"".equals(strPrxyHost))
				{
					intProxyPort = Integer.parseInt(strPrxyPort);
				}

				// SSLの場合、HttpsURLConnectionへキャスト
				if (bSslFlg)
				{
					// Proxy設定値がある場合はProxyをセットしてコネクションをオープン
					if (strPrxyHost != null && !"".equals(strPrxyHost) && strPrxyPort != null && !"".equals(strPrxyPort))
					{
						Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(strPrxyHost, intProxyPort));
						conn = (HttpsURLConnection)url.openConnection(proxy);
					}
					else
					{
						conn = (HttpsURLConnection)url.openConnection();
					}
					log.printDebugLog(PGID + "#HttpsURLConnection openConnection");
				}
				else
				{
					conn = (HttpURLConnection)url.openConnection();
					log.printDebugLog(PGID + "#HttpURLConnection openConnection");
				}

				// リクエスト設定
				conn.setRequestMethod(S_POST);
				conn.setDoOutput(true);
				conn.setInstanceFollowRedirects(true);
				conn.setRequestProperty("Accept-Language", "jp");
				// 未設定の場合は「Content-Type:application/x-www-form-urlencoded」となる
				conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=" + S_CHR_CODE);

				//タイムアウト設定
				conn.setReadTimeout(timeout);

				//POSTパラメータストリームの生成
				OutputStream os = conn.getOutputStream();
//				PrintStream ps = new PrintStream(os, true, S_CHR_CODE);
				PrintStream ps = new PrintStream(os);

				/*
				 * 送信パラメータ作成
				 */
				reqStr = requestParamMake(inMap);
				printInfoLog(PGID + "#reqParam=" + reqStr);
				ps.print(reqStr);
				ps.close();

				// 接続開始ログ
				printInfoLog(PGID + "#connect start");
				// 情報ログを出力する
				log.printBusinessErrorLog(JPCBatchMessageConstant.EKKB1150AI, new String[] { String.valueOf(i + 1) });

				//********************//
				// 接続実行
				//********************//
				conn.connect();

				// 接続終了ログ
				printInfoLog(PGID + "#connect end");
				// 情報ログを出力する
				log.printBusinessErrorLog(JPCBatchMessageConstant.EKKB1160AI, new String[] {});

				int responseCode = 500;
				responseCode = conn.getResponseCode();

				// HttpsURLConnection.HTTP_OK: // HTTP OK
				Hashtable<String, Object> ret = new Hashtable<String, Object>();
				Transformer transformer = null;
				Document responseXml = null;
				StringWriter sw = null;

				TransformerFactory transformerFactory = TransformerFactory.newInstance();
				transformer = transformerFactory.newTransformer();

				//XML形式
				transformer.setOutputProperty(OutputKeys.METHOD, "xml");
				printInfoLog(PGID + "#レスポンス受信 START");

				//	inputStream = conn.getInputStream();
				//	DOMResult dr = new DOMResult();
				//	transformer.transform(new StreamSource(inputStream), dr);
				//	responseXml = (Document)dr.getNode();

				log.printDebugLog(PGID + "#ContentEncoding=[" + conn.getContentEncoding() + "]");
				//  String responseContentType = conn.getHeaderField("Content-Type");
				String encoding = S_CHR_CODE;
				isReader = new InputStreamReader(conn.getInputStream(), encoding);
				DOMResult dr = new DOMResult();
				transformer.transform(new StreamSource(isReader), dr);

				responseXml = (Document)dr.getNode();

				printInfoLog(PGID + "#レスポンス受信 END");

				/**
				 * 下り電文のログ出力
				 */
				sw = new StringWriter();
				transformer.transform(new DOMSource(responseXml), new StreamResult(sw));

				/**
				 * レスポンス読込処理
				 */
				printInfoLog(PGID + "#レスポンス読込処理 START");
				ret = read(responseXml);
				printInfoLog(PGID + "#retParam=" + ret);
				printInfoLog(PGID + "#レスポンス読込処理 END");

				StringBuffer sb = new StringBuffer();
				sb.append("CASHPOST連携結果 responseCode=[");
				sb.append(responseCode + "]   ");
				sb.append(makeLogStr(ret));
				printInfoLog(PGID + "#" + sb.toString());
				//********************//
				// 処理結果返却
				//********************//
				resultPut(inMap, ret);

				// 情報ログを出力する『reader close』
				log.printBusinessErrorLog(JPCBatchMessageConstant.EKKB1180AI, new String[] {});

				/*
				 * HTTP 応答メッセージから状態コードを取得し設定する。 
				 * HTTP/1.0 200 OK
				 * HTTP/1.0 401 Unauthorized
				 */
				inMap.put(EXE_STATUS, Integer.toString(responseCode));
			}

			catch (HTTPException he)
			{
				if (i < retryCount - 1)
				{
					printInfoLog(PGID + "#(HTTPException)" + he.getMessage());
					logputputResponse(conn, reqStr);
					// スリープした後、再度CASHPOST呼び出し
					log.printDebugLog(PGID + "#(HTTPException)sleep start");
					Thread.sleep(retryInterval);
					log.printDebugLog(PGID + "#(HTTPException)sleep end");
					log.printDebugLog(PGID + "#(HTTPException)retryCount=" + i);
					continue;
				}
				else
				{
					printInfoLog(PGID + "#(HTTPException)" + he.getMessage());
					logputputResponse(conn, reqStr);
				}
			}
			catch (TransformerException trnEx)
			{
				// タグが不正（文字化けなどでも発生）
				if (i < retryCount - 1)
				{
					printInfoLog(PGID + "#(TransformerException)" + trnEx.getMessage());
					logputputResponse(conn, reqStr);
					// スリープした後、再度API呼び出し
					log.printDebugLog(PGID + "#(TransformerException)sleep start");
					Thread.sleep(retryInterval);
					log.printDebugLog(PGID + "#(TransformerException)sleep end");
					log.printDebugLog(PGID + "#(TransformerException)retryCount=" + i);
					continue;
				}
				else
				{
					printInfoLog(PGID + "#(TransformerException)" + trnEx.getMessage());
					logputputResponse(conn, reqStr);
				}
			}
			catch (IOException ie)
			{
				if (i < retryCount - 1)
				{
					printInfoLog(PGID + "#(IOException)" + ie.getMessage());
					logputputResponse(conn, reqStr);
					// スリープした後、再度API呼び出し
					log.printDebugLog(PGID + "#(IOException)sleep start");
					Thread.sleep(retryInterval);
					log.printDebugLog(PGID + "#(IOException)sleep end");
					log.printDebugLog(PGID + "#(IOException)retryCount=" + i);
					continue;
				}
				else
				{
					printInfoLog(PGID + "#(IOException)" + ie.getMessage());
					logputputResponse(conn, reqStr);
				}
			}
			finally
			{
				if (reader != null)
				{
					reader.close();
				}
				if (conn != null)
				{
					conn.disconnect();
					conn = null;
				}
				if (inputStream != null)
				{
					inputStream.close();
				}
				if (isReader != null)
				{
					isReader.close();
				}
				printInfoLog(PGID + "#execute end");
			}
			// 情報ログを出力する
			log.printBusinessErrorLog(JPCBatchMessageConstant.EKKB1190AI, new String[] {});
			break;
		}
	}

	/**
	 * APIに対して送信するリクエストパラメータを作成する。
	 * @param inMap メッセージキャリア
	 * @return CASHPOSTAPIへのリクエストパラメータ
	 * @throws UnsupportedEncodingException
	 */
	@SuppressWarnings("unchecked")
	protected abstract String requestParamMake(HashMap inMap) throws UnsupportedEncodingException;

	/**
	 * API処理結果を格納する。
	 * @param inMap メッセージキャリア
	 * @param key レスポンスキー
	 * @param value レスポンスバリュー
	 */
	protected abstract void resultPut(HashMap<String, Object> inMap, Hashtable<String, Object> resultMap);

	/**
	 * ＮＵＬＬ、空文字の場合はtrueを返却します。
	 * 
	 * @param str
	 * @return boolean
	 */
	protected boolean isNullBlunk(String str)
	{
		if (str == null || "".equals(str))
		{
			return true;
		}
		return false;
	}

	/**
	 * 電文読み込み処理
	 * @param soapResponse
	 * @return XML電文解析結果
	 * @throws IOException
	 * @throws ParserConfigurationException
	 * @throws SAXException
	 */
	private Hashtable<String, Object> read(Document soapResponse) throws IOException, ParserConfigurationException, SAXException
	{
		if (soapResponse == null)
		{
			return null;
		}
		// レスポンス解析
		Element root = soapResponse.getDocumentElement();//ルート要素(SOAP通信の例：<SOAP-ENV:Envelope>)	
		Hashtable<String, Object> result = analyzeXml(root, true);

		return result;
	}

	/**
	 * XMLFAULT電文解析処理
	 * 
	 * @param elem XMLFAULT電文
	 * @return ArrayListエラー情報
	 */
	private String analyzeFaultXml(Node elem)
	{
		Node node = elem.getFirstChild();
		String errmsg = "";

		while (node != null)
		{
			if (node.getNodeType() == Node.ELEMENT_NODE)
			{
				String nodename = node.getLocalName();

				if (SOAP_FAULT_CODE.equals(nodename.toLowerCase()))
				{
					Node child = node.getFirstChild();
					if (child != null)
					{
						errmsg = errmsg + "エラーコード：" + child.getTextContent();
					}
				}
				if (SOAP_FAULT_STRING.equals(nodename.toLowerCase()))
				{
					errmsg = errmsg + "エラー詳細：" + node.getTextContent();
				}
			}

			node = node.getNextSibling();
		}

		return errmsg;
	}

	/**
	 * コマンド送信戻り電文解析処理
	 * @param elem コマンド解析電文rootXML要素
	 * @param rootflag ルートフラグ
	 * @return XML解析結果
	 */
	public Hashtable<String, Object> analyzeXml(Node elem, boolean rootflag)
	{
		Node node = elem.getFirstChild();
		Hashtable<String, Object> resultMap = null;
		List<Map<String, Object>> Bodynodelist = new ArrayList<Map<String, Object>>();

		//電文の要素をすべて解析する。
		while (node != null)
		{
			log.printDebugLog(PGID + "#" + node.getLocalName() + "：" + node.getTextContent());

			if (node.getNodeType() == Node.ELEMENT_NODE)
			{

				String nodename = node.getLocalName();
				String typeValue = null;
				if (node.getAttributes().getNamedItem("type") != null)
				{
					typeValue = node.getAttributes().getNamedItem("type").getNodeValue();
				}

				String childname = "";

				NodeList nodelist = node.getChildNodes();
				if (nodelist != null)
				{
					for (int i = 0; i < nodelist.getLength(); i++)
					{
						Node child = nodelist.item(i);

						if (child.getNodeType() == Node.ELEMENT_NODE)
						{
							childname = child.getLocalName();
							break;
						}
					}
				}

				// SOAP例外の場合
				if (SOAP_FAULT.equals(nodename.toLowerCase()) || SOAP_FAULT.equals(childname.toLowerCase()))
				{
					resultMap = new Hashtable<String, Object>();
					String faultinfo = analyzeFaultXml(node);
					resultMap.put(CMD_RESULT_CD, CMD_RESULT_CD_ERR_SOAP);
					resultMap.put(CMD_ERROR_MESSAGE, faultinfo);
					return resultMap;
				}
				else
				{
					if (resultMap == null)
					{
						resultMap = new Hashtable<String, Object>();
					}
					Hashtable<String, Object> resultinfo = analyzeXml(node, false);
					if (RECORD.equals(nodename) || SERVICEIF.equals(nodename) || Arrays.asList(typeValues).contains(typeValue))
					{
						if (resultinfo != null && !resultinfo.isEmpty())
						{
							Bodynodelist.add(resultinfo);
						}

						resultMap.put(nodename, Bodynodelist);

					}

					else if (Arrays.asList(tagNames).contains(nodename))
					{
						resultMap.putAll(analyzeXml(node, false));
					}
					else
					{
						resultMap.put(nodename, node.getTextContent());
						if (node.getAttributes().getNamedItem("err") != null)
						{
							String StrErr = node.getAttributes().getNamedItem("err").getTextContent();
							resultMap.put(nodename + "_ERR", StrErr);
						}
					}

				}
			}

			node = node.getNextSibling();
		}

		if (rootflag)
		{
			if (resultMap == null)
			{
				resultMap = new Hashtable<String, Object>();
			}

			// OK
			log.printDebugLog(PGID + "#analyzeXml root read");
			return resultMap;
		}

		return resultMap;
	}

	/**
	 * APIの返却結果をログに出力するため編集を行う
	 * @param ret CASHPOSTからの返却結果
	 * @return ログ出力用文字列
	 */
	@SuppressWarnings("unchecked")
	private String makeLogStr(Hashtable<String, Object> ret)
	{

		if (ret == null)
		{
			return "";
		}
		//ログ用文字列組み立て用の変数を宣言する
		StringBuilder sb = new StringBuilder();

		//返却結果よりkeyリストを取得する
		Enumeration keys = ret.keys();

		//取得したkeyの件数分ループを行う
		while (keys.hasMoreElements())
		{

			//valueを取得するためkeyを取得する
			String key = (String)keys.nextElement();
			//keyを元にvalueを取得する
			String value = (String)ret.get(key);

			//返却結果のそのまま出力する
			sb.append(key + "=" + value + ",");

		}

		return sb.toString();
	}

	/**
	 * 応答電文（エラー発生時）
	 * 
	 * <br>
	 * @param conn HttpURLConnection
	 * @param reqStr リクエストパラメータ
	 * @throws Exception
	 */
	protected void logputputResponse(HttpURLConnection conn, String reqStr) throws Exception
	{
		//String encoding = conn.getContentEncoding();
		StringBuffer result = new StringBuffer();
		if (conn == null)
		{
			printInfoLog(PGID + "#conn=null" + "] URL Param=[" + reqStr + "]");
			return;
		}
		int responseCode = conn.getResponseCode();

		result.append(PGID + "#ResponseCode=[" + responseCode + "] URL Param=[" + reqStr + "]");

		printInfoLog(result.toString());

	}

	/**
	 * 情報メッセージ出力
	 * 
	 * <br>
	 * @param msg メッセージ
	 */
	private void printInfoLog(String msg)
	{
		log.printBusinessErrorLog(JPCBatchMessageConstant.EKKB1200AI, new String[] { msg });
	}

}
