/*
このファイルの中身は、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) ______________________________________.
*/
//
//
//	XMS共通 設定ファイルロードクラス
//			変更履歴
//				2004.01.08	新規作成		二條智文
//
package jp.co.ntt.lms.xmo;

import java.util.*;
import java.io.*;

/**
 * XMS共通 設定ファイルロードクラスです。<BR>
 * @author T.Nijou
 * @version 0.0.0.1 2004/01/08
 */
public class Environment {

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

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

	// プロパティ定義
	/** サーバ名 */
	public static final String SERVER_NAME = "server_name";
	/** XMSBaseのクラス名 */
	public static final String BASE_NAME = "base_name";
	/** LOサーバ名 */
	public static final String LO_SERVER_NAME = "lo_server_name";
	/** DBコネクションプール数 */
	public static final String POOL_COUNT = "pool_count";
	/** DBHost名称 */
	public static final String DB_HOST = "db_host";
	/** DBPort番号 */
	public static final String DB_PORT = "db_port";
	/** データベース名 */
	public static final String DB_NAME = "db_name";
	/** データベースユーザ名 */
	public static final String DB_USER = "db_user";
	/** データベースパスワード */
	public static final String DB_PASS = "db_pass";
	/** JDBCドライバー名称 */
	public static final String DB_DRIVER = "db_driver";
	/** 接続文字列 */
	public static final String DB_CON_STR = "db_con_str";
	/** リトライ回数 */
	public static final String RETRY_COUNT = "retry_count";
	/** 待ち時間 */
	public static final String WAIT_TIME = "wait_time";
	/** XMOレジストリポート */
	public static final String XMO_REGISTRY_PORT = "xmo_registry_port";
	/** LOレジストリポート */
	public static final String LO_REGISTRY_PORT = "lo_registry_port";

	/** WEBアプリケーションサーバURL */
	public static final String SYSTEM_URL = "system_url";
	/** XMSⅡインストールディレクトリ */
	public static final String SYSTEM_DIR = "system_dir";

	/** WBTServerURL */
	public static final String XCAL_URL = "xcal_url";

	/** ログ出力ディレクトリ名 */
	public static final String LOG_PATH = "log_path";
	/** ログ出力レベル */
	public static final String LOG_LEVEL = "log_level";

	/** セッションディレクトリ */
	public static final String SESSION_DIR = "session_dir";

	/** LOタイプ */
	public static final String LO_TYPE = "type";

	/** ADサーバ名称 */
	public static final String AD_HOST = "ad_host";
	/** ADポート番号 */
	public static final String AD_PORT = "ad_port";
	/** ADユーザ名 */
	public static final String AD_USER = "ad_user";
	/** ADパスワード */
	public static final String AD_PASS = "ad_pass";
	/** ADルートDN */
	public static final String AD_ROOT = "ad_root";
	/** ADの存在ファイル確認ファイル名 */
	public static final String AD_FILE = "ad_file";

	/** CSVファイル出力ディレクトリ */
	public static final String CSV_PATH = "csv_path";

	/** CSVファイル出力ディレクトリ(仮想パス) */
	public static final String CSV_PATH_2 = "csv_path_2";

	/** DB切替え種別(MS SQLServer or Oracle) */
	public static final String DB_SERVER = "db_server";

	/** DB切替え種別番号(MS SQLServer) */
	public static final String DB_SQLSERVER = "0";
	/** DB切替え種別番号(Oracle) */
	public static final String DB_ORACLE = "1";

	/** DB切替え種別番号(PostgreSQL) */
	public static final String DB_POSTGRE = "2";

	/** LO Prefix*/
	public static final String LO_PREFIX = "lo_prefix";
	/** PE(ユーザ） Prefix */
	public static final String PE_PREFIX = "pe_prefix";
	/** GR(グループ）Prefix */
	public static final String GR_PREFIX = "gr_prefix";

	/** CSV出力ファイルエンコード */
	public static final String CSV_ENCODE = "csv_encode";

	/**
	 * コンストラクタです
	 * @exception XMOException
	 */
	public Environment()
		throws Exception
	{
		init();
	}

	/**
	 * 環境ファイルを読み込みます
	 */
	public void init() throws Exception {
		// クラス単位の排他処理を行う。
		synchronized( this.getClass() ) {
			//	環境情報の初期化が行われていない時のみ
			//	環境ファイルを読み込む
			if( mobjProperty == null ) {
				mobjProperty = loadProperty(mstrFileName);
			}
		}
	}

	/**
	 * キーを元にプロパティ値を取得します
	 * @param strPropertyName
	 */
	public String getProperty( String strPropertyName )
		throws Exception
	{

		if( mobjProperty == null ){
			return null;
		}

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

		return strValue;

	}

	/**
	 * キーを元にプロパティ値を取得します
	 * @param strPropertyName プロパティ値
	 * @param objProperty プロパティオブジェクト
	 * @return String 値
	 */
	public String getProperty( String strPropertyName, Properties objProperty )
		throws Exception
	{

		if( objProperty == null ){
			return null;
		}

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

		return strValue;

	}

	private Properties loadProperty( String strFileName ) throws Exception {

		Properties objProperty = null;

		//	環境ファイルオブジェクトの取得
		InputStream objFile = this.getClass().getResourceAsStream( strFileName );
		if( objFile != null ) {
			objProperty = new Properties();
			try{
				objProperty.load(objFile);
			}
			catch( IOException Ex ){
				throw Ex;
			}
			finally {
				//	環境ファイルをクローズする
				try {objFile.close();} catch( Exception e ) {}
			}
		}
		else{
			// ログ出力
			// DebugLogは相互参照になるため、標準出力に出力。
			Exception e = new Exception("ファイルアクセスエラー：" + strFileName);
			throw e;
		}

		return objProperty;
	}

	/**
	 * XMOサーバ名称の取得を行います
	 * @return String サーバ名
	 */
	public String getServerName()
		throws Exception
	{
		return getProperty( SERVER_NAME );
	}

	/**
	 * LOサーバ名称の取得を行います
	 * @return String サーバ名
	 */
	public String getLoServerName()
		throws Exception
	{
		return getProperty( LO_SERVER_NAME );
	}

	/**
	 * XMSBaseのクラス名を取得します
	 */
	public String getBaseName()
		throws Exception
	{
		return getProperty( BASE_NAME );
	}

	/**
	 * DBコネクションプール数を取得します
	 */
	public String getPoolCount()
		throws Exception
	{
		return getProperty( POOL_COUNT );
	}

	/**
	 * DBHost名称を取得します
	 */
	public String getDBHost()
		throws Exception
	{
		return getProperty( DB_HOST );
	}

	/**
	 * DBPort番号を取得します
	 */
	public String getDBPort()
		throws Exception
	{
		return getProperty( DB_PORT );
	}

	/**
	 * データベース名を取得します
	 */
	public String getDBName()
		throws Exception
	{
		return getProperty( DB_NAME );
	}

	/**
	 * データベースユーザ名を取得します
	 */
	public String getDBUser()
		throws Exception
	{
		return getProperty( DB_USER );
	}

	/**
	 * データベースパスワードを取得します
	 */
	public String getDBPass()
		throws Exception
	{
		return getProperty( DB_PASS );
	}

	/**
	 * JDBCドライバー名称を取得します
	 */
	public String getDBDriver()
		throws Exception
	{
		return getProperty( DB_DRIVER );
	}

	/**
	 * コネクション取得リトライ回数を取得します
	 */
	public String getRetryCount()
		throws Exception
	{
		return getProperty( RETRY_COUNT );
	}

	/**
	 * コネクション取得待ち時間を取得します
	 */
	public String getWaitTime()
		throws Exception
	{
		return getProperty( WAIT_TIME );
	}

	/**
	 * XMO用のレジストリポート番号を取得します
	 */
	public String getXmoRegistryPort()
		throws Exception
	{
		return getProperty( XMO_REGISTRY_PORT );
	}

	/**
	 * LO用のレジストリポート番号を取得します
	 */
	public String getLoRegistryPort()
		throws Exception
	{
		return getProperty( LO_REGISTRY_PORT );
	}

	/**
	 * ログ出力ディレクトリを取得します
	 */
	public String getLogPath()
		throws Exception
	{
		String strLogPath = getProperty( LOG_PATH );
		Hashtable htbMacro = new Hashtable();
		htbMacro.put( SYSTEM_DIR, getSystemDir() );
		strLogPath = expand( strLogPath, htbMacro );
		return strLogPath;
	}

	/**
	 * CSV出力ディレクトリを取得します
	 */
	public String getCSVPath()
		throws Exception
	{
		String strCSVPath = getProperty( CSV_PATH );
		Hashtable htbMacro_csv = new Hashtable();
		htbMacro_csv.put( SYSTEM_DIR, getSystemDir() );
		strCSVPath = expand( strCSVPath, htbMacro_csv );
		return strCSVPath;
	}

	/**
	 * ログ出力レベルを取得します
	 */
	public String getLogLevel()
		throws Exception
	{
		return getProperty( LOG_LEVEL );
	}

	/**
	 * XMSⅡインストールディレクトリを取得します
	 */
	public String getSystemDir()
		throws Exception
	{
		return getProperty( SYSTEM_DIR );
	}

	/**
	 * WBTServerURLを取得します
	 */
	public String getXcalURL()
		throws Exception
	{
		return getProperty( XCAL_URL );
	}


	/**
	 * XMSⅡアプリケーションサーバURLを取得します
	 */
	public String getSystemURL()
		throws Exception
	{
		return getProperty( SYSTEM_URL );
	}

	/**
	 * ADサーバ名称を取得します
	 */
	public String getADHost()
		throws Exception
	{
		return getProperty( AD_HOST );
	}

	/**
	 * ADポート番号を取得します
	 */
	public String getADPort()
		throws Exception
	{
		return getProperty( AD_PORT );
	}

	/**
	 * ADユーザ名を取得します
	 */
	public String getADUser()
		throws Exception
	{
		return getProperty( AD_USER );
	}

	/**
	 * ADパスワードを取得します
	 */
	public String getADPass()
		throws Exception
	{
		return getProperty( AD_PASS );
	}

	/**
	 * ADルートDNを取得します
	 */
	public String getADRoot()
		throws Exception
	{
		return getProperty( AD_ROOT );
	}

	/**
	 * ADの存在ファイル確認ファイル名を取得します
	 */
	public String getADFile()
		throws Exception
	{
		return getProperty( AD_FILE );
	}

	/**
	 * CSVファイル出力ディレクトリを取得します
	 */
	public String getOutputFile()
		throws Exception
	{
		return getProperty( CSV_PATH );
	}

	/**
	 * CSVファイル出力ディレクトリ(仮想パス)を取得します
	 */
	public String getOutputDir()
		throws Exception
	{
		String strCSVPath = getProperty( CSV_PATH_2 );
		Hashtable htbMacro_csv = new Hashtable();
		htbMacro_csv.put( SYSTEM_URL, getSystemURL() );
		strCSVPath = expand( strCSVPath, htbMacro_csv );
		return strCSVPath;
	}

	/**
	 * セッション情報格納用のディレクトリを取得します
	 */
	public String getSessionDir()
		throws Exception
	{
		String strSessionDir = getProperty( SESSION_DIR );
		// マクロ展開用ハッシュ
		Hashtable htbMacro = new Hashtable();
		htbMacro.put( SYSTEM_DIR, getSystemDir() );
		strSessionDir = expand( strSessionDir, htbMacro );
		return strSessionDir;
	}

	/**
	 * データベース接続文字列を取得します<BR>
	 * 設定ファイル上の'$'で囲まれた文字列を適切な値に
	 * 変換して返します
	 * @return String 接続文字列
	 */
	public String getDBConStr()
		throws Exception
	{
		// DBホスト名を取得します
		String strDBHost = getDBHost();
		// DBポート名を取得します
		String strDBPort = getDBPort();
		// DB名を取得します
		String strDBName = getDBName();

		// マクロ展開用にHastableにキーと値を入れます。
		Hashtable htMacro = new Hashtable();
		htMacro.put( DB_HOST, strDBHost );
		htMacro.put( DB_PORT, strDBPort );
		htMacro.put( DB_NAME, strDBName );

		// 接続文字列を取得します
		String strConStr = getProperty( DB_CON_STR );
		// マクロ展開
		strConStr = expand( strConStr, htMacro );
		return strConStr;
	}

	/**
	 * LO種別ごとのLOクラス名を返します
	 */
	public Vector getLoClassName()
		throws Exception
	{
		if( mobjProperty == null ){
			return null;
		}

		Enumeration e = mobjProperty.propertyNames();
		Vector vecClassList = new Vector();

		while( e.hasMoreElements() ) {
			String strType = (String)e.nextElement();
			int intTypeIndex = strType.indexOf( LO_TYPE );
			if( intTypeIndex >= 0 ) {
				String[] strTemp = new String[2];
				// 配列の一番目に種別を入れます
				strTemp[0] = strType.substring( intTypeIndex + LO_TYPE.length(), strType.length() );
				// 配列の２番目にクラス名を入れます
				strTemp[1] = getProperty( strType );

				vecClassList.add( strTemp );
			}
		}

		return vecClassList;
	}

	/**
	 * 文字列をマクロ展開します<BR>
	 * '$'で囲まれた文字列を取得し、引数で渡されたHashtableから
	 * 取得した文字列をキーにして、値を取得し、入れ替えて返します。
	 * @param strBase 変換前
	 * @param htbTable マクロ情報
	 * @return String 変換後文字列
	 */
	public static String expand(String strBase , Hashtable htbTable ) {
		// 返還前文字列をchar配列に変換します
		char[] chrBase = strBase.toCharArray();

		// 変換後の文字列を格納します
		StringBuffer sbBase = new StringBuffer();
		// '$'で囲まれてた文字列を格納します
		StringBuffer sbMacro = new StringBuffer();
		// マクロ文字列読み取り中か、普通の文字列読み取り中かを判断する
		boolean blMacro = false;
		// charの配列文ループします
		for( int i = 0; i < chrBase.length; i++ ) {
			// '$'の部分はマクロ文字列として格納します
			if( chrBase[i] == '$' ) {
				if( blMacro ) {
					blMacro = false;
					// マクロ文字列をキーにして、値を入れる
					sbBase.append( (String)htbTable.get( sbMacro.toString() ) );
					// マクロ文字列を初期化します
					sbMacro = new StringBuffer();
				}
				else {
					blMacro = true;
				}
				continue;
			}

			// マクロ読み取り中の場合
			if( blMacro ) {
				sbMacro.append( chrBase[i] );
			}
			// 普通の文字列読み取り中
			else {
				sbBase.append( chrBase[i] );
			}
		}
		return sbBase.toString();
	}

	/**
	 * DB種別の取得を行います
	 * @return String DB種別( MS SQLServer：0、Oracle：1 )
	 */
	public String getDBType()
		throws Exception
	{
		return getProperty( DB_SERVER );
	}
	/**
	 * LO Prefixを取得します
	 */
	public String getLoPrefix()
		throws Exception
	{
		return getPrefixProperty( LO_PREFIX );
	}
	/**
	 * PE(ユーザ） Prefixを取得します
	 */
	public String getPePrefix()
		throws Exception
	{
		return getPrefixProperty( PE_PREFIX );
	}
	/**
	 * GR(グルプ) Prefixを取得します
	 */
	public String getGrPrefix()
		throws Exception
	{
		return getPrefixProperty( GR_PREFIX );
	}
	/**
	 * キーを元にプロパティ値を取得します
	 * @param strPropertyName
	 */
	public String getPrefixProperty( String strPropertyName )
		throws Exception
	{

		if( mobjProperty == null ){
			return null;
		}

		String strValue;
		strValue = mobjProperty.getProperty( strPropertyName );

		return strValue;

	}


	/**
	 * 設定ファイルよりCSVエンコードをを取得します
	 */
	public String getCsvEncode()
		throws Exception
	{
		String lsCsvEncode = getProperty( CSV_ENCODE );
		if (lsCsvEncode == null || lsCsvEncode.trim().equals("")) {
			lsCsvEncode = "Windows-31J";	
		}
		return lsCsvEncode;
	}
}
