drools.getRule().getName() 在属性 -rule 流水文件中
Posted
技术标签:
【中文标题】drools.getRule().getName() 在属性 -rule 流水文件中【英文标题】:drools.getRule().getName() in attributes -rule drool file 【发布时间】:2015-03-25 18:33:47 【问题描述】:我需要根据来自后端的数据启用/禁用 drl 文件中的某些规则。 即为迪拜启用规则 1,2,3,为新加坡启用 1,3 所以,我通过 drools.getRule().getName() 如下。
rule "Apply 50% discount to VIP customers"
enabled (checkenabled(drools.getRule().getName()))
when
$s : Sale( customer.type == CustomerType.VIP )
then
$s.setDiscount(0.50);
System.out.println("VIP discount applied1" + drools.getRule().getName());
end
我在这方面遇到了错误。
Exception in thread "main" [Error: null pointer: drools.rule.name]
[Near : ... checkenabled(drools.rule.name) ....]
^
[Line: 1, Column: 14]
at org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.compileGetChain(ReflectiveAccessorOptimizer.java:427)
at org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.optimizeAccessor(ReflectiveAccessorOptimizer.java:140)
at org.mvel2.ast.ASTNode.optimize(ASTNode.java:159)
at org.mvel2.ast.ASTNode.getReducedValueAccelerated(ASTNode.java:115)
at org.mvel2.compiler.ExecutableAccessor.getValue(ExecutableAccessor.java:38)
at org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.getMethod(ReflectiveAccessorOptimizer.java:948)
at org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.compileGetChain(ReflectiveAccessorOptimizer.java:373)
at org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.optimizeAccessor(ReflectiveAccessorOptimizer.java:140)
at org.mvel2.ast.ASTNode.optimize(ASTNode.java:159)
at org.mvel2.ast.ASTNode.getReducedValueAccelerated(ASTNode.java:115)
at org.mvel2.MVELRuntime.execute(MVELRuntime.java:86)
at org.mvel2.compiler.CompiledExpression.getDirectValue(CompiledExpression.java:123)
at org.mvel2.compiler.CompiledExpression.getValue(CompiledExpression.java:119)
at org.mvel2.compiler.CompiledExpression.getValue(CompiledExpression.java:113)
at org.mvel2.MVEL.executeExpression(MVEL.java:930)
at org.drools.core.base.mvel.MVELEnabledExpression.getValue(MVELEnabledExpression.java:92)
at org.drools.core.definitions.rule.impl.RuleImpl.isEffective(RuleImpl.java:384)
at org.drools.core.phreak.RuleExecutor.cancelAndContinue(RuleExecutor.java:326)
at org.drools.core.phreak.RuleExecutor.fire(RuleExecutor.java:142)
at org.drools.core.phreak.RuleExecutor.evaluateNetworkAndFire(RuleExecutor.java:94)
at org.drools.core.common.DefaultAgenda.fireNextItem(DefaultAgenda.java:964)
at org.drools.core.common.DefaultAgenda.fireAllRules(DefaultAgenda.java:1234)
at org.drools.core.impl.StatefulKnowledgeSessionImpl.fireAllRules(StatefulKnowledgeSessionImpl.java:1239)
at org.drools.core.impl.StatefulKnowledgeSessionImpl.fireAllRules(StatefulKnowledgeSessionImpl.java:1212)
at com.emirates.App.testGoodCustomer(App.java:95)
at com.emirates.App.main(App.java:74)
Caused by: java.lang.NullPointerException
at org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.compileGetChain(ReflectiveAccessorOptimizer.java:393)
... 25 more
【问题讨论】:
请格式化您的代码。 根据规则名称创建应用程序逻辑非常脆弱。你真的应该在你的规则中建立这样的逻辑。这就是他们的目的!因此,我怀疑对这个特定问题的任何回答都不太可能是解决实际问题的好方法。 请注意那些似乎投票结束这个问题的人“不清楚你在问什么”。对于熟悉 Drools 的人来说,OP 在问什么是完全清楚的。 我可以将 drools.getName().getRule() 作为参数传递给 java 方法处理启用属性,如上面的代码所示。如果是,请帮忙。我被卡住的数据。 【参考方案1】:你为什么不使用 AgendaFilter ?
很容易使用,可以在Java部分这样完成:
AgendaFilter myFilter = new RuleNameStartsWithAgendaFilter("DUBAI");
mySession.fireAllRules(filter);
myFilter = new RuleNameStartsWithAgendaFilter("SINGAPORE");
mySession.fireAllRules(filter);
AgendaFilter 有多种变体:
开始于 结束 包含 匹配项我不是你所需要的,但它可能是一个提示 ;-)
【讨论】:
嘿 Etenyl,感谢您的解决方案。它接近我的要求的 70%。我需要将 rule -name 从 enabled(checkenabled(drools.getRule().getName()) 传递给 java 文件。Checkenabled 是 java 函数,它根据作为参数传递给它的规则名启用/禁用规则。但是在传递 drools .getRule().getName() 作为参数,它给出了上述错误。而在 RHS 中同样有效。【参考方案2】:这看起来像是“声明性议程”功能的一个很好的案例。这是基于用于阻止规则的规则。这是一个简单的例子:
import org.kie.api.runtime.rule.Match;
rule "Apply 50% discount"
@Eager // required for each rule to be blocked
@Category("Singapore")
when
$s : Sale( article matches ".*PX" ) // anything
then
System.out.println("VIP: " + drools.getRule().getName());
end
rule "CheckBlock"
@Direct @Eager // required for each rule that blocks
when
Location( $country: country )
// $m: Match( Category == "Singapore" )
$m: Match( rule.name == "Apply 50% discount" )
then
kcontext.blockMatch( $m );
end
位置是一个简单的bean。如图所示,阻止规则可以访问“匹配”对象,该对象(神奇地)允许您匹配元数据或规则名称。当然,评估可能会访问 Location 中的某些方法,以对规则名称进行更复杂的检查。
注意,你需要设置一个选项:
KieBaseConfiguration config = ks.newKieBaseConfiguration();
config.setOption( DeclarativeAgendaOption.ENABLED );
或使用 kmodule XML(参见文档)。
【讨论】:
以上是关于drools.getRule().getName() 在属性 -rule 流水文件中的主要内容,如果未能解决你的问题,请参考以下文章
Thread.currentThread().getName() ,对象实例.getName() 和 this.getName()区别
Thread.currentThread().getName() ,对象实例.getName() 和 this.getName()区别
Thread.currentThread().getName() ,对象实例.getName() 和 this.getName()区别