/*
 * Copyright (c) 2009 The openGion Project.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 * either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */
package org.opengion.hayabusa.common;

import org.opengion.fukurou.util.LogWriter;
import org.opengion.fukurou.util.StringUtil;
import org.opengion.fukurou.util.HybsEntry;

import java.util.Date;
import java.util.Calendar;
import java.util.Set;
import java.util.Map;
import java.util.HashMap;
import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Arrays;
import java.util.Locale ;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.net.InetAddress;
import java.net.UnknownHostException;

/**
 * 共通的に、使用されるシステム関連メソッドを集約したクラスです。
 *
 * 全変数は、public static final 宣言されています。
 * メソッドは、日付取得，エラーメッセージ処理 を行っています。
 *
 * @og.group 初期化
 *
 * @version  4.0
 * @author	 Kazuhiko Hasegawa
 * @since    JDK5.0,
 */
public final class HybsSystem {

	/** バッファの初期容量を通常より若干多い目に設定します。  {@value}  */
	public static final int BUFFER_SMALL = 50;

	/** バッファの初期容量を通常より多い目に設定します。  {@value}  */
	public static final int BUFFER_MIDDLE = 200;

	/** バッファの初期容量を通常より大幅に多い目に設定します。  {@value} */
	public static final int BUFFER_LARGE  = 500;

	/** システム依存の改行記号をセットします。	*/
	public static final String CR = System.getProperty("line.separator");

	/** HTMLでの改行記号（ &lt;br /&gt; ）をセットします。	*/
	public static final String BR = "<br />" + CR ;

	/** システム依存のファイルセパレーター文字をセットします。	*/
	public static final char FS = (System.getProperty("file.separator")).charAt(0);

	/** システム設定ＤＢのキーと値を、Map に読み込みます。  */
	// 4.0.0 (2005/01/31) システムパラメータの管理オブジェクト
	private static Map<String,String> sysParam = null;

	// 4.3.1.0 (2008/09/03) リクエストでのみ生成できる設定値のキャッシュ
	private static Map<String, String> reqCache = new HashMap<String, String>();

	/** URL の /（ルート）に対応する物理ディレクトリ  */
	private static String  realPath = null;	// 4.0.0 (2005/01/31)

	/** リクエスト関係パラメータの初期設定フラグ */
	private static boolean paramSetFlag = false;	// 4.0.0 (2005/11/30)

	/**
	 * テーブル表示時のチェックボックスのname属性  {@value}
	 * テーブル表示時にチェックボックスを表示しておき、どの行が選ばれたかを
	 * 指定する場合に、その name 属性に指定するキーの値です。
	 * 受け取る側は、このキーで、request 情報より選ばれた行番号を知ることができます。
	 */
	public static final String ROW_SEL_KEY = "h_rowSel";

	/**
	 * テーブル表示のチェックボックスを特定する id の 名称( id は、この名称＋行番号)   {@value}
	 */
	public static final String ROW_ID_KEY = "cb";	// 3.6.0.0 (2004/09/17)

	/** session オブジェクトに関連付ける DBTableModel インスタンスのデフォルトキー {@value} */
	public static final String TBL_MDL_KEY = "h_tblmdl" ;

	// 3.8.1.1 (2005/11/21) ExcelOut の整合性を取る為の仕掛け
	/** session オブジェクトに関連付ける ExcelOut の整合性チェック用のキー */
	public static final String TBL_MDL_CONKEY = "h_tblmdlCon" ;

	/** session オブジェクトに関連付ける Viewform インスタンスのデフォルトキー {@value} */
	public static final String VIEWFORM_KEY = "h_vform" ;

	/** session オブジェクトに関連付ける ViewLink インスタンスのデフォルトキー {@value} */
	public static final String VIEWLINK_KEY = "h_vlink" ;

	/** session オブジェクトに関連付ける ViewMark インスタンスのデフォルトキー {@value} */
	public static final String VIEW_MARK_KEY = "h_vmark" ;

	// 3.8.6.1 (2006/10/20) 編集時にカラムを置き換える 機能に対応
	/** session オブジェクトに関連付ける ViewMark:editor インスタンスのデフォルトキー */
	public static final String EDIT_MARK_KEY = "h_emark" ;

	/** session オブジェクトに関連付ける UserInfo インスタンスのキー {@value} */
	public static final String USERINFO_KEY = "h_uInfo" ;

	/** session オブジェクトに関連付ける GUIInfo インスタンスのキー {@value} */
	public static final String GUIINFO_KEY = "h_gInfo" ;

	/** session オブジェクトに関連付ける リクエスト情報キャッシュのキー {@value} */
	public static final String REQ_CACHE_KEY = "h_req" ;

	/** session オブジェクトに関連付ける エラーメッセージ情報キャッシュのキー {@value} */
	public static final String ERR_MSG_KEY = "h_errMsg" ;

	// 2.3.1.0 (2002/12/20) 管理者が全てのユーザーにメッセージを同報できるタグを追加
	/** session 管理者がステータスバーに設定するオブジェクトのキー {@value} */
	public static final String ST_BAR_OBJ_KEY = "h_stBar" ;

	// 3.0.0.0 (2002/12/25) SceduleTag 追加の伴う、Timerオブジェクトの管理用キー追加
	/** Timerオブジェクトの管理用キー {@value} */
	public static final String SCEDULE_KEY = "h_timer" ;

	// 3.0.0.0 (2002/12/25) SceduleTag 追加の伴う、Timerオブジェクトの管理用キー追加
	/** TimerTaskオブジェクトの管理用キー {@value} */
	public static final String SCEDULE_TASK_KEY = "h_timer_task" ;

	// 3.1.2.0 (2003/04/07) ソースコード中の固定値を、定義ファイルを使用するように変更する。
	/** Forward時の転送先ページ名をセッションに登録するときのキー {@value} */
	public static final String FORWARD_PAGE_KEY = "h_fpg" ;

	// 3.1.2.0 (2003/04/07) ソースコード中の固定値を、定義ファイルを使用するように変更する。
	/** Forward時の転送元ページ名をセッションに登録するときのキー {@value} */
	public static final String REVIEW_PAGE_KEY = "h_rpg" ;

	// 3.1.8.0 (2003/05/16) BACK_GAMENID のキャッシュ方法を、通常のリクエスト情報と分離して、管理する。
	/** BACK_GAMENID情報をセッションに登録するときのキー {@value} */
	public static final String BACK_GAMENID_KEY = "h_bgid" ;

	// 4.0.1.0 (2007/12/17) BACK_ADDRESS のキャッシュ方法を、通常のリクエスト情報と分離して、管理する。
	/** BACK_GAMENID情報をセッションに登録するときのキー {@value} */
	public static final String BACK_ADDRESS_KEY = "h_bgadrs" ;

	// 3.7.0.3 (2005/03/01) 戻るリンクで戻る行番号を指定します。(BACK_GAMENIDとセット)
	/** BACK_ROW情報をセッションに登録するときのキー {@value} */
	public static final String BACK_ROW_KEY = "h_brow" ;

	// 3.1.9.0 (2003/05/16) ShellTag で、Shell オブジェクトをキープする為のキーを作成。
	/** Shell オブジェクトをセッションに登録するときのキー {@value} */
	public static final String SHELL_KEEP_KEY = "h_shKeepKey" ;

	// 3.5.0.0 (2003/09/17) ユーザー変更時の、旧ユーザーIDのをキープする為のキーを作成。
	/** oldUserId 文字列をセッションに登録するときのキー {@value} */
	public static final String OLD_USERID_KEY = "h_oldID" ;

	// 3.5.4.7 (2004/02/06) DBTableModelのソート時のカラム名の受け渡しキー。
	/** sortColumns 文字列をリクエスト情報より取得するときのキー {@value} */
	public static final String SORT_COLUMNS = "h_sortClmns" ;

	// 3.5.4.7 (2004/02/06) DBTableModelのソート時のソート方向の受け渡しキー。
	/** sortAscending をリクエスト情報より取得するときのキー {@value} */
	public static final String SORT_ASCENDING = "h_sortAsc" ;

	// 3.5.5.0 (2004/03/12) キー＋行番号の連結文字列（例：__）を設定します。
	/** カラムID(連結文字列)行番号の連結文字列を定義 {@value} */
	public static final String JOINT_STRING = "__" ;

	// 3.5.5.3 (2004/04/09) synchronized 用のロックオブジェクトを作成します。
	private static final Object lock = new Object();

	// 3.5.5.5 (2004/04/23) DBTableModel の整合性パラメータを hidden で出力します。
	/** DBTableModel の整合性パラメータをリクエスト情報より取得するときのキー {@value} */
	public static final String CONSISTENCY_KEY = "h_consisKey" ;

	// 3.5.5.5 (2004/04/23) 転送不要パラメータの先頭に付けるキーワードです。
	/** SubmitTag で出力されるボタンパラメータは、次ページへ転送しません。 {@value} */
	public static final String NO_XFER_KEY = "hX_" ;

	// 3.8.0.0 (2005/06/07) 同一セッションでのマルチ起動対策用キーワードです。
	/** 同一セッションでのマルチ起動された場合に、前に開かれた画面からのアクセスを禁止します。 */
	public static final String MULTI_SESSION_CHECK = "MSC" ;

	/** 3.8.9.1 (2005/07/29) JFreeChart オブジェクトのキャッシュ {@value}  */
	public static final String JF_CHART_CACHE_KEY = "h_chartKey" ;

	// 3.8.0.8 (2005/10/03) GET時のURL に使用可能な文字数制限
	/** URL に使用可能な文字数は最大 2,083 文字
	 * http://support.microsoft.com/default.aspx?scid=kb;ja;208427
	 */
	public static final int MAX_GET_LENGTH = 2083 ;

	/** 4.0.0 (2005/01/31) GUIのロールを区切る、区切り文字		{@value}  */
	public static final char GUI_DELIMITER = '|' ;

	/** 4.0.0 (2005/01/31) ローカルリソースのオブジェクト保存時のキー	{@value}  */
	public static final String LOCAL_RES_KEY = "h_lclRes" ;

	/** 4.0.0 (2005/02/28) Tomcat起動時エラーが発生した場合のエラーキー	{@value}  */
	public static final String LOCAL_CONTX_ERR_KEY = "h_lclConErr" ;

	/** 4.0.0 (2005/08/31) グループメニューのキャッシュキー	{@value} */
	public static final String GUI_GR_MENU_CACHE_KEY = "h_grpCache" ;

	/** 4.0.0 (2005/09/30) 個人別お気に入りメニューの GE16 登録キーワード	{@value} */
	public static final String GUI_FAV_MENU_KEY = "GUI_FAV_MENU_KEY" ;

	/** 4.0.0 (2005/06/04) DBTableWriter の columns 属性のセッション登録キーワード	{@value} */
	public static final String TBL_WRITER_CLMS = "TBL_WRITER_CLMS" ;

	/** 4.1.2.1 (2008/03/13) must 属性をrequest変数にセットする場合の キー {@value} */
	public static final String MUST_KEY = "h_must_" ;

	/** 4.3.0.0 (2008/07/04) 最後に Queryを実行した情報の保存時のキー {@value} */
	public static final String DB_LAST_SQL_KEY = "h_lastSql" ;

	/** 4.3.3.0 (2008/10/01) ページ内で画面遷移なしモードを指定しようする場合のキー	{@value}  */
	public static final String NO_TRANSITION_MODE_KEY = "h_noTrnsKey" ;
	
	/** 4.3.6.0 (2009/04/01) イベントカラムを利用したかどうかのチェックキー	{@value}  */
	public static final String USE_EVENT_COLUMN_KEY = "h_eventColumn" ;

	/** 5.1.7.0 (2010/06/01) イベントカラムをラップするspanタグのクラス	{@value}  */	
	public static final String EVENT_COLUMN_CLASS = "h_evElm";

	/** 5.1.7.0 (2010/06/01) イベントカラムをラップするspanタグで、子カラムの書き込み可/不可を設定する属性名	{@value}  */	
	public static final String EVENT_COLUMN_WRITABLE = "h_evWrtbl";

	/** 5.1.7.0 (2010/06/01) イベントカラムをラップするspanタグで、子カラムのIDを設定する属性名	{@value}  */		
	public static final String EVENT_COLUMN_ID = "h_evCid";

	/** 5.1.7.0 (2010/06/01) イベントカラムをラップするspanタグで、子カラムの初期値を設定する属性名	{@value}  */		
	public static final String EVENT_COLUMN_INITVAL = "h_evVal";

	/** 4.3.7.0 (2009/06/01) linkタグのurlCheckキーを出力する際のパラメーターキー	{@value}  */
	public static final String URL_CHECK_KEY = "h_urlCheck" ;
	
	/** 4.3.7.5 (2009/07/08) ページ内でajaxSubmitを利用する場合のキー	{@value}  */
	public static final String USE_AJAX_SUBMIT_KEY = "h_ajaxSubmit" ;

	/** 5.1.6.0 (2010/05/01) Viewでソート済みかどうかを判定する際のキー	{@value} */
	public static final String VIEW_SORT_KEY = "h_viewSrt";

	/** 5.1.9.0 (2010/08/01) トランザクションを実現する際のキー	{@value} */
	public static final String TRANSACTION_KEY = "h_tran";

	/** 5.2.2.0 (2010/11/01) URLの引数部をハッシュする際のリクエストキー	{@value} */
	public static final String URL_HASH_REQ_KEY = "h_r";

	/** 5.3.2.0 (2011/02/01) リクエストパラメーターのキー一覧を保存する際のキー	{@value} */
	public static final String PARAM_NAMES_KEY = "h_prmNms";

	/** 5.3.6.0 (2011/06/01) クエリを呼び出し時のフォーカスを制御するためのキー	{@value} */
	public static final String QUERY_FOCUS_KEY = "h_qryFcs";

	/**
	 * 帳票エンコーディング	{@value}
	 * 設定されていない場合は、UTF-8 に設定されます。
	 */
	public static final String REPORT_ENCODE = "UTF-8" ;

	/** 実行しているサーバーの名称 */
	public static final String HOST_NAME ;
	/** 実行しているサーバーのIPアドレス */
	public static final String HOST_ADRS ;

	static {
		String dmnHost ;
		String dnmAdrs ;
		try {
			InetAddress address = InetAddress.getLocalHost();
			dmnHost = address.getHostName() ;
			dnmAdrs = address.getHostAddress() ;
		}
		catch( UnknownHostException ex ) {
			dmnHost = "Unknown";
			dnmAdrs = "Unknown";
		}
		HOST_NAME = dmnHost;
		HOST_ADRS = dnmAdrs;
	}

	/**
	 * デフォルトコンストラクターをprivateにして、
	 * オブジェクトの生成をさせないようにする。
	 *
	 */
	private HybsSystem() {}

	/**
	 * 内部システムリソースマップオブジェクトを設定します。
	 *
	 * @og.rev 3.5.3.1 (2003/10/31) 新規作成
	 * @og.rev 4.0.0 (2005/01/31) Ver4 のシステムパラメータ情報の取得処理を追加します。
	 * @og.rev 4.3.1.0 (2008/09/03) SERVER_NAME,SERVER_URL,CONTEXT_URLをキャッシュから復元
	 *
	 * @param	param Map<String,String> システムリソースマップオブジェクト
	 */
	public static void setInitialData( final Map<String,String> param ) {
		synchronized( lock ) {
			sysParam	= param;
			realPath	= param.get( "REAL_PATH" );	// 4.0.0 (2005/01/31)
			// 4.3.1.0 (2008/09/03) SERVER_NAME,SERVER_URL,CONTEXT_URLをキャッシュから復元
			if( paramSetFlag ) {
				sysParam.putAll( reqCache );
			}
		}

		System.out.println( "    [" + sysParam.get( "CONTEXT_NAME" ) + "] のシステムパラメータが、[" + sysParam.size() + "] 件設定されました。" );
	}

	/**
	 * システムパラメータ情報を取得します。
	 * Ver3 では、プロパティーファイルでリソースを提供している為、
	 * 立ち上げタイミングとの関係で始めて使用する場合にデータを取得します。
	 *
	 * @og.rev 4.0.0 (2005/01/31) 新規作成
	 *
	 * @param	key String システムパラメータのキー
	 * @return  String システムパラメータ の値
	 */
	private static String getParam( final String key ) {
		synchronized( lock ) {
			return sysParam.get( key );
		}
	}

	/**
	 * システムパラメータの追加情報セットが終了しているかどうかを取得します。
	 * 設定処理を行うかどうかの判定に使用します。
	 *
	 * @og.rev 4.0.0 (2005/11/30) 新規作成
	 *
	 * @return	boolean true:設定完了 / false:未完了(設定可能)
	 * @see #setRequestParam( String,String,int,String )
	 */
	public static boolean isParamSet() {
		return paramSetFlag;
	}

	/**
	 * システムパラメータ情報を追加設定します。
	 * これは、SERVER_NAME、SERVER_URL、CONTEXT_URL などのリクエストオブジェクトから
	 * しか取得できない共有情報を、登録する場合に使用します。
	 * これらの値は、taglib/JspInitTag タグでセットされます。
	 * セットする前に、isParamSet() で設定済みかどうか判断してください。
	 * このメソッドは、isParamSet() の値に関係なく、セットします。
	 *
	 * @og.rev 4.0.0 (2005/01/31) 新規作成
	 * @og.rev 4.3.1.0 (2008/09/03) SERVER_NAME,SERVER_URL,CONTEXT_URLのキャッシュ処理追加
	 *
	 * @param	serverName String サーバー名
	 * @param	scheme String スキーマ
	 * @param	port int ポート番号
	 * @param	path String コンテキストパス
	 * @see #isParamSet()
	 */
	public static void setRequestParam( final String serverName,final String scheme,
										final int port,final String path ) {
		synchronized( lock ) {
			sysParam.put( "SERVER_NAME",serverName );
			
			String portStr = ( port == 80 ) ? "" : ":" + port ;
			String serverURL = scheme + "://" + serverName + portStr ;
			sysParam.put( "SERVER_URL",serverURL + "/" );
			
			String contextURL = serverURL + path + "/" ;
			sysParam.put( "CONTEXT_URL",contextURL );
			// 4.3.1.0 (2008/09/03) SERVER_NAME,SERVER_URL,CONTEXT_URLをキャッシュして置く
			reqCache.put( "SERVER_NAME",serverName );
			reqCache.put( "SERVER_URL",serverURL + "/" );
			reqCache.put( "CONTEXT_URL",contextURL );
			paramSetFlag = true;
		}
	}

	/**
	 * 現在日付、時刻を所得します。
	 * 出力フォーマットは、システムパラメータ の SYS_TIME の
	 * 設定を適用します。（ "yyyy/MM/dd HH:mm:ss" ）
	 *
	 * @og.rev 4.0.0 (2005/01/31) getSystemResource() ⇒ sysParam に変更
	 *
	 * @return	現在日付、時刻 ( 例 2001/04/17 15:48:22 )
	 */
	public static String getDate() {
		return getDate( getParam( "SYS_TIME" ) );
	}

	/**
	 * 指定時刻をデフォルトのフォーマットで、所得します。
	 * フォーマットの指定方法は、java.text.SimpleDateFormat の指定方法と同一です。
	 * 出力フォーマットは、システムパラメータ の SYS_TIME の
	 * 設定を適用します。（ "yyyy/MM/dd HH:mm:ss" ）
	 *
	 * @og.rev 4.0.0 (2005/01/31) getSystemResource() ⇒ sysParam に変更
	 *
	 * @param	time 指定のカレントタイム
	 * @return	現在日付、時刻( 例 2001/04/17 15:48:22 )
	 */
	public static String getDate( final long time ) {
		String form = getParam( "SYS_TIME" );
		DateFormat formatter = new SimpleDateFormat( form,Locale.JAPAN );
		return formatter.format(new Date( time ));
	}

	/**
	 * 現在日付、時刻をフォーマットを指定して、所得します。
	 * フォーマットの指定方法は、java.text.SimpleDateFormat の指定方法と同一です。
	 *
	 * @param	form フォーム文字列 ( 例 "yyyy/MM/dd HH:mm:ss.SSS" )
	 * @return	現在日付、時刻
	 */
	public static String getDate( final String form ) {
		DateFormat formatter = new SimpleDateFormat( form,Locale.JAPAN );
		return formatter.format(new Date());
	}

	/**
	 * 指定時刻をデフォルトのフォーマットで、所得します。
	 * フォーマットの指定方法は、java.text.SimpleDateFormat の指定方法と同一です。
	 * 出力フォーマットは、システムパラメータ の SYS_TIME の
	 * 設定を適用します。（ "yyyy/MM/dd HH:mm:ss" ）
	 *
	 * @og.rev 4.0.0 (2005/01/31) 新規追加
	 *
	 * @param	time 指定のカレントタイム
	 * @param	form フォーム文字列 ( 例 "yyyy/MM/dd HH:mm:ss.SSS" )
	 * @return	現在日付、時刻( 例 2001/04/17 15:48:22 )
	 */
	public static String getDate( final long time,final String form ) {
		DateFormat formatter = new SimpleDateFormat( form,Locale.JAPAN );
		return formatter.format(new Date( time ));
	}

	/**
	 * 現在の月に、指定の月数をプラスした日付文字列を返します。
	 * 日付文字列のフォーマットは、"yyyyMM" です。
	 * 指定する月数にマイナスを指定すると、減算できます。
	 *
	 * @param	plus  プラスする月数
	 * @return	指定の月数をプラスした日付文字列
	 */
	public static String getYMDate( final int plus ) {
		Calendar rightNow = Calendar.getInstance();
		rightNow.set( Calendar.DATE, 1 );		// 当月の 1 日に設定
		rightNow.add( Calendar.MONTH , plus );

		DateFormat formatter = new SimpleDateFormat( "yyyyMM",Locale.JAPAN );
		return formatter.format( rightNow.getTime() );
	}

	/**
	 * システム設定ファイルのデータを所得します。
	 * キーが存在しない場合は、null を返します。
	 * キーがnullの場合は、HybsSystemException をスローします。
	 *
	 * @og.rev 3.5.5.0 (2004/03/12) {&#064;SYS.XXXX} で使用できる変数を増やします。
	 * @og.rev 3.5.5.3 (2004/04/09) {&#064;SYS.XXXX} に、DATE というキーを追加します。
	 * @og.rev 4.0.0 (2005/01/31) getSystemResource() ⇒ sysParam に変更
	 *
	 * @param	key システム設定 キー
	 * @return	システム設定値
	 * @throws HybsSystemException
	 */
	public static String sys( final String key ) throws HybsSystemException {
		if( key == null ) {
			String errMsg = "キーが null です。";
			throw new HybsSystemException( errMsg );		// 3.5.5.4 (2004/04/15) 引数の並び順変更
		}

		if( "DATE".equals( key ) ) { return getDate() ; }	// 3.5.5.3 (2004/04/09)

		String rtn = getParam( key );
		if( rtn == null && ! key.startsWith( "h_" ) ) {
			String errMsg = CR + "システムリソースキーが存在しません。key = " + key;
			LogWriter.log( errMsg );
		}
		return rtn;
	}

	/**
	 * システム設定ファイルから、複数のデータを所得します。
	 * キーが,"ABC" とすれば、それで始まるデータ（ ABCD, ABC_01 など）
	 * を配列で取得できます。
	 * リターン配列は、ソートされています。
	 *
	 * @og.rev 4.0.0 (2005/01/31) getSystemResource() ⇒ sysParam に変更
	 *
	 * @param	key システム設定 キー（の先頭の部分文字列）
	 * @return	システム設定配列 HybsEntry
	 */
	public static HybsEntry[] sysEntry( final String key ) {

		List<HybsEntry> vals = new ArrayList<HybsEntry>();

		synchronized( lock ) {
			Iterator<String> keyIte = sysParam.keySet().iterator();		// 4.3.3.6 (2008/11/15) Generics警告対応
			while( keyIte.hasNext() ) {
				String tempKey = keyIte.next();		// 4.3.3.6 (2008/11/15) Generics警告対応
				if( tempKey != null && tempKey.startsWith( key ) ) {
					HybsEntry entry = new HybsEntry( tempKey,sysParam.get( tempKey ) );
					vals.add( entry );
				}
			}
		}
		HybsEntry[] entrys = vals.toArray( new HybsEntry[vals.size()] ) ;
		Arrays.sort( entrys );

		return entrys;
	}

	/**
	 * システム設定ファイルのデータを所得します。
	 * 特別に,int 型にデータを変換して,渡します。
	 * 変換できない場合は,NumberFormatException がスローされます。
	 *
	 * @og.rev 3.5.3.1 (2003/10/31) エラー時に、判るようにメッセージを出します。
	 * @og.rev 4.0.0 (2005/01/31) getSystemResource() ⇒ sysParam に変更
	 *
	 * @param	key システム設定 キー
	 * @return	システム設定値（int型)
	 */
	public static int sysInt( final String key ) {
		if( key == null ) {
			String errMsg = "キーが null です。";
			throw new HybsSystemException( errMsg );		// 3.5.5.4 (2004/04/15) 引数の並び順変更
		}

		String tmp = getParam( key );
		int rtn ;
		try {
			rtn = Integer.parseInt( tmp );
		}
		catch( NumberFormatException ex2 ) {
			String errMsg = "システムリソース の値が数字ではありません。" + CR
					+ "  Resource key=[" + key + "] val=[" + tmp + "]"  ;
			throw new HybsSystemException( errMsg,ex2 );		// 3.5.5.4 (2004/04/15) 引数の並び順変更
		}

		return rtn;
	}

	/**
	 * システム設定ファイルのデータを所得します。
	 * 特別に,boolean 型にデータを変換して,渡します。
	 * 変換できない場合は,NumberFormatException がスローされます。
	 *
	 * @og.rev 3.5.6.0 (2004/06/18) Booleanのコンストラクタの代わりに、Boolean.valueOf(...) を使用します。
	 *
	 * @param	key システム設定 キー
	 * @return	システム設定値（boolean型)
	 */
	public static boolean sysBool( final String key ) {
		return Boolean.valueOf( HybsSystem.sys( key ) ).booleanValue();
	}

	/**
	 * システム依存のURL文字列から，実際のディレクトリ名を所得します。
	 * UNIX と Windows を URL パス名から判断して、実ディレクトリを返します。<br/>
	 * 指定方法は、通常の fileURL 属性と同様に、先頭が、'/' （UNIX) または、２文字目が、
	 * ":" （Windows）の場合は、指定のURLそのままのディレクトリに、そうでない場合は、
	 * システムパラメータ の FILE_URL 属性で指定のフォルダの下に、作成されます。
	 * 相対パス、または、URL の場合は、頭に / を入れないでください。UNIX の
	 * 絶対パスと判断されます。<br/>
	 * また、絶対パスの最後には、/ を入れておいてください。
	 *
	 * @og.rev 4.0.0 (2005/01/31) StringUtil.urlAppend メソッドの利用
	 *
	 * @param	url URL文字列
	 * @return	ディレクトリ文字列
	 */
	public static String url2dir( final String url ) {
		return StringUtil.urlAppend( realPath,url ).replace( '/',FS );
	}

	/**
	 * システムリソース情報を取得します。
	 * 形式は、キー([0])、値([1])の２次元配列です。
	 * キーでソートされています。
	 *
	 * @og.rev 3.5.3.1 (2003/10/31) 新規追加
	 * @og.rev 4.0.0 (2005/01/31) getSystemResource() ⇒ sysParam に変更
	 *
	 * @return	String[][] キー([0])、値([1])の２次元配列
	 */
	public static String[][] getSystemResourceData() {
		String[][] rtn ;

		synchronized( lock ) {
			Set<Map.Entry<String,String>> entrSet = sysParam.entrySet();
			int size = entrSet.size();
			rtn = new String[2][size];

			Iterator<Map.Entry<String,String>> entrIte = entrSet.iterator();
			for( int i=0; i<size; i++ ) {
				Map.Entry<String,String> entry = entrIte.next();
				rtn[0][i] = entry.getKey();
				rtn[1][i] = entry.getValue();
			}
		}
		return rtn ;
	}

	/**
	 * システムのコンテキスト名を取得します。
	 * コンテキスト名は、Tomcat の servr.xml で指定する仮想フォルダ名です。
	 *
	 * @og.rev 3.5.4.3 (2004/01/05) 新規追加
	 *
	 * @return	String コンテキスト名（仮想フォルダ名）
	 */
	public static String getContextName() {
		return sys( "CONTEXT_NAME" );	// 4.0.0 (2005/01/31)
	}

	/**
	 * 指定の引数の日付け文字列（YYYYMMDDHHMMSS）より、カレンダオブジェクトを作成します。
	 * 引数は、YYYYMMDD の８文字か、YYYYMMDDHHMMSS の１４文字のどちらかです。
	 *
	 * @og.rev 3.5.4.8 (2004/02/23) 新規作成
	 *
	 * @param value 日付け文字列（YYYYMMDD または YYYYMMDDHHMMSS）
	 * @return	String カレンダオブジェクト
	 */
	public static Calendar getCalendar( final String value ) {
		if ( value == null || ( value.length() != 8 && value.length() != 14 ) ) {
			String errMsg = "引数は、YYYYMMDD または YYYYMMDDHHMMSS 形式の日付け文字列のみです。"
					+ " value=[" + value + "]" ;
			throw new HybsSystemException( errMsg );
		}

		Calendar cal = Calendar.getInstance();
		cal.clear();

		int hour=0,minute=0,second=0;

		int year   = Integer.parseInt( value.substring( 0,4 ) );
		int month  = Integer.parseInt( value.substring( 4,6 ) ) - 1;
		int date   = Integer.parseInt( value.substring( 6,8 ) );

		if( value.length() == 14 ) {
			hour   = Integer.parseInt( value.substring( 8,10 ) );
			minute = Integer.parseInt( value.substring( 10,12 ) );
			second = Integer.parseInt( value.substring( 12,14 ) );
		}

		cal.set( year,month,date,hour,minute,second );

		return cal;
	}

	/**
	 * 指定の引数の日付け文字列（YYYYMMDD）より、差分の日付を計算して返します。
	 * 引数は、YYYYMMDD と 差分の日数。
	 *
	 * @og.rev 4.1.1.0 (2008/01/30) 新規作成
	 *
	 * @param baseDate 日付け文字列（YYYYMMDD）
	 * @param diff     差分の日数（過去の日付[+]、将来の日付は[-]）
	 * @return	String 結果の日付（YYYYMMDD）
	 */
	public static String getDate( final String baseDate,final int diff ) {
		if ( baseDate == null || ( baseDate.length() != 8 ) ) {
			String errMsg = "引数 baseDate は、YYYYMMDD 形式の日付け文字列のみです。"
					+ " baseDate=[" + baseDate + "]" ;
			throw new HybsSystemException( errMsg );
		}

		Calendar cal = getCalendar( baseDate );
		cal.add( Calendar.DATE,diff );
		String rtn = null;

		int calYear		= cal.get( Calendar.YEAR );
		int calMonth	= cal.get( Calendar.MONTH ) + 1;
		int calDay		= cal.get( Calendar.DATE );
		rtn = String.valueOf( calYear );
		if( calMonth < 10 ) {
//			rtn = rtn + "0" + String.valueOf( calMonth );
			rtn = rtn + "0" + calMonth;
		}
		else {
//			rtn = rtn + String.valueOf( calMonth );
			rtn = rtn + calMonth;
		}
		if( calDay < 10 ) {
//			rtn = rtn + "0" + String.valueOf( calDay );
			rtn = rtn + "0" + calDay;
		}
		else {
//			rtn = rtn + String.valueOf( calDay );
			rtn = rtn + calDay;
		}
		return rtn;
	}

	/**
	 * 指定されたクラスローダを使って、識別id に応じた オブジェクトを作成します。
	 * 作成するには、デフォルトコンストラクターが必要です。
	 * initialize パラメータは true 相当(それまでに初期化されていない場合だけ初期化)です。
	 *
	 * @param	cls String 作成するクラスのフルネーム
	 * @return	オブジェクト
	 * @throws RuntimeException 何らかのエラーが発生した場合
	 */
	public static Object newInstance( final String cls ) {
		try {
			return Class.forName( cls ).newInstance();
		}
		catch( ClassNotFoundException ex1 ) {
			String errMsg = "クラスが見つかりません。class=[" + cls + "]" + CR
						+ ex1.getMessage() ;
			throw new RuntimeException( errMsg,ex1 );
		}
		catch( LinkageError ex2 ) {
			String errMsg = "リンケージが失敗しました。class=[" + cls + "]" + CR
						+ ex2.getMessage();
			throw new RuntimeException( errMsg,ex2 );
		}
		catch( InstantiationException ex3 ) {
			String errMsg = "インスタンスの生成が失敗しました。class=[" + cls + "]" + CR
						+ ex3.getMessage() ;
			throw new RuntimeException( errMsg,ex3 );
		}
		catch( IllegalAccessException ex4 ) {
			String errMsg = "クラスまたは初期化子にアクセスできません。class=[" + cls + "]" + CR
						+ ex4.getMessage();
			throw new RuntimeException( errMsg,ex4 );
		}
		catch( RuntimeException ex5 ) {		// 3.6.0.0 (2004/09/17)
			String errMsg = "予期せぬエラー class=[" + cls + "]" + CR
						+ ex5.getMessage() ;
			throw new RuntimeException( errMsg,ex5 );
		}
	}
}
