/*
このファイルの中身は、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) ______________________________________.
*/
//
//
//	WBT教材 サーバクラス
//			変更履歴
//				2004.01.08	新規作成	二條智文

package jp.co.ntt.lms.lo.WBT;

import java.util.*;
import java.io.*;
import jp.co.ntt.lms.lo.*;
import jp.co.ntt.lms.xmo.util.*;
import jp.co.ntt.lms.xmo.Environment;

import jp.co.ntt.lms.xmo.People.PeopleClient;
import jp.co.ntt.lms.xmo.XMOException;
import jp.co.ntt.lms.xmo.Lo.LoClient;
import java.net.URLEncoder;
import java.io.UnsupportedEncodingException;

public class WbtLoEnv extends LoEnvironment implements WbtLoPropertyDef{

	private static final String mstrFileName = "/conf/lo/WBT.ini";

	/** プロパティファイルを保持します */
	private static Properties objProperty = null;

	// プロパティ定義
	/** 教材xmlファイルリストフォルダパス */
	public static final String MATERIAL_PATH = "material_path";
	/** 教材リストフォルダパス */
	public static final String MATERIAL_TEMP = "material_temp";
	/** 教材URL */
	public static final String MATERIAL_URL = "MatURL";
	/** 教材構造ファイル名 */
	public static final String MAT_FILE_NAME = "mat_file_name";
	/** Xcalatサーバ認証キー */
	public static final String XMS_KEY = "XMSKey";
	/** COMDパラメータ */
	public static final String COMD = "comd";
	/** COMDパラメータ(新規：NEW) */
	public static final String COMD_NEW = "NEW&FORCE=1";
	/** COMDパラメータ(中断：CONT) */
	public static final String COMD_CONT = "CONT";
	/** ログ取得URLパス */
	public static final String LOG_URL = "log_url";
	/** 登録メニューURLパス */
	public static final String INSERT_MENU_URL = "insert_menu_url";
	/** 更新メニューURLパス */
	public static final String UPDATE_MENU_URL = "update_menu_url";
	/** 削除メニューURLパス */
	public static final String DELETE_MENU_URL = "delete_menu_url";

	/** 進捗状況一覧（ユーザ）メニューURLパス */
	public static final String USER_PROGRESSSTATUS_URL = "user_progressstatus_url";
	/** 進捗状況一覧（グループ）メニューURLパス */
	public static final String GROUP_PROGRESSSTATUS_URL = "group_progressstatus_url";
	/** 演習回答状況（ユーザ）メニューURLパス */
	public static final String USER_REPLYSTATUS_URL = "user_replystatus_url";
	/** 演習回答状況（グループ）メニューURLパス */
	public static final String GROUP_REPLYSTATUS_URL = "group_replystatus_url";
	/** 演習結果分析メニューURLパス */
	public static final String RESULT_ANALYSIS_URL = "result_analysis_url";
	/** CSV出力メニューURLパス */
	public static final String CSV_OUTPUT_URL = "csv_output_url";

	public static final String XCAL_NAME = "xcal_name";
 	public static final int XCAL_SERVER_MAX = 99;

	// メニュー用文字列
	public static final String PROGRESSSTATUS  = "進捗状況一覧";
	public static final String REPLYSTATUS     = "演習回答状況";
	public static final String RESULT_ANALYSIS = "演習成績分析";
	public static final String CSV_OUTPUT      = "CSV出力";


	/**
	 * コンストラクタです
	 * @exception LOException
	 */
	public WbtLoEnv()
		throws LOException
	{
		super();
		// クラス単位の排他処理を行う。
		synchronized( this.getClass() ) {
			//	環境情報の初期化が行われていない時のみ
			//	環境ファイルを読み込む
			if( objProperty == null ) {
				objProperty = loadProperty(mstrFileName);
			}
		}
	}

	/**
	 * 教材xmlファイル格納フォルダを取得します
	 *
	 * @return String 教材パス
	 * @exception LOException LO固有の例外エラー
	 */
	public String getMaterialPath()
		throws LOException
	{
		try
		{
			String strMaterialPath = getProperty( MATERIAL_PATH, objProperty );
			Hashtable htbMacro = new Hashtable();
			htbMacro.put( mobjEnv.SYSTEM_DIR, mobjEnv.getSystemDir() );
			strMaterialPath = expand( strMaterialPath, htbMacro );
			return strMaterialPath;
		}
		catch(Exception e)
		{
			throw new LOException(e.getMessage());
		}
	}

	/**
	 * 教材格納フォルダを取得します
	 *
	 * @return String 教材パス
	 * @exception LOException LO固有の例外エラー
	 */
	public String getTempMaterialPath()
		throws LOException
	{
		try
		{
			String strTempPath = getProperty(MATERIAL_TEMP, objProperty);
			Hashtable htbMacro = new Hashtable();
			htbMacro.put(mobjEnv.SYSTEM_DIR, mobjEnv.getSystemDir());
			strTempPath = expand(strTempPath, htbMacro);
			return strTempPath;
		}
		catch(Exception e)
		{
			throw new LOException(e.getMessage());
		}
	}
	/**
	 * 評価ウィンドウオープンフラグを取得します
	 *
	 * @return String 評価ウィンドウオープンフラグ
	 */
	public String getEstimation()
		throws LOException
	{
		return getProperty(ESTIMATION, objProperty);
	}

	/**
	 * ログ取得URL + パラメータを取得します
	 * @param htParam マクロ展開時のパラメータ設定です
	 * @return String ログ取得URL + パラメータ
	 * @exception LOException LO固有の例外エラー
	 */
	public String getLogURL( Hashtable htParam )
		throws LOException
	{
		try
		{
			// ログ取得URL + パラメータを取得します
			String strLogURL = getProperty(LOG_URL, objProperty);
			// マクロにXcalatServerURLを追加します
			htParam.put(mobjEnv.XCAL_URL, mobjEnv.getXcalURL());
			// マクロ展開
			strLogURL = expand( strLogURL, htParam );
			// マクロ展開したURL + パラメータを返します
			return strLogURL;
		}
		catch(Exception e)
		{
			DebugLog.write( this.getClass(), e, DebugLog.HIGHT );
			throw new LOException(e.getMessage());
		}
	}

	/**
	 * WbtLo登録メニューURLを取得します
	 *
	 * @return String 登録メニューURL
	 * @exception LOException LO固有の例外エラー
	 */
	public String getInsertMenuURL()
		throws LOException
	{
		try
		{
			return getProperty(INSERT_MENU_URL, objProperty);
		}
		catch(Exception e)
		{
			DebugLog.write( this.getClass(), e, DebugLog.HIGHT );
			throw new LOException(e.getMessage());
		}
	}

	/**
	 * WbtLo更新メニューURLを取得します
	 *
	 * @return String 更新メニューURL
	 * @exception LOException LO固有の例外エラー
	 */
	public String getUpdateMenuURL()
		throws LOException
	{
		try
		{
			return getProperty(UPDATE_MENU_URL, objProperty);
		}
		catch(Exception e)
		{
			DebugLog.write( this.getClass(), e, DebugLog.HIGHT );
			throw new LOException(e.getMessage());
		}
	}

	/**
	 * WbtLo削除メニューURLを取得します
	 *
	 * @return String 削除メニューURL
	 * @exception LOException LO固有の例外エラー
	 */
	public String getDeleteMenuURL()
		throws LOException
	{
		try
		{
			return getProperty(DELETE_MENU_URL, objProperty);
		}
		catch(Exception e)
		{
			DebugLog.write( this.getClass(), e, DebugLog.HIGHT );
			throw new LOException(e.getMessage());
		}
	}

	/**
	 * 学習開始URLを取得します
	 * @param htParam マクロ展開時のパラメータ設定です
	 */
	public String getLearnURL( Hashtable htParam )
		throws LOException
	{
		try {
			// 学習開始パラメータを取得します
			String strXcalQUR = getXcalQUR();

			// マクロ展開
			strXcalQUR = expand( strXcalQUR, htParam );

			// マクロにXcalatServerURLを追加します
			//WBT.iniより取得したXcalatServerサーバを割当てたサーバ名称をマクロに追加する
			htParam.put( mobjEnv.XCAL_URL, "http://"+(String)htParam.get(XCAL_SERVER_NAME));
			// マクロ展開した学習開始パラメータを設定します
			htParam.put( XCAL_QUR, strXcalQUR );

			// 学習開始URLを取得します
			String strLearnURL = getProperty( XCAL_LEARN_URL );

			// マクロ展開します
			strLearnURL = expand( strLearnURL, htParam );

			//AICC [CORE] Student_nameへの対応

			String strUserName ="";		//ユーザ名
			String strUserID = (String)htParam.get(USER);
			String strStudentAddr1 = "";
			String strStudentAddr2 = "";
			PeopleClient objPeople = new  PeopleClient();
			objPeople.setWhereUserID( strUserID );

			// グループ検索処理
			if( !objPeople.select() ) {
				throw new XMOException( objPeople.getMessage() );
			}
			// ユーザ名称の取得
			if( objPeople.next() ) {
				strUserName = objPeople.getUserName();
				strStudentAddr1 = objPeople.getContactEmail();
				strStudentAddr2 = objPeople.getContactEmail2();
			}

			// 日本語名前をURLEncodeして学習開始URLに追加する
			strLearnURL = strLearnURL+ "&studentname="+URLEncoder.encode(strUserName, "UTF-8");

			String strLoID = (String)htParam.get(LOID);
			LoClient objLo = new LoClient();
			objLo.setWhereLoID(strLoID);
			String strTeacherAddr = "";
			if( !objLo.select() ) {
				// 検索がうまくいかなかった場合
				DebugLog.write(this.getClass(), "LO検索失敗", DebugLog.HIGHT);
			}
			else{
				while(objLo.next()){
					strTeacherAddr = objLo.getMentorEmail();
				}
			}
			if( !strTeacherAddr.equals("") && !strTeacherAddr.equals(null) ){
				// LOにメンターEmailアドレスが設定されていた場合
				String strStudentAddr  = "";
				if( !strStudentAddr1.equals("") && !strStudentAddr1.equals(null) ){
					strStudentAddr = strStudentAddr1;
				}
				else{
					if( !strStudentAddr2.equals("") && !strStudentAddr2.equals(null) ){
						strStudentAddr = strStudentAddr2;
					}
				}
				if( !strStudentAddr.equals("") && !strStudentAddr.equals(null) ){
					// メンターアドレス、学習者アドレスが共に設定されている場合、起動パラメータ追加
					strLearnURL = strLearnURL+ "&TEACHERADDR="+URLEncoder.encode(strTeacherAddr, "UTF-8");
					strLearnURL = strLearnURL+ "&STUDENTADDR="+URLEncoder.encode(strStudentAddr, "UTF-8");
				}
			}

			return strLearnURL;
		}
		catch( Exception e ) {
			DebugLog.write( this.getClass(), e, DebugLog.HIGHT );
			throw new LOException(e.getMessage());
		}

	}

	/**
	 * 教材URLを取得します
	 * @param String strMatFileName 教材構造ファイル
	 */
	public String getMaterialURL( String strMatFileName )
		throws LOException
	{
		try {
			Environment objEnv = new Environment();

			Hashtable htbParam = new Hashtable();
			// 教材構造ファイルを設定
			htbParam.put( MAT_FILE_NAME, strMatFileName );

			// XMSⅡサーバURLの設定
			htbParam.put( mobjEnv.SYSTEM_URL, mobjEnv.getSystemURL() );
			String strMaterialUrl = getProperty( MATERIAL_URL, objProperty );
			return expand( strMaterialUrl, htbParam );

		}
		catch( Exception e ) {
			DebugLog.write( this.getClass(), e, DebugLog.HIGHT );
			throw new LOException(e.getMessage());
		}
	}
	/**
	 * 個別ログ進捗状況一覧URLを取得します
	 *
	 * @return Vector 削除メニューURL
	 * @exception LOException LO固有の例外エラー
	 */
	public Vector getUserProgressUrl()
		throws LOException
	{
		try
		{
			Vector vecResult = new Vector();
			vecResult.add( PROGRESSSTATUS );
			vecResult.add( getProperty(USER_PROGRESSSTATUS_URL, objProperty) );
			return vecResult;
		}
		catch(Exception e)
		{
			DebugLog.write( this.getClass(), e, DebugLog.HIGHT );
			throw new LOException(e.getMessage());
		}
	}

	/**
	 * 個別ログ進捗状況一覧URLを取得します
	 *
	 * @return Vector 削除メニューURL
	 * @exception LOException LO固有の例外エラー
	 */
	public Vector getGroupProgressUrl()
		throws LOException
	{
		try
		{
			Vector vecResult = new Vector();
			vecResult.add( PROGRESSSTATUS );
			vecResult.add( getProperty(GROUP_PROGRESSSTATUS_URL, objProperty) );
			return vecResult;
		}
		catch(Exception e)
		{
			DebugLog.write( this.getClass(), e, DebugLog.HIGHT );
			throw new LOException(e.getMessage());
		}
	}

	/**
	 * 個別ログ演習回答状況URLを取得します
	 *
	 * @return Vector 削除メニューURL
	 * @exception LOException LO固有の例外エラー
	 */
	public Vector getUserReplystatusUrl()
		throws LOException
	{
		try
		{
			Vector vecResult = new Vector();
			vecResult.add( REPLYSTATUS );
			vecResult.add( getProperty(USER_REPLYSTATUS_URL, objProperty) );
			return vecResult;
		}
		catch(Exception e)
		{
			DebugLog.write( this.getClass(), e, DebugLog.HIGHT );
			throw new LOException(e.getMessage());
		}
	}

	/**
	 * 個別ログ演習回答状況URLを取得します
	 *
	 * @return Vector 削除メニューURL
	 * @exception LOException LO固有の例外エラー
	 */
	public Vector getGroupReplystatusUrl()
		throws LOException
	{
		try
		{
			Vector vecResult = new Vector();
			vecResult.add( REPLYSTATUS );
			vecResult.add( getProperty(GROUP_REPLYSTATUS_URL, objProperty) );
			return vecResult;
		}
		catch(Exception e)
		{
			DebugLog.write( this.getClass(), e, DebugLog.HIGHT );
			throw new LOException(e.getMessage());
		}
	}

	/**
	 * 個別ログ演習成績分析URLを取得します
	 *
	 * @return Vector 削除メニューURL
	 * @exception LOException LO固有の例外エラー
	 */
	public Vector getResultAnalysisUrl()
		throws LOException
	{
		try
		{
			Vector vecResult = new Vector();
			vecResult.add( RESULT_ANALYSIS );
			vecResult.add( getProperty(RESULT_ANALYSIS_URL, objProperty) );
			return vecResult;
		}
		catch(Exception e)
		{
			DebugLog.write( this.getClass(), e, DebugLog.HIGHT );
			throw new LOException(e.getMessage());
		}
	}

	/**
	 * 個別ログCSV出力URLを取得します
	 *
	 * @return Vector 削除メニューURL
	 * @exception LOException LO固有の例外エラー
	 */
	public Vector getCsvOutPutUrl()
		throws LOException
	{
		try
		{
			Vector vecResult = new Vector();
			vecResult.add( CSV_OUTPUT );
			vecResult.add( getProperty(CSV_OUTPUT_URL, objProperty) );
			return vecResult;
		}
		catch(Exception e)
		{
			DebugLog.write( this.getClass(), e, DebugLog.HIGHT );
			throw new LOException(e.getMessage());
		}
	}

	/**
	 * WBTの学習終了時のログ収集サーブレットのURLを取得します
	 * @return String ログ収集サーブレットURL
	 */
	public String getEndLearnServletURL()
		throws LOException
	{
		try {
			String strURL = getProperty( END_SERVLET_URL, objProperty );
			Hashtable htbMacro = new Hashtable();
			htbMacro.put( mobjEnv.SYSTEM_URL, mobjEnv.getSystemURL() );
			strURL = expand( strURL, htbMacro );
			return strURL;
		}
		catch( Exception e ) {
			DebugLog.write( this.getClass(), e, DebugLog.HIGHT );
			throw new LOException(e.getMessage());
		}
	}
	/**
	 * WBTのサーバ情報を取得します
	 * @return htbSerName  取得した情報をキャッシュで返す
	 */
	public Hashtable getXcaServerList()
		throws LOException
	{
		try {
			Hashtable htbSerName = new Hashtable();
			//WBT.iniファイルからサーバ情報取得
			for (int i=1; i<=XCAL_SERVER_MAX; i++){
				String strServerNO=XCAL_NAME+Integer.toString(i);
				String strServerName = getProperty(strServerNO, objProperty );
				if(strServerName==null){
					break;
				}
				//取得した情報をキャッシュに保持する	
				htbSerName.put( strServerNO, strServerName);
			}
			return htbSerName;
		}
		catch( Exception e ) {
			DebugLog.write( this.getClass(), e, DebugLog.HIGHT );
			throw new LOException(e.getMessage());
		}
	}
	/**
	 * キーを元にプロパティ値を取得します
	 * @param strPropertyName キー
	 * @param objProperty 親あるいは子供のプロパティ
	 */
	public String getProperty( String strPropertyName, Properties objProperty )
		throws LOException
	{
		try {
			if( objProperty == null ){
				return null;
			}

			String strValue;
			strValue = objProperty.getProperty( strPropertyName );
			if( strValue == null ) {

				if(!(strPropertyName.substring(0,9)).equals(XCAL_NAME)){

					String errMessage = "環境エラー:" + strPropertyName;
					LOException e = new LOException( errMessage );
					// ログ出力
					// DebugLogは相互参照になるため、標準出力に出力。
					e.printStackTrace();
					throw e;
				}
			}

			return strValue;
		}
		catch( Exception e ) {
			DebugLog.write( this.getClass(), e, DebugLog.HIGHT );
			throw new LOException(e.getMessage());
		}
	}

	/**
	 * 学習画面のウィンドウサイズ(縦)を取得します
	 *
	 * @return String 学習画面のウィンドウサイズ(縦)
	 */
	public String getWinHeight()
		throws LOException
	{
		return getProperty(WIN_HEIGHT, objProperty);
	}

	/**
	 * 学習画面のウィンドウサイズ(横)を取得します
	 *
	 * @return String 学習画面のウィンドウサイズ(横)
	 */
	public String getWinWidth()
		throws LOException
	{
		return getProperty(WIN_WIDTH, objProperty);
	}

}
