/////////////////////////////////////////////////////////////////
//Copyright (C) 2005 NTT CORPORATION.
//
//Lo拡張情報テーブルデータアクセスクラス
//
//変更履歴
//2005.02.10  新規作成  鏡味 克彦
//
//機能
//
//OLMSカスタマイズに伴うLo拡張情報テーブルデータアクセスクラスです。
//
/////////////////////////////////////////////////////////////////

package jp.co.ntt.lms.xmo.Lo.LoExtend;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Hashtable;
import java.util.Vector;

import jp.co.ntt.lms.xmo.Lo.LoTable;
import jp.co.ntt.lms.xmo.Message.Message;
import jp.co.ntt.lms.xmo.MessageData;
import jp.co.ntt.lms.xmo.util.DebugLog;
import jp.co.ntt.lms.xmo.util.ChangeEncode;
import jp.co.ntt.lms.xmo.DataAccess;
import jp.co.ntt.lms.lo.LOException;

/**
 * OLMS機能カスタマイズ：LO拡張情報テーブルデータアクセスクラス
 * @author Katsuhiko Kagami(UNITEC)
 * @version 1.0
 */
public class LoExtendDataAccess
	implements LoExtendMessage, LoTable, LoExtendTable 
{

	/**
     * デフォルトコンストラクタ
     */
    public LoExtendDataAccess()
	{
    }

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

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

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

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

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

		Vector vecReturn = new Vector();
		while(rs.next()) {
			String strLoID = ChangeEncode.setChar( rs.getString( LO_ID ) );
			String strBuy = ChangeEncode.setChar( rs.getString( LOEXTEND_BUY ) );
			String strKeyword1 = ChangeEncode.setChar( rs.getString( LOEXTEND_KEYWORD1 ) );
			String strKeyword2 = ChangeEncode.setChar( rs.getString( LOEXTEND_KEYWORD2 ) );
			String strKeyword3 = ChangeEncode.setChar( rs.getString( LOEXTEND_KEYWORD3 ) );
			String strKeyword4 = ChangeEncode.setChar( rs.getString( LOEXTEND_KEYWORD4 ) );
			String strKeyword5 = ChangeEncode.setChar( rs.getString( LOEXTEND_KEYWORD5 ) );

			LoExtendRecord objData = new LoExtendRecord(strLoID, strBuy, 
					strKeyword1, strKeyword2, strKeyword3, strKeyword4, strKeyword5);
			vecReturn.add( objData );
		}

		return vecReturn;
	}
	
	/**
	 * LoExtendテーブルへ登録処理を行います。<BR>
	 * 以下の情報をHashtableに格納して渡してください。<BR>
	 * なおテーブルの主キー以外を省略した場合は省略したフィールドには
	 * Null値が格納されます。
	 * <PRE>
	 *             key                     説明
	 *          ---------------------------------------------
	 *             LOID                    LoID
	 *             LOEXTEND_BUY            購入ステータス
	 *             LOEXTEND_KEYWORD1       LO推奨キーワード1
	 *             LOEXTEND_KEYWORD2       LO推奨キーワード2
	 *             LOEXTEND_KEYWORD3       LO推奨キーワード3
	 *             LOEXTEND_KEYWORD4       LO推奨キーワード4
	 *             LOEXTEND_KEYWORD5       LO推奨キーワード5
	 *          ---------------------------------------------
	 * </PRE>
	 * @param htData 登録情報
	 * @exception LOException データベースエラーが発生した場合
	 */
	synchronized public void insert( Hashtable htData )
		throws LOException
	{
		// 評価データがnullのとき
		if( htData == null ) {
			// パラメータエラーをスローする
			throw new LOException( getMessageData( PARAM_WAR ) );
		}

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

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

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

		return;
	}

	/**
	 * 登録処理実行メソッドです。<BR>
	 * 自分のテーブルに登録処理を行った後、GroupAndPeople管理XMO
	 * に親子関係を登録します。
	 * パラメータのチェックおよびトランザクションの管理は
	 * 上位メソッド内で行ってください。<BR>
	 * @param htbParam 登録情報
	 * @exception LOException パラメータエラーが発生した場合
	 * @exception SQLException DBエラーが発生した場合
	 */
	private void insertAction( Hashtable htbParam, DataAccess objDataAccess )
		throws SQLException, LOException
	{
		String strLoID = (String)htbParam.get( LO_ID );
		if( strLoID != null ) {
			// レコードが既に存在する場合は例外を発生させる。
			if( objDataAccess.isExit(htbParam, LO_ID, LOEXTEND_TABLE_NAME) ) {
				throw new LOException( getMessageData( EXIST_RECORD_WAR ) );
			}
		}
		
		// 登録処理用のデータをセットします
		Hashtable htbData = getData( htbParam );
		// 登録用SQLを生成します
		String strSQL = objDataAccess.getInsertSQL(htbData);
		// 登録処理を実行
		objDataAccess.execute( strSQL );
	}
	
	/**
	 * LoExtendテーブルへ更新処理を行います。<BR>
	 * 以下の情報をHashtableに格納して渡してください。<BR>
	 * 省略したフィールドは更新されません。
	 * <PRE>
	 *             key                     説明
	 *          ---------------------------------------------
	 *             LOID                    LoID
	 *             LOEXTEND_BUY            購入ステータス
	 *             LOEXTEND_KEYWORD1       LO推奨キーワード1
	 *             LOEXTEND_KEYWORD2       LO推奨キーワード2
	 *             LOEXTEND_KEYWORD3       LO推奨キーワード3
	 *             LOEXTEND_KEYWORD4       LO推奨キーワード4
	 *             LOEXTEND_KEYWORD5       LO推奨キーワード5
	 *          ---------------------------------------------
	 *             CONDITION_KEY           更新条件文
	 *          ---------------------------------------------
	 * </PRE>
	 * @param htData 更新情報
	 * @exception LOException データベースエラーが発生した場合
	 */
	synchronized public void update( Hashtable htData )
		throws LOException
	{
		// データがnullのとき
		if( htData == null ) {
			// パラメータエラーをスローする
			throw new LOException( getMessageData( PARAM_WAR ) );
		}

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

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

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

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

		return;
	}

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

	/**
	 * 削除処理実行メソッドです。<BR>
	 * パラメータのチェックおよびトランザクションの管理は
	 * 上位メソッド内で行ってください。<BR>
	 * @param htbParam 削除情報
	 * @exception LOException パラメータエラーが発生した場合
	 * @exception SQLException DBエラーが発生した場合
	 * MOD 2005/02/25 START
	 */
	synchronized public void deleteAction( Hashtable htbParam, DataAccess objDataAccess )
		throws LOException, SQLException
	{
		///////////////////////////////////////////////////////
		// 削除対象レコードの存在チェックを行います
		///////////////////////////////////////////////////////
		String strCondition = (String)htbParam.get( CONDITION_KEY );
		if( strCondition != null ) {
			if( !objDataAccess.isExit( strCondition ) ) {
				throw new LOException( getMessageData( NOEXIST_RECORD_WAR ) );
			}
		}

		// LOLogテーブルデータ削除用SQLの組み立て
		StringBuffer sbSQL = new StringBuffer();
		sbSQL.append( "DELETE FROM " );
		sbSQL.append( LOEXTEND_TABLE_NAME );
		if (strCondition != null) {
			sbSQL.append( " " );
			sbSQL.append( strCondition );
		}

		// SQLを実行する
		objDataAccess.execute( sbSQL.toString() );
	}
	
	/**
	 * 登録、更新処理時のデータを組み立てます
	 * @param htData
	 * @return Hashtable
	 */
	private Hashtable getData( Hashtable htbParam ) {
		Hashtable htbData = new Hashtable();
		putData( htbData, htbParam, LO_ID );
		putData( htbData, htbParam, LOEXTEND_BUY );
		putData( htbData, htbParam, LOEXTEND_KEYWORD1 );
		putData( htbData, htbParam, LOEXTEND_KEYWORD2 );
		putData( htbData, htbParam, LOEXTEND_KEYWORD3 );
		putData( htbData, htbParam, LOEXTEND_KEYWORD4 );
		putData( htbData, htbParam, LOEXTEND_KEYWORD5 );
		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;
	}

}
