<?php
/**
 * File containing the ezcWorkflowNode class.
 *
 * This class provides basic facilities for workflow nodes
 * such as constraints for in and output nodes and methods
 * for identifying and execution of the node.
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 Workflow
 * @version //autogen//
 * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
 */

/**
 * Abstract base class for workflow nodes.
 *
 * All workflow nodes must extend this class.
 *
 * @package Workflow
 * @version //autogen//
 * @mainclass
 */
abstract class ezcWorkflowNode implements ezcWorkflowVisitable
{
    /**
     * The node is waiting to be activated.
     */
    const WAITING_FOR_ACTIVATION = 0;

    /**
     * The node is activated and waiting to be executed.
     */
    const WAITING_FOR_EXECUTION = 1;

    /**
     * Unique ID of this node.
     *
     * Only available when the workflow this node belongs to has been loaded
     * from or saved to the data storage.
     *
     * @var integer
     */
    protected $id = false;

    /**
     * The incoming nodes of this node.
     *
     * @var array( int => ezcWorkflowNode )
     */
    protected $inNodes = array();

    /**
     * The outgoing nodes of this node.
     *
     * @var array( int => ezcWorkflowNode )
     */
    protected $outNodes = array();

    /**
     * Constraint: The minimum number of incoming nodes this node has to have
     * to be valid. Set to false to disable this constraint.
     *
     * @var integer
     */
    protected $minInNodes = 1;

    /**
     * Constraint: The maximum number of incoming nodes this node has to have
     * to be valid. Set to false to disable this constraint.
     *
     * @var integer
     */
    protected $maxInNodes = 1;

    /**
     * Constraint: The minimum number of outgoing nodes this node has to have
     * to be valid. Set to false to disable this constraint.
     *
     * @var integer
     */
    protected $minOutNodes = 1;

    /**
     * Constraint: The maximum number of outgoing nodes this node has to have
     * to be valid. Set to false to disable this constraint.
     *
     * @var integer
     */
    protected $maxOutNodes = 1;

    /**
     * The number of incoming nodes.
     *
     * @var integer
     */
    protected $numInNodes = 0;

    /**
     * The number of outgoing nodes.
     *
     * @var integer
     */
    protected $numOutNodes = 0;

    /**
     * The configuration of this node.
     *
     * The configuration is a structured (hash) array with the
     * various options of the implemented node.
     *
     * This functionality is implemented as an array to make it possible
     * to have the storage engines unaware of the node classes.
     *
     * @var array( config key => config value )
     */
    protected $configuration;

    /**
     * The state of this node.
     *
     * @var integer
     */
    protected $activationState;

    /**
     * The node(s) that activated this node.
     *
     * @var ezcWorkflowNode[]
     */
    protected $activatedFrom = array();

    /**
     * The state of this node.
     *
     * @var mixed
     */
    protected $state = null;

    /**
     * The id of the thread this node is executing in.
     *
     * @var integer
     */
    protected $threadId = null;

    /**
     * Flag that indicates whether an add*Node() or remove*Node()
     * call is internal. This is necessary to avoid unlimited loops. 
     *
     * @var boolean
     */
    protected static $internalCall = false;

    /**
     * Constructs a new node with the configuration $configuration.
     *
     * The configuration is a structured (hash) array. Implementations
     * must pass their complete configuration on to this object. We have
     * chosen to use structured arrays for the configuration since it
     * simplifies the process of creating new node types and storing workflows.
     *
     * @param mixed $configuration
     */
    public function __construct( $configuration = null )
    {
        if ( $configuration !== null )
        {
            $this->configuration = $configuration;
        }

        $this->initState();
    }

    /**
     * Adds a node to the incoming nodes of this node.
     *
     * Automatically adds $node to the workflow and adds
     * this node as an out node of $node.
     *
     * @param  ezcWorkflowNode $node The node that is to be added as incoming node.
     * @throws ezcWorkflowInvalidWorkflowException if the operation violates the constraints of the nodes involved.
     * @return ezcWorkflowNode
     */
    public function addInNode( ezcWorkflowNode $node )
    {
        // Check whether the node is already an incoming node of this node.
        if ( ezcWorkflowUtil::findObject( $this->inNodes, $node ) === false )
        {
            // Add this node as an outgoing node to the other node.
            if ( !self::$internalCall )
            {
                self::$internalCall = true;
                $node->addOutNode( $this );
            }
            else
            {
                self::$internalCall = false;
            }

            // Add the other node as an incoming node to this node.
            $this->inNodes[] = $node;
            $this->numInNodes++;
        }

        return $this;
    }

    /**
     * Removes a node from the incoming nodes of this node.
     *
     * Automatically removes $this as an out node of $node.
     *
     * @param  ezcWorkflowNode $node The node that is to be removed as incoming node.
     * @throws ezcWorkflowInvalidWorkflowException if the operation violates the constraints of the nodes involved.
     * @return boolean
     */
    public function removeInNode( ezcWorkflowNode $node )
    {
        $index = ezcWorkflowUtil::findObject( $this->inNodes, $node );

        if ( $index !== false )
        {
            // Remove this node as an outgoing node from the other node.
            if ( !self::$internalCall )
            {
                self::$internalCall = true;
                $node->removeOutNode( $this );
            }
            else
            {
                self::$internalCall = false;
            }

            unset( $this->inNodes[$index] );
            $this->numInNodes--;

            return true;
        }

        return false;
    }

    /**
     * Adds a node to the outgoing nodes of this node.
     *
     * Automatically adds $node to the workflow and adds
     * this node as an in node of $node.
     *
     * @param  ezcWorkflowNode $node The node that is to be added as outgoing node.
     * @throws ezcWorkflowInvalidWorkflowException if the operation violates the constraints of the nodes involved.
     * @return ezcWorkflowNode
     */
    public function addOutNode( ezcWorkflowNode $node )
    {
        // Check whether the other node is already an outgoing node of this node.
        if ( ezcWorkflowUtil::findObject( $this->outNodes, $node ) === false )
        {
            // Add this node as an incoming node to the other node.
            if ( !self::$internalCall )
            {
                self::$internalCall = true;
                $node->addInNode( $this );
            }
            else
            {
                self::$internalCall = false;
            }

            // Add the other node as an outgoing node to this node.
            $this->outNodes[] = $node;
            $this->numOutNodes++;
        }

        return $this;
    }

    /**
     * Removes a node from the outgoing nodes of this node.
     *
     * Automatically removes $this as an in node of $node.
     *
     * @param  ezcWorkflowNode $node The node that is to be removed as outgoing node.
     * @throws ezcWorkflowInvalidWorkflowException if the operation violates the constraints of the nodes involved.
     * @return boolean
     */
    public function removeOutNode( ezcWorkflowNode $node )
    {
        $index = ezcWorkflowUtil::findObject( $this->outNodes, $node );

        if ( $index !== false )
        {
            // Remove this node as an incoming node from the other node.
            if ( !self::$internalCall )
            {
                self::$internalCall = true;
                $node->removeInNode( $this );
            }
            else
            {
                self::$internalCall = false;
            }

            unset( $this->outNodes[$index] );
            $this->numOutNodes--;

            return true;
        }

        return false;
    }

    /**
     * Returns the Id of this node.
     *
     * @return integer
     * @ignore
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Sets the Id of this node.
     *
     * @param int $id
     * @ignore
     */
    public function setId( $id )
    {
        $this->id = $id;
    }

    /**
     * Sets the activation state for this node.
     *
     * One of ezcWorkflowNode::WAITING_FOR_ACTIVATION or
     * ezcWorkflowNode::WAITING_FOR_EXECUTION.
     *
     * @param int $activationState
     * @ignore
     */
    public function setActivationState( $activationState )
    {
        if ( $activationState == self::WAITING_FOR_ACTIVATION ||
             $activationState == self::WAITING_FOR_EXECUTION )
        {
            $this->activationState = $activationState;
        }
    }

    /**
     * Returns the incoming nodes of this node.
     *
     * @return ezcWorkflowNode[]
     */
    public function getInNodes()
    {
        return $this->inNodes;
    }

    /**
     * Returns the outgoing nodes of this node.
     *
     * @return ezcWorkflowNode[]
     */
    public function getOutNodes()
    {
        return $this->outNodes;
    }

    /**
     * Returns the configuration of this node.
     *
     * @return mixed
     */
    public function getConfiguration()
    {
        return $this->configuration;
    }

    /**
     * Returns the state of this node.
     *
     * @return mixed
     * @ignore
     */
    public function getState()
    {
        return $this->state;
    }

    /**
     * Sets the state of this node.
     *
     * @param mixed $state
     * @ignore
     */
    public function setState( $state )
    {
        $this->state = $state;
    }

    /**
     * Returns the node(s) that activated this node.
     *
     * @return array
     * @ignore
     */
    public function getActivatedFrom()
    {
        return $this->activatedFrom;
    }

    /**
     * Sets the node(s) that activated this node.
     *
     * @param array $activatedFrom
     * @ignore
     */
    public function setActivatedFrom( array $activatedFrom )
    {
        $this->activatedFrom = $activatedFrom;
    }

    /**
     * Returns the id of the thread this node is executing in.
     *
     * @return integer
     * @ignore
     */
    public function getThreadId()
    {
        return $this->threadId;
    }

    /**
     * Sets the id of the thread this node is executing in.
     *
     * @param int $threadId
     * @ignore
     */
    public function setThreadId( $threadId )
    {
        $this->threadId = $threadId;
    }

    /**
     * Checks this node's constraints.
     *
     * The constraints checked are the minimum in nodes
     * maximum in nodes, minimum out nodes and maximum
     * out nodes.
     *
     * @throws ezcWorkflowInvalidWorkflowException if the constraints of this node are not met.
     */
    public function verify()
    {
        $type = str_replace( 'ezcWorkflowNode', '', get_class( $this ) );

        if ( $this->minInNodes !== false && $this->numInNodes < $this->minInNodes )
        {
            throw new ezcWorkflowInvalidWorkflowException(
              sprintf(
                'Node of type "%s" has less incoming nodes than required.',
                $type
              )
            );
        }

        if ( $this->maxInNodes !== false && $this->numInNodes > $this->maxInNodes )
        {
            throw new ezcWorkflowInvalidWorkflowException(
              sprintf(
                'Node of type "%s" has more incoming nodes than allowed.',
                $type
              )
            );
        }

        if ( $this->minOutNodes !== false && $this->numOutNodes < $this->minOutNodes )
        {
            throw new ezcWorkflowInvalidWorkflowException(
              sprintf(
                'Node of type "%s" has less outgoing nodes than required.',
                $type
              )
            );
        }

        if ( $this->maxOutNodes !== false && $this->numOutNodes > $this->maxOutNodes )
        {
            throw new ezcWorkflowInvalidWorkflowException(
              sprintf(
                'Node of type "%s" has more outgoing nodes than allowed.',
                $type
              )
            );
        }
    }

    /**
     * Reimplementation of accept() calls accept on all out nodes.
     *
     * @param ezcWorkflowVisitor $visitor
     */
    public function accept( ezcWorkflowVisitor $visitor )
    {
        if ( $visitor->visit( $this ) )
        {
            foreach ( $this->outNodes as $outNode )
            {
                $outNode->accept( $visitor );
            }
        }
    }

    /**
     * Activate this node in the execution environment $execution.
     *
     * $activatedFrom is the node that activated this node and $threadId is
     * threadId of the thread the node should be activated in.
     *
     * This method is called by other nodes and/or the execution environment
     * depending on the workflow.
     *
     * @param ezcWorkflowExecution $execution
     * @param ezcWorkflowNode $activatedFrom
     * @param int $threadId
     * @ignore
     */
    public function activate( ezcWorkflowExecution $execution, ezcWorkflowNode $activatedFrom = null, $threadId = 0 )
    {
        if ( $this->activationState === self::WAITING_FOR_ACTIVATION )
        {
            $this->activationState = self::WAITING_FOR_EXECUTION;
            $this->setThreadId( $threadId );

            if ( $activatedFrom !== null )
            {
                $this->activatedFrom[] = get_class( $activatedFrom );
            }

            $execution->activate( $this );
        }
    }

    /**
     * Convenience method for activating an (outgoing) node.
     *
     * @param ezcWorkflowExecution $execution
     * @param ezcWorkflowNode $node
     */
    protected function activateNode( ezcWorkflowExecution $execution, ezcWorkflowNode $node )
    {
        $node->activate( $execution, $this, $this->getThreadId() );
    }

    /**
     * Returns true if this node is ready for execution
     * and false if it is not.
     *
     * @return boolean
     * @ignore
     */
    public function isExecutable()
    {
        return $this->activationState === self::WAITING_FOR_EXECUTION;
    }

    /**
     * Executes and performs the workflow duties of this node
     * and returns true if the node completed execution.
     *
     * Implementations of ezcWorkflowNode should reimplement this method.
     *
     * This method is called automatically by the workflow execution
     * environment and should not be called directly.
     *
     * The default implementation resets the activation state of the
     * node.
     *
     * @param  ezcWorkflowExecution $execution
     * @return boolean true when the node finished execution,
     *                 and false otherwise
     * @ignore
     */
    public function execute( ezcWorkflowExecution $execution )
    {
        $this->activationState = self::WAITING_FOR_ACTIVATION;
        $this->activatedFrom = array();
        $this->threadId = null;

        return true;
    }

    /**
     * Generate node configuration from XML representation.
     *
     * @param DOMElement $element
     * @ignore
     */
    public static function configurationFromXML( DOMElement $element )
    {
    }

    /**
     * Generate XML representation of this node's configuration.
     *
     * @param DOMElement $element
     * @ignore
     */
    public function configurationToXML( DOMElement $element )
    {
    }

    /**
     * Returns a textual representation of this node.
     *
     * @return string
     * @ignore
     */
    public function __toString()
    {
        $type   = str_replace( 'ezcWorkflowNode', '', get_class( $this ) );
        $max    = strlen( $type );
        $string = '';

        for ( $i = 0; $i < $max; $i++ )
        {
            if ( $i > 0 && ord( $type[$i] ) >= 65 && ord( $type[$i] ) <= 90 )
            {
                $string .= ' ';
            }

            $string .= $type[$i];
        }

        return $string;
    }

    /**
     * Initializes the state of this node.
     *
     * @ignore
     */
    public function initState()
    {
        $this->activatedFrom = array();
        $this->state         = null;
        $this->threadId      = null;

        $this->setActivationState( self::WAITING_FOR_ACTIVATION );
    }
}
?>
