bpmn-js/lib/core/BpmnImporter.js

184 lines
4.5 KiB
JavaScript

'use strict';
var _ = require('lodash');
var LabelUtil = require('../util/Label');
var hasExternalLabel = LabelUtil.hasExternalLabel,
getExternalLabelBounds = LabelUtil.getExternalLabelBounds,
isExpanded = require('../util/Di').isExpanded;
function elementData(semantic, attrs) {
return _.extend({
id: semantic.id,
type: semantic.$type,
businessObject: semantic
}, attrs);
}
function collectWaypoints(waypoints) {
return _.collect(waypoints, function(p) {
return { x: p.x, y: p.y };
});
}
/**
* An importer that adds bpmn elements to the canvas
*
* @param {EventBus} eventBus
* @param {Canvas} canvas
* @param {ElementFactory} elementFactory
* @param {ElementRegistry} elementRegistry
*/
function BpmnImporter(eventBus, canvas, elementFactory, elementRegistry) {
this._eventBus = eventBus;
this._canvas = canvas;
this._elementFactory = elementFactory;
this._elementRegistry = elementRegistry;
}
BpmnImporter.$inject = [ 'eventBus', 'canvas', 'elementFactory', 'elementRegistry' ];
module.exports = BpmnImporter;
/**
* Add bpmn element (semantic) to the canvas onto the
* specified parent shape.
*/
BpmnImporter.prototype.add = function(semantic, parentElement) {
var di = semantic.di,
element;
// ROOT ELEMENT
// handle the special case that we deal with a
// invisible root element (process or collaboration)
if (di.$instanceOf('bpmndi:BPMNPlane')) {
// add a virtual element (not being drawn)
element = this._elementFactory.createRoot(elementData(semantic));
}
// SHAPE
else if (di.$instanceOf('bpmndi:BPMNShape')) {
var collapsed = !isExpanded(semantic);
var hidden = parentElement && (parentElement.hidden || parentElement.collapsed);
var bounds = semantic.di.bounds;
element = this._elementFactory.createShape(elementData(semantic, {
collapsed: collapsed,
hidden: hidden,
x: bounds.x,
y: bounds.y,
width: bounds.width,
height: bounds.height
}));
this._canvas.addShape(element, parentElement);
}
// CONNECTION
else if (di.$instanceOf('bpmndi:BPMNEdge')) {
var source = this._getSource(semantic),
target = this._getTarget(semantic);
if (!source || !target) {
throw new Error('source or target not rendered for element <' + semantic.id + '>');
}
element = this._elementFactory.createConnection(elementData(semantic, {
source: source,
target: target,
waypoints: collectWaypoints(semantic.di.waypoint)
}));
this._canvas.addConnection(element, parentElement);
} else {
throw new Error('unknown di <' + di.$type + '> for element <' + semantic.id + '>');
}
// (optional) LABEL
if (hasExternalLabel(semantic)) {
this.addLabel(semantic, element);
}
this._eventBus.fire('bpmnElement.added', { element: element });
return element;
};
/**
* add label for an element
*/
BpmnImporter.prototype.addLabel = function (semantic, element) {
var bounds = getExternalLabelBounds(semantic, element);
var label = this._elementFactory.createLabel(elementData(semantic, {
id: semantic.id + '_label',
labelTarget: element,
type: 'label',
hidden: element.hidden,
x: bounds.x,
y: bounds.y,
width: bounds.width,
height: bounds.height
}));
return this._canvas.addShape(label, element.parent);
};
BpmnImporter.prototype._getSource = function(semantic) {
var element,
elementSemantic = semantic.sourceRef;
// handle mysterious isMany DataAssociation#sourceRef
if (_.isArray(elementSemantic)) {
elementSemantic = elementSemantic[0];
}
if (elementSemantic && elementSemantic.$instanceOf('bpmn:DataOutput')) {
elementSemantic = elementSemantic.$parent.$parent;
}
element = elementSemantic && this._getElement(elementSemantic);
if (element) {
return element;
}
throw new Error('element <' + elementSemantic.id + '> referenced by <' + semantic.id + '> not yet drawn');
};
BpmnImporter.prototype._getTarget = function(semantic) {
var element,
elementSemantic = semantic.targetRef;
if (elementSemantic && elementSemantic.$instanceOf('bpmn:DataInput')) {
elementSemantic = elementSemantic.$parent.$parent;
}
element = elementSemantic && this._getElement(elementSemantic);
if (element) {
return element;
}
throw new Error('element <' + elementSemantic.id + '> referenced by <' + semantic.id + '> not yet drawn');
};
BpmnImporter.prototype._getElement = function(semantic) {
return this._elementRegistry.getById(semantic.id);
};