/*
このファイルの中身は、NTT オープンソースライセンス　バージョン 1.0（「本
契約」という）の適用を受けます。
本契約を遵守しない限り、このファイルを使用してはなりません。
本契約のコピーは、次のＵＲＬから入手できます。
【配布サイトのURL】 http://www.oss.ecl.ntt.co.jp/lms/

本契約に基づき頒布されるソフトウェアは、現状のまま、明示又は黙示のあらゆ
る種類の保証なしで、頒布されます。本契約に基づく権利及び制限を律する特定
の文言については、本契約を参照してください。

「オリジナルコード」は、 NTT Cyber Space Laboratories Code です。 
「オリジナルコード」の「初期開発者」は、日本電信電話株式会社です。  
日本電信電話株式会社により創作された部分は、Copyright (C) 2004 
日本電信電話株式会社 です。
全ての権利が留保されます。 
「コントリビュータ」：_____________________________________ 


The contents of this file are subject to the NTT Opensource License
Version 1.0 (the License); you may not use this file except in
compliance with the License. You may obtain a copy of the License at
【配布サイトのURL】 http://www.oss.ecl.ntt.co.jp/lms/

Software distributed under the License is distributed on an AS IS
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
License for the specific language governing rights and limitations
under the License.

The Original Code is NTT Cyber Space Laboratories Code .

The Initial Developer of the Original Code is NIPPON TELEGRAPH AND 
TELEPHONE CORPORATION.
Portions created by the NIPPON TELEGRAPH AND TELEPHONE CORPORATION 
are Copyright (C) 2004 NIPPON TELEGRAPH AND TELEPHONE CORPORATION. 
All Rights Reserved.

Contributor(s) ______________________________________.
*/

//
//	Evaluate 管理XMO データ保持クラス
//			変更履歴
//				2004.01.08	新規作成              五木田　泰史
//
package jp.co.ntt.lms.xmo.Evaluate;

import java.util.*;
import java.sql.*;

import org.apache.commons.lang.StringEscapeUtils;

import jp.co.ntt.lms.xmo.*;
import jp.co.ntt.lms.xmo.util.ChangeEncode;
import jp.co.ntt.lms.xmo.util.DebugLog;
import jp.co.ntt.lms.xmo.Message.Message;

/**
 * Evaluate 管理XMO データアクセスクラスです。<BR>
 * このクラスはEvaluateテーブルへの登録、修正、削除、検索処理を実行します。<BR>
 * DataAccessクラスを使用し、登録、修正、削除、検索処理単位で
 * トランザクション管理を行います。
 * @author Y.Gokita
 * @version 0.0.0.1 2004/01/08
 */
public class EvaluateDataAccess
	implements EvaluateMessage, EvaluateTable
{

	/**
	 * コンストラクタです。<BR>
	 * 親クラスのコンストラクタを呼び出し、自分が管理するテーブル名を
	 * 設定します。
	 */
	public EvaluateDataAccess() {
	}

	/**
	 * Evaluateテーブルへ登録処理を行います。<BR>
	 * 以下の情報をHashtableに格納して渡してください。<BR>
	 * なおテーブルの主キー以外を省略した場合は省略したフィールドには
	 * Null値が格納されます。
	 * <PRE>
	 *             key                     説明
	 *          ---------------------------------------------
	 *             LOID                    LoID
	 *             USER                    ユーザーID
	 *             SCORE                   得点
	 *             CUSTOM_MSG_DIR          コメント
	 *          ---------------------------------------------
	 * </PRE>
	 * @param htData 登録情報
	 * @return String 結果(正しく終了した場合のみ)
	 * @exception XMOException データベースエラーが発生した場合
	 */
	synchronized public String insert( Hashtable htData )
		throws XMOException
	{
		// 評価データがnullのとき
		if( htData == null ) {
			// パラメータエラーをスローする
			throw new XMOException( getMessageData( PARAM_WAR ) );
		}

		// データアクセスクラスをインスタンス化します
		DataAccess objDataAccess = new DataAccess(TABLE_NAME);
		try {
			// トランザクションを開始する
			objDataAccess.trans( htData );

			// 登録処理を実行します
			insertAction( htData, objDataAccess );

			// コミット処理
			objDataAccess.commit();
		}
		catch( XMOException xe ) {
			// ロールバック
			try { objDataAccess.rollback(); } catch( Exception ex ) {}
			throw xe;
		}
		catch( SQLException e ) {
			DebugLog.write( this.getClass(), e, DebugLog.HIGHT );
			// ロールバック
			try { objDataAccess.rollback(); } catch( Exception ex ) {}
			// データベースエラーを設定
			throw new XMOException( getMessageData( DB_ERR ) );
		}

		// 正常時空文字返却
		return "";
	}

	/**
	 * 登録処理実行メソッドです。<BR>
	 * 自分のテーブルに登録処理を行った後、GroupAndPeople管理XMO
	 * に親子関係を登録します。
	 * パラメータのチェックおよびトランザクションの管理は
	 * 上位メソッド内で行ってください。<BR>
	 * @param htbParam 登録情報
	 * @exception XMOException XMO独自エラー
	 * @exception SQLException DBエラーが発生した場合
	 */
	private void insertAction( Hashtable htbParam, DataAccess objDataAccess )
		throws XMOException, SQLException
	{
		// 登録処理用のデータをセットします
		Hashtable htbData = getData( htbParam );
		// 登録用SQLを生成します
		String strSQL = objDataAccess.getInsertSQL(htbData);
		// 登録処理を実行
		objDataAccess.execute( strSQL );
	}
	
	/**
	 * Evaluateテーブルへ更新処理を行います。<BR>
	 * 以下の情報をHashtableに格納して渡してください。<BR>
	 * 省略したフィールドは更新されません。
	 * <PRE>
	 *             key                     説明
	 *          ---------------------------------------------
	 *             LOID                    LoID
	 *             USER                    ユーザーID
	 *             SCORE                   得点
	 *             CUSTOM_MSG_DIR          コメント
	 *          ---------------------------------------------
	 *             CONDITION_KEY           更新条件文
	 *          ---------------------------------------------
	 * </PRE>
	 * @param htData 更新情報
	 * @return String 結果(正しく終了した場合のみ)
	 * @exception XMOException データベースエラーが発生した場合
	 */
	synchronized public String update( Hashtable htData )
		throws XMOException
	{
		// グループデータがnullのとき
		if( htData == null ) {
			// パラメータエラーをスローする
			throw new XMOException( getMessageData( PARAM_WAR ) );
		}

		// データアクセスクラスをインスタンス化します
		DataAccess objDataAccess = new DataAccess(TABLE_NAME);
		try {

			// トランザクションを開始する
			objDataAccess.trans( htData );

			// 更新処理を実行します
			updateAction( htData, objDataAccess );

			// コミット処理
			objDataAccess.commit();
		}
		catch( XMOException xe ) {
			// ロールバック
			try { objDataAccess.rollback(); } catch( Exception ex ) {}
			throw xe;
		}
		catch( SQLException e ) {
			DebugLog.write( this.getClass(), e, DebugLog.HIGHT );
			// ロールバック
			try { objDataAccess.rollback(); } catch( Exception ex ) {}
			// データベースエラーを設定
			throw new XMOException( getMessageData( DB_ERR ) );
		}

		// 正常時空文字返却
		return "";
	}

	/**
	 * 更新処理実行メソッドです。<BR>
	 * パラメータのチェックおよびトランザクションの管理は
	 * 上位メソッド内で行ってください。<BR>
	 * @param htbParam 更新情報
	 * @exception XMOException XMO独自エラー
	 * @exception SQLException DBエラーが発生した場合
	 */
	private void updateAction( Hashtable htbParam, DataAccess objDataAccess  )
		throws XMOException, SQLException
	{
		///////////////////////////////////////////////////////
		// 更新対象レコードの存在チェックを行います
		///////////////////////////////////////////////////////
		String strCondition = (String)htbParam.get( CONDITION_KEY );
		if( strCondition != null ) {
			if( !objDataAccess.isExit( strCondition ) ) {
				throw new XMOException( getMessageData( NOEXIT_RECORD_WAR ) );
			}
		}
		// 更新するレコードを取得します
		Vector vecSelect = selectAction( htbParam, objDataAccess );
		// 登録処理用のデータをセットします
		Hashtable htbData = getData( htbParam );
		
		String strSQL = objDataAccess.getUpdateSQL(htbData);
		// 条件文の設定
		if( strCondition != null ) {
			strSQL += strCondition;
		}
		
		// 登録処理を実行
		objDataAccess.execute( strSQL );
	}
	
	/**
	 * Evaluateテーブルへ削除処理を行います。<BR>
	 * 以下の情報をHashtableに格納して渡してください。
	 * <PRE>
	 *             key                     説明
	 *          ---------------------------------------------
	 *             CONDITION_KEY           削除条件文
	 *          ---------------------------------------------
	 * </PRE>
	 * @param htData 削除情報
	 * @return String 結果(正しく終了した場合のみ)
	 * @exception XMOException データベースエラーが発生した場合
	 */
	synchronized public String delete( Hashtable htData )
		throws XMOException
	{
		// データアクセスクラスをインスタンス化します
		DataAccess objDataAccess = new DataAccess(TABLE_NAME);
		try {
			// トランザクションを開始する
			objDataAccess.trans( htData );
			// 削除処理実行メソッドを実行します
			deleteAction( htData, objDataAccess );
			// コミット処理
			objDataAccess.commit();
		}
		catch( XMOException xe ) {
			// ロールバック
			try { objDataAccess.rollback(); } catch( Exception ex ) {}
			throw xe;
		}
		catch( SQLException e ) {
			DebugLog.write( this.getClass(), e, DebugLog.HIGHT );
			// ロールバック
			try { objDataAccess.rollback(); } catch( Exception ex ) {}
			// データベースエラーを設定
			throw new XMOException( getMessageData( DB_ERR ) );
		}
		return "";
	}

	/**
	 * 削除処理実行メソッドです。<BR>
	 * パラメータのチェックおよびトランザクションの管理は
	 * 上位メソッド内で行ってください。<BR>
	 * @param htbParam 削除情報
	 * @exception XMOException XMO独自エラー
	 * @exception SQLException DBエラーが発生した場合
	 */
	private void deleteAction( Hashtable htbParam, DataAccess objDataAccess )
		throws XMOException, SQLException
	{

		// LOIDの取得
		String strLOID = (String)htbParam.get( DELETE_LOID );

		if( strLOID == null ) {
			throw new XMOException( getMessageData( "LOID_GET_FAILD_ERR" ) );
		}

		// LOLogテーブルデータ削除用SQLの組み立て
		StringBuffer sbSQL = new StringBuffer();
		sbSQL.append( "DELETE FROM " );
		sbSQL.append( TABLE_NAME );
		sbSQL.append( " WHERE " );
		sbSQL.append( LOID );
		sbSQL.append( " = '" );
		sbSQL.append( StringEscapeUtils.escapeSql(strLOID) );
		sbSQL.append( "' ");

		// SQLを実行する
		objDataAccess.execute( sbSQL.toString() );

	}

	/**
	 * Evaluateテーブルへ検索処理を行います。<BR>
	 * 以下の情報をHashtableに格納して渡してください。
	 * <PRE>
	 *             key                     説明
	 *          ---------------------------------------------
	 *             CONDITION_KEY           検索条件文
	 *          ---------------------------------------------
	 * </PRE>
	 * @param htData 検索情報
	 * @return String 結果(正しく終了した場合のみ)
	 * @exception XMOException データベースエラーが発生した場合
	 */
	public Vector select( Hashtable htData )
		throws XMOException
	{
		// データがnullのとき
		if( htData == null ) {
			throw new XMOException( getMessageData( PARAM_WAR ) );
		}

		// 戻り値
		Vector vecReturn = new Vector();
		// データアクセスクラスをインスタンス化します
		DataAccess objDataAccess = new DataAccess(TABLE_NAME);
		try {
			// トランザクションを開始する
			objDataAccess.trans( htData );
			// 検索処理実行メソッド
			vecReturn = selectAction( htData, objDataAccess );
			// コミット
			objDataAccess.commit();
		}
		catch( XMOException xe ) {
			// ロールバック
			try { objDataAccess.rollback(); } catch( Exception ex ) {}
			throw xe;
		}
		catch( SQLException e ) {
			DebugLog.write( this.getClass(), e, DebugLog.HIGHT );
			// ロールバック
			try { objDataAccess.rollback(); } catch( Exception ex ) {}
			// データベースエラーを設定
			throw new XMOException( getMessageData( DB_ERR ) );
		}
		return vecReturn;
	}

	/**
	 * 検索処理実行メソッドです。<BR>
	 * パラメータのチェックおよびトランザクションの管理は
	 * 上位メソッド内で行ってください。<BR>
	 * @param htbParam 検索情報
	 * @return Vector 検索結果
	 * @exception XMOException XMO独自エラー
	 * @exception SQLException DBエラーが発生した場合
	 */
	private Vector selectAction( Hashtable htbParam, DataAccess objDataAccess )
		throws XMOException, SQLException
	{

		// SQLの組み立て
		StringBuffer sbSQL = new StringBuffer();
		sbSQL.append( "SELECT * FROM " + TABLE_NAME );
		// 条件文の取得
		String strCondition = (String)htbParam.get( CONDITION_KEY );
		if( strCondition != null ) {
			sbSQL.append( strCondition );
		}
		String strOrderBy   = (String)htbParam.get(ORDER_BY);
		if(strOrderBy != null)
		{
			sbSQL.append(strOrderBy);
		}

		// クエリーを実行します
		ResultSet rs = objDataAccess.executeQuery(sbSQL.toString());

		Vector vecReturn = new Vector();
		while(rs.next()) {
			String strLoID = ChangeEncode.setChar( rs.getString( LOID ) );
			String strUserID = ChangeEncode.setChar( rs.getString( USER ) );
			String strScoreDate = ChangeEncode.setChar( rs.getString( SCOREDATE ) );
			String strScore = ChangeEncode.setChar( rs.getString( SCORE ) );
			String strCustomMsgDir = ChangeEncode.setChar( rs.getString( CUSTOM_MSG_DIR ) );
			EvaluateData objData = new EvaluateData();
			objData.setLoID( strLoID );
			objData.setUserID( strUserID );
			objData.setScore( strScore );
			objData.setCustomMsgDir( strCustomMsgDir );
			vecReturn.add( objData );
		}
		return vecReturn;
	}

	/**
	 * 登録、更新処理時のデータを組み立てます
	 * @param htData
	 * @return Hashtable
	 */
	private Hashtable getData( Hashtable htbParam ) {
		Hashtable htbData = new Hashtable();
		putData( htbData, htbParam, LOID );
		putData( htbData, htbParam, USER );
		putData( htbData, htbParam, SCOREDATE );								
		putData( htbData, htbParam, SCORE );
		putData( htbData, htbParam, CUSTOM_MSG_DIR );
		return htbData;
	}

	/**
	 * 安全にHashtableに追加するメソッドです
	 */
	private void putData( Hashtable htbData,  Hashtable htbParam, String strKey ) {
		String strValue = (String)htbParam.get( strKey );
		if( strValue != null ) {
			htbData.put( strKey, strValue );
		}
	}

	/**
	 * メッセージオブジェクトを作成します
	 * @param strMessageID メッセージID
	 * @return MessageData メッセージオブジェクト 例外発生時はnullを返します
	 */
	private MessageData getMessageData( String strMessageID) {
		MessageData objMessage = null;
		try {
			objMessage = Message.getInstance().getMessageData( strMessageID, MSG_FIEL_PATH, MSG_FILE_NAME );
		}
		catch( Exception e ) {

		}
		return objMessage;
	}

	/**
	 * Evaluateテーブルへ更新処理を行います。<BR>
	 * 以下の情報をHashtableに格納して渡してください。<BR>
	 * 省略したフィールドは更新されません。
	 * <PRE>
	 *             key                     説明
	 *          ---------------------------------------------
	 *             LOID                    LoID
	 *             USER                    ユーザーID
	 *             SCORE                   得点
	 *             CUSTOM_MSG_DIR          コメント
	 *          ---------------------------------------------
	 *             CONDITION_KEY           更新条件文
	 *          ---------------------------------------------
	 * </PRE>
	 * @param htData 更新情報
	 * @return String 結果(正しく終了した場合のみ)
	 * @exception XMOException データベースエラーが発生した場合
	 */
	synchronized public String changeTypeUpdate( Hashtable htData )
		throws XMOException {
		// グループデータがnullのとき
		if ( htData == null ) {
			// パラメータエラーをスローする
			throw new XMOException( getMessageData( PARAM_WAR ) );
		}

		// データアクセスクラスをインスタンス化します
		DataAccess objDataAccess = new DataAccess( TABLE_NAME );
		try {

			// トランザクションを開始する
			objDataAccess.trans( htData );

			// 更新処理を実行します
			changeTypeUpdateAction( htData, objDataAccess );

			// コミット処理
			objDataAccess.commit();
		}

		catch ( SQLException e ) {
			DebugLog.write( this.getClass(), e, DebugLog.HIGHT );
			// ロールバック
			try {
				objDataAccess.rollback();
			} catch ( Exception ex ) {
			}
			// データベースエラーを設定
			throw new XMOException( getMessageData( DB_ERR ) );
		}

		// 正常時空文字返却
		return "";
	}

	/**
	 * 更新処理実行メソッドです。 <BR>
	 * パラメータのチェックおよびトランザクションの管理は 上位メソッド内で行ってください。 <BR>
	 * 
	 * @param htbParam 更新情報
	 * @param objDataAccess
	 * @exception SQLException DBエラーが発生した場合
	 */
	private void changeTypeUpdateAction(
		Hashtable htbParam,
		DataAccess objDataAccess ) throws SQLException {
		///////////////////////////////////////////////////////
		// 更新対象レコードの存在チェックを行います
		///////////////////////////////////////////////////////
		String strCondition = ( String ) htbParam.get( CONDITION_KEY );
		if ( strCondition != null ) {
			if ( objDataAccess.isExit( strCondition ) ) {
				// 登録処理用のデータをセットします
				Hashtable htbData = getData( htbParam );

				String strSQL = objDataAccess.getUpdateSQL( htbData );
				// 条件文の設定
				if ( strCondition != null ) {
					strSQL += strCondition;
				}
				// 登録処理を実行
				objDataAccess.execute( strSQL );
			}
		}
	}
}
