Search in sources :

Example 16 with ExecutionEntityManager

use of org.activiti.engine.impl.persistence.entity.ExecutionEntityManager in project Activiti by Activiti.

the class TakeOutgoingSequenceFlowsOperation method leaveFlowNode.

protected void leaveFlowNode(FlowNode flowNode) {
    logger.debug("Leaving flow node {} with id '{}' by following it's {} outgoing sequenceflow", flowNode.getClass(), flowNode.getId(), flowNode.getOutgoingFlows().size());
    // Get default sequence flow (if set)
    String defaultSequenceFlowId = null;
    if (flowNode instanceof Activity) {
        defaultSequenceFlowId = ((Activity) flowNode).getDefaultFlow();
    } else if (flowNode instanceof Gateway) {
        defaultSequenceFlowId = ((Gateway) flowNode).getDefaultFlow();
    }
    // Determine which sequence flows can be used for leaving
    List<SequenceFlow> outgoingSequenceFlows = new ArrayList<SequenceFlow>();
    for (SequenceFlow sequenceFlow : flowNode.getOutgoingFlows()) {
        String skipExpressionString = sequenceFlow.getSkipExpression();
        if (!SkipExpressionUtil.isSkipExpressionEnabled(execution, skipExpressionString)) {
            if (!evaluateConditions || (evaluateConditions && ConditionUtil.hasTrueCondition(sequenceFlow, execution) && (defaultSequenceFlowId == null || !defaultSequenceFlowId.equals(sequenceFlow.getId())))) {
                outgoingSequenceFlows.add(sequenceFlow);
            }
        } else if (flowNode.getOutgoingFlows().size() == 1 || SkipExpressionUtil.shouldSkipFlowElement(commandContext, execution, skipExpressionString)) {
            // The 'skip' for a sequence flow means that we skip the condition, not the sequence flow.
            outgoingSequenceFlows.add(sequenceFlow);
        }
    }
    // Check if there is a default sequence flow
    if (outgoingSequenceFlows.size() == 0 && evaluateConditions) {
        // The elements that set this to false also have no support for default sequence flow
        if (defaultSequenceFlowId != null) {
            for (SequenceFlow sequenceFlow : flowNode.getOutgoingFlows()) {
                if (defaultSequenceFlowId.equals(sequenceFlow.getId())) {
                    outgoingSequenceFlows.add(sequenceFlow);
                    break;
                }
            }
        }
    }
    // No outgoing found. Ending the execution
    if (outgoingSequenceFlows.size() == 0) {
        if (flowNode.getOutgoingFlows() == null || flowNode.getOutgoingFlows().size() == 0) {
            logger.debug("No outgoing sequence flow found for flow node '{}'.", flowNode.getId());
            Context.getAgenda().planEndExecutionOperation(execution);
        } else {
            throw new ActivitiException("No outgoing sequence flow of element '" + flowNode.getId() + "' could be selected for continuing the process");
        }
    } else {
        // Leave, and reuse the incoming sequence flow, make executions for all the others (if applicable)
        ExecutionEntityManager executionEntityManager = commandContext.getExecutionEntityManager();
        List<ExecutionEntity> outgoingExecutions = new ArrayList<ExecutionEntity>(flowNode.getOutgoingFlows().size());
        SequenceFlow sequenceFlow = outgoingSequenceFlows.get(0);
        // Reuse existing one
        execution.setCurrentFlowElement(sequenceFlow);
        execution.setActive(true);
        outgoingExecutions.add((ExecutionEntity) execution);
        // Executions for all the other one
        if (outgoingSequenceFlows.size() > 1) {
            for (int i = 1; i < outgoingSequenceFlows.size(); i++) {
                ExecutionEntity parent = execution.getParentId() != null ? execution.getParent() : execution;
                ExecutionEntity outgoingExecutionEntity = commandContext.getExecutionEntityManager().createChildExecution(parent);
                SequenceFlow outgoingSequenceFlow = outgoingSequenceFlows.get(i);
                outgoingExecutionEntity.setCurrentFlowElement(outgoingSequenceFlow);
                executionEntityManager.insert(outgoingExecutionEntity);
                outgoingExecutions.add(outgoingExecutionEntity);
            }
        }
        // Leave (only done when all executions have been made, since some queries depend on this)
        for (ExecutionEntity outgoingExecution : outgoingExecutions) {
            Context.getAgenda().planContinueProcessOperation(outgoingExecution);
        }
    }
}
Also used : ActivitiException(org.activiti.engine.ActivitiException) ExecutionEntity(org.activiti.engine.impl.persistence.entity.ExecutionEntity) Gateway(org.activiti.bpmn.model.Gateway) SequenceFlow(org.activiti.bpmn.model.SequenceFlow) ArrayList(java.util.ArrayList) Activity(org.activiti.bpmn.model.Activity) ExecutionEntityManager(org.activiti.engine.impl.persistence.entity.ExecutionEntityManager)

Example 17 with ExecutionEntityManager

use of org.activiti.engine.impl.persistence.entity.ExecutionEntityManager in project Activiti by Activiti.

the class IntermediateCatchEventActivityBehavior method deleteOtherEventsRelatedToEventBasedGateway.

protected void deleteOtherEventsRelatedToEventBasedGateway(DelegateExecution execution, EventGateway eventGateway) {
    // To clean up the other events behind the event based gateway, we must gather the
    // activity ids of said events and check the _sibling_ executions of the incoming execution.
    // Note that it can happen that there are multiple such execution in those activity ids,
    // (for example a parallel gw going twice to the event based gateway, kinda silly, but valid)
    // so we only take _one_ result of such a query for deletion.
    // Gather all activity ids for the events after the event based gateway that need to be destroyed
    List<SequenceFlow> outgoingSequenceFlows = eventGateway.getOutgoingFlows();
    // -1, the event being triggered does not need to be deleted
    Set<String> eventActivityIds = new HashSet<String>(outgoingSequenceFlows.size() - 1);
    for (SequenceFlow outgoingSequenceFlow : outgoingSequenceFlows) {
        if (outgoingSequenceFlow.getTargetFlowElement() != null && !outgoingSequenceFlow.getTargetFlowElement().getId().equals(execution.getCurrentActivityId())) {
            eventActivityIds.add(outgoingSequenceFlow.getTargetFlowElement().getId());
        }
    }
    CommandContext commandContext = Context.getCommandContext();
    ExecutionEntityManager executionEntityManager = commandContext.getExecutionEntityManager();
    // Find the executions
    List<ExecutionEntity> executionEntities = executionEntityManager.findExecutionsByParentExecutionAndActivityIds(execution.getParentId(), eventActivityIds);
    // Execute the cancel behaviour of the IntermediateCatchEvent
    for (ExecutionEntity executionEntity : executionEntities) {
        if (eventActivityIds.contains(executionEntity.getActivityId()) && execution.getCurrentFlowElement() instanceof IntermediateCatchEvent) {
            IntermediateCatchEvent intermediateCatchEvent = (IntermediateCatchEvent) execution.getCurrentFlowElement();
            if (intermediateCatchEvent.getBehavior() instanceof IntermediateCatchEventActivityBehavior) {
                ((IntermediateCatchEventActivityBehavior) intermediateCatchEvent.getBehavior()).eventCancelledByEventGateway(executionEntity);
                // We only need to delete ONE execution at the event.
                eventActivityIds.remove(executionEntity.getActivityId());
            }
        }
    }
}
Also used : CommandContext(org.activiti.engine.impl.interceptor.CommandContext) ExecutionEntity(org.activiti.engine.impl.persistence.entity.ExecutionEntity) SequenceFlow(org.activiti.bpmn.model.SequenceFlow) IntermediateCatchEvent(org.activiti.bpmn.model.IntermediateCatchEvent) ExecutionEntityManager(org.activiti.engine.impl.persistence.entity.ExecutionEntityManager) HashSet(java.util.HashSet)

Example 18 with ExecutionEntityManager

use of org.activiti.engine.impl.persistence.entity.ExecutionEntityManager in project Activiti by Activiti.

the class ParallelGatewayActivityBehavior method execute.

public void execute(DelegateExecution execution) {
    // First off all, deactivate the execution
    execution.inactivate();
    // Join
    FlowElement flowElement = execution.getCurrentFlowElement();
    ParallelGateway parallelGateway = null;
    if (flowElement instanceof ParallelGateway) {
        parallelGateway = (ParallelGateway) flowElement;
    } else {
        throw new ActivitiException("Programmatic error: parallel gateway behaviour can only be applied" + " to a ParallelGateway instance, but got an instance of " + flowElement);
    }
    lockFirstParentScope(execution);
    DelegateExecution multiInstanceExecution = null;
    if (hasMultiInstanceParent(parallelGateway)) {
        multiInstanceExecution = findMultiInstanceParentExecution(execution);
    }
    ExecutionEntityManager executionEntityManager = Context.getCommandContext().getExecutionEntityManager();
    Collection<ExecutionEntity> joinedExecutions = executionEntityManager.findInactiveExecutionsByActivityIdAndProcessInstanceId(execution.getCurrentActivityId(), execution.getProcessInstanceId());
    if (multiInstanceExecution != null) {
        joinedExecutions = cleanJoinedExecutions(joinedExecutions, multiInstanceExecution);
    }
    int nbrOfExecutionsToJoin = parallelGateway.getIncomingFlows().size();
    int nbrOfExecutionsCurrentlyJoined = joinedExecutions.size();
    // Fork
    // Is needed to set the endTime for all historic activity joins
    Context.getCommandContext().getHistoryManager().recordActivityEnd((ExecutionEntity) execution, null);
    if (nbrOfExecutionsCurrentlyJoined == nbrOfExecutionsToJoin) {
        // Fork
        if (log.isDebugEnabled()) {
            log.debug("parallel gateway '{}' activates: {} of {} joined", execution.getCurrentActivityId(), nbrOfExecutionsCurrentlyJoined, nbrOfExecutionsToJoin);
        }
        if (parallelGateway.getIncomingFlows().size() > 1) {
            // All (now inactive) children are deleted.
            for (ExecutionEntity joinedExecution : joinedExecutions) {
                // The current execution will be reused and not deleted
                if (!joinedExecution.getId().equals(execution.getId())) {
                    executionEntityManager.deleteExecutionAndRelatedData(joinedExecution, null);
                }
            }
        }
        // TODO: potential optimization here: reuse more then 1 execution, only 1 currently
        // false -> ignoring conditions on parallel gw
        Context.getAgenda().planTakeOutgoingSequenceFlowsOperation((ExecutionEntity) execution, false);
    } else if (log.isDebugEnabled()) {
        log.debug("parallel gateway '{}' does not activate: {} of {} joined", execution.getCurrentActivityId(), nbrOfExecutionsCurrentlyJoined, nbrOfExecutionsToJoin);
    }
}
Also used : ActivitiException(org.activiti.engine.ActivitiException) ExecutionEntity(org.activiti.engine.impl.persistence.entity.ExecutionEntity) FlowElement(org.activiti.bpmn.model.FlowElement) ParallelGateway(org.activiti.bpmn.model.ParallelGateway) DelegateExecution(org.activiti.engine.delegate.DelegateExecution) ExecutionEntityManager(org.activiti.engine.impl.persistence.entity.ExecutionEntityManager)

Example 19 with ExecutionEntityManager

use of org.activiti.engine.impl.persistence.entity.ExecutionEntityManager in project Activiti by Activiti.

the class BoundaryCancelEventActivityBehavior method trigger.

@Override
public void trigger(DelegateExecution execution, String triggerName, Object triggerData) {
    BoundaryEvent boundaryEvent = (BoundaryEvent) execution.getCurrentFlowElement();
    CommandContext commandContext = Context.getCommandContext();
    ExecutionEntityManager executionEntityManager = commandContext.getExecutionEntityManager();
    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 ActivitiException("No execution found for sub process of boundary cancel event " + boundaryEvent.getId());
    }
    EventSubscriptionEntityManager eventSubscriptionEntityManager = commandContext.getEventSubscriptionEntityManager();
    List<CompensateEventSubscriptionEntity> eventSubscriptions = eventSubscriptionEntityManager.findCompensateEventSubscriptionsByExecutionId(subProcessExecution.getParentId());
    if (eventSubscriptions.isEmpty()) {
        leave(execution);
    } else {
        String deleteReason = DeleteReason.BOUNDARY_EVENT_INTERRUPTING + "(" + boundaryEvent.getId() + ")";
        // cancel boundary is always sync
        ScopeUtil.throwCompensationEvent(eventSubscriptions, execution, false);
        executionEntityManager.deleteExecutionAndRelatedData(subProcessExecution, deleteReason);
        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()) == false && activity.getId().equals(miChildExecution.getCurrentActivityId())) {
                        executionEntityManager.deleteExecutionAndRelatedData(miChildExecution, deleteReason);
                    }
                }
            }
        }
        leave(execution);
    }
}
Also used : ActivitiException(org.activiti.engine.ActivitiException) BoundaryEvent(org.activiti.bpmn.model.BoundaryEvent) CommandContext(org.activiti.engine.impl.interceptor.CommandContext) ExecutionEntity(org.activiti.engine.impl.persistence.entity.ExecutionEntity) EventSubscriptionEntityManager(org.activiti.engine.impl.persistence.entity.EventSubscriptionEntityManager) Activity(org.activiti.bpmn.model.Activity) CompensateEventSubscriptionEntity(org.activiti.engine.impl.persistence.entity.CompensateEventSubscriptionEntity) ExecutionEntityManager(org.activiti.engine.impl.persistence.entity.ExecutionEntityManager)

Example 20 with ExecutionEntityManager

use of org.activiti.engine.impl.persistence.entity.ExecutionEntityManager in project Activiti by Activiti.

the class BoundaryEventActivityBehavior method executeNonInterruptingBehavior.

protected void executeNonInterruptingBehavior(ExecutionEntity executionEntity, CommandContext commandContext) {
    // Non-interrupting: the current execution is given the first parent
    // scope (which isn't its direct parent)
    // 
    // Why? Because this execution does NOT have anything to do with
    // the current parent execution (the one where the boundary event is on): when it is deleted or whatever,
    // this does not impact this new execution at all, it is completely independent in that regard.
    // Note: if the parent of the parent does not exists, this becomes a concurrent execution in the process instance!
    ExecutionEntityManager executionEntityManager = commandContext.getExecutionEntityManager();
    ExecutionEntity parentExecutionEntity = executionEntityManager.findById(executionEntity.getParentId());
    ExecutionEntity scopeExecution = null;
    ExecutionEntity currentlyExaminedExecution = executionEntityManager.findById(parentExecutionEntity.getParentId());
    while (currentlyExaminedExecution != null && scopeExecution == null) {
        if (currentlyExaminedExecution.isScope()) {
            scopeExecution = currentlyExaminedExecution;
        } else {
            currentlyExaminedExecution = executionEntityManager.findById(currentlyExaminedExecution.getParentId());
        }
    }
    if (scopeExecution == null) {
        throw new ActivitiException("Programmatic error: no parent scope execution found for boundary event");
    }
    ExecutionEntity nonInterruptingExecution = executionEntityManager.createChildExecution(scopeExecution);
    nonInterruptingExecution.setCurrentFlowElement(executionEntity.getCurrentFlowElement());
    Context.getAgenda().planTakeOutgoingSequenceFlowsOperation(nonInterruptingExecution, true);
}
Also used : ActivitiException(org.activiti.engine.ActivitiException) ExecutionEntity(org.activiti.engine.impl.persistence.entity.ExecutionEntity) ExecutionEntityManager(org.activiti.engine.impl.persistence.entity.ExecutionEntityManager)

Aggregations

ExecutionEntityManager (org.activiti.engine.impl.persistence.entity.ExecutionEntityManager)30 ExecutionEntity (org.activiti.engine.impl.persistence.entity.ExecutionEntity)29 ActivitiException (org.activiti.engine.ActivitiException)11 CommandContext (org.activiti.engine.impl.interceptor.CommandContext)6 SubProcess (org.activiti.bpmn.model.SubProcess)5 ActivitiObjectNotFoundException (org.activiti.engine.ActivitiObjectNotFoundException)5 FlowElement (org.activiti.bpmn.model.FlowElement)4 ActivitiIllegalArgumentException (org.activiti.engine.ActivitiIllegalArgumentException)4 DelegateExecution (org.activiti.engine.delegate.DelegateExecution)4 ArrayList (java.util.ArrayList)3 Activity (org.activiti.bpmn.model.Activity)3 BoundaryEvent (org.activiti.bpmn.model.BoundaryEvent)3 CallActivity (org.activiti.bpmn.model.CallActivity)3 Process (org.activiti.bpmn.model.Process)2 SequenceFlow (org.activiti.bpmn.model.SequenceFlow)2 CompensateEventSubscriptionEntity (org.activiti.engine.impl.persistence.entity.CompensateEventSubscriptionEntity)2 EventSubscriptionEntity (org.activiti.engine.impl.persistence.entity.EventSubscriptionEntity)2 EventSubscriptionEntityManager (org.activiti.engine.impl.persistence.entity.EventSubscriptionEntityManager)2 ProcessDefinition (org.activiti.engine.repository.ProcessDefinition)2 HashMap (java.util.HashMap)1