<?php
/**
* モジュールグラフのノードを実装するクラス
*
* PHP version 5
*
* @package    core
* @author     stk2k <stk2k@sazysoft.com>
* @copyright  2008 stk2k, sazysoft
*/

class charcoal_ModuleGraphNode 
{
	var $_node_name;
	var $_action;
	var $_module_name;
	var $_transitions;
	var $_context_values;

	/*
	 *    コンストラクタ
	 */
	public function __construct()
	{
		$this->_module = NULL;
		$this->_transitions = NULL;
		$this->_context_values = NULL;
	}

	/*
	 * ノード名を取得
	 */
	public function getNodeName()
	{
		return $this->_node_name;
	}

	/*
	 * モジュール名を取得
	 */
	public function getModuleName()
	{
		return $this->_module_name;
	}

	/*
	 * 遷移先キー一覧を取得
	 */
	public function getTransitionKeys()
	{
		return array_keys( $this->_transitions );
	}

	/*
	 * 遷移先を取得
	 */
	public function getNextNode( $transition_key )
	{
		return isset($this->_transitions[ $transition_key ]) ? $this->_transitions[ $transition_key ] : NULL;
	}

	/*
	 * ノードを作成
	 */
	public function create( $node_name, $node_config )
	{
		log_info( "system",  "ノード[$node_name]を作成します。", __FILE__, __LINE__ );

		// 遷移先情報を取得
		if ( !isset($node_config[ "next" ]) ){
			throw new charcoal_ModuleGraphConfigException( "$node_name/next", "mandatory" );
		}
		$transitions = $node_config[ "next" ];

		// モジュール名を取得
		if ( !isset($node_config[ "module_name" ]) ){
			throw new charcoal_ModuleGraphConfigException( "$node_name/module_name", "mandatory" );
		}
		$module_name = $node_config[ "module_name" ];

		// モジュールコンテキスト値を取得
		$context_values = isset($node_config[ "context" ]) ? $node_config[ "context" ] : NULL;

		// アクションを取得
		$action = isset($node_config[ "action" ]) ? $node_config[ "action" ] : NULL;

		$this->_node_name = $node_name;
		$this->_action = $action;
		$this->_module_name = $module_name;
		$this->_transitions = $transitions;
		$this->_context_values = $context_values;
	}

	/*
	 * コンテキスト値をインジェクトする
	 */
	private function injectContext( charcoal_ProcedureContext $context )
	{
		if ( !$this->_context_values ){
			return;
		}

		$node_name = $this->_node_name;
		foreach( $this->_context_values as $key => $value ){
			log_debug( 'system', "ノード[$node_name]設定値[$key:$value]", __FILE__, __LINE__ );
			$context->set( $key, $value );
			log_debug( 'system', "ノード[$node_name]でコンテキスト値[$key:$value]がinjectされました。", __FILE__, __LINE__ );
		}
	}

	/*
	 * ノードを実行する
	 */
	public function execute( charcoal_Request $request, charcoal_ProcedureContext $context, charcoal_Response $response )
	{
//		try{
			// コンテキスト値をインジェクトする
			$this->injectContext($context);

			// ノード名とモジュール名を取得
			$node_name = $this->_node_name;
			$module_name = $this->_module_name;

			log_info( "system",  "ノード[$node_name]を実行します。", __FILE__, __LINE__ );

			// モジュールのロード
			$module = charcoal_ModuleFactory::create( $module_name );

			// モジュールの実行
			log_info( "system",  "モジュール[$module_name]を実行します。", __FILE__, __LINE__ );

	//			try{
				$transition_key = $module->execute( $this->_action, $request, $context, $response );

	/*			}
			catch( Exception $e ){
				// 例外遷移
				$exception_name = get_class($e);
				log_info( "system",  "例外[$exception_name]をcatchしました。", __FILE__, __LINE__ );
				$transition_key = "exception";
				// モジュールコンテキストに例外内容をコピー
				$context->set( "exception", $e );
			}
	*/

			log_info( "system",  "モジュール[$module_name]を実行しました。遷移先=[$transition_key]", __FILE__, __LINE__ );

			return $transition_key;
/*		}
		catch ( Exception $e ){
			throw new charcoal_ModuleGraphNodeException( $this, "ModuleGraphNode#execute() failed", $e );
		}*/
	}
}
