/*********************************************************************
 * All Rights reserved, Copyright (c) K-Opticom
 **********************************************************************
 *＜プログラム内容＞
 *   システム名      ：eo顧客基幹システム
 *   モジュール名    ：JFUSplitAddressInfoChomeCC
 *   ソースファイル名：JFUSplitAddressInfoChomeCC.java
 *   作成者          ：富士通
 *   日付            ：2024年10月16日
 *＜機能概要＞
 *   住所情報分割処理部品です。
 *＜修正履歴＞
 *   バージョン  修正日       修正者      修正内容
 *   v72.0.1	2024/10/16	FJ) 美濃原	ANK-4494-19-00_【双方向番ポ対応】 FRONTIERの利用場所住所連携内容変更
 **********************************************************************/
package com.fujitsu.futurity.bp.custom.common;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
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 JFUSplitAddressInfoChomeCC extends AbstractCommonComponent
{

	// 入力パラメータ
	// ※フロンティアからの呼出時は「字・丁目」が設定。番地は設定なし。
	/** 都道府県、市区町村 */
	private static final String IN_STATE_CITY = "state_city";
	/** 字・丁目 */
	private static final String IN_AZA_CHOME = "aza_chome";
	/** 番地号 */
	private static final String IN_BNCHI = "bnchi";

	// 出力パラメータ
	/** 郵便番号 */
	private static final String PCD = "pcd";
	/** 住所コード */
	private static final String AD_CD = "ad_cd";
	/** 都道府県 */
	private static final String STATE_NM = "state_nm";
	/** 市区町村 */
	private static final String CITY_NM = "city_nm";
	/** 大字通称名 */
	private static final String OAZTSU_NM = "oaztsu_nm";
	/** 字丁目名 */
	private static final String AZCHO_NM = "azcho_nm";
	/** 住所コード取得元情報 */
	private static final String STAT_FLG = "stat_flg";
	/** 住所修正フラグ：住所マスタ完全合致でない場合に"1" */
	private static final String MOD_FLG = "mod_flg";
	/** 番地号の再編集用文字列 */
	private static final String AFTER_BNCHI = "after_bnchi";

	// その他定数
	/** テンプレートID */
	public static final String TEMPLATE_ID = "EZM0081B050";
	/** テンプレートID */
	public static final String TEMPLATE_ID_EZM0081B011 = "EZM0081B011";

	/** インマップ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 bnchi_separate_val = "−";

	/** 住所マスタに存在しないため調整あり */
	private static final String CHOSEI_FLG_ON = "1";

	/** ハイフン */
	public static final List<String> CON_HYP = Arrays.asList(bnchi_separate_val, "-", "ー");

	/**
	 * 住所情報分割処理
	 *
	 * @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 inStateCity = (String)inMap.get(IN_STATE_CITY);
		String inAzaChome = (String)inMap.get(IN_AZA_CHOME);
		String inBnchi = (String)inMap.get(IN_BNCHI);

		try
		{
			// ■丁目・番地等
			// @都道府県情報の一覧照会を行います。（全都道府県）
			HashMap<String, Object> paramMap = editStateInMsg(param); // 上りマッピング
			Map<?, ?> stateList = scCall.run(paramMap, handle); // SC呼び出し

			// A分割後の都道府県名、市区町村名を取得します。（@の都道府県で合致したもので単純分割）
			HashMap<String, String> splitStateMap = editStateOutMsg(param, stateList); // 下りマッピング
			
			String state = (String)splitStateMap.get("state");
			String city = (String)splitStateMap.get("city");
			String oaztsu = JFUStrConst.EMPTY;
			String azcho = JFUStrConst.EMPTY;
			String azchoAmari = JFUStrConst.EMPTY;
			Map<?, ?> chomeList = null;

			if (JFUBPCommon.isNull(splitStateMap.get("exeState")))
			{
				// B字丁目情報の一覧照会を行います。（KEY:都道府県、市区町村⇒一覧取得）
				paramMap = editChoBnchiInMsg(param, splitStateMap); // 上りマッピング
				chomeList = scCall.run(paramMap, handle); // SC呼び出し

				// 市区町村リストを元に大字、字丁目を検索する。
				HashMap<?, ?> azchoMap = editChomeOutMsg(param, chomeList); // 下りマッピング
				// 分割後の都道府県名、市区町村名を取得します。
				oaztsu = (String)azchoMap.get("oaztsu");
				azcho = (String)azchoMap.get("azcho");
				azchoAmari = (String)azchoMap.get("azchoAmari");
				splitStateMap.put("oaztsu", oaztsu);
				splitStateMap.put("azcho", azcho);
			}

			// 住所コード取得部品に渡すマップを生成します。
			HashMap<String, Object> map = new HashMap<String, Object>(10);

			// 都道府県名 → 住所コード取得マップ.都道府県名
			if (JFUBPCommon.isNull(state))
			{
				map.put(EZM0081B050CBSMsg.KEY_STATE_NM, JFUStrConst.EMPTY);
			}
			else
			{
				map.put(EZM0081B050CBSMsg.KEY_STATE_NM, state);
			}

			// 市区町村名 → 住所コード取得マップ.市区町村名
			if (JFUBPCommon.isNull(city))
			{
				map.put(EZM0081B050CBSMsg.KEY_CITY_NM, JFUStrConst.EMPTY);
			}
			else
			{
				map.put(EZM0081B050CBSMsg.KEY_CITY_NM, city);
			}

			// 大字通称名 → 住所コード取得マップ.大字通称名
			if (JFUBPCommon.isNull(oaztsu))
			{
				map.put(EZM0081B050CBSMsg.KEY_OAZTSU_NM, JFUStrConst.EMPTY);
			}
			else
			{
				map.put(EZM0081B050CBSMsg.KEY_OAZTSU_NM, oaztsu);
			}

			// 字丁目名 → 住所コード取得マップ.字丁目名
			if (JFUBPCommon.isNull(azcho))
			{
				map.put(EZM0081B050CBSMsg.KEY_AZCHO_NM, JFUStrConst.EMPTY);
			}
			else
			{
				map.put(EZM0081B050CBSMsg.KEY_AZCHO_NM, azcho);
			}

			// 番地 → 編集前番地
			map.put("before_bnchi", JFUStrConst.EMPTY);
			// 丁目・番地 → 編集前丁目・番地
			map.put("before_chome_bnchi", JFUStrConst.EMPTY);

			// ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
			// <<住所コード取得部品を呼び出します。>>
			//   検索処理@ （都道府県名による検索）都道府県名で検索
			//   検索処理A （市区町村名による検索）都道府県名、市区町村、大字通称名はnull、字丁目名はnullで検索
			//   検索処理B （大字通称名による検索）都道府県名、市区町村、大字通称名、字丁目名はnullで検索
			//   検索処理C （字丁目名による検索）  都道府県名、市区町村、大字通称名、字丁目名で検索
			//   検索処理C'（字丁目名による検索）  都道府県名、市区町村、大字通称名null、字丁目名で検索 ※大字なしの場合
			//   ※C⇒B⇒A⇒@の順で、先に合致するものが返却される。
			//     番地はパラメータに設定しない。
			//     予め市町村のリストで字・丁目に該当するものが存在するかチェックしているので、
			//     「after_bnchi」に値が入ってくることはない前提。
			// ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
			JFUGetAddressCodeUtilFr getAddress = new JFUGetAddressCodeUtilFr();
			outMap = getAddress.getAddressCode(handle, param, map);

			String rs_stat_flg = (String)outMap.get(STAT_FLG);
			String rs_state_nm = (String)outMap.get(STATE_NM);
			String rs_city_nm = (String)outMap.get(CITY_NM);
			String rs_oaztsu_nm = (String)outMap.get(OAZTSU_NM);
			String rs_azcho_nm = (String)outMap.get(AZCHO_NM);
			String rs_after_bnchi = (String)outMap.get(AFTER_BNCHI);
			String resultBnchi = JFUStrConst.EMPTY;

			String rs_mod = CHOSEI_FLG_ON;

			if (JFUBPCommon.isNull(rs_state_nm))
			{
				resultBnchi = inStateCity + addSepalate(inAzaChome, inBnchi);
			}
			else if (JFUBPCommon.isNull(rs_city_nm))
			{
				resultBnchi = city + addSepalate(inAzaChome, inBnchi);
			}
			else if (JFUBPCommon.isNull(rs_oaztsu_nm) && (JFUBPCommon.isNull(rs_azcho_nm)))
			{
				resultBnchi = addSepalate(inAzaChome, inBnchi);
			}
			else if (JFUBPCommon.isNull(rs_azcho_nm))
			{
				resultBnchi = addSepalate(azchoAmari, inBnchi);
			}
			else if (!JFUBPCommon.isNull(rs_after_bnchi))
			{
				resultBnchi = addSepalate(rs_after_bnchi, inBnchi);
			}
			else
			{
				resultBnchi = inBnchi;
				rs_mod = JFUStrConst.EMPTY;
			}

			outMap.put(AFTER_BNCHI, resultBnchi);
			outMap.put(MOD_FLG, rs_mod);
		}
		catch (Exception e)
		{
			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, inStateCity + addSepalate(inAzaChome, inBnchi));
			outMap.put(STAT_FLG, e.toString());
			outMap.put(MOD_FLG, CHOSEI_FLG_ON);
		}

		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<String, String> 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;
		String exeState = 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;
			exeState = "stateErr";

		}

		HashMap<String, String> outMap = new HashMap<String, String>();
		outMap.put("state", state);
		outMap.put("city", city);
		outMap.put("exeState", exeState);

		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 paramAzaChome = JFUStrConst.EMPTY;
		if (null == (String)inMap.get(IN_AZA_CHOME))
		{
			paramAzaChome = JFUStrConst.EMPTY;
		}
		else
		{
			paramAzaChome = (String)inMap.get(IN_AZA_CHOME);
		}
		// 全角スペースを除去した文字列
		String paramAzaChomeTrim = getTrimSpace(paramAzaChome);
//		paramAzaChomeTrim = trimHyp(paramAzaChome);

		// 分割判定フラグを生成します。
		String splitChoBan_flg = JFUStrConst.EMPTY;

		// 字丁目一覧情報を取得します。
		ArrayList list = getChomeTemplate(templates);

		// 丁目･番地等の分割処理を行います。
		String oaztsu = JFUStrConst.EMPTY;
		String azcho = JFUStrConst.EMPTY;
		String bnchi = JFUStrConst.EMPTY;
		String azchoAmari = JFUStrConst.EMPTY;
		String saveOaztsu = JFUStrConst.EMPTY;


//		都道府県名	市区町村名	大字通称名	字丁目名
//		香川県	仲多度郡琴平町				９９丁目

		String saveCheckAzaChome = JFUStrConst.EMPTY;
		String saveCheckAzaChomeKana = 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);
			// 丁目、丁を取り除いたもの
			String azcho_nm_trim = getSepString(azcho_nm, false);
			String azcho_kana_trim = getSepString(azcho_kana, false);

			String checkKey1 = oaztsu_nm + azcho_nm;
			String checkKeyTrim1 = oaztsu_nm + azcho_nm_trim;
			String checkKey2 = oaztsu_nm + azcho_kana;
			String checkKeyTrim2 = oaztsu_nm + azcho_kana_trim;
			String matchingKey = JFUStrConst.EMPTY;

			if (paramAzaChomeTrim.startsWith(oaztsu_nm) && saveOaztsu.length() < oaztsu_nm.length())
			{
				saveOaztsu = oaztsu_nm;
			}
			if (paramAzaChomeTrim.equals(checkKey1))
			{
				matchingKey = checkKey1;
			}
			else if (paramAzaChomeTrim.equals(checkKeyTrim1))
			{
				matchingKey = checkKeyTrim1;
			}
			else if (paramAzaChomeTrim.equals(checkKey2))
			{
				matchingKey = checkKey2;
			}
			else if (paramAzaChomeTrim.equals(checkKeyTrim2))
			{
				matchingKey = checkKeyTrim2;
			}

			if (JFUBPCommon.isNull(splitChoBan_flg) && !JFUBPCommon.isNull(matchingKey))
			{
				// ■@一致した場合、一致部分を「字丁目名」、それ以外を「番地」として設定します。
				saveCheckAzaChome = matchingKey;
				saveOaztsu = oaztsu_nm;
				oaztsu = oaztsu_nm;
				azcho = azcho_nm;
				bnchi = paramAzaChomeTrim.replaceFirst(matchingKey, JFUStrConst.EMPTY);
				// 丁目番地分割フラグに"1"を設定します。
				splitChoBan_flg = "1";
				break;
			}
		}

		if (!"1".equals(splitChoBan_flg))
		{
			if (JFUBPCommon.isNull(saveOaztsu))
			{
				// ■A一致しなかった場合、都道府県、市を除いて、全て番地にセット
				azchoAmari = paramAzaChome;
			} else {
				oaztsu = saveOaztsu;
				azcho = JFUStrConst.EMPTY;
				azchoAmari = paramAzaChome.replaceFirst(oaztsu, JFUStrConst.EMPTY);
			}
		}
		else if (!JFUBPCommon.isNull(bnchi))
		{
			// チェック時に番地を含まないので、番地が返却されている場合は正しくない。
			// 大字まで正しいもとのし、番地に残りをセット
			azcho = JFUStrConst.EMPTY;
			azchoAmari = paramAzaChome.replaceFirst(oaztsu, JFUStrConst.EMPTY);
		}

		HashMap<String, Object> outMap = new HashMap<String, Object>(10);
		outMap.put("oaztsu", oaztsu);
		outMap.put("azcho", azcho);
		outMap.put("azchoAmari", azchoAmari);

		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;
	}

	/**
	 * 全角スペースを除去。
	 * <br>
	 * @param adInf 住所情報
	 * @return 全角スペースを除去した文字列
	 */
	private String getTrimSpace(String adInf)
	{
		String sepString = "";
		if (!adInf.isEmpty())
		{
			// 全角空白をすべて削除 ※各項目は単項目チェック済みの前提であるため半角空白は含まれていないものとする
			sepString = adInf.replaceAll("　", "");
		}
		else
		{
			sepString = adInf;
		}
		return sepString;
	}

	/**
	 * 丁目、丁を変換。
	 * <br>
	 * @param adInf 住所情報
	 * @param isHyphen "丁"、"丁目"を"−"に置換するかどうか
	 * @return 住所分割用文字列
	 */
	private String getSepString(String adInf, boolean isHyphen)
	{
		String sepString = "";
		if (!adInf.isEmpty())
		{
			// 全角空白をすべて削除 ※各項目は単項目チェック済みの前提であるため半角空白は含まれていないものとする
			sepString = adInf.replaceAll("　", "");
			if (isHyphen)
			{
				// 数字の直後にある"丁"、"丁目"を"−"(全角マイナス)に置換 ※誤変換防止のため丁目、丁の順で行うこと
				sepString = sepString.replaceAll("([０-９])丁目", "$1−").replaceAll("([０-９])丁", "$1−");
			}
			else
			{
				// 数字の直後にある"丁"、"丁目"を削除 ※誤変換防止のため丁目、丁の順で行うこと
				sepString = sepString.replaceAll("([０-９])丁目", "$1").replaceAll("([０-９])丁", "$1");
			}
		}
		else
		{
			sepString = adInf;
		}

		return sepString;
	}

	/**
	 * 入力されている分離府（ハイフン）を削除。
	 * 
	 * @param adInf
	 * @return ハイフン除去後の文字列
	 */
	private String trimHyp(String adInf)
	{
		String resultStr = adInf;
		if (!adInf.isEmpty())
		{
			int wLen = adInf.length();
			String endStr = adInf.substring(wLen - 1, wLen);
			if (CON_HYP.contains(endStr))
			{
				resultStr = adInf.substring(0, wLen);
			}
		}
		return resultStr;
	}

	/**
	 * 住所用セパレータ（全角マイナス）を設定。
	 * <br>
	 * 
	 * @param paramAdd 住所（例：字）
	 * @param paramAdd2 住所２（例：丁目）
	 * @return 編集後の文字列
	 */
	private String addSepalate(String aza, String chome_bnchi)
	{
		if (isNecessarySepalate(aza, chome_bnchi))
		{
			// 例）字の最後1桁と丁目の最初1桁が全角数字の場合にセパレータを設定する。
			return aza + bnchi_separate_val + chome_bnchi;
		}
		return aza + chome_bnchi;
	}

	/**
	 * 住所用セパレータ（全角マイナス）が必要か判定。
	 * <br>
	 * 
	 * @param aza 住所（例：字）
	 * @param chome_bnchi 住所２（例：丁目）
	 * @return true：必要、false：不要
	 */
	private boolean isNecessarySepalate(String aza, String chome_bnchi)
	{
		if (aza != null && aza.length() > 0 && aza.substring(aza.length() - 1, aza.length()).matches("[０-９]") && chome_bnchi != null
				&& chome_bnchi.length() > 0 && chome_bnchi.substring(0, 1).matches("[０-９]"))
		{
			// 字の最後1桁と丁目・番地の最初1桁が全角数字の場合にセパレータを設定する。
			return true;
		}
		return false;
	}

}
