/*********************************************************************
*	All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*	システム名		：Futurity
*	モジュール名	：JBSbatCRDataAccessUtil
*	ソースファイル名：JBSbatCRDataAccessUtil.java
*	作成者			：富士通
*	日付			：2011年04月05日
*＜機能概要＞
*	顧客対応履歴管理バッチデータアクセス共通部品
*＜修正履歴＞
*	バージョン	修正日		修正者		修正内容
*	v1.00.00	2011/05/18	富士通		新規作成
*
**********************************************************************/

package eo.business.common;

import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import eo.business.util.table.JBSbatZM_M_CD_NM_KANRI;
import eo.business.util.table.JBSbatZM_M_USER;
import eo.business.util.table.JBSbatZM_M_WKKBT_ORG;
import eo.framework.db.JBSbatSQLAccess;
import eo.framework.item.JBSbatCommonDBInterface;
import eo.framework.item.JBSbatCommonItem;

/**
 * 対応履歴管理システムバッチデータアクセス共通部品<p>
 * <BR>
 * @author 富士通
 */
public class JBSbatCRDataAccessUtil
{
	/**
	 * データアクセスオブジェクト保持マップ
	 * 生成したデータアクセスオブジェクトをジョブ中共有できるように保持
	 */
	private static final Map<String, JBSbatSQLAccess> DATA_ACCESS_OBJ_MAP = new HashMap<String, JBSbatSQLAccess>();

	/** テーブル(コード名称管理)*/
	private static final String D_TBL_NAME_ZM_M_CD_NM_KANRI = "ZM_M_CD_NM_KANRI";

	/** テーブル(ユーザー)*/
	private static final String D_TBL_NAME_ZM_M_USER = "ZM_M_USER";

	/** テーブル(業務個別設定組織)*/
	private static final String ZM_M_WKKBT_ORG = "ZM_M_WKKBT_ORG";

	/** SQL定義キー(CR_SELECT_001)*/
	private static final String ZM_M_CD_NM_KANRI_CR_SELECT_001 = "CR_SELECT_001";

	/** SQL定義キー(CR_SELECT_002)*/
	private static final String ZM_M_CD_NM_KANRI_CR_SELECT_002 = "CR_SELECT_002";

	/** ワイルドカード文字列 */
	private static final String[] ESCAPE_TARGET = {"\\", "%", "_"};

	/** ワイルドカード置き換え文字列 */
	private static final String[] ESCAPE_TARGET_REPLACE_RESULT = {"\\\\", "\\%", "\\_"};

	/** SQL用% */
	private static final String PERCENT = "%";

	/**
	 * スキーマ別のデータアクセスオブジェクトを取得する。
	 * (生成したデータアクセスオブジェクトは共有するためにMapに保持する)
	 * @param commonItem バッチ共通パラメータ電文
	 * @param tableName テーブル名
	 * @return 指定テーブル用データアクセスオブジェクト
	 * @throws SQLException SQL実行例外
	 * @throws IOException ファイルIO例外
	 */
	static JBSbatSQLAccess getDataAccessObj(JBSbatCommonItem commonItem, String tableName) throws SQLException, IOException
	{
		JBSbatSQLAccess dataAccessObj = DATA_ACCESS_OBJ_MAP.get(tableName);
		if (dataAccessObj == null)
		{
			dataAccessObj = new JBSbatSQLAccess(commonItem, tableName);
			DATA_ACCESS_OBJ_MAP.put(tableName, dataAccessObj);
		}
		return dataAccessObj;
	}

	/**
	 * データアクセスオブジェクトをクローズする
	 * @param commonItem バッチ共通パラメータ電文
	 */
	static void closeDataAccessObj(JBSbatCommonItem commonItem)
	{
		Object[] keys = DATA_ACCESS_OBJ_MAP.keySet().toArray();
		for (int i = 0; i < keys.length; i++)
		{
			closeDataAccessObj(commonItem, keys[i].toString());
		}
		DATA_ACCESS_OBJ_MAP.clear();
	}

	/**
	 * データアクセスオブジェクトをクローズする(テーブル指定)
	 * @param commonItem バッチ共通パラメータ電文
	 * @param tableName テーブル名
	 * @param dataAccessObj データアクセスオブジェクト
	 */
	static void closeDataAccessObj(JBSbatCommonItem commonItem, String tableName)
	{
		JBSbatSQLAccess dataAccessObj = DATA_ACCESS_OBJ_MAP.get(tableName);
		if (dataAccessObj != null)
		{
			try
			{
				dataAccessObj.close();
			}
			catch (SQLException sqle)
			{
				commonItem.getLogPrint().printDebugLog("close error" + sqle.toString());
			}
		}
		DATA_ACCESS_OBJ_MAP.remove(tableName);
	}

	/**
	 * コード名称からコード区分を取得する。
	 * @param commonItem バッチ共通パラメータ電文
	 * @param shubetsu コード種別区分
	 * @param cdNm コード名称
	 * @return 取得データ情報
	 * @throws Exception 業務サービス内で発生した例外全般。
	 */
	static String getCodeKbn(JBSbatCommonItem commonItem, String shubetsu, String cdNm) throws Exception
	{
		// コード名称管理
		JBSbatSQLAccess dbCdNmKanri = getDataAccessObj(commonItem, D_TBL_NAME_ZM_M_CD_NM_KANRI);

		// バイント変数のリストを生成します
		JBSbatCommonDBInterface paramList = new JBSbatCommonDBInterface();
		paramList.setValue(shubetsu);	// コード種別区分
		paramList.setValue(cdNm);		// コード名称

		// DBアクセスを実行します
		dbCdNmKanri.selectBySqlDefine(paramList, ZM_M_CD_NM_KANRI_CR_SELECT_001);

		JBSbatCommonDBInterface selectedData = dbCdNmKanri.selectNext();

		String codeKbn = null;

		if (selectedData != null)
		{
			codeKbn = selectedData.getString(JBSbatZM_M_CD_NM_KANRI.CD_DIV);	// コード区分
		}

		return codeKbn;
	}

	/**
	 * コード種別からコード区分情報を取得する。
	 * @param commonItem バッチ共通パラメータ電文
	 * @param shubetsu コード種別区分
	 * @return 取得データ情報
	 * @throws Exception 業務サービス内で発生した例外全般。
	 */
	static List<JBSbatCommonDBInterface> getCodeNm(JBSbatCommonItem commonItem, String shubetsu) throws Exception
	{
		// コード名称管理
		JBSbatSQLAccess dbCdNmKanri = getDataAccessObj(commonItem, D_TBL_NAME_ZM_M_CD_NM_KANRI);

		// バイント変数のリストを生成します
		JBSbatCommonDBInterface paramList = new JBSbatCommonDBInterface();
		paramList.setValue(shubetsu);	// コード種別区分

		// DBアクセスを実行します
		dbCdNmKanri.selectBySqlDefine(paramList, ZM_M_CD_NM_KANRI_CR_SELECT_002);

		return getSelectedDataList(dbCdNmKanri);
	}

	/**
	 * SELECTされたデータのListを取得する。
	 * <p>
	 * <b>処理フロー</b><br>
	 * <pre>
	 * 1.JBSbatSQLAccessオブジェクトのselectNext()で1行分のデータを取得する。<br>
	 *
	 * 2.データが存在する場合、戻り値のListに追加する。<br>
	 * 
	 * ※ 1,2を繰り返して結果を返す。データが無ければnullを返す。<br>
	 * </pre>
	 * <p>
	 * @param tableObject JBSbatSQLAccessオブジェクト
	 * @return 取得結果データのList
	 * @throws Exception 業務サービス内で発生した例外全般。
	 */
	static List<JBSbatCommonDBInterface> getSelectedDataList(JBSbatSQLAccess tableObject)  throws Exception
	{
		// 引数チェック
		if (tableObject == null)
		{
			return null;
		}

		// 戻り値のList
		List<JBSbatCommonDBInterface> selectedDataList = new ArrayList<JBSbatCommonDBInterface>();

		// データ1行の取得
		JBSbatCommonDBInterface selectedData = tableObject.selectNext();
		while (selectedData != null)
		{
			selectedDataList.add(selectedData);
			// データ1行の取得
			selectedData = tableObject.selectNext();//ほんとうはwhile()の条件の中に書きたい！
		}

		return selectedDataList.size() == 0 ? null : selectedDataList;
	}

	/**
	 * ユーザーIDからユーザー名を取得する。
	 * @param commonItem バッチ共通パラメータ電文
	 * @param userId ユーザーID
	 * @return ユーザー名
	 * @throws Exception 業務サービス内で発生した例外全般。
	 */
	static String getUserNm(JBSbatCommonItem commonItem, String userId) throws Exception
	{
		// ユーザー
		JBSbatSQLAccess dbUser = getDataAccessObj(commonItem, D_TBL_NAME_ZM_M_USER);

		// バイント変数のリストを生成します
		JBSbatCommonDBInterface whereMap = new JBSbatCommonDBInterface();
		whereMap.setValue(JBSbatZM_M_USER.USER_ID, userId);	// ユーザーID

		// DBアクセスを実行します
		JBSbatCommonDBInterface selectedData = dbUser.selectByPrimaryKeys(whereMap);

		String userNm = null;

		if (selectedData != null)
		{
			userNm = selectedData.getString(JBSbatZM_M_USER.USER_NM);	// ユーザー名
		}

		return userNm;
	}

	/**
	 * 業務個別設定組織コードから業務個別設定組織名を取得する。
	 * @param commonItem バッチ共通パラメータ電文
	 * @param wkkbtOrgCd 業務個別設定組織コード
	 * @return 業務個別設定組織名
	 * @throws Exception 業務サービス内で発生した例外全般。
	 */
	static String getWkkbtOrgNm(JBSbatCommonItem commonItem, String wkkbtOrgCd) throws Exception
	{
		// 業務個別設定組織
		JBSbatSQLAccess db = getDataAccessObj(commonItem, ZM_M_WKKBT_ORG);

		// バイント変数のリストを生成します
		JBSbatCommonDBInterface whereMap = new JBSbatCommonDBInterface();
		whereMap.setValue(JBSbatZM_M_WKKBT_ORG.WKKBT_ORG_CD, wkkbtOrgCd);	// 業務個別設定組織コード

		// DBアクセスを実行します
		JBSbatCommonDBInterface selectedData = db.selectByPrimaryKeys(whereMap);

		String wkkbtOrgNm = null;

		if (selectedData != null)
		{
			// 業務個別設定組織名
			wkkbtOrgNm = selectedData.getString(JBSbatZM_M_WKKBT_ORG.WKKBT_ORG_NM);
		}

		if (wkkbtOrgNm == null)
		{
			wkkbtOrgNm = "";
		}

		return wkkbtOrgNm;
	}

	/**
	 * 後方一致検索の検索文字列を取得します。
	 * @param value 検索文字
	 * @return % + ワイルドカードをエスケープした検索文字
	 */
	static String getPostfixSearchString(String value)
	{
		if (value == null)
		{
			return null;
		}
		return PERCENT + replaceLikeValue(value);
	}

	/**
	 * LIKE検索に設定する値に対して、ワイルドカードが含まれている場合、
	 * ESCAPE文字列を追加して値を返却します。
	 * @param value 設定値
	 * @return 変換後文字列
	 */
	private static String replaceLikeValue(String value)
	{
		if (value == null)
		{
			return null;
		}

		String returnValue = value;
		for (int index = 0; index < ESCAPE_TARGET.length; index++)
		{
			returnValue = returnValue.replace(ESCAPE_TARGET[index], ESCAPE_TARGET_REPLACE_RESULT[index]);
		}
		return returnValue;
	}
}
