OGNL简介
分支节点条件支持Ognl语法,必须是返回值为布尔值的表达式,具体可以参考Ognl的语法官方指引;
一、模型介绍:
WorkflowTemplate实体,表示一个工单模版;
WorkflowInstance实体,表示一个工单实例;
WorkNode:工单模版中的节点;
WorkTransition:有prevNodeId和nextNodeId字段,表示两个模版节点之间的流转关系,有一个字段:conditions,如果非null,表示这是一个分支流转,并且conditions是一个ognl表达式,要求表达式返回true|false.
二、流程实例中的参数
(1)表达式中,可以直接调用com.cloudbility.workflow.WorkflowFunction中定义的方法,比如:max,maxOf,sort,equals等。
(2)表达式中,可以通过'#'引用当前流程meta中的变量。
不同类型流程实例会有不同的meta类型。下面举例说明,文件传输审核流程:
- 文件上传审核meta参数:
{ "action":"WebUpload", "hostId":5, "hostPlatform":"windows", "hostInnerIp":"192.168.5.64", "hostInstanceName":"192.168.5.64", "targetDir":"host_disk://9/", "fileReady":true, "fileItems":[ { "fileName":"激活码.txt", "fileSize":3669, "relativePath":"激活码.txt", "tempUrl":"host_disk_hidden://5/FileTransferAudit/107/激活码.txt" }, { "fileName":"阿里云插件-memo.txt", "fileSize":300, "relativePath":"阿里云插件-memo.txt", "tempUrl":"host_disk_hidden://5/FileTransferAudit/107/阿里云插件-memo.txt" } ], "paths":[ "激活码.txt", "阿里云插件-memo.txt" ], "prepareJobId":-1, "targetDirDescription":"主机网盘:/" }
- 文件下载审核meta参数:
{ "action":"WebDownload", "hostId":5, "hostPlatform":"windows", "hostInnerIp":"192.168.5.64", "hostInstanceName":"192.168.5.64", "srcUrl":"host_disk://9/NOTICE.harmony.txt", "locationUrl":"host_disk_hidden://5/FileTransferAudit/108/", "prepareJobId":568, "fileReady":true, "fileItems":[ { "fileName":"NOTICE.harmony.txt", "fileSize":171, "relativePath":"NOTICE.harmony.txt", "tempUrl":"host_disk_hidden://5/FileTransferAudit/108/NOTICE.harmony.txt" } ], "paths":[ "NOTICE.harmony.txt" ], "srcDescription":"主机网盘:/NOTICE.harmony.txt" }
条件:包含txt文件需要进入当前分支审核。对应的ognl表达式可以这么写:
#paths.{? #this.endsWith('.txt')}.size()>0
后面详细介绍ognl的语法结构。
三、Ognl的语法简介
分支节点条件支持Ognl语法,必须是返回值为布尔值的表达式,具体可以参考Ognl的语法官方指引,以下是一些简单的语法介绍;
3.1、映射数组
语法结构:objects.{delegate} ,在delegate子表达式中,可以使用#this表示当前的元素。
比如,假设contenxt是:
{ "action":"WebUpload", "hostId":5, "hostPlatform":"windows", "hostInnerIp":"192.168.5.64", "hostInstanceName":"192.168.5.64", "targetDir":"host_disk://9/", "fileReady":true, "fileItems":[ { "fileName":"激活码.txt", "fileSize":3669, "relativePath":"激活码.txt", "tempUrl":"host_disk_hidden://5/FileTransferAudit/107/激活码.txt" }, { "fileName":"阿里云插件-memo.txt", "fileSize":300, "relativePath":"阿里云插件-memo.txt", "tempUrl":"host_disk_hidden://5/FileTransferAudit/107/阿里云插件-memo.txt" } ], "paths":[ "激活码.txt", "阿里云插件-memo.txt" ], "prepareJobId":-1, "targetDirDescription":"主机网盘:/" }
那么表达式"#fileItems.{#this.fileName}"
会返回 java.util.ArrayList:[激活码.txt, 阿里云插件-memo.txt]
而"#fileItems.{#this.fileSize}"
会返回 java.util.ArrayList:[3669, 300]
上面的例子,{delegate}是取元素的一个属性。如果想把一个数组按照条件过滤(即满足条件的元素一起组成一个新的数组),那么delegate需要写一个布尔表达式,如下:
"#fileItems.{?#this.fileName.endsWith('.txt')}"
会返回 [{ "fileName": "激活码.txt", "fileSize": 3669, "relativePath": "激活码.txt", "tempUrl": "host_disk_hidden://5/FileTransferAudit/107/激活码.txt" }]
布尔表达式以?开头,后面跟一个子表达式。
objects.{^ expression} 和 objects.{$ expression}分别是过滤数组中的第一个和最后一个满足expression条件的元素,当然,返回的依旧是数组(包含选中的元素)
比如 :
-
"#fileItems.{^ #this.fileName.length()>5}"
返回 [{ "fileName": "激活码.txt", "fileSize": 3669, "relativePath": "激活码.txt", "tempUrl": "host_disk_hidden://5/FileTransferAudit/107/激活码.txt" }] -
"#fileItems.{$ #this.fileName.length()>5}"
返回 [{ "fileName": "阿里云插件-memo.txt", "fileSize": 300, "relativePath": "阿里云插件-memo.txt", "tempUrl": "host_disk_hidden://5/FileTransferAudit/107/阿里云插件-memo.txt" }]
映射数组以后,还是数组,所以可以继续对后续数据进行处理,也可以直接用[i]进行元素引用(用[i]引用的时候要保证数组不能为空,否则会出现越界异常),比如:
-
"#fileItems.{#this.fileSize}[1]"
返回java.lang.Long:300 -
"sumOf(#fileItems.{#this.fileSize})"
返回所有文件大小之和,即java.lang.Double:3969.0 ,这里sumOf是定义在WorkflowFunction中的函数,返回值是java.lang.Double类型。 -
"maxOf(#fileItems.{#this.fileSize})"
返回所有文件大小最大值,即java.lang.Long:3669 ,这里maxOf是定义在WorkflowFunction中的函数。
四、其他操作符
(1) Sequence operator :序列操作符:
e1,e2
e1和e2,都会被执行,表达式返回e2的返回值。
(2) 赋值操作:
e1=e2
会调用e2的getValue,调用e1的setValue(e2的返回值)
(3)条件运算:
e1?e2:e3
(4)逻辑运算:
e1&& e2
e1 and e2
(5)相等判定 == ,调用equals
(6)元素e1 是否在数组e2中;
e1 in e2
(7) e1 not in e2
(8) 方法调用:
e.method(args),e.property
五、文件传输审批-ongl条件示例
(1)文件个数超过10个
"#fileItems.size()>10"
(2)文件总大小超过10M
"sumOf(#fileItems.{#this.fileSize})>10*1024*1024"
(3)文件列表中最大文件大小超过1M
"maxOf(#fileItems.{#this.fileSize})>1024*1024"
(4)文件列表中包含.txt结尾的文件
"#fileItems.{? #this.fileName.endsWith('.txt')}.size()>0"
(5)文件列表中,包含.txt或者.pdf文件
"#fileItems.{? fName=#this.fileName,fName.endsWith('.txt') || fName.endsWith('.pdf1')}.size()>0"
或者用以下方式,其中,filterInFormats是定义在WorkflowFunction中的函数,这个函数可以处理大小写,比如fileName='abc.Txt’也能被检测到:
"filterInFormats(#fileItems.{#this.fileName},{'.txt','.pdf'}).size()>0"
(6)文件列表中,包含.txt文件
"filterInFormat(#fileItems.{#this.fileName},'.txt').size()>0"
(7)文件列表中,全部是.txt文件
"filterInFormat(#fileItems.{#this.fileName},'.txt').size()==#fileItems.size()"
(8)文件列表中,全部是txt 或者pdf文件
"filterInFormats(#fileItems.{#this.fileName},{'.txt','.pdf'}).size()==#fileItems.size()"