/** * 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; }