BPMN model¶
BPMN metamodel¶
This metamodel allows the definition of BPMN (Business Process Model and Notation) diagrams, the OMG standard for visualising and specifying business processes. A BPMN model captures the flow of work across flow nodes (tasks, events, gateways) connected by sequence flows, optionally organised into pools (one per participant) and lanes (sub-partitions of a pool). The metamodel covers the BPMN element set supported by the Web Modeling Editor (WME) and follows the BPMN 2.0.2 class hierarchy.
The top-level container is BPMNModel. A diagram without pools has a single
Process; a diagram with pools has a Collaboration whose Participants each
reference one Process.
Note
The classes highlighted in green originate from the structural metamodel.
For the sake of clarity, associations of BPMNModel and Process are represented as attributes.
Key concepts¶
Flow nodes (
FlowNode): everything that can sit in a process and be the source or target of a sequence flow. Three concrete branches:Activity: work to be performed. Concrete subtypes:Task,SubProcess,Transaction(aSubProcesssubclass per BPMN 2.0.2 § 10.3), andCallActivity. Tasks carry atask_type(USER,SERVICE,SEND,RECEIVE,MANUAL,BUSINESS_RULE,SCRIPT,DEFAULT). All activities carryloop_characteristics(NONE/STANDARD_LOOP/PARALLEL_MI/SEQUENTIAL_MI).Event: something that happens. Concrete subtypes:StartEvent,IntermediateEvent,EndEvent. See the Event model subsection below.Gateway: branch / merge / join point. The kind is set viagateway_type(EXCLUSIVE,INCLUSIVE,PARALLEL,COMPLEX,EVENT_BASED).
Connecting objects (
BPMNConnectingObject): four concrete subtypes:SequenceFlow(orders flow nodes inside a process or sub-process),MessageFlow(across pool boundaries; endpoints may be message-eligible nodes (activities or events) or wholeParticipantpools per BPMN 2.0.2 § 9.3),Association(links an artifact to any element),DataAssociation(connects exactly oneDataElementto exactly oneFlowNode).Containers:
ProcessandSubProcessboth hold flow nodes and sequence flows (they expose the sameflow_nodes/sequence_flowsAPI and are duck-type compatible).Lanepartitions a process;Participantis a pool referencing a process;Collaborationgroups participants and the message flows between them.Data & artifacts:
DataObject(process-scoped),DataStore(model-scoped; per BPMN 2.0.2 § 10.3 a root-level element shared across processes),TextAnnotation,Group.
BPMNModel also exposes three convenience methods: all_flow_nodes() returns
every flow node across all processes, all_sequence_flows() returns every sequence
flow including those nested inside sub-processes, and all_connecting_objects()
returns every connecting object across the entire model.
Event model¶
Events split along two orthogonal axes:
direction(EventDirection.CATCH/THROW):CATCHmeans the event waits to receive a trigger (message arrives, timer fires, signal broadcast from elsewhere);THROWmeans the event sends a trigger as the flow passes through it. Fixed toCATCHonStartEventandTHROWonEndEvent; free onIntermediateEvent.event_definition(EventDefinitionType):NONE,MESSAGE,TIMER,SIGNAL,ESCALATION,ERROR,COMPENSATION,LINK,CONDITIONAL,TERMINATE.
The metamodel enforces a legality table of valid (class, direction,
event_definition) triples at construction time, so illegal combinations
(e.g. StartEvent(event_definition=TERMINATE)) raise ValueError
immediately rather than waiting for validate().
Sequence-flow defaults¶
SequenceFlow.is_default may be set to True only when the source is an
Activity or an exclusive / inclusive / complex Gateway (BPMN 2.0.2
§ 8.3.13). The metamodel guards this in the setter and re-validates in
BPMNModel.validate(). The derived Activity.default_flow /
Gateway.default_flow properties return the single outgoing flow marked
is_default=True, or None if no default is set. Because the flag and the
property read from the same underlying field they can never disagree.
Example¶
A pool-less process with a start event, a user task, and an end event:
from besser.BUML.metamodel.bpmn import (
BPMNModel, Process, Task, StartEvent, EndEvent, SequenceFlow,
TaskType,
)
start = StartEvent(name="received")
task = Task(name="Review order", task_type=TaskType.USER)
end = EndEvent(name="done")
process = Process(
name="Order Review",
flow_nodes={start, task, end},
sequence_flows={SequenceFlow(start, task), SequenceFlow(task, end)},
)
model = BPMNModel(name="OrderReview", processes={process})
Validation¶
Call BPMNModel.validate() to check structural correctness: endpoint
references resolve, sequence flows stay within a single container, message
flows cross pool boundaries, default-flow source rules hold, event-definition
triples are legal, lane membership matches process membership, and every
participant references a process in the model:
result = model.validate(raise_exception=False)
# result = {"success": True/False, "errors": [...], "warnings": [...]}
Validation collects all errors and warnings in a single pass rather than stopping at the first failure, so one call reports everything that is wrong.
Round-trip with the Web Modeling Editor¶
The BPMN converters live alongside the others under
besser.utilities.web_modeling_editor.backend.services.converters:
process_bpmn_diagram(json)WME BPMN JSON →
BPMNModel.bpmn_object_to_json(model)BPMNModel→ WME BPMN JSON.bpmn_buml_to_json(content)B-UML
.pysource string → WME BPMN JSON (executes the source and delegates tobpmn_object_to_json).bpmn_model_to_code(model)BPMNModel→ executable Python that reconstructs the model whenexec()’d.
Because BPMN names can be empty, whitespace, or repeated, the metamodel
identifies elements by object (no __eq__ / __hash__ overrides);
the converters keep the original WME ids in an opaque BPMNElement.layout
side-channel so round-trips remain stable.