Class AStatefulWorkflowBpmnModeler<Element,​PartBuilder extends IStructuredBpmnModelPartBuilder<?>,​Params extends IModelWorkflowItemParams<Element,​PartBuilder>>

  • Type Parameters:
    Element - The type of the workflow element to be modeled, such as a process, task, trigger, or node.
    PartBuilder - The type of the part builder to be used for the workflow element.
    Params - The type of the parameters passed to the modeler.
    Direct Known Subclasses:
    AStatefulWorkflowBpmnModeler.ANodeStatefulModeler, AStatefulWorkflowBpmnModeler.AProcessStatefulModeler, AStatefulWorkflowBpmnModeler.ATaskStatefulModeler, AStatefulWorkflowBpmnModeler.ATriggerStatefulModeler

    public abstract class AStatefulWorkflowBpmnModeler<Element,​PartBuilder extends IStructuredBpmnModelPartBuilder<?>,​Params extends IModelWorkflowItemParams<Element,​PartBuilder>>
    extends Object
    Helper class for modeling a workflow element as a structured BPMN part. For more complex elements, it may prove useful to keep state as instance fields around, to avoid having to pass many parameters around methods. This class provides a base for such modelers and contains various protected fields that can be used by subclasses.

    It also enforces a certain structure for the modelling process by defining template methods that are called in a specific order:

    • createLayoutItem is called first to create the layout item for the workflow element. It may contain nested items. Here you should create all BPMN elements such as tasks, events, gateways, etc., and align them with the various methods from the layouter.
    • The layout items then gets flattened to a IFlattenedAlignmentItemMap, and passed on to the next steps.
    • Next, configurePartBuilder is called to configure the part builder with basic data, such as the bounding box, in and out ports, and the position of the child parts.
    • Next, addShapes is called to create the shapes for all flow nodes created during the first step. IFlattenedAlignmentItemMap provides several convenience methods to create shapes.
    • Next, addFlows is called to create the flows and interconnections between the BPMN elements created during the first step. IFlattenedAlignmentItemMap provides several convenience methods to create flows and interconnections, most notably flattened.flow()...build().
    • Next, addAssociations is called to create the Association and edges between the BPMN elements created during the first step. IFlattenedAlignmentItemMap provides several convenience methods to create associations, most notably flattened.association()...build().
    • Finally, finishBpmnModel is called to finish the BPMN model.
    If you decide to use this class, the intended usage is as follows. Let's say we want to build a simple IWorkflowNodeBpmnModeler that creates 2 tasks connected with a SequenceFlow; and each task has a text annotation. We could implement it like this:
     public enum MyModeler implements IWorkflowNodeBpmnModeler<MyProps> {
       INSTANCE;
    
       @Override
       public void modelNode(IModelWorkflowNodeParams<MyProps> params, IWorkflowBpmnModelContext context) {
         modelWorkflowElementWithState(StatefulModeler::new, params, context);
       }
    
       private final static class StatefulModeler extends ANodeStatefulModeler<MyProps> {
         // implement the abstract template methods here...
    
         private IAnnotatedNamedBpmnElementLayout<Task> task1;
         private IAnnotatedNamedBpmnElementLayout<Task> task2;
    
         @Override
         protected IWorkflowBpmnAlignmentItem<?, ?> createLayoutItem() {
             var taskElement1 = factory.serviceTask().name("My Task 1");
             var taskElement2 = factory.serviceTask().name("My Task 2");
             task1 = layouter.layoutEvent().annotation("Task details 1").build(taskElement1);
             task2 = layouter.layoutEvent().annotation("Task details 2").build(taskElement2);
             return layouter.alignAtAxis()
               .portsOfFirstAndLastItem()
               .flowDirection()
               .flowDirectionSpacing(2)
               .build(task1.item().value(), task2.item().value());
         }
    
         @Override
         protected void configurePartBuilder(IFlattenedAlignmentItemMap<?> flattened) {
             builder.boundingBox(flattened.boundingBox());
             builder.inPort(flattened.inPort());
             builder.outPort(flattened.outPort());
             builder.addRaisableError(ctx.bpmnElements().generalError());
         }
    
         @Override
         protected void addShapes(IFlattenedAlignmentItemMap<?> flattened) {
           flattened.createTaskShape(task1);
           flattened.createTaskShape(task2);
         }
    
         @Override
         protected void addFlows(IFlattenedAlignmentItemMap<?> flattened) {
             flattened.flow().fromOutPort(task1).toInPort(task2).build();
         }
    
         @Override
         protected void addAssociations(IFlattenedAlignmentItemMap<?> flattened) {
             flattened.association().closestDiagonalConnectionToAnnotation(task1).build();
             flattened.association().closestDiagonalConnectionToAnnotation(task2).build();
         }
       }
     }
     
    Since:
    8.4.0