/*********************************************************************
*	All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*	システム名		：eo顧客基幹システム
*	モジュール名	：JKKejbKKA0110001SecProc
*	ソースファイル名：JKKejbKKA0110001SecProc.java
*	作成者			：富士通
*	日付			：2022年2月21日
*＜機能概要＞
*	CASHPOST送信ステータス取得部品に対する副次処理を行う部品です。
*＜修正履歴＞
*	バージョン	修正日		修正者		修正内容
*   v57.00.00   2022/02/21  FJ）平野    【ANK4193-00-00】CASHPOSTお客さま受取結果反映 新規作成
*
**********************************************************************/

package eo.ejb.common.db;

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.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 com.fujitsu.futurity.model.base.CAANMsg;
import com.fujitsu.futurity.model.common.JCMAPLConstMgr;
import com.fujitsu.futurity.model.ejb.common.JSYejbLog;
import com.fujitsu.futurity.model.ejb.common.fw.AgentDispatchContext;


import eo.ejb.cbs.cbsmsg.EKKA0110001CBSMsg;
import eo.ejb.cbs.cbsmsg.EKKA0110001CBSMsg1List;


/**
 * <p>
 * 初回オーソリに対する副次処理を行う部品です。
 * </p>
 * @author 富士通
 */
public class JKKejbKKA0110001SecProc
{
	/** 部品ID*/
	private static final String PGID = "JKKejbKKA0110001SecProc";
	
	/** HTTP リターンコード */
	private static final String HTTP_OK = "200";

	/** パラメータセパレート文字:=*/
	protected static final String S_SEP_EQ = "=";

	/** パラメータセパレート文字:& */
	private static final String S_SEP_AN = "&";
	
	/** 通信方式パラメータ */
	private static final String S_SSL = "SSL";
	
	/** リクエスト種別パラメータ */
	private static final String S_POST = "POST";

	/** 文字コード*/
	protected static final String S_CHR_CODE = "MS932";

	/** APIシステムエラー*/
	protected static final String S_AUTH_SYSERR = "9000000";

	/** 通信方式SSL*/
	protected static final String S_HTTPS = "https";

	/**
	 * レコード ※現状、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";


	/**
	 * 処理結果コード 0:正常、1：パラメータエラー、2：エラー、9：その他（SOAP通信エラー）
	 */
	public static String TRN_RSLT_CD = null;
	/** 処理結果コード 0:正常 */
	public static final String TRN_RSLT_CD_NORMAL = "0";
	/** 処理結果コード 1：パラメータエラー */
	public static final String TRN_RSLT_CD_ERR_PARAM = "1";
	/** 処理結果コード 2：エラー */
	public static final String TRN_RSLT_CD_ERR = "2";
	/** 処理結果コード 9：SOAP通信エラー（現状、判定不要） */
	public static final String TRN_RSLT_CD_ERR_SOAP = "9";

	/**
	 * コマンド実行結果（エラー）
	 */
	public static final String CMD_ERROR_MESSAGE = "CMD_ERROR_MESSAGE";

	/** サイトコード（受信） */
	public static final String OUT_SHOPID = "out_shopid";

	/** 処理区分（受信） */
	public static final String OUT_PROCTYPE = "out_proctype";

	/** サイト管理番号（受信） */
	public static final String OUT_ORDERNO = "out_orderno";

	/** 受付番号（受信） */
	public static final String OUT_RECEIVENO = "out_receiveNo";

	/** ステータス（受信） */
	public static final String OUT_STATUS = "out_status";

	/** 結果コード（受信）0:正常終了、1:形式エラー、2:業務エラー、9:システムエラー */
	public static final String OUT_RESULT = "out_result";

	/** 結果コード詳細（受信） */
	public static final String OUT_RESULTDET = "out_resultdet";

	/** 結果内容（受信） */
	public static final String OUT_RESULTCONTENT = "out_resultcontent";

	/** 応答日時（受信） */
	public static final String OUT_ENDTIME = "out_endtime";


	/**
	 * HTTPSリクエスト独自処理部品です。
	 * @param inMap メッセージ
	 * @throws Exception エラー全般
	 */
	@SuppressWarnings("unchecked")
	public void execute(CAANMsg msgList, AgentDispatchContext inContext) throws Exception
	{
		
		// 開始ログ出力を実施。
		JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), PGID + "#execute start");
		JSYejbLog.println(JSYejbLog.EXECUTION, this.getClass(), PGID + "#execute start");

		HttpURLConnection conn = null;
		BufferedReader reader = null;
		URL url = null;
		String strUrl = null;
		int timeout = 0;
		int retryCount = 0;
		int retryInterval = 0;
		TRN_RSLT_CD = TRN_RSLT_CD_ERR;
		/*-----------------------------
		 * パラメータ設定
		 *----------------------------*/
		try
		{
			//system.properties設定値取得
			strUrl = JCMAPLConstMgr.getString("KK_CASHPOST_GETSTATUS_URL");

			timeout = Integer.parseInt(JCMAPLConstMgr.getString("KK_CASHPOST_GETSTATUS_TIMEOUT"));
			retryCount = Integer.parseInt(JCMAPLConstMgr.getString("KK_CASHPOST_GETSTATUS_RETRYCOUNT"));
			retryInterval = Integer.parseInt(JCMAPLConstMgr.getString("KK_CASHPOST_GETSTATUS_RETRYINTERVAL"));

			// アプリケーションプロパティ設定チェック
			if (isNullBlunk(strUrl))
			{
				TRN_RSLT_CD = TRN_RSLT_CD_ERR_PARAM;
				JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), PGID + "#Properties Error");
				
				CAANMsg[] l_EKKA0110001csvmsg1list = null;
				
				l_EKKA0110001csvmsg1list =  new CAANMsg[1];
				CAANMsg msg = new CAANMsg("eo.ejb.cbs.cbsmsg.EKKA0110001CBSMsg1List");
				l_EKKA0110001csvmsg1list[0] = msg;
				// コマンド実行結果
				msg.set(EKKA0110001CBSMsg1List.TRN_RSLT_CD, TRN_RSLT_CD);
				msgList.set(EKKA0110001CBSMsg.EKKA0110001CBSMSG1LIST, l_EKKA0110001csvmsg1list);

				return;
			}
		}
		catch (NumberFormatException ne)
		{
			TRN_RSLT_CD = TRN_RSLT_CD_ERR_PARAM;
			JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), PGID + "#NumberFormatException");
			
			CAANMsg[] l_EKKA0110001csvmsg1list = null;
			
			l_EKKA0110001csvmsg1list =  new CAANMsg[1];
			CAANMsg msg = new CAANMsg("eo.ejb.cbs.cbsmsg.EKKA0110001CBSMsg1List");
			l_EKKA0110001csvmsg1list[0] = msg;
			// コマンド実行結果
			msg.set(EKKA0110001CBSMsg1List.TRN_RSLT_CD, TRN_RSLT_CD);
			msgList.set(EKKA0110001CBSMsg.EKKA0110001CBSMSG1LIST, l_EKKA0110001csvmsg1list);

			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);
		JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), PGID + "#送信URLパラメータ" + url);
		// リクエスト結果読込用ストリーム
		InputStream inputStream = null;
		InputStreamReader isReader = null;
		String reqStr = "";

		for (int i = 0; i < retryCount; i++)
		{
			try
			{
				reqStr = "";
				// アプリケーションプロパティよりProxy設定値を取得
				String strPrxyHost = JCMAPLConstMgr.getString("KK_CASHPOST_GETSTATUS_HTTPS_PROXY_HOST");
				String strPrxyPort = JCMAPLConstMgr.getString("KK_CASHPOST_GETSTATUS_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();
					}
					JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), PGID + "#HttpsURLConnection openConnection");
					
				}
				else
				{
					conn = (HttpURLConnection)url.openConnection();
					JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), 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);

				/*
				 * 送信パラメータ作成
				 */
				reqStr = requestParamMake(msgList);
				JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), PGID + "#reqParam=" + reqStr);
				JSYejbLog.println(JSYejbLog.EXECUTION, this.getClass(), PGID + "#reqParam=" + reqStr);
				ps.print(reqStr);
				ps.close();

				// 接続開始ログ
				JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), PGID + "#connect start");

				//********************//
				// 接続実行
				//********************//
				conn.connect();

				// 接続終了ログ
				JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), PGID + "#connect end");

				int responseCode = 500;
				responseCode = conn.getResponseCode();
				if (responseCode >= 200 && responseCode < 300)
				{
					// 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");
					JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), PGID + "#レスポンス受信 START");

					JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), PGID + "#ContentEncoding=[" + conn.getContentEncoding() + "]");

					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();

					JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), PGID + "#レスポンス受信 END");

					/**
					 * 下り電文のログ出力
					 */
					sw = new StringWriter();
					transformer.transform(new DOMSource(responseXml), new StreamResult(sw));

					/**
					 * レスポンス読込処理
					 */
					JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), PGID + "#レスポンス読込処理 START");
					ret = read(responseXml);
					JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), PGID + "#retParam=" + ret);
					JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), PGID + "#レスポンス読込処理 END");

					StringBuffer sb = new StringBuffer();
					sb.append("CASHPOST連携結果 responseCode=[");
					sb.append(responseCode + "]   ");
					sb.append(makeLogStr(ret));
					JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), PGID + "#" + sb.toString());
					JSYejbLog.println(JSYejbLog.EXECUTION, this.getClass(), PGID + "#" + sb.toString());
					/*
					 * HTTP 応答メッセージから状態コードを取得し設定する。 
					 * HTTP/1.0 200 OK
					 * HTTP/1.0 401 Unauthorized
					 */
					if (HTTP_OK.equals(Integer.toString(responseCode)))
					{
						// ステータス=200：CASHPOST連携正常とする。
						TRN_RSLT_CD = TRN_RSLT_CD_NORMAL;
					}
					//********************//
					// 処理結果返却
					//********************//
					resultPut(msgList, ret);
				}
				else
				{
					TRN_RSLT_CD = TRN_RSLT_CD_ERR;
					JSYejbLog.println(JSYejbLog.EXECUTION, this.getClass(), PGID + "#HttpStatusCd Error HttpStatusCd=[" + responseCode+ "]");
					
					CAANMsg[] l_EKKA0110001csvmsg1list = null;
					
					l_EKKA0110001csvmsg1list =  new CAANMsg[1];
					CAANMsg msg = new CAANMsg("eo.ejb.cbs.cbsmsg.EKKA0110001CBSMsg1List");
					l_EKKA0110001csvmsg1list[0] = msg;
					// コマンド実行結果
					msg.set(EKKA0110001CBSMsg1List.TRN_RSLT_CD, TRN_RSLT_CD);
					msgList.set(EKKA0110001CBSMsg.EKKA0110001CBSMSG1LIST, l_EKKA0110001csvmsg1list);

					return;
					
				}

			}

			catch (HTTPException he)
			{
				if (i < retryCount - 1)
				{
					JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), PGID + "#(HTTPException)" + he.getMessage());
					// スリープした後、再度CASHPOST呼び出し
					JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), PGID + "#(HTTPException)sleep start");
					Thread.sleep(retryInterval);
					JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), PGID + "#(HTTPException)sleep end");
					JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), PGID + "#(HTTPException)retryCount=" + i);
					continue;
				}
				else
				{
					JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), PGID + "#(HTTPException)" + he.getMessage());
					JSYejbLog.println(JSYejbLog.EXECUTION, this.getClass(), PGID + "#(HTTPException)" + he.getMessage());
					
					
					CAANMsg[] l_EKKA0110001csvmsg1list = null;
					TRN_RSLT_CD = TRN_RSLT_CD_ERR;
					l_EKKA0110001csvmsg1list =  new CAANMsg[1];
					CAANMsg msg = new CAANMsg("eo.ejb.cbs.cbsmsg.EKKA0110001CBSMsg1List");
					l_EKKA0110001csvmsg1list[0] = msg;
					// 処理結果コード
					msg.set(EKKA0110001CBSMsg1List.TRN_RSLT_CD, TRN_RSLT_CD);
					msgList.set(EKKA0110001CBSMsg.EKKA0110001CBSMSG1LIST, l_EKKA0110001csvmsg1list);
				}
			}
			catch (TransformerException trnEx)
			{
				// タグが不正（文字化けなどでも発生）
				if (i < retryCount - 1)
				{
					JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), PGID + "#(TransformerException)" + trnEx.getMessage());
					// スリープした後、再度API呼び出し
					JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), PGID + "#(TransformerException)sleep start");
					Thread.sleep(retryInterval);
					JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), PGID + "#(TransformerException)sleep end");
					JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), PGID + "#(TransformerException)retryCount=" + i);
					continue;
				}
				else
				{
					JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), PGID + "#(TransformerException)" + trnEx.getMessage());
					JSYejbLog.println(JSYejbLog.EXECUTION, this.getClass(), PGID + "#(TransformerException)" + trnEx.getMessage());
					
					CAANMsg[] l_EKKA0110001csvmsg1list = null;
					TRN_RSLT_CD = TRN_RSLT_CD_ERR;
					l_EKKA0110001csvmsg1list =  new CAANMsg[1];
					CAANMsg msg = new CAANMsg("eo.ejb.cbs.cbsmsg.EKKA0110001CBSMsg1List");
					l_EKKA0110001csvmsg1list[0] = msg;
					// 処理結果コード
					msg.set(EKKA0110001CBSMsg1List.TRN_RSLT_CD, TRN_RSLT_CD);
					msgList.set(EKKA0110001CBSMsg.EKKA0110001CBSMSG1LIST, l_EKKA0110001csvmsg1list);
				}
			}
			catch (IOException ie)
			{
				if (i < retryCount - 1)
				{
					JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), PGID + "#(IOException)" + ie.getMessage());
					// スリープした後、再度API呼び出し
					JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), PGID + "#(IOException)sleep start");
					Thread.sleep(retryInterval);
					JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), PGID + "#(IOException)sleep end");
					JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), PGID + "#(IOException)retryCount=" + i);
					continue;
				}
				else
				{
					JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), PGID + "#(IOException)" + ie.getMessage());
					JSYejbLog.println(JSYejbLog.EXECUTION, this.getClass(), PGID + "#(IOException)" + ie.getMessage());
					
					CAANMsg[] l_EKKA0110001csvmsg1list = null;
					TRN_RSLT_CD = TRN_RSLT_CD_ERR;
					l_EKKA0110001csvmsg1list =  new CAANMsg[1];
					CAANMsg msg = new CAANMsg("eo.ejb.cbs.cbsmsg.EKKA0110001CBSMsg1List");
					l_EKKA0110001csvmsg1list[0] = msg;
					// 処理結果コード
					msg.set(EKKA0110001CBSMsg1List.TRN_RSLT_CD, TRN_RSLT_CD);
					msgList.set(EKKA0110001CBSMsg.EKKA0110001CBSMSG1LIST, l_EKKA0110001csvmsg1list);
				}
			}
			finally
			{
				if (reader != null)
				{
					reader.close();
				}
				if (conn != null)
				{
					conn.disconnect();
					conn = null;
				}
				if (inputStream != null)
				{
					inputStream.close();
				}
				if (isReader != null)
				{
					isReader.close();
				}
				JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), PGID + "#execute end");
				JSYejbLog.println(JSYejbLog.EXECUTION, this.getClass(), PGID + "#execute end");
			}

			break;
		}
	}

	/**
	 * APIに対して送信するリクエストパラメータを作成する。
	 * @param inMap メッセージキャリア
	 * @return CASHPOSTAPIへのリクエストパラメータ
	 * @throws UnsupportedEncodingException
	 */
	@SuppressWarnings("unchecked")
	protected String requestParamMake(CAANMsg ccMsg)
	{
		// リクエストパラメータ作成
		StringBuffer strBuf = new StringBuffer();

		// サイトコード(APLConst)
		strBuf.append("in_shopid");
		strBuf.append(S_SEP_EQ);
		strBuf.append(JCMAPLConstMgr.getString("KK_CASHPOST_GETSTATUS_SHOP_ID"));
		// チェックコード(APLConst)
		strBuf.append(S_SEP_AN);
		strBuf.append("in_chkCode");
		strBuf.append(S_SEP_EQ);
		strBuf.append(JCMAPLConstMgr.getString("KK_CASHPOST_GETSTATUS_CHKCODE"));
		// 処理区分(APLConst)
		strBuf.append(S_SEP_AN);
		strBuf.append("in_proctype");
		strBuf.append(S_SEP_EQ);
		strBuf.append(JCMAPLConstMgr.getString("KK_CASHPOST_GETSTATUS_PROCTYPE"));
		// サイト管理番号
		strBuf.append(S_SEP_AN);
		strBuf.append("in_orderno");
		strBuf.append(S_SEP_EQ);
		strBuf.append((String)ccMsg.getString(EKKA0110001CBSMsg.KEY_SITE_KANRI_NO));

		//------------------------------------------//
		// ログ出力
		//------------------------------------------//
		JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), PGID + "#【CASHPOST呼出】：" + strBuf.toString());

		return strBuf.toString();
	}
		

	/**
	 * API処理結果を格納する。
	 * @param inMap メッセージキャリア
	 * @param key レスポンスキー
	 * @param value レスポンスバリュー
	 */
	private void resultPut(CAANMsg msgList, Hashtable<String, Object> resultMap){
		
		
		CAANMsg[] l_EKKA0110001csvmsg1list = null;
					
		l_EKKA0110001csvmsg1list =  new CAANMsg[1];
					
		CAANMsg msg = new CAANMsg("eo.ejb.cbs.cbsmsg.EKKA0110001CBSMsg1List");
		
		l_EKKA0110001csvmsg1list[0] = msg;
		// サイトコード（受信）
		msg.set(EKKA0110001CBSMsg1List.OUT_SHOPID, resultMap.get(OUT_SHOPID));
		// 処理区分（受信）
		msg.set(EKKA0110001CBSMsg1List.OUT_PROCTYPE, resultMap.get(OUT_PROCTYPE));
		// サイト管理番号（受信）
		msg.set(EKKA0110001CBSMsg1List.OUT_ORDERNO, resultMap.get(OUT_ORDERNO));
		// 受付番号（受信）
		msg.set(EKKA0110001CBSMsg1List.OUT_RECEIVENO, resultMap.get(OUT_RECEIVENO));
		// ステータス（受信）
		msg.set(EKKA0110001CBSMsg1List.OUT_STATUS, resultMap.get(OUT_STATUS));
		// 結果コード（受信）
		msg.set(EKKA0110001CBSMsg1List.OUT_RESULT, resultMap.get(OUT_RESULT));
		// 結果コード詳細（受信）
		msg.set(EKKA0110001CBSMsg1List.OUT_RESULTDET, resultMap.get(OUT_RESULTDET));
		// 結果内容（受信）
		msg.set(EKKA0110001CBSMsg1List.OUT_RESULTCONTENT, resultMap.get(OUT_RESULTCONTENT));
		// 応答日時（受信）
		msg.set(EKKA0110001CBSMsg1List.OUT_ENDTIME, resultMap.get(OUT_ENDTIME));
		
		// コマンド実行結果
		msg.set(EKKA0110001CBSMsg1List.TRN_RSLT_CD, TRN_RSLT_CD);
		
		msgList.set(EKKA0110001CBSMsg.EKKA0110001CBSMSG1LIST, l_EKKA0110001csvmsg1list);
		
			
		return;
	}

	/**
	 * ＮＵＬＬ、空文字の場合は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)
		{
			JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), 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);
					TRN_RSLT_CD = TRN_RSLT_CD_ERR_SOAP;
					resultMap.put(TRN_RSLT_CD, TRN_RSLT_CD);
					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
			JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), 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();
	}

}
