bpmnlint
Version:
Validate your BPMN diagrams based on configurable lint rules
83 lines (63 loc) • 1.77 kB
JavaScript
const {
isAny,
is
} = require('bpmnlint-utils');
const {
annotateRule
} = require('./helper');
/**
* A rule that verifies that there exists no disconnected
* flow elements, i.e. elements without incoming or outgoing sequence flows.
*
* @type { import('../lib/types.js').RuleFactory }
*/
module.exports = function() {
function check(node, reporter) {
if (!isAny(node, [
'bpmn:Task',
'bpmn:Gateway',
'bpmn:SubProcess',
'bpmn:Event'
]) || node.triggeredByEvent) {
return;
}
// compensation activity and boundary events are
// linked visually via associations. If these associations
// exist we are fine, too
if (isCompensationLinked(node)) {
return;
}
// adhoc subprocesses can have disconnected activities
if (is(node.$parent, 'bpmn:AdHocSubProcess')) {
return;
}
const incoming = node.incoming || [];
const outgoing = node.outgoing || [];
if (!incoming.length && !outgoing.length) {
reporter.report(node.id, 'Element is not connected');
}
}
return annotateRule('no-disconnected', {
check
});
};
// helpers /////////////////
function isCompensationBoundary(node) {
var eventDefinitions = node.eventDefinitions;
if (!is(node, 'bpmn:BoundaryEvent')) {
return false;
}
if (!eventDefinitions || eventDefinitions.length !== 1) {
return false;
}
return is(eventDefinitions[0], 'bpmn:CompensateEventDefinition');
}
function isCompensationActivity(node) {
return node.isForCompensation;
}
function isCompensationLinked(node) {
var source = isCompensationBoundary(node);
var target = isCompensationActivity(node);
// TODO(nikku): check, whether compensation association exists
return source || target;
}