/**
  * Builds a simple Diagram of the Process
  *
  * @access public
  * @author Joel Bout, <*****@*****.**>
  * @param  Resource process
  * @return string
  */
 public static function buildDiagramData(core_kernel_classes_Resource $process)
 {
     $returnValue = (string) '';
     common_Logger::i("Building diagram for " . $process->getLabel());
     $authoringService = wfAuthoring_models_classes_ProcessService::singleton();
     $activityService = wfEngine_models_classes_ActivityService::singleton();
     $connectorService = wfEngine_models_classes_ConnectorService::singleton();
     $activityCardinalityService = wfEngine_models_classes_ActivityCardinalityService::singleton();
     $activities = $authoringService->getActivitiesByProcess($process);
     $todo = array();
     foreach ($activities as $activity) {
         if ($activityService->isInitial($activity)) {
             $todo[] = $activity;
         }
     }
     $currentLevel = 0;
     $diagram = new wfAuthoring_models_classes_ProcessDiagram();
     $done = array();
     while (!empty($todo)) {
         $nextLevel = array();
         $posOnLevel = 0;
         foreach ($todo as $item) {
             $next = array();
             if ($activityService->isActivity($item)) {
                 // add this activity
                 $diagram->addActivity($item, 54 + 200 * $posOnLevel + 10 * $currentLevel, 35 + 80 * $currentLevel);
                 $next = array_merge($next, $activityService->getNextConnectors($item));
                 common_Logger::d('Activity added ' . $item->getUri());
             } elseif ($connectorService->isConnector($item)) {
                 // add this connector
                 $diagram->addConnector($item, 100 + 200 * $posOnLevel + 10 * $currentLevel, 40 + 80 * $currentLevel);
                 $next = array_merge($next, $connectorService->getNextActivities($item));
             } else {
                 common_Logger::w('unexpected ressource in process ' . $item->getUri());
             }
             //replace cardinalities
             foreach ($next as $key => $destination) {
                 if ($activityCardinalityService->isCardinality($destination)) {
                     // not represented on diagram
                     $next[$key] = $activityCardinalityService->getDestination($destination);
                 }
             }
             //add arrows
             foreach ($next as $destination) {
                 $diagram->addArrow($item, $destination);
             }
             $posOnLevel++;
             $nextLevel = array_merge($nextLevel, $next);
         }
         $done = array_merge($done, $todo);
         $todo = array_diff($nextLevel, $done);
         $currentLevel++;
     }
     $returnValue = $diagram->toJSON();
     return (string) $returnValue;
 }
 /**
  * Short description of method connectorNode
  *
  * @access public
  * @author Joel Bout, <*****@*****.**>
  * @param  Resource connector
  * @param  string nodeClass
  * @param  boolean recursive
  * @return array
  */
 public function connectorNode(core_kernel_classes_Resource $connector, $nodeClass = '', $recursive = false)
 {
     $returnValue = array();
     $connectorData = array();
     $connectorService = wfEngine_models_classes_ConnectorService::singleton();
     //		$activityService = wfEngine_models_classes_ActivityService::singleton();
     //type of connector:
     //if not null, get the information on the next activities. Otherwise, return an "empty" connector node, indicating that the node has just been created, i.e. at the same time as an activity
     $connectorType = $connector->getOnePropertyValue(new core_kernel_classes_Property(PROPERTY_CONNECTORS_TYPE), false);
     if (is_null($connectorType)) {
         //create default connector node:
         $returnValue = $this->addNodePrefix($this->defaultConnectorNode($connector), $nodeClass);
         return $returnValue;
     } else {
         //if it is a conditional type
         if ($connectorType->getUri() == INSTANCE_TYPEOFCONNECTORS_CONDITIONAL) {
             //get the rule
             $connectorRule = $connector->getOnePropertyValue(new core_kernel_classes_Property(PROPERTY_CONNECTORS_TRANSITIONRULE), false);
             if (!is_null($connectorRule)) {
                 //continue getting connector data:
                 $connectorData[] = $this->conditionNode($connectorRule);
                 //get the "THEN"
                 $then = $connectorRule->getOnePropertyValue(new core_kernel_classes_Property(PROPERTY_TRANSITIONRULES_THEN), false);
                 if (!is_null($then)) {
                     $portData = array('id' => 0, 'label' => 'then', 'multiplicity' => 1);
                     if ($connectorService->isConnector($then)) {
                         $connectorActivityReference = $then->getUniquePropertyValue(new core_kernel_classes_Property(PROPERTY_CONNECTORS_ACTIVITYREFERENCE))->getUri();
                         if ($connectorActivityReference == $this->currentActivity->getUri() && !in_array($then->getUri(), $this->addedConnectors)) {
                             if ($recursive) {
                                 $connectorData[] = $this->connectorNode($then, 'then', true, $portData);
                             } else {
                                 $connectorData[] = $this->activityNode($then, 'then', false, $portData);
                             }
                         } else {
                             $connectorData[] = $this->activityNode($then, 'then', true, $portData);
                         }
                     } else {
                         $connectorData[] = $this->activityNode($then, 'then', true, $portData);
                     }
                 }
                 //same for the "ELSE"
                 $else = $connectorRule->getOnePropertyValue(new core_kernel_classes_Property(PROPERTY_TRANSITIONRULES_ELSE), false);
                 if (!is_null($else)) {
                     $portData = array('id' => 1, 'label' => 'else', 'multiplicity' => 1);
                     if ($connectorService->isConnector($else)) {
                         $connectorActivityReference = $else->getUniquePropertyValue(new core_kernel_classes_Property(PROPERTY_CONNECTORS_ACTIVITYREFERENCE))->getUri();
                         if ($connectorActivityReference == $this->currentActivity->getUri() && !in_array($else->getUri(), $this->addedConnectors)) {
                             if ($recursive) {
                                 $connectorData[] = $this->connectorNode($else, 'else', true, $portData);
                             } else {
                                 $connectorData[] = $this->activityNode($else, 'else', false, $portData);
                             }
                         } else {
                             $connectorData[] = $this->activityNode($else, 'else', true, $portData);
                         }
                     } else {
                         $connectorData[] = $this->activityNode($else, 'else', true, $portData);
                     }
                 }
             }
         } elseif ($connectorType->getUri() == INSTANCE_TYPEOFCONNECTORS_SEQUENCE) {
             $next = $connector->getOnePropertyValue(new core_kernel_classes_Property(PROPERTY_STEP_NEXT), false);
             if (!is_null($next)) {
                 $connectorData[] = $this->activityNode($next, 'next', true);
                 //the default portData array will do
             }
         } elseif ($connectorType->getUri() == INSTANCE_TYPEOFCONNECTORS_PARALLEL) {
             $cardinalityService = wfEngine_models_classes_ActivityCardinalityService::singleton();
             $variableService = wfEngine_models_classes_VariableService::singleton();
             $nextActivitiesCollection = $connector->getPropertyValuesCollection(new core_kernel_classes_Property(PROPERTY_STEP_NEXT));
             $portId = 0;
             foreach ($nextActivitiesCollection->getIterator() as $nextActivity) {
                 if ($cardinalityService->isCardinality($nextActivity)) {
                     $activity = $cardinalityService->getDestination($nextActivity);
                     $cardinality = $cardinalityService->getCardinality($nextActivity);
                     $number = $cardinality instanceof core_kernel_classes_Resource ? '^' . $variableService->getCode($cardinality) : $cardinality;
                     $connectorData[] = $this->activityNode($activity, 'next', true, array('id' => $portId, 'multiplicity' => $number, 'label' => $activity->getLabel()), "(count : {$number})");
                     $portId++;
                 }
             }
         } elseif ($connectorType->getUri() == INSTANCE_TYPEOFCONNECTORS_JOIN) {
             $next = $connector->getOnePropertyValue(new core_kernel_classes_Property(PROPERTY_STEP_NEXT), false);
             if (!is_null($next)) {
                 $connectorData[] = $this->activityNode($next, 'next', true);
                 //the default portData array will do
             }
         } else {
             throw new Exception("unknown connector type: {$connectorType->getLabel()} for connector {$connector->getUri()}");
         }
         if (empty($portInfo)) {
             $portInfo = array('id' => 0, 'label' => 'next', 'multiplicity' => 1);
         } else {
             if (!isset($portInfo['id'])) {
                 $portInfo['id'] = 0;
             }
             if (!isset($portInfo['id'])) {
                 $portInfo['label'] = 'next';
             }
             if (!isset($portInfo['id'])) {
                 $portInfo['multiplicity'] = 1;
             }
         }
         //add to data
         $returnValue = array('data' => $connectorType->getLabel() . ":" . $connector->getLabel(), 'attributes' => array('id' => tao_helpers_Uri::encode($connector->getUri()), 'class' => 'node-connector'), 'type' => trim(strtolower($connectorType->getLabel())), 'port' => $nodeClass, 'portData' => $portInfo);
         $returnValue = self::addNodePrefix($returnValue, $nodeClass);
         if (!empty($connectorData)) {
             $returnValue['children'] = $connectorData;
         }
         $this->addedConnectors[] = $connector->getUri();
     }
     return (array) $returnValue;
 }
 /**
  * retrieve connector previous activities
  *
  * @access public
  * @author Joel Bout, <*****@*****.**>
  * @param  Resource connector
  * @param  boolean followCardinalities
  * @return array
  */
 public function getPreviousActivities(core_kernel_classes_Resource $connector, $followCardinalities = false)
 {
     $returnValue = array();
     $steps = $this->getPreviousSteps($connector);
     if (!$followCardinalities) {
         $returnValue = $steps;
     } else {
         $cardService = wfEngine_models_classes_ActivityCardinalityService::singleton();
         foreach ($steps as $cand) {
             if ($cardService->isCardinality($cand)) {
                 // no recursion nescessary since cardinalities cannnot follow each other
                 foreach ($this->getPreviousSteps($cand) as $orig) {
                     $returnValue[] = $orig;
                 }
             } else {
                 $returnValue[] = $cand;
             }
         }
     }
     return (array) $returnValue;
 }
 /**
  * Short description of method delete
  *
  * @access public
  * @author Joel Bout, <*****@*****.**>
  * @param  Resource connector
  * @return boolean
  */
 public function delete(core_kernel_classes_Resource $connector)
 {
     $returnValue = (bool) false;
     $cardinalityService = wfEngine_models_classes_ActivityCardinalityService::singleton();
     if (!$this->isConnector($connector)) {
         // throw new Exception("the resource in the parameter is not a connector: {$connector->getLabel()} ({$connector->getUri()})");
         return $returnValue;
     }
     //get the type of connector:
     $connectorType = $connector->getOnePropertyValue(new core_kernel_classes_Property(PROPERTY_CONNECTORS_TYPE));
     if (!is_null($connectorType) && $connectorType instanceof core_kernel_classes_Resource) {
         if ($connectorType->getUri() == INSTANCE_TYPEOFCONNECTORS_CONDITIONAL) {
             //delete the related rule:
             $relatedRule = $this->getTransitionRule($connector);
             if (!is_null($relatedRule)) {
                 $processAuthoringService = wfAuthoring_models_classes_ProcessService::singleton();
                 $processAuthoringService->deleteRule($relatedRule);
             }
         }
     }
     //delete cardinality resources if exists in previous activities:
     foreach ($this->getPreviousActivities($connector) as $prevActivity) {
         if ($cardinalityService->isCardinality($prevActivity)) {
             $prevActivity->delete();
             //delete the cardinality resource
         }
     }
     //manage the connection to the following activities
     $activityRef = $connector->getUniquePropertyValue(new core_kernel_classes_Property(PROPERTY_CONNECTORS_ACTIVITYREFERENCE))->getUri();
     foreach ($this->getNextActivities($connector) as $nextActivity) {
         $activity = null;
         if ($cardinalityService->isCardinality($nextActivity)) {
             try {
                 $activity = $cardinalityService->getDestination($nextActivity);
             } catch (Exception $e) {
                 //the actiivty could be null if the reference have been removed...
             }
             $nextActivity->delete();
             //delete the cardinality resource
         } else {
             $activity = $nextActivity;
         }
         if (!is_null($activity) && $this->isConnector($activity)) {
             $nextActivityRef = $activity->getUniquePropertyValue(new core_kernel_classes_Property(PROPERTY_CONNECTORS_ACTIVITYREFERENCE))->getUri();
             if ($nextActivityRef == $activityRef) {
                 $this->delete($activity);
                 //delete following connectors only if they have the same activity reference
             }
         }
     }
     //delete connector itself:
     $returnValue = $connector->delete(true);
     return (bool) $returnValue;
 }
 /**
  * Short description of method getSplitConnectorNewActivities
  *
  * @access public
  * @author Somsack Sipasseuth, <*****@*****.**>
  * @param  Resource activityExecution
  * @param  Resource currentConnector
  * @return array
  */
 public function getSplitConnectorNewActivities(core_kernel_classes_Resource $activityExecution, core_kernel_classes_Resource $currentConnector)
 {
     $returnValue = array();
     $connectorService = wfEngine_models_classes_ConnectorService::singleton();
     $cardinalityService = wfEngine_models_classes_ActivityCardinalityService::singleton();
     foreach ($connectorService->getNextActivities($currentConnector) as $cardinality) {
         if ($cardinalityService->isCardinality($cardinality)) {
             $activity = $cardinalityService->getDestination($cardinality);
             if (!is_null($activity)) {
                 try {
                     $count = $cardinalityService->getCardinality($cardinality, $activityExecution);
                 } catch (wfEngine_models_classes_ProcessExecutionException $e) {
                     $count = 0;
                     //in case the parallel variable is not set
                 }
                 for ($i = 0; $i < $count; $i++) {
                     $returnValue[] = $activity;
                 }
             }
         }
     }
     return (array) $returnValue;
 }
 public function getCardinality(core_kernel_classes_Resource $activity)
 {
     $returnValue = 1;
     // check multiplicity  (according to the cardinality defined in the related parallel connector):
     $parallelConnector = $this->findParallelFromActivityBackward($activity);
     if (!is_null($parallelConnector)) {
         $cardinalityService = wfEngine_models_classes_ActivityCardinalityService::singleton();
         //count the number of time theprevious activity must be set as the previous activity of the join connector
         $cardinalities = $cardinalityService->getNextSteps($parallelConnector);
         foreach ($cardinalities as $nextActivityCardinality) {
             if (in_array($cardinalityService->getDestination($nextActivityCardinality)->getUri(), $this->getCheckedActivities())) {
                 return $cardinalityService->getCardinality($nextActivityCardinality);
             }
         }
         throw new common_exception_Error('parallel execution found by workflow ' . $parallelConnector->getUri() . ' not in current execution path');
     } else {
         // no parallel execution, so 1 execution
         common_Logger::i('no parallel connector found for ' . $activity->getUri());
     }
     return $returnValue;
 }
 /**
  * Short description of method setParallelActivities
  *
  * @access public
  * @author Joel Bout, <*****@*****.**>
  * @param  Resource connectorInstance
  * @param  array newActivitiesArray
  * @return boolean
  */
 public function setParallelActivities(core_kernel_classes_Resource $connectorInstance, $newActivitiesArray = array())
 {
     $returnValue = (bool) false;
     $this->setConnectorType($connectorInstance, new core_kernel_classes_Resource(INSTANCE_TYPEOFCONNECTORS_PARALLEL));
     $propNextActivities = new core_kernel_classes_Property(PROPERTY_STEP_NEXT);
     $cardinalityService = wfEngine_models_classes_ActivityCardinalityService::singleton();
     //remove old property values:
     $nextActivitiesCollection = $connectorInstance->getPropertyValuesCollection($propNextActivities);
     $oldSplitVariablesByActivity = array();
     foreach ($nextActivitiesCollection->getIterator() as $activityMultiplicityResource) {
         if ($cardinalityService->isCardinality($activityMultiplicityResource)) {
             //record the old split variables values in case it is needed (TODO: optimize this process)
             $activity = $cardinalityService->getDestination($activityMultiplicityResource);
             $splitVars = $cardinalityService->getSplitVariables($activityMultiplicityResource);
             if (!empty($splitVars)) {
                 $oldSplitVariablesByActivity[$activity->getUri()] = $splitVars;
             }
             //delete it
             $activityMultiplicityResource->delete();
         }
     }
     $returnValue = $connectorInstance->removePropertyValues($propNextActivities);
     //finally, set the next activities values to the parallel connector:
     $joinConnector = null;
     $processFlow = new wfEngine_models_classes_ProcessFlow();
     $i = 0;
     foreach ($newActivitiesArray as $activityUri => $count) {
         $activity = new core_kernel_classes_Resource($activityUri);
         //set multiplicity to the parallel connector:
         $cardinality = $cardinalityService->createCardinality($activity, $count);
         if (isset($oldSplitVariablesByActivity[$activityUri])) {
             if (!empty($oldSplitVariablesByActivity[$activityUri]) && !$cardinalityService->editSplitVariables($cardinality, $oldSplitVariablesByActivity[$activityUri])) {
                 throw new Exception('cannot set split variables to new cardinality resources');
             }
         }
         $returnValue = $connectorInstance->setPropertyValue($propNextActivities, $cardinality);
         //set multiplicity to the merge connector:
         $previousActvityUri = '';
         if ($i == 0) {
             //use the ProcessFlow service to find if a merge connector exists for the current parallel connector:
             //do it only once:
             $processFlow->resetCheckedResources();
             $joinConnector = $processFlow->findJoinFromActivityForward($activity);
             if (!is_null($joinConnector)) {
                 //if it exists, we erase all previous activities:
                 //the previous acitivites must be related to the *exact* same activity-multiplicity objects as the parallel but not necessarily the same (e.g. parallel thread with more than 1 acitivty)
                 //we suppose that the previous activities of the found merge connector come *exactly* from the thread generated by its parallel connector (condition for a valid process design)
                 $prevActivities = wfEngine_models_classes_ConnectorService::singleton()->getPreviousActivities($joinConnector);
                 foreach ($prevActivities as $activityMultiplicityResource) {
                     if ($cardinalityService->isCardinality($activityMultiplicityResource)) {
                         $activityMultiplicityResource->delete();
                     }
                     $prevActivities->removePropertyValues(new core_kernel_classes_Property(PROPERTY_STEP_NEXT));
                 }
                 /*
                 $prevActivitiesCollection = $joinConnector->getPropertyValuesCollection($propPreviousActivities);
                 foreach ($prevActivitiesCollection->getIterator() as $activityMultiplicityResource){
                 	if($cardinalityService->isCardinality($activityMultiplicityResource)){
                 		$activityMultiplicityResource->delete();
                 	}
                 }
                 $returnValue = $joinConnector->removePropertyValues($propPreviousActivities);
                 */
             }
             $toPop = $processFlow->getCheckedActivities();
             $previousActvityUri = array_pop($toPop);
         }
         if (!is_null($joinConnector)) {
             if (empty($previousActvityUri)) {
                 //if there are more than 1 activity in the newActivitiesArray:
                 $processFlow->resetCheckedResources();
                 $joinConnector = $processFlow->findJoinFromActivityForward($activity);
                 $previousActvityUri = array_pop($processFlow->getCheckedActivities());
             }
             if (!empty($previousActvityUri)) {
                 $previous = new core_kernel_classes_Resource($previousActvityUri);
                 $cardinality = $cardinalityService->createCardinality($joinConnector, $count);
                 $returnValue = $previous->setPropertyValues(new core_kernel_classes_Property(PROPERTY_STEP_NEXT), $cardinality);
                 /*
                 $multiplicity = $cardinalityService->createCardinality($previous, $count);
                 $returnValue = $joinConnector->setPropertyValue($propPreviousActivities, $multiplicity);
                 */
             }
         }
         $i++;
     }
     return (bool) $returnValue;
 }
 public static function nextActivityElements(core_kernel_classes_Resource $connector, $type, $allowCreation = true, $includeConnectors = true, $optionsWidget = 'Combobox')
 {
     $returnValue = array();
     $authorizedOptionsWidget = array('Combobox', 'Checkbox');
     if (!in_array($optionsWidget, $authorizedOptionsWidget)) {
         throw new Exception('Wrong type of widget');
         return $returnValue;
     }
     $idPrefix = '';
     $nextActivity = null;
     $propTransitionRule = new core_kernel_classes_Property(PROPERTY_CONNECTORS_TRANSITIONRULE);
     $propNextActivities = new core_kernel_classes_Property(PROPERTY_STEP_NEXT);
     //find the next activity if available
     switch (strtolower($type)) {
         case 'next':
             $nextActivityCollection = $connector->getPropertyValuesCollection($propNextActivities);
             foreach ($nextActivityCollection->getIterator() as $activity) {
                 if ($activity instanceof core_kernel_classes_Resource) {
                     $nextActivity = $activity;
                     //we take the last one...(note: there should be only one though)
                 }
             }
             $idPrefix = 'next';
             break;
         case 'then':
             $transitionRuleCollection = $connector->getPropertyValuesCollection($propTransitionRule);
             foreach ($transitionRuleCollection->getIterator() as $transitionRule) {
                 if ($transitionRule instanceof core_kernel_classes_Resource) {
                     foreach ($transitionRule->getPropertyValuesCollection(new core_kernel_classes_Property(PROPERTY_TRANSITIONRULES_THEN))->getIterator() as $then) {
                         if ($then instanceof core_kernel_classes_Resource) {
                             $nextActivity = $then;
                         }
                     }
                 }
             }
             $idPrefix = 'then';
             break;
         case 'else':
             $transitionRuleCollection = $connector->getPropertyValuesCollection($propTransitionRule);
             foreach ($transitionRuleCollection->getIterator() as $transitionRule) {
                 if ($transitionRule instanceof core_kernel_classes_Resource) {
                     foreach ($transitionRule->getPropertyValuesCollection(new core_kernel_classes_Property(PROPERTY_TRANSITIONRULES_ELSE))->getIterator() as $else) {
                         if ($else instanceof core_kernel_classes_Resource) {
                             $nextActivity = $else;
                         }
                     }
                 }
             }
             $idPrefix = 'else';
             break;
         case 'parallel':
             $nextActivity = array();
             $nextActivityCollection = $connector->getPropertyValuesCollection($propNextActivities);
             foreach ($nextActivityCollection->getIterator() as $cardinality) {
                 if ($cardinality instanceof core_kernel_classes_Resource) {
                     $nextActivity[] = $cardinality;
                 }
             }
             $idPrefix = 'parallel';
             break;
         case 'join':
             // should only have one following activity
             $nextActivity = $connector->getOnePropertyValue($propNextActivities);
             $idPrefix = $type;
             break;
         default:
             throw new Exception("unknown type for the next activity");
     }
     $activityOptions = array();
     $connectorOptions = array();
     if ($allowCreation) {
         //create the activity label element (used only in case of new activity craetion)
         $elementActivityLabel = tao_helpers_form_FormFactory::getElement($idPrefix . "_activityLabel", 'Textbox');
         $elementActivityLabel->setDescription(__('Label'));
         //add the "creating" option
         $activityOptions["newActivity"] = __("create new activity");
         $connectorOptions["newConnector"] = __("create new connector");
     }
     //the activity associated to the connector:
     $referencedActivity = $connector->getUniquePropertyValue(new core_kernel_classes_Property(PROPERTY_CONNECTORS_ACTIVITYREFERENCE));
     //mandatory property value, initiated at the connector creation
     if ($referencedActivity instanceof core_kernel_classes_Resource) {
         $processDefClass = new core_kernel_classes_Class(CLASS_PROCESS);
         $processes = $processDefClass->searchInstances(array(PROPERTY_PROCESS_ACTIVITIES => $referencedActivity->getUri()), array('like' => false));
         if (count($processes) > 0) {
             $process = array_shift($processes);
             if (!empty($process)) {
                 //get list of activities and connectors for the current process:
                 $connectorClass = new core_kernel_classes_Class(CLASS_CONNECTORS);
                 $processAuthoringService = wfAuthoring_models_classes_ProcessService::singleton();
                 $activities = $processAuthoringService->getActivitiesByProcess($process);
                 foreach ($activities as $activityTemp) {
                     //include activities options:
                     $encodedUri = tao_helpers_Uri::encode($activityTemp->getUri());
                     $activityOptions[$encodedUri] = $activityTemp->getLabel();
                     if (strtolower($type) == 'parallel') {
                         $elementHidden = tao_helpers_form_FormFactory::getElement("{$encodedUri}_num_hidden", 'Hidden');
                         $returnValue[$idPrefix . '_' . $activityTemp->getUri()] = $elementHidden;
                     }
                     //include connectors options:
                     if ($includeConnectors) {
                         $connectors = $connectorClass->searchInstances(array(PROPERTY_CONNECTORS_ACTIVITYREFERENCE => $activityTemp->getUri()), array('like' => false));
                         foreach ($connectors as $connectorTemp) {
                             if ($connector->getUri() != $connectorTemp->getUri()) {
                                 $connectorOptions[tao_helpers_Uri::encode($connectorTemp->getUri())] = $connectorTemp->getLabel();
                             }
                         }
                     }
                 }
             }
         }
     }
     //create the description element
     $elementDescription = tao_helpers_form_FormFactory::getElement($idPrefix, 'Free');
     $elementDescription->setValue(strtoupper($type) . ' :');
     //create the activity select element:
     $elementActivities = tao_helpers_form_FormFactory::getElement($idPrefix . "_activityUri", $optionsWidget);
     $elementActivities->setDescription(__('Activity'));
     $elementActivities->setOptions($activityOptions);
     $elementChoice = null;
     $elementConnectors = null;
     if ($includeConnectors) {
         //the default radio button to select between the 3 possibilities:
         $elementChoice = tao_helpers_form_FormFactory::getElement($idPrefix . "_activityOrConnector", 'Radiobox');
         $elementChoice->setDescription(__('Activity or Connector'));
         $options = array("activity" => __("Activity"), "connector" => __("Connector"));
         $elementChoice->setOptions($options);
         //create the connector select element:
         $elementConnectors = tao_helpers_form_FormFactory::getElement($idPrefix . "_connectorUri", $optionsWidget);
         $elementConnectors->setDescription(__('Connector'));
         $elementConnectors->setOptions($connectorOptions);
     }
     if (!empty($nextActivity)) {
         if (is_array($nextActivity) && $optionsWidget == 'Checkbox') {
             if (strtolower($type) == 'parallel') {
                 $cardinalityService = wfEngine_models_classes_ActivityCardinalityService::singleton();
                 foreach ($nextActivity as $cardinality) {
                     $activity = $cardinalityService->getDestination($cardinality);
                     $number = $cardinalityService->getCardinality($cardinality);
                     if (isset($returnValue[$idPrefix . '_' . $activity->getUri()])) {
                         $returnValue[$idPrefix . '_' . $activity->getUri()]->setValue($number instanceof core_kernel_classes_Resource ? tao_helpers_Uri::encode($number->getUri()) : intval($number));
                     }
                     $elementActivities->setValue($activity->getUri());
                     //no need for tao_helpers_Uri::encode
                 }
             } else {
                 foreach ($nextActivity as $activity) {
                     $elementActivities->setValue($activity->getUri());
                     //no need for tao_helpers_Uri::encode
                 }
             }
         } elseif ($nextActivity instanceof core_kernel_classes_Resource) {
             $aService = wfEngine_models_classes_ActivityService::singleton();
             if ($aService->isActivity($nextActivity)) {
                 if ($includeConnectors) {
                     $elementChoice->setValue("activity");
                 }
                 $elementActivities->setValue($nextActivity->getUri());
                 //no need for tao_helpers_Uri::encode
             }
             $conmectorService = wfEngine_models_classes_ConnectorService::singleton();
             if ($conmectorService->isConnector($nextActivity) && $includeConnectors) {
                 $elementChoice->setValue("connector");
                 $elementConnectors->setValue($nextActivity->getUri());
             }
         }
     }
     //put all elements in the return value:
     $returnValue[$idPrefix . '_description'] = $elementDescription;
     if ($includeConnectors) {
         $returnValue[$idPrefix . '_choice'] = $elementChoice;
     }
     $returnValue[$idPrefix . '_activities'] = $elementActivities;
     if ($allowCreation) {
         $returnValue[$idPrefix . '_label'] = $elementActivityLabel;
     }
     if ($includeConnectors) {
         $returnValue[$idPrefix . '_connectors'] = $elementConnectors;
     }
     return $returnValue;
 }
 public function testCreateCBAProcess()
 {
     if (!$this->createProcess) {
         return;
     }
     $authoringService = wfAuthoring_models_classes_ProcessService::singleton();
     $activityService = wfEngine_models_classes_ActivityService::singleton();
     $connectorService = wfAuthoring_models_classes_ConnectorService::singleton();
     $processVariableService = wfEngine_models_classes_VariableService::singleton();
     $cardinalityService = wfEngine_models_classes_ActivityCardinalityService::singleton();
     //create some process variables:
     $varCodes = array('unitUri', 'countryCode', 'languageCode', 'npm', 'translatorsCount', 'translator', 'reconciler', 'verifier', 'translatorSelected', 'translationFinished', 'TDreview', 'layoutCheck', 'finalCheck', 'opticalCheck', 'TDsignOff', 'countrySignOff', 'xliff', 'vff', 'xliff_working', 'vff_working');
     //"workingFiles" holds the working versions of the xliff and vff files, plus their revision number, in an serialized array()
     //during translation: workingFiles = array('user'=>#007, 'xliff' => array('uri' => #123456, 'revision'=>3), 'vff'=> array('uri' => #456789, 'revision'=>5))
     $this->populateVariables($varCodes);
     $aclUser = new core_kernel_classes_Resource(INSTANCE_ACL_USER);
     $aclRole = new core_kernel_classes_Resource(INSTANCE_ACL_ROLE);
     $processDefinition = $authoringService->createProcess($this->processLabel['CBA'], 'For Unit test');
     $this->assertIsA($processDefinition, 'core_kernel_classes_Resource');
     //set process initialization rights:
     $this->assertTrue($authoringService->setAcl($processDefinition, $aclRole, $this->roles['consortium']));
     //define activities and connectors
     //Select translators:
     $activitySelectTranslators = $authoringService->createActivity($processDefinition, 'Select Translator');
     $this->assertNotNull($activitySelectTranslators);
     $authoringService->setFirstActivity($processDefinition, $activitySelectTranslators);
     $activityService->setAcl($activitySelectTranslators, $aclUser, $this->vars['npm']);
     $activityService->setControls($activitySelectTranslators, array(INSTANCE_CONTROL_FORWARD));
     $connectorSelectTranslators = $authoringService->createConnector($activitySelectTranslators);
     $this->assertNotNull($connectorSelectTranslators);
     //translate:
     $activityTranslate = $authoringService->createActivity($processDefinition, 'Translate');
     $this->assertNotNull($activityTranslate);
     $activityService->setAcl($activityTranslate, $aclUser, $this->vars['translator']);
     $activityService->setControls($activityTranslate, array(INSTANCE_CONTROL_FORWARD));
     $result = $authoringService->setParallelActivities($connectorSelectTranslators, array($activityTranslate->getUri() => $this->vars['translatorsCount']));
     $this->assertTrue($result);
     $this->assertTrue($connectorService->setSplitVariables($connectorSelectTranslators, array($activityTranslate->getUri() => $this->vars['translator'])));
     $nextActivities = $connectorService->getNextActivities($connectorSelectTranslators);
     $this->assertEqual(count($nextActivities), 1);
     $cardinality = reset($nextActivities);
     $this->assertTrue($cardinalityService->isCardinality($cardinality));
     $this->assertEqual($cardinalityService->getDestination($cardinality)->getUri(), $activityTranslate->getUri());
     $this->assertEqual($cardinalityService->getCardinality($cardinality)->getUri(), $this->vars['translatorsCount']->getUri());
     $connectorTranslate = $authoringService->createConnector($activityTranslate);
     $this->assertNotNull($connectorTranslate);
     //reconciliation:
     $activityReconciliation = $authoringService->createJoinActivity($connectorTranslate, null, 'Reconciliation', $activityTranslate);
     $prevActivities = $connectorService->getPreviousActivities($connectorTranslate);
     $this->assertEqual(count($prevActivities), 1);
     $cardinality = reset($prevActivities);
     $this->assertTrue($cardinalityService->isCardinality($cardinality));
     $this->assertEqual($cardinalityService->getSource($cardinality)->getUri(), $activityTranslate->getUri());
     $this->assertEqual($cardinalityService->getCardinality($cardinality)->getUri(), $this->vars['translatorsCount']->getUri());
     $this->assertNotNull($activityReconciliation);
     $activityService->setAcl($activityReconciliation, $aclUser, $this->vars['reconciler']);
     $activityService->setControls($activityReconciliation, array(INSTANCE_CONTROL_FORWARD));
     $connectorReconciliation = $authoringService->createConnector($activityReconciliation);
     $this->assertNotNull($connectorReconciliation);
     //verify translations
     $activityVerifyTranslations = $authoringService->createSequenceActivity($connectorReconciliation, null, 'Verify Translations');
     $this->assertNotNull($activityVerifyTranslations);
     $activityService->setAcl($activityVerifyTranslations, $aclUser, $this->vars['verifier']);
     $activityService->setControls($activityVerifyTranslations, array(INSTANCE_CONTROL_FORWARD));
     $connectorVerifyTranslations = $authoringService->createConnector($activityVerifyTranslations);
     $this->assertNotNull($connectorVerifyTranslations);
     //correct verification
     $activityCorrectVerification = $authoringService->createSequenceActivity($connectorVerifyTranslations, null, 'Correct Verification Issues');
     $this->assertNotNull($activityCorrectVerification);
     $activityService->setAcl($activityCorrectVerification, $aclUser, $this->vars['reconciler']);
     $activityService->setControls($activityCorrectVerification, array(INSTANCE_CONTROL_FORWARD));
     $connectorCorrectVerification = $authoringService->createConnector($activityCorrectVerification);
     $this->assertNotNull($connectorCorrectVerification);
     //TD review :
     $activityTDreview = $authoringService->createSequenceActivity($connectorCorrectVerification, null, 'TD review');
     $this->assertNotNull($activityTDreview);
     $activityService->setAcl($activityTDreview, $aclRole, $this->roles['testDeveloper']);
     $activityService->setControls($activityTDreview, array(INSTANCE_CONTROL_FORWARD));
     $connectorTDreview = $authoringService->createConnector($activityTDreview);
     $this->assertNotNull($connectorTDreview);
     //if TD review not ok, return to correct verification issues:
     $transitionRule = $authoringService->createTransitionRule($connectorTDreview, '^TDreview == 1');
     $this->assertNotNull($transitionRule);
     $activityCorrectVerificationBis = $authoringService->createConditionalActivity($connectorTDreview, 'else', $activityCorrectVerification);
     //if ^TDreview != 1
     $this->assertEqual($activityCorrectVerification->getUri(), $activityCorrectVerificationBis->getUri());
     //correct layout :
     $activityCorrectLayout = $authoringService->createConditionalActivity($connectorTDreview, 'then', null, 'Correct Layout Issues');
     //if ^TDreview == 1
     $this->assertNotNull($activityCorrectLayout);
     $activityService->setAcl($activityCorrectLayout, $aclRole, $this->roles['developer']);
     $activityService->setControls($activityCorrectLayout, array(INSTANCE_CONTROL_FORWARD));
     $connectorCorrectLayout = $authoringService->createConnector($activityCorrectLayout);
     $this->assertNotNull($connectorCorrectLayout);
     //if correct layout needs verification :
     $transitionRule = $authoringService->createTransitionRule($connectorCorrectLayout, '^layoutCheck == 1');
     $this->assertNotNull($transitionRule);
     $activityVerification = $authoringService->createConditionalActivity($connectorCorrectLayout, 'else', null, 'Verification Followup');
     //if ^layoutCheck != 1
     $this->assertNotNull($activityVerification);
     $activityService->setAcl($activityVerification, $aclUser, $this->vars['verifier']);
     $activityService->setControls($activityVerification, array(INSTANCE_CONTROL_FORWARD));
     $connectorVerification = $authoringService->createConnector($activityVerification);
     $this->assertNotNull($connectorVerification);
     //final check :
     $activityFinalCheck = $authoringService->createConditionalActivity($connectorCorrectLayout, 'then', null, 'Final Check');
     //if ^layoutCheck == 1
     $this->assertNotNull($activityFinalCheck);
     $activityService->setAcl($activityFinalCheck, $aclRole, $this->roles['testDeveloper']);
     $activityService->setControls($activityFinalCheck, array(INSTANCE_CONTROL_FORWARD));
     $connectorFinalCheck = $authoringService->createConnector($activityFinalCheck);
     $this->assertNotNull($connectorFinalCheck);
     //if final check ok, go to scoring definition :
     $transitionRule = $authoringService->createTransitionRule($connectorFinalCheck, '^finalCheck == 1');
     $this->assertNotNull($transitionRule);
     $activityScoringDefinition = $authoringService->createConditionalActivity($connectorFinalCheck, 'then', null, 'Scoring Definition and Testing');
     //if ^finalCheck == 1
     $this->assertNotNull($activityScoringDefinition);
     $activityService->setAcl($activityScoringDefinition, $aclUser, $this->vars['reconciler']);
     $activityService->setControls($activityScoringDefinition, array(INSTANCE_CONTROL_FORWARD));
     $connectorScoringDefinition = $authoringService->createConnector($activityScoringDefinition);
     $this->assertNotNull($connectorScoringDefinition);
     //if not ok, return to correct layout :
     $activityCorrectLayoutBis = $authoringService->createConditionalActivity($connectorFinalCheck, 'else', $activityCorrectLayout);
     //if ^finalCheck != 1
     $this->assertEqual($activityCorrectLayout->getUri(), $activityCorrectLayoutBis->getUri());
     //verification :
     $transitionRule = $authoringService->createTransitionRule($connectorVerification, '^opticalCheck == 1');
     $this->assertNotNull($transitionRule);
     $activityFinalCheckBis = $authoringService->createConditionalActivity($connectorVerification, 'then', $activityFinalCheck);
     //if ^opticalCheck == 1
     $this->assertEqual($activityFinalCheckBis->getUri(), $activityFinalCheck->getUri());
     $activityCorrectLayoutBis = $authoringService->createConditionalActivity($connectorVerification, 'else', $activityCorrectLayout);
     //if ^opticalCheck != 1
     $this->assertEqual($activityCorrectLayoutBis->getUri(), $activityCorrectLayout->getUri());
     //scoring verification:
     $activityScoringVerification = $authoringService->createSequenceActivity($connectorScoringDefinition, null, 'Scoring Verification');
     $this->assertNotNull($activityScoringVerification);
     $activityService->setAcl($activityScoringVerification, $aclUser, $this->vars['verifier']);
     $activityService->setControls($activityScoringVerification, array(INSTANCE_CONTROL_FORWARD));
     $connectorScoringVerification = $authoringService->createConnector($activityScoringVerification);
     $this->assertNotNull($connectorScoringVerification);
     //final sign off :
     $activityTDSignOff = $authoringService->createSequenceActivity($connectorScoringVerification, null, 'Test Developer Sign Off');
     $this->assertNotNull($activityTDSignOff);
     $activityService->setAcl($activityTDSignOff, $aclRole, $this->roles['testDeveloper']);
     $activityService->setControls($activityTDSignOff, array(INSTANCE_CONTROL_FORWARD));
     $connectorTDSignOff = $authoringService->createConnector($activityTDSignOff);
     $this->assertNotNull($connectorTDSignOff);
     //link back to final check:
     $transitionRule = $authoringService->createTransitionRule($connectorTDSignOff, '^TDsignOff == 1');
     $this->assertNotNull($transitionRule);
     $authoringService->createConditionalActivity($connectorTDSignOff, 'else', $activityFinalCheck);
     //sign off :
     $activityCountrySignOff = $authoringService->createConditionalActivity($connectorTDSignOff, 'then', null, 'Country Sign Off');
     $activityService->setAcl($activityCountrySignOff, $aclUser, $this->vars['reconciler']);
     $activityService->setControls($activityCountrySignOff, array(INSTANCE_CONTROL_FORWARD));
     //complete the process:
     $connectorCountrySignOff = $authoringService->createConnector($activityCountrySignOff);
     $this->assertNotNull($connectorCountrySignOff);
     $transitionRule = $authoringService->createTransitionRule($connectorCountrySignOff, '^countrySignOff == 1');
     $this->assertNotNull($transitionRule);
     $activityFinal = $authoringService->createConditionalActivity($connectorCountrySignOff, 'then', null, 'Completed');
     $activityService->setAcl($activityFinal, $aclUser, $this->vars['reconciler']);
     $activityService->setControls($activityFinal, array(INSTANCE_CONTROL_FORWARD));
     $activityService->setHidden($activityFinal, true);
     $activityTDSignOffBis = $authoringService->createConditionalActivity($connectorCountrySignOff, 'else', $activityTDSignOff);
     $this->assertEqual($activityTDSignOff->getUri(), $activityTDSignOffBis->getUri());
     //end of process definition
     $this->processDefinition['CBA'] = $processDefinition;
 }
 public function testGetPreviousActivities()
 {
     /*
      *  activity > connector1(COND)
      *  -> THEN  > thenConnector(SQ)
      *  -> ELSE > elseConnector (SQ)
      *  -> Act3 > connector2(PARA)
      *  -> Act4 > connector3(JOIN)
      *  -> Act5 > connector4(JOIN)
      * 	-> Acto6
      *
      */
     $connector1 = $this->authoringService->createConnector($this->activity);
     $then = $this->authoringService->createConditionalActivity($connector1, 'then');
     //create "Activity_2"
     $thenConnector = $this->authoringService->createConnector($then, 'then Connector');
     //create "Activity_2"
     $else = $this->authoringService->createConditionalActivity($connector1, 'else', null, '', true);
     //create another connector
     $elseConnector = $this->authoringService->createConnector($else, 'else Connector');
     //create "Activity_2"
     $activity3 = $this->authoringService->createSequenceActivity($thenConnector, null, 'Act3');
     $this->authoringService->createSequenceActivity($elseConnector, $activity3);
     $connector1PrevAct = $this->service->getPreviousActivities($connector1);
     $this->assertInternalType('array', $connector1PrevAct);
     $this->assertTrue(sizeof($connector1PrevAct) == 1);
     if (isset($connector1PrevAct[0]) && $connector1PrevAct[0] instanceof core_kernel_classes_Resource) {
         $this->assertTrue($connector1PrevAct[0]->getUri() == $this->activity->getUri());
     }
     $elsePrevAct = $this->service->getPreviousActivities($elseConnector);
     $this->assertInternalType('array', $elsePrevAct);
     $this->assertTrue(sizeof($elsePrevAct) == 1);
     if (isset($elsePrevAct[0]) && $elsePrevAct[0] instanceof core_kernel_classes_Resource) {
         $this->assertTrue($elsePrevAct[0]->getUri() == $else->getUri());
     }
     $thenPrevAct = $this->service->getPreviousActivities($thenConnector);
     $this->assertInternalType('array', $thenPrevAct);
     $this->assertTrue(sizeof($thenPrevAct) == 1);
     if (isset($thenPrevAct[0]) && $thenPrevAct[0] instanceof core_kernel_classes_Resource) {
         $this->assertTrue($thenPrevAct[0]->getUri() == $then->getUri());
     }
     $myProcessVar1 = $this->variableService->getProcessVariable('myProcessVarCode1', true);
     $transitionRule = $this->authoringService->createTransitionRule($connector1, '^myProcessVarCode1 == 1');
     $connector2 = $this->authoringService->createConnector($activity3);
     $activity4 = $this->authoringService->createActivity($this->processDefinition, 'activity4 for interactive service unit test');
     $connector3 = $this->authoringService->createConnector($activity4);
     $activity5 = $this->authoringService->createActivity($this->processDefinition, 'activity5 for interactive service unit test');
     $connector4 = $this->authoringService->createConnector($activity5);
     $newActivitiesArray = array($activity4->getUri() => 2, $activity5->getUri() => 3);
     $this->authoringService->setParallelActivities($connector2, $newActivitiesArray);
     $activity6 = $this->authoringService->createActivity($this->processDefinition);
     $connector3 = wfAuthoring_models_classes_ConnectorService::singleton()->createJoin(array($activity4, $activity5), $activity6);
     /*
             $activity6 = $this->authoringService->createJoinActivity($connector3, null, '', $activity4);
     $activity7 = $this->authoringService->createJoinActivity($connector4, $activity6, '', $activity5);
     */
     $this->assertEquals(count($this->service->getNextActivities($connector2)), 2);
     $activity3PrevActi = $this->service->getPreviousActivities($connector2);
     $this->assertInternalType('array', $activity3PrevActi);
     $this->assertTrue(sizeof($activity3PrevActi) == 1);
     if (isset($activity3PrevActi[0]) && $activity3PrevActi[0] instanceof core_kernel_classes_Resource) {
         $this->assertTrue($activity3PrevActi[0]->getUri() == $activity3->getUri());
     }
     $activity4PrevActi = $this->service->getPreviousSteps($connector3);
     $this->assertInternalType('array', $activity4PrevActi);
     $this->assertEquals(sizeof($activity4PrevActi), 2);
     $cardinalityService = wfEngine_models_classes_ActivityCardinalityService::singleton();
     $prevActivitiesarrayCount = array();
     foreach ($activity4PrevActi as $cardinality) {
         $this->assertTrue($cardinalityService->isCardinality($cardinality));
         $activities = $cardinalityService->getPreviousSteps($cardinality);
         $this->assertEquals(count($activities), 1);
         $activity = current($activities);
         $keyExists = array_key_exists($activity->getUri(), $newActivitiesArray);
         $this->assertTrue($keyExists);
         if ($keyExists) {
             $prevActivitiesarrayCount[$activity->getUri()] = $cardinalityService->getCardinality($cardinality);
         }
     }
     $this->assertEquals($prevActivitiesarrayCount, $newActivitiesArray);
     $then->delete(true);
     $else->delete(true);
     $activity3->delete(true);
     $activity4->delete(true);
     $activity5->delete(true);
     $activity6->delete(true);
     $transitionRule->delete(true);
     $connector1->delete(true);
     $connector2->delete(true);
     $connector3->delete(true);
     $connector4->delete(true);
 }
 /**
  * Return dispatched process variables values, by activity definiiton
  *
  * @access public
  * @author Somsack Sipasseuth, <*****@*****.**>
  * @param  Resource activityExecution
  * @param  Resource connector
  * @return array
  */
 public function getSplitVariables(core_kernel_classes_Resource $activityExecution, core_kernel_classes_Resource $connector)
 {
     $returnValue = array();
     $connectorService = wfEngine_models_classes_ConnectorService::singleton();
     $cardinalityService = wfEngine_models_classes_ActivityCardinalityService::singleton();
     $allSplitVariables = array();
     foreach ($connectorService->getNextActivities($connector) as $cardinality) {
         if ($cardinalityService->isCardinality($cardinality)) {
             $splitVars = $cardinalityService->getSplitVariables($cardinality);
             $activity = $cardinalityService->getDestination($cardinality);
             if (!is_null($activity) && !empty($splitVars)) {
                 $allSplitVariables[$activity->getUri()] = $splitVars;
             }
         }
     }
     $codeProperty = new core_kernel_classes_Property(PROPERTY_PROCESSVARIABLES_CODE);
     foreach ($allSplitVariables as $activityUri => $splitVariables) {
         $returnValue[$activityUri] = array();
         foreach ($splitVariables as $splitVariable) {
             if ($splitVariable instanceof core_kernel_classes_Resource) {
                 $codeLiteral = $splitVariable->getOnePropertyValue($codeProperty);
                 if (!is_null($codeLiteral) && $codeLiteral instanceof core_kernel_classes_Literal) {
                     $code = $codeLiteral->literal;
                     $serialisedValues = $activityExecution->getOnePropertyValue(new core_kernel_classes_Property($splitVariable->getUri()));
                     if (!empty($serialisedValues) && $serialisedValues instanceof core_kernel_classes_Literal) {
                         $values = unserialize($serialisedValues);
                         if ($values && is_array($values) && !empty($values)) {
                             $count = count($values);
                             for ($i = 0; $i < $count; $i++) {
                                 if (!isset($returnValue[$activityUri][$i])) {
                                     $returnValue[$activityUri][$i] = array();
                                 }
                                 $returnValue[$activityUri][$i][$code] = $values[$i];
                             }
                         }
                     }
                 }
             }
         }
     }
     return (array) $returnValue;
 }
 /**
  * Short description of method trigger
  *
  * @access public
  * @author Somsack Sipasseuth, <*****@*****.**>
  * @param  Resource connector
  * @param  Resource activityExecution
  * @param  Resource processExecution
  * @return int
  */
 public function trigger(core_kernel_classes_Resource $connector, core_kernel_classes_Resource $activityExecution, core_kernel_classes_Resource $processExecution = null)
 {
     $returnValue = (int) 0;
     if (!is_null($connector) && !is_null($activityExecution)) {
         //initialize properties
         $connectorUserNotifiedProp = new core_kernel_classes_Property(PROPERTY_CONNECTORS_USER_NOTIFIED);
         $connectorRoleNotifiedProp = new core_kernel_classes_Property(PROPERTY_CONNECTORS_ROLE_NOTIFIED);
         $connectorNextActivitiesProp = new core_kernel_classes_Property(PROPERTY_STEP_NEXT);
         $activityExecutionUserProp = new core_kernel_classes_Property(PROPERTY_ACTIVITY_EXECUTION_CURRENT_USER);
         $activityAclModeProp = new core_kernel_classes_Property(PROPERTY_ACTIVITIES_ACL_MODE);
         $activityAclUserProp = new core_kernel_classes_Property(PROPERTY_ACTIVITIES_RESTRICTED_USER);
         $activityAclRoleProp = new core_kernel_classes_Property(PROPERTY_ACTIVITIES_RESTRICTED_ROLE);
         $connectorService = wfEngine_models_classes_ConnectorService::singleton();
         $transitionRuleService = wfEngine_models_classes_TransitionRuleService::singleton();
         $roleService = wfEngine_models_classes_RoleService::singleton();
         $activityExecutionService = wfEngine_models_classes_ActivityExecutionService::singleton();
         $processExecutionService = wfEngine_models_classes_ProcessExecutionService::singleton();
         if (is_null($processExecution)) {
             $processExecution = $activityExecutionService->getRelatedProcessExecution($activityExecution);
         }
         $users = array();
         //get the notifications mode defined for that connector
         $notifyModes = $connector->getPropertyValuesCollection(new core_kernel_classes_Property(PROPERTY_CONNECTORS_NOTIFY));
         foreach ($notifyModes->getIterator() as $notify) {
             $nextActivities = array();
             //get the users regarding the notification mode
             switch ($notify->getUri()) {
                 //users directly defined
                 case INSTANCE_NOTIFY_USER:
                     foreach ($connector->getPropertyValues($connectorUserNotifiedProp) as $userUri) {
                         if (!in_array($userUri, $users)) {
                             $users[] = $userUri;
                         }
                     }
                     break;
                     //users from roles directly defined
                 //users from roles directly defined
                 case INSTANCE_NOTIFY_ROLE:
                     foreach ($connector->getPropertyValues($connectorRoleNotifiedProp) as $roleUri) {
                         foreach ($roleService->getUsers(new core_kernel_classes_Resource($roleUri)) as $userUri) {
                             if (!in_array($userUri, $users)) {
                                 $users[] = $userUri;
                             }
                         }
                     }
                     break;
                     //get the users who have executed the previous activity
                 //get the users who have executed the previous activity
                 case INSTANCE_NOTIFY_PREVIOUS:
                     $previousActivities = array();
                     $cardinalityService = wfEngine_models_classes_ActivityCardinalityService::singleton();
                     foreach ($connectorService->getPreviousActivities($connector) as $prevActivity) {
                         if ($cardinalityService->isCardinality($prevActivity)) {
                             $previousActivities[] = $cardinalityService->getSource($prevActivity)->getUri();
                         } else {
                             $previousActivities[] = $prevActivity->getUri();
                         }
                     }
                     $activity = $activityExecutionService->getExecutionOf($activityExecution);
                     //check activity execution against connector
                     if (in_array($activity->getUri(), $previousActivities)) {
                         $activityExecutionUser = $activityExecutionService->getActivityExecutionUser($activityExecution);
                         if (!is_null($activityExecutionUser)) {
                             if (!in_array($activityExecutionUser->getUri(), $users)) {
                                 $users[] = $activityExecutionUser->getUri();
                             }
                         }
                     }
                     break;
                     //get the users
                 //get the users
                 case INSTANCE_NOTIFY_THEN:
                     if ($connectorService->getType($connector)->getUri() == INSTANCE_TYPEOFCONNECTORS_CONDITIONAL) {
                         $transitionRule = $connectorService->getTransitionRule($connector);
                         if ($transitionRule instanceof core_kernel_classes_Resource) {
                             $then = $transitionRuleService->getThenActivity($transitionRule);
                             if ($then instanceof core_kernel_classes_Resource) {
                                 $nextActivities[] = $then->getUri();
                             }
                         }
                     } else {
                         //wrong connector type!
                         break;
                     }
                     //do not break, continue to the INSTANCE_NOTIFY_NEXT case
                 case INSTANCE_NOTIFY_ELSE:
                     if (empty($nextActivities)) {
                         if ($connectorService->getType($connector)->getUri() == INSTANCE_TYPEOFCONNECTORS_CONDITIONAL) {
                             $transitionRule = $connectorService->getTransitionRule($connector);
                             if ($transitionRule instanceof core_kernel_classes_Resource) {
                                 $else = $transitionRuleService->getElseActivity($transitionRule);
                                 if ($else instanceof core_kernel_classes_Resource) {
                                     $nextActivities[] = $else->getUri();
                                 }
                             }
                         } else {
                             //wrong connector type!
                             break;
                         }
                     }
                     //do not break, continue to the INSTANCE_NOTIFY_NEXT case
                 case INSTANCE_NOTIFY_NEXT:
                     if (empty($nextActivities)) {
                         $cardinalityService = wfEngine_models_classes_ActivityCardinalityService::singleton();
                         foreach ($connectorService->getNextActivities($connector) as $nextActivity) {
                             if ($cardinalityService->isCardinality($nextActivity)) {
                                 $nextActivities[] = $cardinalityService->getDestination($nextActivity)->getUri();
                             } else {
                                 $nextActivities[] = $nextActivity->getUri();
                             }
                         }
                     }
                     $nextActivityExecutions = $activityExecutionService->getFollowing($activityExecution);
                     foreach ($nextActivityExecutions as $activityExec) {
                         $activity = $activityExecutionService->getExecutionOf($activityExec);
                         if (!in_array($activity->getUri(), $nextActivities)) {
                             //invalid activity exec
                             continue;
                         }
                         //check if it is among the next activity of the connector:
                         $mode = $activityExecutionService->getAclMode($activityExec);
                         if ($mode instanceof core_kernel_classes_Resource) {
                             switch ($mode->getUri()) {
                                 case INSTANCE_ACL_USER:
                                     $restrictedUser = $activityExecutionService->getRestrictedUser($activityExec);
                                     //@TODO: implemente multiple restricted users?
                                     if (!is_null($restrictedUser)) {
                                         if (!in_array($restrictedUser->getUri(), $users)) {
                                             $users[] = $restrictedUser->getUri();
                                         }
                                     }
                                     break;
                                 case INSTANCE_ACL_ROLE:
                                 case INSTANCE_ACL_ROLE_RESTRICTED_USER:
                                 case INSTANCE_ACL_ROLE_RESTRICTED_USER_INHERITED:
                                     $restrictedRole = $activityExecutionService->getRestrictedRole($activityExec);
                                     //@TODO: implemente multiple restricted roles?
                                     if (!is_null($restrictedRole)) {
                                         foreach ($roleService->getUsers($restrictedRole) as $userUri) {
                                             if (!in_array($userUri, $users)) {
                                                 $users[] = $userUri;
                                             }
                                         }
                                     }
                                     break;
                             }
                         }
                     }
                     break;
             }
         }
         //build notification message for every user here:
         foreach ($users as $userUri) {
             if ($this->createNotification($connector, new core_kernel_classes_Resource($userUri), $activityExecution, $processExecution)) {
                 //get message from connector:
                 //replace SPX in message bodies
                 $returnValue++;
             }
         }
     }
     return (int) $returnValue;
 }