Ejemplo n.º 1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="executionEntityManager"></param>
        /// <param name="parentExecution"></param>
        /// <param name="subProcess"></param>
        /// <returns></returns>
        protected internal virtual IExecutionEntity HandleSubProcessEnd(IExecutionEntityManager executionEntityManager, IExecutionEntity parentExecution, SubProcess subProcess)
        {
            // create a new execution to take the outgoing sequence flows
            IExecutionEntity executionToContinue = executionEntityManager.CreateChildExecution(parentExecution.Parent);

            executionToContinue.CurrentFlowElement = subProcess;

            bool hasCompensation = false;

            if (subProcess is Transaction)
            {
                hasCompensation = true;
            }
            else
            {
                foreach (FlowElement subElement in subProcess.FlowElements)
                {
                    if (subElement is Activity subActivity)
                    {
                        if (CollectionUtil.IsNotEmpty(subActivity.BoundaryEvents))
                        {
                            foreach (BoundaryEvent boundaryEvent in subActivity.BoundaryEvents)
                            {
                                if (CollectionUtil.IsNotEmpty(boundaryEvent.EventDefinitions) && boundaryEvent.EventDefinitions[0] is CompensateEventDefinition)
                                {
                                    hasCompensation = true;
                                    break;
                                }
                            }
                        }
                    }
                }
            }

            // All executions will be cleaned up afterwards. However, for compensation we need
            // a copy of these executions so we can use them later on when the compensation is thrown.
            // The following method does exactly that, and moves the executions beneath the process instance.
            if (hasCompensation)
            {
                ScopeUtil.CreateCopyOfSubProcessExecutionForCompensation(parentExecution);
            }

            executionEntityManager.DeleteChildExecutions(parentExecution, null, false);
            executionEntityManager.DeleteExecutionAndRelatedData(parentExecution, null, false);

            Context.ProcessEngineConfiguration.EventDispatcher.DispatchEvent(ActivitiEventBuilder.CreateActivityEvent(ActivitiEventType.ACTIVITY_COMPLETED, subProcess.Id, subProcess.Name, parentExecution.Id, parentExecution.ProcessInstanceId, parentExecution.ProcessDefinitionId, subProcess));
            return(executionToContinue);
        }
Ejemplo n.º 2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="executionEntityManager"></param>
        /// <param name="parentExecution"></param>
        /// <returns></returns>
        protected internal virtual IExecutionEntity HandleRegularExecutionEnd(IExecutionEntityManager executionEntityManager, IExecutionEntity parentExecution)
        {
            if (!parentExecution.ProcessInstanceType && !(parentExecution.CurrentFlowElement is SubProcess))
            {
                parentExecution.CurrentFlowElement = execution.CurrentFlowElement;
            }

            IExecutionEntity executionToContinue;

            if (execution.CurrentFlowElement is SubProcess currentSubProcess)
            {
                if (currentSubProcess.OutgoingFlows.Count > 0)
                {
                    // create a new execution to take the outgoing sequence flows
                    executionToContinue = executionEntityManager.CreateChildExecution(parentExecution);
                    executionToContinue.CurrentFlowElement = execution.CurrentFlowElement;
                }
                else
                {
                    if (!parentExecution.Id.Equals(parentExecution.ProcessInstanceId))
                    {
                        // create a new execution to take the outgoing sequence flows
                        executionToContinue = executionEntityManager.CreateChildExecution(parentExecution.Parent);
                        executionToContinue.CurrentFlowElement = parentExecution.CurrentFlowElement;

                        executionEntityManager.DeleteChildExecutions(parentExecution, null, false);
                        executionEntityManager.DeleteExecutionAndRelatedData(parentExecution, null, false);
                    }
                    else
                    {
                        executionToContinue = parentExecution;
                    }
                }
            }
            else
            {
                executionToContinue = parentExecution;
            }
            return(executionToContinue);
        }
Ejemplo n.º 3
0
        /// <summary>
        ///
        /// </summary>
        protected internal virtual void HandleRegularExecution()
        {
            IExecutionEntityManager executionEntityManager = commandContext.ExecutionEntityManager;

            // There will be a parent execution (or else we would be in the process instance handling method)
            IExecutionEntity parentExecution = executionEntityManager.FindById <IExecutionEntity>(execution.ParentId);

            // If the execution is a scope, all the child executions must be deleted first.
            if (execution.IsScope)
            {
                executionEntityManager.DeleteChildExecutions(execution, null, false);
            }

            // Delete current execution
            logger.LogDebug($"Ending execution {execution.Id}");
            executionEntityManager.DeleteExecutionAndRelatedData(execution, null, false);

            logger.LogDebug($"Parent execution found. Continuing process using execution {parentExecution.Id}");

            // When ending an execution in a multi instance subprocess , special care is needed
            if (IsEndEventInMultiInstanceSubprocess(execution))
            {
                HandleMultiInstanceSubProcess(executionEntityManager, parentExecution);
                return;
            }

            SubProcess subProcess = execution.CurrentFlowElement.SubProcess;

            // If there are no more active child executions, the process can be continued
            // If not (eg an embedded subprocess still has active elements, we cannot continue)
            if (GetNumberOfActiveChildExecutionsForExecution(executionEntityManager, parentExecution.Id) == 0 || IsAllEventScopeExecutions(executionEntityManager, parentExecution))
            {
                IExecutionEntity executionToContinue = null;

                if (subProcess != null)
                {
                    // In case of ending a subprocess: go up in the scopes and continue via the parent scope
                    // unless its a compensation, then we don't need to do anything and can just end it

                    if (subProcess.ForCompensation)
                    {
                        Context.Agenda.PlanEndExecutionOperation(parentExecution);
                    }
                    else
                    {
                        executionToContinue = HandleSubProcessEnd(executionEntityManager, parentExecution, subProcess);
                    }
                }
                else
                {
                    // In the 'regular' case (not being in a subprocess), we use the parent execution to
                    // continue process instance execution

                    executionToContinue = HandleRegularExecutionEnd(executionEntityManager, parentExecution);
                }

                if (executionToContinue != null)
                {
                    // only continue with outgoing sequence flows if the execution is
                    // not the process instance root execution (otherwise the process instance is finished)
                    if (executionToContinue.ProcessInstanceType)
                    {
                        HandleProcessInstanceExecution(executionToContinue);
                    }
                    else
                    {
                        Context.Agenda.PlanTakeOutgoingSequenceFlowsOperation(executionToContinue, true);
                    }
                }
            }
        }