/*********************************************************************
*	 All Rights reserved,Copyright (c) K-Opticom 
**********************************************************************
*＜プログラム内容＞
*   システム名      ：eo顧客基幹システム
*   モジュール名    ：JECNA0040001TPMA
*   ソースファイル名：JECNA0040001TPMA.java
*   作成者          ：富士通
*   日付            ：2011年10月14日
*＜機能概要＞
*   主処理(共通)<BR>
*   クリアパスHTTPSリクエスト処理部品です。
*＜修正履歴＞
*   バージョン  修正日      修正者      修正内容
*   v1.00.00    2011/10/14  富士通      新規作成
*   v3.00.00    2012/09/03  FJ)小林     【ST1-2012-0000505】外部IF項目.カード所有者名空文字対応
*   v4.00.01    2012/09/25  FJ)小林     【TAI-2012-0000095】Fortify指摘内容の是正
*   v5.00.00    2013/04/30  FJ)味岡     【TAI-2013-0000025】静的解析の指摘事項修正
*   v12.00.00   2015/01/13  FJ)中山     【OM-2014-0004037】随時-14-7455のアプリ改修
*   v19.00.00   2015/08/20  FJ)西面     【ANK-2585-00-00】クレカ経路変更
*   v19.00.01   2015/09/03  FJ)西面     【IT1-2015-0000094】XML解析処理追加
*   v19.00.02   2015/09/11  FJ)西面     【IT1-2015-0000096】クレジットカード番号マスク処理
*   v22.00.00   2015/11/19  FJ)西面     【ANK-2565-00-00】クレジットカード番号預かりサービス導入（Step3）
*   v23.00.00   2016/02/29  FJ)西面     【ANK-2810-00-00】クレジットカード番号マスク化対応
*   v34.00.00   2017/12/12  FJ)大崎     【ANK-3313-00-00】クレジットカード番号非通過対応 2月末向け
*   v36.00.00   2017/12/12  FJ)大崎     【ANK-3313-00-00】クレジットカード番号非通過対応 3月末向け
*   v36.00.00   2018/03/01   FJ)大崎	【ST-2018-0000007】トークン利用区分設定による、カード預かりＩＤでのオーソリエラー。
*   v44.00.00   2019/05/22  FJ)河邊     【OM-2019-0000398】売上オーソリの結果受信の例外アラーム変更
*   v45.00.00   2019/08/06  FJ)前田     【ANK-3602-01-00】特定クレジットカード案件内仕様変更１
*   v58.00.00   2022/04/22  FJ)上村     【ANK-3846-00-00】【クレカ】クリアパス→ペイジェント移行
**********************************************************************/

package eo.ejb.cbs.mainproc;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashMap;

import com.fujitsu.futurity.common.JSYLogBase;
import com.fujitsu.futurity.common.JSYbpmLog;
import com.fujitsu.futurity.model.base.CAANMsg;
import com.fujitsu.futurity.model.ejb.common.JSYejbLog;
import com.fujitsu.futurity.model.ejb.common.fw.AgentDispatchContext;
import com.fujitsu.futurity.model.ejb.common.fw.TemplateMainHandler;

import eo.common.constant.JCNStrConst;
import eo.common.util.JCNAuthResultCdConvertUtil;
import eo.ejb.cbs.cbsmsg.ECNA0040001CBSMsg;
import eo.ejb.common.JCCModelCommon;
import eo.ejb.common.edit.JCNejbOracleSeqParts;

import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URL;

import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

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 java.util.Map;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import java.util.List;
import com.fujitsu.futurity.model.common.JCMAPLConstMgr;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import java.util.Hashtable;
import javax.xml.ws.http.HTTPException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
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 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.PrintWriter;
import java.io.StringWriter;
import java.security.SecureRandom;
import java.security.cert.CertificateException;

/**
 * <p>
 * クリアパスHTTPSリクエスト独自処理部品クラスです。
 * </p>
 * @author 富士通
 */
public class JECNA0040001TPMA implements TemplateMainHandler
{
	/** 部品ID*/
	public static final String PGID = "JECNA0040001TPMA";
	
	/** パラメータセパレート文字:=*/
	private static final String S_SEP_EQ = JCNStrConst.S_SEP_EQ;
	
	/** パラメータセパレート文字:&*/
	private static final String S_SEP_AN = JCNStrConst.S_SEP_AN;
	
	/** パラメータキー文字列*/
	private static final String S_KEY_HEAD = JCNStrConst.S_KEY_HEAD;
	
	/** 通信方式パラメータ*/
	private static final String S_SSL = JCNStrConst.S_SSL;
	
	/** リクエスト種別パラメータ*/
	private static final String S_POST = JCNStrConst.S_POST;
	
	/** 文字コード*/
	private static final String S_CHR_CODE = JCNStrConst.S_CHR_CODE;
	
	/** クリアパスAPIシステムエラー*/
	private static final String S_AUTH_SYSERR = JCNStrConst.S_AUTH_SYSERR;
	
	/** レスポンス区切り文字*/
	private static final String S_DELIM_TAB = JCNStrConst.S_DELIM_TAB;
	
	/** 通信方式SSL*/
	private static final String S_HTTPS = "https";
	
	/** 空文字 */
	private static final String S_BLANK = "";
	
//v19.00.00 2015/08/20 ANK-2585-00-00 Add Start

	/** コマンドタイプ  */
	private static final String CMD = "cmd";
	
	/** 処理区分  */
	private static final String EXEC_TYPE = "exec_type";
	
	/** システム接続設定番号 */
	private static final String CONNECT_NO = "connect_no";
	
	/** 接続キー */
	private static final String CONNECT_KEY = "connect_key";
	
	/** グループコード */
	private static final String COMP_CD = "comp_cd";
	
	/** 事業者コード */
	private static final String SHOP_CD = "shop_cd";
	
	/** カード預かりID */
	private static final String SAVE_ID = "save_id";
	
	/** カードブランド */
	private static final String CARD_BRAND_CD = "card_brand_cd";
	
	/** カード番号 */
	private static final String CARD_NO = "card_no";
	
	/** カード有効期限 */
	private static final String CARD_EXP_DATE = "card_exp_date";
	
	/** カード名義人 */
	private static final String CARD_USER_NAME = "card_user_name";
	
	/** セキュリティコード */
	private static final String CARD_SEC_CD = "card_sec_cd";
	
	/** 決済金額 */
	private static final String AMOUNT = "amount";
	
	/** 再掲額 */
	private static final String SUB_AMOUNT = "sub_amount";
	
	/** 支払区分 */
	private static final String PAY_TYPE = "pay_type";
	
	/** 分割回数 */
	private static final String PAY_COUNT = "pay_count";
	
	/** 事業者請求番号 */
	private static final String ORDER_NO = "order_no";
	
	/** 顧客ID */
	private static final String SHOP_MB_ID = "shop_mb_id";
	
	/** 顧客名 */
	private static final String SHOP_MB_NAME = "shop_mb_name";
	
	/** IPアドレス */
	private static final String IP_ADDRESS = "ip_address";
	
	/** 結果コード */
	private static final String RESULT_CD = "result_cd";

	/** 詳細コード */
	private static final String RESULT_INFO_CD = "result_info_cd";

	/** エラーコード */
	private static final String ERR_CD = "err_cd";

	/** 結果区分 */
	private static final String RESULT_KBN = "result_kbn";

	/** オーソリ結果 */
	private static final String AUTH_RESULT = "auth_result";

	/** オーソリ結果コード */
	private static final String AUTH_RESULT_CD = "auth_result_cd";

	/** 承認番号 */
	private static final String RECOGNIZED_NO = "recognized_no";

	/** トランザクションID */
	private static final String TRAN_ID = "tran_id";

	/** クリアパス取引ID */
	private static final String CP_TRAN_ID = "cp_tran_id";

	/** 問合せ用カード番号 */
	private static final String INQUIRE_CARD_NO = "inquire_card_no";

	/** 仕向会社コード */
	private static final String CARD_CORP_CD = "card_corp_cd";
	
	//ANK-3313-00-00 ADD START v36.00.00
	/** トークン利用区分 */
	private static final String TOKEN_USE = "token_use";

	//ANK-3313-00-00 ADD END v36.00.00
	//ANK-3313-00-00 ADD START v34.00.00
	/** カード識別コード */
	private static final String UNIQUE_CD = "unique_cd";

	/** カードブランド(K-OPT) */
	private static final String CARD_BRAND_OPTCD = "card_brand_optcd";

	//ANK-3313-00-00 ADD END v34.00.00
	// ANK-3602-01-00 2019/08/06 ADD START
	/** カード種別 */
	private static final String CARD_TYPE = "card_type";

	/** イシュア区分 */
	private static final String ISSUER_CLASS = "issuer_class";

	// ANK-3602-01-00 2019/08/06 ADD END
	/** コマンドタイプ "EXEC"(取引実行処理)*/
	private static final String CMD_EXEC = "EXEC";
	
	/** 処理区分 "191"（オーソリ） */
	private static final String EXEC_TYPE_191 = "191";
	
	/** カードブランド "99"（クリアパス自動判断）*/
	private static final String CARD_BRAND_CD_99 = "99";
	
	/** 支払い区分 "10"（1回払い) */
	private static final String PAY_TYPE_10 = "10";
	
	/** システム接続設定番号（アプリケーションプロパティ） */
	private static final String CN_CONNECT_NO = "CN_CONNECT_NO";
	
	/** 接続キー（アプリケーションプロパティ） */
	private static final String CN_CONNECT_KEY = 	"CN_CONNECT_KEY";
	
	/** グループコード（アプリケーションプロパティ） */
	private static final String CN_COMP_CD = "CN_COMP_CD";
	
	/** 事業者コード（アプリケーションプロパティ） */
	private static final String CN_SHOP_CD = "CN_SHOP_CD";

//v19.00.00 2015/08/20 ANK-2585-00-00 Add End
//v19.00.01 2015/09/03  Add Start
	
	/**
	 * コマンド実行結果
	 */
    public static final String CMD_RESULT_CD = "CMD_RESULT_CD";
    
    /**
	 * レコード
	 */
    public static final String RECORD = "record";
    
    /**
	 * サービスIF
	 */
	public static final String SERVICEIF = "service_if";
    
	/**
	 * タグ属性(=TYPE)
	 */
	private static final String[] typeValues = {"service_if","service_if_list"};
	
	/**
	 * タグ名
	 */
	private static final String[] tagNames = {"Envelope","Body","Header","initResponse"};
	
	/**
	 * コマンド実行結果（エラー）
	 */
    public static final String CMD_ERROR_MESSAGE = "CMD_ERROR_MESSAGE";
    
    /**
	 * SOALFAULT（処理例外）
	 */
	private static final String SOAP_FAULT = "fault";

	/**
	 * SOALFAULT（エラーコード）
	 */
	private static final String SOAP_FAULT_CODE = "reason";
	
	/**
	 * SOALFAULT（エラー詳細）
	 */
	private static final String SOAP_FAULT_STRING = "detail";
	
//v19.00.01 2015/09/03  Add End

	/**
	 * コンストラクタ.
	 */
	public JECNA0040001TPMA()
	{
		super();
	}

	/**
	 * クリアパスHTTPSリクエスト独自処理部品です。
	 * @param inCBSMsg CAANメッセージ
	 * @param inContext コンテキスト
	 * @throws Exception 
	 */
	public void invoke(CAANMsg inCBSMsg, AgentDispatchContext inContext) throws Exception
	{
		// 開始ログ出力を実施。
		JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JECNA0040001TPMA#invoke start");
		
		HttpURLConnection conn = null;
		URL url = null;
		
		try
		{
			//system.properties設定値取得
			String strUrl = JCMAPLConstMgr.getString("CN_CLEARPASS_URL");
			String strApiNm = JCMAPLConstMgr.getString("CN_CLEARPASS_APINAME");
//OM-2014-0004037 MOD START
//			int timeout = Integer.parseInt(JCMAPLConstMgr.getString("CN_CLEARPASS_TIMEOUT"));
//			int retryCount = Integer.parseInt(JCMAPLConstMgr.getString("CN_CLEARPASS_RETRYCOUNT"));
			int timeout = Integer.parseInt(JCMAPLConstMgr.getString("CN_CLEARPASS_AUTH_TIMEOUT"));
			int retryCount = Integer.parseInt(JCMAPLConstMgr.getString("CN_CLEARPASS_AUTH_RETRYCOUNT"));
//OM-2014-0004037 MOD END
			int retryInterval = Integer.parseInt(JCMAPLConstMgr.getString("CN_CLEARPASS_RETRYINTERVAL"));
			
			// アプリケーションプロパティ.加盟店ID格納
			String strCrCpid = JCMAPLConstMgr.getString(inCBSMsg.getString(ECNA0040001CBSMsg.CR_CPID));
			// アプリケーションプロパティ.加盟店パスワード格納
			String strCrPasswd = JCMAPLConstMgr.getString(inCBSMsg.getString(ECNA0040001CBSMsg.CR_PASSWD));
			
			// アプリケーションプロパティ設定チェック
			if(strUrl == null
					|| strApiNm == null
					|| strCrCpid == null
					|| strCrPasswd == null)
			{
				inCBSMsg.set(ECNA0040001CBSMsg.CR_RESULTCODE, S_AUTH_SYSERR);
				return;
			}
			
			// パスワード復合化
			strCrPasswd = decriptPassWd(strCrPasswd);
			
			// 通信方式判定
			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 
					{
						// TODO 自動生成されたメソッドスタブ
					}
	
					/**
					 * checkServerTrustedスタブメソッド
					 * @param arg0
					 * @param arg1
					 * @throws CertificateException
					 */
					public void checkServerTrusted(
							java.security.cert.X509Certificate[] arg0, String arg1)
							throws CertificateException 
					{
						// TODO 自動生成されたメソッドスタブ
					}
				} };
				SSLContext sslcontext = SSLContext.getInstance(S_SSL);
				sslcontext.init(km, tm, new SecureRandom());
				HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
					
					/**
					 * verifyスタブメソッド
					 * @param aHostname
					 * @param aSession
					 * @return クリアパスAPIへのリクエストパラメータ
					 */
					public boolean verify(String aHostname, SSLSession aSession) 
					{
						return true;
					}
				});
				HttpsURLConnection.setDefaultSSLSocketFactory(sslcontext.getSocketFactory());
			}
			
			// URL生成
			url = new URL(strUrl + strApiNm);
			
			for(int i = 0 ; i < retryCount ; i++)
			{
				//リクエスト結果読み出し try-catch外で生成するよう修正(TAI-2012-0000095対応)
				InputStream is = null;
				BufferedReader reader = null;
				
				try
				{
					// アプリケーションプロパティよりProxy設定値を取得
					String strPrxyHost = JCMAPLConstMgr.getString("CN_HTTPS_PROXY_HOST");
					String strPrxyPort = JCMAPLConstMgr.getString("CN_HTTPS_PROXY_PORT");
					
					int intProxyPort = 0;
					if(strPrxyHost != null)
					{
						intProxyPort = Integer.parseInt(strPrxyPort);
					}
					
					// SSLの場合、HttpsURLConnectionへキャスト
					if(bSslFlg)
					{
						// Proxy設定値がある場合はProxyをセットしてコネクションをオープン
						if(strPrxyHost != null
								&& strPrxyPort != null)
						{
							Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(strPrxyHost, intProxyPort));
							conn = (HttpsURLConnection) url.openConnection(proxy);
						}
						else
						{
							conn = (HttpsURLConnection) url.openConnection();
						}
						
					}
					else
					{
						conn = (HttpURLConnection) url.openConnection();
					}
					
					// リクエスト設定
					conn.setRequestMethod(S_POST);
					conn.setDoOutput(true);
					conn.setInstanceFollowRedirects(true);
					
					
					//タイムアウト設定
					conn.setReadTimeout(timeout);
					
					//POSTパラメータストリームの生成
					OutputStream os = conn.getOutputStream();
					PrintStream ps = new PrintStream(os);
					ps.print(requestParamMake(inCBSMsg, strCrCpid, strCrPasswd, inContext));
					ps.close();
					
					
					// 接続開始ログ
					JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JECNA0040001TPMA#connect start");
					
					// 接続実行
					conn.connect();
					
					// 接続終了ログ
					JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JECNA0040001TPMA#connect end");
					
					int statusCode = 500;
					statusCode = conn.getResponseCode();
					
					JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JECNA0040001TPMA#statusCode=" + statusCode);
	
//v19.00.01 2015/09/03  Del Start
//					//リクエスト結果読み出し コメントアウト(TAI-2012-0000095対応)
//					is = conn.getInputStream();
//					reader = new BufferedReader(new InputStreamReader(is, S_CHR_CODE));
//					
//					String s = null;
//					
////v19.00.00 2015/08/20 Add Start
//					HashMap<String,String> resultMap = new HashMap<String,String>(25);
////v19.00.00 2015/08/20 Add End
//					for(s = reader.readLine() ; null != s ; s = reader.readLine())
//					{
////v19.00.00 2015/08/27 Del Start
//						//if(s.startsWith(S_KEY_HEAD)) 
//						//{s
////v19.00.00 2015/08/27 Del End
//							String delim = S_DELIM_TAB;
//							// レスポンス読込結果をキーと値に分割
//							StringTokenizer token = new StringTokenizer(s, delim);
//							if (token.countTokens() != 2) 
//							{
//								continue;
//							}
//							String key = token.nextToken();
//							String value = token.nextToken();
//							
////v19.00.00 2015/08/20 Del Start
////							// クリアパスAPI処理結果をinCBSMsgへ格納
////							resultPut(inCBSMsg, key, value);
////v19.00.00 2015/08/20 Del End
////v19.00.00 2015/08/20 Add Start
//							//クリアパスAPI処理結果をマップに格納する
//							resultMap.put(key, value);
////v19.00.00 2015/08/20 Add End
//							
//							JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JECNA0040001TPMA#resKey=" + key);
//							JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JECNA0040001TPMA#resValue=" + value);
//							
////v19.00.00 2015/08/27 Del Start
//						//}
////v19.00.00 2015/08/27 Del End
//					}
////v19.00.00 2015/08/27 Add Start	
//					StringBuffer sb = new StringBuffer();
//					sb.append("クリアパス出力結果=statusCode=");
//					sb.append(statusCode);
//					sb.append(resultMap);
//					JSYbpmLog.println(JSYLogBase.EXECUTION, this.getClass() ,sb, "",  new String[]{"", ""}, "");
////v19.00.00 2015/08/27 Add End					
////v19.00.00 2015/08/20 Add Start
//					resultPut(inCBSMsg, resultMap);
////v19.00.00 2015/08/20 Add End
//					// readerクローズ コメントアウト(TAI-2012-0000095対応)
//					reader.close();
//v19.00.01 2015/09/03  Del End
//v19.00.01 2015/09/03  Add Start
					Hashtable<String, Object> ret = new Hashtable<String, Object>();
					Transformer transformer = null;
					Document responseXml = null;
					StringWriter sw = null;
					Document requestXml = null;
					String request = null;
					String response = null;
					
					TransformerFactory transformerFactory = TransformerFactory.newInstance();
					transformer = transformerFactory.newTransformer();
					
					JSYejbLog.outlog(null, JSYejbLog.DEBUG, this.getClass(), "SOAPレスポンス受信 START");
					is = conn.getInputStream();
					DOMResult dr = new DOMResult();
					transformer.transform(new StreamSource(is), dr);
					responseXml = (Document)dr.getNode();
					JSYejbLog.outlog(null, JSYejbLog.DEBUG, this.getClass(), "SOAPレスポンス受信 END");
					
					/**
					 * 下り電文のログ出力
					 */
					sw = new StringWriter();
					transformer.transform(new DOMSource(responseXml), new StreamResult(sw));
					response = sw.toString();

					/**
					 * SOAPレスポンス読込処理
					 */
					JSYejbLog.outlog(null, JSYejbLog.DEBUG, this.getClass(), "SOAPレスポンス読込処理 START");
					ret = read(responseXml);
					JSYejbLog.outlog(null, JSYejbLog.DEBUG, this.getClass(), ret);
					JSYejbLog.outlog(null, JSYejbLog.DEBUG, this.getClass(), "SOAPレスポンス読込処理 END");
							
					resultPut(inCBSMsg, ret);

					StringBuffer sb = new StringBuffer();
					sb.append("クリアパス出力結果=statusCode=");
					sb.append(statusCode);
//v19.00.02 2015/09/14 Mod Start
					//sb.append(ret);
					sb.append(makeLogStr(ret));
//v19.00.02 2015/09/14 Mod End
					JSYbpmLog.println(JSYLogBase.EXECUTION, this.getClass() ,sb, "",  new String[]{"", ""}, "");
//v19.00.01 2015/09/03  Add End
					
					// 通信レスポンスコードが異常だった場合は処理結果にシステムエラーを設定
					if (statusCode != 200) 
					{
						inCBSMsg.set(ECNA0040001CBSMsg.CR_RESULTCODE, S_AUTH_SYSERR);
					}
					
				}
				catch(HTTPException he)
				{
					inCBSMsg.set(ECNA0040001CBSMsg.CR_RESULTCODE, S_AUTH_SYSERR);
					
					StringBuilder sb = new StringBuilder();
					StringWriter sw = new StringWriter();
					PrintWriter pw = new PrintWriter(sw);
					he.printStackTrace(pw);
					sb.append("\n" + sw.toString());
					JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(),"#JECNA0040001TPMA(HTTPException)発生" + sb.toString());
					
					
					// リトライ
					if(i < retryCount)
					{
						// スリープ開始ログ
						JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JECNA0040001TPMA#sleep start");
						// スリープ処理
						Thread.sleep(retryInterval);
						// スリープ終了ログ
						JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JECNA0040001TPMA#sleep end");
						// リトライカウントログ
						JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JECNA0040001TPMA#retryCount="
								+ i);
						continue;
					}
					else
					{
						throw he;
					}
				}
				catch(IOException ie)
				{
					inCBSMsg.set(ECNA0040001CBSMsg.CR_RESULTCODE, S_AUTH_SYSERR);
					
					StringBuilder sb = new StringBuilder();
					StringWriter sw = new StringWriter();
					PrintWriter pw = new PrintWriter(sw);
					ie.printStackTrace(pw);
					sb.append("\n" + sw.toString());
					JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(),"#JECNA0040001TPMA(IOException)発生" + sb.toString());
					
					// リトライ
					if(i < retryCount)
					{
						// スリープ開始ログ
						JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JECNA0040001TPMA#sleep start");
						// スリープ処理
						Thread.sleep(retryInterval);
						// スリープ終了ログ
						JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JECNA0040001TPMA#sleep end");
						// リトライカウントログ
						JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JECNA0040001TPMA#retryCount="
								+ i);
						continue;
					}
					else
					{
						throw ie;
					}
				}
				finally
				{
					// ストリームreaderクローズ前にnullチェックを実施するよう修正(TAI-2013-0000025:静的解析指摘事項修正)
					if(reader != null)
					{
						// readerクローズ ストリームreaderをfainallyでクローズするよう修正(TAI-2012-0000095対応)
						reader.close();
					}
				}
				break;
			}
			
		}
		catch (Exception e)
		{
			StringBuilder sb = new StringBuilder();
			StringWriter sw = new StringWriter();
			PrintWriter pw = new PrintWriter(sw);
			e.printStackTrace(pw);
			sb.append("\n" + sw.toString());
			JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(),"#JECNA0040001TPMA(Exception)発生" + sb.toString());
			
			inCBSMsg.set(ECNA0040001CBSMsg.CR_RESULTCODE, S_AUTH_SYSERR);
			return;
		}
		finally
		{
			if (conn != null)
			{
				//切断処理
				conn.disconnect();
				conn = null;
			}
			
			// 処理結果ログ出力
			JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JECNA0040001TPMA#CR_RESULTCODE=" + 
					inCBSMsg.getString(ECNA0040001CBSMsg.CR_RESULTCODE));	// 処理結果コード
			JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JECNA0040001TPMA#CR_ORDERID=" + 
					inCBSMsg.getString(ECNA0040001CBSMsg.CR_ORDERID));		// 取引ID
			JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JECNA0040001TPMA#CR_BRANDCODE=" + 
					inCBSMsg.getString(ECNA0040001CBSMsg.CR_BRANDCODE));	// 仕向先会社コード
			JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JECNA0040001TPMA#CR_SLIPNUMBER=" + 
					inCBSMsg.getString(ECNA0040001CBSMsg.CR_SLIPNUMBER));	// 伝票番号
			JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JECNA0040001TPMA#CR_AUTHNUMBER=" + 
					inCBSMsg.getString(ECNA0040001CBSMsg.CR_AUTHNUMBER));	// オーソリ承認番号
			JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JECNA0040001TPMA#CR_PAIDAMOUNT=" + 
					inCBSMsg.getString(ECNA0040001CBSMsg.CR_PAIDAMOUNT));	// 決済金額
			// ANK-3602-01-00 2019/08/06 ADD START
			JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JECNA0040001TPMA#CR_CARD_TYPE=" + 
					inCBSMsg.getString(ECNA0040001CBSMsg.CR_CARD_TYPE));	// カード種別
			JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JECNA0040001TPMA#CR_ISSUER_CLASS=" + 
					inCBSMsg.getString(ECNA0040001CBSMsg.CR_ISSUER_CLASS));	// イシュア区分
			// ANK-3602-01-00 2019/08/06 ADD END
		}
		
		JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JECNA0040001TPMA#invoke end");
	}

	/**
	 * クリアパスAPIに対して送信するリクエストパラメータを作成する。
	 * @param inCBSMsg メッセージキャリア
	 * @param strCrCpid 加盟店ID
	 * @param strCrPasswd 加盟店パスワード
	 * @param inContext コンテキスト
	 * @return クリアパスAPIへのリクエストパラメータ
	 */
	private String requestParamMake(CAANMsg inCBSMsg, String strCrCpid, String strCrPasswd, AgentDispatchContext inContext)
	{

		// リクエストパラメータ作成(CBSMsgより読み出し)
		StringBuffer strBuf = new StringBuffer();
		
//v19.00.00 2015/08/20 Add Start
		// コマンドタイプ  
		strBuf.append(CMD);
		strBuf.append(S_SEP_EQ);
		strBuf.append(CMD_EXEC);

		// 処理区分  
		strBuf.append(S_SEP_AN);
		strBuf.append(EXEC_TYPE);
		strBuf.append(S_SEP_EQ);
		strBuf.append(EXEC_TYPE_191);

		// システム接続設定番号 
		strBuf.append(S_SEP_AN);
		strBuf.append(CONNECT_NO);
		strBuf.append(S_SEP_EQ);
		strBuf.append(JCMAPLConstMgr.getString(CN_CONNECT_NO));

		// 接続キー 
		strBuf.append(S_SEP_AN);
		strBuf.append(CONNECT_KEY);
		strBuf.append(S_SEP_EQ);
		strBuf.append(JCMAPLConstMgr.getString(CN_CONNECT_KEY));

		// グループコード 
		strBuf.append(S_SEP_AN);
		strBuf.append(COMP_CD);
		strBuf.append(S_SEP_EQ);
		strBuf.append(JCMAPLConstMgr.getString(CN_COMP_CD));

		// 事業者コード 
		strBuf.append(S_SEP_AN);
		strBuf.append(SHOP_CD);
		strBuf.append(S_SEP_EQ);
		strBuf.append(JCMAPLConstMgr.getString(CN_SHOP_CD));

		// カードブランド 
		strBuf.append(S_SEP_AN);
		strBuf.append(CARD_BRAND_CD);
		strBuf.append(S_SEP_EQ);
		strBuf.append(CARD_BRAND_CD_99);

		
		//v22.00.00 2015/11/20 Add Start
		//クレジットカード番号が設定されている場合、クリアパスに連携する
		if(!isNullBlank(inCBSMsg.getString(ECNA0040001CBSMsg.CR_CARDNUMBER))){
		//v22.00.00 2015/11/20 Add End
		// カード番号 
		strBuf.append(S_SEP_AN);
		strBuf.append(CARD_NO);
		strBuf.append(S_SEP_EQ);
		strBuf.append(inCBSMsg.getString(ECNA0040001CBSMsg.CR_CARDNUMBER));
		//v22.00.00 2015/11/20 Add Start
		}
		
		//カード預かりIDが設定されている場合、クリアパスに連携する
		if(!isNullBlank(inCBSMsg.getString(ECNA0040001CBSMsg.CR_SAVE_ID))){	
			// カード番号 
			strBuf.append(S_SEP_AN);
			strBuf.append(SAVE_ID);
			strBuf.append(S_SEP_EQ);
			strBuf.append(inCBSMsg.getString(ECNA0040001CBSMsg.CR_SAVE_ID));
		}
		//v22.00.00 2015/11/20 Add End

		// カード有効期限 
		strBuf.append(S_SEP_AN);
		strBuf.append(CARD_EXP_DATE);
		strBuf.append(S_SEP_EQ);
		strBuf.append(inCBSMsg.getString(ECNA0040001CBSMsg.CR_CARDEXP).replaceAll("/", ""));

		// 決済金額 
		strBuf.append(S_SEP_AN);
		strBuf.append(AMOUNT);
		strBuf.append(S_SEP_EQ);
		strBuf.append(inCBSMsg.getString(ECNA0040001CBSMsg.CR_AMOUNT));

		// 支払区分 
		strBuf.append(S_SEP_AN);
		strBuf.append(PAY_TYPE);
		strBuf.append(S_SEP_EQ);
		strBuf.append(PAY_TYPE_10);

		// 顧客ID 
		strBuf.append(S_SEP_AN);
		strBuf.append(SHOP_MB_ID);
		strBuf.append(S_SEP_EQ);
		strBuf.append(makeShopMbName(inCBSMsg,inContext));

		//ANK-3313-00-00 ADD START v36.00.00
		// トークン利用区分が設定されている場合、クリアパスに連携する 
		if(!isNullBlank(inCBSMsg.getString(ECNA0040001CBSMsg.CR_TOKEN_USE))){	
			strBuf.append(S_SEP_AN);
			strBuf.append(TOKEN_USE);
			strBuf.append(S_SEP_EQ);
			strBuf.append(inCBSMsg.getString(ECNA0040001CBSMsg.CR_TOKEN_USE));
		}
		//ANK-3313-00-00 ADD END v36.00.00
//v19.00.00 2015/08/20 Add End
		
//v19.00.00 2015/08/20 DEL Start
//		// 加盟店ID
//		strBuf.append(	ECNA0040001CBSMsg.CR_CPID);
//		strBuf.append(S_SEP_EQ);
//		strBuf.append(strCrCpid);
//		// 加盟店パスワード
//		strBuf.append(S_SEP_AN);
//		strBuf.append(ECNA0040001CBSMsg.CR_PASSWD);
//		strBuf.append(S_SEP_EQ);
//		strBuf.append(strCrPasswd);
//		// 取引年月日
//		strBuf.append(S_SEP_AN);
//		strBuf.append(ECNA0040001CBSMsg.CR_ORDERDATE);
//		strBuf.append(S_SEP_EQ);
//		strBuf.append(inCBSMsg.getString(ECNA0040001CBSMsg.CR_ORDERDATE));
//		// 取引時間
//		strBuf.append(S_SEP_AN);
//		strBuf.append(ECNA0040001CBSMsg.CR_ORDERTIME);
//		strBuf.append(S_SEP_EQ);
//		strBuf.append(inCBSMsg.getString(ECNA0040001CBSMsg.CR_ORDERTIME));
//		// 一連番号
//		strBuf.append(S_SEP_AN);
//		strBuf.append(ECNA0040001CBSMsg.CR_ORDERNUMBER);
//		strBuf.append(S_SEP_EQ);
//		strBuf.append(Long.valueOf(JCNejbOracleSeqParts.getSeqNo(inCBSMsg, inContext, "SEQ_CN_ORDERNUMBER", "5", 
//				inCBSMsg.getObject(ECNA0040001CBSMsg.FUNC_CODE))));
//		// 決済金額
//		strBuf.append(S_SEP_AN);
//		strBuf.append(ECNA0040001CBSMsg.CR_AMOUNT);
//		strBuf.append(S_SEP_EQ);
//		strBuf.append(inCBSMsg.getString(ECNA0040001CBSMsg.CR_AMOUNT));
//		// カード番号
//		strBuf.append(S_SEP_AN);
//		strBuf.append(ECNA0040001CBSMsg.CR_CARDNUMBER);
//		strBuf.append(S_SEP_EQ);
//		strBuf.append(inCBSMsg.getString(ECNA0040001CBSMsg.CR_CARDNUMBER));
//		// カード有効期限
//		strBuf.append(S_SEP_AN);
//		strBuf.append(ECNA0040001CBSMsg.CR_CARDEXP);
//		strBuf.append(S_SEP_EQ);
//		strBuf.append(inCBSMsg.getString(ECNA0040001CBSMsg.CR_CARDEXP));
//		// クレジット契約番号
//		// 値が設定されている場合のみパラメータ作成
//		if(inCBSMsg.getString(ECNA0040001CBSMsg.CR_CCID) != null)
//		{
//			strBuf.append(S_SEP_AN);
//			strBuf.append(ECNA0040001CBSMsg.CR_CCID);
//			strBuf.append(S_SEP_EQ);
//			strBuf.append(inCBSMsg.getString(ECNA0040001CBSMsg.CR_CCID));
//		}
//		// カード所有者名(入力パラメータは無視して空文字を設定)
//		strBuf.append(S_SEP_AN);
//		strBuf.append(ECNA0040001CBSMsg.CR_CARDOWNER);
//		strBuf.append(S_SEP_EQ);
//		strBuf.append(S_BLANK);
//		// 支払種別
//		// 値が設定されている場合のみパラメータ作成
//		if(inCBSMsg.getString(ECNA0040001CBSMsg.CR_PAYMODE) != null)
//		{
//			strBuf.append(S_SEP_AN);
//			strBuf.append(ECNA0040001CBSMsg.CR_PAYMODE);
//			strBuf.append(S_SEP_EQ);
//			strBuf.append(inCBSMsg.getString(ECNA0040001CBSMsg.CR_PAYMODE));
//		}
//		// 分割回数
//		if(inCBSMsg.getString(ECNA0040001CBSMsg.CR_PAYMODE_C) != null)
//		{
//			strBuf.append(S_SEP_AN);
//			strBuf.append(ECNA0040001CBSMsg.CR_PAYMODE_C);
//			strBuf.append(S_SEP_EQ);
//			strBuf.append(inCBSMsg.getString(ECNA0040001CBSMsg.CR_PAYMODE_C));
//		}
//		// 支払開始日
//		if(inCBSMsg.getString(ECNA0040001CBSMsg.CR_PAYMODE_A) != null)
//		{
//			strBuf.append(S_SEP_AN);
//			strBuf.append(ECNA0040001CBSMsg.CR_PAYMODE_A);
//			strBuf.append(S_SEP_EQ);
//			strBuf.append(inCBSMsg.getString(ECNA0040001CBSMsg.CR_PAYMODE_A));
//		}
//v19.00.00 2015/08/20 DEL End		
		
		JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JECNA0040001TPMA#reqParam=" + strBuf.toString());
		
//v19.00.02 2015/09/14 Add Start
		StringBuilder logStr = new StringBuilder(300);
		logStr.append("cmd="+CMD_EXEC + ",");                                                                        // コマンドタイプ  
		logStr.append("exec_type="+EXEC_TYPE_191 + ",");                                                             // 処理区分  
		logStr.append("connect_no="+JCMAPLConstMgr.getString(CN_CONNECT_NO) + ",");                                  // システム接続設定番号 
		logStr.append("connect_key="+JCMAPLConstMgr.getString(CN_CONNECT_KEY)+ ",");                                 // 接続キー 
		logStr.append("comp_cd="+JCMAPLConstMgr.getString(CN_COMP_CD)+ ",");                                         // グループコード 
		logStr.append("shop_cd="+JCMAPLConstMgr.getString(CN_SHOP_CD)+ ",");                                         // 事業者コード 
		logStr.append("card_brand_cd="+CARD_BRAND_CD_99 + ",");                                                      // カードブランド 
		logStr.append("card_no="+"***" + ",");                                                                       // カード番号 
		logStr.append("card_exp_date="+inCBSMsg.getString(ECNA0040001CBSMsg.CR_CARDEXP).replaceAll("/", "") + ",");  // カード有効期限 
		logStr.append("amount="+inCBSMsg.getString(ECNA0040001CBSMsg.CR_AMOUNT) + ",");                              // 決済金額 
		logStr.append("pay_type="+PAY_TYPE_10 + ",");                                                                // 支払区分 
		logStr.append("shop_mb_id="+makeShopMbName(inCBSMsg,inContext) + ",");                                       // 顧客ID 
//v22.00.00 2015/12/04 Add Start
		logStr.append("save_id ="+ inCBSMsg.getString(ECNA0040001CBSMsg.CR_SAVE_ID) + ",");                          // クレジットカード番号預りID
//v22.00.00 2015/12/04 Add End
//v19.00.02 2015/09/14 Add End
//ST-2018-0000007 ADD START
		if(!isNullBlank(inCBSMsg.getString(ECNA0040001CBSMsg.CR_TOKEN_USE))){
//ST-2018-0000007 ADD END
		//ANK-3313-00-00 ADD START v36.00.00
			logStr.append("token_use ="+ inCBSMsg.getString(ECNA0040001CBSMsg.CR_TOKEN_USE) + ",");                  // トークン利用区分
		//ANK-3313-00-00 ADD END v36.00.00
//ST-2018-0000007 ADD START
		}
//ST-2018-0000007 ADD END
//v19.00.00 2015/08/27 Add Start		
//v19.00.02 2015/09/14 Mod Start
//		JSYbpmLog.println(JSYLogBase.EXECUTION, this.getClass() ,
//				"クリアパス入力結果=" + strBuf.toString(), "",  new String[]{"", ""}, "");
		JSYbpmLog.println(JSYLogBase.EXECUTION, this.getClass() ,
				"クリアパス入力結果=" + logStr.toString(), "",  new String[]{"", ""}, "");
//v19.00.02 2015/09/14 Mod End
//v19.00.00 2015/08/27 Add End
		
		return strBuf.toString();
	}
	
	
	/**
	 * クリアパスAPI処理結果を格納する。
	 * @param inCBSMsg メッセージキャリア
	 * @param key レスポンスキー
	 * @param value レスポンスバリュー
	 */
//v19.00.00 2015/08/20 Mod Start
	//private void resultPut(CAANMsg inCBSMsg, String key, String value)
//v19.00.01 2015/09/03 Mod Start
//	private void resultPut(CAANMsg inCBSMsg, HashMap<String, String> resultMap)
	private void resultPut(CAANMsg inCBSMsg, Hashtable<String, Object> resultMap)
//v19.00.01 2015/09/03 Mod End
//v19.00.00 2015/08/20 Mod End
	{
//v19.00.00 2015/08/20 Del Start
//		// 処理結果コード
//		if(RESULT_CD.equals(key))
//		{
//			inCBSMsg.set(ECNA0040001CBSMsg.CR_RESULTCODE, value);
//		}
//		// 取引ID
//		if(ECNA0040001CBSMsg.CR_ORDERID.equals(key))
//		{
//			inCBSMsg.set(ECNA0040001CBSMsg.CR_ORDERID, value);
//		}
//		// 仕向先カード会社コード
//		if(ECNA0040001CBSMsg.CR_BRANDCODE.equals(key))
//		{
//			inCBSMsg.set(ECNA0040001CBSMsg.CR_BRANDCODE, value);
//		}
//		// 伝票番号
//		if(ECNA0040001CBSMsg.CR_SLIPNUMBER.equals(key))
//		{
//			inCBSMsg.set(ECNA0040001CBSMsg.CR_SLIPNUMBER, value);
//		}
//		// オーソリ承認番号
//		if(ECNA0040001CBSMsg.CR_AUTHNUMBER.equals(key))
//		{
//			inCBSMsg.set(ECNA0040001CBSMsg.CR_AUTHNUMBER, value);
//		}
//		// 決済金額
//		if(ECNA0040001CBSMsg.CR_PAIDAMOUNT.equals(key))
//		{
//			inCBSMsg.set(ECNA0040001CBSMsg.CR_PAIDAMOUNT, value);
//		}
//v19.00.00 2015/08/20 Del End
//v19.00.00 2015/08/20 Add Start
//v19.00.01 2015/09/03 Del Start
//		
//		//オーソリ結果変換部品インスタンスを作成
//		JCNAuthResultCdConvertUtil convertUtil = new JCNAuthResultCdConvertUtil(resultMap.get(RESULT_CD), 
//				  resultMap.get(RESULT_INFO_CD), 
//				  resultMap.get(ERR_CD), 
//				  resultMap.get(AUTH_RESULT), 
//				  resultMap.get(AUTH_RESULT_CD));
//		
//		// クリアパスより取得したコードを利用して、処理結果コードに変換し返却する
//		inCBSMsg.set(ECNA0040001CBSMsg.CR_RESULTCODE, convertUtil.convertResultCd());
//				
//		// 変換部品ログ
//		JSYejbLog.println(JSYejbLog.EXECUTION, this.getClass(),"処理結果コード変換ログ:"+ 
//																"結果コード="+resultMap.get(RESULT_CD)+
//																":詳細コード="+resultMap.get(RESULT_INFO_CD)+
//																":エラーコード="+resultMap.get(ERR_CD)+
//																":オーソリ結果="+resultMap.get(AUTH_RESULT)+
//																":オーソリ結果コード="+resultMap.get(AUTH_RESULT_CD)+
//																":処理結果コード="+convertUtil.convertResultCd());
//
//		//仕向先カード会社コードが存在していた場合、CBSMsgに設定する
//		if(!isNullBlank(resultMap.get(CARD_CORP_CD))){
//			// 仕向先カード会社コード
//			inCBSMsg.set(ECNA0040001CBSMsg.CR_BRANDCODE, resultMap.get(CARD_CORP_CD));
//		}
//		//オーソリ承認番号が存在していた場合、CBSMsgに設定する
//		if(!isNullBlank(resultMap.get(RECOGNIZED_NO))){
//		// オーソリ承認番号
//		inCBSMsg.set(ECNA0040001CBSMsg.CR_AUTHNUMBER, resultMap.get(RECOGNIZED_NO));
//		}
//v19.00.01 2015/09/03 Del End
//v19.00.00 2015/08/20 Add End
//v19.00.01 2015/09/03 Add Start

// ANK-3846-00-00 DEL START
//		//オーソリ結果変換部品インスタンスを作成
//		JCNAuthResultCdConvertUtil convertUtil = new JCNAuthResultCdConvertUtil((String)resultMap.get(RESULT_CD), 
//				(String)resultMap.get(RESULT_INFO_CD), 
//				(String)resultMap.get(ERR_CD), 
//				(String)resultMap.get(AUTH_RESULT), 
//				(String)resultMap.get(AUTH_RESULT_CD));
//		// クリアパスより取得したコードを利用して、処理結果コードに変換し返却する
//		inCBSMsg.set(ECNA0040001CBSMsg.CR_RESULTCODE, convertUtil.convertResultCd());
// ANK-3846-00-00 DEL END
// OM-2019-0000398 2019/05/22 ADD START
		String returnCRresultCode = inCBSMsg.getString(ECNA0040001CBSMsg.CR_RESULTCODE);
		// 処理結果コードがその他の場合、処理結果コードをカード事故・無効カードに変換する
		if(JCNStrConst.AUTH_RESULT_OTHER.equals(returnCRresultCode))
		{
			inCBSMsg.set(ECNA0040001CBSMsg.CR_RESULTCODE, JCNStrConst.AUTH_RESULT_CARDACCIDENT);
		}
// OM-2019-0000398 2019/05/22 ADD END
		// 変換部品ログ
		JSYejbLog.println(JSYejbLog.EXECUTION, this.getClass(),"処理結果コード変換ログ:"+ 
																"結果コード="+resultMap.get(RESULT_CD)+
																":詳細コード="+resultMap.get(RESULT_INFO_CD)+
																":エラーコード="+resultMap.get(ERR_CD)+
																":オーソリ結果="+resultMap.get(AUTH_RESULT)+
																":オーソリ結果コード="+resultMap.get(AUTH_RESULT_CD)+
// OM-2019-0000398 2019/05/22 MOD START
//																":処理結果コード="+convertUtil.convertResultCd());
																":処理結果コード="+inCBSMsg.getString(ECNA0040001CBSMsg.CR_RESULTCODE));
// OM-2019-0000398 2019/05/22 MOD END

		//仕向先カード会社コードが存在していた場合、CBSMsgに設定する
		if(!isNullBlank((String)resultMap.get(CARD_CORP_CD))){
			// 仕向先カード会社コード
			inCBSMsg.set(ECNA0040001CBSMsg.CR_BRANDCODE, resultMap.get(CARD_CORP_CD));
		}
		//オーソリ承認番号が存在していた場合、CBSMsgに設定する
		if(!isNullBlank((String)resultMap.get(RECOGNIZED_NO))){
		// オーソリ承認番号
		inCBSMsg.set(ECNA0040001CBSMsg.CR_AUTHNUMBER, resultMap.get(RECOGNIZED_NO));
		}
//v19.00.01 2015/09/03 Add End
		
		// v20.00.00 2015/09/09 ANK-2586-00-00 Add Start
		//クリアパス取引IDが存在していた場合、CBSMsgに設定する
		if(!isNullBlank((String)resultMap.get(CP_TRAN_ID)))
		{
			// クリアパス取引ID
			inCBSMsg.set(ECNA0040001CBSMsg.CR_ORDERID, resultMap.get(CP_TRAN_ID));
			JSYejbLog.println(JSYejbLog.EXECUTION, this.getClass(),"クリアパス取引ID:"+ (String)resultMap.get(CP_TRAN_ID));
		}
		// v20.00.00 2015/09/09 ANK-2586-00-00 Add End
		
		//v22.00.00 2015/11/20 Add Start
		
		//カード預かりIDが存在していた場合、CBSMsgに設定する
		if(!isNullBlank((String)resultMap.get(SAVE_ID)))
		{
			// クリアパス取引ID
			inCBSMsg.set(ECNA0040001CBSMsg.SAVE_ID, resultMap.get(SAVE_ID));
			JSYejbLog.println(JSYejbLog.EXECUTION, this.getClass(),"クリアパス取引ID:"+ (String)resultMap.get(SAVE_ID));
		}
		
		//v22.00.00 2015/11/20 Add End
		
		//v23.00.00 2016/02/29 Add Start
		if(!isNullBlank((String)resultMap.get(INQUIRE_CARD_NO)))
		{
			// 問合せ用カード番号
			inCBSMsg.set(ECNA0040001CBSMsg.CR_CARDNUMBER, resultMap.get(INQUIRE_CARD_NO));
			JSYejbLog.println(JSYejbLog.EXECUTION, this.getClass(),"問合せ用カード番号:"+ (String)resultMap.get(INQUIRE_CARD_NO));
		}
		//v23.00.00 2016/02/29 Add End
		
		//ANK-3313-00-00 ADD START v34.00.00
		if(!isNullBlank((String)resultMap.get(UNIQUE_CD)))
		{
			// カード識別コード
			inCBSMsg.set(ECNA0040001CBSMsg.CR_UNIQUE_CD, resultMap.get(UNIQUE_CD));
			JSYejbLog.println(JSYejbLog.EXECUTION, this.getClass(),"カード識別コード:"+ (String)resultMap.get(UNIQUE_CD));
		}

		if(!isNullBlank((String)resultMap.get(CARD_BRAND_OPTCD)))
		{
			// カードブランド(K-OPT)
			inCBSMsg.set(ECNA0040001CBSMsg.CR_CARD_BRAND_OPTCD, resultMap.get(CARD_BRAND_OPTCD));
			JSYejbLog.println(JSYejbLog.EXECUTION, this.getClass(),"カードブランド(K-OPT):"+ (String)resultMap.get(CARD_BRAND_OPTCD));
		}
		//ANK-3313-00-00 ADD END v34.00.00
		
		// ANK-3602-01-00 2019/08/06 ADD START
		if(!isNullBlank((String)resultMap.get(CARD_TYPE)))
		{
			// カード種別
			inCBSMsg.set(ECNA0040001CBSMsg.CR_CARD_TYPE, resultMap.get(CARD_TYPE));
			JSYejbLog.println(JSYejbLog.EXECUTION, this.getClass(),"カード種別:"+ (String)resultMap.get(CARD_TYPE));
		}

		if(!isNullBlank((String)resultMap.get(ISSUER_CLASS)))
		{
			// イシュア区分
			inCBSMsg.set(ECNA0040001CBSMsg.CR_ISSUER_CLASS, resultMap.get(ISSUER_CLASS));
			JSYejbLog.println(JSYejbLog.EXECUTION, this.getClass(),"イシュア区分:"+ (String)resultMap.get(ISSUER_CLASS));
		}
		// ANK-3602-01-00 2019/08/06 ADD END
		return;
	}
	
	/**
	 * パスワード復合化処理
	 * @param strPassWd パスワード
	 * @return resultPassWd 暗号化済パスワード
	 * @throws Throwable
	 */
	private String decriptPassWd(String strPassWd) throws Exception
	{
		String resultPassWd = "";
		
		resultPassWd = 
			JCCModelCommon.getDecryptResultPassword(strPassWd);
		
		return resultPassWd;
	}
	
//v19.00.00 2015/08/20 Add Start
	
	private String makeShopMbName(CAANMsg inCBSMsg,AgentDispatchContext inContext){
		
		StringBuffer strBuf = new StringBuffer(150);
		
		//取引年月日
		strBuf.append(inCBSMsg.getString(ECNA0040001CBSMsg.CR_ORDERDATE));
		strBuf.append(inCBSMsg.getString(ECNA0040001CBSMsg.CR_ORDERTIME));
		strBuf.append(Long.valueOf(JCNejbOracleSeqParts.getSeqNo(inCBSMsg, inContext, "SEQ_CN_ORDERNUMBER", "5", 
				inCBSMsg.getObject(inCBSMsg.getString(ECNA0040001CBSMsg.FUNC_CODE)))));
		
		
		return strBuf.toString();
	}
	
	/**
	 * null又は空文字の場合、trueを返却する
	 * 
	 * @param str 検査対象文字列
	 * @return true:null、又は空文字／false:左記以外
	 */
	public static boolean isNullBlank(String str)
	{
		if (null == str || "".equals(str))
		{
			return true;
		}
		return false;
	}
//v19.00.00 2015/08/20 Add End
	

	
//v19.00.01 2015/09/03 Add Start
		/**
		 * 電文読み込み処理
		 * @param soapResponse
		 * @return XML電文解析結果
		 * @throws IOException
		 * @throws ParserConfigurationException
		 * @throws SAXException
		 */
		private Hashtable<String, Object> read(Document soapResponse) 
		throws IOException,ParserConfigurationException,SAXException
		{
			// レスポンス解析
			Element root =  soapResponse.getDocumentElement();//ルート要素(<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(JECNA0040001TPMA.SOAP_FAULT_CODE.equals(nodename.toLowerCase()))
					{
						Node child = node.getFirstChild();
						if(child != null)
						{
							errmsg = errmsg + "エラーコード：" + child.getTextContent();
						}
					}
					if(JECNA0040001TPMA.SOAP_FAULT_STRING.equals(nodename.toLowerCase()))
					{
						errmsg = errmsg + "エラー詳細：" + node.getTextContent();
					}
				}
				
				node = node.getNextSibling();
			}
			
			return errmsg;
		}
		
		/**
		 * コマンド送信戻り電文解析処理
		 * @param elem コマンド解析電文rootXML要素
		 * @param rootflag ルートフラグ
		 * @return XML解析結果
		 */
		public Hashtable 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.outlog(null, JSYejbLog.DEBUG , this.getClass(), 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(JECNA0040001TPMA.SOAP_FAULT.equals(nodename.toLowerCase()) || JECNA0040001TPMA.SOAP_FAULT.equals(childname.toLowerCase()))
					{
						resultMap = new Hashtable<String, Object>();
						String faultinfo = analyzeFaultXml(node);
						resultMap.put(JECNA0040001TPMA.CMD_RESULT_CD,"1");
						resultMap.put(JECNA0040001TPMA.CMD_ERROR_MESSAGE,faultinfo);	
						return resultMap;
					}
					else
					{
						if(resultMap == null) {
							resultMap = new Hashtable<String, Object>();
						}
						Hashtable<String, Object>resultinfo = analyzeXml(node, false);
						if(JECNA0040001TPMA.RECORD.equals(nodename) || JECNA0040001TPMA.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>();
				}
				
				resultMap.put(JECNA0040001TPMA.CMD_RESULT_CD,"0");
				return resultMap;
			}
			
			return resultMap;
		}
		
//v19.00.01 2015/09/03 Add End
//v19.00.02 2015/09/11 Add Start
		/**
		 * クリアパスからの返却結果をログに出力するため編集を行う
		 * 編集内容
		 *   key名がカード番号(card_no)の場合はマスキング処理を行う
		 * @param ret クリアパスからの返却結果
		 * @return ログ出力用文字列
		 */
		private String makeLogStr(Hashtable<String, Object> ret){
		
			//ログ用文字列組み立て用の変数を宣言する
			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);
				
				//keyがカード番号（card_no)の場合value(カード番号）をマスキングする
				if(INQUIRE_CARD_NO.equals(key)){
					value = "***";
				}
		
				//カード番号以外の場合は、返却結果のそのまま出力する
				sb.append(key + "=" + value + ",");
				
			}
			
		
			return sb.toString();
		}
//v19.00.02 2015/09/11 Add End

}
