/*********************************************************************
 * All Rights reserved, Copyright (c) K-Opticom
 **********************************************************************
 *＜プログラム内容＞
 *   システム名      ：eo顧客基幹システム
 *   モジュール名    ：JFUSplitAddressInfoCC
 *   ソースファイル名：JFUSplitAddressInfoCC.java
 *   作成者          ：富士通
 *   日付            ：2011年10月01日
 *＜機能概要＞
 *   住所情報分割処理部品です。
 *＜修正履歴＞
 *   バージョン  修正日       修正者      修正内容
 *   v1.00.00    2011/10/01   FJ）馬場    新規作成
 *   v1.01.00    2013/02/21   FJ) 大塚    ファミリーパック対応
 *   v5.00.00    2013/05/02   FJ) 岡井    【No.732】ファミリーパック番地号対応
 *   v7.00.00    2014/01/20   FJ) 川瀬   【TAI-2014-0000004】多機能ルーター(機器追加)JFUNewAddKkopSvcKeiCC通過時対応
 *   v10.00.00   2014/09/05   FJ) 清水    OM-2014-0002910
 **********************************************************************/
package com.fujitsu.futurity.bp.custom.common;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

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.common.JCMConstants;
import com.fujitsu.futurity.common.x01.sc.SCControlMapKeys;
import com.fujitsu.futurity.model.base.CAANMsg;
import com.fujitsu.futurity.model.common.JCMAPLConstMgr;

import eo.common.constant.JFUStrConst;
import eo.ejb.cbs.cbsmsg.EZM0081B050CBSMsg;
import eo.ejb.cbs.cbsmsg.EZM0081B060CBSMsg;
import eo.ejb.cbs.cbsmsg.EZM0081B060CBSMsg1List;
import eo.ejb.cbs.cbsmsg.EZM0081B070CBSMsg;
import eo.ejb.cbs.cbsmsg.EZM0081B070CBSMsg1List;

/**
 * 住所情報分割処理。
 *
 * @author FJ
 */
public class JFUSplitAddressInfoCC extends AbstractCommonComponent
{

	/** テンプレートID */
	public static final String TEMPLATE_ID = "EZM0081B050";

	/** インマップID */
	public static final String INMAP_ID = "JFUGetAddressCodeMap";

	/** アウトマップID */
	public static final String OUTMAP_ID = "addressInfoMap";

	/** エラーリスト */
	private static final String ERR_LIST = "err_list";

	/** RETURN_MESSAGE */
	private static final String RETURN_MESSAGE = "RETURN_MESSAGE_";

	/** Status Format */
	private static final String STATUS_FORMAT = "%1$04d";

	/** コンポーネント名称 */
	private String cName = JFUStrConst.EMPTY;

	/** 定数 "0" */
	public static final String ZERO = "0";

	/** 機能コード1 */
	private static final String func_code_key_1 = "1";

	/** 住所コード（例外発生時） **/
	private static final String ad_code_0 = "00000000000";


	/** 本登録のファミリーパックのキー */
	private static final String FUSV016005CC = "FUSV016005CC";
	/** 一括登録のファミリーパックのキー */
	private static final String FUSV016118CC = "FUSV016118CC";
	/** JFUNewAddKkopSvcKeiCCのキー */
	private static final String FUSV016020CC = "FUSV016020CC";

	/** 本登録の利用場所住所分割部品のキー */
	private static final String FUSV016006CC = "FUSV016006CC";
	/** 一括登録の利用場所住所分割部品のキー */
	private static final String FUSV016102CC = "FUSV016102CC";

	/** IN項目:機器送付先住所コード */
	private static final String IN_PARAM_KIKI_SOHUS_AD_CD = "kiki_sohus_ad_cd";
	/** IN項目:機器送付先都道府県名 */
	private static final String IN_PARAM_KIKI_SOHUS_STATE_NM = "kiki_sohus_state_nm";
	/** IN項目:機器送付先市区町村名 */
	private static final String IN_PARAM_KIKI_SOHUS_CITY_NM = "kiki_sohus_city_nm";
	/** IN項目:機器送付先大字通称名 */
	private static final String IN_PARAM_KIKI_SOHUS_OAZTSU_NM = "kiki_sohus_oaztsu_nm";
	/** IN項目:機器送付先字丁目名 */
	private static final String IN_PARAM_KIKI_SOHUS_AZCHO_NM = "kiki_sohus_azcho_nm";
	/** IN項目:機器送付先番地号 */
	private static final String IN_PARAM_KIKI_SOHUS_BNCHIGO = "kiki_sohus_bnchigo";



	/**
	 * 住所情報分割処理
	 *
	 * @param handle
	 *            セッションマネージャなどを持ったハンドル
	 * @param param
	 *            モデルグループ、コントロールマップを含むパラメータオブジェクト
	 * @param fixedText
	 *            ユーザ任意文字列
	 * @return IRequestParameterReadWrite パラメータオブジェクト
	 * @exception Exceptionがスローされます。
	 *
	 */
	public IRequestParameterReadWrite splitAddressInfo(SessionHandle handle, IRequestParameterReadWrite param, String fixedText) throws Exception
	{

		HashMap outMap = new HashMap(10);

		// SC呼び出し部品のインスタンスを生成します。
		ServiceComponentRequestInvoker scCall = new ServiceComponentRequestInvoker();

		// マップのキー値を取得します。
		cName = fixedText;

		// ユーザデータ情報を取得します。
		HashMap<String, Object> inMap = (HashMap)param.getData(cName);

		if (inMap == null)
		{
			return param;
		}

		// 字は分割しないため、あらかじめ保持しておきます。
		String aza = JFUStrConst.EMPTY;
		if (null == (String)inMap.get("aza"))
		{
			aza = JFUStrConst.EMPTY;
		}
		else
		{
			aza = (String)inMap.get("aza");
		}
		try
		{
			// ■丁目・番地等
			// 都道府県情報の一覧照会を行います。
			HashMap<String, Object> paramMap = editStateInMsg(param); // 上りマッピング
			Map<?, ?> stateList = scCall.run(paramMap, handle); // SC呼び出し
			HashMap<?, ?> splitStateMap = editStateOutMsg(param, stateList); // 下りマッピング

			// 分割後の都道府県名、市区町村名を取得します。
			String state = (String)splitStateMap.get("state");
			String city = (String)splitStateMap.get("city");

			// 大字通称名に字を設定します。
			String oaztsu = aza;

			// 字丁目情報の一覧照会を行います。
			paramMap = editChoBnchiInMsg(param, splitStateMap); // 上りマッピング
			Map<?, ?> chomeList = scCall.run(paramMap, handle); // SC呼び出し
			HashMap<?, ?> splitAzchoMap = editChomeOutMsg(param, chomeList); // 下りマッピング

			// 分割後の都道府県名、市区町村名を取得します。
			String azcho = (String)splitAzchoMap.get("azcho");
			String bnchi = (String)splitAzchoMap.get("bnchi");
			String chome_bnchi = (String)splitAzchoMap.get("chome_bnchi");

			// 住所コード取得部品に渡すマップを生成します。
			HashMap<String, Object> map = new HashMap<String, Object>(10);

			// 都道府県名 → 住所コード取得マップ.都道府県名
			if (null == state)
			{
				map.put(EZM0081B050CBSMsg.KEY_STATE_NM, JFUStrConst.EMPTY);
			}
			else
			{
				map.put(EZM0081B050CBSMsg.KEY_STATE_NM, state);
			}

			// 市区町村名 → 住所コード取得マップ.市区町村名
			if (null == city)
			{
				map.put(EZM0081B050CBSMsg.KEY_CITY_NM, JFUStrConst.EMPTY);
			}
			else
			{
				map.put(EZM0081B050CBSMsg.KEY_CITY_NM, city);
			}

			// 大字通称名 → 住所コード取得マップ.大字通称名
			if (null == oaztsu)
			{
				map.put(EZM0081B050CBSMsg.KEY_OAZTSU_NM, JFUStrConst.EMPTY);
			}
			else
			{
				map.put(EZM0081B050CBSMsg.KEY_OAZTSU_NM, oaztsu);
			}

			// 字丁目名 → 住所コード取得マップ.字丁目名
			if (null == azcho)
			{
				map.put(EZM0081B050CBSMsg.KEY_AZCHO_NM, JFUStrConst.EMPTY);
			}
			else
			{
				map.put(EZM0081B050CBSMsg.KEY_AZCHO_NM, azcho);
			}

			// 番地 → 編集前番地
			if (null == bnchi)
			{
				map.put("before_bnchi", JFUStrConst.EMPTY);
			}
			else
			{
				map.put("before_bnchi", bnchi);
			}

			// 丁目・番地 → 編集前丁目・番地
			if (null == chome_bnchi)
			{
				map.put("before_chome_bnchi", JFUStrConst.EMPTY);
			}
			else
			{
				map.put("before_chome_bnchi", chome_bnchi);
			}

			// 住所コード取得部品を呼び出します。
			JFUGetAddressCodeUtil getAddress = new JFUGetAddressCodeUtil();
			outMap = getAddress.getAddressCode(handle, param, map);


			// ユーザデータ情報を取得します。

			// 本登録の情報
			HashMap<String, Object> familyMap1 = (HashMap)param.getData(FUSV016005CC);

			if (familyMap1 != null && FUSV016006CC.equals(cName))
			{
				// 住所コード
				if (outMap.get("ad_cd") == null || JFUStrConst.EMPTY.equals(outMap.get("ad_cd")))
				{
					familyMap1.put(IN_PARAM_KIKI_SOHUS_AD_CD, JFUStrConst.EMPTY);
				}
				else
				{
					familyMap1.put(IN_PARAM_KIKI_SOHUS_AD_CD, outMap.get("ad_cd"));
				}

				// 都道府県名 → 住所コード取得マップ.都道府県名
				if (outMap.get("state_nm") == null || JFUStrConst.EMPTY.equals(outMap.get("state_nm")))
				{
					familyMap1.put(IN_PARAM_KIKI_SOHUS_STATE_NM, JFUStrConst.EMPTY);
				}
				else
				{
					familyMap1.put(IN_PARAM_KIKI_SOHUS_STATE_NM, outMap.get("state_nm"));
				}

				// 市区町村名 → 住所コード取得マップ.市区町村名
				if (outMap.get("city_nm") == null || JFUStrConst.EMPTY.equals(outMap.get("city_nm")))
				{
					familyMap1.put(IN_PARAM_KIKI_SOHUS_CITY_NM, JFUStrConst.EMPTY);
				}
				else
				{
					familyMap1.put(IN_PARAM_KIKI_SOHUS_CITY_NM, outMap.get("city_nm"));
				}

				// 大字通称名 → 住所コード取得マップ.大字通称名
				if (outMap.get("oaztsu_nm") == null || JFUStrConst.EMPTY.equals(outMap.get("oaztsu_nm")))
				{
					familyMap1.put(IN_PARAM_KIKI_SOHUS_OAZTSU_NM, JFUStrConst.EMPTY);
				}
				else
				{
					familyMap1.put(IN_PARAM_KIKI_SOHUS_OAZTSU_NM, outMap.get("oaztsu_nm"));
				}

				// 字丁目名 → 住所コード取得マップ.字丁目名
				if (outMap.get("azcho_nm") == null || JFUStrConst.EMPTY.equals(outMap.get("azcho_nm")))
				{
					familyMap1.put(IN_PARAM_KIKI_SOHUS_AZCHO_NM, JFUStrConst.EMPTY);
				}
				else
				{
					familyMap1.put(IN_PARAM_KIKI_SOHUS_AZCHO_NM, outMap.get("azcho_nm"));
				}

				// 番地号 → 住所コード取得マップ.番地号
				if (outMap.get("after_bnchi") == null || JFUStrConst.EMPTY.equals(outMap.get("after_bnchi")))
				{
					familyMap1.put(IN_PARAM_KIKI_SOHUS_BNCHIGO, JFUStrConst.EMPTY);
				}
				else
				{
					familyMap1.put(IN_PARAM_KIKI_SOHUS_BNCHIGO, outMap.get("after_bnchi"));
				}
			}

			// 一括登録の情報
			HashMap<String, Object> familyMap2 = (HashMap)param.getData(FUSV016118CC);

			if (familyMap2 != null && FUSV016102CC.equals(cName))
			{
				// 住所コード
				if (outMap.get("ad_cd") == null || JFUStrConst.EMPTY.equals(outMap.get("ad_cd")))
				{
					familyMap2.put(IN_PARAM_KIKI_SOHUS_AD_CD, JFUStrConst.EMPTY);
				}
				else
				{
					familyMap2.put(IN_PARAM_KIKI_SOHUS_AD_CD, outMap.get("ad_cd"));
				}

				// 都道府県名 → 住所コード取得マップ.都道府県名
				if (outMap.get("state_nm") == null || JFUStrConst.EMPTY.equals(outMap.get("state_nm")))
				{
					familyMap2.put(IN_PARAM_KIKI_SOHUS_STATE_NM, JFUStrConst.EMPTY);
				}
				else
				{
					familyMap2.put(IN_PARAM_KIKI_SOHUS_STATE_NM, outMap.get("state_nm"));
				}

				// 市区町村名 → 住所コード取得マップ.市区町村名
				if (outMap.get("city_nm") == null || JFUStrConst.EMPTY.equals(outMap.get("city_nm")))
				{
					familyMap2.put(IN_PARAM_KIKI_SOHUS_CITY_NM, JFUStrConst.EMPTY);
				}
				else
				{
					familyMap2.put(IN_PARAM_KIKI_SOHUS_CITY_NM, outMap.get("city_nm"));
				}

				// 大字通称名 → 住所コード取得マップ.大字通称名
				if (outMap.get("oaztsu_nm") == null || JFUStrConst.EMPTY.equals(outMap.get("oaztsu_nm")))
				{
					familyMap2.put(IN_PARAM_KIKI_SOHUS_OAZTSU_NM, JFUStrConst.EMPTY);
				}
				else
				{
					familyMap2.put(IN_PARAM_KIKI_SOHUS_OAZTSU_NM, outMap.get("oaztsu_nm"));
				}

				// 字丁目名 → 住所コード取得マップ.字丁目名
				if (outMap.get("azcho_nm") == null || JFUStrConst.EMPTY.equals(outMap.get("azcho_nm")))
				{
					familyMap2.put(IN_PARAM_KIKI_SOHUS_AZCHO_NM, JFUStrConst.EMPTY);
				}
				else
				{
					familyMap2.put(IN_PARAM_KIKI_SOHUS_AZCHO_NM, outMap.get("azcho_nm"));
				}

				// 番地号 → 住所コード取得マップ.番地号
				if (outMap.get("after_bnchi") == null || JFUStrConst.EMPTY.equals(outMap.get("after_bnchi")))
				{
					familyMap2.put(IN_PARAM_KIKI_SOHUS_BNCHIGO, JFUStrConst.EMPTY);
				}
				else
				{
					familyMap2.put(IN_PARAM_KIKI_SOHUS_BNCHIGO, outMap.get("after_bnchi"));
				}
			}


			// JFUNewAddKkopSvcKeiCCの情報
			HashMap<String, Object> newAddKkopSvcKeiCCMap = (HashMap)param.getData(FUSV016020CC);

			if (newAddKkopSvcKeiCCMap != null && FUSV016006CC.equals(cName))
			{
				// 住所コード
				if (outMap.get("ad_cd") == null || JFUStrConst.EMPTY.equals(outMap.get("ad_cd")))
				{
					newAddKkopSvcKeiCCMap.put(IN_PARAM_KIKI_SOHUS_AD_CD, JFUStrConst.EMPTY);
				}
				else
				{
					newAddKkopSvcKeiCCMap.put(IN_PARAM_KIKI_SOHUS_AD_CD, outMap.get("ad_cd"));
				}

				// 都道府県名 → 住所コード取得マップ.都道府県名
				if (outMap.get("state_nm") == null || JFUStrConst.EMPTY.equals(outMap.get("state_nm")))
				{
					newAddKkopSvcKeiCCMap.put(IN_PARAM_KIKI_SOHUS_STATE_NM, JFUStrConst.EMPTY);
				}
				else
				{
					newAddKkopSvcKeiCCMap.put(IN_PARAM_KIKI_SOHUS_STATE_NM, outMap.get("state_nm"));
				}

				// 市区町村名 → 住所コード取得マップ.市区町村名
				if (outMap.get("city_nm") == null || JFUStrConst.EMPTY.equals(outMap.get("city_nm")))
				{
					newAddKkopSvcKeiCCMap.put(IN_PARAM_KIKI_SOHUS_CITY_NM, JFUStrConst.EMPTY);
				}
				else
				{
					newAddKkopSvcKeiCCMap.put(IN_PARAM_KIKI_SOHUS_CITY_NM, outMap.get("city_nm"));
				}

				// 大字通称名 → 住所コード取得マップ.大字通称名
				if (outMap.get("oaztsu_nm") == null || JFUStrConst.EMPTY.equals(outMap.get("oaztsu_nm")))
				{
					newAddKkopSvcKeiCCMap.put(IN_PARAM_KIKI_SOHUS_OAZTSU_NM, JFUStrConst.EMPTY);
				}
				else
				{
					newAddKkopSvcKeiCCMap.put(IN_PARAM_KIKI_SOHUS_OAZTSU_NM, outMap.get("oaztsu_nm"));
				}

				// 字丁目名 → 住所コード取得マップ.字丁目名
				if (outMap.get("azcho_nm") == null || JFUStrConst.EMPTY.equals(outMap.get("azcho_nm")))
				{
					newAddKkopSvcKeiCCMap.put(IN_PARAM_KIKI_SOHUS_AZCHO_NM, JFUStrConst.EMPTY);
				}
				else
				{
					newAddKkopSvcKeiCCMap.put(IN_PARAM_KIKI_SOHUS_AZCHO_NM, outMap.get("azcho_nm"));
				}

				// 番地号 → 住所コード取得マップ.番地号
				if (outMap.get("after_bnchi") == null || JFUStrConst.EMPTY.equals(outMap.get("after_bnchi")))
				{
					newAddKkopSvcKeiCCMap.put(IN_PARAM_KIKI_SOHUS_BNCHIGO, JFUStrConst.EMPTY);
				}
				else
				{
					newAddKkopSvcKeiCCMap.put(IN_PARAM_KIKI_SOHUS_BNCHIGO, outMap.get("after_bnchi"));
				}
			}
		}
		catch (Exception e)
		{

			String in_state_city = (String)inMap.get("state_city");
			String in_aza = (String)inMap.get("aza");
			String in_chome_bnchi = (String)inMap.get("chome_bnchi");

			outMap.put("ad_cd", ad_code_0);
			outMap.put("pcd", JFUStrConst.EMPTY);
			outMap.put("state_nm", JFUStrConst.EMPTY);
			outMap.put("city_nm", JFUStrConst.EMPTY);
			outMap.put("oaztsu_nm", JFUStrConst.EMPTY);
			outMap.put("azcho_nm", JFUStrConst.EMPTY);
			outMap.put("after_bnchi", in_state_city + in_aza + in_chome_bnchi);
		}

		param.setData(cName, outMap);

		return param;
	}

	/**
	 * 住所情報分割処理の入力チェック
	 *
	 * @param handle
	 *            セッションマネージャなどを持ったハンドル
	 * @param param
	 *            モデルグループ、コントロールマップを含むパラメータオブジェクト
	 * @param fixedText
	 *            ユーザ任意文字列
	 * @return HashMap 住所情報分割処理用メッセージ設定したパラメータオブジェクト
	 * @exception RequestParameterExceptionがスローされます。
	 */
	public HashMap<String, Object> getInvokeCBS(SessionHandle handle, IRequestParameterReadWrite param, String fixedText)
			throws RequestParameterException
	{

		// マップを取得するキーを設定します。
		cName = fixedText;

		// 入力チェック用パラメータ設定処理を行います。（チェック自体は実施しません）
		HashMap paramMap = editStateInMsg(param);

		return paramMap;
	}

	/**
	 * 都道府県一覧照会処理用メッセージ設定処理
	 *
	 * @param param
	 *            モデルグループ、コントロールマップを含むパラメータオブジェクト
	 * @return HashMap 都道府県一覧取得処理用メッセージ設定したパラメータオブジェクト
	 * @exception RequestParameterExceptionがスローされます。
	 */
	private HashMap<String, Object> editStateInMsg(IRequestParameterReadWrite param) throws RequestParameterException
	{
		HashMap<String, Object> paramMap = new HashMap<String, Object>(10);

		// 【取得元：電文ヘッダ(ヘッダ)】
		// 電文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));

		// ユーザデータ情報
		HashMap inMap = (HashMap)param.getData(cName);

		CAANMsg[] templates = new CAANMsg[1];
		templates[0] = setStateTemplate(inMap, param);
		paramMap.put(JCMConstants.TEMPLATE_LIST_KEY, templates);

		return paramMap;
	}

	/**
	 * 字丁目情報一覧照会処理用メッセージ設定処理
	 *
	 * @param param
	 *            モデルグループ、コントロールマップを含むパラメータオブジェクト
	 * @param splitStateList
	 *            前処理にて分割された都道府県、市区町村を保持したマップ
	 * @return HashMap 字丁目情報一覧照会処理用メッセージ設定したパラメータオブジェクト
	 * @exception RequestParameterExceptionがスローされます。
	 */
	private HashMap<String, Object> editChoBnchiInMsg(IRequestParameterReadWrite param, HashMap<?, ?> splitStateList)
			throws RequestParameterException
	{
		HashMap<String, Object> paramMap = new HashMap<String, Object>(10);

		// 【取得元：電文ヘッダ(ヘッダ)】
		// 電文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));

		// ユーザデータ情報
		HashMap inMap = (HashMap)param.getData(cName);
		CAANMsg template = setChomeTemplate(inMap, param, splitStateList);

		CAANMsg[] templates = new CAANMsg[1];
		templates[0] = template;
		paramMap.put(JCMConstants.TEMPLATE_LIST_KEY, templates);

		return paramMap;
	}

	/**
	 * 都道府県一覧照会処理用メッセージ取得処理
	 *
	 * @param param
	 *            モデルグループ、コントロールマップを含むパラメータオブジェクト
	 * @param stateList
	 *            都道府県名一覧マップ
	 * @return HashMap 分割処理後の都道府県、市区町村を保持したマップ
	 * @exception Exceptionがスローされます。
	 */
	private HashMap<?, ?> editStateOutMsg(IRequestParameterReadWrite param, Map<?, ?> stateList) throws Exception
	{

		// SCからの戻り値からCAANMsgを取得します。
		CAANMsg[] templates = (CAANMsg[])stateList.get(JCMConstants.TEMPLATE_LIST_KEY);

		// ユーザデータ情報を取得します。
		HashMap<String, Object> inMap = (HashMap)param.getData(cName);

		// 都道府県・市区町村を取得します。
		String state_city = JFUStrConst.EMPTY;

		if (null == (String)inMap.get("state_city"))
		{
			state_city = JFUStrConst.EMPTY;
		}
		else
		{
			state_city = (String)inMap.get("state_city");
		}

		// 分割フラグを生成します。
		String state_split_flg = JFUStrConst.EMPTY;

		// 都道府県一覧リストを取得します。
		ArrayList list = getStateTemplate(templates);

		// 都道府県・市区町村の分割処理を行います。
		String state = JFUStrConst.EMPTY;
		String city = JFUStrConst.EMPTY;

		for (int i = 0; i < list.size(); i++)
		{

			// リストに含まれる都道府県名を取得します。
			String state_val = (String)list.get(i);

			// 「都道府県・市区町村」の先頭が「都道府県名」に一致するかを確認します。
			Pattern pattern = Pattern.compile("^" + state_val);
			Matcher matcher = pattern.matcher(state_city);
			if (matcher.find())
			{
				// 一致した場合は、一致部分を「都道府県」、それ以外を「市区町村」として分割します。
				state = matcher.group();
				city = matcher.replaceFirst(JFUStrConst.EMPTY);

				state_split_flg = "1";

				// 繰り返しから離脱します。
				break;
			}

		}
		if (!"1".equals(state_split_flg))
		{
			// 一致しなかった場合、「都道府県・市区町村」を「都道府県」に設定します。
			state = JFUStrConst.EMPTY;
			city = state_city;

		}

		HashMap<String, Object> outMap = new HashMap<String, Object>(10);
		outMap.put("state", state);
		outMap.put("city", city);

		return outMap;
	}

	/**
	 * 字丁目一覧照会処理用メッセージ取得処理
	 *
	 * @param param
	 *            モデルグループ、コントロールマップを含むパラメータオブジェクト
	 * @param chomeList
	 *            字丁目名一覧マップ
	 * @return HashMap 分割処理後の字丁目名、番地を保持したマップ
	 * @exception Exceptionがスローされます。
	 */
	private HashMap<?, ?> editChomeOutMsg(IRequestParameterReadWrite param, Map<?, ?> chomeList) throws Exception
	{

		// SCからの戻り値からCAANMsgを取得します。
		CAANMsg[] templates = (CAANMsg[])chomeList.get(JCMConstants.TEMPLATE_LIST_KEY);

		// ユーザデータ情報を取得します。
		HashMap<String, Object> inMap = (HashMap)param.getData(cName);

		String aza = JFUStrConst.EMPTY;
		if (null == (String)inMap.get("aza"))
		{
			aza = JFUStrConst.EMPTY;
		}
		else
		{
			aza = (String)inMap.get("aza");
		}

		// 丁目・番地を取得します。
		String chome_bnchi = JFUStrConst.EMPTY;

		if (null == (String)inMap.get("chome_bnchi"))
		{
			chome_bnchi = JFUStrConst.EMPTY;
		}
		else
		{
			chome_bnchi = (String)inMap.get("chome_bnchi");
		}

		// 分割判定フラグを生成します。
		String splitChoBan_flg = JFUStrConst.EMPTY;

		// 字丁目一覧情報を取得します。
		ArrayList list = getChomeTemplate(templates);

		// 丁目･番地等の分割処理を行います。
		String azcho = JFUStrConst.EMPTY;
		String bnchi = JFUStrConst.EMPTY;

		for (int i = 0; i < list.size(); i++)
		{

			Map map = (Map)list.get(i);
			// 大字通称名,大字通称カナ名を取得します。
			String oaztsu_nm = (String)map.get(EZM0081B070CBSMsg1List.OAZTSU_NM);

			// 字丁目名,字丁目カナ名を取得します。
			String azcho_nm = (String)map.get(EZM0081B070CBSMsg1List.AZCHO_NM);
			String azcho_kana = (String)map.get(EZM0081B070CBSMsg1List.AZCHO_KANA);

			// 「丁目・番地等」の先頭が「字丁目名」に一致するかを確認します。
			Pattern azcho_nm_pattern = Pattern.compile("^" + oaztsu_nm + azcho_nm);
			Matcher azcho_nm_matcher = azcho_nm_pattern.matcher(aza + chome_bnchi);

			// 「丁目・番地等」の先頭が「字丁目カナ名」に一致するかを確認します。
			Pattern azcho_kana_pattern = Pattern.compile("^" + oaztsu_nm + azcho_kana);
			Matcher azcho_kana_matcher = azcho_kana_pattern.matcher(aza + chome_bnchi);

			if (azcho_nm_matcher.find())
			{
				// ■@一致した場合、一致部分を「字丁目名」、それ以外を「番地」として設定します。
				azcho = azcho_nm;
				bnchi = azcho_nm_matcher.replaceFirst(JFUStrConst.EMPTY);

				// 丁目番地分割フラグに"1"を設定します。
				splitChoBan_flg = "1";
				// 繰り返しから離脱します。
				break;

			}
			else if (azcho_kana_matcher.find())
			{
				// ■@一致した場合、一致部分を「字丁目名」、それ以外を「番地」として設定します。
				azcho = azcho_nm;
				bnchi = azcho_kana_matcher.replaceFirst(JFUStrConst.EMPTY);

				// 丁目番地分割フラグに"1"を設定します。
				splitChoBan_flg = "1";
				// 繰り返しから離脱します。
				break;
			}

		}
		if (!"1".equals(splitChoBan_flg))
		{
			// ■A一致しなかった場合、"−"が含まれていればそこで分割処理を行います。
			int pos = chome_bnchi.indexOf("−");
			boolean bunkatsu_flg = false;
			if (pos > 0)
			{
				char ch = chome_bnchi.charAt(pos - 1);
				if (ch >= '０' && ch <= '９')
				{
					bunkatsu_flg = true;
				}
			}
			if (-1 != pos && bunkatsu_flg)
			{
				String str1 = chome_bnchi.substring(0, pos);
				pos += 1;
				String str2 = chome_bnchi.substring(pos);

				azcho = str1;
				bnchi = str2;
			}
			else
			{
				// OM-2014-0002910「字丁目」から「番地」に修正
				// ■B分割できなかった場合、「丁目番地」を「番地」に設定します。
				bnchi = chome_bnchi;
			}

		}

		HashMap<String, Object> outMap = new HashMap<String, Object>(10);
		outMap.put("azcho", azcho);
		outMap.put("bnchi", bnchi);
		outMap.put("chome_bnchi", chome_bnchi);

		return outMap;
	}

	/**
	 * 都道府県一覧照会情報設定処理
	 *
	 * @param inMap
	 *            ユーザデータ情報
	 * @param param
	 *            モデルグループ、コントロールマップを含むパラメータオブジェクト
	 * @return template 都道府県一覧照会処理情報を設定したパラメータオブジェクト
	 * @exception RequestParameterExceptionがスローされます。
	 */
	private CAANMsg setStateTemplate(HashMap inMap, IRequestParameterReadWrite param) throws RequestParameterException
	{

		CAANMsg template = new CAANMsg(EZM0081B060CBSMsg.class.getName());

		// テンプレートID
		template.set(EZM0081B060CBSMsg.TEMPLATEID, "EZM0081B060");

		// オペレータID
		Object operatorId = param.getControlMapData(SCControlMapKeys.OPERATOR_ID);
		template.set(JCMConstants.OPERATOR_ID_KEY, operatorId);

		// 運用日付
		Object operateDate = param.getControlMapData(SCControlMapKeys.OPE_DATE);
		template.set(JCMConstants.OPERATE_DATE_KEY, operateDate);

		// 運用日時
		Object operateDateTime = param.getControlMapData(SCControlMapKeys.OPE_TIME);
		template.set(JCMConstants.OPERATE_DATETIME_KEY, operateDateTime);

		// 機能コード（"1"を固定で設定）
		template.set(EZM0081B060CBSMsg.FUNC_CODE, func_code_key_1);

		return template;

	}

	/**
	 * 字丁目一覧照会情報設定処理
	 *
	 * @param inMap
	 *            ユーザデータ情報
	 * @param param
	 *            モデルグループ、コントロールマップを含むパラメータオブジェクト
	 * @return template 字丁目一覧照会処理情報を設定したパラメータオブジェクト
	 * @exception RequestParameterExceptionがスローされます。
	 */
	private CAANMsg setChomeTemplate(HashMap inMap, IRequestParameterReadWrite param, HashMap<?, ?> splitStateList) throws RequestParameterException
	{

		CAANMsg template = new CAANMsg(EZM0081B070CBSMsg.class.getName());

		// テンプレートID
		template.set(EZM0081B070CBSMsg.TEMPLATEID, TEMPLATE_ID);

		// オペレータID
		Object operatorId = param.getControlMapData(SCControlMapKeys.OPERATOR_ID);
		template.set(JCMConstants.OPERATOR_ID_KEY, operatorId);

		// 運用日付
		Object operateDate = param.getControlMapData(SCControlMapKeys.OPE_DATE);
		template.set(JCMConstants.OPERATE_DATE_KEY, operateDate);

		// 運用日時
		Object operateDateTime = param.getControlMapData(SCControlMapKeys.OPE_TIME);
		template.set(JCMConstants.OPERATE_DATETIME_KEY, operateDateTime);

		// 機能コード（"1"を固定で設定）
		template.set(EZM0081B070CBSMsg.FUNC_CODE, func_code_key_1);

		// 分割した都道府県、市区町村を取得します。
		String state = (String)splitStateList.get("state");
		String city = (String)splitStateList.get("city");

		// ◇業務データの設定
		// 分割後の都道府県名 → ＫＥＹ＿都道府県名
		if (JFUStrConst.EMPTY.equals(state))
		{
			template.setNull(EZM0081B070CBSMsg.KEY_STATE_NM);
		}
		else
		{
			template.set(EZM0081B070CBSMsg.KEY_STATE_NM, state);
		}

		// 分割後の市区町村名 → ＫＥＹ＿市区町村名
		if (JFUStrConst.EMPTY.equals(city))
		{
			template.setNull(EZM0081B070CBSMsg.KEY_CITY_NM);
		}
		else
		{
			template.set(EZM0081B070CBSMsg.KEY_CITY_NM, city);
		}

		return template;

	}

	/**
	 * 都道府県一覧照会情報の取得処理
	 *
	 * @param templates
	 *            都道府県一覧照会処理の返却情報が設定されているパラメータオブジェクト
	 * @return list 都道府県一覧照会処理の返却情報を設定したList
	 * @exception Exceptionがスローされます。
	 */
	private ArrayList getStateTemplate(CAANMsg[] templates) throws Exception
	{

		// 返却情報を詰めるマップを設定します。
		ArrayList list = new ArrayList(10);

		// 返却情報を取得します。
		CAANMsg template = templates[0];

		// 都道府県情報の一覧を取得します。
		CAANMsg[] templateArray = template.getCAANMsgList(EZM0081B060CBSMsg.EZM0081B060CBSMSG1LIST);

		int count = 0;

		for (int i = 0; i < templateArray.length; i++)
		{
			CAANMsg childTemplate = templateArray[i];

			// 値がnull以外の場合、値を取得します。
			if (!childTemplate.isNull(EZM0081B060CBSMsg1List.STATE_NM))
			{

				list.add(childTemplate.getString(EZM0081B060CBSMsg1List.STATE_NM));
				count = count + 1;
			}

		}

		return list;
	}

	/**
	 * 字丁目一覧照会情報設定処理
	 *
	 * @param templates
	 *            字丁目一覧照会処理の返却情報が設定されているパラメータオブジェクト
	 * @return map 字丁目一覧照会処理の返却情報を設定したMap
	 * @exception Exceptionがスローされます。
	 */
	private ArrayList getChomeTemplate(CAANMsg[] templates) throws Exception
	{

		// 返却情報を詰めるマップを設定します。
		ArrayList list = new ArrayList(10);

		// 返却情報を取得します。
		CAANMsg template = templates[0];

		// 字丁目情報の一覧を取得します。
		CAANMsg[] templateArray = template.getCAANMsgList(EZM0081B070CBSMsg.EZM0081B070CBSMSG1LIST);

		for (int i = 0; i < templateArray.length; i++)
		{
			CAANMsg childTemplate = templateArray[i];
			Map map = new HashMap();

			map.put(EZM0081B070CBSMsg1List.OAZTSU_NM, JFUBPCommon.nvl(childTemplate.getString(EZM0081B070CBSMsg1List.OAZTSU_NM), JFUStrConst.EMPTY));
			map.put(EZM0081B070CBSMsg1List.OAZTSU_KANA, JFUBPCommon.nvl(childTemplate.getString(EZM0081B070CBSMsg1List.OAZTSU_KANA), JFUStrConst.EMPTY));
			map.put(EZM0081B070CBSMsg1List.AZCHO_NM, JFUBPCommon.nvl(childTemplate.getString(EZM0081B070CBSMsg1List.AZCHO_NM), JFUStrConst.EMPTY));
			map.put(EZM0081B070CBSMsg1List.AZCHO_KANA, JFUBPCommon.nvl(childTemplate.getString(EZM0081B070CBSMsg1List.AZCHO_KANA), JFUStrConst.EMPTY));

			list.add(map);
		}
		return list;
	}

	/**
	 * エラー情報マッピング処理
	 *
	 * @param param
	 *            モデルグループ、コントロールマップを含むパラメータオブジェクト
	 * @param templates
	 *            サービスインターフェイスの実行結果を格納しているテンプレート
	 * @param returnCode
	 *            サービスインターフェイスを実行後のリタンコード
	 * @return IRequestParameterReadWrite 住所コード取得処理用メッセージ設定したパラメータオブジェクト
	 * @exception RequestParameterExceptionがスローされます。
	 */
	public IRequestParameterReadWrite editErrorInfo(IRequestParameterReadWrite param, CAANMsg[] templates, int returnCode)
			throws RequestParameterException
	{

		// エラーリストを設定します。
		ArrayList errlist = new ArrayList(10);

		// エラーマップを設定します。
		HashMap errMap = new HashMap(10);

		// ユーザデータ情報を取得します。
		HashMap inMap = (HashMap)param.getData(cName);

		for (int i = 0; i < templates.length; i++)
		{

			CAANMsg template = templates[i];
			int templateStatus = template.getInt(EZM0081B050CBSMsg.STATUS);
			if (0 != returnCode)
			{
				templateStatus = 9000;
			}
			if (null == JCMAPLConstMgr.getString(RETURN_MESSAGE + String.format(STATUS_FORMAT, templateStatus)))
			{
				templateStatus = 0;
			}

			int bpStatus = 0;
			Object obj = param.getControlMapData(SCControlMapKeys.RETURN_CODE);
			if (null == obj)
			{
				bpStatus = -1;
			}
			else
			{
				bpStatus = Integer.parseInt((String)param.getControlMapData(SCControlMapKeys.RETURN_CODE));
			}

			if (templateStatus > bpStatus)
			{

				// BPにサービスコンポーネントのステータスを設定します。
				String formatStatus = String.format(STATUS_FORMAT, templateStatus);
				String message = JCMAPLConstMgr.getString(RETURN_MESSAGE + formatStatus);
				param.setControlMapData(SCControlMapKeys.RETURN_CODE, formatStatus);
				param.setControlMapData(SCControlMapKeys.RETURN_MESSAGE, message);
			}

			// 住所コード取得マップ.ＫＥＹ＿都道府県名エラー → ＫＥＹ＿都道府県名のエラー情報返却
			if (!template.isNull(EZM0081B050CBSMsg.KEY_STATE_NM_ERR))
			{
				errMap.put(EZM0081B050CBSMsg.KEY_STATE_NM_ERR, template.getString(EZM0081B050CBSMsg.KEY_STATE_NM_ERR));
			}

			// 住所コード取得マップ.ＫＥＹ＿市区町村名エラー → ＫＥＹ＿市区町村名のエラー情報返却
			if (!template.isNull(EZM0081B050CBSMsg.KEY_CITY_NM_ERR))
			{
				errMap.put(EZM0081B050CBSMsg.KEY_CITY_NM_ERR, template.getString(EZM0081B050CBSMsg.KEY_CITY_NM_ERR));
			}

			// 住所コード取得マップ.ＫＥＹ＿大字通称名エラー → ＫＥＹ＿大字通称名のエラー情報返却
			if (!template.isNull(EZM0081B050CBSMsg.KEY_OAZTSU_NM_ERR))
			{
				errMap.put(EZM0081B050CBSMsg.KEY_OAZTSU_NM_ERR, template.getString(EZM0081B050CBSMsg.KEY_OAZTSU_NM_ERR));
			}

			// 住所コード取得マップ.ＫＥＹ＿字丁目名エラー → ＫＥＹ＿字丁目名のエラー情報返却
			if (!template.isNull(EZM0081B050CBSMsg.KEY_AZCHO_NM_ERR))
			{
				errMap.put(EZM0081B050CBSMsg.KEY_AZCHO_NM_ERR, template.getString(EZM0081B050CBSMsg.KEY_AZCHO_NM_ERR));
			}

			// エラー情報をリストに設定します。
			errlist.add(errMap);
		}

		inMap.put(ERR_LIST, errlist);
		return param;
	}
}
