public override Void execute(CommandContext commandContext) { ExecutionEntity sourceInstanceExecution = determineSourceInstanceExecution(commandContext); // Outline: // 1. find topmost scope execution beginning at scopeExecution that has exactly // one child (this is the topmost scope we can cancel) // 2. cancel all children of the topmost execution // 3. cancel the activity of the topmost execution itself (if applicable) // 4. remove topmost execution (and concurrent parent) if topmostExecution is not the process instance ExecutionEntity topmostCancellableExecution = sourceInstanceExecution; ExecutionEntity parentScopeExecution = (ExecutionEntity)topmostCancellableExecution.getParentScopeExecution(false); // if topmostCancellableExecution's scope execution has no other non-event-scope children, // we have reached the correct execution while (parentScopeExecution != null && (parentScopeExecution.NonEventScopeExecutions.Count <= 1)) { topmostCancellableExecution = parentScopeExecution; parentScopeExecution = (ExecutionEntity)topmostCancellableExecution.getParentScopeExecution(false); } if (topmostCancellableExecution.PreserveScope) { topmostCancellableExecution.interrupt(cancellationReason, skipCustomListeners, skipIoMappings); topmostCancellableExecution.leaveActivityInstance(); topmostCancellableExecution.setActivity(null); } else { topmostCancellableExecution.deleteCascade(cancellationReason, skipCustomListeners, skipIoMappings); ModificationUtil.handleChildRemovalInScope(topmostCancellableExecution); } return(null); }
public static void handleChildRemovalInScope(ExecutionEntity removedExecution) { ActivityImpl activity = removedExecution.getActivity(); if (activity == null) { if (removedExecution.getSuperExecution() != null) { removedExecution = removedExecution.getSuperExecution(); activity = removedExecution.getActivity(); if (activity == null) { return; } } else { return; } } ScopeImpl flowScope = activity.FlowScope; PvmExecutionImpl scopeExecution = removedExecution.getParentScopeExecution(false); PvmExecutionImpl executionInParentScope = removedExecution.Concurrent ? removedExecution : removedExecution.Parent; if (flowScope.ActivityBehavior != null && flowScope.ActivityBehavior is ModificationObserverBehavior) { // let child removal be handled by the scope itself ModificationObserverBehavior behavior = (ModificationObserverBehavior)flowScope.ActivityBehavior; behavior.destroyInnerInstance(executionInParentScope); } else { if (executionInParentScope.Concurrent) { executionInParentScope.remove(); scopeExecution.tryPruneLastConcurrentChild(); scopeExecution.forceUpdate(); } } }