//
//メソッド 管理XMO サーバクラス
//		変更履歴
//			2004.01.08	新規作成	二條智文
//
package jp.co.ntt.lms.xmo.Method;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.Hashtable;
import java.util.Vector;

import org.apache.commons.lang.StringEscapeUtils;

import jp.co.ntt.lms.xmo.Message.Message;
import jp.co.ntt.lms.xmo.Method.MethodTable;
import jp.co.ntt.lms.xmo.MenuData;
import jp.co.ntt.lms.xmo.MessageData;
import jp.co.ntt.lms.xmo.XMO;
import jp.co.ntt.lms.xmo.XMOException;
import jp.co.ntt.lms.xmo.Method.MethodDataAccess;
import jp.co.ntt.lms.xmo.util.DebugLog;

/**
 * メソッド 管理XMO サーバクラスです。<BR>
 * XMO基本メソッドを実装し、クライアントからの登録、更新、削除、検索処理
 * 要求をうけそれぞれの処理を行います。<BR>
 * RMIサーバとして動作するためRemoteインタフェースであるXMOインタフェースを実装し、
 * 永続的な起動状態を確保するためjava.rmi.server.UnicastRemoteObjectクラスを継承します。
 * @author T.Nijou
 * @version 0.0.0.1 2004.01.08
 */
public class Method extends UnicastRemoteObject
implements XMO, MethodMessage,	MethodTable 
{
	//////////////////////////////////////////////////////////////////
	// メソッド名定義
	//////////////////////////////////////////////////////////////////
	/** 登録メソッド名です */
	private static final String METHOD1 = "insert";	// 登録
	/** 更新メソッド名です */
	private static final String METHOD2 = "update";	// 更新
	/** 削除メソッド名です */
	private static final String METHOD3 = "delete";	// 削除
	/** 検索メソッド名です */
	private static final String METHOD4 = "select";	// 検索
	
//	ADD 2005/05/16 START Koji Umehara [toeic650]
	/** カウンセルスケジュール検索メソッド名 */
	private static final String METHOD5 = METHOD_GETCOUNSELSCHEDULE;
	/** 配下メソッド一覧取得メソッド名 **/
	private static final String METHOD6 = METHOD_GETCHILDMETHODLIST;
//	ADD 2005/05/16 END Koji Umehara [toeic650]

	/**
	 * ＬＯテーブルアクセスクラスを保持します
	 */
	private MethodDataAccess pobjDataAccess = new MethodDataAccess();

	/**
	 * コンストラクタです。
	 */
	public Method() throws RemoteException {
		// リモートオブジェクトをエクスポートする
		// java.rmi.server.UnicastRemoteObject の
		// 引数なしのコンストラクタを呼び出す
		super();
	}

	/**
	 * メニュー一覧を返します
	 * @return Vector メニュー一覧
	 */
	public Vector getMenuList(Hashtable htbParam) {

		// 未実装
		return null;
	}

	/**
	 * メソッド一覧を返します
	 * @return Vector
	 */
	public Vector getMethodList() {
		Vector vecMethod = new Vector();
		vecMethod.add( METHOD1 );
		vecMethod.add( METHOD2 );
		vecMethod.add( METHOD3 );
		vecMethod.add( METHOD4 );
		return vecMethod;
	}

	/**
	 * デフォルトメニューを返します
	 * @return String
	 */
	public MenuData getDefaultMenu() {
		return null;
	}

	/**
	 * このXMOで定義された、メソッドのクライアント側からの入り口になるメソッドです。
	 * @param strMethodName 実行するメソッド名を指定します
	 * @param htData メソッドで実行するパラメータを指定します<BR>
	 *               なお必要なキーと値は各DAOの処理メソッドの説明を参照して下さい。
	 * @retunr Object 戻り値（さまざまな戻り値に対応するためObject型としてあります)<BR>
	 *                受け取り側では適切な値にキャストする必要があります。
	 */
	public Object execute( String strMethodName, Hashtable htData ) {

		Object objReturn = null;

		if( strMethodName.equals( METHOD1 ) ) {
			objReturn = insert( htData );
		}
		else if( strMethodName.equals( METHOD2 ) ) {
			objReturn = update( htData );
		}
		else if( strMethodName.equals( METHOD3 ) ) {
			objReturn = delete( htData );
		}
		else if( strMethodName.equals( METHOD4 ) ) {
			objReturn = select( htData );
		}
		else if( strMethodName.equals( METHOD5 ) ) {
			objReturn = getCounselSchedule( htData );
		}
		else if( strMethodName.equals( METHOD6 ) ) {
			objReturn = getChildMethodList( htData );
		}

		return objReturn;
	}

	/**
	 * 起動確認（必ずtrueを返す）
	 * @return boolean 必ずtrueが返ります
	 */
	public boolean isLaunch() {
		return true;
	}
	
	/**
	 * Methodテーブルへ登録処理を行います。<BR>
	 * 以下のパラメータチェックを行い、すべてOKの場合は
	 * DAOの登録処理メソッドを実行します。
	 * <PRE>
	 *             key                     説明
	 *          ---------------------------------------------
	 *             LO_ID                   LOID
	 *          ---------------------------------------------
	 * </PRE>
	 * @param htData 登録情報
	 * @return Vector 結果（配列の先頭にMessageDataオブジェクトを格納して返します)
	 */
	private Vector insert( Hashtable htData ) {
		MessageData objMessage = null;
		Vector vecResult = new Vector();

		try {
			// パラメータのチェック
			String strLoID = (String)htData.get( LO_ID );
			String strMethodLOID = (String)htData.get( METHODLOID );
			String strParallelFlag = (String)htData.get( PARALLELFLAG );
			String strStartDate = (String)htData.get( STARTDATE );
			String strEndDate = (String)htData.get( ENDDATE );
			String strPeriodNum = (String)htData.get( PERIODNUM );
			String strBeforeLearnFlag = (String)htData.get( BEFORELEARNFLAG );
			String strAfterLearnFlag = (String)htData.get( AFTERLEARNFLAG );
			String strLOURL = (String)htData.get( LOURL );

			String strMessage = MethodCheck.checkLOID( strLoID, true );
			if( !strMessage.equals( "" ) ) {
				throw new Exception( strMessage );
			}
			strMessage = MethodCheck.checkMethodLoID( strMethodLOID, false );
			if( !strMessage.equals( "" ) ) {
				throw new Exception( strMessage );
			}
			strMessage = MethodCheck.checkParallelFlag( strParallelFlag, false );
			if( !strMessage.equals( "" ) ) {
				throw new Exception( strMessage );
			}
			strMessage = MethodCheck.checkStart_date( strStartDate, false );
			if( !strMessage.equals( "" ) ) {
				throw new Exception( strMessage );
			}
			strMessage = MethodCheck.checkEnd_date( strEndDate, false );
			if( !strMessage.equals( "" ) ) {
				throw new Exception( strMessage );
			}
			strMessage = MethodCheck.checkPeriod_num( strPeriodNum, false );
			if( !strMessage.equals( "" ) ) {
				throw new Exception( strMessage );
			}
			strMessage = MethodCheck.checkBeforeLearnFlag( strBeforeLearnFlag, false );
			if( !strMessage.equals( "" ) ) {
				throw new Exception( strMessage );
			}
			strMessage = MethodCheck.checkAfterLearnFlag( strAfterLearnFlag, false );
			if( !strMessage.equals( "" ) ) {
				throw new Exception( strMessage );
			}

			// 格納する情報の設定
			Hashtable htParams = makeParam(strLoID, strLoID, strMethodLOID, 
					strParallelFlag, strStartDate, strEndDate, strPeriodNum, 
					strBeforeLearnFlag, strAfterLearnFlag, strLOURL, false);
			
			// LOExtendテーブルへ情報を格納します。
			MethodDataAccess objMethodDataAccess= new MethodDataAccess();
			objMethodDataAccess.insert(htParams);
	    }
	    catch (Exception e) {
			// 例外発生時は、メッセージを格納
			DebugLog.write(this.getClass(), e,DebugLog.HIGHT);
			objMessage = getMessageData( SYSTEM_ERR );
		}
	    finally {
	    	vecResult.add(0, objMessage);
	    }

		return vecResult;
	}
	
	/**
	 * Methodテーブルへ更新処理を行います。<BR>
	 * 以下のパラメータチェックを行い、すべてOKの場合は
	 * DAOの更新処理メソッドを実行します。
	 * <PRE>
	 *             key                     説明
	 *          ---------------------------------------------
	 *             LO_ID                   LOID
	 *          ---------------------------------------------
	 * </PRE>
	 * @param htData 登録情報
	 * @return Vector 結果（配列の先頭にMessageDataオブジェクトを格納して返します)
	 */
	private Vector update( Hashtable htData ) {
		MessageData objMessage = null;
		Vector vecResult = new Vector();

		try {
			// パラメータのチェック
			String strLoID = (String)htData.get( LO_ID );
			String strMethodLOID = (String)htData.get( METHODLOID );
			String strParallelFlag = (String)htData.get( PARALLELFLAG );
			String strStartDate = (String)htData.get( STARTDATE );
			String strEndDate = (String)htData.get( ENDDATE );
			String strPeriodNum = (String)htData.get( PERIODNUM );
			String strBeforeLearnFlag = (String)htData.get( BEFORELEARNFLAG );
			String strAfterLearnFlag = (String)htData.get( AFTERLEARNFLAG );
			String strLOURL = (String)htData.get( LOURL );

			String strMessage = MethodCheck.checkLOID( strLoID, true );
			if( !strMessage.equals( "" ) ) {
				throw new Exception( strMessage );
			}
			strMessage = MethodCheck.checkMethodLoID( strMethodLOID, false );
			if( !strMessage.equals( "" ) ) {
				throw new Exception( strMessage );
			}
			strMessage = MethodCheck.checkParallelFlag( strParallelFlag, false );
			if( !strMessage.equals( "" ) ) {
				throw new Exception( strMessage );
			}
			strMessage = MethodCheck.checkStart_date( strStartDate, false );
			if( !strMessage.equals( "" ) ) {
				throw new Exception( strMessage );
			}
			strMessage = MethodCheck.checkEnd_date( strEndDate, false );
			if( !strMessage.equals( "" ) ) {
				throw new Exception( strMessage );
			}
			strMessage = MethodCheck.checkPeriod_num( strPeriodNum, false );
			if( !strMessage.equals( "" ) ) {
				throw new Exception( strMessage );
			}
			strMessage = MethodCheck.checkBeforeLearnFlag( strBeforeLearnFlag, false );
			if( !strMessage.equals( "" ) ) {
				throw new Exception( strMessage );
			}
			strMessage = MethodCheck.checkAfterLearnFlag( strAfterLearnFlag, false );
			if( !strMessage.equals( "" ) ) {
				throw new Exception( strMessage );
			}

			// 格納する情報の設定
			Hashtable htParams = makeParam(strLoID, null, strMethodLOID, 
					strParallelFlag, strStartDate, strEndDate, strPeriodNum, 
					strBeforeLearnFlag, strAfterLearnFlag, strLOURL, true);
			
			// LOExtendテーブルへ情報を格納します。
			MethodDataAccess objMethodDataAccess= new MethodDataAccess();
			objMethodDataAccess.update(htParams);
	    }
	    catch (Exception e) {
			// 例外発生時は、メッセージを格納
			DebugLog.write(this.getClass(), e,DebugLog.HIGHT);
			objMessage = getMessageData( SYSTEM_ERR );
		}
	    finally {
	    	vecResult.add(0, objMessage);
	    }

		return vecResult;
	}
	
	/**
	 * Methodテーブルへ削除処理を行います。<BR>
	 * 以下のパラメータチェックを行い、すべてOKの場合は
	 * DAOの削除処理メソッドを実行します。
	 * <PRE>
	 *             key                     説明
	 *          ---------------------------------------------
	 *             CONDITION_KEY           更新条件文
	 *          ---------------------------------------------
	 * </PRE>
	 * @param htData 削除情報
	 * @return Vector 結果（配列の先頭にMessageDataオブジェクトを格納して返します)
	 */
	private Vector delete( Hashtable htData ) {
		MessageData objMessage = null;
		Vector vecResult = new Vector();

		try {
			// パラメータのチェック
			String strLoID = (String)htData.get( DELETE_LOID );
			
			String strMessage = MethodCheck.checkLOID( strLoID, true );
			if( !strMessage.equals( "" ) ) {
				throw new Exception( strMessage );
			}

			// 削除する情報の設定
			Hashtable htParams = makeParam(strLoID, null, null,
					null, null, null, null, null, null, null, true);
			
			// Methodテーブルの情報を削除します。
			MethodDataAccess objMethodDataAccess= new MethodDataAccess();
			objMethodDataAccess.delete(htParams);
	    }
	    catch (Exception e) {
			// 例外発生時は、メッセージを格納
			DebugLog.write(this.getClass(), e,DebugLog.HIGHT);
			objMessage = getMessageData( SYSTEM_ERR );
		}
	    finally {
	    	vecResult.add(0, objMessage);
	    }

		return vecResult;
	}

	/**
	 * Methodテーブルへ検索処理を行います。<BR>
	 * 以下のパラメータチェックを行い、すべてOKの場合は
	 * DAOの検索処理メソッドを実行します。
	 * <PRE>
	 *             key                     説明
	 *          ---------------------------------------------
	 *             CONDITION_KEY           検索条件文
	 *          ---------------------------------------------
	 * </PRE>
	 * @param htData 検索情報
	 * @return Vector 結果（配列の先頭にMessageDataオブジェクトを格納し、２番目移行に
	 *                      MethodDataクラスを格納して返します。)
	 */
	private Vector select( Hashtable htData ) {
		Vector vecResult = new Vector();

		MessageData objMessage = null;
		try {
			vecResult = pobjDataAccess.select( htData );
		}
		catch( XMOException xe ) {
			objMessage = xe.getMessageData();
		}

		// 配列の先頭にメッセージデータを格納します
		vecResult.add( 0, objMessage );
		return vecResult;
	}
	
	/**
	 * データの投入および検索に使用するパラメータを作成します。
	 * @param strTargetLoID			対象のLoID
	 * @param strLoID				LoID
	 * @param strMethodLoID			メソッドLOID
	 * @param strParallelFlag		配下の並び順並列フラグ
	 * @param strStartDate			開始日付
	 * @param strEndDate			終了予定日付
	 * @param strPeriodNum			期間
	 * @param strBeforeLearnFlag	計画日付前学習可能フラグ
	 * @param strAfterLearnFlag		計画日付後学習可能フラグ
	 * @param bWhere				LoIDを使用してWhere句を作成する:true/Where句無し:false
	 * @return Hashtable 			パラメータが設定されたオブジェクト
	 */
	private Hashtable makeParam(String strTargetLoID, String strLoID, 
			String strMethodLoID, 
			String strParallelFlag, String strStartDate, 
			String strEndDate, String strPeriodNum,
			String strBeforeLearnFlag, String strAfterLearnFlag,
			String strLOURL,
			boolean bWhere)
	{
		Hashtable htParams = new Hashtable();

		if (strLoID != null) {
			// LoIDの設定
			htParams.put( LO_ID, strLoID );
		}
		if (strMethodLoID != null) {
			// Buyの設定
			htParams.put( METHODLOID, strMethodLoID );
		}
		if (strParallelFlag != null) {
			// keyword1の設定
			htParams.put( PARALLELFLAG, strParallelFlag );
		}
		if (strStartDate != null) {
			// keyword2の設定
			htParams.put( STARTDATE, strStartDate );
		}
		if (strEndDate != null) {
			// keyword3の設定
			htParams.put( ENDDATE, strEndDate );
		}
		if (strPeriodNum != null) {
			// keyword4の設定
			htParams.put( PERIODNUM, strPeriodNum );
		}
		if (strBeforeLearnFlag != null) {
			// keyword5の設定
			htParams.put( BEFORELEARNFLAG, strBeforeLearnFlag );
		}
		if (strAfterLearnFlag != null) {
			// keyword5の設定
			htParams.put( AFTERLEARNFLAG, strAfterLearnFlag );
		}
		if (strLOURL != null) {
			// keyword5の設定
			htParams.put( LOURL, strLOURL );
		}

		// Where句を作成する
		if (bWhere) {
			if (strTargetLoID != null) {
				// 検索条件の設定
				String strCondition = TABLE_NAME + "." + LO_ID + "= '" + StringEscapeUtils.escapeSql(strTargetLoID) + "' ";
				htParams.put( CONDITION_KEY, " WHERE " + strCondition );
			}
		}
		
		return htParams;
	}

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

		}
		return objMessage;
	}

//	ADD 2005/05/16 START Koji Umehara [toeic650]
	/**
	 * ユーザーのカウンセルスケジュールを取得します。<BR>
	 * 以下のパラメータチェックを行い、すべてOKの場合は
	 * DAOの検索処理メソッドを実行します。
	 * <PRE>
	 *             key                     説明
	 *          ---------------------------------------------
	 *             CONDITION_KEY           検索条件文
	 *          ---------------------------------------------
	 * </PRE>
	 * @param htData 検索情報
	 * @return Vector 結果（配列の先頭にMessageDataオブジェクトを格納し、２番目移行に
	 *                      MethodDataクラスを格納して返します。)
	 */
	private Vector getCounselSchedule( Hashtable htData ) {
		Vector vecResult = new Vector();

		MessageData objMessage = null;
		try {
			vecResult = pobjDataAccess.getCounselSchedule( htData );
		}
		catch( XMOException xe ) {
			objMessage = xe.getMessageData();
		}

		// 配列の先頭にメッセージデータを格納します
		vecResult.add( 0, objMessage );
		return vecResult;
	}
	
	/**
	 * 指定したメソッド配下のメソッド一覧を取得します。<BR>
	 * 以下のパラメータチェックを行い、すべてOKの場合は
	 * DAOの検索処理メソッドを実行します。
	 * <PRE>
	 *             key                     説明
	 *          ---------------------------------------------
	 *             LO_ID                   親LOID
	 *             CONDITION_KEY           検索条件文
	 *             ORDER_BY                ソート条件文
	 *          ---------------------------------------------
	 * </PRE>
	 * @param htData 検索情報
	 * @return Vector 結果（配列の先頭にMessageDataオブジェクトを格納し、２番目移行に
	 *                      MethodDataクラスを格納して返します。)
	 */
	private Vector getChildMethodList( Hashtable htData ) {
		Vector vecResult = new Vector();

		MessageData objMessage = null;
		try {
			vecResult = pobjDataAccess.getChildMethodList( htData );
		}
		catch( XMOException xe ) {
			objMessage = xe.getMessageData();
		}

		// 配列の先頭にメッセージデータを格納します
		vecResult.add( 0, objMessage );
		return vecResult;
	}
//	ADD 2005/05/16 END Koji Umehara [toeic650]

}
