/* $Id: MySQLUserManagerDAO.java,v 1.3 2007/12/07 05:04:57 nito Exp $
 *
 * Copyright (c)ARGO 21, Corporation. 2005, 2006.  All rights reserved.
 * 
 * This file is part of Nautica Workflow Core.
 * 
 *  Nautica Workflow Core is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation; either version 2.1 of the License, or
 *  (at your option) any later version.
 * 
 *  Nautica Workflow Core 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 Lesser General Public License for more details.
 * 
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with Nautica Workflow Core; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *  
 */
package jp.co.argo21.nautica.workflow.dataaccess.mysql;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.apache.log4j.Logger;

import jp.co.argo21.nautica.workflow.dataaccess.AbstractDAO;
import jp.co.argo21.nautica.workflow.dataaccess.DAOException;
import jp.co.argo21.nautica.workflow.dataaccess.RoleManagerDAO;
import jp.co.argo21.nautica.workflow.dataaccess.UserBean;
import jp.co.argo21.nautica.workflow.dataaccess.UserManagerDAO;
import jp.co.argo21.nautica.workflow.dataaccess.WorkflowDAOFactory;
import jp.co.argo21.nautica.workflow.engine.DataAccessManager;
import jp.co.argo21.nautica.workflow.engine.LogManager;
import jp.co.argo21.nautica.workflow.wfmc.Participant;

/**
 * UserBeanをデータとするMySQL用DAOクラスである。
 * 
 * <pre><tt>
 * USERテーブル
 * +--------------+-------------+------+-----+---------+-------+
 * | Field        | Type        | Null | Key | Default | Extra |
 * +--------------+-------------+------+-----+---------+-------+
 * | USER_ID      | varchar(64) |      | PRI |         |       |
 * | FIRST_NAME   | varchar(64) |      |     |         |       |
 * | LAST_NAME    | varchar(64) |      |     |         |       |
 * | PASSWORD     | varchar(64) |      |     |         |       |
 * | MAIL_ADDRESS | varchar(64) |      |     |         |       |
 * +--------------+-------------+------+-----+---------+-------+
 * </tt></pre>
 * 
 * 属性は、カラム名をキー値としている。 カラム名の大文字小文字に関わらず、属性のキー値は大文字で設定される。
 * 
 * @author mmanabe(Argo 21, Corp.)
 * @version $Revision: 1.3 $
 * @since Nautica Workflow 1.0
 */
public class MySQLUserManagerDAO extends AbstractDAO implements UserManagerDAO
{
	/** エンジンログ */
	protected static Logger eLog = LogManager.getEngineLogger();

	/** ユーザIDのカラム名 */
	private static final String USER_ID = "USER_ID";

	/** ファミリーネームのカラム名 */
	private static final String FIRST_NAME = "FIRST_NAME";

	/** ファーストネームのカラム名 */
	private static final String LAST_NAME = "LAST_NAME";

	private static final String MAIL_ADDRESS = "MAIL_ADDRESS";

	private static final String SQL_SELECT_BY_USER_ID
		= "select * from USER where USER_ID = ?";

	private static final String SQL_SELECT_BY_USER_ID_AND_PASSWORD
		= "select * from USER where USER_ID = ? and PASSWORD = ?";

	/**
	 * ユーザテーブルに対するアクセスオブジェクトを生成する。
	 * 
	 * @param conn
	 *            コネクション
	 */
	MySQLUserManagerDAO(Connection conn)
	{
		super(conn);
	}

	/**
	 * 指定されたユーザIDのユーザ情報を返す。 該当するユーザ情報が存在しない場合は null を返す。
	 * 
	 * @param uid
	 *            ユーザID
	 * @return 指定されたユーザIDの情報を持つUserBean
	 * @throws SQLException
	 *             任意のSQL例外
	 * @see jp.co.argo21.nautica.workflow.dataaccess.UserManagerDAO#findByUserID(java.lang.String)
	 */
	public UserBean findByUserID(String uid) throws SQLException
	{

		PreparedStatement st = getConnection().prepareStatement(
				SQL_SELECT_BY_USER_ID);
		try {
			st.setString(1, uid);

			/** ************ DEBUG ************* */
			eLog.debug(st.toString());
			/** ******************************** */

			ResultSet rs = st.executeQuery();

			UserBean bean = null;
			if (rs.next()) {
				bean = createBean(rs);
			}

			return bean;

		} finally {
			st.close();
		}
	}

	/**
	 * 指定されたユーザIDのユーザ情報を返す。 該当するユーザ情報が存在しない場合は null を返す。
	 * 
	 * @param uid
	 *            ユーザID
	 * @param passwd
	 *            パスワード
	 * @return 指定されたユーザIDの情報を持つUserBean
	 * @throws SQLException
	 *             任意のSQL例外
	 * @throws DAOException
	 *             DAO実行中に処理としてあげる場合がある例外
	 */
	public UserBean findByUserIDAndPasswd(String uid, String passwd)
			throws SQLException, DAOException
	{
		PreparedStatement st = getConnection().prepareStatement(
				SQL_SELECT_BY_USER_ID_AND_PASSWORD);
		try {
			st.setString(1, uid);
			st.setString(2, passwd);

			/** ************ DEBUG ************* */
			eLog.debug(st.toString());
			/** ******************************** */

			ResultSet rs = st.executeQuery();

			UserBean bean = null;
			if (rs.next()) {
				bean = createBean(rs);
			}

			return bean;

		} finally {
			st.close();
		}
	}

	/**
	 * ResultSet中の情報からUserBeanを作成する。
	 * 
	 * @param rs
	 *            ResultSet
	 * @return ResultSetから取得した情報を持つUserBean
	 * @throws SQLException
	 *             任意のSQL例外
	 */
	static UserBean createBean(ResultSet rs) throws SQLException
	{
		UserBean bean = null;
		String uid = rs.getString(USER_ID);
		boolean isSystemUser = false;
		WorkflowDAOFactory factory = DataAccessManager.getDAOFactory();
		try {
			RoleManagerDAO roleDAO = factory.getRoleManagerDAO();
			isSystemUser = roleDAO.checkSystemRole(uid);
		} catch (Exception ex) {
			eLog.warn(ex.getMessage());
		}

		if (isSystemUser) {
			bean = new UserBean(uid, Participant.SYSTEM);
		} else {
			bean = new UserBean(uid, Participant.HUMAN);
		}
		bean.setFirstName(rs.getString(FIRST_NAME));
		bean.setLastName(rs.getString(LAST_NAME));
		bean.setAttribute(MAIL_ADDRESS, rs.getString(MAIL_ADDRESS));
		return bean;
	}
}