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

//
//	XMSBase データアクセスクラス
//			変更履歴
//				2004.01.08	新規作成	二條智文
//
package jp.co.ntt.lms.xmo.Base;

// Java API
import java.util.*;
import java.sql.*;

import org.apache.commons.lang.StringEscapeUtils;
// XMS API
import jp.co.ntt.lms.xmo.*;
import jp.co.ntt.lms.xmo.util.DebugLog;
import jp.co.ntt.lms.xmo.util.ChangeEncode;
import jp.co.ntt.lms.xmo.Message.Message;
import jp.co.ntt.lms.xmo.Base.Gui.*;

/**
 * Base(XMS_B)のデータアクセスクラスです。<BR>
 * XMSBaseが管理するXMOEntryテーブルへの登録、更新、削除、検索機能を実装します。
 * @author T.Nijou
 * @version 0.0.0.1 2004/01/08
 */
public class XMSBaseDataAccess
	implements XMSBaseMessage, XMSBaseTable
{

	/**
	 * コンストラクタ<BR>
	 * クラスの初期化を行います
	 */
	public XMSBaseDataAccess() {
	}

	/**
	 * XMOEntryテーブルへの登録処理を行います
	 * @exception XMOException 登録処理で例外が発生した場合
	 */
	synchronized public String insertEntry( Hashtable htbParam )
		throws XMOException
	{

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

			// インサート処理実行メソッドを呼びます
			insertEntryAction( htbParam, 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 "";
	}

	/**
	 * XMOEntryテーブルへの登録処理実行メソッドです。<BR>
	 * パラメータのチェックおよびトランザクションの管理は
	 * 上位メソッド内で行ってください。<BR>
	 * @param htbParam 登録情報
	 * @exception SQLException データベースエラーが発生した場合
	 */
	private void insertEntryAction( Hashtable htbParam, DataAccess objDataAccess )
		throws SQLException
	{
		// 登録処理用のデータをセットします
		Hashtable htbData = setData( htbParam );

		// 登録SQLを取得します
		String strSQL = objDataAccess.getInsertSQL( htbData );

		// 登録処理実行
		objDataAccess.execute( strSQL );
	}

	/**
	 * XMOEntryテーブルへの更新処理を行います
	 */
	synchronized public String updateEntry( Hashtable htbParam )
		throws XMOException
	{

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

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

			// 更新処理実行メソッドを実行します
			updateEntryAction( htbParam, 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 "";
	}

	/**
	 * XMOEntryテーブルへの更新処理実行メソッドです。<BR>
	 * パラメータのチェックおよびトランザクションの管理は
	 * 上位メソッド内で行ってください。<BR>
	 * @param htbParam 更新情報
	 * @exception SQLException データベースエラーが発生した場合
	 */
	private void updateEntryAction( Hashtable htbParam, DataAccess objDataAccess )
		throws SQLException
	{
		// 更新処理用のデータをセットします
		Hashtable htbData = setData( htbParam );

		String strSQL = objDataAccess.getUpdateSQL(htbData);

		// 条件文の取得
		String strCondition = (String)htbParam.get( "condition_key" );
		if( strCondition != null ) {
			strSQL += strCondition;
		}

		// 更新処理を実行
		objDataAccess.execute( strSQL );

	}

	/**
	 * XMOEntryテーブルへの削除処理を行います
	 * @param htbParam 削除情報
	 * @exception SQLException データベースエラーが発生した場合
	 */
	synchronized public String deleteEntry( Hashtable htbParam )
		throws XMOException
	{
		// データアクセスクラスをインスタンス化します
		DataAccess objDataAccess = new DataAccess(ENTRY_TABLE_NAME);
		try {

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

			// 削除処理実行メソッドを実行します
			deleteEntryAction( htbParam, 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 削除情報
	 * @exception SQLException データベースエラーが発生した場合
	 */
	private void deleteEntryAction( Hashtable htbParam, DataAccess objDataAccess )
		throws SQLException
	{
		// SQLの組み立て
		StringBuffer sbSQL = new StringBuffer();
		sbSQL.append( "DELETE FROM " + ENTRY_TABLE_NAME );

		// 条件文の取得
		String strCondition = (String)htbParam.get( "condition_key" );
		if( strCondition != null ) {
			sbSQL.append( strCondition );
		}

		// 削除処理を実行
		objDataAccess.execute( sbSQL.toString() );
	}

	/**
	 * XMOEntryテーブルへの検索処理を行います
	 * @param htbParam 検索情報
	 * @exception SQLException データベースエラーが発生した場合
	 */
	public Vector selectEntry( Hashtable htbParam )
		throws XMOException
	{
		Vector vecReturn = new Vector();
		// データアクセスクラスをインスタンス化します
		DataAccess objDataAccess = new DataAccess(ENTRY_TABLE_NAME);
		try {

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

			// 削除処理実行メソッドを実行します
			vecReturn = selectEntryAction( htbParam, 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 vecReturn;
	}

	/**
	 * 検索処理実行メソッドです。<BR>
	 * パラメータのチェックおよびトランザクションの管理は
	 * 上位メソッド内で行ってください。<BR>
	 * @param htbParam 削除情報
	 * @exception SQLException データベースエラーが発生した場合
	 */
	private Vector selectEntryAction( Hashtable htbParam, DataAccess objDataAccess )
		throws SQLException
	{
		// SQLの組み立て
		StringBuffer sbSQL = new StringBuffer();
		sbSQL.append( "SELECT * FROM " + ENTRY_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 strXmoID = ChangeEncode.setChar( rs.getString( XMO_ID ) );
			String strXmoName = ChangeEncode.setChar( rs.getString( XMO_NAME ) );
			String strXmoOutLine = ChangeEncode.setChar( rs.getString( XMO_OUT_LINE ) );
			String strXmoUri = ChangeEncode.setChar( rs.getString( XMO_URI ) );
			String strXmoOnFlg = ChangeEncode.setChar( rs.getString( XMO_ON_FLG ) );
			String strClassName = ChangeEncode.setChar( rs.getString( CLASS_NAME_F ) );
			String strTreeViewType = ChangeEncode.setChar( rs.getString( TREE_VIEW_TIPE ) );
			String strIniMenu = ChangeEncode.setChar( rs.getString( INI_MENU ) );
			String strPriority = ChangeEncode.setChar( rs.getString( PRIORITY ) );
			// AssignmentsDataクラスのインスタンス化
			XMOEntryData objData = new XMOEntryData();
			// 各フィールド値をセットします
			objData.setXmoID( strXmoID );
			objData.setXmoName( strXmoName );
			objData.setXmoOutLine( strXmoOutLine );
			objData.setXmoUri( strXmoUri );
			objData.setXmoOnFlg( strXmoOnFlg );
			objData.setClassName( strClassName );
			objData.setTreeViewType( strTreeViewType );
			objData.setIniMenu( strIniMenu );
			objData.setPriority( strPriority );
			// 返却ベクターにAssignmentsDataクラスを追加します
			vecReturn.add( objData );
		}

		return vecReturn;

	}

	/**
	 * 最大のXMOIDを取得
	 * @return String 最大AssignID
	 */
	private String getMaxAssignID( DataAccess objDataAccess )
		throws SQLException
	{

			String strMaxAssignID = "";
			String strSQL="";
		try{
			//XMS.iniファイルロードクラスのインスタンス
			Environment objEnv=new Environment();
			//SQLServerの場合
			if(objEnv.getDBType().equals( Environment.DB_SQLSERVER )){
				strSQL = "select MAX(CONVERT(INT," + XMO_ID + ")) + 1 as maxassignid from " + ENTRY_TABLE_NAME;
			//Oracleの場合
			}else if(objEnv.getDBType().equals( Environment.DB_ORACLE )){
				strSQL = "select MAX(TO_NUMBER("+ XMO_ID +")) + 1 as maxassignid from " + ENTRY_TABLE_NAME;
			//PostgreSQLの場合
			}else if(objEnv.getDBType().equals( Environment.DB_POSTGRE )){
				strSQL = "select MAX(TO_NUMBER("+ XMO_ID +",'999999999999999')) + 1 as maxassignid from " + ENTRY_TABLE_NAME;
			}

			Vector vecList = new Vector();
			try {
				ResultSet rs = objDataAccess.executeQuery(strSQL);

				while(rs.next()) {
					int intTemp = 0;
					intTemp = rs.getInt( "maxassignid" );
					strMaxAssignID = new Integer(intTemp).toString();
				}
			}
			catch( SQLException e ) {
				// ここでログをはく
				DebugLog.write( this.getClass(), e, DebugLog.HIGHT );
				throw e;
			}
		}
		catch(Exception ex)
		{

		}
		return strMaxAssignID;
	}

	/**
	 * 登録、更新処理時のデータを組み立てます
	 * @param htData
	 * @return Hashtable
	 */
	private Hashtable setData( Hashtable htbParam ) {

		Hashtable htbData = new Hashtable();
		putData( htbData, htbParam, XMO_ID );
		putData( htbData, htbParam, XMO_NAME );
		putData( htbData, htbParam, XMO_OUT_LINE );
		putData( htbData, htbParam, XMO_URI );
		putData( htbData, htbParam, XMO_ON_FLG );
		putData( htbData, htbParam, CLASS_NAME_F );
		putData( htbData, htbParam, TREE_VIEW_TIPE );
		putData( htbData, htbParam, INI_MENU );
		putData( htbData, htbParam, PRIORITY );
		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;
	}

	/**
	 * 指定された親ID配下のグループとユーザの情報を基本画面の表示データクラスに格納して返します。<BR>
	 * 配列はGroupAndPeopleのsort_noでソートされます。
	 * @param strParentID 親ID
	 * @param objDataAccess データアクセスクラス
	 * @return BaseDisplayData[] 画面情報
	 * @exception SQLException DB例外
	 */
	public BaseDisplayData[] getGroupDisplay(String strParentID, DataAccess objDataAccess)
		throws SQLException
	{
		StringBuffer sbSQL = new StringBuffer();
		sbSQL.append( "SELECT Groups.group_id AS group_id, " );
		sbSQL.append( "People.user_id AS user_id, Groups.group_name AS group_name, " );
		sbSQL.append( "People.user_name AS user_name, " );
		sbSQL.append( "Groups.custom_msg_dir AS group_msg_dir, " );
		sbSQL.append( "People.custom_msg_dir AS people_mas_dir, " );
		sbSQL.append( "Groups.group_type AS group_type, People.sex AS sex, People.user_type AS user_type " );
		sbSQL.append( "FROM GroupAndPeople LEFT OUTER JOIN " );
		sbSQL.append( "People ON " );
		sbSQL.append( "GroupAndPeople.childID = People.user_id LEFT OUTER JOIN " );
		sbSQL.append( "Groups ON GroupAndPeople.childID = Groups.group_id " );
		sbSQL.append( "WHERE (GroupAndPeople.parentID = '" + StringEscapeUtils.escapeSql(strParentID) + "') " );
		sbSQL.append( "ORDER BY GroupAndPeople.sort_no" );

		ResultSet rs = objDataAccess.executeQuery(new String(sbSQL));

		// 結果一時保管用Vector
		Vector vecResult = new Vector();
		while(rs.next()) {
			String strUserID = rs.getString( "user_id" );
			BaseDisplayData objDisplayData = new BaseDisplayData();

			if( strUserID != null ) {
				// ユーザ情報から表示データを作成する

				// ID設定
				objDisplayData.setID( ChangeEncode.setChar(strUserID) );
				// 名前設定
				objDisplayData.setTitle( ChangeEncode.setChar(rs.getString( "user_name" )) );
				// ID設定
				objDisplayData.setDescription( ChangeEncode.setChar(rs.getString( "people_mas_dir" )) );
				// ID設定
				objDisplayData.setType( ChangeEncode.setChar(rs.getString( "sex" ) + "^" + rs.getString( "user_type" )) );
			}
			else {
				// グループ情報から表示データを作成する
				String strGroupID = rs.getString( "group_id" );

				// ID設定
				objDisplayData.setID( ChangeEncode.setChar(strGroupID) );
				// 名前設定
				objDisplayData.setTitle( ChangeEncode.setChar(rs.getString( "group_name" )) );
				// ID設定
				objDisplayData.setDescription( ChangeEncode.setChar(rs.getString( "group_msg_dir" )) );
				// ID設定
				objDisplayData.setType( ChangeEncode.setChar(rs.getString( "group_type" )) );
			}

			vecResult.add( objDisplayData );
		}

		BaseDisplayData[] objDisplayList = new BaseDisplayData[vecResult.size()];

		vecResult.copyInto( objDisplayList );

		return objDisplayList;
	}

	/**
	 * 指定された親ID配下のLOの情報を基本画面の表示データクラスに格納して返します。<BR>
	 * 配列はLORelationのsort_noでソートされます。
	 * @param strParentID 親ID
	 * @param objDataAccess データアクセスクラス
	 * @return BaseDisplayData[] 画面情報
	 * @exception SQLException DB例外
	 */
	public BaseDisplayData[] getLoDisplay(String strParentID, DataAccess objDataAccess)
		throws SQLException
	{
		StringBuffer sbSQL = new StringBuffer();
		sbSQL.append( "SELECT LO.LOID AS LOID, LO.LOTitle AS LOTile, " );
		sbSQL.append( "LO.Prere AS Prere, " );
		sbSQL.append( "LO.LOType AS LOType, LO.Loexplanation AS Loexplanation " );
		sbSQL.append( "FROM LO INNER JOIN " );
		sbSQL.append( "LORelation ON LO.LOID = LORelation.childID " );
		sbSQL.append( "WHERE (LORelation.parentID = '" + StringEscapeUtils.escapeSql(strParentID) + "') " );
		sbSQL.append( "ORDER BY LORelation.sort_no" );

		ResultSet rs = objDataAccess.executeQuery(new String(sbSQL));

		// 結果一時保管用Vector
		Vector vecResult = new Vector();
		while(rs.next()) {
			BaseDisplayData objDisplayData = new BaseDisplayData();

			// ID設定
			objDisplayData.setID( ChangeEncode.setChar(rs.getString( "LOID" )) );
			// 名前設定
			objDisplayData.setTitle( ChangeEncode.setChar(rs.getString( "LOTile" )) );
			// ID設定
			objDisplayData.setDescription( ChangeEncode.setChar(rs.getString( "Loexplanation" )) );
			// ID設定
			objDisplayData.setType( ChangeEncode.setChar(rs.getString( "LOType" )) );
			// 前提条件設定
			objDisplayData.setPrere( ChangeEncode.setChar(rs.getString( "Prere" )) );

			vecResult.add( objDisplayData );
		}

		BaseDisplayData[] objDisplayList = new BaseDisplayData[vecResult.size()];

		vecResult.copyInto( objDisplayList );

		return objDisplayList;
	}

}

