protected internal virtual void DefaultTerminateEndEventBehaviour(IExecutionEntity execution, ICommandContext commandContext, IExecutionEntityManager executionEntityManager)
        {
            IExecutionEntity scopeExecutionEntity = executionEntityManager.FindFirstScope(execution);

            SendProcessInstanceCancelledEvent(scopeExecutionEntity, execution.CurrentFlowElement);

            // If the scope is the process instance, we can just terminate it all
            // Special treatment is needed when the terminated activity is a subprocess (embedded/callactivity/..)
            // The subprocess is destroyed, but the execution calling it, continues further on.
            // In case of a multi-instance subprocess, only one instance is terminated, the other instances continue to exist.

            string deleteReason = CreateDeleteReason(execution.CurrentActivityId);

            if (scopeExecutionEntity.ProcessInstanceType && scopeExecutionEntity.SuperExecutionId is null)
            {
                EndAllHistoricActivities(scopeExecutionEntity.Id, deleteReason);
                DeleteExecutionEntities(executionEntityManager, scopeExecutionEntity, deleteReason);
                commandContext.HistoryManager.RecordProcessInstanceEnd(scopeExecutionEntity.Id, deleteReason, execution.CurrentActivityId);
            }
            else if (scopeExecutionEntity.CurrentFlowElement != null && scopeExecutionEntity.CurrentFlowElement is SubProcess)
            { // SubProcess
                SubProcess subProcess = (SubProcess)scopeExecutionEntity.CurrentFlowElement;

                scopeExecutionEntity.DeleteReason = deleteReason;
                if (subProcess.HasMultiInstanceLoopCharacteristics())
                {
                    Context.Agenda.PlanDestroyScopeOperation(scopeExecutionEntity);
                    MultiInstanceActivityBehavior multiInstanceBehavior = (MultiInstanceActivityBehavior)subProcess.Behavior;
                    multiInstanceBehavior.Leave(scopeExecutionEntity);
                }
                else
                {
                    Context.Agenda.PlanDestroyScopeOperation(scopeExecutionEntity);
                    IExecutionEntity outgoingFlowExecution = executionEntityManager.CreateChildExecution(scopeExecutionEntity.Parent);
                    outgoingFlowExecution.CurrentFlowElement = scopeExecutionEntity.CurrentFlowElement;
                    Context.Agenda.PlanTakeOutgoingSequenceFlowsOperation(outgoingFlowExecution, true);
                }
            }
            else if (scopeExecutionEntity.ParentId is null && scopeExecutionEntity.SuperExecutionId is object)
            { // CallActivity
                IExecutionEntity callActivityExecution = scopeExecutionEntity.SuperExecution;
                CallActivity     callActivity          = (CallActivity)callActivityExecution.CurrentFlowElement;

                if (callActivity.HasMultiInstanceLoopCharacteristics())
                {
                    MultiInstanceActivityBehavior multiInstanceBehavior = (MultiInstanceActivityBehavior)callActivity.Behavior;
                    multiInstanceBehavior.Leave(callActivityExecution);
                    executionEntityManager.DeleteProcessInstanceExecutionEntity(scopeExecutionEntity.Id, execution.CurrentFlowElement.Id, "terminate end event", false, false);
                }
                else
                {
                    executionEntityManager.DeleteProcessInstanceExecutionEntity(scopeExecutionEntity.Id, execution.CurrentFlowElement.Id, "terminate end event", false, false);
                    IExecutionEntity superExecutionEntity = executionEntityManager.FindById <IExecutionEntity>(scopeExecutionEntity.SuperExecutionId);
                    Context.Agenda.PlanTakeOutgoingSequenceFlowsOperation(superExecutionEntity, true);
                }
            }
        }
Example #2
0
        public override void Leave(IExecutionEntity execution, object signalData)
        {
            FlowElement currentFlowElement             = execution.CurrentFlowElement;
            ICollection <BoundaryEvent> boundaryEvents = FindBoundaryEventsForFlowNode(execution.ProcessDefinitionId, currentFlowElement);

            if (CollectionUtil.IsNotEmpty(boundaryEvents))
            {
                ExecuteCompensateBoundaryEvents(boundaryEvents, execution);
            }
            if (!HasLoopCharacteristics())
            {
                base.Leave(execution, signalData);
            }
            else if (HasMultiInstanceCharacteristics())
            {
                multiInstanceActivityBehavior.Leave(execution, signalData);
            }
        }