2022-01-31 11:18:53 +01:00
|
|
|
import {
|
|
|
|
find,
|
|
|
|
forEach,
|
|
|
|
map
|
|
|
|
} from 'min-dash';
|
|
|
|
|
2018-04-02 21:01:53 +02:00
|
|
|
import BpmnTreeWalker from './BpmnTreeWalker';
|
2014-04-25 16:14:36 +02:00
|
|
|
|
2022-01-31 11:18:53 +01:00
|
|
|
import { is } from '../util/ModelUtil';
|
|
|
|
|
2020-04-29 11:02:42 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* The importBpmnDiagram result.
|
|
|
|
*
|
|
|
|
* @typedef {Object} ImportBPMNDiagramResult
|
|
|
|
*
|
|
|
|
* @property {Array<string>} warnings
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The importBpmnDiagram error.
|
|
|
|
*
|
|
|
|
* @typedef {Error} ImportBPMNDiagramError
|
|
|
|
*
|
|
|
|
* @property {Array<string>} warnings
|
|
|
|
*/
|
2014-04-25 16:14:36 +02:00
|
|
|
|
2014-05-21 16:23:52 +02:00
|
|
|
/**
|
2014-08-01 07:55:47 +02:00
|
|
|
* Import the definitions into a diagram.
|
|
|
|
*
|
|
|
|
* Errors and warnings are reported through the specified callback.
|
2014-06-30 17:01:00 +02:00
|
|
|
*
|
2019-04-12 11:56:00 +02:00
|
|
|
* @param {djs.Diagram} diagram
|
|
|
|
* @param {ModdleElement<Definitions>} definitions
|
|
|
|
* @param {ModdleElement<BPMNDiagram>} [bpmnDiagram] the diagram to be rendered
|
2019-04-04 16:17:43 +02:00
|
|
|
* (if not provided, the first one will be rendered)
|
2020-04-29 11:02:42 +02:00
|
|
|
*
|
|
|
|
* Returns {Promise<ImportBPMNDiagramResult, ImportBPMNDiagramError>}
|
2014-05-21 16:23:52 +02:00
|
|
|
*/
|
2020-04-29 11:02:42 +02:00
|
|
|
export function importBpmnDiagram(diagram, definitions, bpmnDiagram) {
|
2014-03-13 16:06:30 +01:00
|
|
|
|
2017-12-04 22:27:32 +01:00
|
|
|
var importer,
|
|
|
|
eventBus,
|
2021-09-17 09:44:58 +02:00
|
|
|
translate,
|
|
|
|
canvas;
|
2014-04-25 16:14:36 +02:00
|
|
|
|
2014-09-08 19:04:18 +02:00
|
|
|
var error,
|
|
|
|
warnings = [];
|
2014-04-25 16:14:36 +02:00
|
|
|
|
2016-03-17 09:39:43 +01:00
|
|
|
/**
|
|
|
|
* Walk the diagram semantically, importing (=drawing)
|
|
|
|
* all elements you encounter.
|
|
|
|
*
|
2019-04-12 11:56:00 +02:00
|
|
|
* @param {ModdleElement<Definitions>} definitions
|
|
|
|
* @param {ModdleElement<BPMNDiagram>} bpmnDiagram
|
2016-03-17 09:39:43 +01:00
|
|
|
*/
|
2019-04-12 11:56:00 +02:00
|
|
|
function render(definitions, bpmnDiagram) {
|
2014-03-13 16:06:30 +01:00
|
|
|
|
2014-09-08 19:04:18 +02:00
|
|
|
var visitor = {
|
2014-07-01 11:33:28 +02:00
|
|
|
|
2021-08-06 10:35:41 +02:00
|
|
|
root: function(element, di) {
|
|
|
|
return importer.add(element, di);
|
2014-09-08 19:04:18 +02:00
|
|
|
},
|
2014-04-25 16:14:36 +02:00
|
|
|
|
2021-08-06 10:35:41 +02:00
|
|
|
element: function(element, di, parentShape) {
|
|
|
|
return importer.add(element, di, parentShape);
|
2014-09-08 19:04:18 +02:00
|
|
|
},
|
2014-03-13 16:06:30 +01:00
|
|
|
|
2014-09-08 19:04:18 +02:00
|
|
|
error: function(message, context) {
|
|
|
|
warnings.push({ message: message, context: context });
|
|
|
|
}
|
|
|
|
};
|
2014-04-25 16:14:36 +02:00
|
|
|
|
2016-02-25 10:40:56 -06:00
|
|
|
var walker = new BpmnTreeWalker(visitor, translate);
|
2014-06-18 13:05:32 +02:00
|
|
|
|
2022-01-17 11:07:10 +01:00
|
|
|
|
|
|
|
bpmnDiagram = bpmnDiagram || (definitions.diagrams && definitions.diagrams[0]);
|
|
|
|
|
2022-01-31 11:18:53 +01:00
|
|
|
var diagramsToImport = getDiagramsToImport(definitions, bpmnDiagram);
|
2022-01-17 11:07:10 +01:00
|
|
|
|
2022-01-31 11:18:53 +01:00
|
|
|
if (!diagramsToImport) {
|
2022-01-17 11:07:10 +01:00
|
|
|
throw new Error(translate('no diagram to display'));
|
2021-09-17 09:44:58 +02:00
|
|
|
}
|
|
|
|
|
2022-01-17 11:07:10 +01:00
|
|
|
// traverse BPMN 2.0 document model,
|
|
|
|
// starting at definitions
|
2022-01-31 11:18:53 +01:00
|
|
|
forEach(diagramsToImport, function(diagram) {
|
2022-01-17 11:07:10 +01:00
|
|
|
walker.handleDefinitions(definitions, diagram);
|
|
|
|
});
|
2021-12-10 00:31:00 +01:00
|
|
|
|
2022-01-17 11:07:10 +01:00
|
|
|
var rootId = bpmnDiagram.plane.bpmnElement.id;
|
2021-12-10 11:06:09 +01:00
|
|
|
|
|
|
|
// we do need to account for different ways we create root elements
|
|
|
|
// each nested imported <root> do have the `_plane` suffix, while
|
|
|
|
// the root <root> is found under the business object ID
|
2021-12-10 00:31:00 +01:00
|
|
|
canvas.setRootElement(
|
2021-12-10 11:06:09 +01:00
|
|
|
canvas.findRoot(rootId + '_plane') || canvas.findRoot(rootId)
|
2021-12-10 00:31:00 +01:00
|
|
|
);
|
2014-09-08 19:04:18 +02:00
|
|
|
}
|
2014-08-05 08:34:54 +02:00
|
|
|
|
2020-04-29 11:02:42 +02:00
|
|
|
return new Promise(function(resolve, reject) {
|
|
|
|
try {
|
|
|
|
importer = diagram.get('bpmnImporter');
|
|
|
|
eventBus = diagram.get('eventBus');
|
|
|
|
translate = diagram.get('translate');
|
2021-09-17 09:44:58 +02:00
|
|
|
canvas = diagram.get('canvas');
|
2017-12-04 22:27:32 +01:00
|
|
|
|
2020-04-29 11:02:42 +02:00
|
|
|
eventBus.fire('import.render.start', { definitions: definitions });
|
2017-12-04 22:27:32 +01:00
|
|
|
|
2020-04-29 11:02:42 +02:00
|
|
|
render(definitions, bpmnDiagram);
|
2017-12-04 22:27:32 +01:00
|
|
|
|
2020-04-29 11:02:42 +02:00
|
|
|
eventBus.fire('import.render.complete', {
|
|
|
|
error: error,
|
|
|
|
warnings: warnings
|
|
|
|
});
|
|
|
|
|
|
|
|
return resolve({ warnings: warnings });
|
|
|
|
} catch (e) {
|
2014-09-08 19:04:18 +02:00
|
|
|
|
2020-04-29 11:02:42 +02:00
|
|
|
e.warnings = warnings;
|
|
|
|
return reject(e);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
2022-01-17 11:07:10 +01:00
|
|
|
|
|
|
|
/**
|
2022-01-31 11:18:53 +01:00
|
|
|
* Returns all diagrams in the same hirarchy as the requested diagram.
|
|
|
|
* Includes all parent and sub process diagrams.
|
2022-01-17 11:07:10 +01:00
|
|
|
*
|
|
|
|
* @param {Array} definitions
|
|
|
|
* @param {Object} bpmnDiagram
|
2022-01-31 11:18:53 +01:00
|
|
|
*
|
|
|
|
* @returns {Array<Object>}
|
2022-01-17 11:07:10 +01:00
|
|
|
*/
|
2022-01-31 11:18:53 +01:00
|
|
|
function getDiagramsToImport(definitions, bpmnDiagram) {
|
2022-01-17 11:07:10 +01:00
|
|
|
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;
|
2022-01-31 11:18:53 +01:00
|
|
|
|
2022-01-17 11:07:10 +01:00
|
|
|
if (is(rootElement, 'bpmn:Collaboration')) {
|
|
|
|
collaboration = rootElement;
|
2022-01-31 11:18:53 +01:00
|
|
|
} else {
|
2022-01-17 11:07:10 +01:00
|
|
|
collaboration = find(definitions.rootElements, function(element) {
|
|
|
|
if (!is(element, 'bpmn:Collaboration')) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
return find(element.participants, function(participant) {
|
|
|
|
return participant.processRef === rootElement;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2022-01-31 11:18:53 +01:00
|
|
|
var rootElements = [ rootElement ];
|
2022-01-17 11:07:10 +01:00
|
|
|
|
|
|
|
// all collaboration processes can contain sub-diagrams
|
|
|
|
if (collaboration) {
|
2022-01-31 11:18:53 +01:00
|
|
|
rootElements = map(collaboration.participants, function(participant) {
|
2022-01-17 11:07:10 +01:00
|
|
|
return participant.processRef;
|
|
|
|
});
|
|
|
|
|
2022-01-31 11:18:53 +01:00
|
|
|
rootElements.push(collaboration);
|
2022-01-17 11:07:10 +01:00
|
|
|
}
|
|
|
|
|
2022-01-31 11:18:53 +01:00
|
|
|
var allChildren = selfAndAllFlowElements(rootElements);
|
2022-01-17 11:07:10 +01:00
|
|
|
|
|
|
|
// if we have multiple diagrams referencing the same element, we
|
|
|
|
// use the first in the file
|
2022-01-31 11:18:53 +01:00
|
|
|
var diagramsToImport = [ bpmnDiagram ];
|
|
|
|
var handledElements = [ bpmnElement ];
|
2022-01-17 11:07:10 +01:00
|
|
|
|
|
|
|
forEach(definitions.diagrams, function(diagram) {
|
2022-01-31 11:18:53 +01:00
|
|
|
var businessObject = diagram.plane.bpmnElement;
|
2022-01-17 11:07:10 +01:00
|
|
|
|
|
|
|
if (
|
2022-01-31 11:18:53 +01:00
|
|
|
allChildren.indexOf(businessObject) !== -1 &&
|
|
|
|
handledElements.indexOf(businessObject) === -1
|
2022-01-17 11:07:10 +01:00
|
|
|
) {
|
2022-01-31 11:18:53 +01:00
|
|
|
diagramsToImport.push(diagram);
|
|
|
|
handledElements.push(businessObject);
|
2022-01-17 11:07:10 +01:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
|
2022-01-31 11:18:53 +01:00
|
|
|
return diagramsToImport;
|
2022-01-17 11:07:10 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
function selfAndAllFlowElements(elements) {
|
|
|
|
var result = [];
|
|
|
|
|
|
|
|
forEach(elements, function(element) {
|
|
|
|
if (!element) {
|
|
|
|
return;
|
|
|
|
}
|
2022-01-31 11:18:53 +01:00
|
|
|
|
2022-01-17 11:07:10 +01:00
|
|
|
result.push(element);
|
2022-01-31 11:18:53 +01:00
|
|
|
|
2022-01-17 11:07:10 +01:00
|
|
|
result = result.concat(selfAndAllFlowElements(element.flowElements));
|
|
|
|
});
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
function findRootProcess(element) {
|
|
|
|
var parent = element;
|
|
|
|
|
|
|
|
while (parent) {
|
|
|
|
if (is(parent, 'bpmn:Process')) {
|
|
|
|
return parent;
|
|
|
|
}
|
2022-01-31 11:18:53 +01:00
|
|
|
|
2022-01-17 11:07:10 +01:00
|
|
|
parent = parent.$parent;
|
|
|
|
}
|
|
|
|
}
|