protected internal virtual void PropagateError(string errorCode, string errorMessage, System.Exception origException,
                                                       IActivityExecution execution)
        {
            var walker = new ActivityExecutionHierarchyWalker(execution);

            var errorDeclarationFinder = new ErrorDeclarationForProcessInstanceFinder(this, origException, errorCode,
                                                                                      execution.Activity);
            var activityExecutionMappingCollector = new ActivityExecutionMappingCollector(execution);

            walker.AddScopePreVisitor(errorDeclarationFinder);
            walker.AddExecutionPreVisitor(activityExecutionMappingCollector);
            // map variables to super executions in the hierarchy of called process instances
            walker.AddExecutionPreVisitor(new OutputVariablesPropagator());

            try
            {
                walker.WalkUntil((element) => errorDeclarationFinder.ErrorEventDefinition != null || element == null);
            }
            catch (System.Exception e)
            {
                //separate the exception handling to support a fail-safe error propagation
                throw new ErrorPropagationException(this, e);
            }

            var errorHandlingActivity = errorDeclarationFinder.ErrorHandlerActivity;

            // process the error
            if (errorHandlingActivity == null)
            {
                if (origException == null)
                {
                    Log.MissingBoundaryCatchEvent(execution.Activity.Id, errorCode);
                    execution.End(true);
                }
                else
                {
                    // throw original exception
                    throw origException;
                }
            }
            else
            {
                var errorDefinition        = errorDeclarationFinder.ErrorEventDefinition;
                var errorHandlingExecution =
                    activityExecutionMappingCollector.GetExecutionForScope(errorHandlingActivity.EventScope);

                if (!ReferenceEquals(errorDefinition.ErrorCodeVariable, null))
                {
                    errorHandlingExecution.SetVariable(errorDefinition.ErrorCodeVariable, errorCode);
                }
                if (!ReferenceEquals(errorDefinition.ErrorMessageVariable, null))
                {
                    errorHandlingExecution.SetVariable(errorDefinition.ErrorMessageVariable, errorMessage);
                }
                errorHandlingExecution.ExecuteActivity(errorHandlingActivity);
            }
        }
예제 #2
0
        // sequential multi instance /////////////////////////////////

        public static bool EventSubprocessComplete(IActivityExecution scopeExecution)
        {
            var performLegacyBehavior = IsLegacyBehaviorRequired(scopeExecution);

            if (performLegacyBehavior)
            {
                Log.CompleteNonScopeEventSubprocess();
                scopeExecution.End(false);
            }

            return(performLegacyBehavior);
        }
예제 #3
0
        public void Complete(IActivityExecution execution)
        {
            var outgoingTransitions = execution.Activity.OutgoingTransitions;

            if (!outgoingTransitions.Any())
            {
                execution.End(true);
            }
            else
            {
                execution.LeaveActivityViaTransitions(outgoingTransitions, new List <IActivityExecution>());
            }
        }
예제 #4
0
        public void Execute(IActivityExecution execution)
        {
            IList <IPvmTransition> outgoingTransitions = execution.Activity.OutgoingTransitions;

            if (!outgoingTransitions.Any())
            {
                execution.End(true);
            }
            else
            {
                execution.LeaveActivityViaTransition(outgoingTransitions[0]);
            }
        }
예제 #5
0
 public override void Execute(IActivityExecution execution)
 {
     execution.End(true);
 }
예제 #6
0
        /// <summary>
        ///     Actual implementation of leaving an activity.
        /// </summary>
        /// <param name="execution">
        ///     The current execution context
        /// </param>
        /// <param name="checkConditions">
        ///     Whether or not to check conditions before determining whether or
        ///     not to take a transition.
        /// </param>
        /// <param name="throwExceptionIfExecutionStuck">
        ///     If true, an <seealso cref="ProcessEngineException" /> will be thrown in case no
        ///     transition could be found to leave the activity.
        /// </param>
        protected internal virtual void PerformOutgoingBehavior(IActivityExecution execution, bool checkConditions,
                                                                bool throwExceptionIfExecutionStuck, IList <IActivityExecution> reusableExecutions)
        {
            Log.LeavingActivity(execution.Activity.Id);

            var defaultSequenceFlow = (string)execution.Activity.GetProperty("default");
            IList <IPvmTransition> transitionsToTake = new List <IPvmTransition>();

            IList <IPvmTransition> outgoingTransitions = execution.Activity.OutgoingTransitions;

            foreach (IPvmTransition outgoingTransition in outgoingTransitions)
            {
                if (defaultSequenceFlow == null || outgoingTransition.Id != defaultSequenceFlow)
                {
                    var condition = (ICondition)outgoingTransition.GetProperty(BpmnParse.PropertynameCondition);
                    if ((condition == null) || !checkConditions || condition.Evaluate(execution))
                    {
                        transitionsToTake.Add(outgoingTransition);
                    }
                }
            }

            if (transitionsToTake.Count == 1)
            {
                execution.LeaveActivityViaTransition(transitionsToTake.ElementAt(0));
            }
            else if (transitionsToTake.Count >= 1)
            {
                if (reusableExecutions == null || reusableExecutions.Count == 0)
                {
                    execution.LeaveActivityViaTransitions(transitionsToTake, new List <IActivityExecution>()
                    {
                        execution
                    });
                }
                else
                {
                    execution.LeaveActivityViaTransitions(transitionsToTake, reusableExecutions);
                }
            }
            else
            {
                //if (!ReferenceEquals(defaultSequenceFlow, null))
                if (!string.IsNullOrEmpty(defaultSequenceFlow))
                {
                    var defaultTransition = execution.Activity.FindOutgoingTransition(defaultSequenceFlow);
                    if (defaultTransition != null)
                    {
                        execution.LeaveActivityViaTransition(defaultTransition);
                    }
                    else
                    {
                        throw Log.MissingDefaultFlowException(execution.Activity.Id, defaultSequenceFlow);
                    }
                }
                else if (outgoingTransitions.Count > 0)
                {
                    throw Log.MissingConditionalFlowException(execution.Activity.Id);
                }
                else
                {
                    if (((ActivityImpl)execution.Activity).CompensationHandler &&
                        IsAncestorCompensationThrowing(execution))
                    {
                        execution.EndCompensation();
                    }
                    else
                    {
                        Log.MissingOutgoingSequenceFlow(execution.Activity.Id);
                        execution.End(true);

                        if (throwExceptionIfExecutionStuck)
                        {
                            throw Log.StuckExecutionException(execution.Activity.Id);
                        }
                    }
                }
            }
        }
예제 #7
0
 public virtual void Execute(IActivityExecution execution)
 {
     execution.End(true);
 }
 public override void Execute(IActivityExecution execution)
 {
     // we are the last execution inside this scope: calling end() ends this scope.
     execution.End(true);
 }