/*******************************************************************************
 *	All Rights reserved,Copyright (c) K-Opticom
 ********************************************************************************
 *＜プログラム内容＞
 *	システム名		：eo顧客基幹システム
 *	モジュール名	：JCNejbExclusiveProcCN0341
 *	ソースファイル名：JCNejbExclusiveProcCN0341.java
 *	作成者			：富士通
 *	日付			：2024年2月27日
 *＜機能概要＞
 *	コンテンツを起点とするルートの排他処理部品。
 *＜修正履歴＞
 *	バージョン	修正日		修正者		修正内容
 *	v70.00.00	2024/2/27	FJ)藤本涼	
 *
 ********************************************************************************/

package eo.ejb.common.db;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;

import com.fujitsu.futurity.model.base.CAANConnectionMgr;
import com.fujitsu.futurity.model.base.CAANJDBCUtil;
import com.fujitsu.futurity.model.base.CAANMsg;
import com.fujitsu.futurity.model.base.CAANRuntimeException;
import com.fujitsu.futurity.model.ejb.common.JSYejbConnection;
import com.fujitsu.futurity.model.ejb.common.JSYejbLog;

import eo.ejb.cbm.entity.CN0341ETMsg;

/**
 * <p>
 * を起点とするルートの排他処理部品です。
 * </p>
 * @author 富士通
 *
 */
public class JCNejbExclusiveProcCN0341
{
	
	/** 更新用キー項目結合用文字（,） */
	private static final String KEY_JOIN_WORD = ",";

	/**
	 * 更新系インターフェイス使用時の処理を行います（SYSID指定）。
	 * レコードのロック、タイムスタンプの実施、ロック対象レコードの更新を行います。
	 * @param inETMsg 処理内で使用する項目を保持しているメッセージ
	 * @param key CONT_KEI_NO
	 * @param updDtmBf タイムスタンプチェック用更新年月日時分秒（更新前）
	 * @param funcCd 機能コード
	 * @return 処理が正常に終了し、タイムスタンプチェックが正常の場合はtrue。
	 */
	public boolean isExProcContKeiNo(CAANMsg inETMsg, String key, String updDtmBf, String funcCd)
	{
		JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "call:JCNejbExclusiveProcCN0341#isExProcContKeiNo");

		// CONT_KEI_NOが未設定の場合はtrueを返却する。
		if(null == key)
		{
			return true;
		}

		// 更新年月日時分秒(更新前)が未設定の場合はtrueを返却する。
		if(null == updDtmBf)
		{
			return true;
		}

		ArrayList<String> updArray = new ArrayList<String>();
		
		ArrayList<String> keyArrayCN0341 = new ArrayList<String>();
		
		// レコードロックの実行
		try 
		{
			// 処理対象の通秘データ同意の最終更新年月日時分秒のレコードを取得
			ArrayList<HashMap<String, String>> resultList = getLastUpdRecordCN0341(key);
			if(resultList.size() == 0)
			{
				return true;
			}
			
			for(HashMap<String, String> hm : resultList)
			{
				// 通秘データ同意をロック
				CAANMsg msg = new CAANMsg(CN0341ETMsg.class.getName());
				msg.set(CN0341ETMsg.CONT_KEI_NO_ERR, hm.get(CN0341ETMsg.CONT_KEI_NO));
				msg.set(CN0341ETMsg.GENE_ADD_DTM, hm.get(CN0341ETMsg.GENE_ADD_DTM));
				new JKKejbDBAUtil(msg).findByKeyForUpdate(msg);
				
				// キー情報の格納
				StringBuffer primary = new StringBuffer();
				primary.append(hm.get(CN0341ETMsg.CONT_KEI_NO));
				primary.append(KEY_JOIN_WORD);
				primary.append(hm.get(CN0341ETMsg.GENE_ADD_DTM));
				keyArrayCN0341.add(primary.toString());
				
				// 更新年月日時分秒の格納
				updArray.add(hm.get(CN0341ETMsg.UPD_DTM));
			}
		}
		catch (CAANRuntimeException ce)
		{
			// レコードロックに失敗した場合はfalseを返却する
			return false;
		}
		
		// データが取得できなかった場合は処理を終了する
		if(keyArrayCN0341.size() < 1)
		{
			return true;
		}
		
		// 共通処理のインスタンスを生成
		JKKejbExclusiveProcCommon epc = new JKKejbExclusiveProcCommon();
		
		// タイムスタンプチェックを行い、チェックエラーの場合はfalseを返却する。
		if (!epc.isTimeStampCheck(updArray, updDtmBf))
		{
			return false;
		}

		// 機能コードが実行モードの場合はロック対象レコード更新処理を行う
		if (!epc.isFuncMode(funcCd))
		{
			epc.updateCN0341(inETMsg, keyArrayCN0341);
		}

		return true;
	}

	/**
	 * <p>
	 * パラメータで渡されたCONT_KEI_NOに該当する
	 * お客様テーブル、異動予約テーブルで最後に更新されたレコードを取得する。
	 * </p>
	 * @param  primaryKey SYSID
	 * @return rsltList   検索結果
	 */
	public ArrayList<HashMap<String, String>> getLastUpdRecordCN0341(String primaryKey)
	{
		// コネクション
		Connection con = null;
		// プリペアステートメント
		PreparedStatement pstmt = null;
		// リザルトセット
		ResultSet rsltQuery = null;
		// SQL文
		StringBuffer sbSql = new StringBuffer();

		sbSql.append(" SELECT ");
		sbSql.append("    CN0341.CONT_KEI_NO, ");
		sbSql.append("    CN0341.GENE_ADD_DTM, ");
		sbSql.append("    CN0341.UPD_DTM ");
		sbSql.append(" FROM ");
		sbSql.append("    CN_T_CNKOTKMBNS_KNRI CN0341 ");
		sbSql.append(" WHERE   CN0341.CONT_KEI_NO = ? ");
		sbSql.append(" AND     CN0341.GENE_ADD_DTM =  ");
		sbSql.append("          (SELECT MAX(CN0341_01.GENE_ADD_DTM) AS CN0341_MAX ");
		sbSql.append("           FROM   CN_T_CNKOTKMBNS_KNRI CN0341_01 ");
		sbSql.append("           WHERE  CN0341_01.CONT_KEI_NO = CN0341.CONT_KEI_NO  ");
		sbSql.append("             AND  CN0341_01.MK_FLG = '0' ) ");
		
		try
		{
			// 対象テーブルのコネクション取得
			con = JSYejbConnection.getConnection(CN0341ETMsg.getTableName());

			// prepareStatementにSQL文をセット
			pstmt = con.prepareStatement(sbSql.toString());

			// ログ出力(SQL文の出力)
			JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), sbSql);

			// バインド変数設定
			CAANJDBCUtil.setParam(pstmt, 1, primaryKey);

			// ResultSetの取得
			rsltQuery = pstmt.executeQuery();

			// 格納マップの生成
			ArrayList<HashMap<String, String>> rsltList = new ArrayList<HashMap<String, String>>();
			
			// 取得結果をマップに格納
			while (rsltQuery.next())
			{
				// 格納マップの生成
				HashMap<String, String> mapRslt = new HashMap<String, String>();

				//コンテンツ公的身分証管理の情報を返却
				mapRslt.put(CN0341ETMsg.CONT_KEI_NO, rsltQuery.getString(1));
				mapRslt.put(CN0341ETMsg.GENE_ADD_DTM, rsltQuery.getString(2));
				mapRslt.put(CN0341ETMsg.UPD_DTM, rsltQuery.getString(3));
				rsltList.add(mapRslt);
			}

			// 取得した情報を返却
			return rsltList;

		}
		catch (SQLException e)
		{
			throw new CAANRuntimeException(e);
		}
		finally
		{
			// 資源の解放
			try
			{
				if (rsltQuery != null)
				{
					rsltQuery.close();
				}
				if (pstmt != null)
				{
					pstmt.close();
				}
				if (con != null)
				{
					CAANConnectionMgr.getInstance().close(con);
				}
			}
			catch (SQLException e1)
			{
				throw new CAANRuntimeException(e1);
			}
		}
	}
	
}
