devexpress-diagram
Version:
DevExpress Diagram Control
148 lines (137 loc) • 5.32 kB
text/typescript
import { Graph } from "../Layout/Graph";
import { ShapeTypes } from "../Model/Shapes/ShapeTypes";
import { ItemKey } from "../Model/DiagramItem";
import { Edge } from "../Layout/Structures";
import { IImportNodeItem, IImportEdgeItem } from "../Data/Interfaces";
import { ImportUtils } from "./ImportUtils";
export class BPMNImporter {
protected doc: Document;
protected graph: Graph<BPMNNode>;
protected dataSourceKey: ItemKey;
constructor(xml: string) {
this.doc = ImportUtils.createDocument(xml);
this.graph = new Graph<BPMNNode>([], []);
}
import(): Graph<BPMNNode> {
for(let child: Element, i = 0; child = this.doc.children[i]; i++)
if(child.nodeName.toUpperCase() === "DEFINITIONS")
this.onDefinitionsElement(child);
this.validate();
return this.graph;
}
private validate() {
const nodesMap = {};
this.graph.nodes.forEach(n => nodesMap[n] = true);
for(let i = 0, edge: Edge; edge = this.graph.edges[i]; i++)
if(!nodesMap[edge.from] || !nodesMap[edge.to]) {
this.graph.edges.splice(i, 1);
i--;
}
}
private onDefinitionsElement(element: Element) {
this.dataSourceKey = element.getAttribute("id");
for(let child: Element, i = 0; child = element.children[i]; i++)
if(child.nodeName.toUpperCase() === "PROCESS")
this.onProcessElement(child);
}
private onProcessElement(element: Element) {
for(let child: Element, i = 0; child = element.children[i]; i++)
switch(child.nodeName.toUpperCase()) {
case "STARTEVENT":
this.onStartEventElement(child);
break;
case "SEQUENCEFLOW":
this.onSequenceFlowElement(child);
break;
case "SCRIPTTASK":
this.onScriptTaskElement(child);
break;
case "USERTASK":
this.onUserTaskElement(child);
break;
case "SERVICETASK":
this.onServiceTaskElement(child);
break;
case "SENDTASK":
this.onSendTaskElement(child);
break;
case "EXCLUSIVEGATEWAY":
this.onExclusiveGateway(child);
break;
case "ENDEVENT":
this.onEndEventGateway(child);
break;
}
}
private onStartEventElement(element: Element) {
const node = this.createNode(element);
node.type = ShapeTypes.Ellipse;
node.text = element.getAttribute("name");
this.graph.addNode(node);
}
private onSequenceFlowElement(element: Element) {
const fromKey = element.getAttribute("sourceRef");
const toKey = element.getAttribute("targetRef");
const edge = this.createEdge(element, fromKey, toKey);
if(element.hasAttribute("name"))
edge.text = element.getAttribute("name");
this.graph.addEdge(edge);
}
private onScriptTaskElement(element: Element) {
const node = this.createNode(element);
node.text = element.getAttribute("name");
this.graph.addNode(node);
}
private onUserTaskElement(element: Element) {
const node = this.createNode(element);
node.text = element.getAttribute("name");
this.graph.addNode(node);
}
private onServiceTaskElement(element: Element) {
const node = this.createNode(element);
node.text = element.getAttribute("name");
this.graph.addNode(node);
}
private onSendTaskElement(element: Element) {
const node = this.createNode(element);
node.text = element.getAttribute("name");
this.graph.addNode(node);
}
private onExclusiveGateway(element: Element) {
const node = this.createNode(element);
node.text = element.getAttribute("name");
node.type = ShapeTypes.Decision;
this.graph.addNode(node);
}
private onEndEventGateway(element: Element) {
const node = this.createNode(element);
node.text = element.getAttribute("name");
node.type = ShapeTypes.Ellipse;
this.graph.addNode(node);
}
private createNode(element: Element) {
return new BPMNNode(this.dataSourceKey, element.getAttribute("id"));
}
private createEdge(element: Element, fromKey: ItemKey, toKey: ItemKey): BPMNEdge {
return new BPMNEdge(this.dataSourceKey, element.getAttribute("id"), fromKey, toKey);
}
}
export class BPMNNode implements IImportNodeItem {
type: string = ShapeTypes.Rectangle;
text: string;
constructor(
public sourceKey: ItemKey,
public key: ItemKey
) { }
}
class BPMNEdge extends Edge implements IImportEdgeItem {
text: string;
constructor(
public sourceKey: ItemKey,
key: ItemKey,
fromKey: ItemKey,
toKey: ItemKey
) {
super(key, fromKey, toKey);
}
}