<?php
/**
* HTTPプローシージャ
*
* PHP version 5
*
* @package    procedures
* @author     stk2k <stk2k@sazysoft.com>
* @copyright  2008 stk2k, sazysoft
*/
class HttpProcedure extends CharcoalComponent implements IProcedure
{
	private $_tasks;
	private $_input_filters;
	private $_output_filters;
	private $_renderer;
	private $_task_manager;
	private $_page_selector;

	/*
	 * コンストラクタ
	 */
	public function __construct( String $name = NULL )
	{
		parent::__construct(s($name));
	}

	/*
	 * プロシージャを初期化する
	 */
	public function init( Config $config )
	{
		$this->_tasks               = $config->getArray( s('tasks') );
		$this->_output_filters      = $config->getArray( s('output_filters') );
		$this->_input_filters       = $config->getArray( s('input_filters') );
		$this->_renderer            = $config->getString( s('renderer') );
		$this->_task_manager        = $config->getString( s('task_manager') );
		$this->_page_selector       = $config->getString( s('page_selector') );

		if ( !$this->_page_selector ){
			_throw( new ProcedureConfigException( 'page_selector', 'mandatory' ) );
		}
	}

	/*
	 * プロシージャを実行する
	 */
	public function execute( IRequest $request, Response $response )
	{
		$proc_name = parent::getName();

		log_info( "system",  "プロシージャ[$proc_name]を実行します。", __FILE__, __LINE__ );

		//=======================================
		// セッションの作成
		//

		if ( Profile::getBoolean( s('USE_SESSION') ) ){
			// セッションを作成
			$session = new Session();

			// セッションの開始
			$session->start();
			$session->restore();
		}

		//=======================================
		// タスクマネージャの作成
		//

		// タスクマネージャを作成
		$task_manager_name = $this->_task_manager;
		$task_manager = Factory::createTaskManager( $task_manager_name );

		//=======================================
		// タスクの登録
		//

		foreach( $this->_tasks as $task_name ){
			$task_manager->registerTask( s($task_name) );
			log_info( "event",  "タスクマネージャにタスク[$task_name]を登録しました。", __FILE__, __LINE__ );
		}

		//=======================================
		// ステートフルタスクの復帰
		//

		if ( Profile::getBoolean( s('USE_SESSION') ) ){
			$task_manager->restoreStatefulTasks( $session );
		}

		//=======================================
		// 入力フィルタの実行
		//

		if ( $this->_input_filters ) {
			log_info( "system",  "入力フィルタを実行します。", __FILE__, __LINE__ );

			foreach( $this->_input_filters as $filter_name ) {
				// フィルタを作成
				$filter = Factory::createFilter( $filter_name );
				// フィルタの実行
				$filter->filter( $request, $context, $response );
			}
	
			log_info( "system",  "入力フィルタを実行しました。", __FILE__, __LINE__ );
		}

		//=======================================
		// イベントディスパッチ
		//

		$task_manager->dispatchEvents( $request );

		//=======================================
		// イベント処理
		//

		$task_manager->processEvents();

		//=======================================
		// ページ選択
		//

		// ページセレクタの作成
		$page_selector_name = $this->_page_selector;
		$page_selector = Factory::createPageSelector( $page_selector_name );
		// ページ選択
		$page = $page_selector->selectPage( $proc_name, $task_manager->getSnapshot(), $response );

		//=======================================
		// 出力フィルタの実行
		//
		if ( $this->_output_filters ) {
			log_info( "system",  "出力フィルタを実行します。", __FILE__, __LINE__ );

			foreach( $this->_output_filters as $filter_name ) {
				// フィルタを作成
				$filter = Factory::createFilter( s($filter_name) );
				// フィルタの実行
				$filter->filter( $request, $response );
			}

			log_info( "system",  "出力フィルタを実行しました。", __FILE__, __LINE__ );
		}

		//=======================================
		// レンダラの実行
		//
		if ( $this->_renderer && strlen($this->_renderer) > 0 ) {
			log_info( "system",  "レンダラを実行します。", __FILE__, __LINE__ );

			$renderer = Factory::createRenderer( $this->_renderer );
			if ( $renderer ) {
				$renderer->render( $page, $response );
			}
			log_info( "system",  "レンダラを実行しました。", __FILE__, __LINE__ );

		}

		//=======================================
		// 終了処理
		//

		// セッション情報の保存
		if ( Profile::getBoolean( s('USE_SESSION') ) ) {

			// ステートフルタスクの保存
			$task_manager->saveStatefulTasks( $session );

			// セッションを保存
			$session->save();
			$session->close();
		}

		log_info( "system",  "プロシージャ[$proc_name]を実行しました。", __FILE__, __LINE__ );
	}
}

return __FILE__;