第14章 Seam 和 JBoss 规则
Seam使从Seam组件或jBPM处理定义调用JBoss规则(Drools) 规则库变得容易。
14.1. 安装规则
第一步,是用一个Seam上下文变量产生一个可用的org.drools.RuleBase实例。为测试的目的,Seam提供了一个内建的组件,编译来自类路径的一个静态规则集。你可能安装这个组件,通过components.xml:
<drools:rule-base name="policyPricingRules">
<drools:rule-files>
<value>policyPricingRules.drl</value>
</drools:rule-files>
</drools:rule-base>
组件从一组.drl文件编译规则,并且缓存一个org.drools.RuleBase实例在Seam APPLICATION上下文中。注意,它与你需要安装的基于规则驱动的应用程序的多重规则十分相似。
如果你想使用一个Drools DSL(Domain Specific Language),你还需要指定DSL定义:
<drools:rule-base name="policyPricingRules" dsl-file="policyPricing.dsl">
<drools:rule-files>
<value>policyPricingRules.drl</value>
</drools:rule-files>
</drools:rule-base>
在大部分规则驱动的应用程序,规则需要动态地部署,因此,一个产品应用程序需要使用一个Drools规则代理管理规则库。规则代理能从一个本地文件仓库连接到一个Drools规则服务器(BRMS)或者热部署规则包。受管理规则代理的规则库在components.xml中也是可配置:
<drools:rule-agent name="insuranceRules"
configurationFile="/WEB-INF/deployedrules.properties" />
属性文件包含规则代理的属性细节。这里是一个配置文件例子,来自发布的Drools例子:
newInstance=true
url=http://localhost:8080/drools-jbrms/org.drools.brms.JBRMS/package/org.acme.insurance/
fmeyer
localCacheDir=/Users/fernandomeyer/projects/jbossrules/drools-examples/drools-examples-
brms/cache
poll=30
name=insuranceconfig
绕过配置文件,直接配置依附于组件的选项也是可能的。
<drools:rule-agent name="insuranceRules"
url="http://localhost:8080/drools-jbrms/org.drools.brms.JBRMS/package/org.acme.insurance/
fmeyer"
local-cache-dir="/Users/fernandomeyer/projects/jbossrules/drools-examples/drools-
examples-brms/cache"
poll="30"
configuration-name="insuranceconfig" />
下一步,我们需要为每个对话产生一个可用的org.drools.WorkingMemory实例。(每个WorkingMemory‘工作存储器’收集涉及当前对话的facts)
<drools:managed-working-memory name="policyPricingWorkingMemory" auto-create="true"
rule-base="#{policyPricingRules}"/>
注意,我们通过 ruleBase 配置属性给policyPricingWorkingMemory 一个返回到我们的规则库的引用。
14.2. 从一个Seam组件使用规则
现在我们能注入我们的WorkingMemory进入任何Seam组件,声称facts,并触发规则:
@In WorkingMemory policyPricingWorkingMemory;
@In Policy policy;
@In Customer customer;
public void pricePolicy() throws FactException
{
policyPricingWorkingMemory.assertObject(policy);
policyPricingWorkingMemory.assertObject(customer);
policyPricingWorkingMemory.fireAllRules();
}
14.3.从一个 jBPM 处理定义使用规则
你甚至能允许一个规则库担当一个jBPM动作处理器、决定处理器或分配处理器——在一个页面流或商业处理定义中。
<decision name="approval">
<handler class="org.jboss.seam.drools.DroolsDecisionHandler">
<workingMemoryName>orderApprovalRulesWorkingMemory</workingMemoryName>
<assertObjects>
<element>#{customer}</element>
<element>#{order}</element>
<element>#{order.lineItems}</element>
</assertObjects>
</handler>
<transition name="approved" to="ship">
<action class="org.jboss.seam.drools.DroolsActionHandler">
<workingMemoryName>shippingRulesWorkingMemory</workingMemoryName>
<assertObjects>
<element>#{customer}</element>
<element>#{order}</element>
<element>#{order.lineItems}</element>
</assertObjects>
</action>
</transition>
<transition name="rejected" to="cancelled"/>
</decision>
<assertObjects>元素指定EL表达式,其返回一个被声明为facts进入到WorkingMemory之内的对象或者对象集。
还支持对jBPM 任务分配使用Drools:
<task-node name="review">
<task name="review" description="Review Order">
<assignment handler="org.jboss.seam.drools.DroolsAssignmentHandler">
<workingMemoryName>orderApprovalRulesWorkingMemory</workingMemoryName>
<assertObjects>
<element>#{actor}</element>
<element>#{customer}</element>
<element>#{order}</element>
<element>#{order.lineItems}</element>
</assertObjects>
</assignment>
</task>
<transition name="rejected" to="cancelled"/>
<transition name="approved" to="approved"/>
</task-node>
某些对象作为Drools globals提供给规则使用,即,jBPM Assignable 作为assignable和Seam Decision对象作为decision。处理决定的规则将要调用decision.setOutcome("result")来确定决定的结果。处理分配的规则将要使用Assignable设置参与者的id。
package org.jboss.seam.examples.shop
import org.jboss.seam.drools.Decision
global Decision decision
rule "Approve Order For Loyal Customer"
when
Customer( loyaltyStatus == "GOLD" )
Order( totalAmount <= 10000 )
then
decision.setOutcome("approved");
end
package org.jboss.seam.examples.shop
import org.jbpm.taskmgmt.exe.Assignable
global Assignable assignable
rule "Assign Review For Small Order"
when
Order( totalAmount <= 100 )
then
assignable.setPooledActors( new String[] {"reviewers"} );
end
注意:在http://www.drools.org能找到更多内容
警告: Seam 配备了足够的Drools从属物来实现一些简单的规则。如果你想对Drools增加额外的能力 ,你应该下载完整的分发版并增加需要的额外的从属物。
技巧:Drools专为Java 1.4配备了MVEL 编译器,它兼容Java 1.4、Java 5 和Java 6。您可以用一个你正使用的java版本的编译器改变你的MVEL jar 。