Author: sb
Date: Mon Jan 21 17:04:16 2008
New Revision: 7215

Log:
- Implement the Cancel Case workflow pattern.

Added:
    trunk/Workflow/src/interfaces/rollbackable_service_object.php
      - copied, changed from r7197, 
trunk/Workflow/src/interfaces/service_object.php
    trunk/Workflow/src/nodes/cancel.php
      - copied, changed from r7197, trunk/Workflow/src/nodes/end.php
    
trunk/Workflow/tests/data/ParallelSplitActionActionCancelCaseSynchronization.dot
   (with props)
    
trunk/Workflow/tests/data/ParallelSplitActionActionCancelCaseSynchronization_1.xml
   (with props)
    
trunk/Workflow/tests/data/ParallelSplitCancelCaseActionActionSynchronization.dot
   (with props)
    
trunk/Workflow/tests/data/ParallelSplitCancelCaseActionActionSynchronization_1.xml
   (with props)
    
trunk/WorkflowEventLogTiein/tests/data/ParallelSplitActionActionCancelCaseSynchronization.log
   (with props)
    
trunk/WorkflowEventLogTiein/tests/data/ParallelSplitCancelCaseActionActionSynchronization.log
   (with props)
    
trunk/WorkflowEventLogTiein/tests/data/ParallelSplitSynchronizationCancelCase.log
   (with props)
Modified:
    trunk/Workflow/ChangeLog
    trunk/Workflow/src/interfaces/execution.php
    trunk/Workflow/src/nodes/action.php
    trunk/Workflow/src/workflow_autoload.php
    trunk/Workflow/tests/case.php
    trunk/Workflow/tests/definition_xml_test.php
    trunk/Workflow/tests/execution_test.php
    trunk/Workflow/tests/visitor_visualization_test.php
    trunk/WorkflowDatabaseTiein/ChangeLog
    trunk/WorkflowDatabaseTiein/src/execution.php
    trunk/WorkflowEventLogTiein/tests/listener_test.php

Modified: trunk/Workflow/ChangeLog
==============================================================================
--- trunk/Workflow/ChangeLog [iso-8859-1] (original)
+++ trunk/Workflow/ChangeLog [iso-8859-1] Mon Jan 21 17:04:16 2008
@@ -1,3 +1,5 @@
+- Implemented issue #10941: Support for the Cancel Case workflow pattern.
+
 - Implemented issue #12404: Separate file i/o from XML processing in
   ezcWorkflowDefinitionStorageXml.
 

Modified: trunk/Workflow/src/interfaces/execution.php
==============================================================================
--- trunk/Workflow/src/interfaces/execution.php [iso-8859-1] (original)
+++ trunk/Workflow/src/interfaces/execution.php [iso-8859-1] Mon Jan 21 
17:04:16 2008
@@ -69,6 +69,14 @@
     protected $numActivatedEndNodes = 0;
 
     /**
+     * Rollbackable service objects that have been executed
+     * in the current execution loop.
+     *
+     * @var array
+     */
+    protected $rollbackableServiceObjects = array();
+
+    /**
      * Nodes of the workflow that started a new thread of execution.
      *
      * @var array
@@ -81,6 +89,11 @@
      * @var integer
      */
     protected $nextThreadId = 0;
+
+    /**
+     * @var bool
+     */
+    protected $cancelled;
 
     /**
      * @var bool
@@ -221,6 +234,7 @@
             );
         }
 
+        $this->cancelled = false;
         $this->ended     = false;
         $this->resumed   = false;
         $this->suspended = false;
@@ -266,6 +280,7 @@
      */
     public function suspend()
     {
+        $this->cancelled = false;
         $this->ended     = false;
         $this->resumed   = false;
         $this->suspended = true;
@@ -318,6 +333,7 @@
             );
         }
 
+        $this->cancelled = false;
         $this->ended     = false;
         $this->resumed   = true;
         $this->suspended = false;
@@ -370,6 +386,41 @@
     }
 
     /**
+     * Cancels workflow execution with the node $endNode.
+     *
+     * @param ezcWorkflowNodeEnd $endNode
+     * @ignore
+     */
+    public function cancel( ezcWorkflowNodeEnd $endNode )
+    {
+        $this->activatedNodes    = array();
+        $this->cancelled         = true;
+        $this->numActivatedNodes = 0;
+
+        foreach ( $this->rollbackableServiceObjects as $object )
+        {
+            $result = $object['object']->rollback( $this );
+
+            $this->notifyListeners(
+              sprintf(
+                '%s back service object "%s" of node #%d for instance #%d ' .
+                'of workflow "%s" (version %d).',
+
+                $result ? 'Rolled' : 'Could not roll',
+                get_class( $object['object'] ),
+                $object['node']->getId(),
+                $this->id,
+                $this->workflow->name,
+                $this->workflow->version
+              ),
+              ezcWorkflowExecutionListener::DEBUG
+            );
+        }
+
+        $this->end( $endNode );
+    }
+
+    /**
      * Ends workflow execution with the node $endNode.
      *
      * End nodes must call this method to end the execution.
@@ -400,12 +451,16 @@
           ezcWorkflowExecutionListener::DEBUG
         );
 
-        $this->endThread( $endNode->getThreadId() );
+        if ( !$this->cancelled )
+        {
+            $this->endThread( $endNode->getThreadId() );
+        }
 
         $this->notifyListeners(
           sprintf(
-            'Ended execution #%d of workflow "%s" (version %d).',
-
+            '%s execution #%d of workflow "%s" (version %d).',
+
+            $this->cancelled ? 'Cancelled' : 'Ended',
             $this->id,
             $this->workflow->name,
             $this->workflow->version
@@ -421,8 +476,7 @@
      */
     protected function execute()
     {
-        // Try to execute nodes until while there are executable nodes on the
-        // stack of activated nodes.
+        // Try to execute nodes while there are executable nodes on the stack.
         do
         {
             // Flag that indicates whether a node has been executed during the
@@ -438,7 +492,8 @@
                 {
                     // The current node is an end node but there are still
                     // activated nodes on the stack.
-                    if ( $node instanceof ezcWorkflowNodeEnd &&
+                    if ( $node  instanceof ezcWorkflowNodeEnd &&
+                         !$node instanceof ezcWorkflowNodeCancel &&
                          $this->numActivatedNodes != 
$this->numActivatedEndNodes )
                     {
                         continue;
@@ -543,6 +598,20 @@
     /**
      * Adds a variable that an (input) node is waiting for.
      *
+     * @param ezcWorkflowNodeAction                $node
+     * @param ezcWorkflowRollbackableServiceObject $object
+     * @ignore
+     */
+    public function addRollbackableServiceObject( ezcWorkflowNodeAction $node, 
ezcWorkflowRollbackableServiceObject $object )
+    {
+        $this->rollbackableServiceObjects[] = array(
+          'node'   => $node, 'object' => $object
+        );
+    }
+
+    /**
+     * Adds a variable that an (input) node is waiting for.
+     *
      * @param ezcWorkflowNode $node
      * @param string $variableName
      * @param ezcWorkflowCondition $condition
@@ -888,6 +957,16 @@
     }
 
     /**
+     * Returns true when the workflow execution has been cancelled.
+     *
+     * @return bool
+     */
+    public function isCancelled()
+    {
+        return $this->cancelled;
+    }
+
+    /**
      * Returns true when the workflow execution has ended.
      *
      * @return bool

Copied: trunk/Workflow/src/interfaces/rollbackable_service_object.php (from 
r7197, trunk/Workflow/src/interfaces/service_object.php)
==============================================================================
--- trunk/Workflow/src/interfaces/service_object.php [iso-8859-1] (original)
+++ trunk/Workflow/src/interfaces/rollbackable_service_object.php [iso-8859-1] 
Mon Jan 21 17:04:16 2008
@@ -1,6 +1,6 @@
 <?php
 /**
- * File containing the ezcWorkflowServiceObject interface.
+ * File containing the ezcWorkflowRollbackableServiceObject interface.
  *
  * @package Workflow
  * @version //autogen//
@@ -9,34 +9,23 @@
  */
 
 /**
- * Interface for service objects that can be attached to
- * ezcWorkflowNodeAction nodes.
+ * Interface for service objects for which the action can be rolled back
+ * in case the workflow execution is cancelled.
  *
  * @package Workflow
  * @version //autogen//
  */
-interface ezcWorkflowServiceObject
+interface ezcWorkflowRollbackableServiceObject extends ezcWorkflowServiceObject
 {
     /**
-     * Executes the business logic of this service object.
+     * Rolls back the business logic of this service object.
      *
-     * Implementations can return true if the execution of the
-     * service object was successful to resume the workflow and activate
-     * the next node.
-     *
-     * Returning false will cause the workflow to be suspended and the service
-     * object to be executed again on a later invokation.
+     * Implementors should return true when the rollback was successful
+     * and false when it was not.
      *
      * @param  ezcWorkflowExecution $execution
      * @return boolean
      */
-    public function execute( ezcWorkflowExecution $execution );
-
-    /**
-     * Returns a textual representation of this service object.
-     *
-     * @return string
-     */
-    public function __toString();
+    public function rollback( ezcWorkflowExecution $execution );
 }
 ?>

Modified: trunk/Workflow/src/nodes/action.php
==============================================================================
--- trunk/Workflow/src/nodes/action.php [iso-8859-1] (original)
+++ trunk/Workflow/src/nodes/action.php [iso-8859-1] Mon Jan 21 17:04:16 2008
@@ -107,7 +107,13 @@
      */
     public function execute( ezcWorkflowExecution $execution )
     {
-        $object   = $this->createObject();
+        $object = $this->createObject();
+
+        if ( $object instanceof ezcWorkflowRollbackableServiceObject )
+        {
+            $execution->addRollbackableServiceObject( $this, $object );
+        }
+
         $finished = $object->execute( $execution );
 
         // Execution of the Service Object has finished.

Copied: trunk/Workflow/src/nodes/cancel.php (from r7197, 
trunk/Workflow/src/nodes/end.php)
==============================================================================
--- trunk/Workflow/src/nodes/end.php [iso-8859-1] (original)
+++ trunk/Workflow/src/nodes/cancel.php [iso-8859-1] Mon Jan 21 17:04:16 2008
@@ -1,6 +1,6 @@
 <?php
 /**
- * File containing the ezcWorkflowNodeEnd class.
+ * File containing the ezcWorkflowNodeCancel class.
  *
  * @package Workflow
  * @version //autogen//
@@ -9,57 +9,45 @@
  */
 
 /**
- * An object of the ezcWorkflowNodeEnd class represents an end node of a 
workflow.
+ * This node implements the Cancel Case workflow pattern.
  *
- * A workflow must have at least one end node. The execution of the workflow 
ends
- * when an end node is reached.
- * Creating an object of the ezcWorkflow class automatically creates a default 
end node for the new
- * workflow. It can be accessed through the getEndNode() method.
+ * A complete process instance is removed. This includes currently executing
+ * tasks, those which may execute at some future time and all sub-processes.
+ * The process instance is recorded as having completed unsuccessfully.
  *
  * Incoming nodes: 1
- * Outgoing nodes: 0
- *
- * Example:
- * <code>
- * $workflow = new ezcWorkflow( 'Test' );
- *  // build up your workflow here... result in $node
- * $node = ....
- * $workflow->startNode->addOutNode( ....some other node here .. );
- * $node->addOutNode( $workflow->endNode );
- * </code>
+ * Outgoing nodes: 0..1
  *
  * @package Workflow
  * @version //autogen//
  */
-class ezcWorkflowNodeEnd extends ezcWorkflowNode
+class ezcWorkflowNodeCancel extends ezcWorkflowNodeEnd
 {
     /**
      * Constraint: The minimum number of outgoing nodes this node has to have
-     * to be valid.
+     * to be valid. Set to false to disable this constraint.
      *
      * @var integer
      */
-    protected $minOutNodes = 0;
+    protected $minOutNodes = false;
 
     /**
      * Constraint: The maximum number of outgoing nodes this node has to have
-     * to be valid.
+     * to be valid. Set to false to disable this constraint.
      *
      * @var integer
      */
-    protected $maxOutNodes = 0;
+    protected $maxOutNodes = false;
 
     /**
-     * Ends the execution of this workflow.
+     * Cancels the execution of this workflow.
      *
      * @param ezcWorkflowExecution $execution
      * @ignore
      */
     public function execute( ezcWorkflowExecution $execution )
     {
-        $execution->end( $this );
-
-        return parent::execute( $execution );
+        $execution->cancel( $this );
     }
 }
 ?>

Modified: trunk/Workflow/src/workflow_autoload.php
==============================================================================
--- trunk/Workflow/src/workflow_autoload.php [iso-8859-1] (original)
+++ trunk/Workflow/src/workflow_autoload.php [iso-8859-1] Mon Jan 21 17:04:16 
2008
@@ -57,6 +57,7 @@
     'ezcWorkflowNodeAction'                    => 'Workflow/nodes/action.php',
     'ezcWorkflowNodeDiscriminator'             => 
'Workflow/nodes/control_flow/discriminator.php',
     'ezcWorkflowNodeEnd'                       => 'Workflow/nodes/end.php',
+    'ezcWorkflowNodeCancel'                    => 'Workflow/nodes/cancel.php',
     'ezcWorkflowNodeExclusiveChoice'           => 
'Workflow/nodes/control_flow/exclusive_choice.php',
     'ezcWorkflowNodeInput'                     => 
'Workflow/nodes/variables/input.php',
     'ezcWorkflowNodeLoop'                      => 
'Workflow/nodes/control_flow/loop.php',
@@ -75,6 +76,7 @@
     'ezcWorkflowNodeVariableSub'               => 
'Workflow/nodes/variables/sub.php',
     'ezcWorkflowNodeVariableUnset'             => 
'Workflow/nodes/variables/unset.php',
     'ezcWorkflowServiceObject'                 => 
'Workflow/interfaces/service_object.php',
+    'ezcWorkflowRollbackableServiceObject'     => 
'Workflow/interfaces/rollbackable_service_object.php',
     'ezcWorkflowUtil'                          => 'Workflow/util.php',
     'ezcWorkflowVariableHandler'               => 
'Workflow/interfaces/variable_handler.php',
     'ezcWorkflowVisitorNodeCollector'          => 
'Workflow/visitors/node_collector.php',

Modified: trunk/Workflow/tests/case.php
==============================================================================
--- trunk/Workflow/tests/case.php [iso-8859-1] (original)
+++ trunk/Workflow/tests/case.php [iso-8859-1] Mon Jan 21 17:04:16 2008
@@ -33,7 +33,7 @@
 
         if ( !class_exists( 'ServiceObject', false ) )
         {
-            $this->getMock( 'ezcWorkflowServiceObject', array(), array(), 
'ServiceObject' );
+            $this->getMock( 'ezcWorkflowRollbackableServiceObject', array(), 
array(), 'ServiceObject' );
         }
     }
 
@@ -690,6 +690,51 @@
                   ->addConditionalOutNode( $outerBreak, $this->endNode );
     }
 
+    protected function setUpCancelCase( $order )
+    {
+        if ( $order == 'first' )
+        {
+            $workflowName = 
'ParallelSplitCancelCaseActionActionSynchronization';
+        }
+        else
+        {
+            $workflowName = 
'ParallelSplitActionActionCancelCaseSynchronization';
+        }
+
+        $this->workflow = new ezcWorkflow( $workflowName );
+        $this->setUpReferences();
+
+        $this->branchNode = new ezcWorkflowNodeParallelSplit;
+        $cancelNode       = new ezcWorkflowNodeCancel;
+        $actionNodeA      = new ezcWorkflowNodeAction( 'ServiceObject' );
+        $actionNodeB      = new ezcWorkflowNodeAction( 'ServiceObject' );
+        $synchronization  = new ezcWorkflowNodeSynchronization;
+
+        if ( $order == 'first' )
+        {
+            $this->branchNode->addOutNode( $cancelNode );
+            $this->branchNode->addOutNode( $actionNodeA );
+            $this->branchNode->addOutNode( $actionNodeB );
+
+            $synchronization->addInNode( $cancelNode );
+            $synchronization->addInNode( $actionNodeA );
+            $synchronization->addInNode( $actionNodeB );
+        }
+        else
+        {
+            $this->branchNode->addOutNode( $actionNodeA );
+            $this->branchNode->addOutNode( $actionNodeB );
+            $this->branchNode->addOutNode( $cancelNode );
+
+            $synchronization->addInNode( $actionNodeA );
+            $synchronization->addInNode( $actionNodeB );
+            $synchronization->addInNode( $cancelNode );
+        }
+
+        $this->startNode->addOutNode( $this->branchNode );
+        $this->endNode->addInNode( $synchronization );
+    }
+
     protected function setUpReferences()
     {
         $this->startNode = $this->workflow->startNode;

Added: 
trunk/Workflow/tests/data/ParallelSplitActionActionCancelCaseSynchronization.dot
==============================================================================
--- 
trunk/Workflow/tests/data/ParallelSplitActionActionCancelCaseSynchronization.dot
 (added)
+++ 
trunk/Workflow/tests/data/ParallelSplitActionActionCancelCaseSynchronization.dot
 [iso-8859-1] Mon Jan 21 17:04:16 2008
@@ -1,0 +1,18 @@
+digraph ParallelSplitActionActionCancelCaseSynchronization {
+node1 [label="Start"]
+node2 [label="Parallel Split"]
+node3 [label=""]
+node4 [label="Synchronization"]
+node5 [label="End"]
+node6 [label=""]
+node7 [label="Cancel"]
+
+node1 -> node2
+node2 -> node3
+node2 -> node6
+node2 -> node7
+node3 -> node4
+node4 -> node5
+node6 -> node4
+node7 -> node4
+}

Propchange: 
trunk/Workflow/tests/data/ParallelSplitActionActionCancelCaseSynchronization.dot
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
trunk/Workflow/tests/data/ParallelSplitActionActionCancelCaseSynchronization_1.xml
==============================================================================
--- 
trunk/Workflow/tests/data/ParallelSplitActionActionCancelCaseSynchronization_1.xml
 (added)
+++ 
trunk/Workflow/tests/data/ParallelSplitActionActionCancelCaseSynchronization_1.xml
 [iso-8859-1] Mon Jan 21 17:04:16 2008
@@ -1,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<workflow name="ParallelSplitActionActionCancelCaseSynchronization" 
version="1">
+  <node id="1" type="Start">
+    <outNode id="2"/>
+  </node>
+  <node id="2" type="ParallelSplit">
+    <outNode id="3"/>
+    <outNode id="6"/>
+    <outNode id="7"/>
+  </node>
+  <node id="3" type="Action" serviceObjectClass="ServiceObject">
+    <outNode id="4"/>
+  </node>
+  <node id="4" type="Synchronization">
+    <outNode id="5"/>
+  </node>
+  <node id="5" type="End"/>
+  <node id="6" type="Action" serviceObjectClass="ServiceObject">
+    <outNode id="4"/>
+  </node>
+  <node id="7" type="Cancel">
+    <outNode id="4"/>
+  </node>
+</workflow>

Propchange: 
trunk/Workflow/tests/data/ParallelSplitActionActionCancelCaseSynchronization_1.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
trunk/Workflow/tests/data/ParallelSplitCancelCaseActionActionSynchronization.dot
==============================================================================
--- 
trunk/Workflow/tests/data/ParallelSplitCancelCaseActionActionSynchronization.dot
 (added)
+++ 
trunk/Workflow/tests/data/ParallelSplitCancelCaseActionActionSynchronization.dot
 [iso-8859-1] Mon Jan 21 17:04:16 2008
@@ -1,0 +1,18 @@
+digraph ParallelSplitCancelCaseActionActionSynchronization {
+node1 [label="Start"]
+node2 [label="Parallel Split"]
+node3 [label="Cancel"]
+node4 [label="Synchronization"]
+node5 [label="End"]
+node6 [label=""]
+node7 [label=""]
+
+node1 -> node2
+node2 -> node3
+node2 -> node6
+node2 -> node7
+node3 -> node4
+node4 -> node5
+node6 -> node4
+node7 -> node4
+}

Propchange: 
trunk/Workflow/tests/data/ParallelSplitCancelCaseActionActionSynchronization.dot
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
trunk/Workflow/tests/data/ParallelSplitCancelCaseActionActionSynchronization_1.xml
==============================================================================
--- 
trunk/Workflow/tests/data/ParallelSplitCancelCaseActionActionSynchronization_1.xml
 (added)
+++ 
trunk/Workflow/tests/data/ParallelSplitCancelCaseActionActionSynchronization_1.xml
 [iso-8859-1] Mon Jan 21 17:04:16 2008
@@ -1,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<workflow name="ParallelSplitCancelCaseActionActionSynchronization" 
version="1">
+  <node id="1" type="Start">
+    <outNode id="2"/>
+  </node>
+  <node id="2" type="ParallelSplit">
+    <outNode id="3"/>
+    <outNode id="6"/>
+    <outNode id="7"/>
+  </node>
+  <node id="3" type="Cancel">
+    <outNode id="4"/>
+  </node>
+  <node id="4" type="Synchronization">
+    <outNode id="5"/>
+  </node>
+  <node id="5" type="End"/>
+  <node id="6" type="Action" serviceObjectClass="ServiceObject">
+    <outNode id="4"/>
+  </node>
+  <node id="7" type="Action" serviceObjectClass="ServiceObject">
+    <outNode id="4"/>
+  </node>
+</workflow>

Propchange: 
trunk/Workflow/tests/data/ParallelSplitCancelCaseActionActionSynchronization_1.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: trunk/Workflow/tests/definition_xml_test.php
==============================================================================
--- trunk/Workflow/tests/definition_xml_test.php [iso-8859-1] (original)
+++ trunk/Workflow/tests/definition_xml_test.php [iso-8859-1] Mon Jan 21 
17:04:16 2008
@@ -274,6 +274,28 @@
         );
     }
 
+    public function 
testSaveParallelSplitCancelCaseActionActionSynchronization()
+    {
+        $this->setUpCancelCase( 'first' );
+        $this->definition->save( $this->workflow );
+
+        $this->assertEquals(
+          $this->readExpected( 
'ParallelSplitCancelCaseActionActionSynchronization' ),
+          $this->readActual( 
'ParallelSplitCancelCaseActionActionSynchronization' )
+        );
+    }
+
+    public function 
testSaveParallelSplitActionActionCancelCaseSynchronization()
+    {
+        $this->setUpCancelCase( 'last' );
+        $this->definition->save( $this->workflow );
+
+        $this->assertEquals(
+          $this->readExpected( 
'ParallelSplitActionActionCancelCaseSynchronization' ),
+          $this->readActual( 
'ParallelSplitActionActionCancelCaseSynchronization' )
+        );
+    }
+
     public function testLoadStartEnd()
     {
         $this->workflow = $this->definition->loadByName( 'StartEnd' );
@@ -512,6 +534,28 @@
         $this->assertEquals(
           $this->readExpected( 'NestedLoops' ),
           $this->readActual( 'NestedLoops' )
+        );
+    }
+
+    public function 
testLoadParallelSplitCancelCaseActionActionSynchronization()
+    {
+        $this->workflow = $this->definition->loadByName( 
'ParallelSplitCancelCaseActionActionSynchronization' );
+        $this->definition->save( $this->workflow );
+
+        $this->assertEquals(
+          $this->readExpected( 
'ParallelSplitCancelCaseActionActionSynchronization' ),
+          $this->readActual( 
'ParallelSplitCancelCaseActionActionSynchronization' )
+        );
+    }
+
+    public function 
testLoadParallelSplitActionActionCancelCaseSynchronization()
+    {
+        $this->workflow = $this->definition->loadByName( 
'ParallelSplitActionActionCancelCaseSynchronization' );
+        $this->definition->save( $this->workflow );
+
+        $this->assertEquals(
+          $this->readExpected( 
'ParallelSplitActionActionCancelCaseSynchronization' ),
+          $this->readActual( 
'ParallelSplitActionActionCancelCaseSynchronization' )
         );
     }
 

Modified: trunk/Workflow/tests/execution_test.php
==============================================================================
--- trunk/Workflow/tests/execution_test.php [iso-8859-1] (original)
+++ trunk/Workflow/tests/execution_test.php [iso-8859-1] Mon Jan 21 17:04:16 
2008
@@ -35,6 +35,7 @@
         $this->execution->workflow = $this->workflow;
         $this->execution->start();
 
+        $this->assertFalse( $this->execution->isCancelled() );
         $this->assertTrue( $this->execution->hasEnded() );
         $this->assertFalse( $this->execution->isResumed() );
         $this->assertFalse( $this->execution->isSuspended() );
@@ -46,6 +47,7 @@
         $this->execution->workflow = $this->workflow;
         $this->execution->start();
 
+        $this->assertFalse( $this->execution->isCancelled() );
         $this->assertTrue( $this->execution->hasEnded() );
         $this->assertFalse( $this->execution->isResumed() );
         $this->assertFalse( $this->execution->isSuspended() );
@@ -59,6 +61,7 @@
         $this->execution->setInputVariable( 'variable', 'value' );
         $this->execution->start();
 
+        $this->assertFalse( $this->execution->isCancelled() );
         $this->assertTrue( $this->execution->hasEnded() );
         $this->assertFalse( $this->execution->isResumed() );
         $this->assertFalse( $this->execution->isSuspended() );
@@ -81,6 +84,7 @@
             $this->assertArrayHasKey( 'variable', $e->errors );
             $this->assertContains( 'is string', $e->errors );
 
+            $this->assertFalse( $this->execution->isCancelled() );
             $this->assertFalse( $this->execution->hasEnded() );
             $this->assertTrue( $this->execution->isResumed() );
             $this->assertFalse( $this->execution->isSuspended() );
@@ -178,6 +182,7 @@
         $this->execution->workflow = $this->workflow;
         $this->execution->start();
 
+        $this->assertFalse( $this->execution->isCancelled() );
         $this->assertTrue( $this->execution->hasEnded() );
         $this->assertFalse( $this->execution->isResumed() );
         $this->assertFalse( $this->execution->isSuspended() );
@@ -189,6 +194,7 @@
         $this->execution->workflow = $this->workflow;
         $this->execution->start();
 
+        $this->assertFalse( $this->execution->isCancelled() );
         $this->assertTrue( $this->execution->hasEnded() );
         $this->assertFalse( $this->execution->isResumed() );
         $this->assertFalse( $this->execution->isSuspended() );
@@ -200,6 +206,7 @@
         $this->execution->workflow = $this->workflow;
         $this->execution->start();
 
+        $this->assertFalse( $this->execution->isCancelled() );
         $this->assertTrue( $this->execution->hasEnded() );
         $this->assertFalse( $this->execution->isResumed() );
         $this->assertFalse( $this->execution->isSuspended() );
@@ -211,6 +218,7 @@
         $this->execution->workflow = $this->workflow;
         $this->execution->start();
 
+        $this->assertFalse( $this->execution->isCancelled() );
         $this->assertTrue( $this->execution->hasEnded() );
         $this->assertFalse( $this->execution->isResumed() );
         $this->assertFalse( $this->execution->isSuspended() );
@@ -223,6 +231,7 @@
         $this->execution->workflow = $this->workflow;
         $this->execution->start();
 
+        $this->assertFalse( $this->execution->isCancelled() );
         $this->assertTrue( $this->execution->hasEnded() );
         $this->assertFalse( $this->execution->isResumed() );
         $this->assertFalse( $this->execution->isSuspended() );
@@ -269,6 +278,7 @@
         $this->execution->workflow = $this->workflow;
         $this->execution->start();
 
+        $this->assertFalse( $this->execution->isCancelled() );
         $this->assertTrue( $this->execution->hasEnded() );
         $this->assertFalse( $this->execution->isResumed() );
         $this->assertFalse( $this->execution->isSuspended() );
@@ -281,6 +291,7 @@
         $this->execution->workflow = $this->workflow;
         $this->execution->start();
 
+        $this->assertFalse( $this->execution->isCancelled() );
         $this->assertTrue( $this->execution->hasEnded() );
         $this->assertFalse( $this->execution->isResumed() );
         $this->assertFalse( $this->execution->isSuspended() );
@@ -293,6 +304,7 @@
         $this->execution->setVariables( array( 'foo' => 'bar', 'bar' => 'foo' 
) );
         $this->execution->start();
 
+        $this->assertFalse( $this->execution->isCancelled() );
         $this->assertTrue( $this->execution->hasEnded() );
         $this->assertFalse( $this->execution->isResumed() );
         $this->assertFalse( $this->execution->isSuspended() );
@@ -327,6 +339,7 @@
         $this->execution->setVariables( array( 'condition' => true ) );
         $this->execution->start();
 
+        $this->assertFalse( $this->execution->isCancelled() );
         $this->assertTrue( $this->execution->hasEnded() );
         $this->assertFalse( $this->execution->isResumed() );
         $this->assertFalse( $this->execution->isSuspended() );
@@ -339,6 +352,7 @@
         $this->execution->setVariables( array( 'condition' => false ) );
         $this->execution->start();
 
+        $this->assertFalse( $this->execution->isCancelled() );
         $this->assertTrue( $this->execution->hasEnded() );
         $this->assertFalse( $this->execution->isResumed() );
         $this->assertFalse( $this->execution->isSuspended() );
@@ -397,6 +411,7 @@
         $this->execution->setVariables( array( 'condition' => true ) );
         $this->execution->start();
 
+        $this->assertFalse( $this->execution->isCancelled() );
         $this->assertTrue( $this->execution->hasEnded() );
         $this->assertFalse( $this->execution->isResumed() );
         $this->assertFalse( $this->execution->isSuspended() );
@@ -410,6 +425,7 @@
         $this->execution->setVariables( array( 'condition' => false ) );
         $this->execution->start();
 
+        $this->assertFalse( $this->execution->isCancelled() );
         $this->assertTrue( $this->execution->hasEnded() );
         $this->assertFalse( $this->execution->isResumed() );
         $this->assertFalse( $this->execution->isSuspended() );
@@ -423,6 +439,7 @@
         $this->execution->setVariables( array( 'condition' => false ) );
         $this->execution->start();
 
+        $this->assertFalse( $this->execution->isCancelled() );
         $this->assertTrue( $this->execution->hasEnded() );
         $this->assertFalse( $this->execution->isResumed() );
         $this->assertFalse( $this->execution->isSuspended() );
@@ -438,6 +455,7 @@
         $this->execution->setVariables( array( 'condition' => true ) );
         $this->execution->start();
 
+        $this->assertFalse( $this->execution->isCancelled() );
         $this->assertTrue( $this->execution->hasEnded() );
         $this->assertFalse( $this->execution->isResumed() );
         $this->assertFalse( $this->execution->isSuspended() );
@@ -452,6 +470,7 @@
         $this->execution->workflow = $this->workflow;
         $this->execution->start();
 
+        $this->assertFalse( $this->execution->isCancelled() );
         $this->assertTrue( $this->execution->hasEnded() );
         $this->assertFalse( $this->execution->isResumed() );
         $this->assertFalse( $this->execution->isSuspended() );
@@ -467,6 +486,7 @@
         $this->execution->workflow = $this->workflow;
         $this->execution->start();
 
+        $this->assertFalse( $this->execution->isCancelled() );
         $this->assertTrue( $this->execution->hasEnded() );
         $this->assertFalse( $this->execution->isResumed() );
         $this->assertFalse( $this->execution->isSuspended() );
@@ -482,6 +502,7 @@
         $this->execution->workflow = $this->workflow;
         $this->execution->start();
 
+        $this->assertFalse( $this->execution->isCancelled() );
         $this->assertTrue( $this->execution->hasEnded() );
         $this->assertFalse( $this->execution->isResumed() );
         $this->assertFalse( $this->execution->isSuspended() );
@@ -496,6 +517,7 @@
         $this->execution->workflow = $this->workflow;
         $this->execution->start();
 
+        $this->assertFalse( $this->execution->isCancelled() );
         $this->assertTrue( $this->execution->hasEnded() );
         $this->assertFalse( $this->execution->isResumed() );
         $this->assertFalse( $this->execution->isSuspended() );
@@ -507,6 +529,7 @@
         $this->execution->workflow = $this->workflow;
         $this->execution->start();
 
+        $this->assertFalse( $this->execution->isCancelled() );
         $this->assertTrue( $this->execution->hasEnded() );
         $this->assertFalse( $this->execution->isResumed() );
         $this->assertFalse( $this->execution->isSuspended() );
@@ -519,6 +542,7 @@
         $this->execution->workflow = $this->workflow;
         $this->execution->start();
 
+        $this->assertFalse( $this->execution->isCancelled() );
         $this->assertTrue( $this->execution->hasEnded() );
         $this->assertFalse( $this->execution->isResumed() );
         $this->assertFalse( $this->execution->isSuspended() );
@@ -554,6 +578,7 @@
         $this->execution->setInputVariableForSubWorkflow( 'variable', 'value' 
);
         $this->execution->start();
 
+        $this->assertFalse( $this->execution->isCancelled() );
         $this->assertTrue( $this->execution->hasEnded() );
         $this->assertFalse( $this->execution->isResumed() );
         $this->assertFalse( $this->execution->isSuspended() );
@@ -565,6 +590,7 @@
         $this->execution->workflow = $this->workflow;
         $this->execution->start();
 
+        $this->assertFalse( $this->execution->isCancelled() );
         $this->assertTrue( $this->execution->hasEnded() );
         $this->assertFalse( $this->execution->isResumed() );
         $this->assertFalse( $this->execution->isSuspended() );
@@ -598,6 +624,7 @@
         $this->execution->workflow = $this->workflow;
         $this->execution->start();
 
+        $this->assertFalse( $this->execution->isCancelled() );
         $this->assertTrue( $this->execution->hasEnded() );
         $this->assertFalse( $this->execution->isResumed() );
         $this->assertFalse( $this->execution->isSuspended() );
@@ -613,12 +640,37 @@
         $this->execution->workflow = $this->workflow;
         $this->execution->start();
 
+        $this->assertFalse( $this->execution->isCancelled() );
         $this->assertTrue( $this->execution->hasEnded() );
         $this->assertFalse( $this->execution->isResumed() );
         $this->assertFalse( $this->execution->isSuspended() );
 
         $this->assertEquals( 1, $this->execution->getVariable( 'x' ) );
         $this->assertEquals( 2, $this->execution->getVariable( 'z' ) );
+    }
+
+    public function 
testExecuteParallelSplitCancelCaseActionActionSynchronization()
+    {
+        $this->setUpCancelCase( 'first' );
+        $this->execution->workflow = $this->workflow;
+        $this->execution->start();
+
+        $this->assertTrue( $this->execution->isCancelled() );
+        $this->assertTrue( $this->execution->hasEnded() );
+        $this->assertFalse( $this->execution->isResumed() );
+        $this->assertFalse( $this->execution->isSuspended() );
+    }
+
+    public function 
testExecuteParallelSplitActionActionCancelCaseSynchronization()
+    {
+        $this->setUpCancelCase( 'last' );
+        $this->execution->workflow = $this->workflow;
+        $this->execution->start();
+
+        $this->assertTrue( $this->execution->isCancelled() );
+        $this->assertTrue( $this->execution->hasEnded() );
+        $this->assertFalse( $this->execution->isResumed() );
+        $this->assertFalse( $this->execution->isSuspended() );
     }
 
     public function testListener()

Modified: trunk/Workflow/tests/visitor_visualization_test.php
==============================================================================
--- trunk/Workflow/tests/visitor_visualization_test.php [iso-8859-1] (original)
+++ trunk/Workflow/tests/visitor_visualization_test.php [iso-8859-1] Mon Jan 21 
17:04:16 2008
@@ -227,6 +227,28 @@
         );
     }
 
+    public function 
testVisitParallelSplitCancelCaseActionActionSynchronization()
+    {
+        $this->setUpCancelCase( 'first' );
+        $this->workflow->accept( $this->visitor );
+
+        $this->assertEquals(
+          $this->readExpected( 
'ParallelSplitCancelCaseActionActionSynchronization' ),
+          $this->visitor->__toString()
+        );
+    }
+
+    public function 
testVisitParallelSplitActionActionCancelCaseSynchronization()
+    {
+        $this->setUpCancelCase( 'last' );
+        $this->workflow->accept( $this->visitor );
+
+        $this->assertEquals(
+          $this->readExpected( 
'ParallelSplitActionActionCancelCaseSynchronization' ),
+          $this->visitor->__toString()
+        );
+    }
+
     protected function readExpected( $name )
     {
         return file_get_contents(

Modified: trunk/WorkflowDatabaseTiein/ChangeLog
==============================================================================
--- trunk/WorkflowDatabaseTiein/ChangeLog [iso-8859-1] (original)
+++ trunk/WorkflowDatabaseTiein/ChangeLog [iso-8859-1] Mon Jan 21 17:04:16 2008
@@ -1,3 +1,5 @@
+- Implemented issue #10941: Support for the Cancel Case workflow pattern.
+
 - Fixed issue #12403: Multiple construction of
   ezcWorkflowDatabaseDefinitionStorage.
 

Modified: trunk/WorkflowDatabaseTiein/src/execution.php
==============================================================================
--- trunk/WorkflowDatabaseTiein/src/execution.php [iso-8859-1] (original)
+++ trunk/WorkflowDatabaseTiein/src/execution.php [iso-8859-1] Mon Jan 21 
17:04:16 2008
@@ -136,7 +136,10 @@
         $this->cleanupTable( 'execution' );
         $this->cleanupTable( 'execution_state' );
 
-        $this->db->commit();
+        if ( !$this->isCancelled() )
+        {
+            $this->db->commit();
+        }
     }
 
     /**

Added: 
trunk/WorkflowEventLogTiein/tests/data/ParallelSplitActionActionCancelCaseSynchronization.log
==============================================================================
--- 
trunk/WorkflowEventLogTiein/tests/data/ParallelSplitActionActionCancelCaseSynchronization.log
 (added)
+++ 
trunk/WorkflowEventLogTiein/tests/data/ParallelSplitActionActionCancelCaseSynchronization.log
 [iso-8859-1] Mon Jan 21 17:04:16 2008
@@ -1,0 +1,19 @@
+MMM DD HH:MM:SS [Info] [default] [default] Started execution #1 of workflow 
"ParallelSplitActionActionCancelCaseSynchronization" (version 1).
+MMM DD HH:MM:SS [Debug] [default] [default] Activated node 
#1(ezcWorkflowNodeStart) for instance #1 of workflow 
"ParallelSplitActionActionCancelCaseSynchronization" (version 1).
+MMM DD HH:MM:SS [Debug] [default] [default] Started thread #0 (1 sibling(s)) 
for execution #1 of workflow 
"ParallelSplitActionActionCancelCaseSynchronization" (version 1).
+MMM DD HH:MM:SS [Debug] [default] [default] Activated node 
#2(ezcWorkflowNodeParallelSplit) for instance #1 of workflow 
"ParallelSplitActionActionCancelCaseSynchronization" (version 1).
+MMM DD HH:MM:SS [Debug] [default] [default] Executed node 
#1(ezcWorkflowNodeStart) for instance #1 of workflow 
"ParallelSplitActionActionCancelCaseSynchronization" (version 1).
+MMM DD HH:MM:SS [Debug] [default] [default] Started thread #1 (3 sibling(s)) 
for execution #1 of workflow 
"ParallelSplitActionActionCancelCaseSynchronization" (version 1).
+MMM DD HH:MM:SS [Debug] [default] [default] Activated node 
#3(ezcWorkflowNodeAction) for instance #1 of workflow 
"ParallelSplitActionActionCancelCaseSynchronization" (version 1).
+MMM DD HH:MM:SS [Debug] [default] [default] Started thread #2 (3 sibling(s)) 
for execution #1 of workflow 
"ParallelSplitActionActionCancelCaseSynchronization" (version 1).
+MMM DD HH:MM:SS [Debug] [default] [default] Activated node 
#6(ezcWorkflowNodeAction) for instance #1 of workflow 
"ParallelSplitActionActionCancelCaseSynchronization" (version 1).
+MMM DD HH:MM:SS [Debug] [default] [default] Started thread #3 (3 sibling(s)) 
for execution #1 of workflow 
"ParallelSplitActionActionCancelCaseSynchronization" (version 1).
+MMM DD HH:MM:SS [Debug] [default] [default] Activated node 
#7(ezcWorkflowNodeCancel) for instance #1 of workflow 
"ParallelSplitActionActionCancelCaseSynchronization" (version 1).
+MMM DD HH:MM:SS [Debug] [default] [default] Executed node 
#2(ezcWorkflowNodeParallelSplit) for instance #1 of workflow 
"ParallelSplitActionActionCancelCaseSynchronization" (version 1).
+MMM DD HH:MM:SS [Debug] [default] [default] Activated node 
#4(ezcWorkflowNodeSynchronization) for instance #1 of workflow 
"ParallelSplitActionActionCancelCaseSynchronization" (version 1).
+MMM DD HH:MM:SS [Debug] [default] [default] Executed node 
#3(ezcWorkflowNodeAction) for instance #1 of workflow 
"ParallelSplitActionActionCancelCaseSynchronization" (version 1).
+MMM DD HH:MM:SS [Debug] [default] [default] Executed node 
#6(ezcWorkflowNodeAction) for instance #1 of workflow 
"ParallelSplitActionActionCancelCaseSynchronization" (version 1).
+MMM DD HH:MM:SS [Debug] [default] [default] Could not roll back service object 
"ServiceObject" of node #3 for instance #1 of workflow 
"ParallelSplitActionActionCancelCaseSynchronization" (version 1).
+MMM DD HH:MM:SS [Debug] [default] [default] Could not roll back service object 
"ServiceObject" of node #6 for instance #1 of workflow 
"ParallelSplitActionActionCancelCaseSynchronization" (version 1).
+MMM DD HH:MM:SS [Debug] [default] [default] Executed node 
#7(ezcWorkflowNodeCancel) for instance #1 of workflow 
"ParallelSplitActionActionCancelCaseSynchronization" (version 1).
+MMM DD HH:MM:SS [Info] [default] [default] Cancelled execution #1 of workflow 
"ParallelSplitActionActionCancelCaseSynchronization" (version 1).

Propchange: 
trunk/WorkflowEventLogTiein/tests/data/ParallelSplitActionActionCancelCaseSynchronization.log
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
trunk/WorkflowEventLogTiein/tests/data/ParallelSplitCancelCaseActionActionSynchronization.log
==============================================================================
--- 
trunk/WorkflowEventLogTiein/tests/data/ParallelSplitCancelCaseActionActionSynchronization.log
 (added)
+++ 
trunk/WorkflowEventLogTiein/tests/data/ParallelSplitCancelCaseActionActionSynchronization.log
 [iso-8859-1] Mon Jan 21 17:04:16 2008
@@ -1,0 +1,14 @@
+MMM DD HH:MM:SS [Info] [default] [default] Started execution #1 of workflow 
"ParallelSplitCancelCaseActionActionSynchronization" (version 1).
+MMM DD HH:MM:SS [Debug] [default] [default] Activated node 
#1(ezcWorkflowNodeStart) for instance #1 of workflow 
"ParallelSplitCancelCaseActionActionSynchronization" (version 1).
+MMM DD HH:MM:SS [Debug] [default] [default] Started thread #0 (1 sibling(s)) 
for execution #1 of workflow 
"ParallelSplitCancelCaseActionActionSynchronization" (version 1).
+MMM DD HH:MM:SS [Debug] [default] [default] Activated node 
#2(ezcWorkflowNodeParallelSplit) for instance #1 of workflow 
"ParallelSplitCancelCaseActionActionSynchronization" (version 1).
+MMM DD HH:MM:SS [Debug] [default] [default] Executed node 
#1(ezcWorkflowNodeStart) for instance #1 of workflow 
"ParallelSplitCancelCaseActionActionSynchronization" (version 1).
+MMM DD HH:MM:SS [Debug] [default] [default] Started thread #1 (3 sibling(s)) 
for execution #1 of workflow 
"ParallelSplitCancelCaseActionActionSynchronization" (version 1).
+MMM DD HH:MM:SS [Debug] [default] [default] Activated node 
#3(ezcWorkflowNodeCancel) for instance #1 of workflow 
"ParallelSplitCancelCaseActionActionSynchronization" (version 1).
+MMM DD HH:MM:SS [Debug] [default] [default] Started thread #2 (3 sibling(s)) 
for execution #1 of workflow 
"ParallelSplitCancelCaseActionActionSynchronization" (version 1).
+MMM DD HH:MM:SS [Debug] [default] [default] Activated node 
#6(ezcWorkflowNodeAction) for instance #1 of workflow 
"ParallelSplitCancelCaseActionActionSynchronization" (version 1).
+MMM DD HH:MM:SS [Debug] [default] [default] Started thread #3 (3 sibling(s)) 
for execution #1 of workflow 
"ParallelSplitCancelCaseActionActionSynchronization" (version 1).
+MMM DD HH:MM:SS [Debug] [default] [default] Activated node 
#7(ezcWorkflowNodeAction) for instance #1 of workflow 
"ParallelSplitCancelCaseActionActionSynchronization" (version 1).
+MMM DD HH:MM:SS [Debug] [default] [default] Executed node 
#2(ezcWorkflowNodeParallelSplit) for instance #1 of workflow 
"ParallelSplitCancelCaseActionActionSynchronization" (version 1).
+MMM DD HH:MM:SS [Debug] [default] [default] Executed node 
#3(ezcWorkflowNodeCancel) for instance #1 of workflow 
"ParallelSplitCancelCaseActionActionSynchronization" (version 1).
+MMM DD HH:MM:SS [Info] [default] [default] Cancelled execution #1 of workflow 
"ParallelSplitCancelCaseActionActionSynchronization" (version 1).

Propchange: 
trunk/WorkflowEventLogTiein/tests/data/ParallelSplitCancelCaseActionActionSynchronization.log
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
trunk/WorkflowEventLogTiein/tests/data/ParallelSplitSynchronizationCancelCase.log
==============================================================================
--- 
trunk/WorkflowEventLogTiein/tests/data/ParallelSplitSynchronizationCancelCase.log
 (added)
+++ 
trunk/WorkflowEventLogTiein/tests/data/ParallelSplitSynchronizationCancelCase.log
 [iso-8859-1] Mon Jan 21 17:04:16 2008
@@ -1,0 +1,14 @@
+MMM DD HH:MM:SS [Info] [default] [default] Started execution #1 of workflow 
"ParallelSplitSynchronizationCancelCase" (version 1).
+MMM DD HH:MM:SS [Debug] [default] [default] Activated node 
#1(ezcWorkflowNodeStart) for instance #1 of workflow 
"ParallelSplitSynchronizationCancelCase" (version 1).
+MMM DD HH:MM:SS [Debug] [default] [default] Started thread #0 (1 sibling(s)) 
for execution #1 of workflow "ParallelSplitSynchronizationCancelCase" (version 
1).
+MMM DD HH:MM:SS [Debug] [default] [default] Activated node 
#2(ezcWorkflowNodeParallelSplit) for instance #1 of workflow 
"ParallelSplitSynchronizationCancelCase" (version 1).
+MMM DD HH:MM:SS [Debug] [default] [default] Executed node 
#1(ezcWorkflowNodeStart) for instance #1 of workflow 
"ParallelSplitSynchronizationCancelCase" (version 1).
+MMM DD HH:MM:SS [Debug] [default] [default] Started thread #1 (3 sibling(s)) 
for execution #1 of workflow "ParallelSplitSynchronizationCancelCase" (version 
1).
+MMM DD HH:MM:SS [Debug] [default] [default] Activated node 
#3(ezcWorkflowNodeCancel) for instance #1 of workflow 
"ParallelSplitSynchronizationCancelCase" (version 1).
+MMM DD HH:MM:SS [Debug] [default] [default] Started thread #2 (3 sibling(s)) 
for execution #1 of workflow "ParallelSplitSynchronizationCancelCase" (version 
1).
+MMM DD HH:MM:SS [Debug] [default] [default] Activated node 
#6(ezcWorkflowNodeAction) for instance #1 of workflow 
"ParallelSplitSynchronizationCancelCase" (version 1).
+MMM DD HH:MM:SS [Debug] [default] [default] Started thread #3 (3 sibling(s)) 
for execution #1 of workflow "ParallelSplitSynchronizationCancelCase" (version 
1).
+MMM DD HH:MM:SS [Debug] [default] [default] Activated node 
#7(ezcWorkflowNodeAction) for instance #1 of workflow 
"ParallelSplitSynchronizationCancelCase" (version 1).
+MMM DD HH:MM:SS [Debug] [default] [default] Executed node 
#2(ezcWorkflowNodeParallelSplit) for instance #1 of workflow 
"ParallelSplitSynchronizationCancelCase" (version 1).
+MMM DD HH:MM:SS [Debug] [default] [default] Executed node 
#3(ezcWorkflowNodeCancel) for instance #1 of workflow 
"ParallelSplitSynchronizationCancelCase" (version 1).
+MMM DD HH:MM:SS [Info] [default] [default] Cancelled execution #1 of workflow 
"ParallelSplitSynchronizationCancelCase" (version 1).

Propchange: 
trunk/WorkflowEventLogTiein/tests/data/ParallelSplitSynchronizationCancelCase.log
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: trunk/WorkflowEventLogTiein/tests/listener_test.php
==============================================================================
--- trunk/WorkflowEventLogTiein/tests/listener_test.php [iso-8859-1] (original)
+++ trunk/WorkflowEventLogTiein/tests/listener_test.php [iso-8859-1] Mon Jan 21 
17:04:16 2008
@@ -344,5 +344,31 @@
           $this->readActual()
         );
     }
+
+    public function testLogParallelSplitCancelCaseActionActionSynchronization()
+    {
+        $this->setUpCancelCase( 'first' );
+        $this->definition->save( $this->workflow );
+        $this->execution->workflow = $this->workflow;
+        $this->execution->start();
+
+        $this->assertEquals(
+          $this->readExpected( 
'ParallelSplitCancelCaseActionActionSynchronization' ),
+          $this->readActual()
+        );
+    }
+
+    public function testLogParallelSplitActionActionCancelCaseSynchronization()
+    {
+        $this->setUpCancelCase( 'last' );
+        $this->definition->save( $this->workflow );
+        $this->execution->workflow = $this->workflow;
+        $this->execution->start();
+
+        $this->assertEquals(
+          $this->readExpected( 
'ParallelSplitActionActionCancelCaseSynchronization' ),
+          $this->readActual()
+        );
+    }
 }
 ?>


-- 
svn-components mailing list
svn-components@lists.ez.no
http://lists.ez.no/mailman/listinfo/svn-components

Reply via email to