/*
 * MosP - Mind Open Source Project    http://www.mosp.jp/
 * Copyright (C) MIND Co., Ltd.       http://www.e-mind.co.jp/
 * 
 * This program is free software: you can redistribute it and/or
 * modify it under the terms of the GNU Affero General Public License
 * as published by the Free Software Foundation, either version 3
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 * 
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package jp.mosp.platform.base;

import java.sql.PreparedStatement;
import java.util.Date;
import java.util.Map;

import jp.mosp.framework.base.BaseDao;
import jp.mosp.framework.base.BaseDaoInterface;
import jp.mosp.framework.base.MospException;
import jp.mosp.framework.instance.InstanceFactory;
import jp.mosp.framework.utils.MospUtility;

/**
 * プラットフォームにおけるBeanの基本機能を提供する。<br>
 * <br>
 */
public abstract class PlatformDao extends BaseDao {
	
	/**
	 * クラスローダーからインスタンスを生成する。<br>
	 * サブクエリを取得したい場合等、DAOインスタンスのみが必要で
	 * コネクション等は不要な際に用いる。<br>
	 * クラス名は{@link MospUtility#getBeanKey(Class)}にて取得する。<br>
	 * @param cls 対象クラス
	 * @return 対象クラスインスタンス
	 * @throws MospException インスタンスの生成に失敗した場合
	 */
	protected Object loadInstance(Class<?> cls) throws MospException {
		// インスタンス生成
		return InstanceFactory.loadInstance(cls, mospParams);
	}
	
	/**
	 * DAOインスタンスを生成し、初期化する。<br>
	 * 但し、コネクションは設定しない。<br>
	 * サブクエリを取得したい場合等、DAOインスタンスのみが必要で
	 * コネクションは不要な際に用いる。<br>
	 * @param cls 対象DAOインターフェース
	 * @return 初期化されたDAOインスタンス
	 * @throws MospException DAOインスタンスの生成及び初期化に失敗した場合
	 */
	protected BaseDaoInterface loadDao(Class<?> cls) throws MospException {
		// インスタンス生成クラスを用いてDAOインスタンスを生成し初期化
		return InstanceFactory.loadDao(cls, mospParams, null);
	}
	
	/**
	 * 検索条件を取得する。<br>
	 * キーの検索条件が設定されていない場合、空文字列を返す。<br>
	 * @param searchParams 検索条件群
	 * @param key          検索条件キー
	 * @return 検索条件
	 */
	protected String getSearchParam(Map<String, Object> searchParams, String key) {
		Object obj = searchParams.get(key);
		if (obj instanceof String) {
			return (String)obj;
		}
		return "";
	}
	
	/**
	 * 検索条件を取得する。<br>
	 * キーの検索条件が設定されていない場合、空文字列を返す。<br>
	 * @param searchParams 検索条件群
	 * @param key          検索条件キー
	 * @return 検索条件
	 */
	protected boolean getSearchBoolParam(Map<String, Object> searchParams, String key) {
		Object obj = searchParams.get(key);
		if (obj instanceof Boolean) {
			return ((Boolean)obj).booleanValue();
		}
		return false;
	}
	
	/**
	 * 検索条件を取得する。<br>
	 * キーの検索条件が設定されていない場合、空の配列を返す。<br>
	 * @param searchParams 検索条件群
	 * @param key          検索条件キー
	 * @return 検索条件
	 */
	protected String[] getSearchParams(Map<String, Object> searchParams, String key) {
		Object obj = searchParams.get(key);
		if (obj instanceof String[]) {
			return (String[])obj;
		}
		return new String[0];
	}
	
	/**
	 * 有効日における最新の情報を抽出する条件SQLを取得する。<br>
	 * 一覧検索時等にWHERE句の最初で利用される。<br>
	 * @param table              対象テーブル名
	 * @param codeColumn         キーとなるコード列名
	 * @param activateDateColumn 有効日列名
	 * @return 有効日における最新の情報を抽出する条件SQL
	 */
	protected String getQueryForMaxActivateDate(String table, String codeColumn, String activateDateColumn) {
		// SQL作成準備
		StringBuffer sb = new StringBuffer();
		// 有効日における最新の情報を抽出する条件SQLを追加
		sb.append(activateDateColumn);
		sb.append(in());
		sb.append(leftParenthesis());
		sb.append(selectMax(getTmpTableColumn(table, activateDateColumn)));
		sb.append(from(table));
		sb.append(asTmpTable(table));
		sb.append(where());
		sb.append(deleteFlagOff());
		sb.append(and());
		sb.append(equalTmpColumn(table, codeColumn));
		sb.append(and());
		sb.append(lessEqual(getTmpTableColumn(table, activateDateColumn)));
		sb.append(rightParenthesis());
		return sb.toString();
	}
	
	/**
	 * 有効日における最新の情報を抽出する条件のパラメータを設定する。<br>
	 * 設定したパラメータの数だけ、パラメータインデックスが加算される。<br>
	 * @param index      パラメータインデックス
	 * @param targetDate 対象日
	 * @param ps         ステートメント
	 * @return 加算されたパラメータインデックス
	 * @throws MospException SQL例外が発生した場合
	 */
	protected int setParamsForMaxActivateDate(int index, Date targetDate, PreparedStatement ps) throws MospException {
		// パラメータインデックス準備
		int idx = index;
		// 有効日における最新の情報を抽出する条件のパラメータを設定
		setParam(idx++, targetDate, false, ps);
		// インデックス返却
		return idx;
	}
	
}
