/*
 * 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.db.ConnectionFactory;
import org.opengion.fukurou.util.Cleanable;
import org.opengion.fukurou.util.HybsEntry;
import org.opengion.fukurou.util.URLConnect;
import org.opengion.fukurou.util.LogWriter;
import java.util.Date;
import java.util.Map;

import javax.servlet.ServletContextListener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContext;

import java.io.IOException;

/**
 * ServletContextListener を実装した、コンテキストの監視オブジェクトです。
 * これは、コンテキスト（Webアプリケーション）の起動/シャットダウンを監視できる。
 *
 * ServletContextListener は、
 *
 *      ConnectionFactory のコネクションプールへのアクセス／開放
 *      ResourceFactory   のリソース情報へのアクセス／開放
 *
 * の作業を行います。
 *
 * このリスナーは、WEB-INF/web.xml で、組み込みます。
 *
 * 【WEB-INF/web.xml】
 *
 *     &lt;listener&gt;
 *         &lt;listener-class&gt;
 *             org.opengion.hayabusa.common.HybsContextListener
 *         &lt;/listener-class&gt;
 *     &lt;/listener&gt;
 *
 * @og.group 初期化
 *
 * @version  4.0
 * @author   Kazuhiko Hasegawa
 * @since    JDK5.0,
 */
public class HybsContextListener implements ServletContextListener {
	// 4.0.0.0 (2007/10/26) ConnectionFactoryのhayabusa依存を切るために移動してきた
	static {
		final Cleanable clr = new Cleanable() {
			public void clear() {
				ConnectionFactory.realClose();
			}
		};
		SystemManager.addCleanable( clr );
	}

	/**
	 *  ServletContextListener インターフェースの実装
	 *
	 * Webアプリケーションがリクエストを処理できる状態になったことを
	 * リスナーに通知する。
	 *
	 * @og.rev 3.0.0.0 (2002/12/25) バージョンチェック、HybsSystem初期化追加
	 * @og.rev 3.4.0.0 (2003/09/01) Contextのpathによる、システムパラメータ の切り替え対応
	 * @og.rev 3.4.0.3 (2003/09/10) ServletContext の名称を、仮想パス名とする。
	 * @og.rev 3.5.3.1 (2003/10/31) システムパラメータ ファイルの読み取りタイミングを遅らせます。
	 * @og.rev 4.0.0 (2005/01/31) Ver4 のシステムパラメータ情報の取得処理を追加します。
	 * @og.rev 4.1.0.1 (2008/01/23) ログ出力先の設定処理を追加
	 * @og.rev 4.3.4.1 (2008/12/08) ログの環境変数対応
	 *
	 * @param  event ServletContextEvent
	 *
	 */
	public void contextInitialized( final ServletContextEvent event ) {
		ServletContext context = event.getServletContext();

//		// 4.0.0.0 (2007/10/26) ConnectionFactoryのhayabusa依存を切るために移動してきた
//		final Cleanable clr = new Cleanable() {
//			public void clear() {
//				ConnectionFactory.realClose();
//			}
//		};
//		SystemManager.addCleanable( clr );

		Map<String,String> param = SystemParameter.makeSystemParameter( context );
		HybsSystem.setInitialData( param );			// 4.0.0 (2005/01/31)

		// 4.3.4.1 (2008/12/08) ログの環境変数対応
//		LogWriter.init( HybsSystem.url2dir( HybsSystem.sys( "SYS_LOG_URL" ) ) ); // 4.1.0.1 (2008/01/23)
		LogWriter.init( HybsSystem.url2dir( System.getProperty( "SYS_LOG_URL" ,HybsSystem.sys( "SYS_LOG_URL" ) ) ) );

		// CONTEXT_INITIAL_CALL_URL で登録されたURLを実行します。
		// 処理は、contextInitialized が終了してから実行する必要があります。
		new Thread( new InitialCallURL() ).start();

		System.out.println( "-------" );
	}

	/**
	 *  ServletContextListener インターフェースの実装
	 *
	 * Webアプリケーションがシャットダウンされることを
	 * リスナーに通知する。
	 *
	 * @og.rev 3.1.1.1 (2003/04/03) キャッシュクリアメソッドを新規追加。
	 * @og.rev 3.3.3.3 (2003/08/06) HybsTimerTaskManager を終了時にキャンセルするロジックを追加。
	 * @og.rev 3.5.2.1 (2003/10/27) リンクエラー対策：永続化セッション（SESSIONS.ser）からオブジェクトを削除しておく。
	 * @og.rev 3.6.0.0 (2004/09/17) CalendarFactory.clear() を追加します。
	 * @og.rev 4.0.0 (2005/01/31) コンテキスト名の取り方を変更します。
	 * @og.rev 4.0.0 (2005/01/31) Cleanable インターフェースによる初期化処理
	 * @og.rev 4.0.0 (2005/01/31) HybsTimerTaskManager は、Cleanable インターフェースによる初期化
	 * @og.rev 4.1.0.0 (2007/12/27) GE12のクリア処理追加
	 * @og.rev 4.3.0.0 (2008/07/18) soffice.binのタスクを削除する処理を追加
	 * @param  event ServletContextEvent
	 */
	public void contextDestroyed( final ServletContextEvent event ) {
		String name = HybsSystem.sys( "CONTEXT_NAME" );
		System.out.println( "Context Destroyed [" + name + "]  " + new Date() );

		// 4.1.0.0 (2007/12/26) GE12からSystemParameterで設定したコンテキスト関係の情報
		SystemManager.clearGE12();

		// 4.0.0 (2005/01/31) Cleanable インターフェースによる初期化処理
		SystemManager.allClear( true ) ;

		// 4.3.0.0 (2008/07/18) soffice.binを全てkillします
		SystemManager.sofficeKill();

		SystemManager.sessionDestroyed();		// 3.5.2.1 (2003/10/27)

		System.out.println( "-------" );
	}

	/**
	 * CONTEXT_INITIAL_CALL_URL を起動する為のスレッド内部クラスです。
	 *
	 * HybsContextListener が正常終了しないと、Tomcatが起動したことになっていない為、
	 * 通常のJSP処理が出来ません。
	 * ここでは、Tomcat起動時に初期処理URL(CONTEXT_INITIAL_CALL_URL)をコールする為に、
	 * 時間差を利用する為、スレッド化して実行させます。
	 * このスレッドは、２秒間スリープ後に、初期処理URLを呼び出します。
	 *
	 * @og.rev 4.2.2.0 (2008/05/22) 初期URLの接続ユーザーをシステムリソースより取得
	 *
	 * @og.group ログイン制御
	 *
	 * @version  4.0
	 * @author   Kazuhiko Hasegawa
	 * @since    JDK5.0,
	 */
	private static class InitialCallURL implements Runnable {
		/**
		 * スレッドの処理開始メソッド
		 *
		 */
		public void run() {
			try {
				Thread.sleep( 2000 );
			}
			catch ( InterruptedException ex) {
				LogWriter.log( "InterruptedException:" + ex.getMessage() );
			}

			HybsEntry[] urls = HybsSystem.sysEntry( "CONTEXT_INITIAL_CALL_URL" );
//			String userPass = "SYSTEM:MANAGER" ;
			String userPass = HybsSystem.sys( "CONTEXT_INITIAL_CALL_USERPASS" );
			boolean isCall = false;
			for( int i=0; i<urls.length; i++ ) {
				String url = urls[i].getValue();
				if( url == null || url.length() == 0 ) { continue; }
				URLConnect conn = new URLConnect( url,userPass );
				try {
					conn.connect();
					String msg = conn.getCode() + ":" + conn.getMessage() ;
					conn.disconnect();
					System.out.println( "    URL[" + i + "]:" + url );
					System.out.println( "           " + msg );
					isCall = true ;
				}
				catch( IOException ex ) {
					LogWriter.log( "    URL[" + i + "]:" + url );
					LogWriter.log( "           " + ex.getMessage() );
				}
			}
			if( isCall ) {
				System.out.println( "  CONTEXT_INITIAL_CALL_URL" );
				System.out.println( "-------" );
			}
		}
	}
}
