/*********************************************************************
 * All Rights reserved,Copyright (c) K-Opticom
 **********************************************************************
 *＜プログラム内容＞
 *   システム名      ：eo顧客基幹システム
 *   モジュール名    ：JCNCtrlTrustDockConnectInfoImpl
 *   ソースファイル名：JCNCtrlTrustDockConnectInfoImpl.java
 *   作成者          ：富士通
 *   日付            ：2024年02月09日
 *＜機能概要＞
 *   TRUSTDOCK連携接続処理部品です。
 *＜修正履歴＞
 *   バージョン  修正日       修正者      修正内容
 *   v70.00.00	2024/02/09	 FJ) 張	 【ANK-4538-00-00】LaLaCall契約時の本人確認必須化
 *   
 **********************************************************************/
package eo.ejb.common;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.httpclient.HostConfiguration;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.json.JSONException;
import org.json.JSONObject;

import com.fasterxml.jackson.databind.ObjectMapper;

import com.fujitsu.futurity.model.base.CAANMsg;
import com.fujitsu.futurity.model.common.JCMAPLConstMgr;
import com.fujitsu.futurity.model.ejb.common.JSYejbLog;

import com.fasterxml.jackson.databind.JsonNode;


public class JCNCtrlTrustDockConnectInfoImpl{
	
	/** 接続情報 */
	public static final String CONNECTINFO = "connectInfo";
	/** 接続情報 接続モード */
	public static final String CONNECTINFO_CONNECTMODE = "connectMode";
	/** 接続情報 接続URL */
	public static final String CONNECTINFO_URL = "URL";
	/** 接続情報 接続APIID */
	public static final String CONNECTINFO_APIID = "APIID";
	/** 接続情報 接続メソッド */
	public static final String CONNECTINFO_CONNECTMETHOD = "connectMethod";
	/** 接続情報 タイムアウト時間 */
	public static final String CONNECTINFO_TIMEOUT = "timeout";
	/** 接続情報 リトライカウント */
	public static final String CONNECTINFO_RETRYCOUNT = "retryCount";
	/** 接続情報 リトライインターバル */
	public static final String CONNECTINFO_RETRYINTERVAL = "retryInterval";
	
	/** リクエスト情報 */
	public static final String REQINFO = "reqInfo";
	/** リクエスト情報 body */
	public static final String REQINFO_BODY = "body";
	
	/** 接続結果 */
	public static final String CONNECTRESULT = "connectResult";
	/** 接続結果 httpstats */
	public static final String CONNECTRESULT_HTTPSTATUS = "httpStatus";
	
	/** レスポンス情報 */
	public static final String RESINFO = "resInfo";
	/** レスポンス情報 body */
	public static final String RESINFO_BODY = "body";
	
	/** TRUSTDOCK接続モード（本番） */
	private static final String TRUSTDOCK_SYSTEM = "0";
	
	/** TRUSTDOCK接続モード（スタブ） */
	private static final String TRUSTDOCK_STUB = "1";
	
	/** APLConst：TRUSTDOCKアクセストークン */
	private static final String TRUSTDOCK_ACCESSTOKEN = "TRUSTDOCK_ACCESSTOKEN";
	
	/** APLConst：TRUSTDOCKテストディレクトリ */
	private static final String TRUSTDOCK_CONNECTION_MODE_TEST_DIR = "TRUSTDOCK_CONNECTION_MODE_TEST_DIR";
	
	/** スタブ利用時のスタブファイル名を指定 */
	private static final Map<String, String> STUB_FILE_MAP = new HashMap<String, String>();

	/** スタブ利用時のHTTPステータスを指定 */
	private static final Map<String, String> STUB_HTTPSTAT_MAP = new HashMap<String, String>();
	
	/** スタブ利用時でのファイル取得時の実行結果を指定 */
	private static final Map<String, String> NOT_EXITS_FILE_RESULT_MAP = new HashMap<String, String>();

	/** スタブ利用時でのファイル取得時のHTTPステータスを指定 */
	private static final Map<String, String> NOT_EXITS_FILE_HTTPSTAT_MAP = new HashMap<String, String>();

	/**
	 * HTTPヘッダ Conten-TYPE（値）
	 */
	protected static final String CONTENT_TYPE_VALUE = "application/json";
	
	/**
	 * ＡＰＩＩＤとサービスの対応表をセットする
	 */
	static
	{
		/**
		 * APIIDとスタブファイル名の対応表をセットする
		 */
		
		STUB_FILE_MAP.put("CNIFE060", "TRUSTDOCK_CNIFE060_STUB.json"); 
		STUB_FILE_MAP.put("CNIFE061", "TRUSTDOCK_CNIFE061_STUB.json"); 
		STUB_FILE_MAP.put("CNIFE062", "TRUSTDOCK_CNIFE062_STUB.jpg"); 

		/**
		 * APIIDとスタブHTTPステータスの対応表をセットする
		 */
		STUB_HTTPSTAT_MAP.put("CNIFE060", "TRUSTDOCK_CNIFE060_HTTP_STAT_CD"); 
		STUB_HTTPSTAT_MAP.put("CNIFE061", "TRUSTDOCK_CNIFE061_HTTP_STAT_CD"); 
		STUB_HTTPSTAT_MAP.put("CNIFE062", "TRUSTDOCK_CNIFE062_HTTP_STAT_CD"); 
		
		
		/**
		 * APIIDとスタブファイルが存在しない場合の実行結果の対比表をセットする。
		 */
		
		NOT_EXITS_FILE_RESULT_MAP.put("CNIFE060", "?"); 
		NOT_EXITS_FILE_RESULT_MAP.put("CNIFE061", "?"); 
		NOT_EXITS_FILE_RESULT_MAP.put("CNIFE062", "?"); 
		
		
		/**
		 * APIIDとスタブファイルが存在しない場合のHTTPステータスの対比表をセットする。 
		 */
		NOT_EXITS_FILE_HTTPSTAT_MAP.put("CNIFE060", "200"); 
		NOT_EXITS_FILE_HTTPSTAT_MAP.put("CNIFE061", "200"); 
		NOT_EXITS_FILE_HTTPSTAT_MAP.put("CNIFE062", "200"); 
		
	}
	
	/** TRUSTDOCK文字コード */
	private static final String TRUSTDOCK_ENCODING = "UTF-8";
	
	/**
	 * 連携されたパラメータより、本番接続またはスタブ接続を判定し処理結果を返却する。
	 * @param inCBSMsg CAANメッセージ
	 * @throws Exception 
	 */
	public Hashtable<String, Object> ctrlTrustDockConnect(CAANMsg inCBSMsg) throws Exception
	{
		// 開始ログ出力を実施。
		JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JCNCtrlTrustDockConnectInfoImpl#ctrlTrustDockConnect start");
		
		// CAANメッセージより「接続情報」「リクエスト情報」を取得
		Object connect = inCBSMsg.getObject(CONNECTINFO);
		Object req = inCBSMsg.getObject(REQINFO);
		
		HashMap<String,Object> connectInfo = (HashMap<String, Object>) connect;
		HashMap<String,Object> reqInfo = (HashMap<String, Object>) req;
		
		// 接続情報を取得する
		// 接続モード
		String connectMode = (String) connectInfo.get(CONNECTINFO_CONNECTMODE);
		// 接続URL
		String url = (String) connectInfo.get(CONNECTINFO_URL);
		// 接続APIID
		String apiId = (String) connectInfo.get(CONNECTINFO_APIID);
		// 接続メソッド
		String connectMethod = (String) connectInfo.get(CONNECTINFO_CONNECTMETHOD);
		// タイムアウト時間
		String timeout = (String) connectInfo.get(CONNECTINFO_TIMEOUT);
		// リトライカウント
		String retryCount = (String) connectInfo.get(CONNECTINFO_RETRYCOUNT);
		// リトライインターバル
		String retryInterval = (String) connectInfo.get(CONNECTINFO_RETRYINTERVAL);
		
		// リクエストを取得する
		Map<String, Object> body = (Map<String, Object>) reqInfo.get(REQINFO_BODY);
		
		// 接続情報をログに出力
		JSYejbLog.println(JSYejbLog.EXECUTION, JCNCtrlTrustDockConnectInfoImpl.class , "JCNCtrlTrustDockConnectInfoImpl" + apiId + "#接続情報 : " + connectInfo);
		// リクエスト情報をログに出力
		JSYejbLog.println(JSYejbLog.EXECUTION, JCNCtrlTrustDockConnectInfoImpl.class , "JCNCtrlTrustDockConnectInfoImpl" + apiId + "#リクエスト情報 : " + reqInfo);
		
		// 結果格納用のMAPを用意
		Hashtable<String, Object> resultMap = new Hashtable<String, Object>();
		
		// 接続モード判定
		if (TRUSTDOCK_SYSTEM.equals(connectMode)) {
			if ("CNIFE062".equals(apiId))
			{
				resultMap = apiConnect2(url, apiId, connectMethod, timeout, retryCount, retryInterval, body);
			}
			else if ("CNIFE060".equals(apiId) || "CNIFE061".equals(apiId))
			{
				resultMap = apiConnect(url, apiId, connectMethod, timeout, retryCount, retryInterval, body);
			}
			
		} else if(TRUSTDOCK_STUB.equals(connectMode)) {
			if ("CNIFE062".equals(apiId))
			{
				resultMap = stubConnect2(apiId, body);
			}
			else if ("CNIFE060".equals(apiId) || "CNIFE061".equals(apiId))
			{
				resultMap = stubConnect(apiId, body);
			}
		}
		
		return resultMap;
	}
	
	/**
	 * モードが本番接続の場合に、TRUSTDOCK向けにAPIを実行する（Json型式）
	 * 
	 * @param url   接続URL
	 * @param apiid 接続APIID
	 * @param connectMethod 接続メソッド
	 * @param timeout タイムアウト時間
	 * @param retryInterval リトライインターバル
	 * @param body リクエスト情報
	 * @return 実行結果
	 */
	private static Hashtable<String, Object> apiConnect(String url, String apiid, String connectMethod, String timeout, String retryCount, String retryInterval, Map<String, Object> body) throws Exception
	{
		// アクセストークンを取得
		String acecssToken = JCMAPLConstMgr.getString(TRUSTDOCK_ACCESSTOKEN);
		
		// 実行するAPI・接続URL・リクエスト情報をログ出力
		JSYejbLog.println(JSYejbLog.EXECUTION, JCNCtrlTrustDockConnectInfoImpl.class , ("JCNCtrlTrustDockConnectInfoImpl 実行URL=" + url + " 実行APIID= " + apiid + "リクエスト情報=" +body 
				).replaceAll("\\s+", " "));
		
		// TRUSTDOCKへ接続を行う
		String result[] = TrustDockConnect(url, apiid, connectMethod, timeout, retryCount, retryInterval, body,acecssToken);
		
		// 接続結果を取得
		String httpstat = result[0];
		String response = result[1];
		
		// 結果設定用
		Hashtable<String, Object> resultMap = new Hashtable<String, Object>();
		// 接続結果設定用
		Map<String, Object> connectResult = new HashMap<String, Object>();
		// レスポンス情報設定用
		Map<String, Object> resInfo = new HashMap<String, Object>();
		
		// 返却情報を作成
		ObjectMapper mapper = new ObjectMapper();
		JsonNode root = mapper.readTree(response);
		
		// 処理結果を格納
		// 接続結果
		connectResult.put(CONNECTRESULT_HTTPSTATUS, httpstat);
		// 実行結果
		resInfo.put(RESINFO_BODY, root);
		
		// レスポンス返却用に格納
		resultMap.put(CONNECTRESULT, connectResult);
		resultMap.put(RESINFO, resInfo);
		
		// 処理結果をログ出力
		JSYejbLog.println(JSYejbLog.EXECUTION, JCNCtrlTrustDockConnectInfoImpl.class , ("json連携結果 HttpStatus=" 
				+ connectResult.get(CONNECTRESULT_HTTPSTATUS)).replaceAll("\\s+", " "));
		JSYejbLog.println(JSYejbLog.EXECUTION, JCNCtrlTrustDockConnectInfoImpl.class , ("json連携結果 response=" + 
				resInfo.toString()).replaceAll("\\s+", " "));
		
		// 接続情報をログに出力
		JSYejbLog.println(JSYejbLog.EXECUTION, JCNCtrlTrustDockConnectInfoImpl.class , "JCNCtrlTrustDockConnectInfoImpl" + apiid + "#レスポンス情報 : " + resultMap);
		return resultMap;
	}
	
	/**
	 * モードが本番接続の場合に、TRUSTDOCK向けにAPIを実行する
	 * 
	 * @param url   接続URL
	 * @param apiid 接続APIID
	 * @param connectMethod 接続メソッド
	 * @param timeout タイムアウト時間
	 * @param retryInterval リトライインターバル
	 * @param body リクエスト情報
	 * @return 実行結果
	 */
	private static Hashtable<String, Object> apiConnect2(String url, String apiid, String connectMethod, String timeout, String retryCount, String retryInterval, Map<String, Object> body) throws Exception
	{
		// アクセストークンを取得
		String acecssToken = JCMAPLConstMgr.getString(TRUSTDOCK_ACCESSTOKEN);
		
		// 実行するAPI・接続URL・リクエスト情報をログ出力
		JSYejbLog.println(JSYejbLog.EXECUTION, JCNCtrlTrustDockConnectInfoImpl.class , ("JCNCtrlTrustDockConnectInfoImpl 実行URL=" + url + " 実行APIID= " + apiid + "リクエスト情報=" +body 
				).replaceAll("\\s+", " "));
		
		// TRUSTDOCKへ接続を行う
		String result[] = TrustDockConnect(url, apiid, connectMethod, timeout, retryCount, retryInterval, body,acecssToken);
		
		// 接続結果を取得
		String httpstat = result[0];
		String response = result[1];
		
		// 結果設定用
		Hashtable<String, Object> resultMap = new Hashtable<String, Object>();
		// 接続結果設定用
		Map<String, Object> connectResult = new HashMap<String, Object>();
		// レスポンス情報設定用
		Map<String, Object> resInfo = new HashMap<String, Object>();
		
		// 処理結果を格納
		// 接続結果
		connectResult.put(CONNECTRESULT_HTTPSTATUS, httpstat);
		// 実行結果
		resInfo.put(RESINFO_BODY, response);
		
		// レスポンス返却用に格納
		resultMap.put(CONNECTRESULT, connectResult);
		resultMap.put(RESINFO, resInfo);
		
		// 処理結果をログ出力
		JSYejbLog.println(JSYejbLog.EXECUTION, JCNCtrlTrustDockConnectInfoImpl.class , ("連携結果 HttpStatus=" 
				+ connectResult.get(CONNECTRESULT_HTTPSTATUS)).replaceAll("\\s+", " "));
		JSYejbLog.println(JSYejbLog.EXECUTION, JCNCtrlTrustDockConnectInfoImpl.class , ("連携結果 response=" + 
				resInfo.toString()).replaceAll("\\s+", " "));
		
		// 接続情報をログに出力
		JSYejbLog.println(JSYejbLog.EXECUTION, JCNCtrlTrustDockConnectInfoImpl.class , "JCNCtrlTrustDockConnectInfoImpl" + apiid + "#レスポンス情報 : " + resultMap);
		return resultMap;
	}
	
	/**
	 * TRUSTDOCKへHTTP接続を実施する。
	 * 
	 * @param url   接続URL
	 * @param apiid 接続APIID
	 * @param connectMethod 接続メソッド
	 * @param send_timeout タイムアウト時間
	 * @param send_retryCount リトライ回数
	 * @param send_retryInterval リトライインターバル
	 * @param body リクエスト情報
	 * @param acecssToken アクセストークン
	 * @return 実行結果
	 */
	private static String[] TrustDockConnect(String url, String apiid, String connectMethod, String send_timeout, String send_retryCount, String send_retryInterval, 
			Map<String, Object> body, String acecssToken) throws Exception
	{

		// レスポンス(レスポンスボディ)
		String resultText = null;

		// HttpClientを生成
		HttpClient client = new HttpClient();
		// HttpConnectionManagerParamsを生成
		HttpConnectionManagerParams clientParams = client.getHttpConnectionManager().getParams();
		// HttpMethodParamsを生成
		HttpMethodParams methodParams = new HttpMethodParams();

		// 送信用の情報を作成
		String proxyHost   = null;
		Integer proxyPort  = null;
		
		Long timeout       = new Long(send_timeout);
		int retryCnt       = Integer.parseInt(send_retryCount);
		int retryInterval  = Integer.parseInt(send_retryInterval);
		byte[] resultbytes = null;
		String methodType  = connectMethod;	// メソッドの設定
		String encoding    = TRUSTDOCK_ENCODING;	// 文字コードの設定(UTF-8)
		
		// プロキシの設定
		if ((proxyHost != null) && (!"".equals(proxyHost)))
		{
			HostConfiguration hostConfig = client.getHostConfiguration();
			hostConfig.setProxy(proxyHost, proxyPort);
		}

		// タイムアウトの設定
		if (timeout != null)
		{
			clientParams.setSoTimeout(timeout.intValue());
		}

		// 文字コードの設定
		if (encoding != null)
		{
			methodParams.setContentCharset(encoding);
		}

		// リクエストメソッドの生成
		GetMethod getMethod = null;
		
		// メソッドごとにリクエストパラメータを作成
		 if ("get".equals(methodType.toLowerCase()))
		{
			getMethod = new GetMethod(url);
			// ヘッダにアクセストークンをセット
			getMethod.setRequestHeader("Authorization","Bearer"+" "+acecssToken);
		}
		
		int httpStatus = 500;
		Exception ex = null;

		// リクエストデータの送信とリトライ
		int reqCnt = retryCnt + 1;
		for (int i = 0; i < reqCnt; i++)
		{
			ex = null;

			try
			{				
				if (getMethod != null)
				{
					if ("CNIFE060".equals(apiid) || "CNIFE061".equals(apiid))
					{
						httpStatus = client.executeMethod(getMethod);
						resultText = getMethod.getResponseBodyAsString();
					}
					else if ("CNIFE062".equals(apiid))
					{
						httpStatus = client.executeMethod(getMethod);
						resultbytes = getMethod.getResponseBody();
						
						resultText = makeBasicAuth(resultbytes);
					}
				}
				
			}
			catch (HttpException e)
			{
				ex = e;
			}
			catch (IOException e)
			{
				ex = e;
			}

			// 失敗時はリトライ回数の上限までリトライ
			if (((ex != null)) && (i < retryCnt))
			{
				try
				{
					JSYejbLog.println(JSYejbLog.EXECUTION, JCNCtrlTrustDockConnectInfoImpl.class , ("[EKB9930-CE]TRUSTDOCKへの連携に失敗しました。"));
					Thread.sleep(retryInterval);
				}
				catch (InterruptedException e)
				{
					// 割り込み要求による例外は無視
				}
				continue;
			}

			break;
		}

		// コネクション解放
		if (getMethod != null)
		{
			getMethod.releaseConnection();
			getMethod = null;
		}
		
		return new String[] { new Integer(httpStatus).toString(), resultText };
	}
	
	/**
	 * モードがスタブ接続の場合に、疑似的にAPIを実行する（Json型式）
	 * 
	 * @param apiid 接続APIID
	 * @param body リクエスト情報
	 * @return 実行結果
	 */
	private static Hashtable<String, Object> stubConnect(String apiid,Map<String, Object> body) throws Exception
	{
		JSYejbLog.println(JSYejbLog.EXECUTION, JCNCtrlTrustDockConnectInfoImpl.class , ("JCNCtrlTrustDockConnectInfoImpl 実行APIID= " + apiid + "リクエスト情報=" +body 
		).replaceAll("\\s+", " "));
		
		// 結果設定用
		Hashtable<String, Object> resultMap = new Hashtable<String, Object>();
		// 接続結果設定用
		Map<String, Object> connectResult = new HashMap<String, Object>();
		// レスポンス情報設定用
		Map<String, Object> resInfo = new HashMap<String, Object>();
		
		// スタブファイル名を取得
		String filenm = "";
		// スタブHTTPステータス取得コードを取得
		String httpstatcd = STUB_HTTPSTAT_MAP.get(apiid);
		// スタブHTTPステータスを取得
		String httpstat = JCMAPLConstMgr.getString(httpstatcd);
		// スタブファイル格納パスを取得
		String dir_pass = JCMAPLConstMgr.getString(TRUSTDOCK_CONNECTION_MODE_TEST_DIR) + "/";
		
		
		String stub_response = null;
		Boolean sonzai_um = false;
		String id = "";
		String token = "";
		
		// スタブファイル名を取得
		filenm = STUB_FILE_MAP.get(apiid);
		
		
		// スタブファイルフルパスを取得
		String full_pass = dir_pass + filenm;
		
		 // スタブファイル読込
		File file = new File(full_pass);
		if(!file.exists()){
			// ファイル読込に失敗した場合、
			// 実行結果およびHTTPステータスを取得
			String gizi_result = NOT_EXITS_FILE_RESULT_MAP.get(apiid);
			String gizi_httpstat = NOT_EXITS_FILE_HTTPSTAT_MAP.get(apiid);
			
			// 処理結果を格納
			// 接続結果
			connectResult.put(CONNECTRESULT_HTTPSTATUS, gizi_httpstat);
			// 実行結果
			ObjectMapper mapper = new ObjectMapper();
			JsonNode root = mapper.readTree(gizi_result);
			
			resInfo.put(RESINFO_BODY, root);
			
		} else {
			// 該当ファイルが存在する場合、
			// ファイル読込用にインスタンスを生成
			BufferedReader br = new BufferedReader(new FileReader(file));
			// 1行目読込
			String line = br.readLine();
			
			// 1行目のキー情報およびレスポンス情報を切り分ける
			String[] response = line.split("@@");
			
			String search_key = null;
			
			if ("CNIFE060".equals(apiid)) {
				// 利用するスタブファイル毎に検索キーを設定
				id = nullToBlank((String) body.get("key_id"));
				search_key = id;
				
			}
			else if ("CNIFE061".equals(apiid) || "CNIFE062".equals(apiid)) {
				// パラメータ.BODYよりファイル判定キー情報を取得する
				token = nullToBlank((String) body.get("token"));
				search_key = token;
			}
			
			while(line != null) {
				response = line.split("@@");
				
				// 検索キーと一致するデータを取得する
				if(response[0].equals(search_key)) {
					stub_response = response[1];
					sonzai_um = true;
					
					// 検索対象が存在した場合は、処理を抜ける
					break;
				}
				// 次の行を読込み
				line = br.readLine();
			}
			// JsonNodeインスタンスを作成
			ObjectMapper mapper = new ObjectMapper();
			JsonNode root = null;
			
			if (sonzai_um) {
				// 検索対象存在有無フラグが"true"の場合、
				root = mapper.readTree(stub_response);
			} else {
				// 検索対象存在有無フラグが"false"の場合、
				 mapper.readTree("{}");
			}			
			
			// 処理結果を格納
			// 接続結果
			connectResult.put(CONNECTRESULT_HTTPSTATUS, httpstat);
			// 実行結果
			resInfo.put(RESINFO_BODY, root);
		}
		
		// レスポンス返却用に格納
		resultMap.put(CONNECTRESULT, connectResult);
		resultMap.put(RESINFO, resInfo);
		
		// 処理結果をログ出力
		JSYejbLog.println(JSYejbLog.EXECUTION, JCNCtrlTrustDockConnectInfoImpl.class , ("json連携結果 HttpStatus=" 
				+ connectResult.get(CONNECTRESULT_HTTPSTATUS)).replaceAll("\\s+", " "));
		JSYejbLog.println(JSYejbLog.EXECUTION, JCNCtrlTrustDockConnectInfoImpl.class , ("json連携結果 response=" + 
				resInfo.toString()).replaceAll("\\s+", " "));
		// 接続情報をログに出力
		JSYejbLog.println(JSYejbLog.EXECUTION, JCNCtrlTrustDockConnectInfoImpl.class , "JCNCtrlTrustDockConnectInfoImpl" + apiid + "#レスポンス情報 : " + resultMap);
		return resultMap;
	}
	
	/**
	 * モードがスタブ接続の場合に、疑似的にAPIを実行する
	 * 
	 * @param apiid 接続APIID
	 * @param body リクエスト情報
	 * @return 実行結果
	 */
	private static Hashtable<String, Object> stubConnect2(String apiid,Map<String, Object> body) throws Exception
	{
		JSYejbLog.println(JSYejbLog.EXECUTION, JCNCtrlTrustDockConnectInfoImpl.class , ("JCNCtrlTrustDockConnectInfoImpl 実行APIID= " + apiid + "リクエスト情報=" +body 
		).replaceAll("\\s+", " "));
		
		// 結果設定用
		Hashtable<String, Object> resultMap = new Hashtable<String, Object>();
		// 接続結果設定用
		Map<String, Object> connectResult = new HashMap<String, Object>();
		// レスポンス情報設定用
		Map<String, Object> resInfo = new HashMap<String, Object>();
		// レスポンス(レスポンスボディ)
		String resultText = null;
		
		// スタブファイル名を取得
		String filenm = "";
		// スタブHTTPステータス取得コードを取得
		String httpstatcd = STUB_HTTPSTAT_MAP.get(apiid);
		// スタブHTTPステータスを取得
		String httpstat = JCMAPLConstMgr.getString(httpstatcd);
		// スタブファイル格納パスを取得
		String dir_pass = JCMAPLConstMgr.getString(TRUSTDOCK_CONNECTION_MODE_TEST_DIR) + "/";
		
		// スタブファイル名を取得
		filenm = STUB_FILE_MAP.get(apiid);
		
		
		// スタブファイルフルパスを取得
		String full_pass = dir_pass + filenm;
		
		 // スタブファイル読込
		File file = new File(full_pass);
		if(!file.exists()){
			// ファイル読込に失敗した場合、
			// 実行結果およびHTTPステータスを取得
			String gizi_httpstat = NOT_EXITS_FILE_HTTPSTAT_MAP.get(apiid);
			
			// 処理結果を格納
			// 接続結果
			connectResult.put(CONNECTRESULT_HTTPSTATUS, gizi_httpstat);
			// 実行結果
			resInfo.put(RESINFO_BODY, resultText);
			
		} else {
			// 該当ファイルが存在する場合、
			FileInputStream input = new FileInputStream(file);
			byte[] httpResponse = new byte[input.available()];
			input.read(httpResponse);
			
			// base64変換
			resultText = makeBasicAuth(httpResponse);
			
			// 処理結果を格納
			// 接続結果
			connectResult.put(CONNECTRESULT_HTTPSTATUS, httpstat);
			// 実行結果
			resInfo.put(RESINFO_BODY, resultText);
		}
		
		// レスポンス返却用に格納
		resultMap.put(CONNECTRESULT, connectResult);
		resultMap.put(RESINFO, resInfo);
		
		// 処理結果をログ出力
		JSYejbLog.println(JSYejbLog.EXECUTION, JCNCtrlTrustDockConnectInfoImpl.class , ("連携結果 HttpStatus=" 
				+ connectResult.get(CONNECTRESULT_HTTPSTATUS)).replaceAll("\\s+", " "));
		JSYejbLog.println(JSYejbLog.EXECUTION, JCNCtrlTrustDockConnectInfoImpl.class , ("連携結果 response=" + 
				resInfo.toString()).replaceAll("\\s+", " "));
		// 接続情報をログに出力
		JSYejbLog.println(JSYejbLog.EXECUTION, JCNCtrlTrustDockConnectInfoImpl.class , "JCNCtrlTrustDockConnectInfoImpl" + apiid + "#レスポンス情報 : " + resultMap);
		return resultMap;
	}
	
	
	/**
	 * null又は空文字の場合、trueを返却する
	 * 
	 * @param str 検査対象文字列
	 * @return true:null、又は空文字／false:左記以外
	 */
	public static boolean isNullBlank(String str)
	{
		if (null == str || "".equals(str))
		{
			return true;
		}
		return false;
	}
	
	/**
	 * nullを空文字に置き換え
	 * 
	 * @param str 置き換え対象文字列
	 * @return
	 */
	public static String nullToBlank(String str)
	{
		if (str == null)
		{
			return "";
		}
		return str;
	}

	/**
	 * JSON形式のパラメータ作成処理
	 * <br>
	 * @param body 		リクエスト情報

	 * @return 作成したJSON形式のリクエストパラメータを返却する。
	 */
	protected static String makeJsonRecParam(Map<String, Object> body)
	{
		JSONObject json1kaisoMap = new JSONObject();
		Iterator<?> it = body.keySet().iterator();
		try
		{
			//JSON形式のリクエストパラメータを作成する。
			while (it.hasNext())
			{
				String paramName = (String) it.next();
				String paramValue = (String) body.get(paramName);
				json1kaisoMap.put(paramName, paramValue); 
			}
		}
		catch (JSONException e)
		{
			e.printStackTrace();
		}
		return json1kaisoMap.toString();
	}
	
	/**
	 * BASIC認証の文字列を作成する
	 * <br>
	 * @param accoutName アカウント名
	 * @param password パスワード
	 * @return "Basic " + [ユーザ]:[パスワード]をBASE64エンコードした文字列
	 */
	protected static String makeBasicAuth(byte[] accoutName)
	{
		byte[] encodedBytes = Base64.encodeBase64(accoutName);
		
		String encodedString = new String(encodedBytes);
		
		return encodedString;
	}
}
