parent
30d2cf9755
commit
99bfdd2fb8
|
@ -1,3 +1,5 @@
|
|||
import { find, forEach, map } from 'min-dash';
|
||||
import { is } from '../util/ModelUtil';
|
||||
import BpmnTreeWalker from './BpmnTreeWalker';
|
||||
|
||||
|
||||
|
@ -65,19 +67,22 @@ export function importBpmnDiagram(diagram, definitions, bpmnDiagram) {
|
|||
|
||||
var walker = new BpmnTreeWalker(visitor, translate);
|
||||
|
||||
// traverse BPMN 2.0 document model,
|
||||
// starting at definitions
|
||||
if (!bpmnDiagram && definitions.diagrams) {
|
||||
for (var i = 0; i < definitions.diagrams.length; i++) {
|
||||
walker.handleDefinitions(definitions, definitions.diagrams[i]);
|
||||
}
|
||||
} else {
|
||||
walker.handleDefinitions(definitions, bpmnDiagram);
|
||||
|
||||
bpmnDiagram = bpmnDiagram || (definitions.diagrams && definitions.diagrams[0]);
|
||||
|
||||
var diagramsToLoad = getDiagramsToLoad(definitions, bpmnDiagram);
|
||||
|
||||
if (!diagramsToLoad) {
|
||||
throw new Error(translate('no diagram to display'));
|
||||
}
|
||||
|
||||
var mainDiagram = bpmnDiagram || definitions.diagrams[0];
|
||||
// traverse BPMN 2.0 document model,
|
||||
// starting at definitions
|
||||
forEach(diagramsToLoad, function(diagram) {
|
||||
walker.handleDefinitions(definitions, diagram);
|
||||
});
|
||||
|
||||
var rootId = mainDiagram.plane.bpmnElement.id;
|
||||
var rootId = bpmnDiagram.plane.bpmnElement.id;
|
||||
|
||||
// we do need to account for different ways we create root elements
|
||||
// each nested imported <root> do have the `_plane` suffix, while
|
||||
|
@ -111,3 +116,99 @@ export function importBpmnDiagram(diagram, definitions, bpmnDiagram) {
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all diagrams in the same hirarchy as the requested Diagram.
|
||||
* It includes all parent- and subProcess diagrams.
|
||||
*
|
||||
* @param {Array} definitions
|
||||
* @param {Object} bpmnDiagram
|
||||
*/
|
||||
function getDiagramsToLoad(definitions, bpmnDiagram) {
|
||||
if (!bpmnDiagram) {
|
||||
return;
|
||||
}
|
||||
|
||||
var bpmnElement = bpmnDiagram.plane.bpmnElement,
|
||||
rootElement = bpmnElement;
|
||||
|
||||
if (!is(bpmnElement, 'bpmn:Process') && !is(bpmnElement, 'bpmn:Collaboration')) {
|
||||
rootElement = findRootProcess(bpmnElement);
|
||||
}
|
||||
|
||||
// in case the process is part of a collaboration, the plane references the
|
||||
// collaboration, not the process
|
||||
var collaboration;
|
||||
if (is(rootElement, 'bpmn:Collaboration')) {
|
||||
collaboration = rootElement;
|
||||
}
|
||||
else {
|
||||
collaboration = find(definitions.rootElements, function(element) {
|
||||
if (!is(element, 'bpmn:Collaboration')) {
|
||||
return;
|
||||
}
|
||||
|
||||
return find(element.participants, function(participant) {
|
||||
return participant.processRef === rootElement;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
var roots = [rootElement];
|
||||
|
||||
// all collaboration processes can contain sub-diagrams
|
||||
if (collaboration) {
|
||||
roots = map(collaboration.participants, function(participant) {
|
||||
return participant.processRef;
|
||||
});
|
||||
|
||||
roots.push(collaboration);
|
||||
}
|
||||
|
||||
var allChildren = selfAndAllFlowElements(roots);
|
||||
|
||||
// if we have multiple diagrams referencing the same element, we
|
||||
// use the first in the file
|
||||
var diagramsToLoad = [bpmnDiagram];
|
||||
var handledElements = [bpmnElement];
|
||||
|
||||
forEach(definitions.diagrams, function(diagram) {
|
||||
var bo = diagram.plane.bpmnElement;
|
||||
|
||||
if (
|
||||
allChildren.indexOf(bo) !== -1 &&
|
||||
handledElements.indexOf(bo) === -1
|
||||
) {
|
||||
diagramsToLoad.push(diagram);
|
||||
handledElements.push(bo);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
return diagramsToLoad;
|
||||
}
|
||||
|
||||
function selfAndAllFlowElements(elements) {
|
||||
var result = [];
|
||||
|
||||
forEach(elements, function(element) {
|
||||
if (!element) {
|
||||
return;
|
||||
}
|
||||
result.push(element);
|
||||
result = result.concat(selfAndAllFlowElements(element.flowElements));
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function findRootProcess(element) {
|
||||
var parent = element;
|
||||
|
||||
while (parent) {
|
||||
if (is(parent, 'bpmn:Process')) {
|
||||
return parent;
|
||||
}
|
||||
parent = parent.$parent;
|
||||
}
|
||||
}
|
|
@ -708,7 +708,7 @@ describe('import - Importer', function() {
|
|||
|
||||
describe('multiple-diagrams', function() {
|
||||
|
||||
it('should import multiple diagrams', function() {
|
||||
it('should import first diagrams if none is defined', function() {
|
||||
|
||||
// given
|
||||
var xml = require('../../fixtures/bpmn/multiple-diagrams.bpmn');
|
||||
|
@ -724,7 +724,7 @@ describe('import - Importer', function() {
|
|||
diagram.invoke(function(elementRegistry, canvas) {
|
||||
|
||||
expect(elementRegistry.get('Task_A')).to.exist;
|
||||
expect(elementRegistry.get('Task_B')).to.exist;
|
||||
expect(elementRegistry.get('Task_B')).to.not.exist;
|
||||
|
||||
expect(canvas.getRootElement()).to.equal(elementRegistry.get('Process_1'));
|
||||
});
|
||||
|
@ -732,6 +732,118 @@ describe('import - Importer', function() {
|
|||
});
|
||||
|
||||
|
||||
it('should import complete diagram tree', function() {
|
||||
|
||||
// given
|
||||
var xml = require('./multiple-nestes-processes.bpmn');
|
||||
var selectedDiagram = 'BpmnDiagram_1';
|
||||
|
||||
// when
|
||||
return runImport(diagram, xml, selectedDiagram).then(function(result) {
|
||||
|
||||
var warnings = result.warnings;
|
||||
|
||||
// then
|
||||
expect(warnings).to.have.length(0);
|
||||
|
||||
diagram.invoke(function(elementRegistry, canvas) {
|
||||
|
||||
expect(elementRegistry.get('SubProcess_1')).to.exist;
|
||||
expect(elementRegistry.get('Task_1A')).to.exist;
|
||||
expect(elementRegistry.get('Task_1B')).to.exist;
|
||||
|
||||
expect(elementRegistry.get('SubProcess_2')).to.not.exist;
|
||||
|
||||
expect(canvas.getRootElement()).to.equal(elementRegistry.get('Process_1'));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('should switch to correct plane', function() {
|
||||
|
||||
// given
|
||||
var xml = require('./multiple-nestes-processes.bpmn');
|
||||
var selectedDiagram = 'SubProcessDiagram_1';
|
||||
|
||||
// when
|
||||
return runImport(diagram, xml, selectedDiagram).then(function(result) {
|
||||
|
||||
var warnings = result.warnings;
|
||||
|
||||
// then
|
||||
expect(warnings).to.have.length(0);
|
||||
|
||||
diagram.invoke(function(elementRegistry, canvas) {
|
||||
|
||||
expect(elementRegistry.get('SubProcess_1')).to.exist;
|
||||
expect(elementRegistry.get('Task_1A')).to.exist;
|
||||
expect(elementRegistry.get('Task_1B')).to.exist;
|
||||
|
||||
expect(elementRegistry.get('SubProcess_2')).to.not.exist;
|
||||
|
||||
expect(canvas.getRootElement()).to.equal(elementRegistry.get('SubProcess_1_plane'));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('should use first diagram for multiple candidates', function() {
|
||||
|
||||
// given
|
||||
var xml = require('./multiple-nestes-processes.bpmn');
|
||||
var selectedDiagram = 'BpmnDiagram_2';
|
||||
|
||||
// when
|
||||
return runImport(diagram, xml, selectedDiagram).then(function(result) {
|
||||
|
||||
var warnings = result.warnings;
|
||||
|
||||
// then
|
||||
expect(warnings).to.have.length(0);
|
||||
|
||||
diagram.invoke(function(elementRegistry, canvas) {
|
||||
|
||||
expect(elementRegistry.get('SubProcess_2')).to.exist;
|
||||
expect(elementRegistry.get('Task_2A')).to.exist;
|
||||
expect(elementRegistry.get('Task_2B')).to.not.exist;
|
||||
|
||||
expect(elementRegistry.get('SubProcess_1')).to.not.exist;
|
||||
|
||||
expect(canvas.getRootElement()).to.equal(elementRegistry.get('Process_2'));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('should use use selected diagram for multiple candidates', function() {
|
||||
|
||||
// given
|
||||
var xml = require('./multiple-nestes-processes.bpmn');
|
||||
var selectedDiagram = 'SubProcess_2_diagram_B';
|
||||
|
||||
// when
|
||||
return runImport(diagram, xml, selectedDiagram).then(function(result) {
|
||||
|
||||
var warnings = result.warnings;
|
||||
|
||||
// then
|
||||
expect(warnings).to.have.length(0);
|
||||
|
||||
diagram.invoke(function(elementRegistry, canvas) {
|
||||
|
||||
expect(elementRegistry.get('SubProcess_2')).to.exist;
|
||||
expect(elementRegistry.get('Task_2A')).to.not.exist;
|
||||
expect(elementRegistry.get('Task_2B')).to.exist;
|
||||
|
||||
expect(elementRegistry.get('SubProcess_1')).to.not.exist;
|
||||
|
||||
expect(canvas.getRootElement()).to.equal(elementRegistry.get('SubProcess_2_plane'));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('should allow subProcess to have attached plane', function() {
|
||||
|
||||
// given
|
||||
|
@ -760,9 +872,7 @@ describe('import - Importer', function() {
|
|||
expect(subProcessElement.parent).to.equal(processRoot);
|
||||
expect(taskInSubProcessElement.parent).to.equal(subProcessRoot);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="sid-38422fae-e03e-43a3-bef4-bd33b32041b2" targetNamespace="http://bpmn.io/bpmn" exporter="bpmn-js (https://demo.bpmn.io)" exporterVersion="3.3.1">
|
||||
<process id="Process_1" isExecutable="false">
|
||||
<bpmn:subProcess id="SubProcess_1">
|
||||
<task id="Task_1A" name="A" />
|
||||
<task id="Task_1B" name="B" />
|
||||
</bpmn:subProcess>
|
||||
</process>
|
||||
<process id="Process_2" isExecutable="false">
|
||||
<bpmn:subProcess id="SubProcess_2">
|
||||
<task id="Task_2A" name="A" />
|
||||
<task id="Task_2B" name="B" />
|
||||
</bpmn:subProcess>
|
||||
</process>
|
||||
<bpmndi:BPMNDiagram id="BpmnDiagram_1">
|
||||
<bpmndi:BPMNPlane id="BpmnPlane_1" bpmnElement="Process_1">
|
||||
<bpmndi:BPMNShape id="SubProcess_1_di" bpmnElement="SubProcess_1">
|
||||
<dc:Bounds x="220" y="50" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
</bpmndi:BPMNPlane>
|
||||
</bpmndi:BPMNDiagram>
|
||||
<bpmndi:BPMNDiagram id="SubProcessDiagram_1">
|
||||
<bpmndi:BPMNPlane id="SubProcessPlane_1" bpmnElement="SubProcess_1">
|
||||
<bpmndi:BPMNShape id="Task_1A_di" bpmnElement="Task_1A">
|
||||
<dc:Bounds x="220" y="50" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Task_1B_di" bpmnElement="Task_1B">
|
||||
<dc:Bounds x="350" y="50" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
</bpmndi:BPMNPlane>
|
||||
</bpmndi:BPMNDiagram>
|
||||
<bpmndi:BPMNDiagram id="BpmnDiagram_2">
|
||||
<bpmndi:BPMNPlane id="BpmnPlane_2" bpmnElement="Process_2">
|
||||
<bpmndi:BPMNShape id="SubProcess_2_di" bpmnElement="SubProcess_2">
|
||||
<omgdc:Bounds x="256" y="81" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
</bpmndi:BPMNPlane>
|
||||
</bpmndi:BPMNDiagram>
|
||||
<bpmndi:BPMNDiagram id="SubProcess_2_diagram_A">
|
||||
<bpmndi:BPMNPlane id="SubProcessPlane_2_A" bpmnElement="SubProcess_2">
|
||||
<bpmndi:BPMNShape id="Task_2A_di" bpmnElement="Task_2A">
|
||||
<omgdc:Bounds x="256" y="81" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
</bpmndi:BPMNPlane>
|
||||
</bpmndi:BPMNDiagram>
|
||||
<bpmndi:BPMNDiagram id="SubProcess_2_diagram_B">
|
||||
<bpmndi:BPMNPlane id="SubProcessPlane_2_B" bpmnElement="SubProcess_2">
|
||||
<bpmndi:BPMNShape id="Task_2B_di" bpmnElement="Task_2B">
|
||||
<omgdc:Bounds x="256" y="81" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
</bpmndi:BPMNPlane>
|
||||
</bpmndi:BPMNDiagram>
|
||||
</definitions>
|
Loading…
Reference in New Issue