2014-05-21 14:23:52 +00:00
|
|
|
'use strict';
|
|
|
|
|
2014-03-13 19:21:42 +00:00
|
|
|
var _ = require('lodash');
|
|
|
|
|
2014-04-03 09:47:26 +00:00
|
|
|
var BpmnTreeWalker = require('./BpmnTreeWalker'),
|
|
|
|
Util = require('../Util');
|
2014-03-13 15:06:30 +00:00
|
|
|
|
2014-04-25 14:14:36 +00:00
|
|
|
|
|
|
|
function hasLabel(element) {
|
|
|
|
|
|
|
|
return element.$instanceOf('bpmn:Event') ||
|
|
|
|
element.$instanceOf('bpmn:Gateway') ||
|
|
|
|
element.$instanceOf('bpmn:DataStoreReference') ||
|
|
|
|
element.$instanceOf('bpmn:DataObjectReference') ||
|
2014-06-17 09:03:03 +00:00
|
|
|
element.$instanceOf('bpmn:SequenceFlow') ||
|
|
|
|
element.$instanceOf('bpmn:MessageFlow');
|
2014-04-25 14:14:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-05-21 14:23:52 +00:00
|
|
|
function isCollapsed(element, di) {
|
2014-05-22 08:51:23 +00:00
|
|
|
return element.$instanceOf('bpmn:SubProcess') && di && !di.isExpanded;
|
2014-05-21 14:23:52 +00:00
|
|
|
}
|
|
|
|
|
2014-04-25 14:14:36 +00:00
|
|
|
function getWaypointsMid(waypoints) {
|
|
|
|
|
|
|
|
var mid = waypoints.length / 2 - 1;
|
|
|
|
|
|
|
|
var first = waypoints[Math.floor(mid)];
|
|
|
|
var second = waypoints[Math.ceil(mid + 0.01)];
|
|
|
|
|
|
|
|
return {
|
|
|
|
x: first.x + (second.x - first.x) / 2,
|
|
|
|
y: first.y + (second.y - first.y) / 2
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-05-21 14:23:52 +00:00
|
|
|
/**
|
|
|
|
* Returns the bounds of an elements label, parsed from the elements DI or
|
|
|
|
* generated from its bounds.
|
|
|
|
*/
|
2014-04-25 14:14:36 +00:00
|
|
|
function getLabelBounds(di, data) {
|
|
|
|
|
|
|
|
var mid,
|
|
|
|
size;
|
|
|
|
|
|
|
|
var label = di.label;
|
|
|
|
if (label && label.bounds) {
|
|
|
|
var bounds = label.bounds;
|
|
|
|
|
|
|
|
size = {
|
|
|
|
width: Math.max(150, bounds.width),
|
|
|
|
height: bounds.height
|
|
|
|
};
|
|
|
|
|
|
|
|
mid = {
|
|
|
|
x: bounds.x + bounds.width / 2,
|
|
|
|
y: bounds.y
|
|
|
|
};
|
|
|
|
} else {
|
|
|
|
|
|
|
|
if (data.waypoints) {
|
|
|
|
mid = getWaypointsMid(data.waypoints);
|
|
|
|
} else {
|
|
|
|
mid = {
|
|
|
|
x: data.x + data.width / 2,
|
2014-05-06 15:22:39 +00:00
|
|
|
y: data.y + data.height - 5
|
2014-04-25 14:14:36 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
size = {
|
2014-05-06 15:22:39 +00:00
|
|
|
width: 90,
|
2014-04-25 14:14:36 +00:00
|
|
|
height: 50
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
return _.extend({
|
|
|
|
x: mid.x - size.width / 2,
|
|
|
|
y: mid.y
|
|
|
|
}, size);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-03-13 15:06:30 +00:00
|
|
|
function importBpmnDiagram(diagram, definitions, done) {
|
|
|
|
|
2014-03-20 15:18:23 +00:00
|
|
|
var canvas = diagram.get('canvas');
|
2014-04-03 09:47:26 +00:00
|
|
|
var events = diagram.get('eventBus');
|
2014-03-18 16:01:24 +00:00
|
|
|
|
2014-04-25 14:14:36 +00:00
|
|
|
|
|
|
|
function addLabel(element, di, data) {
|
|
|
|
if (!hasLabel(element)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
var labelBounds = getLabelBounds(di, data);
|
|
|
|
|
2014-06-11 12:41:55 +00:00
|
|
|
var label = _.extend({
|
2014-04-25 14:14:36 +00:00
|
|
|
id: element.id + '_label',
|
|
|
|
attachedId: element.id,
|
2014-06-17 09:18:33 +00:00
|
|
|
type: 'label',
|
|
|
|
hidden: data.hidden
|
2014-06-11 12:41:55 +00:00
|
|
|
}, labelBounds);
|
|
|
|
|
|
|
|
canvas.addShape(label);
|
|
|
|
|
|
|
|
// we wire data and label so that
|
|
|
|
// the label of a BPMN element can be quickly accessed via
|
|
|
|
// element.label in various components
|
|
|
|
data.label = label;
|
2014-04-25 14:14:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-03-21 15:46:56 +00:00
|
|
|
var visitor = {
|
2014-03-13 15:06:30 +00:00
|
|
|
|
2014-03-21 15:46:56 +00:00
|
|
|
element: function(element, di, parent) {
|
2014-03-18 16:01:24 +00:00
|
|
|
|
2014-03-21 15:46:56 +00:00
|
|
|
var shape;
|
2014-03-13 15:06:30 +00:00
|
|
|
|
2014-04-03 09:47:26 +00:00
|
|
|
function fire(type, shape) {
|
|
|
|
events.fire('bpmn.element.' + type, {
|
|
|
|
semantic: element, di: di, diagramElement: shape
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2014-03-21 15:46:56 +00:00
|
|
|
if (di.$type === 'bpmndi:BPMNShape') {
|
|
|
|
var bounds = di.bounds;
|
2014-03-18 16:01:24 +00:00
|
|
|
|
2014-05-21 14:23:52 +00:00
|
|
|
var collapsed = isCollapsed(element, di);
|
|
|
|
var hidden = parent && (parent.hidden || parent.collapsed);
|
|
|
|
|
2014-04-01 12:16:18 +00:00
|
|
|
shape = {
|
|
|
|
id: element.id, type: element.$type,
|
|
|
|
x: bounds.x, y: bounds.y,
|
|
|
|
width: bounds.width, height: bounds.height,
|
2014-05-21 14:23:52 +00:00
|
|
|
collapsed: collapsed,
|
|
|
|
hidden: hidden,
|
2014-04-01 12:16:18 +00:00
|
|
|
parent: parent
|
|
|
|
};
|
2014-03-13 19:21:42 +00:00
|
|
|
|
2014-04-03 09:47:26 +00:00
|
|
|
fire('add', shape);
|
2014-03-21 15:46:56 +00:00
|
|
|
canvas.addShape(shape);
|
|
|
|
} else {
|
2014-03-13 19:21:42 +00:00
|
|
|
|
2014-03-21 15:46:56 +00:00
|
|
|
var waypoints = _.collect(di.waypoint, function(p) {
|
|
|
|
return { x: p.x, y: p.y };
|
|
|
|
});
|
|
|
|
|
|
|
|
shape = { id: element.id, type: element.$type, waypoints: waypoints };
|
2014-04-03 09:47:26 +00:00
|
|
|
|
|
|
|
fire('add', shape);
|
2014-03-21 15:46:56 +00:00
|
|
|
canvas.addConnection(shape);
|
|
|
|
}
|
2014-03-18 16:01:24 +00:00
|
|
|
|
2014-04-03 09:47:26 +00:00
|
|
|
fire('added', shape);
|
2014-03-18 16:01:24 +00:00
|
|
|
|
2014-04-25 14:14:36 +00:00
|
|
|
// add label if needed
|
|
|
|
addLabel(element, di, shape);
|
|
|
|
|
2014-03-21 15:46:56 +00:00
|
|
|
return shape;
|
|
|
|
},
|
2014-04-25 14:14:36 +00:00
|
|
|
|
2014-03-21 15:46:56 +00:00
|
|
|
error: function(message, context) {
|
|
|
|
console.warn('[import]', message, context);
|
|
|
|
}
|
2014-03-13 15:06:30 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
var walker = new BpmnTreeWalker(visitor);
|
|
|
|
walker.handleDefinitions(definitions);
|
2014-04-25 14:14:36 +00:00
|
|
|
|
2014-03-13 15:06:30 +00:00
|
|
|
done();
|
|
|
|
}
|
|
|
|
|
2014-04-03 09:47:26 +00:00
|
|
|
module.exports.importBpmnDiagram = Util.failSafeAsync(importBpmnDiagram);
|