Skip to content

Commit c74bffc

Browse files
authored
[FEAT] BpmnElementsRegistry API returns source/target for edges (#2522)
This will facilitate the implementation of "path-related" use cases.
1 parent 1c1fa5b commit c74bffc

File tree

7 files changed

+85
-25
lines changed

7 files changed

+85
-25
lines changed

src/component/registry/bpmn-model-registry.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@
1717
import type BpmnModel from '../../model/bpmn/internal/BpmnModel';
1818
import type Shape from '../../model/bpmn/internal/shape/Shape';
1919
import type { Edge } from '../../model/bpmn/internal/edge/edge';
20-
import type { BpmnSemantic } from './types';
20+
import { Flow } from '../../model/bpmn/internal/edge/flows';
21+
import type { BpmnSemantic, EdgeBpmnSemantic } from './types';
2122
import { ShapeBpmnMarkerKind, ShapeUtil } from '../../model/bpmn/internal';
2223
import type { ShapeBpmnSubProcess } from '../../model/bpmn/internal/shape/ShapeBpmnElement';
2324
import ShapeBpmnElement from '../../model/bpmn/internal/shape/ShapeBpmnElement';
@@ -43,14 +44,19 @@ export class BpmnModelRegistry {
4344
this.onLoadCallback = callback;
4445
}
4546

46-
getBpmnSemantic(bpmnElementId: string): BpmnSemantic | undefined {
47+
getBpmnSemantic(bpmnElementId: string): BpmnSemantic | EdgeBpmnSemantic | undefined {
4748
const element = this.searchableModel.elementById(bpmnElementId);
4849
if (!element) {
4950
return undefined;
5051
}
5152
const bpmnElement = element.bpmnElement;
5253
const isShape = bpmnElement instanceof ShapeBpmnElement;
53-
return { id: bpmnElementId, name: bpmnElement.name, isShape: isShape, kind: bpmnElement.kind };
54+
const semantic: BpmnSemantic = { id: bpmnElementId, name: bpmnElement.name, isShape: isShape, kind: bpmnElement.kind };
55+
if (bpmnElement instanceof Flow) {
56+
(<EdgeBpmnSemantic>semantic).sourceRefId = bpmnElement.sourceRefId;
57+
(<EdgeBpmnSemantic>semantic).targetRefId = bpmnElement.targetRefId;
58+
}
59+
return semantic;
5460
}
5561
}
5662

src/component/registry/types.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,14 @@ export interface BpmnSemantic {
2727
kind: BpmnElementKind;
2828
}
2929

30+
/**
31+
* Extended properties available when {@link BpmnSemantic.isShape} is `false`.
32+
*/
33+
export interface EdgeBpmnSemantic extends BpmnSemantic {
34+
sourceRefId: string;
35+
targetRefId: string;
36+
}
37+
3038
/**
3139
* @category Custom Behavior
3240
*/

test/integration/dom.bpmn.elements.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ describe('Bpmn Elements registry - retrieve BPMN elements', () => {
4949
expect(bpmnElements).toHaveLength(2);
5050

5151
expectStartEventBpmnElement(bpmnElements[0], { id: 'StartEvent_1', name: 'Start Event 1' });
52-
expectSequenceFlowBpmnElement(bpmnElements[1], { id: 'Flow_2' });
52+
expectSequenceFlowBpmnElement(bpmnElements[1], { id: 'Flow_2', source: 'Activity_1', target: 'EndEvent_1' });
5353
});
5454

5555
it('Pass a single non existing id', async () => {
@@ -79,8 +79,8 @@ describe('Bpmn Elements registry - retrieve BPMN elements', () => {
7979
const bpmnElements = bpmnVisualization.bpmnElementsRegistry.getElementsByKinds(FlowKind.SEQUENCE_FLOW);
8080
expect(bpmnElements).toHaveLength(2);
8181

82-
expectSequenceFlowBpmnElement(bpmnElements[0], { id: 'Flow_1', name: 'Sequence Flow 1' });
83-
expectSequenceFlowBpmnElement(bpmnElements[1], { id: 'Flow_2' });
82+
expectSequenceFlowBpmnElement(bpmnElements[0], { id: 'Flow_1', name: 'Sequence Flow 1', source: 'StartEvent_1', target: 'Activity_1' });
83+
expectSequenceFlowBpmnElement(bpmnElements[1], { id: 'Flow_2', source: 'Activity_1', target: 'EndEvent_1' });
8484
});
8585

8686
it('No elements for this kind', async () => {

test/integration/helpers/semantic-with-svg-utils.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
*/
16-
import type { BpmnElement } from '../../../src/component/registry';
17-
import type { ExpectedBaseBpmnElement } from '../../unit/helpers/bpmn-semantic-utils';
16+
import type { BpmnElement, EdgeBpmnSemantic } from '../../../src/component/registry';
17+
import type { ExpectedBaseBpmnElement, ExpectedFlowElement } from '../../unit/helpers/bpmn-semantic-utils';
1818
import { expectEndEvent, expectPool, expectSequenceFlow, expectServiceTask, expectStartEvent, expectTask } from '../../unit/helpers/bpmn-semantic-utils';
1919
import { expectSvgEvent, expectSvgPool, expectSvgSequenceFlow, expectSvgTask } from './html-utils';
2020

@@ -28,8 +28,8 @@ export function expectEndEventBpmnElement(bpmnElement: BpmnElement, expected: Ex
2828
expectSvgEvent(bpmnElement.htmlElement);
2929
}
3030

31-
export function expectSequenceFlowBpmnElement(bpmnElement: BpmnElement, expected: ExpectedBaseBpmnElement): void {
32-
expectSequenceFlow(bpmnElement.bpmnSemantic, expected);
31+
export function expectSequenceFlowBpmnElement(bpmnElement: BpmnElement, expected: ExpectedFlowElement): void {
32+
expectSequenceFlow(<EdgeBpmnSemantic>bpmnElement.bpmnSemantic, expected);
3333
expectSvgSequenceFlow(bpmnElement.htmlElement);
3434
}
3535

test/unit/component/registry/bpmn-model-registry.test.ts

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,10 @@
1414
* limitations under the License.
1515
*/
1616

17+
import type { EdgeBpmnSemantic } from '../../../../src/component/registry';
1718
import { BpmnModelRegistry } from '../../../../src/component/registry/bpmn-model-registry';
18-
import { expectLane, expectPool, expectSequenceFlow, expectStartEvent } from '../../helpers/bpmn-semantic-utils';
19-
import { laneInModel, poolInModel, sequenceFlowInModel, startEventInModel } from '../../helpers/bpmn-model-utils';
19+
import { expectAssociationFlow, expectLane, expectMessageFlow, expectPool, expectSequenceFlow, expectStartEvent } from '../../helpers/bpmn-semantic-utils';
20+
import { associationFlowInModel, laneInModel, messageFlowInModel, poolInModel, sequenceFlowInModel, startEventInModel } from '../../helpers/bpmn-model-utils';
2021

2122
const bpmnModelRegistry = new BpmnModelRegistry();
2223

@@ -29,13 +30,23 @@ describe('Bpmn Model registry', () => {
2930
expect(callback).toHaveBeenCalledTimes(1);
3031
});
3132

32-
it('search edge', () => {
33-
bpmnModelRegistry.load(sequenceFlowInModel('seq flow id', 'seq flow name'));
34-
const bpmnSemantic = bpmnModelRegistry.getBpmnSemantic('seq flow id');
35-
expectSequenceFlow(bpmnSemantic, { id: 'seq flow id', name: 'seq flow name' });
33+
it('search sequence flow', () => {
34+
bpmnModelRegistry.load(sequenceFlowInModel('seq_flow_id', 'seq flow name', 'sourceRefId', 'targetRefId'));
35+
const bpmnSemantic = <EdgeBpmnSemantic>bpmnModelRegistry.getBpmnSemantic('seq_flow_id');
36+
expectSequenceFlow(bpmnSemantic, { id: 'seq_flow_id', name: 'seq flow name', source: 'sourceRefId', target: 'targetRefId' });
37+
});
38+
it('search message flow', () => {
39+
bpmnModelRegistry.load(messageFlowInModel('msg_flow_id', 'msg flow name', 'sourceRefId', 'targetRefId'));
40+
const bpmnSemantic = <EdgeBpmnSemantic>bpmnModelRegistry.getBpmnSemantic('msg_flow_id');
41+
expectMessageFlow(bpmnSemantic, { id: 'msg_flow_id', name: 'msg flow name', source: 'sourceRefId', target: 'targetRefId' });
42+
});
43+
it('search association flow', () => {
44+
bpmnModelRegistry.load(associationFlowInModel('association_flow_id', 'association flow name', 'sourceRefId', 'targetRefId'));
45+
const bpmnSemantic = <EdgeBpmnSemantic>bpmnModelRegistry.getBpmnSemantic('association_flow_id');
46+
expectAssociationFlow(bpmnSemantic, { id: 'association_flow_id', name: 'association flow name', source: 'sourceRefId', target: 'targetRefId' });
3647
});
3748

38-
it('search flownode', () => {
49+
it('search flowNode', () => {
3950
bpmnModelRegistry.load(startEventInModel('start event id', 'start event name'));
4051
const bpmnSemantic = bpmnModelRegistry.getBpmnSemantic('start event id');
4152
expectStartEvent(bpmnSemantic, { id: 'start event id', name: 'start event name' });

test/unit/helpers/bpmn-model-utils.ts

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
import type BpmnModel from '../../../src/model/bpmn/internal/BpmnModel';
1818
import { Edge } from '../../../src/model/bpmn/internal/edge/edge';
19-
import { MessageFlow, SequenceFlow } from '../../../src/model/bpmn/internal/edge/flows';
19+
import { AssociationFlow, MessageFlow, SequenceFlow } from '../../../src/model/bpmn/internal/edge/flows';
2020
import Shape from '../../../src/model/bpmn/internal/shape/Shape';
2121
import ShapeBpmnElement, {
2222
ShapeBpmnActivity,
@@ -44,14 +44,28 @@ export const buildEdgeId = (bpmnElementId: string): string => {
4444

4545
const newSequenceFlow = (id: string, name: string, source: string, target: string): Edge => new Edge(buildEdgeId(id), new SequenceFlow(id, name, source, target));
4646

47-
const newMessageFlow = (id: string, name: string, source: string, target: string): Edge => new Edge(buildEdgeId(id), new MessageFlow(id, name, source, target));
48-
49-
export const sequenceFlowInModel = (id: string, name: string): BpmnModel => {
47+
const flowInModel = (factoryFunction: (id: string, name: string, source: string, target: string) => Edge, id: string, name: string, source: string, target: string): BpmnModel => {
5048
const bpmnModel = newBpmnModel();
51-
bpmnModel.edges.push(newSequenceFlow(id, name, undefined, undefined));
49+
bpmnModel.edges.push(factoryFunction(id, name, source, target));
5250
return bpmnModel;
5351
};
5452

53+
export const sequenceFlowInModel = (id: string, name: string, source: string, target: string): BpmnModel => {
54+
return flowInModel(newSequenceFlow, id, name, source, target);
55+
};
56+
57+
const newMessageFlow = (id: string, name: string, source: string, target: string): Edge => new Edge(buildEdgeId(id), new MessageFlow(id, name, source, target));
58+
59+
export const messageFlowInModel = (id: string, name: string, source: string, target: string): BpmnModel => {
60+
return flowInModel(newMessageFlow, id, name, source, target);
61+
};
62+
63+
const newAssociationFlow = (id: string, name: string, source: string, target: string): Edge => new Edge(buildEdgeId(id), new AssociationFlow(id, name, source, target));
64+
65+
export const associationFlowInModel = (id: string, name: string, source: string, target: string): BpmnModel => {
66+
return flowInModel(newAssociationFlow, id, name, source, target);
67+
};
68+
5569
export const startEventInModel = (id: string, name: string): BpmnModel => {
5670
const bpmnModel = newBpmnModel();
5771
bpmnModel.flowNodes.push(newStartEvent('parentId', id, name));

test/unit/helpers/bpmn-semantic-utils.ts

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,41 @@
1414
* limitations under the License.
1515
*/
1616

17-
import type { BpmnSemantic } from '../../../src/component/registry';
17+
import type { BpmnSemantic, EdgeBpmnSemantic } from '../../../src/component/registry';
1818
import { FlowKind, ShapeBpmnElementKind } from '../../../src/model/bpmn/internal';
1919

2020
export interface ExpectedBaseBpmnElement {
2121
id: string;
2222
name?: string;
2323
}
2424

25-
export function expectSequenceFlow(bpmnSemantic: BpmnSemantic, expected: ExpectedBaseBpmnElement): void {
25+
export interface ExpectedFlowElement extends ExpectedBaseBpmnElement {
26+
source: string;
27+
target: string;
28+
}
29+
30+
const expectFlow = (bpmnSemantic: EdgeBpmnSemantic, expected: ExpectedFlowElement): void => {
2631
expect(bpmnSemantic.id).toEqual(expected.id);
2732
expect(bpmnSemantic.name).toEqual(expected.name);
2833
expect(bpmnSemantic.isShape).toBeFalsy();
34+
expect(bpmnSemantic.sourceRefId).toEqual(expected.source);
35+
expect(bpmnSemantic.targetRefId).toEqual(expected.target);
36+
};
37+
38+
export const expectSequenceFlow = (bpmnSemantic: EdgeBpmnSemantic, expected: ExpectedFlowElement): void => {
2939
expect(bpmnSemantic.kind).toEqual(FlowKind.SEQUENCE_FLOW);
30-
}
40+
expectFlow(bpmnSemantic, expected);
41+
};
42+
43+
export const expectMessageFlow = (bpmnSemantic: EdgeBpmnSemantic, expected: ExpectedFlowElement): void => {
44+
expect(bpmnSemantic.kind).toEqual(FlowKind.MESSAGE_FLOW);
45+
expectFlow(bpmnSemantic, expected);
46+
};
47+
48+
export const expectAssociationFlow = (bpmnSemantic: EdgeBpmnSemantic, expected: ExpectedFlowElement): void => {
49+
expect(bpmnSemantic.kind).toEqual(FlowKind.ASSOCIATION_FLOW);
50+
expectFlow(bpmnSemantic, expected);
51+
};
3152

3253
function expectShape(bpmnSemantic: BpmnSemantic, expected: ExpectedBaseBpmnElement): void {
3354
expect(bpmnSemantic.id).toEqual(expected.id);

0 commit comments

Comments
 (0)