public override void Execute(IExecutionEntity execution) { try { bool isSkipExpressionEnabled = SkipExpressionUtil.IsSkipExpressionEnabled(execution, skipExpression); if (!isSkipExpressionEnabled || (isSkipExpressionEnabled && !SkipExpressionUtil.ShouldSkipFlowElement(execution, skipExpression))) { if (Context.ProcessEngineConfiguration.EnableProcessDefinitionInfoCache) { JToken taskElementProperties = Context.GetBpmnOverrideElementProperties(serviceTaskId, execution.ProcessDefinitionId); if (taskElementProperties != null && taskElementProperties[DynamicBpmnConstants.SERVICE_TASK_EXPRESSION] != null) { string overrideExpression = taskElementProperties[DynamicBpmnConstants.SERVICE_TASK_EXPRESSION].ToString(); if (!string.IsNullOrWhiteSpace(overrideExpression) && !overrideExpression.Equals(expression.ExpressionText)) { expression = Context.ProcessEngineConfiguration.ExpressionManager.CreateExpression(overrideExpression); } } } object value = expression.GetValue(execution); if (!(resultVariable is null)) { execution.SetVariable(resultVariable, value); } } Leave(execution); } catch (Exception exc) { Exception cause = exc; BpmnError error = null; while (cause != null) { if (cause is BpmnError) { error = (BpmnError)cause; break; } cause = cause.InnerException; } if (error != null) { ErrorPropagation.PropagateError(error, execution); } else { throw new ActivitiException("Could not execute service task expression", exc); } } }
// private static Logger log = LoggerFactory.getLogger(typeof(ExclusiveGatewayActivityBehavior)); /// <summary> /// The default behaviour of BPMN, taking every outgoing sequence flow (where the condition evaluates to true), is not valid for an exclusive gateway. /// /// Hence, this behaviour is overridden and replaced by the correct behavior: selecting the first sequence flow which condition evaluates to true (or which hasn't got a condition) and leaving the /// activity through that sequence flow. /// /// If no sequence flow is selected (ie all conditions evaluate to false), then the default sequence flow is taken (if defined). /// </summary> public override void Leave(IExecutionEntity execution) { if (log.IsEnabled(LogLevel.Debug)) { log.LogDebug($"Leaving exclusive gateway '{execution.CurrentActivityId}'"); } ExclusiveGateway exclusiveGateway = (ExclusiveGateway)execution.CurrentFlowElement; ProcessEngineConfigurationImpl processEngineConfiguration = Context.ProcessEngineConfiguration; if (processEngineConfiguration is object && processEngineConfiguration.EventDispatcher.Enabled) { processEngineConfiguration.EventDispatcher.DispatchEvent(ActivitiEventBuilder.CreateActivityEvent(ActivitiEventType.ACTIVITY_COMPLETED, exclusiveGateway.Id, exclusiveGateway.Name, execution.Id, execution.ProcessInstanceId, execution.ProcessDefinitionId, exclusiveGateway)); } SequenceFlow outgoingSequenceFlow = null; SequenceFlow defaultSequenceFlow = null; string defaultSequenceFlowId = exclusiveGateway.DefaultFlow; // Determine sequence flow to take foreach (SequenceFlow sequenceFlow in exclusiveGateway.OutgoingFlows) { string skipExpressionString = sequenceFlow.SkipExpression; if (!SkipExpressionUtil.IsSkipExpressionEnabled(execution, skipExpressionString)) { bool conditionEvaluatesToTrue = ConditionUtil.HasTrueCondition(sequenceFlow, execution); if (conditionEvaluatesToTrue && (defaultSequenceFlowId is null || !defaultSequenceFlowId.Equals(sequenceFlow.Id))) { if (log.IsEnabled(LogLevel.Debug)) { log.LogDebug($"Sequence flow '{sequenceFlow.Id}'selected as outgoing sequence flow."); } outgoingSequenceFlow = sequenceFlow; break; } } else if (SkipExpressionUtil.ShouldSkipFlowElement(Context.CommandContext, execution, skipExpressionString)) { outgoingSequenceFlow = sequenceFlow; break; } // Already store it, if we would need it later. Saves one for loop. if (defaultSequenceFlowId is object && defaultSequenceFlowId.Equals(sequenceFlow.Id)) { defaultSequenceFlow = sequenceFlow; } } // We have to record the end here, or else we're already past it Context.CommandContext.HistoryManager.RecordActivityEnd(execution, null); // Leave the gateway if (outgoingSequenceFlow != null) { execution.CurrentFlowElement = outgoingSequenceFlow; log.LogInformation($"条件表达式:id={outgoingSequenceFlow.Id} expression={outgoingSequenceFlow.ConditionExpression}"); } else { if (defaultSequenceFlow != null) { execution.CurrentFlowElement = defaultSequenceFlow; log.LogInformation($"条件表达式:id={defaultSequenceFlow.Id} expression={defaultSequenceFlow.ConditionExpression}"); } else { // No sequence flow could be found, not even a default one throw new ActivitiException("No outgoing sequence flow of the exclusive gateway '" + exclusiveGateway.Id + "' could be selected for continuing the process"); } } base.Leave(execution); }
/// <summary> /// /// </summary> /// <param name="flowNode"></param> protected internal virtual void LeaveFlowNode(FlowNode flowNode) { log.LogDebug($"Leaving flow node {flowNode.GetType()} with id '{flowNode.Id}' by following it's {flowNode.OutgoingFlows.Count} outgoing sequenceflow"); // Get default sequence flow (if set) string defaultSequenceFlowId = null; if (flowNode is Activity) { defaultSequenceFlowId = ((Activity)flowNode).DefaultFlow; } else if (flowNode is Gateway) { defaultSequenceFlowId = ((Gateway)flowNode).DefaultFlow; } // Determine which sequence flows can be used for leaving IList <SequenceFlow> outgoingSequenceFlows = new List <SequenceFlow>(); foreach (SequenceFlow sequenceFlow in flowNode.OutgoingFlows) { string skipExpressionString = sequenceFlow.SkipExpression; if (!SkipExpressionUtil.IsSkipExpressionEnabled(execution, skipExpressionString)) { if (!evaluateConditions || (evaluateConditions && ConditionUtil.HasTrueCondition(sequenceFlow, execution) && (defaultSequenceFlowId is null || !defaultSequenceFlowId.Equals(sequenceFlow.Id)))) { outgoingSequenceFlows.Add(sequenceFlow); } } else if (flowNode.OutgoingFlows.Count == 1 || SkipExpressionUtil.ShouldSkipFlowElement(commandContext, execution, skipExpressionString)) { // The 'skip' for a sequence flow means that we skip the condition, not the sequence flow. outgoingSequenceFlows.Add(sequenceFlow); } } // Check if there is a default sequence flow if (outgoingSequenceFlows.Count == 0 && evaluateConditions) { // The elements that set this to false also have no support for default sequence flow if (defaultSequenceFlowId is object) { foreach (SequenceFlow sequenceFlow in flowNode.OutgoingFlows) { if (defaultSequenceFlowId.Equals(sequenceFlow.Id)) { outgoingSequenceFlows.Add(sequenceFlow); break; } } } } // No outgoing found. Ending the execution if (outgoingSequenceFlows.Count == 0) { if (flowNode.OutgoingFlows == null || flowNode.OutgoingFlows.Count == 0) { log.LogDebug($"No outgoing sequence flow found for flow node '{flowNode.Id}'."); Context.Agenda.PlanEndExecutionOperation(execution); } else { throw new ActivitiException("No outgoing sequence flow of element '" + flowNode.Id + "' could be selected for continuing the process"); } } else { // Leave, and reuse the incoming sequence flow, make executions for all the others (if applicable) IExecutionEntityManager executionEntityManager = commandContext.ExecutionEntityManager; IList <IExecutionEntity> outgoingExecutions = new List <IExecutionEntity>(flowNode.OutgoingFlows.Count); SequenceFlow sequenceFlow = outgoingSequenceFlows[0]; // Reuse existing one execution.CurrentFlowElement = sequenceFlow; execution.IsActive = true; outgoingExecutions.Add(execution); // Executions for all the other one if (outgoingSequenceFlows.Count > 1) { for (int i = 1; i < outgoingSequenceFlows.Count; i++) { IExecutionEntity parent = execution.ParentId is object?execution.Parent : execution; IExecutionEntity outgoingExecutionEntity = commandContext.ExecutionEntityManager.CreateChildExecution(parent); SequenceFlow outgoingSequenceFlow = outgoingSequenceFlows[i]; outgoingExecutionEntity.CurrentFlowElement = outgoingSequenceFlow; executionEntityManager.Insert(outgoingExecutionEntity); outgoingExecutions.Add(outgoingExecutionEntity); } } // Leave (only done when all executions have been made, since some queries depend on this) foreach (IExecutionEntity outgoingExecution in outgoingExecutions) { Context.Agenda.PlanContinueProcessOperation(outgoingExecution); } } }
/// <summary> /// /// </summary> /// <param name="execution"></param> public override void Execute(IExecutionEntity execution) { ICommandContext commandContext = Context.CommandContext; ITaskEntityManager taskEntityManager = commandContext.TaskEntityManager; //如果当前任务为补偿任务,则修改任务的父级为流程实例 if ((execution.CurrentFlowElement as UserTask).ForCompensation) { execution.Parent = execution.ProcessInstance; } ITaskEntity task = taskEntityManager.Create(); task.Execution = execution; task.TaskDefinitionKey = userTask.Id; task.IsRuntimeAssignee(); task.CanTransfer = userTask.CanTransfer; task.OnlyAssignee = task.OnlyAssignee; ProcessEngineConfigurationImpl processEngineConfiguration = Context.ProcessEngineConfiguration; ExpressionManager expressionManager = processEngineConfiguration.ExpressionManager; string activeTaskName; string activeTaskDescription; string activeTaskDueDate; string activeTaskCategory; string activeTaskSkipExpression; string activeTaskPriority; string activeTaskFormKey; string activeTaskAssignee; string activeTaskOwner; IList <string> activeTaskCandidateUsers; IList <string> activeTaskCandidateGroups; if (Context.ProcessEngineConfiguration.EnableProcessDefinitionInfoCache) { JToken taskElementProperties = Context.GetBpmnOverrideElementProperties(userTask.Id, execution.ProcessDefinitionId); activeTaskName = GetActiveValue(userTask.Name, DynamicBpmnConstants.USER_TASK_NAME, taskElementProperties); activeTaskDescription = GetActiveValue(userTask.Documentation, DynamicBpmnConstants.USER_TASK_DESCRIPTION, taskElementProperties); activeTaskDueDate = GetActiveValue(userTask.DueDate, DynamicBpmnConstants.USER_TASK_DUEDATE, taskElementProperties); activeTaskPriority = GetActiveValue(userTask.Priority, DynamicBpmnConstants.USER_TASK_PRIORITY, taskElementProperties); activeTaskCategory = GetActiveValue(userTask.Category, DynamicBpmnConstants.USER_TASK_CATEGORY, taskElementProperties); activeTaskFormKey = GetActiveValue(userTask.FormKey, DynamicBpmnConstants.USER_TASK_FORM_KEY, taskElementProperties); activeTaskSkipExpression = GetActiveValue(userTask.SkipExpression, DynamicBpmnConstants.TASK_SKIP_EXPRESSION, taskElementProperties); activeTaskAssignee = GetActiveValue(userTask.Assignee, DynamicBpmnConstants.USER_TASK_ASSIGNEE, taskElementProperties); activeTaskOwner = GetActiveValue(userTask.Owner, DynamicBpmnConstants.USER_TASK_OWNER, taskElementProperties); activeTaskCandidateUsers = GetActiveValueList(userTask.CandidateUsers, DynamicBpmnConstants.USER_TASK_CANDIDATE_USERS, taskElementProperties); activeTaskCandidateGroups = GetActiveValueList(userTask.CandidateGroups, DynamicBpmnConstants.USER_TASK_CANDIDATE_GROUPS, taskElementProperties); } else { activeTaskName = userTask.Name; activeTaskDescription = userTask.Documentation; activeTaskDueDate = userTask.DueDate; activeTaskPriority = userTask.Priority; activeTaskCategory = userTask.Category; activeTaskFormKey = userTask.FormKey; activeTaskSkipExpression = userTask.SkipExpression; activeTaskAssignee = userTask.Assignee; activeTaskOwner = userTask.Owner; activeTaskCandidateUsers = userTask.CandidateUsers; activeTaskCandidateGroups = userTask.CandidateGroups; } if (!string.IsNullOrWhiteSpace(activeTaskName)) { string name; try { name = (string)expressionManager.CreateExpression(activeTaskName).GetValue(execution); } catch (ActivitiException e) { name = activeTaskName; log.LogWarning("property not found in task name expression " + e.Message); } task.Name = name; } if (!string.IsNullOrWhiteSpace(activeTaskDescription)) { string description; try { description = (string)expressionManager.CreateExpression(activeTaskDescription).GetValue(execution); } catch (ActivitiException e) { description = activeTaskDescription; log.LogWarning("property not found in task description expression " + e.Message); } task.Description = description; } if (!string.IsNullOrWhiteSpace(activeTaskDueDate)) { object dueDate = expressionManager.CreateExpression(activeTaskDueDate).GetValue(execution); if (dueDate != null) { if (dueDate is DateTime time) { task.DueDate = time; } else if (dueDate is string @string) { string businessCalendarName; if (!string.IsNullOrWhiteSpace(userTask.BusinessCalendarName)) { businessCalendarName = expressionManager.CreateExpression(userTask.BusinessCalendarName).GetValue(execution).ToString(); } else { businessCalendarName = DueDateBusinessCalendar.NAME; } IBusinessCalendar businessCalendar = Context.ProcessEngineConfiguration.BusinessCalendarManager.GetBusinessCalendar(businessCalendarName); task.DueDate = businessCalendar.ResolveDuedate(@string); } else { throw new ActivitiIllegalArgumentException("Due date expression does not resolve to a Date or Date string: " + activeTaskDueDate); } } } if (!string.IsNullOrWhiteSpace(activeTaskPriority)) { object priority = expressionManager.CreateExpression(activeTaskPriority).GetValue(execution); if (priority != null) { if (priority is string @string) { try { task.Priority = Convert.ToInt32(@string); } catch (FormatException e) { throw new ActivitiIllegalArgumentException("Priority does not resolve to a number: " + priority, e); } } else if (priority is int || priority is long) { task.Priority = (int)priority; } else { throw new ActivitiIllegalArgumentException("Priority expression does not resolve to a number: " + activeTaskPriority); } } } if (!string.IsNullOrWhiteSpace(activeTaskCategory)) { object category = expressionManager.CreateExpression(activeTaskCategory).GetValue(execution); if (category != null) { if (category is string) { task.Category = category.ToString(); } else { throw new ActivitiIllegalArgumentException("Category expression does not resolve to a string: " + activeTaskCategory); } } } if (!string.IsNullOrWhiteSpace(activeTaskFormKey)) { object formKey = expressionManager.CreateExpression(activeTaskFormKey).GetValue(execution); if (formKey != null) { if (formKey is string) { task.FormKey = formKey.ToString(); } else { throw new ActivitiIllegalArgumentException("FormKey expression does not resolve to a string: " + activeTaskFormKey); } } } taskEntityManager.Insert(task, execution); bool skipUserTask = false; if (!string.IsNullOrWhiteSpace(activeTaskSkipExpression)) { IExpression skipExpression = expressionManager.CreateExpression(activeTaskSkipExpression); skipUserTask = SkipExpressionUtil.IsSkipExpressionEnabled(execution, skipExpression) && SkipExpressionUtil.ShouldSkipFlowElement(execution, skipExpression); } // Handling assignments need to be done after the task is inserted, to have an id if (!skipUserTask) { HandleAssignments(taskEntityManager, activeTaskAssignee, activeTaskOwner, activeTaskCandidateUsers, activeTaskCandidateGroups, task, expressionManager, execution); } processEngineConfiguration.ListenerNotificationHelper.ExecuteTaskListeners(task, BaseTaskListenerFields.EVENTNAME_CREATE); // All properties set, now fire events if (Context.ProcessEngineConfiguration.EventDispatcher.Enabled) { IActivitiEventDispatcher eventDispatcher = Context.ProcessEngineConfiguration.EventDispatcher; eventDispatcher.DispatchEvent(ActivitiEventBuilder.CreateEntityEvent(ActivitiEventType.TASK_CREATED, task)); if (string.IsNullOrWhiteSpace(task.Assignee) == false) { eventDispatcher.DispatchEvent(ActivitiEventBuilder.CreateEntityEvent(ActivitiEventType.TASK_ASSIGNED, task)); } } if (skipUserTask) { taskEntityManager.DeleteTask(task, null, false, false); Leave(execution); } }
public override void Execute(IExecutionEntity execution) { try { bool isSkipExpressionEnabled = SkipExpressionUtil.IsSkipExpressionEnabled(execution, skipExpression); if (!isSkipExpressionEnabled || (isSkipExpressionEnabled && !SkipExpressionUtil.ShouldSkipFlowElement(execution, skipExpression))) { if (Context.ProcessEngineConfiguration.EnableProcessDefinitionInfoCache) { JToken taskElementProperties = Context.GetBpmnOverrideElementProperties(serviceTaskId, execution.ProcessDefinitionId); if (taskElementProperties != null && taskElementProperties[DynamicBpmnConstants.SERVICE_TASK_DELEGATE_EXPRESSION] != null) { string overrideExpression = taskElementProperties[DynamicBpmnConstants.SERVICE_TASK_DELEGATE_EXPRESSION].ToString(); if (!string.IsNullOrWhiteSpace(overrideExpression) && !overrideExpression.Equals(expression.ExpressionText)) { expression = Context.ProcessEngineConfiguration.ExpressionManager.CreateExpression(overrideExpression); } } } object @delegate = DelegateExpressionUtil.ResolveDelegateExpression(expression, execution, fieldDeclarations); if (@delegate is IActivityBehavior) { if (@delegate is AbstractBpmnActivityBehavior) { ((AbstractBpmnActivityBehavior)@delegate).MultiInstanceActivityBehavior = MultiInstanceActivityBehavior; } Context.ProcessEngineConfiguration.DelegateInterceptor.HandleInvocation(new ActivityBehaviorInvocation((IActivityBehavior)@delegate, execution)); } else if (@delegate is ICSharpDelegate) { Context.ProcessEngineConfiguration.DelegateInterceptor.HandleInvocation(new CSharpDelegateInvocation((ICSharpDelegate)@delegate, execution)); Leave(execution); } else { throw new ActivitiIllegalArgumentException("Delegate expression " + expression + " did neither resolve to an implementation of " + typeof(IActivityBehavior) + " nor " + typeof(ICSharpDelegate)); } } else { Leave(execution); } } catch (Exception exc) { Exception cause = exc; BpmnError error = null; while (cause != null) { if (cause is BpmnError) { error = (BpmnError)cause; break; } cause = cause.InnerException; } if (error != null) { ErrorPropagation.PropagateError(error, execution); } else { throw new ActivitiException(exc.Message, exc); } } }