Java Code Examples for org.flowable.engine.impl.persistence.entity.ExecutionEntity#getParent()

The following examples show how to use org.flowable.engine.impl.persistence.entity.ExecutionEntity#getParent() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: FlowableProcessStartedEventImpl.java    From flowable-engine with Apache License 2.0 6 votes vote down vote up
public FlowableProcessStartedEventImpl(final Object entity, final Map variables, final boolean localScope) {
    super(entity, variables, localScope, FlowableEngineEventType.PROCESS_STARTED);
    if (entity instanceof ExecutionEntity) {
        ExecutionEntity executionEntity = (ExecutionEntity) entity;
        if (!executionEntity.isProcessInstanceType()) {
            executionEntity = executionEntity.getParent();
        }

        final ExecutionEntity superExecution = executionEntity.getSuperExecution();
        if (superExecution != null) {
            this.nestedProcessDefinitionId = superExecution.getProcessDefinitionId();
            this.nestedProcessInstanceId = superExecution.getProcessInstanceId();
        } else {
            this.nestedProcessDefinitionId = null;
            this.nestedProcessInstanceId = null;
        }

    } else {
        this.nestedProcessDefinitionId = null;
        this.nestedProcessInstanceId = null;
    }
}
 
Example 2
Source File: TakeOutgoingSequenceFlowsOperation.java    From flowable-engine with Apache License 2.0 6 votes vote down vote up
/**
 * @param executionEntityToIgnore
 *            The execution entity which we can ignore to be ended, as it's the execution currently being handled in this operation.
 */
protected ExecutionEntity findNextParentScopeExecutionWithAllEndedChildExecutions(ExecutionEntity executionEntity, ExecutionEntity executionEntityToIgnore) {
    if (executionEntity.getParentId() != null) {
        ExecutionEntity scopeExecutionEntity = executionEntity.getParent();

        // Find next scope
        while (!scopeExecutionEntity.isScope() || !scopeExecutionEntity.isProcessInstanceType()) {
            scopeExecutionEntity = scopeExecutionEntity.getParent();
        }

        // Return when all child executions for it are ended
        if (allChildExecutionsEnded(scopeExecutionEntity, executionEntityToIgnore)) {
            return scopeExecutionEntity;
        }

    }
    return null;
}
 
Example 3
Source File: AbstractDynamicStateManager.java    From flowable-engine with Apache License 2.0 6 votes vote down vote up
protected ExecutionEntity resolveParentExecutionToDelete(ExecutionEntity execution, Collection<FlowElementMoveEntry> moveToFlowElements) {
    ExecutionEntity parentExecution = execution.getParent();

    if (parentExecution.isProcessInstanceType()) {
        return null;
    }

    if (!isSubProcessContainerOfAnyFlowElement(parentExecution.getActivityId(), moveToFlowElements)) {
        ExecutionEntity subProcessParentExecution = resolveParentExecutionToDelete(parentExecution, moveToFlowElements);
        if (subProcessParentExecution != null) {
            return subProcessParentExecution;
        } else {
            return parentExecution;
        }
    }

    return null;
}
 
Example 4
Source File: AbstractDynamicStateManager.java    From flowable-engine with Apache License 2.0 6 votes vote down vote up
protected ExecutionEntity deleteDirectParentExecutions(String parentExecutionId, Collection<FlowElementMoveEntry> moveToFlowElements, Collection<String> executionIdsNotToDelete, CommandContext commandContext) {
    ExecutionEntityManager executionEntityManager = CommandContextUtil.getExecutionEntityManager(commandContext);

    ExecutionEntity parentExecution = executionEntityManager.findById(parentExecutionId);
    if (parentExecution.getCurrentFlowElement() instanceof SubProcess) {
        SubProcess parentSubProcess = (SubProcess) parentExecution.getCurrentFlowElement();
        if (!isSubProcessContainerOfAnyFlowElement(parentSubProcess.getId(), moveToFlowElements)) {
            ExecutionEntity toDeleteParentExecution = resolveParentExecutionToDelete(parentExecution, moveToFlowElements);
            ExecutionEntity finalDeleteExecution = null;
            if (toDeleteParentExecution != null) {
                finalDeleteExecution = toDeleteParentExecution;
            } else {
                finalDeleteExecution = parentExecution;
            }

            parentExecution = finalDeleteExecution.getParent();

            String flowElementIdsLine = printFlowElementIds(moveToFlowElements);
            executionEntityManager.deleteChildExecutions(finalDeleteExecution, executionIdsNotToDelete, null, "Change activity to " + flowElementIdsLine, true, null);
            executionEntityManager.deleteExecutionAndRelatedData(finalDeleteExecution, "Change activity to " + flowElementIdsLine, false, true, finalDeleteExecution.getCurrentFlowElement());
        }
    }

    return parentExecution;
}
 
Example 5
Source File: AbstractDynamicStateManager.java    From flowable-engine with Apache License 2.0 6 votes vote down vote up
protected ExecutionEntity deleteParentExecutions(String parentExecutionId, Collection<FlowElementMoveEntry> moveToFlowElements, Collection<String> executionIdsNotToDelete, CommandContext commandContext) {
    ExecutionEntityManager executionEntityManager = CommandContextUtil.getExecutionEntityManager(commandContext);

    ExecutionEntity parentExecution = executionEntityManager.findById(parentExecutionId);
    if (parentExecution != null && parentExecution.getCurrentFlowElement() instanceof SubProcess) {
        SubProcess parentSubProcess = (SubProcess) parentExecution.getCurrentFlowElement();
        if (!isSubProcessAncestorOfAnyNewFlowElements(parentSubProcess.getId(), moveToFlowElements)) {
            ExecutionEntity toDeleteParentExecution = resolveParentExecutionToDelete(parentExecution, moveToFlowElements);
            ExecutionEntity finalDeleteExecution = null;
            if (toDeleteParentExecution != null) {
                finalDeleteExecution = toDeleteParentExecution;
            } else {
                finalDeleteExecution = parentExecution;
            }

            parentExecution = finalDeleteExecution.getParent();

            String flowElementIdsLine = printFlowElementIds(moveToFlowElements);
            executionEntityManager.deleteChildExecutions(finalDeleteExecution, executionIdsNotToDelete, null, "Change activity to " + flowElementIdsLine, true, null);
            executionEntityManager.deleteExecutionAndRelatedData(finalDeleteExecution, "Change activity to " + flowElementIdsLine, false, true, finalDeleteExecution.getCurrentFlowElement());
        }
    }

    return parentExecution;
}
 
Example 6
Source File: MultiInstanceActivityBehavior.java    From flowable-engine with Apache License 2.0 6 votes vote down vote up
protected void cleanupMiRoot(DelegateExecution execution) {
    // Delete multi instance root and all child executions.
    // Create a fresh execution to continue
    
    ExecutionEntity multiInstanceRootExecution = (ExecutionEntity) getMultiInstanceRootExecution(execution);
    FlowElement flowElement = multiInstanceRootExecution.getCurrentFlowElement();
    ExecutionEntity parentExecution = multiInstanceRootExecution.getParent();
    
    ExecutionEntityManager executionEntityManager = CommandContextUtil.getExecutionEntityManager();
    Collection<String> executionIdsNotToSendCancelledEventsFor = execution.isMultiInstanceRoot() ? null : Collections.singletonList(execution.getId());
    executionEntityManager.deleteChildExecutions(multiInstanceRootExecution, null, executionIdsNotToSendCancelledEventsFor, DELETE_REASON_END, true, flowElement);
    executionEntityManager.deleteRelatedDataForExecution(multiInstanceRootExecution, DELETE_REASON_END);
    executionEntityManager.delete(multiInstanceRootExecution);

    ExecutionEntity newExecution = executionEntityManager.createChildExecution(parentExecution);
    newExecution.setCurrentFlowElement(flowElement);
    super.leave(newExecution);
}
 
Example 7
Source File: EscalationPropagation.java    From flowable-engine with Apache License 2.0 6 votes vote down vote up
public static void propagateEscalation(String escalationCode, String escalationName, DelegateExecution execution) {
    Map<String, List<Event>> eventMap = new HashMap<>();
    Set<String> rootProcessDefinitionIds = new HashSet<>();
    if (!execution.getProcessInstanceId().equals(execution.getRootProcessInstanceId())) {
        ExecutionEntity parentExecution = (ExecutionEntity) execution;
        while (parentExecution.getParentId() != null || parentExecution.getSuperExecutionId() != null) {
            if (parentExecution.getParentId() != null) {
                parentExecution = parentExecution.getParent();
            } else {
                parentExecution = parentExecution.getSuperExecution();
                rootProcessDefinitionIds.add(parentExecution.getProcessDefinitionId());
            }
        }
    }
    
    if (rootProcessDefinitionIds.size() > 0) {
        for (String processDefinitionId : rootProcessDefinitionIds) {
            eventMap.putAll(findCatchingEventsForProcess(processDefinitionId, escalationCode));
        }
    }
    
    eventMap.putAll(findCatchingEventsForProcess(execution.getProcessDefinitionId(), escalationCode));
    if (eventMap.size() > 0) {
        executeCatch(eventMap, execution, escalationCode, escalationName);
    }
}
 
Example 8
Source File: ExecutionTreeUtil.java    From flowable-engine with Apache License 2.0 6 votes vote down vote up
public static ExecutionTree buildExecutionTree(DelegateExecution executionEntity) {

        // Find highest parent
        ExecutionEntity parentExecution = (ExecutionEntity) executionEntity;
        while (parentExecution.getParentId() != null || parentExecution.getSuperExecutionId() != null) {
            if (parentExecution.getParentId() != null) {
                parentExecution = parentExecution.getParent();
            } else {
                parentExecution = parentExecution.getSuperExecution();
            }
        }

        // Collect all child executions now we have the parent
        List<ExecutionEntity> allExecutions = new ArrayList<>();
        allExecutions.add(parentExecution);
        collectChildExecutions(parentExecution, allExecutions);
        return buildExecutionTree(allExecutions);
    }
 
Example 9
Source File: ErrorPropagation.java    From flowable-engine with Apache License 2.0 5 votes vote down vote up
public static void propagateError(String errorCode, DelegateExecution execution) {
    Map<String, List<Event>> eventMap = new HashMap<>();
    Set<String> rootProcessDefinitionIds = new HashSet<>();
    if (!execution.getProcessInstanceId().equals(execution.getRootProcessInstanceId())) {
        ExecutionEntity parentExecution = (ExecutionEntity) execution;
        while (parentExecution.getParentId() != null || parentExecution.getSuperExecutionId() != null) {
            if (parentExecution.getParentId() != null) {
                parentExecution = parentExecution.getParent();
            } else {
                parentExecution = parentExecution.getSuperExecution();
                rootProcessDefinitionIds.add(parentExecution.getProcessDefinitionId());
            }
        }
    }
    
    if (rootProcessDefinitionIds.size() > 0) {
        for (String processDefinitionId : rootProcessDefinitionIds) {
            eventMap.putAll(findCatchingEventsForProcess(processDefinitionId, errorCode));
        }
    }
    
    eventMap.putAll(findCatchingEventsForProcess(execution.getProcessDefinitionId(), errorCode));
    if (eventMap.size() > 0) {
        executeCatch(eventMap, execution, errorCode);
    }

    if (eventMap.size() == 0) {
        throw new BpmnError(errorCode, "No catching boundary event found for error with errorCode '" + errorCode + "', neither in same process nor in parent process");
    }
}
 
Example 10
Source File: ErrorPropagation.java    From flowable-engine with Apache License 2.0 5 votes vote down vote up
public static boolean mapException(Exception e, ExecutionEntity execution, List<MapExceptionEntry> exceptionMap) {
    String errorCode = findMatchingExceptionMapping(e, exceptionMap);
    if (errorCode != null) {
        propagateError(errorCode, execution);
        return true;
    } else {
        ExecutionEntity callActivityExecution = null;
        ExecutionEntity parentExecution = execution.getParent();
        while (parentExecution != null && callActivityExecution == null) {
            if (parentExecution.getId().equals(parentExecution.getProcessInstanceId())) {
                if (parentExecution.getSuperExecution() != null) {
                    callActivityExecution = parentExecution.getSuperExecution();
                } else {
                    parentExecution = null;
                }
            } else {
                parentExecution = parentExecution.getParent();
            }
        }

        if (callActivityExecution != null) {
            CallActivity callActivity = (CallActivity) callActivityExecution.getCurrentFlowElement();
            if (CollectionUtil.isNotEmpty(callActivity.getMapExceptions())) {
                errorCode = findMatchingExceptionMapping(e, callActivity.getMapExceptions());
                if (errorCode != null) {
                    propagateError(errorCode, callActivityExecution);
                    return true;
                }
            }
        }

        return false;
    }
}
 
Example 11
Source File: DeleteMultiInstanceExecutionCmd.java    From flowable-engine with Apache License 2.0 5 votes vote down vote up
protected ExecutionEntity getMultiInstanceRootExecution(ExecutionEntity executionEntity) {
    ExecutionEntity multiInstanceRootExecution = null;
    ExecutionEntity currentExecution = executionEntity;
    while (currentExecution != null && multiInstanceRootExecution == null && currentExecution.getParent() != null) {
        if (currentExecution.isMultiInstanceRoot()) {
            multiInstanceRootExecution = currentExecution;
        } else {
            currentExecution = currentExecution.getParent();
        }
    }
    return multiInstanceRootExecution;
}
 
Example 12
Source File: EndExecutionOperation.java    From flowable-engine with Apache License 2.0 5 votes vote down vote up
protected boolean isInEventSubProcess(ExecutionEntity executionEntity) {
    ExecutionEntity currentExecutionEntity = executionEntity;
    while (currentExecutionEntity != null) {
        if (currentExecutionEntity.getCurrentFlowElement() instanceof EventSubProcess) {
            return true;
        }
        currentExecutionEntity = currentExecutionEntity.getParent();
    }
    return false;
}
 
Example 13
Source File: ContinueProcessOperation.java    From flowable-engine with Apache License 2.0 5 votes vote down vote up
protected ExecutionEntity createMultiInstanceRootExecution(ExecutionEntity execution) {
    ExecutionEntity parentExecution = execution.getParent();
    FlowElement flowElement = execution.getCurrentFlowElement();
    
    ExecutionEntityManager executionEntityManager = CommandContextUtil.getExecutionEntityManager();
    executionEntityManager.deleteRelatedDataForExecution(execution, null);
    executionEntityManager.delete(execution);
    
    ExecutionEntity multiInstanceRootExecution = executionEntityManager.createChildExecution(parentExecution);
    multiInstanceRootExecution.setCurrentFlowElement(flowElement);
    multiInstanceRootExecution.setMultiInstanceRoot(true);
    multiInstanceRootExecution.setActive(false);
    return multiInstanceRootExecution;
}
 
Example 14
Source File: ContinueProcessOperation.java    From flowable-engine with Apache License 2.0 5 votes vote down vote up
protected boolean hasMultiInstanceRootExecution(ExecutionEntity execution, FlowNode flowNode) {
    ExecutionEntity currentExecution = execution.getParent();
    while (currentExecution != null) {
        if (currentExecution.isMultiInstanceRoot() && flowNode.getId().equals(currentExecution.getActivityId())) {
            return true;
        }
        currentExecution = currentExecution.getParent();
    }
    return false;
}
 
Example 15
Source File: EscalationPropagation.java    From flowable-engine with Apache License 2.0 4 votes vote down vote up
protected static void executeCatch(Map<String, List<Event>> eventMap, DelegateExecution delegateExecution, String escalationCode, String escalationName) {
    Set<String> toDeleteProcessInstanceIds = new HashSet<>();
    
    Event matchingEvent = null;
    ExecutionEntity currentExecution = (ExecutionEntity) delegateExecution;
    ExecutionEntity parentExecution = null;

    if (eventMap.containsKey(currentExecution.getActivityId() + "#" + currentExecution.getProcessDefinitionId())) {
        // Check for multi instance
        if (currentExecution.getParentId() != null && currentExecution.getParent().isMultiInstanceRoot()) {
            parentExecution = currentExecution.getParent();
        } else {
            parentExecution = currentExecution;
        }
        
        matchingEvent = getCatchEventFromList(eventMap.get(currentExecution.getActivityId() + 
                        "#" + currentExecution.getProcessDefinitionId()), parentExecution);

    } else {
        parentExecution = currentExecution.getParent();
        
        // Traverse parents until one is found that is a scope and matches the activity the boundary event is defined on
        while (matchingEvent == null && parentExecution != null) {
            FlowElementsContainer currentContainer = null;
            if (parentExecution.getCurrentFlowElement() instanceof FlowElementsContainer) {
                currentContainer = (FlowElementsContainer) parentExecution.getCurrentFlowElement();
            } else if (parentExecution.getId().equals(parentExecution.getProcessInstanceId())) {
                currentContainer = ProcessDefinitionUtil.getProcess(parentExecution.getProcessDefinitionId());
            }

            if (currentContainer != null) {
                for (String refId : eventMap.keySet()) {
                    List<Event> events = eventMap.get(refId);
                    if (CollectionUtil.isNotEmpty(events) && events.get(0) instanceof StartEvent) {
                        String refActivityId = refId.substring(0, refId.indexOf('#'));
                        String refProcessDefinitionId = refId.substring(refId.indexOf('#') + 1);
                        if (parentExecution.getProcessDefinitionId().equals(refProcessDefinitionId) && 
                                        currentContainer.getFlowElement(refActivityId) != null) {
                            
                            matchingEvent = getCatchEventFromList(events, parentExecution);
                            EscalationEventDefinition escalationEventDef = getEscalationEventDefinition(matchingEvent);
                            if (StringUtils.isNotEmpty(escalationEventDef.getEscalationCode())) {
                                break;
                            }
                        }
                    }
                }
            }

            if (matchingEvent == null) {
                if (eventMap.containsKey(parentExecution.getActivityId() + "#" + parentExecution.getProcessDefinitionId())) {
                    // Check for multi instance
                    if (parentExecution.getParentId() != null && parentExecution.getParent().isMultiInstanceRoot()) {
                        parentExecution = parentExecution.getParent();
                    }
                    
                    matchingEvent = getCatchEventFromList(eventMap.get(parentExecution.getActivityId() + 
                                    "#" + parentExecution.getProcessDefinitionId()), parentExecution);

                } else if (StringUtils.isNotEmpty(parentExecution.getParentId())) {
                    parentExecution = parentExecution.getParent();
                    
                } else {
                    if (parentExecution.getProcessInstanceId().equals(parentExecution.getRootProcessInstanceId()) == false) {
                        toDeleteProcessInstanceIds.add(parentExecution.getProcessInstanceId());
                        parentExecution = parentExecution.getSuperExecution();
                    } else {
                        parentExecution = null;
                    }
                }
            }
        }
    }

    if (matchingEvent != null && parentExecution != null) {
        
        for (String processInstanceId : toDeleteProcessInstanceIds) {
            ExecutionEntityManager executionEntityManager = CommandContextUtil.getExecutionEntityManager();
            ExecutionEntity processInstanceEntity = executionEntityManager.findById(processInstanceId);

            // Event
            ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration();
            FlowableEventDispatcher eventDispatcher = null;
            if (processEngineConfiguration != null) {
                eventDispatcher = processEngineConfiguration.getEventDispatcher();
            }
            if (eventDispatcher != null && eventDispatcher.isEnabled()) {
                processEngineConfiguration.getEventDispatcher()
                        .dispatchEvent(FlowableEventBuilder.createEntityEvent(FlowableEngineEventType.PROCESS_COMPLETED_WITH_ESCALATION_END_EVENT, processInstanceEntity));
            }
        }
        
        executeEventHandler(matchingEvent, parentExecution, currentExecution, escalationCode, escalationName);   
    }
}
 
Example 16
Source File: BoundaryCompensateEventActivityBehavior.java    From flowable-engine with Apache License 2.0 4 votes vote down vote up
@Override
public void execute(DelegateExecution execution) {
    ExecutionEntity executionEntity = (ExecutionEntity) execution;
    BoundaryEvent boundaryEvent = (BoundaryEvent) execution.getCurrentFlowElement();

    Process process = ProcessDefinitionUtil.getProcess(execution.getProcessDefinitionId());
    if (process == null) {
        throw new FlowableException("Process model (id = " + execution.getId() + ") could not be found");
    }

    Activity sourceActivity = null;
    Activity compensationActivity = null;
    List<Association> associations = process.findAssociationsWithSourceRefRecursive(boundaryEvent.getId());
    for (Association association : associations) {
        sourceActivity = boundaryEvent.getAttachedToRef();
        FlowElement targetElement = process.getFlowElement(association.getTargetRef(), true);
        if (targetElement instanceof Activity) {
            Activity activity = (Activity) targetElement;
            if (activity.isForCompensation()) {
                compensationActivity = activity;
                break;
            }
        }
    }
    
    if (sourceActivity == null) {
        throw new FlowableException("Parent activity for boundary compensation event could not be found");
    }

    if (compensationActivity == null) {
        throw new FlowableException("Compensation activity could not be found (or it is missing 'isForCompensation=\"true\"'");
    }

    // find SubProcess or Process instance execution
    ExecutionEntity scopeExecution = null;
    ExecutionEntity parentExecution = executionEntity.getParent();
    while (scopeExecution == null && parentExecution != null) {
        if (parentExecution.getCurrentFlowElement() instanceof SubProcess) {
            scopeExecution = parentExecution;

        } else if (parentExecution.isProcessInstanceType()) {
            scopeExecution = parentExecution;
        } else {
            parentExecution = parentExecution.getParent();
        }
    }

    if (scopeExecution == null) {
        throw new FlowableException("Could not find a scope execution for compensation boundary event " + boundaryEvent.getId());
    }

    EventSubscriptionEntity eventSubscription = (EventSubscriptionEntity) CommandContextUtil.getEventSubscriptionService().createEventSubscriptionBuilder()
                    .eventType(CompensateEventSubscriptionEntity.EVENT_TYPE)
                    .executionId(scopeExecution.getId())
                    .processInstanceId(scopeExecution.getProcessInstanceId())
                    .activityId(sourceActivity.getId())
                    .tenantId(scopeExecution.getTenantId())
                    .create();
    
    CountingEntityUtil.handleInsertEventSubscriptionEntityCount(eventSubscription);
}
 
Example 17
Source File: ParallelMultiInstanceBehavior.java    From flowable-engine with Apache License 2.0 4 votes vote down vote up
/**
 * Called when the wrapped {@link ActivityBehavior} calls the {@link AbstractBpmnActivityBehavior#leave(DelegateExecution)} method. Handles the completion of one of the parallel instances
 */
@Override
public void leave(DelegateExecution execution) {

    boolean zeroNrOfInstances = false;
    if (resolveNrOfInstances(execution) == 0) {
        // Empty collection, just leave.
        zeroNrOfInstances = true;
        super.leave(execution); // Plan the default leave
    }

    int loopCounter = getLoopVariable(execution, getCollectionElementIndexVariable());
    int nrOfInstances = getLoopVariable(execution, NUMBER_OF_INSTANCES);
    int nrOfCompletedInstances = getLoopVariable(execution, NUMBER_OF_COMPLETED_INSTANCES) + 1;
    int nrOfActiveInstances = getLoopVariable(execution, NUMBER_OF_ACTIVE_INSTANCES) - 1;
    
    DelegateExecution miRootExecution = getMultiInstanceRootExecution(execution);
    if (miRootExecution != null) { // will be null in case of empty collection
        setLoopVariable(miRootExecution, NUMBER_OF_COMPLETED_INSTANCES, nrOfCompletedInstances);
        setLoopVariable(miRootExecution, NUMBER_OF_ACTIVE_INSTANCES, nrOfActiveInstances);
    }

    CommandContextUtil.getActivityInstanceEntityManager().recordActivityEnd((ExecutionEntity) execution, null);
    callActivityEndListeners(execution);
    
    logLoopDetails(execution, "instance completed", loopCounter, nrOfCompletedInstances, nrOfActiveInstances, nrOfInstances);

    if (zeroNrOfInstances) {
        return;
    }

    ExecutionEntity executionEntity = (ExecutionEntity) execution;
    if (executionEntity.getParent() != null) {

        executionEntity.inactivate();
        lockFirstParentScope(executionEntity);

        boolean isCompletionConditionSatisfied = completionConditionSatisfied(execution.getParent());
        if (nrOfCompletedInstances >= nrOfInstances || isCompletionConditionSatisfied) {

            ExecutionEntity leavingExecution = null;
            if (nrOfInstances > 0) {
                leavingExecution = executionEntity.getParent();
            } else {
                CommandContextUtil.getActivityInstanceEntityManager().recordActivityEnd((ExecutionEntity) execution, null);
                leavingExecution = executionEntity;
            }

            Activity activity = (Activity) execution.getCurrentFlowElement();
            verifyCompensation(execution, leavingExecution, activity);
            verifyCallActivity(leavingExecution, activity);
            
            if (isCompletionConditionSatisfied) {
                LinkedList<DelegateExecution> toVerify = new LinkedList<>(miRootExecution.getExecutions());
                while (!toVerify.isEmpty()) {
                    DelegateExecution childExecution = toVerify.pop();
                    if (((ExecutionEntity) childExecution).isInserted()) {
                        childExecution.inactivate();
                    }
                    
                    List<DelegateExecution> childExecutions = (List<DelegateExecution>) childExecution.getExecutions();
                    if (childExecutions != null && !childExecutions.isEmpty()) {
                        toVerify.addAll(childExecutions);
                    }
                }
                sendCompletedWithConditionEvent(leavingExecution);
            }
            else {
                sendCompletedEvent(leavingExecution);
            }

            super.leave(leavingExecution);
          }

    } else {
        sendCompletedEvent(execution);
        super.leave(execution);
    }
}
 
Example 18
Source File: BoundaryCancelEventActivityBehavior.java    From flowable-engine with Apache License 2.0 4 votes vote down vote up
@Override
public void trigger(DelegateExecution execution, String triggerName, Object triggerData) {
    BoundaryEvent boundaryEvent = (BoundaryEvent) execution.getCurrentFlowElement();

    CommandContext commandContext = Context.getCommandContext();
    ExecutionEntityManager executionEntityManager = CommandContextUtil.getExecutionEntityManager(commandContext);

    ExecutionEntity subProcessExecution = null;
    // TODO: this can be optimized. A full search in the all executions shouldn't be needed
    List<ExecutionEntity> processInstanceExecutions = executionEntityManager.findChildExecutionsByProcessInstanceId(execution.getProcessInstanceId());
    for (ExecutionEntity childExecution : processInstanceExecutions) {
        if (childExecution.getCurrentFlowElement() != null
                && childExecution.getCurrentFlowElement().getId().equals(boundaryEvent.getAttachedToRefId())) {
            subProcessExecution = childExecution;
            break;
        }
    }

    if (subProcessExecution == null) {
        throw new FlowableException("No execution found for sub process of boundary cancel event " + boundaryEvent.getId());
    }

    EventSubscriptionService eventSubscriptionService = CommandContextUtil.getEventSubscriptionService(commandContext);
    List<CompensateEventSubscriptionEntity> eventSubscriptions = eventSubscriptionService.findCompensateEventSubscriptionsByExecutionId(subProcessExecution.getParentId());

    if (!eventSubscriptions.isEmpty()) {

        String deleteReason = DeleteReason.BOUNDARY_EVENT_INTERRUPTING + "(" + boundaryEvent.getId() + ")";

        // cancel boundary is always sync
        ScopeUtil.throwCompensationEvent(eventSubscriptions, execution, false);
        executionEntityManager.deleteExecutionAndRelatedData(subProcessExecution, deleteReason, false);
        if (subProcessExecution.getCurrentFlowElement() instanceof Activity) {
            Activity activity = (Activity) subProcessExecution.getCurrentFlowElement();
            if (activity.getLoopCharacteristics() != null) {
                ExecutionEntity miExecution = subProcessExecution.getParent();
                List<ExecutionEntity> miChildExecutions = executionEntityManager.findChildExecutionsByParentExecutionId(miExecution.getId());
                for (ExecutionEntity miChildExecution : miChildExecutions) {
                    if (!subProcessExecution.getId().equals(miChildExecution.getId()) && activity.getId().equals(miChildExecution.getCurrentActivityId())) {
                        executionEntityManager.deleteExecutionAndRelatedData(miChildExecution, deleteReason, false);
                    }
                }
            }
        }
    }
    leave(execution);
}
 
Example 19
Source File: AbstractDynamicStateManager.java    From flowable-engine with Apache License 2.0 4 votes vote down vote up
protected ExecutionEntity migrateExecutionEntity(ExecutionEntity parentExecutionEntity, ExecutionEntity childExecution, FlowElement newFlowElement, CommandContext commandContext) {

        TaskService taskService = CommandContextUtil.getTaskService(commandContext);

        // manage the bidirectional parent-child relation
        childExecution.setProcessInstanceId(parentExecutionEntity.getProcessInstanceId());
        childExecution.setProcessInstance(parentExecutionEntity.getProcessInstance());
        childExecution.setProcessDefinitionId(parentExecutionEntity.getProcessDefinitionId());
        ExecutionEntity oldParent = childExecution.getParent();
        if (oldParent != null && !oldParent.getId().equals(parentExecutionEntity.getId())) {
            oldParent.getExecutions().remove(childExecution);
        }
        childExecution.setParent(parentExecutionEntity);
        parentExecutionEntity.addChildExecution(childExecution);

        //Additional changes if the new activity Id doesn't match
        String oldActivityId = childExecution.getCurrentActivityId();
        if (!childExecution.getCurrentActivityId().equals(newFlowElement.getId())) {
            ((ExecutionEntityImpl) childExecution).setActivityId(newFlowElement.getId());
        }

        // If we are moving a UserTask we need to update its processDefinition references
        if (newFlowElement instanceof UserTask) {
            TaskEntityImpl task = (TaskEntityImpl) taskService.createTaskQuery().executionId(childExecution.getId()).singleResult();
            task.setProcessDefinitionId(childExecution.getProcessDefinitionId());
            task.setTaskDefinitionKey(newFlowElement.getId());
            task.setName(newFlowElement.getName());
            task.setProcessInstanceId(childExecution.getProcessInstanceId());

            //Sync history
            CommandContextUtil.getActivityInstanceEntityManager(commandContext).syncUserTaskExecution(childExecution, newFlowElement, oldActivityId, task);
        }

        // Boundary Events - only applies to Activities and up to this point we have a UserTask or ReceiveTask execution, both are Activities
        List<BoundaryEvent> boundaryEvents = ((Activity) newFlowElement).getBoundaryEvents();
        if (boundaryEvents != null && !boundaryEvents.isEmpty()) {
            List<ExecutionEntity> boundaryEventsExecutions = createBoundaryEvents(boundaryEvents, childExecution, commandContext);
            executeBoundaryEvents(boundaryEvents, boundaryEventsExecutions);
        }

        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("Child execution {} updated with parent {}", childExecution, parentExecutionEntity.getId());
        }
        return childExecution;
    }