/**
 * LOGICAL-PARADOX.ORG
 * Copyright (C)2004 satoshi akabane(akabane@logical-paradox.org)
 *
 */
package org.logical_paradox.common.session;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;


/**
 * セッションのタイムアウトを検出するスレッドを呼び出す
 * @author satoshi akabane@logical-paradox.org
 * @version $Revision: 1.3 $
 */
public class SessionUnbounder extends Thread {
	/** 監視間隔(msec) */
	private int interval;
	/** スレッド終了フラグ */
	private boolean exitf = false; 
	/** セッションマネージャー */
	private SessionManager manager;

	/**
	 * コンストラクタ
	 */
	SessionUnbounder(SessionManager mngr, int itv) {
		interval = itv;
		manager = mngr;

		// このスレッドの停止を待たないようにする
		setDaemon(true);
	}
	/**
	 * スレッドメイン
	 */
	public void run() {
		try {
			while(true) {
				if(exitf) {
					// 終了シグナル
					throw new InterruptedException();
				}
				checkAllSessions();
				sleep(interval);
			}
		} catch(InterruptedException ie) {
			shutdown();
		}
	}
	/**
	 * 監視をやめる
	 */
	public void done() {
		exitf = true;
	}
	/**
	 * 終了処理を実行する
	 */
	private void shutdown() {
		done();
		manager = null;
	}
	/**
	 * セッションのタイムアウトを監視する
	 * タイムアウトしているセッションがあれば，タイムアウトイベントを発生させる
	 */
	protected void checkAllSessions() {
		Map sessions = manager.getAllSessions();
		ArrayList inactives = new ArrayList();
		synchronized(sessions) {
			for(Iterator it = sessions.keySet().iterator(); it.hasNext();) {
				String sessionId = (String)it.next();
				Session session;
				try {
					session = manager.getSession(sessionId, false);
					if(session != null && session.isActive() == false) {
						inactives.add(session);
					}
				} catch (IllegalSessionStateException e) {
					// セッションが既に無効だったので無視する
				}
			}
			manager.removeAllSessions(inactives);
		}
	}
}
