/*******************************************************************************
*	All Rights reserved,Copyright (c) K-Opticom
********************************************************************************
*＜プログラム内容＞
*	システム名		：eo顧客基幹システム
*	モジュール名	：JEKKA1880001TPMA
*	ソースファイル名：JEKKA1880001TPMA.java
*	作成者			：FJ）加藤
*	日付			：2021年04月20日
*＜機能概要＞
*	SMS送信(SMSプッシュサービス)頼独自処理部品です。
*＜修正履歴＞
*	バージョン	修正日		修正者		修正内容
*   V53.0.0    2021/04/20  富士通      新規作成
*   V54.0.0    2021/08/03  FJ)西窪      ANK-4092-00-00_CX戦略WG方針対応STEP2
*   V55.0.0    2021/11/16  FJ)舘山      SGY-2021-0000038_ＳＭＳ資産のスタブ箇所修正対応
*
********************************************************************************/
package eo.ejb.cbs.mainproc;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
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.StatusCodes;
import com.fujitsu.futurity.model.ejb.common.fw.AgentDispatchContext;
import com.fujitsu.futurity.model.ejb.common.fw.TemplateMainHandler;

import eo.common.util.JCHStringUtil;
import eo.ejb.cbs.cbsmsg.EKKA1880001CBSMsg;
import eo.ejb.cbs.cbsmsg.EKKA1880001CBSMsg1List;
import eo.ejb.common.db.JKKejbKK3351SecProc;


/**
 * SMS送信(SMSプッシュサービス)頼独自処理部品です。
 * <br>
 * @author FJ
 *
 */
public class JEKKA1880001TPMA implements TemplateMainHandler
{	
	/** モード取得用キー */
	private static final String SMS_MODE_KEY = "KK_SMS_MODE";
	/** モード取得用キー */
	private static final String CONTENTS_LENGTH_MODE = "KK_SMS_CONTENTS_LENGTH_MODE";
	

	/** 実連携モード */
	private static final String MODE_REAL = "2";
	
	private static final String CONTENTS_LENGTH_MODE_REAL = "2";

	/** エラーフラグ(E1：必須チェックエラー) */
	private static final String E1_ERR_FLAG = "E1";

	/** エラーフラグ(E2：ドメインチェックエラー) */
	private static final String E2_ERR_FLAG = "E2";

	/** エラーフラグ(E3：桁数チェックエラー) */
	private static final String E3_ERR_FLAG = "E3";

	/** エラーフラグ(EA：設定値取得エラー) */
	private static final String EA_ERR_FLAG = "EA";

	/** エラーフラグ(EB：応答コードエラー) */
	private static final String EB_ERR_FLAG = "EB";

	/** エラーフラグ(EC：実行時エラー) */
	private static final String EC_ERR_FLAG = "EC";

	/** SMS文字コード */
	private static final String SMS_ENCODING = "UTF-8";

	/** URL取得用キー */
	private static final String URL_KEY = "KK_SMS_URL";

	/** AUTHORIZATION取得用キー */
	private static final String AUTHORIZATION_KEY = "KK_SMS_AUTHORIZATION";

	/** 接続タイムアウト取得用キー */
	private static final String CONNECT_TIMEOUT_KEY = "KK_SMS_CONNECT_TIMEOUT";

	/** 読取タイムアウト取得用キー */
	private static final String READ_TIMEOUT_KEY = "KK_SMS_READ_TIMEOUT";

	/** リトライ回数取得用キー */
	private static final String RETRYCOUNT_KEY = "KK_SMS_RETRYCOUNT";

	/** リトライインターバル取得用キー */
	private static final String RETRYINTERVAL_KEY = "KK_SMS_RETRYINTERVAL";

	/** スタブHTTPステータス取得用キー */
	private static final String STUB_HTTP_STATUS_KEY = "STUB_HTTP_STATUS_KEY";

	/** スタブメッセージID取得用キー */
	private static final String STUB_MESSAGEID_KEY = "STUB_MESSAGEID_KEY";

	/** スタブエラー内容取得用キー */
	private static final String STUB_ERRORREASON_KEY = "STUB_ERRORREASON_KEY";

	/** ステータスOK */
	private static final String HTTP_STATUS_OK = "200";

	/** 【HTTPヘッダ】  */
	/** 認証  */
	private static final String AUTHORIZATION = "Authorization";

	/** CONTENT_TYPE  */
	private static final String CONTENT_TYPE = "Content-Type";

	/** CONTENT_TYPE_設定値  */
	private static final String CONTENT_TYPE_VALUE = "application/json; charset=UTF-8";

	/** ボディー部データ長  */
	private static final String CONTENT_LENGTH = "Content-Length";

	/** 【SMS送信情報】  */
	/** 電話番号 */
	private static final String ADDRESS = "address";

	/** 送信者情報 */
	private static final String SENDERNAME = "senderName";

	/** 文字コード */
	private static final String CODINGSCHEME = "codingScheme";

	/** 文字コード_設定値 */
	//固定値を"1"(UTF-8)とする
	private static final int CODINGSCHEME_VALUE = 1;

	/** メッセージ */
	private static final String MESSAGE = "message";

	/** SMS送信情報 */
	private static final String SENDTEXTSMS = "sendTextSms";

	/** ダミーAUTHORIZATION */
	private static final String DUMMY_URL = "DUMMY";

	/** ダミーAUTHORIZATION */
	private static final String DUMMY_AUTHORIZATION = "1234567890";
	
	/** 【処理結果】 */
	/** SMS送信レスポンス */
	private static final String SENDSMSRESPONSE = "sendSmsResponse";

	/** SMS送信エラーレスポンス */
	private static final String SENDSMSERRRESPONSE = "sendSmsErrResponse";

	/** エラー内容 */
	private static final String MESSAGEID = "messageId";


	/** エラー内容 */
	private static final String ERRORREASON = "errorReason";


	/**
	 * 個別割引適用可否照会・変更依頼を行います。
	 * 
	 * @param inCBSMsg 個別割引適用可否照会・変更依頼メッセージ
	 * @param inContext AgentDispatchContext
	 */
	public static void call_KKIFE461(CAANMsg inCBSMsg, AgentDispatchContext inContext)  throws Exception
	{
		// 開始ログ出力を実施。
		JSYejbLog.println(JSYejbLog.DEBUG, JEKKA1880001TPMA.class, "JEKKA1880001TPMA#invoke start");
		
		String[] response = new String[]{"", "", ""};
		

		// メッセージの単項目チェックを実施
		// 必須チェック
		if (JCHStringUtil.isNullBlank(inCBSMsg.getString(EKKA1880001CBSMsg.MESSAGE)))
		{
			inCBSMsg.set(EKKA1880001CBSMsg.STATUS, StatusCodes.SINGLEDATA_ERR);
			inCBSMsg.set(EKKA1880001CBSMsg.MESSAGE_ERR, E1_ERR_FLAG);
			editOutMsg(inCBSMsg, response);
			return;
		}
		// 桁数チェック
		if (inCBSMsg.getString(EKKA1880001CBSMsg.MESSAGE).length() > 670)
		{
			inCBSMsg.set(EKKA1880001CBSMsg.STATUS, StatusCodes.SINGLEDATA_ERR);
			inCBSMsg.set(EKKA1880001CBSMsg.MESSAGE_ERR, E3_ERR_FLAG);
			editOutMsg(inCBSMsg, response);
			return;
		}
		
		/** 接続先などの判定に使用
		*   1：開発 、2: 本番・検証
		*/
		String mode = JCMAPLConstMgr.getString(SMS_MODE_KEY);
		String contets_length_mode = JCMAPLConstMgr.getString(CONTENTS_LENGTH_MODE);
		
		// アプリケーションプロパティ設定チェック
		if(JCHStringUtil.isNullBlank(mode))
		{
			// ステータス設定（設定値取得エラー）
			inCBSMsg.set(EKKA1880001CBSMsg.STATUS, StatusCodes.RELATION_ERR);
			inCBSMsg.set(EKKA1880001CBSMsg.ADDRESS, EA_ERR_FLAG);
			editOutMsg(inCBSMsg, response);
			return;
		}
		
		JSYejbLog.println(JSYejbLog.DEBUG, JEKKA1880001TPMA.class, "JEKKA1880001TPMA#invoke mode = " + mode);
		// eo顧客 ⇒ そとれんへの電話番号を設定
		String strUrl = "";
		// 認証
		String authorization = "";
		// 認証
		String content_length = "";
		
		if (MODE_REAL.equals(mode))
		{
			// 本番・検証：propertiesに設定された値を使用
			strUrl = JCMAPLConstMgr.getString(URL_KEY);
			authorization = JCMAPLConstMgr.getString(AUTHORIZATION_KEY);
		}
		else
		{
			// スタブモード
			// スタブ用設定値取得
			if(!getStubParams(response))
			{
				// ステータス設定（設定値取得エラー）
				inCBSMsg.set(EKKA1880001CBSMsg.STATUS, StatusCodes.RELATION_ERR);
				inCBSMsg.set(EKKA1880001CBSMsg.ADDRESS, EA_ERR_FLAG);
				editOutMsg(inCBSMsg, response);
				return;
			}
			// 開発：設定しない
			strUrl = DUMMY_URL;
			authorization = DUMMY_AUTHORIZATION;
		}
		// 接続タイムアウト
		String strConnectTimeout = JCMAPLConstMgr.getString(CONNECT_TIMEOUT_KEY);
		// 読取タイムアウト
		String strReadTimeout = JCMAPLConstMgr.getString(READ_TIMEOUT_KEY);
		// リトライ回数
		String strRetryCount = JCMAPLConstMgr.getString(RETRYCOUNT_KEY);
		// リトライインターバル
		String strRetryInterval = JCMAPLConstMgr.getString(RETRYINTERVAL_KEY);
		// アプリケーションプロパティ設定チェック
		if(JCHStringUtil.isNullBlank(strUrl)
				|| JCHStringUtil.isNullBlank(authorization)
				|| JCHStringUtil.isNullBlank(strConnectTimeout)
				|| JCHStringUtil.isNullBlank(strReadTimeout)
				|| JCHStringUtil.isNullBlank(strRetryCount)
				|| JCHStringUtil.isNullBlank(strRetryInterval))
		{
			// ステータス設定（設定値取得エラー）
			inCBSMsg.set(EKKA1880001CBSMsg.STATUS, StatusCodes.RELATION_ERR);
			inCBSMsg.set(EKKA1880001CBSMsg.ADDRESS, EA_ERR_FLAG);
			editOutMsg(inCBSMsg, response);
			return;
		}
		JSYejbLog.println(JSYejbLog.EXECUTION, JEKKA1880001TPMA.class , "JEKKA1880001TPMA#Authorization=" + authorization);
		JSYejbLog.println(JSYejbLog.EXECUTION, JEKKA1880001TPMA.class , "JEKKA1880001TPMA#Content-Type=" + CONTENT_TYPE_VALUE);
		JSYejbLog.println(JSYejbLog.EXECUTION, JEKKA1880001TPMA.class , "JEKKA1880001TPMA#URL=" + strUrl);
		
		// 接続タイムアウト
		int connectTimeout = Integer.parseInt(strConnectTimeout);
		// 読取タイムアウト
		int readTimeout = Integer.parseInt(strReadTimeout);
		// リトライ回数
		int retryCount = Integer.parseInt(strRetryCount);
		// リトライインターバル
		int retryInterval = Integer.parseInt(strRetryInterval);

		try
		{
			// JSON形式の文字列を作成する。
			String json = requestParamMake(inCBSMsg, inContext, mode);
			JSYejbLog.println(JSYejbLog.DEBUG, JEKKA1880001TPMA.class, "JEKKA1880001TPMA# request=" + json);
			
			if (!JCHStringUtil.isNullBlank(json))
			{
				String logStr = json.replaceAll("\\s+", " ");
				logStr = maskJson(logStr, ADDRESS, 11);
				logStr = maskJson(logStr, SENDERNAME, 11);
				logStr = maskJson(logStr, CODINGSCHEME, 1);
				logStr = maskJson(logStr, MESSAGE, 670);
				JSYejbLog.println(JSYejbLog.EXECUTION, JEKKA1880001TPMA.class , "JEKKA1880001TPMA#request=" + logStr);
			}

			if (CONTENTS_LENGTH_MODE_REAL.equals(contets_length_mode))
			{
				// JSON形式の文字列(ボディー部データ長)のバイト数取得
				content_length = String.valueOf(json.getBytes("UTF-8").length);
			}

			if (MODE_REAL.equals(mode))
			{
				// SMSのSMS送信APIに対してリクエストを送信する。
				response = callPost(strUrl, authorization, content_length, json, connectTimeout, readTimeout, retryCount, retryInterval);
				JSYejbLog.println(JSYejbLog.DEBUG, JEKKA1880001TPMA.class, "JEKKA1880001TPMA# response=" + response);
			}
			else
			{
				JSYejbLog.println(JSYejbLog.DEBUG, JEKKA1880001TPMA.class, "JEKKA1880001TPMA#invoke stabStart response=" + response);
				// スタブを呼ぶ。
				response = callStub(response);
				JSYejbLog.println(JSYejbLog.DEBUG, JEKKA1880001TPMA.class, "JEKKA1880001TPMA#invoke stabEnd response=" + response);
			}
			
			// 共通API連携実行結果判定
			if (response != null && response.length == 3)
			{
				// HTTPステータスをログ出力
				JSYejbLog.println(JSYejbLog.EXECUTION, JEKKA1880001TPMA.class, "JEKKA1880001TPMA#http_status=" + response[0]);
				// HTTPステータス（200:正常）の場合
				if (HTTP_STATUS_OK.equals(response[0]))
				{
					// ステータス設定（0:正常終了）
					inCBSMsg.set(EKKA1880001CBSMsg.STATUS, StatusCodes.NORMAL_END);
					
					// ANK-4092-00-00 ADD START
					// SMS配信結果副次処理を呼出す
					String messageId = response[1];
					new JKKejbKK3351SecProc().createSmsHaisinRslt(inCBSMsg, inContext, messageId);
					// ANK-4092-00-00 ADD END
				}
				//  HTTPステータス（200:正常）以外の場合
				else
				{
					// ステータス設定（送信エラー）
					inCBSMsg.set(EKKA1880001CBSMsg.STATUS, StatusCodes.WARNING);
				}
			}
		}
		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, JEKKA1880001TPMA.class,"#JECNA0110001TPMA(Exception)発生" + sb.toString());
			
			// ステータス設定（実行時エラー）
			inCBSMsg.set(EKKA1880001CBSMsg.STATUS, StatusCodes.RELATION_ERR);
			inCBSMsg.set(EKKA1880001CBSMsg.ADDRESS, EC_ERR_FLAG);
		}
		finally
		{
			// レスポンス電文を設定
			editOutMsg(inCBSMsg, response);
		}
		// 終了ログ出力を実施。
		JSYejbLog.println(JSYejbLog.DEBUG, JEKKA1880001TPMA.class, "JEKKA1880001TPMA#invoke end");
	}

	/**
	 * 共通APIのレスポンス電文を設定します。
	 * <br>
	 * @param inCBSMsg 個別割引適用可否照会・変更依頼メッセージ
	 * @param resServiceMap レスポンスサービスマップ
	 */
	private static void editOutMsg(CAANMsg inCBSMsg, String[] response)
	{
		List<CAANMsg> msg1List = new ArrayList<CAANMsg>();
		
		CAANMsg msg1 = new CAANMsg(EKKA1880001CBSMsg1List.class.getName());
		
		String httpStatus = "";
		String messageId = "";
		String errorReason = "";
		
		if (response != null)
		{
			if (response.length > 0)
			{
				httpStatus = nullToBlank(response[0]);
			}
			if (response.length > 1)
			{
				messageId = nullToBlank(response[1]);
			}
			if (response.length > 2)
			{
				errorReason = nullToBlank(response[2]);
			}
		}
		
		msg1.set(EKKA1880001CBSMsg1List.HTTP_STATUS, httpStatus);
		msg1.set(EKKA1880001CBSMsg1List.MESSAGEID, messageId);
		msg1.set(EKKA1880001CBSMsg1List.ERRORREASON, errorReason);
		msg1List.add(msg1);
		
		// Listから配列に変換して設定
		inCBSMsg.set(EKKA1880001CBSMsg.EKK1880001CBSMSG1LIST, msg1List.toArray(new CAANMsg[msg1List.size()]));
	}
	
	/**
	 * SMS JSON形式の文字列を作成する。
	 * @param inCBSMsg CAANメッセージ
	 * @param inContext コンテキスト
	 * @param mode 処理区分
	 * @param loginUrlShortName 略称（URL用）
	 * @param smsMessage SMSメッセージ
	 * @param label ラベル名
	 * @param confirmMessage 商品確認メッセージ
	 * @param note 備考
	 * @param paymentOkUrl 決済OK後遷移URL
	 * @param paymentNgUrl 決済NG後遷移URL
	 * @param freefield2Env フリー項目２取得元
	 * @param freefield2 フリー項目２
	 * @return SMS JSON形式のリクエストパラメータを返却する。
	 * @throws IOException JOSN形式へ変換する際のI/O例外
	 */
	private static String requestParamMake(CAANMsg inCBSMsg, AgentDispatchContext inContext, String mode) throws IOException
	{
		// JOSN形式へ変換するためのMAP
		Map<String, Object> requestMap = new HashMap<String, Object>();
		// 変換後文字列
		String json = "";

		// ▼▼▼▼▼▼▼▼▼▼▼【SMS送信情報】▼▼▼▼▼▼▼▼▼▼▼

		// SMS送信情報パラメータ
		Map<String, Object> sendTextSmsParamMap = new HashMap<String, Object>();

		// 電話番号
		sendTextSmsParamMap.put(ADDRESS, inCBSMsg.getString(EKKA1880001CBSMsg.ADDRESS));

		// 送信者情報
		sendTextSmsParamMap.put(SENDERNAME, inCBSMsg.getString(EKKA1880001CBSMsg.SENDERNAME));

		// 文字コード
		sendTextSmsParamMap.put(CODINGSCHEME, CODINGSCHEME_VALUE);

		// メッセージ
		sendTextSmsParamMap.put(MESSAGE, inCBSMsg.getString(EKKA1880001CBSMsg.MESSAGE));

		// SMS送信情報パラメータの設定
		requestMap.put(SENDTEXTSMS, sendTextSmsParamMap);

		// ▲▲▲▲▲▲▲▲▲▲▲【SMS送信情報】▲▲▲▲▲▲▲▲▲▲▲

		ObjectMapper mapper = new ObjectMapper();
		mapper.enable(SerializationFeature.INDENT_OUTPUT);
		try
		{
			// JOSN形式へ変換
			json = mapper.writeValueAsString(requestMap);

		} catch (IOException e)
		{
			e.printStackTrace();
			throw e;
		}
		
		return json;
	}

	/**
	 * レスポンス設定値を取得する
	 * @param response レスポンス設定値
	 * @return 取得結果
	 */
	private static boolean getStubParams(String[] response)
	{
		// HTTPステータス
		response[0] = JCMAPLConstMgr.getString(STUB_HTTP_STATUS_KEY);
		// メッセージID
		response[1] = JCMAPLConstMgr.getString(STUB_MESSAGEID_KEY);
		// エラー内容
		response[2] = JCMAPLConstMgr.getString(STUB_ERRORREASON_KEY);
		
// ▽▽▽ SGY-2021-0000038 2021-09-17 ADD START
		if (response[1] == null || response[1].length() <= 20)
		{
			java.util.UUID uuid = java.util.UUID.randomUUID();
			response[1] = uuid.toString();
		}
// △△△ SGY-2021-0000038 2021-09-17 ADD END
		// アプリケーションプロパティ設定チェック
		if(JCHStringUtil.isNullBlank(response[0]))
		{
			return false;
		}
		
		return true;
	}

	/**
	 * SMS APIに対して送信するリクエストパラメータを作成する。
	 * @param json 送信するJSON文字列
	 * @param connectTimeout 接続タイムアウト
	 * @param readTimeout 読取タイムアウト
	 * @param retryCount リトライ回数
	 * @param retryInterval リトライインターバル
	 * @return JSONレスポンスから取得したパラメータ
	 * @throws Exception 
	 */
	private static String[] callPost(String address, String authorization, String content_length, String json, int connectTimeout, int readTimeout, int retryCount,
			int retryInterval)
	throws IOException
	{
		// レスポンス
		StringBuffer result = new StringBuffer();
		// メッセージID
		String messageId = null;
		// エラー内容
		String errorReason = null;

		HttpURLConnection con = null;

		int httpStatus = 500;
		int reqCnt = retryCount + 1;
		IOException ex = null;

		for (int i = 0; i < reqCnt; i++)
		{
			try
			{
				ex = null;
				URL url = new URL(address);
				con = (HttpURLConnection) url.openConnection();
				// HTTPリクエストコード
				con.setRequestMethod("POST");
				// HTTPヘッダの設定
				con.setRequestProperty(AUTHORIZATION, authorization);
				con.setRequestProperty(CONTENT_TYPE, CONTENT_TYPE_VALUE);
				con.setRequestProperty(CONTENT_LENGTH, content_length);

				//タイムアウト設定
				con.setConnectTimeout(connectTimeout);
				con.setReadTimeout(readTimeout);

				con.setDoOutput(true);
				OutputStreamWriter out = new OutputStreamWriter(con.getOutputStream(), SMS_ENCODING);
				out.write(json);

				out.flush();

				// 接続開始ログ
				JSYejbLog.println(JSYejbLog.DEBUG, JEKKA1880001TPMA.class, "JEKKA1880001TPMA#connect start");

				// 接続
				con.connect();

				httpStatus = con.getResponseCode();

				// 接続終了ログ
				JSYejbLog.println(JSYejbLog.DEBUG, JEKKA1880001TPMA.class, "JEKKA1880001TPMA#connect end");

				
				// 通信に成功したテキストを取得する
				final InputStream in = con.getInputStream();
				String encoding = con.getContentEncoding();
				if (null == encoding)
				{
					encoding = SMS_ENCODING;
				}
				final InputStreamReader inReader = new InputStreamReader(in, encoding);
				final BufferedReader bufReader = new BufferedReader(inReader);
				String line = null;

				while ((line = bufReader.readLine()) != null)
				{
					result.append(line);
				}
				bufReader.close();
				inReader.close();
				in.close();
				ObjectMapper mapper = new ObjectMapper();
				JsonNode root = mapper.readTree(result.toString());
				// 【処理結果】を取得
				if (root.get(SENDSMSRESPONSE) != null && root.get(SENDSMSRESPONSE).get(MESSAGEID) != null)
				{
					messageId =(root.get(SENDSMSRESPONSE).get(MESSAGEID)).textValue();
				}
				if (root.get(SENDSMSERRRESPONSE) != null && root.get(SENDSMSERRRESPONSE).get(ERRORREASON) != null)
				{
					errorReason = (root.get(SENDSMSERRRESPONSE).get(ERRORREASON)).textValue();
				}
				// レスポンスをログ出力
				JSYejbLog.println(JSYejbLog.EXECUTION, JEKKA1880001TPMA.class ,("JEKKA1880001TPMA#response=" +
						result.toString()).replaceAll("\\s+", " "));
			}
			catch (IOException e)
			{
				e.printStackTrace();
				ex = e;
			}
			finally
			{
				if (con != null)
				{
					//切断処理
					con.disconnect();
					con = null;
				}
			}
			// 失敗時はリトライ回数の上限までリトライ
			if (((ex != null) || (httpStatus != HttpURLConnection.HTTP_OK)) && (i < retryCount))
			{
				try
				{
					Thread.sleep(retryInterval);
				}
				catch (InterruptedException e)
				{
					// 割り込み要求による例外は無視
				}
				continue;
			}
			else
			{
				break;
			}
		}
		
		// 例外情報がある場合はthrowする
		if (ex != null)
		{
			throw ex;
		}
		
		return new String[] {String.valueOf(httpStatus), messageId, errorReason};
	}

	/**
	 * スタブをコールする
	 * @param response レスポンス設定値
	 * @return レスポンス設定値
	 * @throws JsonProcessingException JSONへの変換時例外
	 */
	private static String[] callStub(String[] response) throws JsonProcessingException
	{
		if (!JCHStringUtil.isNullBlank(response[1]))
		{
			Map<String, Object> responseMap = new HashMap<String, Object>();
			if (HTTP_STATUS_OK.equals(response[0]))
			{
				// SMS送信レスポンスパラメータ
				Map<String, Object> sendSmsResponseParamMap = new HashMap<String, Object>();
				
				// メッセージID
				sendSmsResponseParamMap.put(MESSAGEID, response[1]);
				
				// SMS送信レスポンスパラメータの設定
				responseMap.put(SENDSMSRESPONSE, sendSmsResponseParamMap);
			}
			else
			{
				// SMS送信エラーレスポンスパラメータ
				Map<String, Object> sendSmsErrResponseParamMap = new HashMap<String, Object>();
				
				// エラー内容
				sendSmsErrResponseParamMap.put(ERRORREASON, response[2]);
				
				// SMS送信エラーレスポンスパラメータの設定
				responseMap.put(SENDSMSERRRESPONSE, sendSmsErrResponseParamMap);
			}
			ObjectMapper mapper = new ObjectMapper();
			mapper.enable(SerializationFeature.INDENT_OUTPUT);
			// JOSN形式へ変換
			String json;
			try {
				json = mapper.writeValueAsString(responseMap);
			} catch (JsonProcessingException e) {
				e.printStackTrace();
				throw e;
			}
			// レスポンスをログ出力
			JSYejbLog.println(JSYejbLog.EXECUTION, JEKKA1880001TPMA.class, ("JEKKA1880001TPMA#response=" + json).replaceAll("\\s+", " "));
		}
		
		return response;
	}

	/**
	 * nullを空文字に置き換え
	 * 
	 * @param str 置き換え対象文字列
	 * @return
	 */
	private static String nullToBlank(String str)
	{
		if (str == null)
		{
			return "";
		}
		return str;
	}

	/**
	 * JSONをマスク
	 * 
	 * @param json マスクするJSON
	 * @param maskKey マスクするキー
	 * @param count マスクする文字数
	 * @return マスク後の文字列
	 */
	private static String maskJson(String json, String maskKey, int count)
	{
		String ret = "";
		
		if (!JCHStringUtil.isNullBlank(json))
		{
			StringBuffer sb = new StringBuffer();
			for (int i = 0; i < count; i++)
			{
				sb.append("\\*");
			}
			ret = json.replaceAll("(\"" + maskKey + "\"\\s*:\\s*\")[^\"]*\"", "$1" + sb.toString() + "\"");
		}
		
		return ret;
	}
}
