import { ELType, GroupType } from "./ELType"; export default class ELNode { id: string; type: ELType; groupType: GroupType; aliasId: string; name: string; data: string; tag: string; nodeId: string; child: ELNode[]; comingEdgeText: string; //指向该节点边的标签 elString: string | undefined; properties: Record | undefined //group专用 startNode: ELNode; breakNode: ELNode; exceptionNode: ELNode; startNum: number; //固定值 maxLineNum: number constructor(id: string = "") { if (id) this.id = id this.child = [] this.maxLineNum = 25 } public addChild(elNode: ELNode) { if (!this.child) this.child = [] this.child.push(elNode); } private assert(condition: boolean, msg: string = "") { if (!condition) throw new Error(msg); } //获取节点对应的EL表达式 //在raw的基础上添加tag和data数据 public getElString() { const tagStr = this.properties?.tag ? `.tag('${this.properties?.tag}')` : '' const dataStr = this.properties?.data ? `.data('${this.properties?.data}')` : '' return `${this.getElStringRaw()}${tagStr}${dataStr}` } //获取节点对应的EL表达式 public getElStringRaw() { if (this.type === ELType.ID) return this.nodeId; if (this.elString) return this.elString; const type = this.type; switch (type) { case ELType.IF: return this.getELString_IF() case ELType.GROUP: return this.getELString_Group() case ELType.SWITCH: return this.getELString_SWITCH() case ELType.WHEN: case ELType.THEN: return this.getElString_WHEN_THEN() } } // 给每一行插入空格,用于数据的格式化 private insertSpace(s: string): string { const res = s.split("\n").join("\n ") return ` ${res}` } //各种节点获取ELstring方法 //THEN和WHEN放到一起 private getElString_WHEN_THEN() { const children = this.child || []; // 这里的id只能是switch链中的 let idStr = '' if (this.aliasId) { idStr = this.aliasId.startsWith('tag:') ? `.tag("${this.aliasId.substring(4)}")` : `.id("${this.aliasId}")` } //加上空格回车进行格式化 const childrenELStrings = children.map(item => item.getElString()) const joins = childrenELStrings.join(","); //只有一个节点,不需要THEN或者WHEN标识,直接返回 if (children.length === 1) { if (!idStr || children[0].type === ELType.THEN || children[0].type === ELType.WHEN) { //这些情况可以直接解包,去掉多余的THEN和WHEN return `${joins}${idStr}`; } } //长度比较小,不需要进行格式化,直接单行输出 if (joins.length < this.maxLineNum - 6) return `${this.type}(${joins})${idStr}` const fomatterJoins = this.insertSpace(childrenELStrings.join(",\n")) return `${this.type}(\n${fomatterJoins}\n)${idStr}` } //对分组节点进行解析 private getELString_Group() { const children = this.child || []; //加上空格回车进行格式化 const childrenELStrings = children.map(item => item.getElString()) const joins = childrenELStrings.join(","); // 配置节点解析 if (this.groupType === GroupType.CONFIG) { const ignoreStr = this.properties?.ignoreError ? `.ignoreError(true)` : ``; const anyStr = this.properties?.any ? `any(true)` : ``; const mustStr = this.properties?.must ? `must(${this.properties?.must})` : ``; return `${joins}${ignoreStr}${anyStr}${mustStr}` } //与或非表达式解析 if (this.groupType === GroupType.LOGIC) { return this.elString; } const name = this.groupType; // 捕获异常表达式解析 if (this.groupType === GroupType.CATCH) { const exceptionStr = this.exceptionNode.getElString(); return `${name}(${joins}).DO(${exceptionStr})` } // 循环节点解析 const breakStr = !!this.breakNode ? `.BREAK(${this.breakNode.getElString()})` : "" const startStr = (this.startNode?.nodeId) ? this.startNode.getElString() : this.startNum; if (children.length === 1) return `${name}(${startStr}).DO(${joins})${breakStr}`; else return `${name}(${startStr}).DO(WHEN(${joins}))${breakStr}`; } private getELString_IF() { const children = this.child || []; //加上空格回车进行格式化 const childrenELStrings = children.map(item => item.getElString()) const joins = childrenELStrings.join(","); //长度比较小,不需要进行格式化,直接单行输出 if (joins.length < this.maxLineNum - 4) return `IF(${joins})` const fomatterJoins = this.insertSpace(childrenELStrings.join(",\n")) return `IF(\n${fomatterJoins}\n)`; } private getELString_SWITCH() { const children = this.child || []; //加上空格回车进行格式化 const childrenELStrings = children.map(item => item.getElString()) const joins = childrenELStrings.join(","); if (joins.length < this.maxLineNum - 13 - this.nodeId.length) return `SWITCH(${this.nodeId}).to(${joins})`; const fomatterJoins = this.insertSpace(childrenELStrings.join(",\n")) return `SWITCH(${this.nodeId}).to(\n${fomatterJoins}\n)`; } }