二、工作流中的函数
OSWorkflow支持下面的函数:
1. Java-based Functions(基于Java的函数)
基于Java的函数必须要实现com.opensymphony.workflow.FunctionProvider接口。这个接口只有一个函数——execute,这个函数有三个参数
--transientVars Map
transientVars Map:是客户端代码调用Workflow.doAction()时传进来的。这个参数可以基于用户的不同的输入使函数有不同的行为。
这个参数也包含了一些特别变量,这些变量对于访问workflow的信息是很有帮助的。它也包含了所有的在Registers中配置的变量和下面两种特别的变量:entry (com.opensymphony.workflow.spi.WorkflowEntry) and context (com.opensymphony.workflow.WorkflowContext)。
--The args Map
args Map是一个包含在所有的<function/>标签中的<arg/>标签的Map。这些参数都是String类型的。这意味着<arg name="foo">this is ${someVar}</arg> 标签中定义的参数将在arg Map中通过"foo",可以映射到"this is [contents of someVar]"字串。
--propertySet
propertySet包含所有的在workflow实例中持久化的变量。
Java-based的函数适用于以下类型:
(1) class
对于一个类的函数,类加载器一定得知道你的函数所属的类的名字。这可以通过class.name参数来完成:
<function type="class">
<arg name="class.name">com.acme.FooFunction</arg>
<arg name="message">The message is ${message}</arg>
</function>
(2) jndi
JNDI函数就象类函数一样,唯一的不同是JNDI函数的对象一定是已经在JNDI树中存在了,这里需要jndi.location参数:
<function type="jndi">
<arg name="jndi.location">java:/FooFunction</arg>
<arg name="message">The message is ${message}</arg>
</function>
(3) remote-ejb
远程EJBs可以在OSWorkflow中作为一个函数使用。EJB的远程接口一定要扩展com.opensymphony.workflow.FunctionProviderRemote,这里需要ejb.location参数:
<function type="remote-ejb">
<arg name="ejb.location">java:/comp/env/FooEJB</arg>
<arg name="message">The message is ${message}</arg>
</function>
(4) local-ejb
本地EJBs与远程EJBs的不同在于,本地EJBs要扩展com.opensymphony.workflow.FunctionProvider接口,例如:
<function type="local-ejb">
<arg name="ejb.location">java:/comp/env/FooEJB</arg>
<arg name="message">The message is ${message}</arg>
</function>
2. BeanShell Functions
OSWorkflow支持BeanShell作为一个scripting语言。到http://www.beanshell.org/上,你可以获得更多的BeanShell的信息。
BeanShell函数的类型一定要指定为beanshell,还需要一个参数,名字叫script。这个参数的值实际上就是要执行的script,例如:
<function type="beanshell">
<arg name="script">
System.out.println("Hello, World!");
</arg>
</function>
在表达式中始终存在三个变量,entry、context和store。entry变量是一个实现了com.opensymphony.workflow.spi.WorkflowEntry接口的对象,它代表workflow实例。context变量是com.opensymphony.workflow.WorkflowContext类型的对象,它允许BeanShell函数回滚事务或决定调用者的名字。store变量是com.opensymphony.workflow.WorkflowStore类型的对象,它允许函数访问workflow的持久化存储区。
和上面Java-based函数一样,也要使用三个变量transientVars, args和propertySet,例如:
<function type="beanshell">
<arg name="script">
propertySet.setString("world", "Earth");
</arg>
</function>
<function type="beanshell">
<arg name="script">
System.out.println("Hello,"+propertySet.getString("world"));
</arg>
</function>
这两个scripts的输出是"Hello,Earth"。这是因为任何存储在propertySet中的变量都会被持久化,以便在后面的该workflow中的函数使用。
3. BSF Functions (perlscript, vbscript, javascript)
OSWorkflow还支持一种Bean Scripting Framework的函数。BSF是IBM AlphaWorks小组的项目,它允许通用的Script语言,如VBScript, Perlscript, Python, and JavaScript在通用的环境中运行。这意味着,在OSWorkflow中你可以使用BSF支持的任何一种语言来编写你的函数:
<function type="bsf">
<arg name="source">foo.pl</arg>
<arg name="row">0</arg>
<arg name="col">0</arg>
<arg name="script">
print $bsf->lookupBean("propertySet").getString("foo");
</arg>
</function>
上面的代码将获得propertySet,然后打印出key为foo的对象的值。在BeanShell函数中的缺省范围的相同的变量,可以在你的BSF script代码中获得。关于如何在你所选择的语言中获取变量,请阅读BSF用户手册。
4. Utility Functions
OSWorkflow本身附带一些很实用的工具函数,这些函数都实现了com.opensymphony.workflow.FunctionProvider接口。要获取更详细的信息,请阅读这些工具函数的javadoc文档。下面是每个函数的简单描述,你在com.opensymphony.workflow.util包中可以找到所有的类。
(1) Caller
用当前动作的执行者名字设置持久化变量caller。
(2) WebWorkExecutor
执行一个WebWork函数并且在动作结束时存储旧的ActionContext。
(3) EJBInvoker
调用一个EJB的session bean方法。
(4) JMSMessage
发送一个TextMessage给一个JMStopic 或 queue。
(5) MostRecentOwner
用最近指定的步骤的所有者的名字来设置持久化变量mostRecentOwner。可选特性可以在有所有者时将变量设置为nothing,或者返回一个内部错误。
(6) ScheduleJob
可以调度一个Trigger函数在某时执行。同时支持cron表达式和简单的repeat/delay counts。
(7) UnschduleJob
删除一个ScheduleJob和所有与之联系的triggers函数。在workflow的状态发生变化而且你不再希望ScheduleJob再执行的时候是很有用的。
(8) SendEmail
给一个或多个用户发送邮件。