update
This commit is contained in:
@@ -0,0 +1,350 @@
|
||||
import {
|
||||
assign
|
||||
} from 'min-dash';
|
||||
|
||||
import { is } from '../util/ModelUtil';
|
||||
|
||||
import {
|
||||
isLabelExternal,
|
||||
getExternalLabelBounds
|
||||
} from '../util/LabelUtil';
|
||||
|
||||
import {
|
||||
getMid
|
||||
} from 'diagram-js/lib/layout/LayoutUtil';
|
||||
|
||||
import {
|
||||
isExpanded
|
||||
} from '../util/DiUtil';
|
||||
|
||||
import {
|
||||
getLabel
|
||||
} from '../features/label-editing/LabelUtil';
|
||||
|
||||
import {
|
||||
elementToString
|
||||
} from './Util';
|
||||
var lineName=[];
|
||||
var lineId=[];
|
||||
|
||||
function elementData(semantic, attrs) {
|
||||
return assign({
|
||||
id: semantic.id,
|
||||
type: semantic.$type,
|
||||
businessObject: semantic
|
||||
}, attrs);
|
||||
}
|
||||
|
||||
function getWaypoints(bo, source, target) {
|
||||
|
||||
var waypoints = bo.di.waypoint;
|
||||
|
||||
if (!waypoints || waypoints.length < 2) {
|
||||
return [ getMid(source), getMid(target) ];
|
||||
}
|
||||
|
||||
return waypoints.map(function(p) {
|
||||
return { x: p.x, y: p.y };
|
||||
});
|
||||
}
|
||||
|
||||
function notYetDrawn(translate, semantic, refSemantic, property) {
|
||||
return new Error(translate('element {element} referenced by {referenced}#{property} not yet drawn', {
|
||||
element: elementToString(refSemantic),
|
||||
referenced: elementToString(semantic),
|
||||
property: property
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* An importer that adds bpmn elements to the canvas
|
||||
*
|
||||
* @param {EventBus} eventBus
|
||||
* @param {Canvas} canvas
|
||||
* @param {ElementFactory} elementFactory
|
||||
* @param {ElementRegistry} elementRegistry
|
||||
* @param {Function} translate
|
||||
* @param {TextRenderer} textRenderer
|
||||
*/
|
||||
export default function BpmnImporter(
|
||||
eventBus, canvas, elementFactory,
|
||||
elementRegistry, translate, textRenderer) {
|
||||
|
||||
this._eventBus = eventBus;
|
||||
this._canvas = canvas;
|
||||
this._elementFactory = elementFactory;
|
||||
this._elementRegistry = elementRegistry;
|
||||
this._translate = translate;
|
||||
this._textRenderer = textRenderer;
|
||||
this._getLineName = lineName;
|
||||
this._getLineId = lineId;
|
||||
}
|
||||
|
||||
BpmnImporter.$inject = [
|
||||
'eventBus',
|
||||
'canvas',
|
||||
'elementFactory',
|
||||
'elementRegistry',
|
||||
'translate',
|
||||
'textRenderer'
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* Add bpmn element (semantic) to the canvas onto the
|
||||
* specified parent shape.
|
||||
*/
|
||||
BpmnImporter.prototype.add = function(semantic, parentElement) {
|
||||
|
||||
var di = semantic.di,
|
||||
element,
|
||||
translate = this._translate,
|
||||
hidden;
|
||||
|
||||
var parentIndex;
|
||||
|
||||
// ROOT ELEMENT
|
||||
// handle the special case that we deal with a
|
||||
// invisible root element (process or collaboration)
|
||||
if (is(di, 'bpmndi:BPMNPlane')) {
|
||||
|
||||
// add a virtual element (not being drawn)
|
||||
element = this._elementFactory.createRoot(elementData(semantic));
|
||||
|
||||
this._canvas.setRootElement(element);
|
||||
}
|
||||
|
||||
// SHAPE
|
||||
else if (is(di, 'bpmndi:BPMNShape')) {
|
||||
var collapsed = !isExpanded(semantic);
|
||||
hidden = parentElement && (parentElement.hidden || parentElement.collapsed);
|
||||
|
||||
var bounds = semantic.di.bounds;
|
||||
|
||||
element = this._elementFactory.createShape(elementData(semantic, {
|
||||
collapsed: collapsed,
|
||||
hidden: hidden,
|
||||
x: Math.round(bounds.x),
|
||||
y: Math.round(bounds.y),
|
||||
width: Math.round(bounds.width),
|
||||
height: Math.round(bounds.height)
|
||||
}));
|
||||
|
||||
if (is(semantic, 'bpmn:BoundaryEvent')) {
|
||||
this._attachBoundary(semantic, element);
|
||||
}
|
||||
|
||||
// insert lanes behind other flow nodes (cf. #727)
|
||||
if (is(semantic, 'bpmn:Lane')) {
|
||||
parentIndex = 0;
|
||||
}
|
||||
|
||||
if (is(semantic, 'bpmn:DataStoreReference')) {
|
||||
|
||||
// check wether data store is inside our outside of its semantic parent
|
||||
if (!isPointInsideBBox(parentElement, getMid(bounds))) {
|
||||
parentElement = this._canvas.getRootElement();
|
||||
}
|
||||
}
|
||||
|
||||
this._canvas.addShape(element, parentElement, parentIndex);
|
||||
}
|
||||
|
||||
// CONNECTION
|
||||
else if (is(di, 'bpmndi:BPMNEdge')) {
|
||||
|
||||
var source = this._getSource(semantic),
|
||||
target = this._getTarget(semantic);
|
||||
|
||||
hidden = parentElement && (parentElement.hidden || parentElement.collapsed);
|
||||
|
||||
element = this._elementFactory.createConnection(elementData(semantic, {
|
||||
hidden: hidden,
|
||||
source: source,
|
||||
target: target,
|
||||
waypoints: getWaypoints(semantic, source, target)
|
||||
}));
|
||||
|
||||
if (is(semantic, 'bpmn:DataAssociation')) {
|
||||
|
||||
// render always on top; this ensures DataAssociations
|
||||
// are rendered correctly across different "hacks" people
|
||||
// love to model such as cross participant / sub process
|
||||
// associations
|
||||
parentElement = null;
|
||||
}
|
||||
|
||||
// insert sequence flows behind other flow nodes (cf. #727)
|
||||
if (is(semantic, 'bpmn:SequenceFlow')) {
|
||||
parentIndex = 0;
|
||||
}
|
||||
|
||||
this._canvas.addConnection(element, parentElement, parentIndex);
|
||||
} else {
|
||||
throw new Error(translate('unknown di {di} for element {semantic}', {
|
||||
di: elementToString(di),
|
||||
semantic: elementToString(semantic)
|
||||
}));
|
||||
}
|
||||
// (optional) LABEL
|
||||
if (isLabelExternal(semantic) && getLabel(element)) {
|
||||
//alert(11)
|
||||
if(semantic.name.length>20){
|
||||
let obj = {};
|
||||
obj.id = semantic.id;
|
||||
obj.name = semantic.name;
|
||||
lineName.push(obj);
|
||||
}
|
||||
if(semantic.$type=='bpmn:SequenceFlow'){
|
||||
lineId.push(semantic.id);
|
||||
}
|
||||
let name = semantic.name.length >20?semantic.name.substring(0,20)+"...":semantic.name;
|
||||
semantic.name=name;
|
||||
this.addLabel(semantic, element);
|
||||
}
|
||||
|
||||
|
||||
this._eventBus.fire('bpmnElement.added', { element: element });
|
||||
|
||||
return element;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Attach the boundary element to the given host
|
||||
*
|
||||
* @param {ModdleElement} boundarySemantic
|
||||
* @param {djs.model.Base} boundaryElement
|
||||
*/
|
||||
BpmnImporter.prototype._attachBoundary = function(boundarySemantic, boundaryElement) {
|
||||
var translate = this._translate;
|
||||
var hostSemantic = boundarySemantic.attachedToRef;
|
||||
|
||||
if (!hostSemantic) {
|
||||
throw new Error(translate('missing {semantic}#attachedToRef', {
|
||||
semantic: elementToString(boundarySemantic)
|
||||
}));
|
||||
}
|
||||
|
||||
var host = this._elementRegistry.get(hostSemantic.id),
|
||||
attachers = host && host.attachers;
|
||||
|
||||
if (!host) {
|
||||
throw notYetDrawn(translate, boundarySemantic, hostSemantic, 'attachedToRef');
|
||||
}
|
||||
|
||||
// wire element.host <> host.attachers
|
||||
boundaryElement.host = host;
|
||||
|
||||
if (!attachers) {
|
||||
host.attachers = attachers = [];
|
||||
}
|
||||
|
||||
if (attachers.indexOf(boundaryElement) === -1) {
|
||||
attachers.push(boundaryElement);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* add label for an element
|
||||
*/
|
||||
BpmnImporter.prototype.addLabel = function(semantic, element) {
|
||||
var bounds,
|
||||
text,
|
||||
label;
|
||||
bounds = getExternalLabelBounds(semantic, element);
|
||||
text = getLabel(element);
|
||||
if (text) {
|
||||
// get corrected bounds from actual layouted text
|
||||
bounds = this._textRenderer.getExternalLabelBounds(bounds, text);
|
||||
}
|
||||
|
||||
label = this._elementFactory.createLabel(elementData(semantic, {
|
||||
id: semantic.id + '_label',
|
||||
labelTarget: element,
|
||||
type: 'label',
|
||||
hidden: element.hidden || !getLabel(element),
|
||||
x: Math.round(bounds.x),
|
||||
y: Math.round(bounds.y),
|
||||
width: Math.round(bounds.width),
|
||||
height: Math.round(bounds.height)
|
||||
}));
|
||||
|
||||
return this._canvas.addShape(label, element.parent);
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the drawn connection end based on the given side.
|
||||
*
|
||||
* @throws {Error} if the end is not yet drawn
|
||||
*/
|
||||
BpmnImporter.prototype._getEnd = function(semantic, side) {
|
||||
|
||||
var element,
|
||||
refSemantic,
|
||||
type = semantic.$type,
|
||||
translate = this._translate;
|
||||
|
||||
refSemantic = semantic[side + 'Ref'];
|
||||
|
||||
// handle mysterious isMany DataAssociation#sourceRef
|
||||
if (side === 'source' && type === 'bpmn:DataInputAssociation') {
|
||||
refSemantic = refSemantic && refSemantic[0];
|
||||
}
|
||||
|
||||
// fix source / target for DataInputAssociation / DataOutputAssociation
|
||||
if (side === 'source' && type === 'bpmn:DataOutputAssociation' ||
|
||||
side === 'target' && type === 'bpmn:DataInputAssociation') {
|
||||
|
||||
refSemantic = semantic.$parent;
|
||||
}
|
||||
|
||||
element = refSemantic && this._getElement(refSemantic);
|
||||
|
||||
if (element) {
|
||||
return element;
|
||||
}
|
||||
|
||||
if (refSemantic) {
|
||||
throw notYetDrawn(translate, semantic, refSemantic, side + 'Ref');
|
||||
} else {
|
||||
throw new Error(translate('{semantic}#{side} Ref not specified', {
|
||||
semantic: elementToString(semantic),
|
||||
side: side
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
BpmnImporter.prototype._getSource = function(semantic) {
|
||||
return this._getEnd(semantic, 'source');
|
||||
};
|
||||
|
||||
BpmnImporter.prototype._getTarget = function(semantic) {
|
||||
return this._getEnd(semantic, 'target');
|
||||
};
|
||||
|
||||
|
||||
BpmnImporter.prototype._getElement = function(semantic) {
|
||||
return this._elementRegistry.get(semantic.id);
|
||||
};
|
||||
|
||||
|
||||
// helpers ////////////////////
|
||||
|
||||
function isPointInsideBBox(bbox, point) {
|
||||
var x = point.x,
|
||||
y = point.y;
|
||||
|
||||
return x >= bbox.x &&
|
||||
x <= bbox.x + bbox.width &&
|
||||
y >= bbox.y &&
|
||||
y <= bbox.y + bbox.height;
|
||||
}
|
||||
BpmnImporter.prototype._getLineName = function() {
|
||||
return lineName;
|
||||
};
|
||||
BpmnImporter.prototype._getLineId = function() {
|
||||
return lineId;
|
||||
};
|
||||
@@ -0,0 +1,464 @@
|
||||
import {
|
||||
filter,
|
||||
find,
|
||||
forEach
|
||||
} from 'min-dash';
|
||||
|
||||
import Refs from 'object-refs';
|
||||
|
||||
import {
|
||||
elementToString
|
||||
} from './Util';
|
||||
|
||||
var diRefs = new Refs(
|
||||
{ name: 'bpmnElement', enumerable: true },
|
||||
{ name: 'di', configurable: true }
|
||||
);
|
||||
|
||||
/**
|
||||
* Returns true if an element has the given meta-model type
|
||||
*
|
||||
* @param {ModdleElement} element
|
||||
* @param {String} type
|
||||
*
|
||||
* @return {Boolean}
|
||||
*/
|
||||
function is(element, type) {
|
||||
return element.$instanceOf(type);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Find a suitable display candidate for definitions where the DI does not
|
||||
* correctly specify one.
|
||||
*/
|
||||
function findDisplayCandidate(definitions) {
|
||||
return find(definitions.rootElements, function(e) {
|
||||
return is(e, 'bpmn:Process') || is(e, 'bpmn:Collaboration');
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
export default function BpmnTreeWalker(handler, translate) {
|
||||
|
||||
// list of containers already walked
|
||||
var handledElements = {};
|
||||
|
||||
// list of elements to handle deferred to ensure
|
||||
// prerequisites are drawn
|
||||
var deferred = [];
|
||||
|
||||
// Helpers //////////////////////
|
||||
|
||||
function contextual(fn, ctx) {
|
||||
return function(e) {
|
||||
fn(e, ctx);
|
||||
};
|
||||
}
|
||||
|
||||
function handled(element) {
|
||||
handledElements[element.id] = element;
|
||||
}
|
||||
|
||||
function isHandled(element) {
|
||||
return handledElements[element.id];
|
||||
}
|
||||
|
||||
function visit(element, ctx) {
|
||||
|
||||
var gfx = element.gfx;
|
||||
|
||||
// avoid multiple rendering of elements
|
||||
if (gfx) {
|
||||
throw new Error(
|
||||
translate('already rendered {element}', { element: elementToString(element) })
|
||||
);
|
||||
}
|
||||
|
||||
// call handler
|
||||
return handler.element(element, ctx);
|
||||
}
|
||||
|
||||
function visitRoot(element, diagram) {
|
||||
return handler.root(element, diagram);
|
||||
}
|
||||
|
||||
function visitIfDi(element, ctx) {
|
||||
|
||||
try {
|
||||
var gfx = element.di && visit(element, ctx);
|
||||
|
||||
handled(element);
|
||||
|
||||
return gfx;
|
||||
} catch (e) {
|
||||
logError(e.message, { element: element, error: e });
|
||||
|
||||
console.error(translate('failed to import {element}', { element: elementToString(element) }));
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
function logError(message, context) {
|
||||
handler.error(message, context);
|
||||
}
|
||||
|
||||
// DI handling //////////////////////
|
||||
|
||||
function registerDi(di) {
|
||||
var bpmnElement = di.bpmnElement;
|
||||
|
||||
if (bpmnElement) {
|
||||
if (bpmnElement.di) {
|
||||
logError(
|
||||
translate('multiple DI elements defined for {element}', {
|
||||
element: elementToString(bpmnElement)
|
||||
}),
|
||||
{ element: bpmnElement }
|
||||
);
|
||||
} else {
|
||||
diRefs.bind(bpmnElement, 'di');
|
||||
bpmnElement.di = di;
|
||||
}
|
||||
} else {
|
||||
logError(
|
||||
translate('no bpmnElement referenced in {element}', {
|
||||
element: elementToString(di)
|
||||
}),
|
||||
{ element: di }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function handleDiagram(diagram) {
|
||||
handlePlane(diagram.plane);
|
||||
}
|
||||
|
||||
function handlePlane(plane) {
|
||||
registerDi(plane);
|
||||
|
||||
forEach(plane.planeElement, handlePlaneElement);
|
||||
}
|
||||
|
||||
function handlePlaneElement(planeElement) {
|
||||
registerDi(planeElement);
|
||||
}
|
||||
|
||||
|
||||
// Semantic handling //////////////////////
|
||||
|
||||
/**
|
||||
* Handle definitions and return the rendered diagram (if any)
|
||||
*
|
||||
* @param {ModdleElement} definitions to walk and import
|
||||
* @param {ModdleElement} [diagram] specific diagram to import and display
|
||||
*
|
||||
* @throws {Error} if no diagram to display could be found
|
||||
*/
|
||||
function handleDefinitions(definitions, diagram) {
|
||||
// make sure we walk the correct bpmnElement
|
||||
|
||||
var diagrams = definitions.diagrams;
|
||||
|
||||
if (diagram && diagrams.indexOf(diagram) === -1) {
|
||||
throw new Error(translate('diagram not part of bpmn:Definitions'));
|
||||
}
|
||||
|
||||
if (!diagram && diagrams && diagrams.length) {
|
||||
diagram = diagrams[0];
|
||||
}
|
||||
|
||||
// no diagram -> nothing to import
|
||||
if (!diagram) {
|
||||
throw new Error(translate('no diagram to display'));
|
||||
}
|
||||
|
||||
// load DI from selected diagram only
|
||||
handleDiagram(diagram);
|
||||
|
||||
|
||||
var plane = diagram.plane;
|
||||
|
||||
if (!plane) {
|
||||
throw new Error(translate(
|
||||
'no plane for {element}',
|
||||
{ element: elementToString(diagram) }
|
||||
));
|
||||
}
|
||||
|
||||
var rootElement = plane.bpmnElement;
|
||||
|
||||
// ensure we default to a suitable display candidate (process or collaboration),
|
||||
// even if non is specified in DI
|
||||
if (!rootElement) {
|
||||
rootElement = findDisplayCandidate(definitions);
|
||||
|
||||
if (!rootElement) {
|
||||
throw new Error(translate('no process or collaboration to display'));
|
||||
} else {
|
||||
|
||||
logError(
|
||||
translate('correcting missing bpmnElement on {plane} to {rootElement}', {
|
||||
plane: elementToString(plane),
|
||||
rootElement: elementToString(rootElement)
|
||||
})
|
||||
);
|
||||
|
||||
// correct DI on the fly
|
||||
plane.bpmnElement = rootElement;
|
||||
registerDi(plane);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var ctx = visitRoot(rootElement, plane);
|
||||
|
||||
if (is(rootElement, 'bpmn:Process')) {
|
||||
handleProcess(rootElement, ctx);
|
||||
} else if (is(rootElement, 'bpmn:Collaboration')) {
|
||||
handleCollaboration(rootElement, ctx);
|
||||
|
||||
// force drawing of everything not yet drawn that is part of the target DI
|
||||
handleUnhandledProcesses(definitions.rootElements, ctx);
|
||||
} else {
|
||||
throw new Error(
|
||||
translate('unsupported bpmnElement for {plane}: {rootElement}', {
|
||||
plane: elementToString(plane),
|
||||
rootElement: elementToString(rootElement)
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
// handle all deferred elements
|
||||
handleDeferred(deferred);
|
||||
}
|
||||
|
||||
function handleDeferred() {
|
||||
|
||||
var fn;
|
||||
|
||||
// drain deferred until empty
|
||||
while (deferred.length) {
|
||||
fn = deferred.shift();
|
||||
|
||||
fn();
|
||||
}
|
||||
}
|
||||
|
||||
function handleProcess(process, context) {
|
||||
handleFlowElementsContainer(process, context);
|
||||
handleIoSpecification(process.ioSpecification, context);
|
||||
|
||||
handleArtifacts(process.artifacts, context);
|
||||
|
||||
// log process handled
|
||||
handled(process);
|
||||
}
|
||||
|
||||
function handleUnhandledProcesses(rootElements, ctx) {
|
||||
|
||||
// walk through all processes that have not yet been drawn and draw them
|
||||
// if they contain lanes with DI information.
|
||||
// we do this to pass the free-floating lane test cases in the MIWG test suite
|
||||
var processes = filter(rootElements, function(e) {
|
||||
return !isHandled(e) && is(e, 'bpmn:Process') && e.laneSets;
|
||||
});
|
||||
|
||||
processes.forEach(contextual(handleProcess, ctx));
|
||||
}
|
||||
|
||||
function handleMessageFlow(messageFlow, context) {
|
||||
visitIfDi(messageFlow, context);
|
||||
}
|
||||
|
||||
function handleMessageFlows(messageFlows, context) {
|
||||
forEach(messageFlows, contextual(handleMessageFlow, context));
|
||||
}
|
||||
|
||||
function handleDataAssociation(association, context) {
|
||||
visitIfDi(association, context);
|
||||
}
|
||||
|
||||
function handleDataInput(dataInput, context) {
|
||||
visitIfDi(dataInput, context);
|
||||
}
|
||||
|
||||
function handleDataOutput(dataOutput, context) {
|
||||
visitIfDi(dataOutput, context);
|
||||
}
|
||||
|
||||
function handleArtifact(artifact, context) {
|
||||
|
||||
// bpmn:TextAnnotation
|
||||
// bpmn:Group
|
||||
// bpmn:Association
|
||||
|
||||
visitIfDi(artifact, context);
|
||||
}
|
||||
|
||||
function handleArtifacts(artifacts, context) {
|
||||
|
||||
forEach(artifacts, function(e) {
|
||||
if (is(e, 'bpmn:Association')) {
|
||||
deferred.push(function() {
|
||||
handleArtifact(e, context);
|
||||
});
|
||||
} else {
|
||||
handleArtifact(e, context);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function handleIoSpecification(ioSpecification, context) {
|
||||
|
||||
if (!ioSpecification) {
|
||||
return;
|
||||
}
|
||||
|
||||
forEach(ioSpecification.dataInputs, contextual(handleDataInput, context));
|
||||
forEach(ioSpecification.dataOutputs, contextual(handleDataOutput, context));
|
||||
}
|
||||
|
||||
function handleSubProcess(subProcess, context) {
|
||||
handleFlowElementsContainer(subProcess, context);
|
||||
handleArtifacts(subProcess.artifacts, context);
|
||||
}
|
||||
|
||||
function handleFlowNode(flowNode, context) {
|
||||
var childCtx = visitIfDi(flowNode, context);
|
||||
|
||||
if (is(flowNode, 'bpmn:SubProcess')) {
|
||||
handleSubProcess(flowNode, childCtx || context);
|
||||
}
|
||||
|
||||
if (is(flowNode, 'bpmn:Activity')) {
|
||||
handleIoSpecification(flowNode.ioSpecification, context);
|
||||
}
|
||||
|
||||
// defer handling of associations
|
||||
// affected types:
|
||||
//
|
||||
// * bpmn:Activity
|
||||
// * bpmn:ThrowEvent
|
||||
// * bpmn:CatchEvent
|
||||
//
|
||||
deferred.push(function() {
|
||||
forEach(flowNode.dataInputAssociations, contextual(handleDataAssociation, context));
|
||||
forEach(flowNode.dataOutputAssociations, contextual(handleDataAssociation, context));
|
||||
});
|
||||
}
|
||||
|
||||
function handleSequenceFlow(sequenceFlow, context) {
|
||||
visitIfDi(sequenceFlow, context);
|
||||
}
|
||||
|
||||
function handleDataElement(dataObject, context) {
|
||||
visitIfDi(dataObject, context);
|
||||
}
|
||||
|
||||
function handleBoundaryEvent(dataObject, context) {
|
||||
visitIfDi(dataObject, context);
|
||||
}
|
||||
|
||||
function handleLane(lane, context) {
|
||||
|
||||
deferred.push(function() {
|
||||
|
||||
var newContext = visitIfDi(lane, context);
|
||||
|
||||
if (lane.childLaneSet) {
|
||||
handleLaneSet(lane.childLaneSet, newContext || context);
|
||||
}
|
||||
|
||||
wireFlowNodeRefs(lane);
|
||||
});
|
||||
}
|
||||
|
||||
function handleLaneSet(laneSet, context) {
|
||||
forEach(laneSet.lanes, contextual(handleLane, context));
|
||||
}
|
||||
|
||||
function handleLaneSets(laneSets, context) {
|
||||
forEach(laneSets, contextual(handleLaneSet, context));
|
||||
}
|
||||
|
||||
function handleFlowElementsContainer(container, context) {
|
||||
handleFlowElements(container.flowElements, context);
|
||||
|
||||
if (container.laneSets) {
|
||||
handleLaneSets(container.laneSets, context);
|
||||
}
|
||||
}
|
||||
|
||||
function handleFlowElements(flowElements, context) {
|
||||
forEach(flowElements, function(e) {
|
||||
if (is(e, 'bpmn:SequenceFlow')) {
|
||||
deferred.push(function() {
|
||||
handleSequenceFlow(e, context);
|
||||
});
|
||||
} else if (is(e, 'bpmn:BoundaryEvent')) {
|
||||
deferred.unshift(function() {
|
||||
handleBoundaryEvent(e, context);
|
||||
});
|
||||
} else if (is(e, 'bpmn:FlowNode')) {
|
||||
handleFlowNode(e, context);
|
||||
} else if (is(e, 'bpmn:DataObject')) {
|
||||
// SKIP (assume correct referencing via DataObjectReference)
|
||||
} else if (is(e, 'bpmn:DataStoreReference')) {
|
||||
handleDataElement(e, context);
|
||||
} else if (is(e, 'bpmn:DataObjectReference')) {
|
||||
handleDataElement(e, context);
|
||||
} else {
|
||||
logError(
|
||||
translate('unrecognized flowElement {element} in context {context}', {
|
||||
element: elementToString(e),
|
||||
context: (context ? elementToString(context.businessObject) : 'null')
|
||||
}),
|
||||
{ element: e, context: context }
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function handleParticipant(participant, context) {
|
||||
var newCtx = visitIfDi(participant, context);
|
||||
|
||||
var process = participant.processRef;
|
||||
if (process) {
|
||||
handleProcess(process, newCtx || context);
|
||||
}
|
||||
}
|
||||
|
||||
function handleCollaboration(collaboration) {
|
||||
|
||||
forEach(collaboration.participants, contextual(handleParticipant));
|
||||
|
||||
handleArtifacts(collaboration.artifacts);
|
||||
|
||||
// handle message flows latest in the process
|
||||
deferred.push(function() {
|
||||
handleMessageFlows(collaboration.messageFlows);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function wireFlowNodeRefs(lane) {
|
||||
// wire the virtual flowNodeRefs <-> relationship
|
||||
forEach(lane.flowNodeRef, function(flowNode) {
|
||||
var lanes = flowNode.get('lanes');
|
||||
|
||||
if (lanes) {
|
||||
lanes.push(lane);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// API //////////////////////
|
||||
|
||||
return {
|
||||
handleDeferred: handleDeferred,
|
||||
handleDefinitions: handleDefinitions,
|
||||
handleSubProcess: handleSubProcess,
|
||||
registerDi: registerDi
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
import BpmnTreeWalker from './BpmnTreeWalker';
|
||||
|
||||
import {
|
||||
isFunction
|
||||
} from 'min-dash';
|
||||
|
||||
/**
|
||||
* Import the definitions into a diagram.
|
||||
*
|
||||
* Errors and warnings are reported through the specified callback.
|
||||
*
|
||||
* @param {djs.Diagram} diagram
|
||||
* @param {ModdleElement<Definitions>} definitions
|
||||
* @param {ModdleElement<BPMNDiagram>} [bpmnDiagram] the diagram to be rendered
|
||||
* (if not provided, the first one will be rendered)
|
||||
* @param {Function} done the callback, invoked with (err, [ warning ]) once the import is done
|
||||
*/
|
||||
export function importBpmnDiagram(diagram, definitions, bpmnDiagram, done) {
|
||||
|
||||
if (isFunction(bpmnDiagram)) {
|
||||
done = bpmnDiagram;
|
||||
bpmnDiagram = null;
|
||||
}
|
||||
|
||||
var importer,
|
||||
eventBus,
|
||||
translate;
|
||||
|
||||
var error,
|
||||
warnings = [];
|
||||
|
||||
/**
|
||||
* Walk the diagram semantically, importing (=drawing)
|
||||
* all elements you encounter.
|
||||
*
|
||||
* @param {ModdleElement<Definitions>} definitions
|
||||
* @param {ModdleElement<BPMNDiagram>} bpmnDiagram
|
||||
*/
|
||||
function render(definitions, bpmnDiagram) {
|
||||
|
||||
var visitor = {
|
||||
|
||||
root: function(element) {
|
||||
return importer.add(element);
|
||||
},
|
||||
|
||||
element: function(element, parentShape) {
|
||||
return importer.add(element, parentShape);
|
||||
},
|
||||
|
||||
error: function(message, context) {
|
||||
warnings.push({ message: message, context: context });
|
||||
}
|
||||
};
|
||||
|
||||
var walker = new BpmnTreeWalker(visitor, translate);
|
||||
|
||||
// traverse BPMN 2.0 document model,
|
||||
// starting at definitions
|
||||
walker.handleDefinitions(definitions, bpmnDiagram);
|
||||
}
|
||||
|
||||
try {
|
||||
importer = diagram.get('bpmnImporter');
|
||||
eventBus = diagram.get('eventBus');
|
||||
translate = diagram.get('translate');
|
||||
|
||||
eventBus.fire('import.render.start', { definitions: definitions });
|
||||
|
||||
render(definitions, bpmnDiagram);
|
||||
|
||||
eventBus.fire('import.render.complete', {
|
||||
error: error,
|
||||
warnings: warnings
|
||||
});
|
||||
} catch (e) {
|
||||
error = e;
|
||||
}
|
||||
|
||||
done(error, warnings);
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
export function elementToString(e) {
|
||||
if (!e) {
|
||||
return '<null>';
|
||||
}
|
||||
|
||||
return '<' + e.$type + (e.id ? ' id="' + e.id : '') + '" />';
|
||||
}
|
||||
10
ebpm-process-modeler/public/js/bpmn-js/lib/import/index.js
Normal file
10
ebpm-process-modeler/public/js/bpmn-js/lib/import/index.js
Normal file
@@ -0,0 +1,10 @@
|
||||
import translate from 'diagram-js/lib/i18n/translate';
|
||||
|
||||
import BpmnImporter from './BpmnImporter';
|
||||
|
||||
export default {
|
||||
__depends__: [
|
||||
translate
|
||||
],
|
||||
bpmnImporter: [ 'type', BpmnImporter ]
|
||||
};
|
||||
Reference in New Issue
Block a user