if (sourceElement.getOutgoingFlows().size() == 0) { visitedElements.add(sourceElement.getId()); if (sourceElement.getId().equals(targetElement.getId())) { return true; visitedElements.add(sourceElement.getId()); List<SequenceFlow> sequenceFlows = sourceElement.getOutgoingFlows(); if (sequenceFlows != null && sequenceFlows.size() > 0) { for (SequenceFlow sequenceFlow : sequenceFlows) { String targetRef = sequenceFlow.getTargetRef(); FlowNode sequenceFlowTarget = (FlowNode) process.getFlowElement(targetRef, true); if (sequenceFlowTarget != null && !visitedElements.contains(sequenceFlowTarget.getId())) { boolean reachable = isReachable(process, sequenceFlowTarget, targetElement, visitedElements);
protected void continueThroughFlowNode(FlowNode flowNode) { execution.setActive(true); // Check if it's the initial flow element. If so, we must fire the execution listeners for the process too if (flowNode.getIncomingFlows() != null && flowNode.getIncomingFlows().size() == 0 && flowNode.getSubProcess() == null) { executeProcessStartExecutionListeners(); } // For a subprocess, a new child execution is created that will visit the steps of the subprocess // The original execution that arrived here will wait until the subprocess is finished // and will then be used to continue the process instance. if (flowNode instanceof SubProcess) { createChildExecutionForSubProcess((SubProcess) flowNode); } if (flowNode instanceof Activity && ((Activity) flowNode).hasMultiInstanceLoopCharacteristics()) { // the multi instance execution will look at async executeMultiInstanceSynchronous(flowNode); } else if (forceSynchronousOperation || !flowNode.isAsynchronous()) { executeSynchronous(flowNode); } else { executeAsynchronous(flowNode); } }
public void setValues(FlowNode otherNode) { super.setValues(otherNode); setAsynchronous(otherNode.isAsynchronous()); setNotExclusive(otherNode.isNotExclusive()); } }
protected ActivityBehavior setLoopCounterVariable(FlowNode flowNode) { ActivityBehavior activityBehavior = (ActivityBehavior) flowNode.getBehavior(); if (!(activityBehavior instanceof MultiInstanceActivityBehavior)) { throw new FlowableException("Programmatic error: expected multi instance activity behavior, but got " + activityBehavior.getClass()); } MultiInstanceActivityBehavior multiInstanceActivityBehavior = (MultiInstanceActivityBehavior) activityBehavior; String elementIndexVariable = multiInstanceActivityBehavior.getCollectionElementIndexVariable(); if (!flowNode.isAsynchronous()) { execution.setVariableLocal(elementIndexVariable, loopCounter); } else { multiInstanceRootExecution.setVariableLocal(elementIndexVariable, loopCounter); } return activityBehavior; }
protected void processFlowElements(Collection<FlowElement> flowElementList, BaseElement parentScope) { for (FlowElement flowElement : flowElementList) { if (flowElement instanceof SequenceFlow) { SequenceFlow sequenceFlow = (SequenceFlow) flowElement; FlowNode sourceNode = getFlowNodeFromScope(sequenceFlow.getSourceRef(), parentScope); if (sourceNode != null) { sourceNode.getOutgoingFlows().add(sequenceFlow); sequenceFlow.setSourceFlowElement(sourceNode); } FlowNode targetNode = getFlowNodeFromScope(sequenceFlow.getTargetRef(), parentScope); if (targetNode != null) { targetNode.getIncomingFlows().add(sequenceFlow); sequenceFlow.setTargetFlowElement(targetNode); } } else if (flowElement instanceof BoundaryEvent) { BoundaryEvent boundaryEvent = (BoundaryEvent) flowElement; FlowElement attachedToElement = getFlowNodeFromScope(boundaryEvent.getAttachedToRefId(), parentScope); if (attachedToElement instanceof Activity) { Activity attachedActivity = (Activity) attachedToElement; boundaryEvent.setAttachedToRef(attachedActivity); attachedActivity.getBoundaryEvents().add(boundaryEvent); } } else if (flowElement instanceof SubProcess) { SubProcess subProcess = (SubProcess) flowElement; processFlowElements(subProcess.getFlowElements(), subProcess); } } }
protected void handleActivityEnd(FlowNode flowNode) { // a process instance execution can never leave a flow node, but it can pass here whilst cleaning up // hence the check for NOT being a process instance if (!execution.isProcessInstanceType()) { if (CollectionUtil.isNotEmpty(flowNode.getExecutionListeners())) { executeExecutionListeners(flowNode, ExecutionListener.EVENTNAME_END); } if (execution.isActive() && !flowNode.getOutgoingFlows().isEmpty() && !(flowNode instanceof ParallelGateway) // Parallel gw takes care of its own history && !(flowNode instanceof InclusiveGateway) // Inclusive gw takes care of its own history && !(flowNode instanceof SubProcess) // Subprocess handling creates and destroys scoped execution. The execution taking the seq flow is different from the one entering && (!(flowNode instanceof Activity) || ((Activity) flowNode).getLoopCharacteristics() == null) // Multi instance root execution leaving the node isn't stored in history ) { // If no sequence flow: will be handled by the deletion of executions CommandContextUtil.getActivityInstanceEntityManager(commandContext).recordActivityEnd(execution, null); } if (!(execution.getCurrentFlowElement() instanceof SubProcess) && !(flowNode instanceof Activity && ((Activity) flowNode).hasMultiInstanceLoopCharacteristics())) { CommandContextUtil.getEventDispatcher(commandContext).dispatchEvent( FlowableEventBuilder.createActivityEvent(FlowableEngineEventType.ACTIVITY_COMPLETED, flowNode.getId(), flowNode.getName(), execution.getId(), execution.getProcessInstanceId(), execution.getProcessDefinitionId(), flowNode)); } } }
protected List<String> gatherCompletedFlows(Set<String> completedActivityInstances, Set<String> currentActivityinstances, BpmnModel pojoModel) { List<String> completedFlows = new ArrayList<>(); List<String> activities = new ArrayList<>(completedActivityInstances); activities.addAll(currentActivityinstances); // TODO: not a robust way of checking when parallel paths are active, should be revisited // Go over all activities and check if it's possible to match any outgoing paths against the activities for (FlowElement activity : pojoModel.getMainProcess().getFlowElements()) { if (activity instanceof FlowNode) { int index = activities.indexOf(activity.getId()); if (index >= 0 && index + 1 < activities.size()) { List<SequenceFlow> outgoingFlows = ((FlowNode) activity).getOutgoingFlows(); for (SequenceFlow flow : outgoingFlows) { String destinationFlowId = flow.getTargetRef(); if (destinationFlowId.equals(activities.get(index + 1))) { completedFlows.add(flow.getId()); } } } } } return completedFlows; } }
if (flowNode.isAsynchronous()) { writeQualifiedAttribute(ATTRIBUTE_ACTIVITY_ASYNCHRONOUS, ATTRIBUTE_VALUE_TRUE, xtw); if (flowNode.isNotExclusive()) { writeQualifiedAttribute(ATTRIBUTE_ACTIVITY_EXCLUSIVE, ATTRIBUTE_VALUE_FALSE, xtw);
protected void executeSynchronous(FlowNode flowNode) { CommandContextUtil.getActivityInstanceEntityManager(commandContext).recordActivityStart(execution); // Execution listener if (CollectionUtil.isNotEmpty(flowNode.getExecutionListeners())) { executeExecutionListeners(flowNode, ExecutionListener.EVENTNAME_START); } // Execute actual behavior ActivityBehavior activityBehavior = (ActivityBehavior) flowNode.getBehavior(); LOGGER.debug("Executing activityBehavior {} on activity '{}' with execution {}", activityBehavior.getClass(), flowNode.getId(), execution.getId()); ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext); if (processEngineConfiguration != null && processEngineConfiguration.getEventDispatcher().isEnabled()) { processEngineConfiguration.getEventDispatcher().dispatchEvent( FlowableEventBuilder.createActivityEvent(FlowableEngineEventType.ACTIVITY_STARTED, flowNode.getId(), flowNode.getName(), execution.getId(), execution.getProcessInstanceId(), execution.getProcessDefinitionId(), flowNode)); } try { activityBehavior.execute(execution); } catch (BpmnError error) { // re-throw business fault so that it can be caught by an Error Intermediate Event or Error Event Sub-Process in the process ErrorPropagation.propagateError(error, execution); } catch (RuntimeException e) { if (LogMDC.isMDCEnabled()) { LogMDC.putMDCExecution(execution); } throw e; } }
flowNode.setAsynchronous(async); flowNode.setNotExclusive(notExclusive);
protected void executeMultiInstanceSynchronous(FlowNode flowNode) { // Execution listener: event 'start' if (CollectionUtil.isNotEmpty(flowNode.getExecutionListeners())) { executeExecutionListeners(flowNode, ExecutionListener.EVENTNAME_START); } if (!hasMultiInstanceRootExecution(execution, flowNode)) { execution = createMultiInstanceRootExecution(execution); } // Create any boundary events, sub process boundary events will be created from the activity behavior List<ExecutionEntity> boundaryEventExecutions = null; List<BoundaryEvent> boundaryEvents = null; if (!inCompensation && flowNode instanceof Activity) { // Only activities can have boundary events boundaryEvents = ((Activity) flowNode).getBoundaryEvents(); if (CollectionUtil.isNotEmpty(boundaryEvents)) { boundaryEventExecutions = createBoundaryEvents(boundaryEvents, execution); } } // Execute the multi instance behavior ActivityBehavior activityBehavior = (ActivityBehavior) flowNode.getBehavior(); if (activityBehavior != null) { executeActivityBehavior(activityBehavior, flowNode); executeBoundaryEvents(boundaryEvents, boundaryEventExecutions); } else { throw new FlowableException("Expected an activity behavior in flow node " + flowNode.getId()); } }
@Override public List<FlowNode> execute(CommandContext commandContext) { ExecutionEntity execution = CommandContextUtil.getExecutionEntityManager(commandContext).findById(executionId); if (execution == null) { throw new FlowableObjectNotFoundException("No execution found for id '" + executionId + "'", ExecutionEntity.class); } if (!(execution.getCurrentFlowElement() instanceof AdhocSubProcess)) { throw new FlowableException("The current flow element of the requested execution is not an ad-hoc sub process"); } List<FlowNode> enabledFlowNodes = new ArrayList<>(); AdhocSubProcess adhocSubProcess = (AdhocSubProcess) execution.getCurrentFlowElement(); // if sequential ordering, only one child execution can be active, so no enabled activities if (adhocSubProcess.hasSequentialOrdering()) { if (execution.getExecutions().size() > 0) { return enabledFlowNodes; } } for (FlowElement flowElement : adhocSubProcess.getFlowElements()) { if (flowElement instanceof FlowNode) { FlowNode flowNode = (FlowNode) flowElement; if (flowNode.getIncomingFlows().size() == 0) { enabledFlowNodes.add(flowNode); } } } return enabledFlowNodes; }
protected void handleAdhocSubProcess(FlowNode flowNode) { boolean completeAdhocSubProcess = false; AdhocSubProcess adhocSubProcess = (AdhocSubProcess) flowNode.getParentContainer(); if (adhocSubProcess.getCompletionCondition() != null) { Expression expression = CommandContextUtil.getProcessEngineConfiguration(commandContext).getExpressionManager().createExpression(adhocSubProcess.getCompletionCondition()); if (flowNode.getOutgoingFlows().size() > 0) { leaveFlowNode(flowNode); } else {
protected void continueThroughMultiInstanceFlowNode(FlowNode flowNode) { setLoopCounterVariable(flowNode); if (!flowNode.isAsynchronous()) { executeSynchronous(flowNode); } else { executeAsynchronous(flowNode); } }
public void setValues(Gateway otherElement) { super.setValues(otherElement); setDefaultFlow(otherElement.getDefaultFlow()); } }
Collection<String> flowNodeIdsWithInactivatedBehavior = new ArrayList<>(); for (FlowNode flowNode : process.findFlowElementsOfType(FlowNode.class)) { if (flowNode.getBehavior() instanceof InactiveActivityBehavior) { flowNodeIdsWithInactivatedBehavior.add(flowNode.getId()); InactiveActivityBehavior inactiveActivityBehavior = ((InactiveActivityBehavior) flowNode.getBehavior()); LOGGER.debug("Found InactiveActivityBehavior instance of class {} that can be executed on activity '{}'", inactiveActivityBehavior.getClass(), flowNode.getId()); inactiveActivityBehavior.executeInactive(inactiveExecution);
protected void executeActivityBehavior(ActivityBehavior activityBehavior, FlowNode flowNode) { LOGGER.debug("Executing activityBehavior {} on activity '{}' with execution {}", activityBehavior.getClass(), flowNode.getId(), execution.getId()); ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(); if (processEngineConfiguration != null && processEngineConfiguration.getEventDispatcher().isEnabled()) { if (flowNode instanceof Activity && ((Activity) flowNode).hasMultiInstanceLoopCharacteristics()) { processEngineConfiguration.getEventDispatcher().dispatchEvent( FlowableEventBuilder.createMultiInstanceActivityEvent(FlowableEngineEventType.MULTI_INSTANCE_ACTIVITY_STARTED, flowNode.getId(), flowNode.getName(), execution.getId(), execution.getProcessInstanceId(), execution.getProcessDefinitionId(), flowNode)); } else { processEngineConfiguration.getEventDispatcher().dispatchEvent( FlowableEventBuilder.createActivityEvent(FlowableEngineEventType.ACTIVITY_STARTED, flowNode.getId(), flowNode.getName(), execution.getId(), execution.getProcessInstanceId(), execution.getProcessDefinitionId(), flowNode)); } } try { activityBehavior.execute(execution); } catch (RuntimeException e) { if (LogMDC.isMDCEnabled()) { LogMDC.putMDCExecution(execution); } throw e; } }
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; }
@Override public void parse(BpmnParse bpmnParse, BaseElement element) { super.parse(bpmnParse, element); createExecutionListenersOnScope(bpmnParse, ((FlowNode) element).getExecutionListeners(), findActivity(bpmnParse, element.getId())); }
((FlowNode) sourceFlowElement).getOutgoingFlows().add(sequenceFlow); JsonNode edgeNode = edgeMap.get(sequenceFlow.getId()); if (edgeNode != null) { ((FlowNode) targetFlowElement).getIncomingFlows().add(sequenceFlow);