/*********************************************************************
* All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*   システム名      ：eo顧客基幹システム
*   モジュール名    ：JCKKisnKeiHmdkShijiAddCC
*   ソースファイル名：JCKKisnKeiHmdkShijiAddCC.java
*   作成者          ：FJ
*   日付            ：2013年03月14日
*＜機能概要＞
*   指示書(F回線契約に紐づく各種サービス契約の情報)作成の共通コンポーネント
*＜修正履歴＞
*＜修正履歴＞
*   バージョン  修正日      修正者      修正内容
*	v4.00.00	2013/03/14	FJ)稲岡		新規作成
*	v4.00.01	2013/05/04	FJ)稲岡		【IT1-2013-0001126】対応
**********************************************************************/
package com.fujitsu.futurity.bp.custom.common;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import com.fujitsu.futurity.bp.x21.bpm.ServiceComponentRequestInvoker;
import com.fujitsu.futurity.bp.x21.bpm.db.SessionHandle;
import com.fujitsu.futurity.bp.x21.bpm.exception.RequestParameterException;
import com.fujitsu.futurity.bp.x21.bpm.parameter.IRequestParameterReadWrite;
import com.fujitsu.futurity.bp.x21.cc.AbstractCommonComponent;
import com.fujitsu.futurity.bp.x21.cc.exception.SCCallException;
import com.fujitsu.futurity.common.JCMConstants;
import com.fujitsu.futurity.common.x01.sc.SCControlMapKeys;
import com.fujitsu.futurity.mapping.bp.common.TemplateErrorUtil;
import com.fujitsu.futurity.model.base.CAANMsg;
import com.fujitsu.futurity.model.common.JCMAPLConstMgr;

import eo.common.constant.JCKStrConst;
import eo.common.constant.JKKStrConst;
import eo.common.util.JPCDateUtil;
import eo.ejb.cbs.cbsmsg.ECK0151D010CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK0191B001CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK0191B001CBSMsg1List;
import eo.ejb.cbs.cbsmsg.EKK0451B010CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK2141B001CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK2141B001CBSMsg1List;

/**
 * 指示書(F回線契約に紐づく各種サービス契約の情報)作成部品。<p>
 * <BR>
 * @author 富士通
 */
public class JCKKisnKeiHmdkShijiAddCC extends AbstractCommonComponent
{
	/** 旧ICSコード変換一覧照会 */
	private static final String TEMPLATE_ID_EKK2141B001 = "EKK2141B001";
	/** 割引サービス契約一覧照会（割引サービス指定） */
	private static final String TEMPLATE_ID_EKK0451B010 = "EKK0451B010";
	/** サービス契約内訳<eo光電話>一覧照会（サービス契約番号） */
	private static final String TEMPLATE_ID_EKK0191B001 = "EKK0191B001";
	/** 指示書登録 */
	private static final String TEMPLATE_ID_ECK0151D010 = "ECK0151D010";
	
	/** 連携先システム識別コード "02":AxM */
	private static final String RNK_SAKI_SYS_SKBT_CD_AXM = "02";
	/** 旧ICSコード変換種別コード "04":料金プランコード */
	private static final String OLD_ICS_CD_CHG_SBT_CD_PPLAN_CD = "04";
	
	/** ０埋め */
	private static final String ZERO_PAD_000 = "000";
	/** ０埋め */
	private static final String ZERO_PAD_00 = "00";
	/** 指示書.対象テーブルID "TNM00040":登録、更新時 */
	private static final String SJISHO_TRGT_TABLE_ID_ADD_UPD = "TNM00040";
	/** 指示書.結果フラグ "0":未実行 */
	private static final String SJISHO_RSLT_FLG_MIJIKKO = "0";
	/** 指示書.パラメータ有効数 "13" */
	private static final String SJISHO_PARAMETER_YK_CNT_13 = "13";
	/** 指示書.適用終了日 "20991231" */
	private static final String SJISHO_TENDYMD = "20991231";
	/** 指示書.無効フラグ "0":有効 */
	private static final String SJISHO_MKFLG_YK = "0";
	
	/**
	 * 指示書作成処理を行う。
	 * 
	 * @param handle
	 * @param param
	 * @param fixedText
	 * @return IRequestParameterReadWrite
	 * @throws Throwable
	 */
	@SuppressWarnings("unchecked")
	public IRequestParameterReadWrite execMakeSjisho(SessionHandle handle, 
												IRequestParameterReadWrite param, 
												String fixedText) throws Throwable
	{
		// SC呼び出し部品のインスタンス生成（引数にはログに出力するクラス名を渡す。空文字を設定した場合はログに出力されない）
		ServiceComponentRequestInvoker scCall = new ServiceComponentRequestInvoker();
		
		HashMap<String, Object> ccMsg = (HashMap<String, Object>)param.getData(fixedText);
		
		Map workMap = param.getMappingWorkArea();
		HashMap workDataMap = (HashMap)workMap.get("WORK");
		String mtsysid = (String)workDataMap.get("sj_mt_sys_id");
		String sksysid = (String)workDataMap.get("sj_sk_sys_id");
		String svcKeiNo = (String)workDataMap.get("sj_svc_kei_no");
		String svcCd = (String)workDataMap.get("sj_svc_cd");
		String prcGrpCd = (String)workDataMap.get("sj_prc_grp_cd");
		String pcrsCd = (String)workDataMap.get("sj_pcrs_cd");
		String pplanCd = (String)workDataMap.get("sj_pplan_cd");
		String shosaYmd = (String)workDataMap.get("sj_shosa_ymd");
		String addDtm = (String)workDataMap.get("sj_add_dtm");
		String addOpeacnt = (String)workDataMap.get("sj_add_opeacnt");
		String updDtm = (String)workDataMap.get("sj_upd_dtm");
		String updOpeacnt = (String)workDataMap.get("sj_upd_opeacnt");
		
		String[] params = new String[6];
		params[0] = svcKeiNo;
		params[1] = addDtm;
		params[2] = addOpeacnt;
		params[3] = updDtm;
		params[4] = updOpeacnt;
		params[5] = svcCd;
		
		ArrayList sjishoMakeList = null;
		
		// 旧ICSコード変換一覧照会
		Object[][] ekk2141b001InMsg = editInMsgEKK2141B001(prcGrpCd, pcrsCd, pplanCd);
		CAANMsg[] ekk2141b001outMsg = callSC(handle, scCall, param, fixedText, ekk2141b001InMsg).getCAANMsgList(EKK2141B001CBSMsg.EKK2141B001CBSMSG1LIST);
		
		if (ekk2141b001outMsg == null || ekk2141b001outMsg.length == 0)
		{
			return param;
		}
		
		// 回線系サービス（ｅｏ光ネット）
		// サービスコード "01":インターネットサービス
		// 編集値：旧ICSコード変換.旧ICS契約サービスコード＋旧ICSコード変換.旧ICS料金プランコード
		if (JKKStrConst.CD00130_01.equals(svcCd))
		{
			// 1.ダミー指示書作成
			// ※分割元または併合元のみ作成 対象料金グループコード = "02":ｅｏ光ネットホームタイプ または "03":ｅｏ光ネットメゾンタイプ
			// 2.指示書(F回線契約に紐づく各種サービス契約の情報)用サービスコード編集
			sjishoMakeList = makeSvcCdForNet(handle, scCall, param, fixedText, ekk2141b001outMsg, svcKeiNo, params, mtsysid, prcGrpCd);
		}
		// 回線系サービス（ｅｏ光電話）
		// サービスコード "02":電話サービス
		// 編集値：旧ICSコード変換.旧ICS付加サービス種別コード＋サービス契約内訳<eo光電話>.電話番号順番(ゼロ埋め3桁)
		else if (JKKStrConst.CD00130_02.equals(svcCd))
		{
			// 旧ICSコード変換.旧ICS付加サービス種別コード
			String oldIcsHukaSvcSbtCd = ekk2141b001outMsg[0].getString(EKK2141B001CBSMsg1List.OLD_ICS_HUKA_SVC_SBT_CD);
			// 編集
			sjishoMakeList = makeSvcCdForTel(handle, scCall, param, fixedText, oldIcsHukaSvcSbtCd, svcKeiNo);
		}
		// 回線系サービス（上記以外）
		// 以外
		else
		{
			// 編集値：旧ICSコード変換.旧ICS契約サービスコード＋"000"
			StringBuilder builder = new StringBuilder();
			builder.append(ekk2141b001outMsg[0].getString(EKK2141B001CBSMsg1List.OLD_ICS_KEI_SVC_CD) );
			builder.append(ZERO_PAD_000);
			sjishoMakeList = new ArrayList();
			sjishoMakeList.add(builder.toString());
		}
		
		Object[][] eck0151d010InMsg = null;
		
		for (int i=0; i<sjishoMakeList.size(); i++)
		{
			// 分割元または併合元
			eck0151d010InMsg = editInMsgECK0151D010(params, mtsysid, SJISHO_MKFLG_YK, shosaYmd, JPCDateUtil.addDay(JPCBPCommon.getOpeDate(null), -1), (String)sjishoMakeList.get(i));
			callSC(handle, scCall, param, fixedText, eck0151d010InMsg);
			
			// 分割先または併合先
			eck0151d010InMsg = editInMsgECK0151D010(params, sksysid, SJISHO_MKFLG_YK, JPCBPCommon.getOpeDate(null), SJISHO_TENDYMD, (String)sjishoMakeList.get(i));
			callSC(handle, scCall, param, fixedText, eck0151d010InMsg);
		}
		
		return param;
	}
	
	/**
	 * @param handle
	 * @param scCall
	 * @param param
	 * @param fixedText
	 * @param ekk2141b001outMsg
	 * @param svcKeiNo
	 * @param params
	 * @param mtsysid
	 * @param String prcGrpCd
	 * @return String
	 */
	@SuppressWarnings("unchecked")
	private ArrayList makeSvcCdForNet(
										SessionHandle handle, 
										ServiceComponentRequestInvoker scCall, 
										IRequestParameterReadWrite param, 
										String fixedText, 
										CAANMsg[] ekk2141b001outMsg, 
										String svcKeiNo, 
										String[] params, 
										String mtsysid, 
										String prcGrpCd) throws Exception
	{
		ArrayList list = new ArrayList();
		StringBuilder svcCd = new StringBuilder();
		String oldIcsPplanCd = "";		// 旧ICS料金プランコード
		String oldIcsKeiSvcCd = "";		// 旧ICS契約サービスコード
		
		// 旧ICSコード変換が１件（即割以外(長割)１レコード）
		if (ekk2141b001outMsg.length == 1)
		{
			oldIcsKeiSvcCd = ekk2141b001outMsg[0].getString(EKK2141B001CBSMsg1List.OLD_ICS_KEI_SVC_CD);
			oldIcsPplanCd = ekk2141b001outMsg[0].getString(EKK2141B001CBSMsg1List.OLD_ICS_PPLAN_CD);
		}
		// 旧ICSコード変換が複数件＝２レコード（即割１レコード、即割以外(長割)１レコード）の場合
		else
		{
			CAANMsg msg = null;
			
			// "即割"データが存在する
			if (isExistSokuWari(handle, scCall, param, fixedText, svcKeiNo))
			{
/* ++++++++++ v4.00.01 追加開始 ++++++++++ */
				// 該当サービス契約.料金グループコード = "02":ｅｏ光ネットホームタイプ または "03":ｅｏ光ネットメゾンタイプ
				if (isMakeDummy(prcGrpCd))
				{
					// 即割"無"でダミー指示書作成
					execDummySjishoAdd(handle, scCall, param, fixedText, ekk2141b001outMsg, params, mtsysid, false);
				}
/* ++++++++++ v4.00.01 追加終了 ++++++++++ */
				
				// 旧ICSコード変換.即割有無 = "有"のレコードからデータ取得
				msg = getTargetMsg(ekk2141b001outMsg, true);
				
				if (null != msg) {
					oldIcsKeiSvcCd = msg.getString(EKK2141B001CBSMsg1List.OLD_ICS_KEI_SVC_CD);
					oldIcsPplanCd = msg.getString(EKK2141B001CBSMsg1List.OLD_ICS_PPLAN_CD);
				}
			}
			// "即割"データが存在しない
			else
			{
/* ++++++++++ v4.00.01 追加開始 ++++++++++ */
				// 該当サービス契約.料金グループコード = "02":ｅｏ光ネットホームタイプ または "03":ｅｏ光ネットメゾンタイプ
				if (isMakeDummy(prcGrpCd))
				{
					// 即割"有"でダミー指示書作成
					execDummySjishoAdd(handle, scCall, param, fixedText, ekk2141b001outMsg, params, mtsysid, true);
				}
/* ++++++++++ v4.00.01 追加終了 ++++++++++ */
				
				// 旧ICSコード変換.即割有無 = "無"のレコードからデータ取得
				msg = getTargetMsg(ekk2141b001outMsg, false);
				
				if (null != msg) {
					oldIcsKeiSvcCd = msg.getString(EKK2141B001CBSMsg1List.OLD_ICS_KEI_SVC_CD);
					oldIcsPplanCd = msg.getString(EKK2141B001CBSMsg1List.OLD_ICS_PPLAN_CD);
				}
			}
		}
		
		// 旧ICSコード変換.旧ICS契約サービスコード＋旧ICSコード変換.旧ICS料金プランコード
		svcCd.append(oldIcsKeiSvcCd);
		svcCd.append(oldIcsPplanCd);
		
		list.add(svcCd.toString());
		
		return list;
	}
	
	/**
	 * @param handle
	 * @param scCall
	 * @param param
	 * @param fixedText
	 * @param oldIcsHukaSvcSbtCd
	 * @param svcKeiNo
	 * @return String
	 */
	@SuppressWarnings("unchecked")
	private ArrayList makeSvcCdForTel(
										SessionHandle handle, 
										ServiceComponentRequestInvoker scCall, 
										IRequestParameterReadWrite param, 
										String fixedText, 
										String oldIcsHukaSvcSbtCd, 
										String svcKeiNo) throws Exception
	{
		ArrayList telnoJunList = new ArrayList();
		StringBuilder svcCd = null;
		
		// サービス契約内訳<eo光電話>一覧照会（サービス契約番号）
		Object[][] ekk0191b001InMsg = editInMsgEKK0191B001(svcKeiNo);
		CAANMsg[] ekk0191b001outMsg = callSC(handle, scCall, param, fixedText, ekk0191b001InMsg).getCAANMsgList(EKK0191B001CBSMsg.EKK0191B001CBSMSG1LIST);
		
		// 検索結果数分指示書作成
		for (int i=0; i<ekk0191b001outMsg.length; i++)
		{
			// 旧ICSコード変換.旧ICS付加サービス種別コード＋サービス契約内訳<eo光電話>.電話番号順番(ゼロ埋め3桁)
			svcCd = new StringBuilder();
			// "00"+サービス契約内訳<eo光電話>.電話番号順番
			svcCd.append(oldIcsHukaSvcSbtCd);
			svcCd.append(ZERO_PAD_00);
			svcCd.append(ekk0191b001outMsg[i].getString(EKK0191B001CBSMsg1List.TELNO_JUN));
			
			telnoJunList.add(svcCd.toString());
		}
		
		return telnoJunList;
	}
	
/* ++++++++++ v4.00.01 追加開始 ++++++++++ */
	/**
	 * @param handle
	 * @param scCall
	 * @param param
	 * @param fixedText
	 * @param ekk2141b001outMsg
	 * @param params
	 * @param mtsysid
	 * @param sokuWariUm
	 */
	private void execDummySjishoAdd(
										SessionHandle handle, 
										ServiceComponentRequestInvoker scCall, 
										IRequestParameterReadWrite param, 
										String fixedText, 
										CAANMsg[] ekk2141b001outMsg, 
										String[] params, 
										String mtsysid, 
										boolean sokuWariUm) throws Exception
	{
		CAANMsg msg = null;
		StringBuilder svcCd = new StringBuilder();
		String oldIcsKeiSvcCd = "";		// 旧ICS契約サービスコード
		String oldIcsPplanCd = "";		// 旧ICS料金プランコード
		
		//*****************************************
		// ダミー指示書作成
		// ※分割元または併合元のみ作成
		//*****************************************
		// 旧ICSコード変換.即割有無 = "有"または"無"のレコードからデータ取得
		msg = getTargetMsg(ekk2141b001outMsg, sokuWariUm);
		if (null != msg) {
			oldIcsKeiSvcCd = msg.getString(EKK2141B001CBSMsg1List.OLD_ICS_KEI_SVC_CD);
			oldIcsPplanCd = msg.getString(EKK2141B001CBSMsg1List.OLD_ICS_PPLAN_CD);
		}
		
		svcCd.append(oldIcsKeiSvcCd);
		svcCd.append(oldIcsPplanCd);
		
		// 上りメッセージ作成
		Object[][] eck0151d010InMsg = editInMsgECK0151D010(
															params, 
															mtsysid, 
															SJISHO_MKFLG_YK, 
															JPCBPCommon.getOpeDate(null), 
															JPCDateUtil.addDay(JPCBPCommon.getOpeDate(null), -1), 
															svcCd.toString());
		
		// 実行
		callSC(handle, scCall, param, fixedText, eck0151d010InMsg);
	}
	
	/**
	 * @param prcGrpCd
	 * @return boolean
	 */
	private boolean isMakeDummy(String prcGrpCd)
	{
		// "02":ｅｏ光ネットホームタイプ
		if (JCKStrConst.PRC_GRP_CD_EOH_NET_HOME.equals(prcGrpCd))
		{
			return true;
		}
		
		// "03":ｅｏ光ネットメゾンタイプ
		if (JCKStrConst.PRC_GRP_CD_EOH_NET_MAISON.equals(prcGrpCd))
		{
			return true;
		}
		
		return false;
	}
	
/* ++++++++++ v4.00.01 追加終了 ++++++++++ */
	
	/**
	 * @param prcGrpCd
	 * @param pcrsCd
	 * @param pplanCd
	 * @return Object[][]
	 */
	private Object[][] editInMsgEKK2141B001(String prcGrpCd, String pcrsCd, String pplanCd)
	{
		// 旧ICSコード変換一覧照会
		Object[][] inList = {
				{EKK2141B001CBSMsg.TEMPLATEID, TEMPLATE_ID_EKK2141B001},
				{EKK2141B001CBSMsg.FUNC_CODE,  "1"},
				{EKK2141B001CBSMsg.KEY_RNK_SAKI_SYS_SKBT_CD,  RNK_SAKI_SYS_SKBT_CD_AXM},
				{EKK2141B001CBSMsg.KEY_OLD_ICS_CD_CHG_SBT_CD,  OLD_ICS_CD_CHG_SBT_CD_PPLAN_CD},
				{EKK2141B001CBSMsg.KEY_PRC_GRP_CD,  prcGrpCd},
				{EKK2141B001CBSMsg.KEY_PCRS_CD,  pcrsCd},
				{EKK2141B001CBSMsg.KEY_PPLAN_CD,  pplanCd}
		};
		
		return inList;
	}
	
	/**
	 * @param sysid
	 * @param rrksNo
	 * @return Object[][]
	 */
	private Object[][] editInMsgEKK0451B010(String svcKeiNo)
	{
		// 割引サービス契約一覧照会（割引サービス指定）
		Object[][] inList = {
				{EKK0451B010CBSMsg.TEMPLATEID, TEMPLATE_ID_EKK0451B010},
				{EKK0451B010CBSMsg.FUNC_CODE,  "1"},
				{EKK0451B010CBSMsg.KEY_SVC_KEI_NO,  svcKeiNo},
				{EKK0451B010CBSMsg.KEY_WRIB_SVC_CD,  JKKStrConst.WRIB_SVC_SOKU_WRIB}	// 割引サービスコード "W00000021":即割
		};
		
		return inList;
	}
	
	/**
	 * @param prcGrpCd
	 * @param pcrsCd
	 * @param pplanCd
	 * @return Object[][]
	 */
	private Object[][] editInMsgEKK0191B001(String svcKeiNo)
	{
		// サービス契約内訳<eo光電話>一覧照会（サービス契約番号）
		Object[][] inList = {
				{EKK0191B001CBSMsg.TEMPLATEID, TEMPLATE_ID_EKK0191B001},
				{EKK0191B001CBSMsg.FUNC_CODE,  "2"},
				{EKK0191B001CBSMsg.KEY_SVC_KEI_NO,  svcKeiNo}
		};
		
		return inList;
	}
	
	/**
	 * @param params
	 * @param sysid
	 * @param mkFlg
	 * @param svcCd
	 * @return Object[][]
	 */
	private Object[][] editInMsgECK0151D010(String[] params, String sysid, String mkFlg, String sjisho_tstaymd, String sjisho_tendymd, String svcCd)
	{
		// 指示書登録
		Object[][] inList = {
				{ECK0151D010CBSMsg.TEMPLATEID, TEMPLATE_ID_ECK0151D010},
				{ECK0151D010CBSMsg.FUNC_CODE, "1"},
				{ECK0151D010CBSMsg.TRN_CD, JCKStrConst.SJISHO_TRN_CD_REPLICA_API},
				{ECK0151D010CBSMsg.TRGT_TABLE_ID, SJISHO_TRGT_TABLE_ID_ADD_UPD},
				{ECK0151D010CBSMsg.TRAN_TRGT_SYSID, sysid},
				{ECK0151D010CBSMsg.RSLT_FLG, SJISHO_RSLT_FLG_MIJIKKO},
				{ECK0151D010CBSMsg.PARAMETER_YK_CNT, SJISHO_PARAMETER_YK_CNT_13},
				{ECK0151D010CBSMsg.PARAMETER_1,  sysid},
				{ECK0151D010CBSMsg.PARAMETER_2,  params[0]},
				{ECK0151D010CBSMsg.PARAMETER_3,  sjisho_tstaymd},
				{ECK0151D010CBSMsg.PARAMETER_4,  sjisho_tendymd},
				{ECK0151D010CBSMsg.PARAMETER_5,  mkFlg},
				{ECK0151D010CBSMsg.PARAMETER_6,  params[1]},
				{ECK0151D010CBSMsg.PARAMETER_7,  params[2]},
				{ECK0151D010CBSMsg.PARAMETER_8,  null},
				{ECK0151D010CBSMsg.PARAMETER_9,  params[3]},
				{ECK0151D010CBSMsg.PARAMETER_10, params[4]},
				{ECK0151D010CBSMsg.PARAMETER_11, null},
				{ECK0151D010CBSMsg.PARAMETER_12, params[5]},
				{ECK0151D010CBSMsg.PARAMETER_13, svcCd}};
		
		return inList;
	}
	
	/**
	 * @param handle
	 * @param scCall
	 * @param param
	 * @param fixedText
	 * @param svcKeiNo
	 * @return boolean
	 */
	private boolean isExistSokuWari(
										SessionHandle handle, 
										ServiceComponentRequestInvoker scCall, 
										IRequestParameterReadWrite param, 
										String fixedText, 
										String svcKeiNo) throws Exception
	{
		// 割引サービス契約一覧照会（割引サービス指定）
		Object[][] ekk0451b010InMsg = editInMsgEKK0451B010(svcKeiNo);
		CAANMsg[] ekk0451b010outMsg = callSC(handle, scCall, param, fixedText, ekk0451b010InMsg).getCAANMsgList(EKK0451B010CBSMsg.EKK0451B010CBSMSG1LIST);
		
		// "即割"の割引サービス契約が存在
		if (ekk0451b010outMsg != null && ekk0451b010outMsg.length > 0)
		{
			return true;
		}
		
		return false;
	}
	
	/**
	 * @param outMsg
	 * @return boolean
	 */
	private CAANMsg getTargetMsg(CAANMsg[] outMsg, boolean sokuWariFlg)
	{
		for (int i=0; i<outMsg.length; i++)
		{
			// 即割
			if (sokuWariFlg)
			{
				// 即割有無 = "有"
				if (JKKStrConst.CD_DIV_UM_ARI.equals(outMsg[i].getString(EKK2141B001CBSMsg1List.SOKU_WARI_UM)))
				{
					return outMsg[i];
				}
			}
			else
			{
				// 即割有無 = "無"
				if (JKKStrConst.CD_DIV_UM_NASHI.equals(outMsg[i].getString(EKK2141B001CBSMsg1List.SOKU_WARI_UM)))
				{
					return outMsg[i];
				}
			}
		}
		
		return null;
	}
	
	/**
	 * SC(サービスインターフェイス）を呼び出す。
	 * 
	 * @param handle
	 * @param scCall
	 * @param param
	 * @param dataMapKey
	 * @param mappingData
	 * @return CAANMsg
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	private CAANMsg callSC(SessionHandle handle, 
							ServiceComponentRequestInvoker scCall, 
							IRequestParameterReadWrite param, 
							String dataMapKey,
							Object[][] mappingData) throws Exception
	{
		HashMap<String, Object> paramMap = editInMsg(param, mappingData);
		
		Map<?, ?> result = scCall.run(paramMap, handle);
		
		CAANMsg[] templates = (CAANMsg[])result.get(JCMConstants.TEMPLATE_LIST_KEY);
		CAANMsg msg = templates[0];
		
		// リターンコード取得
		Object return_code = result.get(JCMConstants.RET_CD_INT_KEY);
		int status = msg.getInt(JCMConstants.STATUS_INT_KEY);
		
		editErrorInfoCom(param, templates, (Integer)return_code, dataMapKey, mappingData);
		
		//エラー情報のマップを取得
		ArrayList<Object> errList = (ArrayList<Object>)param.getControlMapData(SCControlMapKeys.ERROR_INFO);
		if (errList == null)
		{
			errList = new ArrayList<Object>();
		}
		
		// コントロールマップに設定
		param.setControlMapData(SCControlMapKeys.ERROR_INFO, TemplateErrorUtil.getErrorInfo(result, errList));
		
		// 異常の場合、SCCallExceptionを生成してスローする
		if(!("0".equals(return_code.toString()) && 0 == status))
		{
			throw new SCCallException("戻り値不正", return_code.toString(), status);
		}
		return msg;
	}
	
	/**
	 * @param param
	 * @param mappingData
	 * @return HashMap<String, Object>
	 * @throws RequestParameterException
	 */
	private HashMap<String, Object> editInMsg(IRequestParameterReadWrite param,
												Object[][] mappingData) throws RequestParameterException
	{
		HashMap<String, Object> paramMap = new HashMap<String, Object>();
		
		// 【取得元：電文ヘッダ(ヘッダ)】
		// 電文ID
		paramMap.put(JCMConstants.TRANZACTION_ID_KEY, param.getTelegramID());
		// ユースケースID
		paramMap.put(JCMConstants.USECASE_ID_KEY, param.getUsecaseID());
		// オペレーションID
		paramMap.put(JCMConstants.OPERATION_ID_KEY, param.getOperationID());
		// サービス呼び出し区分
		paramMap.put(JCMConstants.CALL_TYPE_KEY, param.getCallType());
		
		// 【取得元：ユーザエリア(コントロールマップ)】
		// 依頼先ホスト名
		paramMap.put(JCMConstants.CLIENT_HOST_NAME_KEY, param.getControlMapData(SCControlMapKeys.REQ_HOSTNAME));
		// 依頼元IPアドレス
		paramMap.put(JCMConstants.CLIENT_IP_ADDRESS_KEY, param.getControlMapData(SCControlMapKeys.REQ_HOSTIP));
		// 依頼元画面ID
		paramMap.put(JCMConstants.INVOKE_GAMEN_ID_KEY, param.getControlMapData(SCControlMapKeys.REQ_VIEWID));
		// オペレータID
		paramMap.put(JCMConstants.OPERATOR_ID_KEY, param.getControlMapData(SCControlMapKeys.OPERATOR_ID));
		
		String svcIf = (String)mappingData[0][1];
		
		CAANMsg template = new CAANMsg(String.format("eo.ejb.cbs.cbsmsg.%sCBSMsg", svcIf));
		
		// オペレータID
		template.set(JCMConstants.OPERATOR_ID_KEY, param.getControlMapData(SCControlMapKeys.OPERATOR_ID));
		// 運用日付
		template.set(JCMConstants.OPERATE_DATE_KEY, param.getControlMapData(SCControlMapKeys.OPE_DATE));
		// 運用日時
		template.set(JCMConstants.OPERATE_DATETIME_KEY, param.getControlMapData(SCControlMapKeys.OPE_TIME));
		
		for (int i = 0; i < mappingData.length; i++)
		{
			if ("".equals(mappingData[i][1]))
			{
				template.setNull((String)mappingData[i][0]);
			}
			else
			{
				template.set((String)mappingData[i][0], mappingData[i][1]);
			}
		}
		
		CAANMsg[] templates = new CAANMsg[1];
		templates[0] = template;
		paramMap.put(JCMConstants.TEMPLATE_LIST_KEY, templates);
		
		return paramMap;
	}
	
	/**
	 * 
	 * @param param
	 * @param templates
	 * @param returnCode
	 * @param dataMapKey
	 * @param mappingData
	 * @return IRequestParameterReadWrite
	 * @throws RequestParameterException
	 */
	@SuppressWarnings("unchecked")
	private IRequestParameterReadWrite editErrorInfoCom(IRequestParameterReadWrite param,
														CAANMsg[] templates, 
														int returnCode,
														String dataMapKey,
														Object[][] mappingData) throws RequestParameterException
	{
		// 本来はサービスインターフェイス分の処理が必要
		CAANMsg template = templates[0];
		int templateStatus = template.getInt(JCMConstants.STATUS_INT_KEY);
		
		if (returnCode != 0)
		{
			templateStatus = 9000;
		}
		
		if (JCMAPLConstMgr.getString("RETURN_MESSAGE_" + String.format("%1$04d", templateStatus)) == null)
		{
			templateStatus = 0;
		}
		
		int bpStatus = 0;
		Object obj = param.getControlMapData(SCControlMapKeys.RETURN_CODE);
		if (obj == null)
		{
			bpStatus = -1;
		}
		else
		{
			bpStatus = Integer.parseInt((String)param.getControlMapData(SCControlMapKeys.RETURN_CODE));
		}
		
		if (templateStatus > bpStatus)
		{
			// BPにサービスコンポーネントのステータスを設定する。
			String formatStatus = String.format("%1$04d", templateStatus);
			String message = JCMAPLConstMgr.getString("RETURN_MESSAGE_" + formatStatus);
			param.setControlMapData(SCControlMapKeys.RETURN_CODE, formatStatus);
			param.setControlMapData(SCControlMapKeys.RETURN_MESSAGE, message);
		}
		
		HashMap<String, String> inMap = null;
		
		// ユーザデータ情報
		inMap = (HashMap<String, String>)param.getData(dataMapKey);
		
		for (int i = 0; i < mappingData.length; i++)
		{
			if (((String)mappingData[i][0]).startsWith("key_"))
			{
				if (!template.isNull(mappingData[i][0] + "_err"))
				{
					if (!inMap.containsKey(mappingData[i][0] + "_err"))
					{
						inMap.put(mappingData[i][0] + "_err", template.getString(mappingData[i][0] + "_err"));
					}
				}
			}
		}
		return param;
	}
}