protected internal override PvmExecutionImpl EventNotificationsStarted(PvmExecutionImpl execution) { execution.IncrementSequenceCounter(); // hack around execution tree structure not being in sync with activity instance concept: // if we end a scope activity, take remembered activity instance from parent and set on // execution before calling END listeners. var parent = execution.Parent; IPvmActivity activity = execution.Activity; if ((parent != null) && execution.IsScope && (activity != null) && activity.IsScope && (activity.ActivityBehavior is ICompositeActivityBehavior || (CompensationBehavior.IsCompensationThrowing(execution) && !LegacyBehavior.IsCompensationThrowing(execution)))) { Log.DebugLeavesActivityInstance(execution, execution.ActivityInstanceId); // use remembered activity instance id from parent execution.ActivityInstanceId = parent.ActivityInstanceId; // make parent go one scope up. parent.LeaveActivityInstance(); } return(execution); }
public EscalationEventDefinitionFinder(ThrowEscalationEventActivityBehavior outerInstance, string escalationCode, IPvmActivity throwEscalationActivity) { this._outerInstance = outerInstance; this.EscalationCode = escalationCode; this.ThrowEscalationActivity = throwEscalationActivity; }
public ValidatingMigrationInstructionImpl(IPvmActivity sourceActivity, IPvmActivity targetActivity, bool updateEventTrigger) { this.sourceActivity = sourceActivity; this.targetActivity = targetActivity; this.updateEventTrigger = updateEventTrigger; }
[Deployment]//表达式解析相关 public virtual void TestParseNamespaceInConditionExpressionType() { ICommandExecutor commandExecutor = processEngineConfiguration.CommandExecutorTxRequired; ProcessDefinitionEntity processDefinitionEntity = commandExecutor.Execute <ProcessDefinitionEntity>(new CommandAnonymousInnerClass2(this)); // Test that the process definition has been deployed Assert.NotNull(processDefinitionEntity); IPvmActivity activity = processDefinitionEntity.FindActivity("ExclusiveGateway_1"); Assert.NotNull(activity); // Test that the conditions has been resolved foreach (IPvmTransition transition in activity.OutgoingTransitions) { if (transition.Destination.Id.Equals("Task_2")) { Assert.AreEqual("#{approved}", transition.GetProperty("conditionText")); //Assert.True(transition.GetProperty("conditionText").Equals("#{approved}")); } else if (transition.Destination.Id.Equals("Task_3")) { Assert.True(transition.GetProperty("conditionText").Equals("#{!approved}")); } else { Assert.Fail("Something went wrong"); } } }
public virtual void Execute(PvmExecutionImpl execution) { // reset activity instance id before creating the scope execution.ActivityInstanceId = execution.ParentActivityInstanceId; PvmExecutionImpl propagatingExecution = null; IPvmActivity activity = execution.Activity; if (activity != null && activity.IsScope) { propagatingExecution = (PvmExecutionImpl)execution.CreateExecution(); propagatingExecution.Activity = activity; propagatingExecution.Transition = (execution.Transition); execution.Transition = (null); execution.IsActive = false; execution.Activity = (null); Log.CreateScope(execution, propagatingExecution); propagatingExecution.Initialize(); } else { propagatingExecution = execution; } ScopeCreated(propagatingExecution); }
protected internal virtual void ValidateAndSwitchVersionOfExecution(CommandContext commandContext, ExecutionEntity execution, ProcessDefinitionEntity newProcessDefinition) { // check that the new process definition version contains the current activity if (execution.Activity != null) { string activityId = execution.Activity.Id; IPvmActivity newActivity = newProcessDefinition.FindActivity(activityId); if (newActivity == null) { throw new ProcessEngineException("The new process definition " + "(key = '" + newProcessDefinition.Key + "') " + "does not contain the current activity " + "(id = '" + activityId + "') " + "of the process instance " + "(id = '" + _processInstanceId + "')."); } // clear cached activity so that outgoing transitions are refreshed execution.Activity = (newActivity); } // switch the process instance to the new process definition version execution.SetProcessDefinition(newProcessDefinition); // and change possible existing tasks (as the process definition id is stored there too) IList <TaskEntity> tasks = commandContext.TaskManager.FindTasksByExecutionId(execution.Id); foreach (TaskEntity taskEntity in tasks) { taskEntity.ProcessDefinitionId = newProcessDefinition.Id; } }
/// <summary> /// creates a process instance using the provided activity as initial /// </summary> public virtual IPvmProcessInstance CreateProcessInstanceForInitial(IPvmActivity init) { EnsureUtil.EnsureNotNull( "Cannot start process instance, initial activity where the process instance should start is null", "initial", init); //坑 这样申明JAVA中会走子类ExecutionEntity里的方法 processInstance等属性的set方法... PvmExecutionImpl processInstance; if (this is ProcessDefinitionEntity) { processInstance = (ExecutionEntity)NewProcessInstance(); } else { processInstance = NewProcessInstance(); } //PvmExecutionImpl processInstance = NewProcessInstance(); //ExecutionEntity processInstance = (ExecutionEntity)NewProcessInstance(); processInstance.ProcessDefinition = this; processInstance.ProcessInstance = processInstance; // always set the process instance to the initial activity, no matter how deeply it is nested; // this is required for firing history events (cf start activity) and persisting the initial activity // on async start processInstance.Activity = (init); return(processInstance); }
protected internal virtual bool CanHaveChildScopes(PvmExecutionImpl execution) { IPvmActivity activity = execution.Activity; return(activity.ActivityBehavior is ICompositeActivityBehavior || CompensationBehavior.IsCompensationThrowing(execution)); }
protected internal static bool IsMultiInstanceInCompensation(IPvmActivity activity, PvmExecutionImpl scopeExecutionCandidate) { return(activity.ActivityBehavior is MultiInstanceActivityBehavior && (((scopeExecutionCandidate != null) && (FindCompensationThrowingAncestorExecution(scopeExecutionCandidate) != null)) || (scopeExecutionCandidate == null))); }
protected internal static bool WasNoScope73(IPvmActivity activity, PvmExecutionImpl scopeExecutionCandidate) { var activityBehavior = (IActivityBehavior)activity.ActivityBehavior; return(activityBehavior is CompensationEventActivityBehavior || activityBehavior is CancelEndEventActivityBehavior || IsMultiInstanceInCompensation(activity, scopeExecutionCandidate)); }
public ErrorDeclarationForProcessInstanceFinder(AbstractBpmnActivityBehavior outerInstance, System.Exception exception, string errorCode, IPvmActivity currentActivity) { this._outerInstance = outerInstance; this.Exception = exception; this.ErrorCode = errorCode; this.CurrentActivity = currentActivity; }
public override void Execute(IActivityExecution execution) { IPvmActivity initialActivity = execution.Activity.Properties.Get(BpmnProperties.InitialActivity); EnsureUtil.EnsureNotNull("No initial activity found for subprocess " + execution.Activity.Id, "initialActivity", initialActivity); execution.ExecuteActivity(initialActivity); }
public InstantiationStack(IList <IPvmActivity> activities, IPvmActivity targetActivity, IPvmTransition targetTransition) { EnsureUtil.EnsureOnlyOneNotNull("target must be either a transition or an activity", targetActivity, targetTransition); this.Activities = activities; // TODO: make this a subclass that contains targetActivity and targetTransition?! this.TargetActivity = targetActivity; this.TargetTransition = targetTransition; }
protected internal virtual void LeaveExecution(IActivityExecution execution, IPvmActivity currentActivity, EscalationEventDefinition escalationEventDefinition) { //execution tree could have been expanded by triggering a non-interrupting event ExecutionEntity replacingExecution = (ExecutionEntity)execution.ReplacedBy; ExecutionEntity leavingExecution = (ExecutionEntity)(replacingExecution != null ? replacingExecution : execution); Leave(leavingExecution); }
protected internal virtual ActivityImpl GetFlowScopeActivity(IPvmActivity activity) { var flowScope = activity.FlowScope; ActivityImpl flowScopeActivity = null; if (flowScope.ProcessDefinition != flowScope) { flowScopeActivity = (ActivityImpl)flowScope; } return(flowScopeActivity); }
/// <summary> /// Cancels an execution which is both concurrent and scope. This can only happen if /// (a) the process instance has been migrated from a previous version to a new version of the process engine /// See: javadoc of this class for note about concurrent scopes. /// </summary> /// <param name="execution"> the concurrent scope execution to destroy </param> /// <param name="cancellingActivity"> /// the activity that cancels the execution; it must hold that /// cancellingActivity's event scope is the scope the execution is responsible for /// </param> public static void CancelConcurrentScope(IActivityExecution execution, IPvmActivity cancelledScopeActivity) { EnsureConcurrentScope(execution); Log.DebugCancelConcurrentScopeExecution(execution); execution.Interrupt("Scope " + cancelledScopeActivity + " cancelled."); // <!> HACK set to event scope activity and leave activity instance execution.Activity = (ActivityImpl)(cancelledScopeActivity); execution.LeaveActivityInstance(); execution.Interrupt("Scope " + cancelledScopeActivity + " cancelled."); execution.Destroy(); }
protected internal static bool WasNoScope72(IPvmActivity activity) { var activityBehavior = (IActivityBehavior)activity.ActivityBehavior; var parentActivityBehavior = (IActivityBehavior)(activity.FlowScope != null ? activity.FlowScope.ActivityBehavior : null); return(activityBehavior is EventSubProcessActivityBehavior || (activityBehavior is SubProcessActivityBehavior && parentActivityBehavior is SequentialMultiInstanceActivityBehavior) || (activityBehavior is ReceiveTaskActivityBehavior && parentActivityBehavior is MultiInstanceActivityBehavior)); }
protected internal override void EventNotificationsCompleted(PvmExecutionImpl execution) { // hack around execution tree structure not being in sync with activity instance concept: // if we start a scope activity, remember current activity instance in parent var parent = execution.Parent; IPvmActivity activity = execution.Activity; if ((parent != null) && execution.IsScope && activity.IsScope && CanHaveChildScopes(execution)) { parent.ActivityInstanceId = execution.ActivityInstanceId; } }
protected internal virtual ValidatingMigrationInstructions WrapMigrationInstructions( IMigrationPlan migrationPlan, ProcessDefinitionImpl sourceProcessDefinition, ProcessDefinitionImpl targetProcessDefinition, MigrationPlanValidationReportImpl planReport) { var validatingMigrationInstructions = new ValidatingMigrationInstructions(); foreach (var migrationInstruction in migrationPlan.Instructions) { var instructionReport = new MigrationInstructionValidationReportImpl(migrationInstruction); var sourceActivityId = migrationInstruction.SourceActivityId; var targetActivityId = migrationInstruction.TargetActivityId; if (!ReferenceEquals(sourceActivityId, null) && !ReferenceEquals(targetActivityId, null)) { IPvmActivity sourceActivity = sourceProcessDefinition.FindActivity(sourceActivityId); IPvmActivity targetActivity = targetProcessDefinition.FindActivity(migrationInstruction.TargetActivityId); if (sourceActivity != null && targetActivity != null) { validatingMigrationInstructions.AddInstruction(new ValidatingMigrationInstructionImpl(sourceActivity, targetActivity, migrationInstruction.UpdateEventTrigger)); } else { if (sourceActivity == null) { instructionReport.AddFailure("Source activity '" + sourceActivityId + "' does not exist"); } if (targetActivity == null) { instructionReport.AddFailure("Target activity '" + targetActivityId + "' does not exist"); } } } else { if (ReferenceEquals(sourceActivityId, null)) { instructionReport.AddFailure("Source activity id is null"); } if (ReferenceEquals(targetActivityId, null)) { instructionReport.AddFailure("Target activity id is null"); } } if (instructionReport.HasFailures()) { planReport.AddInstructionReport(instructionReport); } } return(validatingMigrationInstructions); }
protected internal override void EventNotificationsCompleted(PvmExecutionImpl execution) { IPvmActivity activity = execution.Activity; if (execution.IsScope && (ExecutesNonScopeActivity(execution) || IsAsyncBeforeActivity(execution)) && !CompensationBehavior.executesNonScopeCompensationHandler(execution)) { // case this is a scope execution and the activity is not a scope execution.LeaveActivityInstance(); execution.Activity = (GetFlowScopeActivity(activity)); execution.PerformOperation(PvmAtomicOperationFields.DeleteCascadeFireActivityEnd); } else { if (execution.IsScope) { execution.Destroy(); } // remove this execution and its concurrent parent (if exists) execution.Remove(); var continueRemoval = !execution.IsDeleteRoot; if (continueRemoval) { var propagatingExecution = execution.Parent; if ((propagatingExecution != null) && !propagatingExecution.IsScope && !propagatingExecution.HasChildren()) { propagatingExecution.Remove(); continueRemoval = !propagatingExecution.IsDeleteRoot; propagatingExecution = propagatingExecution.Parent; } if (continueRemoval) { if (propagatingExecution != null) { // continue deletion with the next scope execution // set activity on parent in case the parent is an inactive scope execution and activity has been set to 'null'. if ((propagatingExecution.Activity == null) && (activity != null) && (activity.FlowScope != null)) { propagatingExecution.Activity = (GetFlowScopeActivity(activity)); } ((PvmExecutionImpl)propagatingExecution).PerformOperation(PvmAtomicOperationFields.DeleteCascade); } } } } }
/// <summary> /// Get the inner activity of the multi instance execution. /// </summary> /// <param name="execution"> /// of multi instance activity /// </param> /// <returns> inner activity </returns> public virtual ActivityImpl GetInnerActivity(IPvmActivity miBodyActivity) { foreach (var activity in miBodyActivity.Activities) { var innerActivity = (ActivityImpl)activity; // note that miBody can contains also a compensation handler if (!innerActivity.CompensationHandler) { return(innerActivity); } } throw new ProcessEngineException("inner activity of multi instance body activity '" + miBodyActivity.Id + "' not found"); }
//public static ICmmnActivityBehavior GetActivityBehavior(CmmnExecution execution) //{ // string id = execution.Id; // CmmnActivity activity = execution.Activity; // EnsureUtil.EnsureNotNull(typeof(PvmException), "Case execution '" + id + "' has no current activity.", "activity", activity); // ICmmnActivityBehavior behavior = (ICmmnActivityBehavior)activity.ActivityBehavior; // EnsureUtil.EnsureNotNull(typeof(PvmException), "There is no behavior specified in " + activity + " for case execution '" + id + "'.", "behavior", behavior); // return behavior; //} public static IActivityBehavior GetActivityBehavior(PvmExecutionImpl execution) { var id = execution.Id; IPvmActivity activity = execution.Activity; EnsureUtil.EnsureNotNull(typeof(PvmException), "Execution '" + id + "' has no current activity.", "activity", activity); var behavior = activity.ActivityBehavior; EnsureUtil.EnsureNotNull(typeof(PvmException), "There is no behavior specified in " + activity + " for execution '" + id + "'.", "behavior", behavior); return(behavior); }
public virtual void Visit(IPvmScope scope) { var errorEventDefinitions = scope.Properties.Get(BpmnProperties.ErrorEventDefinitions); foreach (var errorEventDefinition in errorEventDefinitions) { var activityHandler = scope.ProcessDefinition.FindActivity(errorEventDefinition.HandlerActivityId); if (!IsReThrowingErrorEventSubprocess(activityHandler) && (((Exception != null) && errorEventDefinition.CatchesException(Exception)) || ((Exception == null) && errorEventDefinition.CatchesError(ErrorCode)))) { errorHandlerActivity = activityHandler; this.errorEventDefinition = errorEventDefinition; break; } } }
public override void Complete(IActivityExecution scopeExecution) { var loopCounter = GetLoopVariable(scopeExecution, LoopCounter) + 1; var nrOfInstances = GetLoopVariable(scopeExecution, NumberOfInstances); var nrOfCompletedInstances = GetLoopVariable(scopeExecution, NumberOfCompletedInstances) + 1; SetLoopVariable(scopeExecution, NumberOfCompletedInstances, nrOfCompletedInstances); if ((loopCounter == nrOfInstances) || CompletionConditionSatisfied(scopeExecution)) { Leave(scopeExecution); } else { IPvmActivity innerActivity = GetInnerActivity(scopeExecution.Activity); PerformInstance(scopeExecution, innerActivity, loopCounter); } }
protected internal override void EventNotificationsCompleted(PvmExecutionImpl execution) { IPvmActivity activity = execution.Activity; if (execution.IsScope && (activity != null) && !activity.IsScope) { execution.Activity = (ActivityImpl)activity.FlowScope; execution.PerformOperation(this); } else { if (execution.IsScope) { execution.Destroy(); } execution.Remove(); } }
protected internal virtual bool IsReachable(IPvmActivity srcActivity, IPvmActivity targetActivity, ISet <IPvmActivity> visitedActivities) { if (srcActivity.Equals(targetActivity)) { return(true); } // To avoid infinite looping, we must capture every node we visit and // check before going further in the graph if we have already visited the node. visitedActivities.Add(srcActivity); var outgoingTransitions = srcActivity.OutgoingTransitions; if (outgoingTransitions.Count == 0) { var flowScope = srcActivity.FlowScope; if ((flowScope == null) || !(flowScope is IPvmActivity)) { return(false); } return(IsReachable((IPvmActivity)flowScope, targetActivity, visitedActivities)); } foreach (var pvmTransition in outgoingTransitions) { var destinationActivity = pvmTransition.Destination; if ((destinationActivity != null) && !visitedActivities.Contains(destinationActivity)) { var reachable = IsReachable(destinationActivity, targetActivity, visitedActivities); // If false, we should investigate other paths, and not yet return the result if (reachable) { return(true); } } } return(false); }
protected internal override void CreateInstances(IActivityExecution execution, int nrOfInstances) { IPvmActivity innerActivity = GetInnerActivity(execution.Activity); // initialize the scope and create the desired number of child executions PrepareScopeExecution(execution, nrOfInstances); IList <IActivityExecution> concurrentExecutions = new List <IActivityExecution>(); for (var i = 0; i < nrOfInstances; i++) { concurrentExecutions.Add(CreateConcurrentExecution(execution)); } // start the concurrent child executions // start executions in reverse order (order will be reversed again in command context with the effect that they are // actually be started in correct order :) ) for (var i = nrOfInstances - 1; i >= 0; i--) { var activityExecution = concurrentExecutions[i]; PerformInstance(activityExecution, innerActivity, i); } }
protected internal IJobHandlerConfiguration ResolveJobHandlerConfigurationA( AtomicOperationInvocation context) { var configuration = new AsyncContinuationJobHandler.AsyncContinuationConfiguration(); configuration.AtomicOperation = context.Operation.CanonicalName; ExecutionEntity execution = context.Execution; IPvmActivity activity = execution.Activity; if (activity != null && activity.AsyncAfter) { if (execution.Transition != null) { // store id of selected transition in case this is async after. // id is not serialized with the execution -> we need to remember it as // job handler configuration. configuration.TransitionId = execution.Transition.Id; } } return(configuration); }
public virtual void Execute(IJobHandlerConfiguration configuration, ExecutionEntity execution, CommandContext commandContext, string tenantId) { var config = (AsyncContinuationConfiguration)configuration; LegacyBehavior.RepairMultiInstanceAsyncJob(execution); var atomicOperation = FindMatchingAtomicOperation(config.AtomicOperation); EnsureUtil.EnsureNotNull("Cannot process job with configuration " + configuration, "atomicOperation", atomicOperation); // reset transition id. var transitionId = config.TransitionId; if (!ReferenceEquals(transitionId, null)) { IPvmActivity activity = execution.GetActivity(); var transition = (TransitionImpl)activity.FindOutgoingTransition(transitionId); execution.Transition = transition; } Context.CommandInvocationContext.PerformOperation(atomicOperation, execution); }
/// <summary> /// With compensation, we have a dedicated scope execution for every handler, even if the handler is not /// a scope activity; this must be respected when invoking end listeners, etc. /// </summary> public static bool executesNonScopeCompensationHandler(IActivityExecution execution) { IPvmActivity activity = execution.Activity; return(execution.IsScope && (activity != null) && activity.CompensationHandler && !activity.IsScope); }