/*********************************************************************
*	All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*	システム名		：eo顧客基幹システム
*	モジュール名	：JKKejbDBAUtil
*	ソースファイル名：JKKejbDBAUtil.java
*	作成者			：富士通
*	日付			：2011年8月2日
*＜機能概要＞
*	顧客契約データベースアクセス共通クラス
*＜修正履歴＞
*	バージョン	修正日		修正者		修正内容
*	v1.00.00	2011/08/02	FJ)			新規作成
*   v6.00.00    2013/11/27  FJ)寺園     ANK-1667-00-00
*
**********************************************************************/

package eo.ejb.common.db;

import java.lang.reflect.Method;

import com.fujitsu.futurity.common.JCMConstants;
import com.fujitsu.futurity.model.base.CAANCreateException;
import com.fujitsu.futurity.model.base.CAANFinderException;
import com.fujitsu.futurity.model.base.CAANMsg;
import com.fujitsu.futurity.model.base.CAANRemoveException;
import com.fujitsu.futurity.model.base.CAANRuntimeException;
import com.fujitsu.futurity.model.ejb.common.fw.TemplateSQLEntity;

/**
 * <p>
 * 顧客契約データベースアクセス共通クラスです。<br>
 * 以下の機能を提供します。<br>
 * <ol>
 * <li>世代登録年月日自分秒を除くプライマリキーでの論理削除
 * <li>世代登録年月日自分秒を除くプライマリキーでの物理削除
 * <li>データ登録処理
 * <li>データ更新処理
 * <li>データ削除処理
 * <li>排他モード一意検索処理
 * </ol>
 * </p>
 * @author 富士通
 */
public class JKKejbDBAUtil extends TemplateSQLEntity
{

	/** 処理対象のメッセージ */
	private CAANMsg inCBSMsg = null;

	/** スキーマ名 */
	private String schemaName = null;

	/** スキーマ定義情報 */
	private Object[][] schemaContents = null;

	/** テーブル名 */
	private String tableName = null;

	/** スキーマ定義情報の取得メソッド名 */
	private static final String GET_CONTENTS = "getContents";

	/** スキーマテーブル名の取得メソッド名 */
	private static final String GET_TABLE = "getTableName";

	/** 世代登録年月日時分秒 */
	private static final String GENE_ADD_DTM = "GENE_ADD_DTM";

	/** 更新年月日時分秒 */
	private static final String UPD_DTM = "UPD_DTM";

	/** 更新オペレータアカウント */
	private static final String UPD_OPEACNT = "UPD_OPEACNT";

	/** 削除年月日時分秒 */
	private static final String DEL_DTM = "DEL_DTM";

	/** 削除オペレータアカウント */
	private static final String DEL_OPEACNT = "DEL_OPEACNT";

	/** 無効フラグ */
	private static final String MK_FLG = "MK_FLG";

	/** 無効フラグ：有効 */
	private static final String MK_FLG_YK = "0";

	/** 無効フラグ：無効 */
	private static final String MK_FLG_MK = "1";

	/** 更新系サービスインターフェイス共通部項目定義 */
	private static final String[] CMN_HEADER_KMK = {
		JCMConstants.TEMPLATE_ID_KEY,		// サービスIF_ID
		JCMConstants.IDENTIFY_CD_KEY,		// 識別コード
		JCMConstants.STATUS_INT_KEY,		// ステータス
		JCMConstants.OPERATOR_ID_KEY,		// オペレータ_ID
		JCMConstants.OPERATE_DATE_KEY,		// 運用日付
		JCMConstants.OPERATE_DATETIME_KEY,	// 運用日時
		JCMConstants.ACCESS_GRP_KEY,		// 権限制御用項目
		JCMConstants.FUNC_CODE_KEY,			// 機能コード
	};

	/**
	 * <p>
	 * スキーマ名を取得します。
	 * </p>
	 * @return スキーマ名
	 */
	protected String getSchemaName()
	{
		return this.schemaName;
	}

	/**
	 * <p>
	 * スキーマの定義情報を取得します。
	 * </p>
	 * @return スキーマの定義情報
	 */
	protected Object[][] getSchemaContents()
	{
		return this.schemaContents;
	}

	/**
	 * <p>
	 * スキーマのテーブル名を取得します。
	 * </p>
	 * @return スキーマのテーブル名
	 */
	protected String getTableName()
	{
		return this.tableName;
	}

	/**
	 * <p>
	 * スキーマの定義情報を設定します。
	 * </p>
	 * @param inMsg 実行するメッセージ
	 */
	private void setSchemaContents(CAANMsg inMsg)
	{
		if (inMsg.getSchemaName().equals(this.schemaName))
		{
			return;
		}

		try
		{
			// 実行メッセージのスキーマ名からETMsgのインスタンスを生成
			Class<?>[] methodParam = null;
			Class<?> cls = Class.forName(inMsg.getSchemaName());
			Object instance = cls.newInstance();
			Method methodContents = cls.getMethod(GET_CONTENTS, methodParam);
			Method methodTable = cls.getMethod(GET_TABLE, methodParam);

			// 抽象メソッドの戻り値を設定
			Object[] invokeParam = null;
			this.schemaName = inMsg.getSchemaName();
			this.schemaContents = (Object[][])methodContents.invoke(instance, invokeParam);
			this.tableName = (String)methodTable.invoke(instance, invokeParam);
		}
		catch (Exception e)
		{
			throw new CAANRuntimeException(e);
		}
	}

	/**
	 * <p>
	 * JKKejbDBAUtilクラスのインスタンスを生成します。
	 * </p>
	 */
	private JKKejbDBAUtil()
	{
	}

	/**
	 * <p>
	 * JKKejbDBAUtilクラスのインスタンスを生成します。
	 * </p>
	 * @param inMsg 処理対象のメッセージ
	 */
	public JKKejbDBAUtil(CAANMsg inMsg)
	{
		this();
		this.inCBSMsg = inMsg;
	}

	/**
	 * <p>
	 * 条件指定で一括論理削除を行います。
	 * </p>
	 * @param inMsg 一括論理削除対象の条件項目が設定されたETメッセージ
	 */
	public void invalidAll(CAANMsg inMsg)
	{
		// スキーマ定義情報の設定
		setSchemaContents(inMsg);
		// 共通部項目の設定
		setCommonHeader(inMsg);

		// 有効データの検索
		inMsg.set(MK_FLG, MK_FLG_YK);
		CAANMsg[] msgList = findByCondition(inMsg);

		for (CAANMsg msg : msgList)
		{
			// 論理削除で更新する項目の設定
			msg.set(UPD_DTM, this.inCBSMsg.getObject(JCMConstants.OPERATE_DATETIME_KEY));
			msg.set(UPD_OPEACNT, this.inCBSMsg.getObject(JCMConstants.OPERATOR_ID_KEY));
			msg.set(DEL_DTM, this.inCBSMsg.getObject(JCMConstants.OPERATE_DATETIME_KEY));
			msg.set(DEL_OPEACNT, this.inCBSMsg.getObject(JCMConstants.OPERATOR_ID_KEY));
			msg.set(MK_FLG, MK_FLG_MK);

			// 更新処理の実行
			update(msg);
		}
	}
	
	/**
	 * <p>
	 * 世代登録年月日自分秒を除くプライマリキーでの物理削除を行います。
	 * </p>
	 * @param inMsg 削除データを格納したメッセージ
	 */
	public void removeAll(CAANMsg inMsg)
	{
		// スキーマ定義情報の設定
		setSchemaContents(inMsg);
		// 共通部項目の設定
		setCommonHeader(inMsg);

		// 有効データの検索
		CAANMsg[] msgList = findByCondition(inMsg);

		for (CAANMsg msg : msgList)
		{
			// プライマリキーの補完
			inMsg.set(GENE_ADD_DTM, msg.getObject(GENE_ADD_DTM));
			// 削除処理の実行
			remove(inMsg);
		}
	}
	
	/**
	 * <p>
	 * 指定した条件での物理削除を行います。
	 * </p>
	 * @param inMsg 削除データを格納したメッセージ
	 */
	public void removeAll2(CAANMsg inMsg)
	{
		// スキーマ定義情報の設定
		setSchemaContents(inMsg);
		// 共通部項目の設定
		setCommonHeader(inMsg);

		// 有効データの検索
		CAANMsg[] msgList = findByCondition(inMsg);

		for (CAANMsg msg : msgList)
		{
			// 削除処理の実行
			remove(msg);
		}
	}

	/**
	 * <p>
	 * データベースの登録処理を実行します。
	 * </p>
	 * @param inMsg 登録データが格納されたメッセージ
	 * @return 実行結果のメッセージ
	 */
	public CAANMsg create(CAANMsg inMsg)
	{
		try
		{
			// スキーマ定義情報の設定
			setSchemaContents(inMsg);
			// 共通部項目の設定
			setCommonHeader(inMsg);
			// 登録処理の実行
			return super.create(inMsg);
		}
		catch (CAANCreateException cce)
		{
			throw new CAANRuntimeException(cce);
		}
	}

	/**
	 * <p>
	 * データベースの更新処理を実行します。
	 * </p>
	 * @param inMsg 更新データが格納されたメッセージ
	 * @return 実行結果のメッセージ
	 */
	public CAANMsg update(CAANMsg inMsg)
	{
		try
		{
			// スキーマ定義情報の設定
			setSchemaContents(inMsg);
			// 共通部項目の設定
			setCommonHeader(inMsg);
			// 更新処理の実行
			return super.update(inMsg);
		}
		catch (CAANFinderException cfe)
		{
			throw new CAANRuntimeException(cfe);
		}
	}

	/**
	 * <p>
	 * データベースの削除処理を実行します。
	 * </p>
	 * @param inMsg 削除データが格納されたメッセージ
	 * @return 実行結果のメッセージ
	 */
	public CAANMsg remove(CAANMsg inMsg)
	{
		try
		{
			// スキーマ定義情報の設定
			setSchemaContents(inMsg);
			// 共通部項目の設定
			setCommonHeader(inMsg);
			// 削除処理の実行
			return super.remove(inMsg);
		}
		catch (CAANRemoveException cre)
		{
			throw new CAANRuntimeException(cre);
		}
	}

	/**
	 * <p>
	 * プライマリキーによる排他モードの一意検索を行います。
	 * </p>
	 * @param inMsg 検索データを格納したメッセージ
	 * @return 検索結果のメッセージ
	 */
	public CAANMsg findByKeyForUpdate(CAANMsg inMsg)
	{
		try
		{
			// スキーマ定義情報の設定
			setSchemaContents(inMsg);
			// 共通部項目の設定
			setCommonHeader(inMsg);
			// 排他モード一意検索の実行
			return super.findByKeyForUpdate(inMsg);
		}
		catch (CAANFinderException cfe)
		{
			return null;
		}
	}

	/**
	 * <p>
	 * 指定された条件による全件検索を行います。
	 * </p>
	 * @param inETMsg 検索条件が格納されたメッセージ
	 * @return 検索結果のメッセージ
	 */
	private CAANMsg[] findByCondition(CAANMsg inETMsg)
	{
		try
		{
			String schemaID = schemaName.substring(18, 24);
			Class<?> cls = Class.forName("eo.ejb.cbm.entity." + schemaID + "LE");
			Object instance = cls.newInstance();
			Method method = cls.getMethod("findByCondition", CAANMsg.class);
			return (CAANMsg[])method.invoke(instance, inETMsg);
		}
		catch (Exception e)
		{
			throw new CAANRuntimeException(e);
		}
	}

	/**
	 * <p>
	 * 共通部項目の設定を行います。
	 * </p>
	 * @param inETMsg 処理対象のETMsg
	 */
	private void setCommonHeader(CAANMsg inETMsg)
	{
		for (String key : CMN_HEADER_KMK)
		{
			inETMsg.set(key, this.inCBSMsg.getObject(key));
		}
	}

}
