/*********************************************************************
*	All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*	システム名		：eo顧客基幹システム
*	モジュール名	：JKKejbKKA0010002SecProc
*	ソースファイル名：JKKejbKKA0010002SecProc.java
*	作成者			：富士通
*	日付			：2015年11月4日
*＜機能概要＞
*	クレジットカード情報一覧照会に対する副次処理を行う部品です。
*＜修正履歴＞
*	バージョン	修正日		修正者		修正内容
*   v20.00.00    2015/11/24   FJ）原田    新規作成
*
**********************************************************************/

package eo.ejb.common.db;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.StringWriter;
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.Iterator;
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.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.common.JSYLogBase;
import com.fujitsu.futurity.common.JSYbpmLog;
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.common.util.JCNAuthResultCdConvertUtil;
import eo.ejb.cbs.cbsmsg.EKKA0010001CBSMsg;
import eo.ejb.cbs.cbsmsg.EKKA0010002CBSMsg;
import eo.ejb.cbs.cbsmsg.EKKA0010002CBSMsg1List;
import eo.ejb.common.JCCModelCommon;
import eo.ejb.common.JKKModelCommon;

/**
 * <p>
 * 初回オーソリに対する副次処理を行う部品です。
 * </p>
 * @author 富士通
 */
public class JKKejbKKA0010002SecProc
{

	/** 部品ID */
	public static final String PGID = "JKKejbKKA0010002SecProc";
	
	/** パラメータセパレート文字:= */
	private 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";
	
	/** 文字コード */
	private static final String S_CHR_CODE = "UTF-8";
	
	/** クリアパスAPIシステムエラー */
	private static final String S_AUTH_SYSERR = "9000000";
	
	/** 通信方式SSL */
	private static final String S_HTTPS = "https";


	
	/** コマンドタイプ */
	private static final String CMD = "cmd";
	
	/** 預かり状態 */
	private static final String SAVE_STATUS = "save_status";
	
	/** システム接続設定番号 */
	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";
	
	/** 照会フラグ */
	private static final String INQ_CARD = "inq_card";
	
	/** カード預かりID */
	private static final String SAVE_ID = "save_id";
	
	/** カード番号(送信時),カード情報(受信時) */
	private static final String CARD_CD = "card_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_BRAND_CD = "card_brand_cd";
	
	/** 決済タイプ */
	private static final String SETTLE_TYPE = "settle_type";
	
	/** 支払区分 */
	private static final String CARD_INFO = "card_info";
	
	/** 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";
	
	/**
	 * コマンド実行結果
	 */
    public static final String CMD_RESULT_CD = "CMD_RESULT_CD";
    
    /**
	 * レコード
	 */
    public static final String RESULT = "result";
    
    /**
	 * サービス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";
    
	/**
	 * コンストラクタ.
	 */
	public JKKejbKKA0010002SecProc()
	{
		super();
	}

	/**
	 * クリアパスHTTPSリクエスト独自処理部品です。
	 * @ccMsg ccMsg CAANメッセージ
	 * @ccMsg inContext コンテキスト
	 * @throws Exception 
	 */
	public void searchCredit(CAANMsg msgList, AgentDispatchContext inContext) throws Exception
	{
		// 開始ログ出力を実施。
		JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JKKejbKKA0010002SecProc#searchCredit start");
		
		HttpURLConnection conn = null;
		URL url = null;
		
		try
		{
			//system.properties設定値取得
			String strUrl = JCMAPLConstMgr.getString("CLARIS_CLEARPASS_URL");
			String strApiNm = JCMAPLConstMgr.getString("CLARIS_CLEARPASS_APINAME");
			int timeout = Integer.parseInt(JCMAPLConstMgr.getString("CN_CLEARPASS_TIMEOUT"));
			int retryCount = Integer.parseInt(JCMAPLConstMgr.getString("CN_CLEARPASS_RETRYCOUNT"));
			int retryInterval = Integer.parseInt(JCMAPLConstMgr.getString("CN_CLEARPASS_RETRYINTERVAL"));	
			
			// 通信方式判定
			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スタブメソッド
					 * @ccMsg arg0
					 * @ccMsg arg1
					 * @throws CertificateException
					 */
					public void checkClientTrusted(
							java.security.cert.X509Certificate[] arg0, String arg1)
							throws CertificateException 
					{
					}
	
					/**
					 * checkServerTrustedスタブメソッド
					 * @ccMsg arg0
					 * @ccMsg 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スタブメソッド
					 * @ccMsg aHostname
					 * @ccMsg aSession
					 * @return クリアパスAPIへのリクエストパラメータ
					 */
					public boolean verify(String aHostname, SSLSession aSession) 
					{
						return true;
					}
				});
				HttpsURLConnection.setDefaultSSLSocketFactory(sslcontext.getSocketFactory());
			}
			
			// URL生成
			url = new URL(strUrl + strApiNm);
			// リクエスト結果読込用ストリーム
			InputStream is = null;
			
			for(int i = 0 ; i < retryCount ; i++)
			{
				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(requestccMsgMake(msgList));
					ps.close();
					
					
					// 接続開始ログ
					JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JKKejbKKA0010002SecProc#connect start");
					
					// 接続実行
					conn.connect();
					
					// 接続終了ログ
					JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JKKejbKKA0010002SecProc#connect end");
					
					int statusCode = 500;
					statusCode = conn.getResponseCode();

					JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JKKejbKKA0010002SecProc#statusCode=" + statusCode);
					
					
					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();
					
					//XML形式
					transformer.setOutputProperty(OutputKeys.METHOD, "xml");
					
					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");
					
					StringBuffer sb = new StringBuffer();
					sb.append("クリアパス出力結果=statusCode=");
					sb.append(statusCode);
					
					JSYbpmLog.println(JSYLogBase.EXECUTION, this.getClass() ,sb, "",  new String[]{"", ""}, "");
					resultPut(msgList, ret);
					

					// 通信レスポンスコードが異常だった場合は処理結果にシステムエラーを設定
					if (200 != (statusCode))
					{
						msgList.set(EKKA0010002CBSMsg.SEARCH_ERR_FLG, S_AUTH_SYSERR);
					}
					
				}
				catch(HTTPException he)
				{
					msgList.set(EKKA0010002CBSMsg.SEARCH_ERR_FLG, 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(),"#JKKejbKKA0010002SecProc(HTTPException)発生" + sb.toString());
					
					// リトライ
					if(i < retryCount)
					{
						// スリープ開始ログ
						JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JKKejbKKA0010002SecProc#sleep start");
						// スリープ処理
						Thread.sleep(retryInterval);
						// スリープ終了ログ
						JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JKKejbKKA0010002SecProc#sleep end");
						// リトライカウントログ
						JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JKKejbKKA0010002SecProc#retryCount="
								+ i);
						continue;
					}
					else
					{
						throw he;
					}
				}
				catch(IOException ie)
				{
					msgList.set(EKKA0010002CBSMsg.SEARCH_ERR_FLG, 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(),"#JKKejbKKA0010002SecProc(IOException)発生" + sb.toString());
					
					// リトライ
					if(i < retryCount)
					{
						// スリープ開始ログ
						JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JKKejbKKA0010002SecProc#sleep start");
						// スリープ処理
						Thread.sleep(retryInterval);
						// スリープ終了ログ
						JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JKKejbKKA0010002SecProc#sleep end");
						// リトライカウントログ
						JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JKKejbKKA0010002SecProc#retryCount="
								+ i);
						continue;
					}
					else
					{
						throw ie;
					}
				}				
				finally
				{
					if(is != null)
					{
						is.close();
						is = null;
					}
				}
				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(),"#JKKejbKKA0010002SecProc(Exception)発生" + sb.toString());
			
			msgList.set(EKKA0010002CBSMsg.SEARCH_ERR_FLG, S_AUTH_SYSERR);
			return;
		}
		finally
		{
			if (conn != null)
			{
				//切断処理
				conn.disconnect();
				conn = null;
			}
			
			// 処理結果ログ出力
			JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JKKejbKKA0010002SecProc#RESULT_CD=" + 
					msgList.getString(EKKA0010002CBSMsg.RESULT_CD));	// 結果コード
		}
		
		JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JKKejbKKA0010002SecProc#searchCredit end");
	}

	/**
	 * クリアパスAPIに対して送信するリクエストパラメータを作成する。
	 * @ccMsg ccMsg メッセージキャリア
	 * @return クリアパスAPIへのリクエストパラメータ
	 */
	private String requestccMsgMake(CAANMsg ccMsg)
	{

		// リクエストパラメータ作成(CBSMsgより読み出し)
		StringBuffer strBuf = new StringBuffer();

		// コマンドタイプ
		strBuf.append(CMD);
		strBuf.append(S_SEP_EQ);
		strBuf.append("SAVEINFO");
		// システム接続設定番号
		strBuf.append(S_SEP_AN);
		strBuf.append(CONNECT_NO);
		strBuf.append(S_SEP_EQ);
		strBuf.append(ccMsg.getString(EKKA0010002CBSMsg.CONNECT_NO));
		// 接続キー
		strBuf.append(S_SEP_AN);
		strBuf.append(CONNECT_KEY);
		strBuf.append(S_SEP_EQ);
		strBuf.append(ccMsg.getString(EKKA0010002CBSMsg.CONNECT_KEY));
		// グループコード
		strBuf.append(S_SEP_AN);
		strBuf.append(COMP_CD);
		strBuf.append(S_SEP_EQ);
		strBuf.append(ccMsg.getString(EKKA0010002CBSMsg.COMP_CD));
		// 事業者コード
		strBuf.append(S_SEP_AN);
		strBuf.append(SHOP_CD);
		strBuf.append(S_SEP_EQ);
		strBuf.append(ccMsg.getString(EKKA0010002CBSMsg.SHOP_CD));
		// 照会フラグ
		strBuf.append(S_SEP_AN);
		strBuf.append(INQ_CARD);
		strBuf.append(S_SEP_EQ);
		strBuf.append(ccMsg.getString(EKKA0010002CBSMsg.INQ_CARD));
		// カード番号
		strBuf.append(S_SEP_AN);
		strBuf.append(CARD_CD);
		strBuf.append(S_SEP_EQ);
		if(ccMsg.getString(EKKA0010002CBSMsg.CARD_CD) != null)
		{
			strBuf.append(ccMsg.getString(EKKA0010002CBSMsg.CARD_CD));
		}
		else
		{
			strBuf.append("");
		}
		// カード預りＩＤ
		strBuf.append(S_SEP_AN);
		strBuf.append(SAVE_ID);
		strBuf.append(S_SEP_EQ);
		if(ccMsg.getString(EKKA0010002CBSMsg.SAVE_ID) != null)
		{
			strBuf.append(ccMsg.getString(EKKA0010002CBSMsg.SAVE_ID));
		}
		else
		{
			strBuf.append("");
		}
		// ＩＰアドレス
		strBuf.append(S_SEP_AN);
		strBuf.append(IP_ADDRESS);
		strBuf.append(S_SEP_EQ);
		strBuf.append("");
		
		JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JKKejbKKA0010002SecProc#reqccMsg=" + strBuf.toString());

		StringBuilder logStr = new StringBuilder(300);
		logStr.append(CMD + "=");
		logStr.append("SAVEINFO" + ",");
		logStr.append(CONNECT_NO + "=");
		logStr.append(ccMsg.getString(EKKA0010002CBSMsg.CONNECT_NO) + ",");
		logStr.append(CONNECT_KEY + "=");
		logStr.append(ccMsg.getString(EKKA0010002CBSMsg.CONNECT_KEY) + ",");
		logStr.append(COMP_CD + "=");
		logStr.append(ccMsg.getString(EKKA0010002CBSMsg.COMP_CD) + ",");
		logStr.append(SHOP_CD + "=");
		logStr.append(ccMsg.getString(EKKA0010002CBSMsg.SHOP_CD) + ",");
		logStr.append(INQ_CARD + "=");
		logStr.append(ccMsg.getString(EKKA0010002CBSMsg.INQ_CARD) + ",");
		logStr.append(CARD_CD + "=");
		logStr.append(ccMsg.getString(EKKA0010002CBSMsg.CARD_CD) + ",");
		logStr.append(SAVE_ID + "=");
		logStr.append(ccMsg.getString(EKKA0010002CBSMsg.SAVE_ID) + ",");
		logStr.append(IP_ADDRESS + "=");
		logStr.append("");

		JSYbpmLog.println(JSYLogBase.EXECUTION, this.getClass() ,
				"クリアパス入力結果=" + logStr.toString(), "",  new String[]{"", ""}, "");
		return strBuf.toString();
	}
	
	/**
	 * XMLFAULT電文解析処理
	 * 
	 * @ccMsg 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(JKKejbKKA0010002SecProc.SOAP_FAULT_CODE.equals(nodename.toLowerCase()))
				{
					Node child = node.getFirstChild();
					if(child != null)
					{
						errmsg = errmsg + "エラーコード：" + child.getTextContent();
					}
				}
				if(JKKejbKKA0010002SecProc.SOAP_FAULT_STRING.equals(nodename.toLowerCase()))
				{
					errmsg = errmsg + "エラー詳細：" + node.getTextContent();
				}
			}
			
			node = node.getNextSibling();
		}
		
		return errmsg;
	}
	
	/**
	 * コマンド送信戻り電文解析処理
	 * @ccMsg elem コマンド解析電文rootXML要素
	 * @ccMsg 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.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(JKKejbKKA0010002SecProc.SOAP_FAULT.equals(nodename.toLowerCase()) || JKKejbKKA0010002SecProc.SOAP_FAULT.equals(childname.toLowerCase()))
				{
					resultMap = new Hashtable<String, Object>();
					String faultinfo = analyzeFaultXml(node);
					resultMap.put(JKKejbKKA0010002SecProc.CMD_RESULT_CD,"1");
					resultMap.put(JKKejbKKA0010002SecProc.CMD_ERROR_MESSAGE,faultinfo);	
					return resultMap;
				}
				else
				{
					if(resultMap == null) {
						resultMap = new Hashtable<String, Object>();
					}
					Hashtable<String, Object> resultinfo = analyzeXml(node, false);
					if(JKKejbKKA0010002SecProc.CARD_INFO.equals(nodename) || JKKejbKKA0010002SecProc.RESULT.equals(nodename))
					{
						if(resultinfo != null && !resultinfo.isEmpty())
						{
							Bodynodelist.add(resultinfo);
						}
						
						resultMap.put(nodename,Bodynodelist);
					
					}
					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(JKKejbKKA0010002SecProc.CMD_RESULT_CD,"0");
			return resultMap;
		}
		
		return resultMap;
	}

	
	/**
	 * 電文読み込み処理
	 * @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;
	}
	
	/**
	 * クリアパスからの返却結果をログに出力するため編集を行う
	 * 編集内容
	 *   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);
			
			//カード番号以外の場合は、返却結果のそのまま出力する
			sb.append(key + "=" + value + ",");
			
		}
		
	
		return sb.toString();
	}
	
	
	/**
	 * クリアパスAPI処理結果を格納する。
	 * @param msgList メッセージキャリア
	 * @param key レスポンスキー
	 * @param value レスポンスバリュー
	 */
	private void resultPut(CAANMsg msgList, Hashtable<String, Object> resultMap){
			
	// 変換部品ログ
	JSYejbLog.println(JSYejbLog.EXECUTION, this.getClass(),"処理結果コード変換ログ:"+ 
					"結果コード="+resultMap.get(RESULT_CD)+
					":詳細コード="+resultMap.get(RESULT_INFO_CD)+
					":エラーコード="+resultMap.get(ERR_CD));

	//結果コードが存在していた場合、msgListに設定する
	if(!isNullBlank((String)resultMap.get(RESULT_CD))){
		// 結果コード
		msgList.set(EKKA0010002CBSMsg.RESULT_CD, resultMap.get(RESULT_CD));
	}
	//詳細コードが存在していた場合、msgListに設定する
	if(!isNullBlank((String)resultMap.get(RESULT_INFO_CD))){
		// 詳細コード
		msgList.set(EKKA0010002CBSMsg.RESULT_INFO_CD, resultMap.get(RESULT_INFO_CD));
	}
	//エラーコードが存在していた場合、msgListに設定する
	if(!isNullBlank((String)resultMap.get(ERR_CD))){
		// エラーコード
		msgList.set(EKKA0010002CBSMsg.ERR_CD, resultMap.get(ERR_CD));
	}
	
	CAANMsg[] l_EKKA0010002csvmsg1list = null;
	ArrayList<Hashtable<String, Object>> result = (ArrayList<Hashtable<String, Object>>)resultMap.get(RESULT);
	ArrayList<Hashtable<String, Object>> list = (ArrayList<Hashtable<String, Object>>)result.get(0).get(CARD_INFO);
	
	if(list != null && !list.isEmpty()) {
		
		l_EKKA0010002csvmsg1list =  new CAANMsg[list.size()];
		
		for(int i=0;i<list.size();i++)
		{
			Hashtable<String, Object> data = list.get(i);
			CAANMsg msg = new CAANMsg("eo.ejb.cbs.cbsmsg.EKKA0010002CBSMsg1List");
			
			l_EKKA0010002csvmsg1list[i] = msg;
			msg.set(EKKA0010002CBSMsg1List.SAVE_STATUS, data.get(SAVE_STATUS));
			msg.set(EKKA0010002CBSMsg1List.CARD_CD, data.get(CARD_CD));
			msg.set(EKKA0010002CBSMsg1List.SAVE_ID, data.get(SAVE_ID));
			msg.set(EKKA0010002CBSMsg1List.CARD_BRAND_CD, data.get(CARD_BRAND_CD));
			msg.set(EKKA0010002CBSMsg1List.CARD_NO, data.get(CARD_NO));
			msg.set(EKKA0010002CBSMsg1List.CARD_EXP_DATE, data.get(CARD_EXP_DATE));
			msg.set(EKKA0010002CBSMsg1List.CARD_USER_NAME, data.get(CARD_USER_NAME));
			msg.set(EKKA0010002CBSMsg1List.SETTLE_TYPE, data.get(SETTLE_TYPE));
		}
		
		msgList.set(EKKA0010002CBSMsg.EKKA0010002CBSMSG1LIST, l_EKKA0010002csvmsg1list);
		
		
	}
	return;
}
	
	
	/**
	 * null又は空文字の場合、trueを返却する
	 * 
	 * @ccMsg str 検査対象文字列
	 * @return true:null、又は空文字／false:左記以外
	 */
	public static boolean isNullBlank(String str)
	{
		if (null == str || "".equals(str))
		{
			return true;
		}
		return false;
	}


}
