Search in sources :

Example 1 with FlowElementsContainer

use of org.activiti.bpmn.model.FlowElementsContainer in project Activiti by Activiti.

the class IntermediateThrowCompensationEventActivityBehavior method execute.

@Override
public void execute(DelegateExecution execution) {
    ThrowEvent throwEvent = (ThrowEvent) execution.getCurrentFlowElement();
    /*
     * From the BPMN 2.0 spec:
     * 
     * The Activity to be compensated MAY be supplied.
     *  
     * If an Activity is not supplied, then the compensation is broadcast to all completed Activities in 
     * the current Sub- Process (if present), or the entire Process instance (if at the global level). This “throws” the compensation.
     */
    final String activityRef = compensateEventDefinition.getActivityRef();
    CommandContext commandContext = Context.getCommandContext();
    EventSubscriptionEntityManager eventSubscriptionEntityManager = commandContext.getEventSubscriptionEntityManager();
    List<CompensateEventSubscriptionEntity> eventSubscriptions = new ArrayList<CompensateEventSubscriptionEntity>();
    if (StringUtils.isNotEmpty(activityRef)) {
        // If an activity ref is provided, only that activity is compensated
        eventSubscriptions.addAll(eventSubscriptionEntityManager.findCompensateEventSubscriptionsByProcessInstanceIdAndActivityId(execution.getProcessInstanceId(), activityRef));
    } else {
        // If no activity ref is provided, it is broadcast to the current sub process / process instance
        Process process = ProcessDefinitionUtil.getProcess(execution.getProcessDefinitionId());
        FlowElementsContainer flowElementsContainer = null;
        if (throwEvent.getSubProcess() == null) {
            flowElementsContainer = process;
        } else {
            flowElementsContainer = throwEvent.getSubProcess();
        }
        for (FlowElement flowElement : flowElementsContainer.getFlowElements()) {
            if (flowElement instanceof Activity) {
                eventSubscriptions.addAll(eventSubscriptionEntityManager.findCompensateEventSubscriptionsByProcessInstanceIdAndActivityId(execution.getProcessInstanceId(), flowElement.getId()));
            }
        }
    }
    if (eventSubscriptions.isEmpty()) {
        leave(execution);
    } else {
        // TODO: implement async (waitForCompletion=false in bpmn)
        ScopeUtil.throwCompensationEvent(eventSubscriptions, execution, false);
        leave(execution);
    }
}
Also used : ThrowEvent(org.activiti.bpmn.model.ThrowEvent) CommandContext(org.activiti.engine.impl.interceptor.CommandContext) EventSubscriptionEntityManager(org.activiti.engine.impl.persistence.entity.EventSubscriptionEntityManager) FlowElement(org.activiti.bpmn.model.FlowElement) ArrayList(java.util.ArrayList) FlowElementsContainer(org.activiti.bpmn.model.FlowElementsContainer) Activity(org.activiti.bpmn.model.Activity) Process(org.activiti.bpmn.model.Process) CompensateEventSubscriptionEntity(org.activiti.engine.impl.persistence.entity.CompensateEventSubscriptionEntity)

Example 2 with FlowElementsContainer

use of org.activiti.bpmn.model.FlowElementsContainer in project Activiti by Activiti.

the class AsyncPropertyValidator method validateFlowElementsInContainer.

protected void validateFlowElementsInContainer(FlowElementsContainer container, List<ValidationError> errors, Process process) {
    for (FlowElement flowElement : container.getFlowElements()) {
        if (flowElement instanceof FlowElementsContainer) {
            FlowElementsContainer subProcess = (FlowElementsContainer) flowElement;
            validateFlowElementsInContainer(subProcess, errors, process);
        }
        if ((flowElement instanceof FlowNode) && ((FlowNode) flowElement).isAsynchronous()) {
            addWarning(errors, Problems.FLOW_ELEMENT_ASYNC_NOT_AVAILABLE, process, flowElement, "Async property is not available when asyncExecutor is disabled.");
        }
        if ((flowElement instanceof Event)) {
            ((Event) flowElement).getEventDefinitions().stream().forEach(event -> {
                if (event instanceof TimerEventDefinition) {
                    addWarning(errors, Problems.EVENT_TIMER_ASYNC_NOT_AVAILABLE, process, flowElement, "Timer event is not available when asyncExecutor is disabled.");
                } else if ((event instanceof SignalEventDefinition) && ((SignalEventDefinition) event).isAsync()) {
                    addWarning(errors, Problems.SIGNAL_ASYNC_NOT_AVAILABLE, process, flowElement, "Async property is not available when asyncExecutor is disabled.");
                }
            });
        }
    }
}
Also used : FlowElement(org.activiti.bpmn.model.FlowElement) FlowElementsContainer(org.activiti.bpmn.model.FlowElementsContainer) Event(org.activiti.bpmn.model.Event) SignalEventDefinition(org.activiti.bpmn.model.SignalEventDefinition) TimerEventDefinition(org.activiti.bpmn.model.TimerEventDefinition) FlowNode(org.activiti.bpmn.model.FlowNode)

Example 3 with FlowElementsContainer

use of org.activiti.bpmn.model.FlowElementsContainer in project Activiti by Activiti.

the class SequenceflowValidator method executeValidation.

@Override
protected void executeValidation(BpmnModel bpmnModel, Process process, List<ValidationError> errors) {
    List<SequenceFlow> sequenceFlows = process.findFlowElementsOfType(SequenceFlow.class);
    for (SequenceFlow sequenceFlow : sequenceFlows) {
        String sourceRef = sequenceFlow.getSourceRef();
        String targetRef = sequenceFlow.getTargetRef();
        if (StringUtils.isEmpty(sourceRef)) {
            addError(errors, Problems.SEQ_FLOW_INVALID_SRC, process, sequenceFlow, "Invalid source for sequenceflow");
        }
        if (StringUtils.isEmpty(targetRef)) {
            addError(errors, Problems.SEQ_FLOW_INVALID_TARGET, process, sequenceFlow, "Invalid target for sequenceflow");
        }
        // Implicit check: sequence flow cannot cross (sub) process
        // boundaries, hence we check the parent and not the process
        // (could be subprocess for example)
        FlowElement source = process.getFlowElement(sourceRef, true);
        FlowElement target = process.getFlowElement(targetRef, true);
        // Src and target validation
        if (source == null) {
            addError(errors, Problems.SEQ_FLOW_INVALID_SRC, process, sequenceFlow, "Invalid source for sequenceflow");
        }
        if (target == null) {
            addError(errors, Problems.SEQ_FLOW_INVALID_TARGET, process, sequenceFlow, "Invalid target for sequenceflow");
        }
        if (source != null && target != null) {
            FlowElementsContainer sourceContainer = process.getFlowElementsContainer(source.getId());
            FlowElementsContainer targetContainer = process.getFlowElementsContainer(target.getId());
            if (sourceContainer == null) {
                addError(errors, Problems.SEQ_FLOW_INVALID_SRC, process, sequenceFlow, "Invalid source for sequenceflow");
            }
            if (targetContainer == null) {
                addError(errors, Problems.SEQ_FLOW_INVALID_TARGET, process, sequenceFlow, "Invalid target for sequenceflow");
            }
            if (sourceContainer != null && targetContainer != null && !sourceContainer.equals(targetContainer)) {
                addError(errors, Problems.SEQ_FLOW_INVALID_TARGET, process, sequenceFlow, "Invalid target for sequenceflow, the target isn't defined in the same scope as the source");
            }
        }
        String conditionExpression = sequenceFlow.getConditionExpression();
        if (conditionExpression != null) {
            try {
                new ExpressionFactoryImpl().createValueExpression(new SimpleContext(), conditionExpression.trim(), Object.class);
            } catch (Exception e) {
                addError(errors, Problems.SEQ_FLOW_INVALID_CONDITIONAL_EXPRESSION, process, sequenceFlow, "Conditional expression is not valid");
            }
        }
    }
}
Also used : SimpleContext(de.odysseus.el.util.SimpleContext) SequenceFlow(org.activiti.bpmn.model.SequenceFlow) FlowElement(org.activiti.bpmn.model.FlowElement) ExpressionFactoryImpl(de.odysseus.el.ExpressionFactoryImpl) FlowElementsContainer(org.activiti.bpmn.model.FlowElementsContainer)

Example 4 with FlowElementsContainer

use of org.activiti.bpmn.model.FlowElementsContainer in project Activiti by Activiti.

the class DefaultProcessDiagramGenerator method drawActivity.

protected void drawActivity(DefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode, List<String> highLightedActivities, List<String> highLightedFlows, double scaleFactor) {
    ActivityDrawInstruction drawInstruction = activityDrawInstructions.get(flowNode.getClass());
    if (drawInstruction != null) {
        drawInstruction.draw(processDiagramCanvas, bpmnModel, flowNode);
        // Gather info on the multi instance marker
        boolean multiInstanceSequential = false, multiInstanceParallel = false, collapsed = false;
        if (flowNode instanceof Activity) {
            Activity activity = (Activity) flowNode;
            MultiInstanceLoopCharacteristics multiInstanceLoopCharacteristics = activity.getLoopCharacteristics();
            if (multiInstanceLoopCharacteristics != null) {
                multiInstanceSequential = multiInstanceLoopCharacteristics.isSequential();
                multiInstanceParallel = !multiInstanceSequential;
            }
        }
        // Gather info on the collapsed marker
        GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
        if (flowNode instanceof SubProcess) {
            collapsed = graphicInfo.getExpanded() != null && !graphicInfo.getExpanded();
        } else if (flowNode instanceof CallActivity) {
            collapsed = true;
        }
        if (scaleFactor == 1.0) {
            // Actually draw the markers
            processDiagramCanvas.drawActivityMarkers((int) graphicInfo.getX(), (int) graphicInfo.getY(), (int) graphicInfo.getWidth(), (int) graphicInfo.getHeight(), multiInstanceSequential, multiInstanceParallel, collapsed);
        }
        // Draw highlighted activities
        if (highLightedActivities.contains(flowNode.getId())) {
            drawHighLight(processDiagramCanvas, bpmnModel.getGraphicInfo(flowNode.getId()));
        }
    }
    // Outgoing transitions of activity
    for (SequenceFlow sequenceFlow : flowNode.getOutgoingFlows()) {
        boolean highLighted = (highLightedFlows.contains(sequenceFlow.getId()));
        String defaultFlow = null;
        if (flowNode instanceof Activity) {
            defaultFlow = ((Activity) flowNode).getDefaultFlow();
        } else if (flowNode instanceof Gateway) {
            defaultFlow = ((Gateway) flowNode).getDefaultFlow();
        }
        boolean isDefault = false;
        if (defaultFlow != null && defaultFlow.equalsIgnoreCase(sequenceFlow.getId())) {
            isDefault = true;
        }
        boolean drawConditionalIndicator = sequenceFlow.getConditionExpression() != null && !(flowNode instanceof Gateway);
        String sourceRef = sequenceFlow.getSourceRef();
        String targetRef = sequenceFlow.getTargetRef();
        FlowElement sourceElement = bpmnModel.getFlowElement(sourceRef);
        FlowElement targetElement = bpmnModel.getFlowElement(targetRef);
        List<GraphicInfo> graphicInfoList = bpmnModel.getFlowLocationGraphicInfo(sequenceFlow.getId());
        if (graphicInfoList != null && graphicInfoList.size() > 0) {
            graphicInfoList = connectionPerfectionizer(processDiagramCanvas, bpmnModel, sourceElement, targetElement, graphicInfoList);
            int[] xPoints = new int[graphicInfoList.size()];
            int[] yPoints = new int[graphicInfoList.size()];
            for (int i = 1; i < graphicInfoList.size(); i++) {
                GraphicInfo graphicInfo = graphicInfoList.get(i);
                GraphicInfo previousGraphicInfo = graphicInfoList.get(i - 1);
                if (i == 1) {
                    xPoints[0] = (int) previousGraphicInfo.getX();
                    yPoints[0] = (int) previousGraphicInfo.getY();
                }
                xPoints[i] = (int) graphicInfo.getX();
                yPoints[i] = (int) graphicInfo.getY();
            }
            processDiagramCanvas.drawSequenceflow(xPoints, yPoints, drawConditionalIndicator, isDefault, highLighted, scaleFactor);
            // Draw sequenceflow label
            GraphicInfo labelGraphicInfo = bpmnModel.getLabelGraphicInfo(sequenceFlow.getId());
            if (labelGraphicInfo != null) {
                processDiagramCanvas.drawLabel(sequenceFlow.getName(), labelGraphicInfo, false);
            }
        }
    }
    // Nested elements
    if (flowNode instanceof FlowElementsContainer) {
        for (FlowElement nestedFlowElement : ((FlowElementsContainer) flowNode).getFlowElements()) {
            if (nestedFlowElement instanceof FlowNode) {
                drawActivity(processDiagramCanvas, bpmnModel, (FlowNode) nestedFlowElement, highLightedActivities, highLightedFlows, scaleFactor);
            }
        }
    }
}
Also used : EventSubProcess(org.activiti.bpmn.model.EventSubProcess) SubProcess(org.activiti.bpmn.model.SubProcess) SequenceFlow(org.activiti.bpmn.model.SequenceFlow) GraphicInfo(org.activiti.bpmn.model.GraphicInfo) CallActivity(org.activiti.bpmn.model.CallActivity) Activity(org.activiti.bpmn.model.Activity) FlowElementsContainer(org.activiti.bpmn.model.FlowElementsContainer) CallActivity(org.activiti.bpmn.model.CallActivity) MultiInstanceLoopCharacteristics(org.activiti.bpmn.model.MultiInstanceLoopCharacteristics) ExclusiveGateway(org.activiti.bpmn.model.ExclusiveGateway) EventGateway(org.activiti.bpmn.model.EventGateway) InclusiveGateway(org.activiti.bpmn.model.InclusiveGateway) ParallelGateway(org.activiti.bpmn.model.ParallelGateway) Gateway(org.activiti.bpmn.model.Gateway) FlowElement(org.activiti.bpmn.model.FlowElement) FlowNode(org.activiti.bpmn.model.FlowNode)

Example 5 with FlowElementsContainer

use of org.activiti.bpmn.model.FlowElementsContainer in project Activiti by Activiti.

the class DefaultProcessDiagramGenerator method drawActivity.

protected void drawActivity(DefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode, List<String> highLightedActivities, List<String> highLightedFlows) {
    ActivityDrawInstruction drawInstruction = activityDrawInstructions.get(flowNode.getClass());
    if (drawInstruction != null) {
        drawInstruction.draw(processDiagramCanvas, bpmnModel, flowNode);
        // Gather info on the multi instance marker
        boolean multiInstanceSequential = false;
        boolean multiInstanceParallel = false;
        boolean collapsed = false;
        if (flowNode instanceof Activity) {
            Activity activity = (Activity) flowNode;
            MultiInstanceLoopCharacteristics multiInstanceLoopCharacteristics = activity.getLoopCharacteristics();
            if (multiInstanceLoopCharacteristics != null) {
                multiInstanceSequential = multiInstanceLoopCharacteristics.isSequential();
                multiInstanceParallel = !multiInstanceSequential;
            }
        }
        // Gather info on the collapsed marker
        GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
        if (flowNode instanceof SubProcess) {
            collapsed = graphicInfo.getExpanded() != null && !graphicInfo.getExpanded();
        } else if (flowNode instanceof CallActivity) {
            collapsed = true;
        }
        // Actually draw the markers
        processDiagramCanvas.drawActivityMarkers((int) graphicInfo.getX(), (int) graphicInfo.getY(), (int) graphicInfo.getWidth(), (int) graphicInfo.getHeight(), multiInstanceSequential, multiInstanceParallel, collapsed);
        // Draw highlighted activities
        if (highLightedActivities.contains(flowNode.getId())) {
            drawHighLight(processDiagramCanvas, bpmnModel.getGraphicInfo(flowNode.getId()));
        }
    }
    // Outgoing transitions of activity
    for (SequenceFlow sequenceFlow : flowNode.getOutgoingFlows()) {
        boolean highLighted = (highLightedFlows.contains(sequenceFlow.getId()));
        String defaultFlow = null;
        if (flowNode instanceof Activity) {
            defaultFlow = ((Activity) flowNode).getDefaultFlow();
        } else if (flowNode instanceof Gateway) {
            defaultFlow = ((Gateway) flowNode).getDefaultFlow();
        }
        boolean isDefault = false;
        if (defaultFlow != null && defaultFlow.equalsIgnoreCase(sequenceFlow.getId())) {
            isDefault = true;
        }
        boolean drawConditionalIndicator = sequenceFlow.getConditionExpression() != null && !(flowNode instanceof Gateway);
        String sourceRef = sequenceFlow.getSourceRef();
        String targetRef = sequenceFlow.getTargetRef();
        FlowElement sourceElement = bpmnModel.getFlowElement(sourceRef);
        FlowElement targetElement = bpmnModel.getFlowElement(targetRef);
        List<GraphicInfo> graphicInfoList = bpmnModel.getFlowLocationGraphicInfo(sequenceFlow.getId());
        if (graphicInfoList != null && graphicInfoList.size() > 0) {
            graphicInfoList = connectionPerfectionizer(processDiagramCanvas, bpmnModel, sourceElement, targetElement, graphicInfoList);
            int[] xPoints = new int[graphicInfoList.size()];
            int[] yPoints = new int[graphicInfoList.size()];
            for (int i = 1; i < graphicInfoList.size(); i++) {
                GraphicInfo graphicInfo = graphicInfoList.get(i);
                GraphicInfo previousGraphicInfo = graphicInfoList.get(i - 1);
                if (i == 1) {
                    xPoints[0] = (int) previousGraphicInfo.getX();
                    yPoints[0] = (int) previousGraphicInfo.getY();
                }
                xPoints[i] = (int) graphicInfo.getX();
                yPoints[i] = (int) graphicInfo.getY();
            }
            processDiagramCanvas.drawSequenceflow(xPoints, yPoints, drawConditionalIndicator, isDefault, highLighted);
            // Draw sequenceflow label
            GraphicInfo labelGraphicInfo = bpmnModel.getLabelGraphicInfo(sequenceFlow.getId());
            if (labelGraphicInfo != null) {
                processDiagramCanvas.drawLabel(sequenceFlow.getName(), labelGraphicInfo, false);
            }
        }
    }
    // Nested elements
    if (flowNode instanceof FlowElementsContainer) {
        for (FlowElement nestedFlowElement : ((FlowElementsContainer) flowNode).getFlowElements()) {
            if (nestedFlowElement instanceof FlowNode) {
                drawActivity(processDiagramCanvas, bpmnModel, (FlowNode) nestedFlowElement, highLightedActivities, highLightedFlows);
            }
        }
    }
}
Also used : EventSubProcess(org.activiti.bpmn.model.EventSubProcess) SubProcess(org.activiti.bpmn.model.SubProcess) SequenceFlow(org.activiti.bpmn.model.SequenceFlow) GraphicInfo(org.activiti.bpmn.model.GraphicInfo) CallActivity(org.activiti.bpmn.model.CallActivity) Activity(org.activiti.bpmn.model.Activity) FlowElementsContainer(org.activiti.bpmn.model.FlowElementsContainer) CallActivity(org.activiti.bpmn.model.CallActivity) MultiInstanceLoopCharacteristics(org.activiti.bpmn.model.MultiInstanceLoopCharacteristics) ExclusiveGateway(org.activiti.bpmn.model.ExclusiveGateway) EventGateway(org.activiti.bpmn.model.EventGateway) InclusiveGateway(org.activiti.bpmn.model.InclusiveGateway) ParallelGateway(org.activiti.bpmn.model.ParallelGateway) Gateway(org.activiti.bpmn.model.Gateway) FlowElement(org.activiti.bpmn.model.FlowElement) FlowNode(org.activiti.bpmn.model.FlowNode)

Aggregations

FlowElementsContainer (org.activiti.bpmn.model.FlowElementsContainer)6 FlowElement (org.activiti.bpmn.model.FlowElement)5 FlowNode (org.activiti.bpmn.model.FlowNode)4 SequenceFlow (org.activiti.bpmn.model.SequenceFlow)4 Activity (org.activiti.bpmn.model.Activity)3 SubProcess (org.activiti.bpmn.model.SubProcess)3 CallActivity (org.activiti.bpmn.model.CallActivity)2 EventGateway (org.activiti.bpmn.model.EventGateway)2 EventSubProcess (org.activiti.bpmn.model.EventSubProcess)2 ExclusiveGateway (org.activiti.bpmn.model.ExclusiveGateway)2 Gateway (org.activiti.bpmn.model.Gateway)2 GraphicInfo (org.activiti.bpmn.model.GraphicInfo)2 InclusiveGateway (org.activiti.bpmn.model.InclusiveGateway)2 MultiInstanceLoopCharacteristics (org.activiti.bpmn.model.MultiInstanceLoopCharacteristics)2 ParallelGateway (org.activiti.bpmn.model.ParallelGateway)2 ExpressionFactoryImpl (de.odysseus.el.ExpressionFactoryImpl)1 SimpleContext (de.odysseus.el.util.SimpleContext)1 ArrayList (java.util.ArrayList)1 Event (org.activiti.bpmn.model.Event)1 Process (org.activiti.bpmn.model.Process)1