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

//
//	基本XMO 共通クライアント部品
//		変更履歴
//			2004.01.08	新規作成	二條智文
//			2004.09.30	M0006		A.Shimoma
//
package jp.co.ntt.lms.xmo;

import java.util.Hashtable;
import java.util.Vector;

import jp.co.ntt.lms.lo.Cafeteria.CafeteriaLoData;
import jp.co.ntt.lms.lo.Catalog.CatalogLoData;
/**
 * 基本XMOの共通クライアント部品です。<BR>
 * @author T.Nijou
 * @version 0.0.0.1 2004/01/08
 */
public class XMOBasicClient extends XMOClient
	implements XMOPropertyDef
{

	// メソッド名定義
	private static final String METHOD_INSERT  = "insert";
	private static final String METHOD_UPDATE  = "update";
	private static final String METHOD_DELETE  = "delete";
	private static final String METHOD_SELECT  = "select";

	// 検索時条件の"="をあらわします
	public static final String SEARCH_EQUALS = "=";

	// 検索時条件の"<"をあらわします
	public static final String SEARCH_SMALLER = "<";

	// 検索時条件の">"をあらわします
	public static final String SEARCH_LAGER = ">";

	// 検索時条件の"<="をあらわします
	public static final String SEARCH_SMALLER_EQUALS = "<=";

	// 検索時条件の">="をあらわします
	public static final String SEARCH_LAGER_EQUALS = ">=";

	// 検索時条件の"LIKE"をあらわします
	public static final String SEARCH_LIKE = " LIKE ";

	// 文字セット
	private static final String CHAR_SET = "Windows-31J";

// 20040930 M0006 ADD start NTTR(N)
	// 文字セット(ini_menu用)
	private static final String CHAR_SET_INIMENU = "UTF-8";
// 20040930 M0006 ADD end

	// 検索条件文を格納するキーです
	private static final String CONDITION_KEY = "condition_key";

	// ORDER BY文を格納するキーです
	private static final String ORDER_BY = "order_by";

	// 文字コード設定
	// EncodingFilter のエンコーディング指定は Windows-31J を指定すること。
	private String mstrEncode = "Windows-31J";

	/**
	 * メッセージデータを保持します
	 */
	protected MessageData mobjMessage;

	/**
	 * パラメータを保持します
	 */
	protected Hashtable htParams = new Hashtable();

	/**
	 * 検索結果を保持します
	 */
	protected Vector vecResults = null;

	/**
	 * 検索結果インデックスを保持します
	 */
	protected int intResultIndex = 0;

	/**
	 * コンストラクタ<BR>
	 * @param RMIリモートオブジェクト名
	 */
	public XMOBasicClient( String strClassName ) throws Exception {
		super( strClassName );
	}

	/**
	 * XMOの基本メソッド<BR>
	 * メニューのリストを返します
	 * @return Vector メニューリスト
	 * @exception Exception RMI接続に失敗した場合
	 */
	public Vector getMenuList()
		throws Exception
	{
		return super.getMenuList(htParams);
	}

	/**
	 * XMOの基本メソッド<BR>
	 * メソッドのリストを返します
	 * @return Vector メニューリスト
	 * @exception Exception RMI接続に失敗した場合
	 */
	public Vector getMethodList()
		throws Exception
	{
		return super.getMethodList();
	}

	/**
	 * XMOの基本メソッド<BR>
	 * デフォルトのメニューを返します
	 * @return MenuData デフォルトメニューURL
	 * @exception Exception RMI接続に失敗した場合
	 */
	public MenuData getDefaultMenu()
		throws Exception
	{
		return super.getDefaultMenu();
	}

	/**
	 * XMOの基本メソッド<BR>
	 * リモートメソッド起動メソッドです。
	 * @param strMethodName 起動するメソッド名
	 * @param objData パラメータ
	 * @exception Exception RMI接続に失敗した場合
	 */
	public Object execute( String strMethodName, Hashtable objData )
		throws Exception
	{
		// 結果インデックスを初期化します
		intResultIndex = 0;
		return super.execute( strMethodName, objData );
	}

	/**
	 * データ登録を実行します。<br>
	 * あらかじめ、setで始まるメソッドで登録するデータのプロパティを指定した上で呼びます。
	 * ＲＭＩ接続して、指定したプロパティでデータの登録を実行し、登録が成功するとtrueを戻します。
	 * ＲＭＩサーバがなにかしらの理由で登録できなかった場合、falseを戻します。
	 * 登録できなかった理由は、getMessageメソッドを呼んで確認します。
	 *
	 * @return 正常時はtrue、エラー時はfalseを戻します。
	 * @throws Exception RMI接続に失敗した場合など処理中に例外が発生した場合。
	 * @see #getMessage()
	 */
	public boolean insert()
		throws Exception
	{
		return execute_m( METHOD_INSERT );
	}

	/**
	 * 更新処理
	 * @return boolean 正常時はtrue　エラー時はfalse
	 * @exception Exception RMI接続に失敗した場合
	 */
	public boolean update()
		throws Exception
	{
		return execute_m( METHOD_UPDATE );
	}

	/**
	 * データ削除を実行します。<br>
	 * あらかじめ、setDeleteで始まるメソッドで削除対象を指定した上で呼びます。
	 * ＲＭＩ接続して、指定した対象データの削除を実行し、削除が成功するとtrueを戻します。
	 * ＲＭＩサーバがなにかしらの理由で削除できなかった場合、falseを戻します。
	 * 削除できなかった理由は、getMessageメソッドを呼んで確認します。
	 *
	 * @return 正常時はtrue、エラー時はfalseを戻します。
	 * @throws Exception RMI接続に失敗した場合など処理中に例外が発生した場合。
	 * @see #getMessage()
	 */
	public boolean delete()
		throws Exception
	{
		return execute_m( METHOD_DELETE );
	}

	/**
	 * 検索処理
	 * @return boolean 正常時はtrue　エラー時はfalse
	 * @exception Exception RMI接続に失敗した場合
	 */
	public boolean select()
		throws Exception
	{
		return select_m( METHOD_SELECT );
	}

	// 内部関数検索処理
	protected boolean select_m( String strMethodName )
		throws Exception
	{
		// 結果インデックスを初期化します
		intResultIndex = 0;
		Vector vecResultTemp = (Vector)execute( strMethodName, htParams );
		MessageData objMessage = (MessageData)vecResultTemp.get(0);
		mobjMessage = objMessage;

		if( isErr( objMessage ) || isWarning( objMessage ) ) {
			return false;
		}

		vecResults = vecResultTemp;
		return true;
	}

	// 内部関数
	protected boolean execute_m( String strMethodName )
		throws Exception
	{
		Vector vecResultTemp = (Vector)execute( strMethodName, htParams );


		// 結果インデックスを初期化します
		intResultIndex = 0;
		MessageData objMessage = (MessageData)vecResultTemp.get(0);
		mobjMessage = objMessage;
		if( isErr( objMessage ) || isWarning( objMessage ) ) {
			return false;
		}

		vecResults = vecResultTemp;
		return true;
	}

	/**
	 * エンコードを設定します。<br>
	 * このクラスまたはサブクラスのプロパティを設定をするメソッドでは、
	 * 渡された設定値（文字列）を&quot;8859_1&quot;から&quot;Shift_JIS&quot;に変換しています。
	 * 変換元のエンコードを&quot;8859_1&quot;以外のエンコードにしたい場合は、予めこのメソッドで指定します。
	 * このメソッドで&quot;Shift_JIS&quot;を指定すると、
	 * &quot;Shift_JIS&quot;から&quot;Shift_JIS&quot;への変換となるので、
	 * 原則として変換しない状態と同じになります。
	 * @param String エンコード文字列（&quot;Shift_JIS&quot;、&quot;EUC-JP&quot;など）
	 */
	public void setEncode(String strEncode)
	{
		mstrEncode = strEncode;
	}
	/**
	 * getMenuListのパラメータにIDを設定します
	 * @param strID 設定するID
	 */
	public void setParamID( String strID ) {
		putData( PARAM_ID, strID );
	}
	/**
	 * メッセージを返します。<br>
	 * データの検索・追加・更新・削除など実施後、実施した処理についてメッセージが存在する場合、
	 * そのメッセージを戻します。通常はエラー発生時にはエラーメッセージを保持しています。
	 * @return 実施した処理についてのメッセージを戻します。
	 * @see #select()
	 * @see #insert()
	 * @see #update()
	 * @see #delete()
	 */
	public String getMessage() {
		if( mobjMessage == null ) {
			return "";
		}
		return mobjMessage.getMessage();
	}
	/**
	 * メッセージIDを返します。
	 * メッセージデータがない場合はnullを返します。
	 * @return String メッセージID
	 */
	public String getMessageID() {
		if( mobjMessage == null ) {
			return null;
		}
		return mobjMessage.getMessageID();
	}

	/**
	 * URLを返します
	 * @return String URL
	 */
	public String getURL() {
		if( mobjMessage == null ) {
			return "";
		}
		return setChar( mobjMessage.getURL() );
	}

	/**
	 * 検索結果数を返します
	 */
	public int getResultCount() {
		if( vecResults == null ) {
			return 0;
		}
		return vecResults.size() - 1;
	}

	/**
	 * 検索結果配列のインデックスとキーを指定して値を取得します
	 * @param strKey 検索するキー
	 * @param intIndex インデックス
	 * @return Object 検索結果
	 */
	protected Object getResult( int intIndex ) {
		if( vecResults == null ) {
			return null;
		}
		try {
			Object objResult = vecResults.get(intIndex);
			return objResult;
		}
		catch( ArrayIndexOutOfBoundsException ae ) {
			return null;
		}
	}

	/**
	 * 検索結果配列の現在のインデックスでキーを指定して値を取得します
	 * @return String 検索結果
	 */
	protected Object getResult() {
		return getResult( intResultIndex );
	}

	/**
	 * パラメータの設定を行います
	 * @param strKey キー
	 * @param strValue 値
	 */
	protected void putData( String strKey, String strValue ) {
		if( strValue == null ) {
			strValue = "";
		}
		htParams.put( strKey, setChar( strValue ) );
	}

	/**
	 * 検索結果が存在するかどうかを返します。<BR>
	 * @return boolean <PRE>
	 *                 true: 存在する
	 *                 false: 存在しない
	 *                 </PRE>
	 */
	public boolean next() {
		if( vecResults == null ) {
			return false;
		}
		intResultIndex++;
		if( vecResults.size() < intResultIndex + 1 ) {
			return false;
		}
		else {
			return true;
		}
	}

	/**
	 * パラメータの設定をクリアします
	 */
	public void clear() {
		htParams = new Hashtable();
	}

	/**
	 * 文字エンコードの変更をします
	 */
	protected String setChar( String s ) {
		String res="";
		if( s==null || s.equals( "" ) ) {
			return res;
		}
		else {
			try {
				res = new String( s.getBytes(mstrEncode), CHAR_SET );
			}
			catch( Exception e ) {
				e.printStackTrace();
			}
		}
		return res.trim();
	}

	/**
	 * 検索条件を設定します
	 * @param strCondition 条件文
	 */
	public void setCondition( String strCondition ) {
		String strTemp = (String)htParams.get( CONDITION_KEY );
		if( strTemp != null ) {
			strCondition = strTemp + " AND " + setChar( strCondition );
			htParams.put( CONDITION_KEY, strCondition );
		}
		else {
			htParams.put( CONDITION_KEY, " WHERE " + setChar( strCondition ) );
		}
	}

// 20040930 M0006 ADD start NTTR(N)
	/**
	 * 検索条件を設定します
	 *
	 * @param strCondition 条件文
	 */
	public void setIniMenutCondition( String strCondition ) {

		String strTemp = ( String ) htParams.get( CONDITION_KEY );
		if ( strTemp != null ) {
			strCondition = strTemp + " AND " + setCharIniMenu( strCondition );
			htParams.put( CONDITION_KEY, strCondition );
		} else {
			htParams.put( CONDITION_KEY, " WHERE " + setCharIniMenu( strCondition ) );
		}
	}

	/**
	 * 文字エンコードの変更をします
	 *
	 * @param strCondition 検索条件
	 * @return				検索条件
	 */
	protected String setCharIniMenu( String strCondition ) {

		String res = "";
		if ( strCondition == null || strCondition.equals( "" ) == false ) {
			try {
				res = new String( strCondition.getBytes( mstrEncode ), CHAR_SET_INIMENU );
			} catch ( Exception e ) {
				e.printStackTrace();
			}
		} else {
			return res;
		}
		return res.trim();
	}
// 20040930 M0006 ADD end

	/**
	 * ORDER BY条件を設定します
	 * @param strOderBy 順序文
	 */
	public void setOrderBy( String strOrderBy ) {
		String strTemp = (String)htParams.get( ORDER_BY );
		if( strTemp != null ) {
			strOrderBy = strTemp + " AND " + setChar( strOrderBy );
			htParams.put( ORDER_BY, strOrderBy );
		}
		else {
			htParams.put( ORDER_BY, " ORDER BY " + setChar( strOrderBy ) );
		}
	}

	/**
	 * エラーかどうかを判定して戻します。<br>
	 * データの検索・追加・更新・削除など実施後、実施した処理についてメッセージオブジェクトを保持しており、
	 * その内容に基づきエラーが発生したか否か判定します。
	 * @return エラーまたは警告の場合、trueを戻します。それ以外の場合falseを戻します。
	 * @see #select()
	 * @see #insert()
	 * @see #update()
	 * @see #delete()
	 */
	public boolean isErr() {
		return isErr( mobjMessage );
	}

	/**
	 * メッセージオブジェクトからエラーかどうかを判定して返します
	 * @param objMessage メッセージオブジェクト。
	 * @return エラーまたは警告の場合、trueを戻します。それ以外の場合falseを戻します。
	 */
	protected boolean isErr( MessageData objMessage ) {
		if( objMessage == null ) {
			return false;
		}
		String strMessageType = objMessage.getMessageType();
		if( strMessageType.equals( MessageData.ERR_TYPE ) ) {
			return true;
		}
		else {
			return false;
		}
	}

	/**
	 * メッセージオブジェクトが警告かどうかの判定をします。
	 * @return 警告の場合、trueを戻します。それ以外の場合falseを戻します。
	 */
	protected boolean isWarning() {
		return isWarning( mobjMessage );
	}


	/**
	 * メッセージオブジェクトが警告かどうかの判定をします。
	 * @param objMessage
	 * @return 警告の場合、trueを戻します。それ以外の場合falseを戻します。
	 */
	protected boolean isWarning( MessageData objMessage ) {
		if( objMessage == null ) {
			return false;
		}
		String strMessageType = objMessage.getMessageType();
		if( strMessageType.equals( MessageData.WAR_TYPE ) ) {
			return true;
		}
		else {
			return false;
		}
	}

	/**
	 * メッセージデータオブジェクトを取得します
	 */
	public MessageData getMessageData() {
		return mobjMessage;
	}

	/**
	 * DBコネクションのインデックス情報を設定します
	 * @param intIndex インデックス
	 */
	public void setConnectionIndex( int intIndex ) {
		Integer objIndex = new Integer( intIndex );
		htParams.put( "connectionindex", objIndex );
	}

	/**
	 * 任意のキーで値を設定します
	 * @param strKey キー
	 * @param strValue 値
	 */
	public void setValue( String strKey, String strValue ) {
		putData( strKey, strValue );
	}

	/**
	 * ログインIDを設定します
	 * @param strID 設定するID
	 */
	public void setLoginID( String strLoginID ) {
		htParams.put( LOGIN_USERID, strLoginID );
	}
	/**
	 * CatalogLoListキーで値を設定します
	 * @param strKey キー
	 * @param objValue 値
	 */
	public void setValueObj( String strKey, CatalogLoData objValue ) {

		htParams.put( strKey, objValue  );
	}

	/**
	 * CafeteriaLoListキーで値を設定します
	 * @param strKey キー
	 * @param objValue 値
	 */
	public void setValueObj( String strKey, CafeteriaLoData objValue ) {

		htParams.put( strKey, objValue  );
	}
}

