/*
このファイルの中身は、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) ______________________________________.
*/

//
//	前提条件を扱うクラス
//			変更履歴
//				2004.01.08	新規作成	鈴木　敏子
//
package jp.co.ntt.lms.Common.status.prerequisite;

import java.util.Vector;

import jp.co.ntt.lms.xmo.LoRelation.LoRelationClient;
import jp.co.ntt.lms.xmo.util.DebugLog;
import jp.co.ntt.lms.xmo.DataAccess;
import jp.co.ntt.lms.xmo.Lo.LoClient;

/**
 * 前提条件を扱うクラスです。<BR>
 * @author T.Suzuki
 * @version 0.0.0.1
 */
public class Prerequisite implements PrerequisiteMessage{

	// インスタンス変数
	/** 前提条件条件式を保持します */
	private String mstrPrerequisite;
	/** ユーザIDを保持します */
	private String mstrUserID;
	/** LOIDを保持します */
	private String mstrLoID;
	/** データアクセスオブジェクトを保持します。*/
	private DataAccess mobjDataAccess;
	/** パース結果を保持します */
	private DecidePrerequisite objDecide = null;

	// コンストラクタ
	/**
	 * 前提条件条件式を指定します。<BR>
	 * 前提条件条件式の構文チェックのみを行いたい場合はこのコンストラクタを呼んでください。
	 * @param strPrerequisite 前提条件条件式
	 */
	public Prerequisite( String strPrerequisite ) {
		mstrPrerequisite = strPrerequisite;
	}

	/**
	 * 前提条件条件式および、LOIDを指定します。<BR>
	 * 前提条件の構文チェックおよび、LOIDチェックを行う場合はこのコンストラクタを呼んでください。
	 * @param strPrerequisite 前提条件条件式
	 * @param strLoID LOID
	 */
	public Prerequisite( String strPrerequisite, String strLoID ) {
		mstrPrerequisite = strPrerequisite;
		mstrLoID = strLoID;
	}

	/**
	 * 前提条件条件式、ユーザID、LOIDを指定します。<BR>
	 * パースを行って、前提条件を満たしているかチェックしたい場合はこのコンストラクタを呼んでください。
	 * @param strPrerequisite 前提条件条件式
	 * @param strUserID ユーザID
	 * @param strLoID LOID
	 */
	public Prerequisite( String strPrerequisite, String strUserID, String strLoID ) {
		mstrPrerequisite = strPrerequisite;
		mstrUserID = strUserID;
		mstrLoID = strLoID;
	}

	/**
	 * 前提条件条件式、ユーザID、LOIDを指定します。<BR>
	 * パースを行って、前提条件を満たしているかチェックしたい場合はこのコンストラクタを呼んでください。
	 * @param strPrerequisite 前提条件条件式
	 * @param strUserID ユーザID
	 * @param strLoID LOID
	 * @param objDataAccess データアクセスオブジェクト
	 */
	public Prerequisite( String strPrerequisite, String strUserID, String strLoID, DataAccess objDataAccess ) {
		mstrPrerequisite = strPrerequisite;
		mstrUserID = strUserID;
		mstrLoID = strLoID;
		mobjDataAccess = objDataAccess;
	}

	// 外部メソッド
	/**
	 * 前提条件条件式を解析します。
	 * @exception PrerequisiteParseException 前提条件条件式の構文に誤りがある場合
	 * @exception PrerequisiteException 解析中に実行時例外が生じた場合
	 */
	public void parse()
		throws PrerequisiteParseException,PrerequisiteException
	{
		if ( mstrPrerequisite == null || mstrPrerequisite.equals("") ){
			throw new PrerequisiteParseException( PrerequisiteEnv.getMessage( INPUT_EMPTY_ERR ) );
		}
		PrerequisiteData objCd = new PrerequisiteData( mstrPrerequisite, mstrUserID, mobjDataAccess );
		PrerequisiteNode objCn = new PrerequisiteNode( objCd );
		objCn.parse();
		objDecide = (DecidePrerequisite)objCn;
	}

	/**
	 * 前提条件条件式の妥当性チェックを行います。<BR>
	 * 以下のようなチェックを行い誤りがある場合は、PrerequisiteParseExceptionをスローします。<BR>
	 * <PRE>
	 *       ①　構文チェック　正しい構文でかかれているかチェック
	 *       ②　LOIDチェック　コンストラクタで、LOIDが指定されている場合、
	 *                         指定されたLOIDがLOテーブルに存在することをチェックします。
	 * </PRE>
	 * @exception PrerequisiteParseException 前提条件条件式の構文に誤りがある場合
	 * @exception PrerequisiteException 解析中に実行時例外が生じた場合
	 */
	public void check(boolean bInsMode)
		throws PrerequisiteParseException,PrerequisiteException
	{
		try
		{
			if ( mstrPrerequisite == null || mstrPrerequisite.equals("") ){
				throw new PrerequisiteParseException( PrerequisiteEnv.getMessage( INPUT_EMPTY_ERR ) );
			}
			PrerequisiteData objCd = new PrerequisiteData( mstrPrerequisite, mstrUserID, mobjDataAccess );
			PrerequisiteNode objCn = new PrerequisiteNode( objCd );
			objCn.parse();
			objDecide = (DecidePrerequisite)objCn;

			//LOIDチェック
			if ( mstrLoID != null ){
				Vector vecPrerequisite = objDecide.getLoIDList();
				if ( vecPrerequisite.size() == 0 ){
					throw new PrerequisiteParseException( PrerequisiteEnv.getMessage( LOID_LIST_NONE ) );
				}
				// 前提条件に指定されているLOIDがLOテーブルに存在するかチェックする。
				boolean boolCheck = checkLOID( vecPrerequisite );
				if ( !boolCheck ){
					DebugLog.write( this.getClass(), vecPrerequisite, DebugLog.ROW );
					throw new PrerequisiteParseException( PrerequisiteEnv.getMessage( LOID_CHECK_ERR ) );
				}
			}
		}
		catch( PrerequisiteParseException pe)
		{
			DebugLog.write( this.getClass(), pe, DebugLog.ROW );
			throw pe;
		}
		catch( PrerequisiteException ce)
		{
			DebugLog.write( this.getClass(), ce, DebugLog.ROW );
			throw ce;
		}
	}

	/**
	 * 前提条件を満たしているかを返します。
	 * @return boolean true: 満たしている false: 満たしていない
	 * @exception PrerequisiteException 前提条件条件式がパースされていないときなど
	 */
	public boolean isPrerequisited()
		throws PrerequisiteException
	{
		mobjDataAccess = new DataAccess();
		return objDecide.isPrerequisited();
	}

	/**
	 * 前提条件条件式で使用されているLOIDの一覧を取得します
	 * @return String[] LOID一覧
	 * @exception PrerequisiteParseException 前提条件条件式の構文に誤りがある場合
	 * @exception PrerequisiteException 解析中に実行時例外が生じた場合
	 */
	public String[] getLoIDList()
		throws PrerequisiteParseException,PrerequisiteException
	{
		if ( objDecide == null ){
			parse();
		}
		Vector vecTemp = objDecide.getLoIDList();
		if ( vecTemp.size() == 0 ){
			return new String[0];
		}
		else{
			String[] result = new String[vecTemp.size()];
			vecTemp.copyInto( result );
			return result;
		}
	}

	/**
	 * 前提条件に指定されたLOIDが使用されているかどうかを調べます。
	 * @param strLoID 比較対照LOID
	 * @return boolean true:使用されている false: 使用されていない
	 * @exception PrerequisiteParseException 前提条件条件式の構文に誤りがある場合
	 * @exception PrerequisiteException 解析中に実行時例外が生じた場合
	 */
	public boolean isUsedLoID( String strLoID )
		throws PrerequisiteParseException,PrerequisiteException
	{
		if ( objDecide == null ){
			parse();
		}
		Vector vecTemp = objDecide.getLoIDList();
		return vecTemp.contains( strLoID );
	}



	/**
	 * LOIDから親LOIDを取得するメソッドです。
	 * @exception PrerequisiteException 伝搬例外
	 */
	private String getParentID(String strLoID)
		throws PrerequisiteException
	{
		String strParentID = null;
		try {
			LoRelationClient objLoRelation = new LoRelationClient();
			// 検索条件に子LOIDを指定します
			objLoRelation.setWhereChildID( strLoID );
			// 検索処理
			if( !objLoRelation.select() ) {
				// 検索に失敗した場合
				throw new PrerequisiteException( objLoRelation.getMessage() );
			}

			// 検索結果を取得
			if( objLoRelation.next() ) {
				strParentID = objLoRelation.getParentID();
			}
		}
		catch(PrerequisiteException pe) {
			throw pe;
		}
		catch(Exception ex) {
			DebugLog.write( this.getClass(), ex, DebugLog.HIGHT );
			throw new PrerequisiteException(ex.getMessage());
		}
		return strParentID;
	}

	/**
	 * 指定されたLOIDがLOテーブルに存在するかチェックします。
	 * @param vecPrereList LOID
	 * @return Vector 子IDリスト
	 * @exception PrerequisiteException 伝搬例外
	 */
	private boolean checkLOID(Vector vecPrereList)
		throws PrerequisiteException
	{
		Vector vecChildList = new Vector();
		try {
			LoClient objLo = new LoClient();
			for(int i=0;i<vecPrereList.size();i++){
				// 検索条件にLOIDを指定します
				objLo.clear();
				objLo.setWhereLoID( (String)vecPrereList.get(i) );
				// 検索処理
				if( !objLo.select() ) {
					// 検索に失敗した場合
					throw new PrerequisiteException( objLo.getMessage() );
				}
				// 検索LOIDのレコードが存在しない場合
				if( !objLo.next() ){
					return false;
				}
			}
		}
		catch(PrerequisiteException pe) {
			throw pe;
		}
		catch(Exception ex) {
			DebugLog.write( this.getClass(), ex, DebugLog.HIGHT );
			throw new PrerequisiteException(ex.getMessage());
		}
		return true;
	}

}


