当规则在RHS中插入新对象时,如何获取规则的LHS中的所有事实?我是Drools的新学员。现在我正在使用Drools 7.规则如下。
rule "Hello World"
when
$ms:MiddleSchool()
then
System.out.println("ruleName is Hello World");
HighSchool hs = new HighSchool();
hs.setNum(10);
insert(hs);
end
我写了eventListener
,但它无法获得规则的LHS。
public class RunListener implements RuleRuntimeEventListener{
@Override
public void objectInserted(ObjectInsertedEvent objectInsertedEvent){
}
}
所以我真的希望有人可以教我如何编写eventListener
以获得规则的LHS,同时规则的RHS中存在插入并且规则被触发。
答案 0 :(得分:0)
嗯,这是一个棘手的问题。首先,让我告诉您,并非所有ObjectInsertedEvents
都与规则相关联。您可以使用KieSession
引用自行插入事实。
不幸的是,你想要做的事情在Drools中并不简单。您需要两个侦听器的组合,并假设规则激活按顺序执行(我认为这是默认行为)。
除了RuleRuntimeEventListener
之外,您还需要在会话中注册AgendaEventListener
的实例。
在将要触发规则(BeforeMatchFiredEvent
)和触发规则(AfterMatchFiredEvent
)之后,将调用此侦听器 - 以及其他时间。
所以现在你有3条信息(这里的顺序很重要):
AgendaEventListener
ObjectInsertedEvent.rule.name == "Rule-X"
- >来自RuleRuntimeEventListener
AgendaEventListener
不幸的是,据我所知,关联这3个事件的唯一方法是规则的名称。
从BeforeMatchFiredEvent
,您可以通过event.getMatch().getObjects()
获取激活规则所涉及的所有事实。如果您只对规则的LHS的绑定对象感兴趣,可以尝试使用event.getMatch().getDeclarationIds()
和event.getMatch().getDeclarationValue()
。
希望它有所帮助,
答案 1 :(得分:0)
The main code is as follows.
public class DroolsTest {
public static final void main(String[] args) {
try {
KieServices ks = KieServices.Factory.get();
KieContainer kieContainer = ks.getKieClasspathContainer();
KieSession kSession = kieContainer.newKieSession("ksession-rules");
AgendaEventListener agendaEventListener = new AgendaEventListener() {
@Override
public void afterMatchFired(AfterMatchFiredEvent arg0) {
System.out.println("##############");
System.out.println(arg0.getMatch().getObjects());
System.out.println(arg0.getMatch().getDeclarationIds());
System.out.println(arg0.getMatch().getRule());
System.out.println("###############");
}
@Override
public void afterRuleFlowGroupActivated(RuleFlowGroupActivatedEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void afterRuleFlowGroupDeactivated(RuleFlowGroupDeactivatedEvent arg0) {
}
@Override
public void agendaGroupPopped(AgendaGroupPoppedEvent arg0) {
}
@Override
public void agendaGroupPushed(AgendaGroupPushedEvent arg0) {
}
@Override
public void beforeMatchFired(BeforeMatchFiredEvent arg0) {
System.out.println("***************");
System.out.println(arg0.getMatch().getObjects());
System.out.println(arg0.getMatch().getDeclarationIds());
System.out.println(arg0.getMatch().getRule());
System.out.println("***************");
}
@Override
public void beforeRuleFlowGroupActivated(RuleFlowGroupActivatedEvent arg0) {
}
@Override
public void beforeRuleFlowGroupDeactivated(RuleFlowGroupDeactivatedEvent arg0) {
}
@Override
public void matchCancelled(MatchCancelledEvent arg0) {
}
@Override
public void matchCreated(MatchCreatedEvent arg0) {
}
};
kSession.addEventListener(agendaEventListener);
Product p1 = new Product();
p1.setDiscount(10);
kSession.insert(p1);//I think insert here would influence the insert in my rule and the eventListener would grasp it.
Message message = new Message();
message.setMessage("Hello World");
message.setStatus(Message.HELLO);
kSession.insert(message);//disturbed insert which would influence insert in my rule.
int count = kSession.fireAllRules();
System.out.println("number of fired rules:" + count + "H");
kSession.dispose();
} catch (Throwable t) {
t.printStackTrace();
}
}
public static class Message {
public static final int HELLO = 0;
public static final int GOODBYE = 1;
private String message;
private int status;
public String getMessage() {
return this.message;
}
public void setMessage(String message) {
this.message = message;
}
public int getStatus() {
return this.status;
}
public void setStatus(int status) {
this.status = status;
}
}
}
这是RuleRuntimeEventListener。
package com.sample;
import org.kie.api.event.rule.ObjectDeletedEvent;
import org.kie.api.event.rule.ObjectInsertedEvent;
import org.kie.api.event.rule.ObjectUpdatedEvent;
import org.kie.api.event.rule.RuleRuntimeEventListener;
public class RunListener implements RuleRuntimeEventListener {
@Override
public void objectInserted(ObjectInsertedEvent objectInsertedEvent) {
System.out.println("监听insert对象");//how to write the method?
System.out.println(objectInsertedEvent.getObject());
}
@Override
public void objectDeleted(ObjectDeletedEvent arg0) {
// TODO Auto-generated method stub
System.out.println("监听delete对象");
}
@Override
public void objectUpdated(ObjectUpdatedEvent arg0) {
// TODO Auto-generated method stub
System.out.println("监听update对象");
}
}
这是我的规则。
package com.sample
import com.sample.DroolsTest.Message;
import java.util.Map;
rule "Hello World"
no-loop true
when
m1 : (Message( status == Message.HELLO))
$p1:Product(discount==10)
then
System.out.println(drools.getRule().getName());
m1.setMessage( "Goodbye cruel world" );
m1.setStatus( Message.GOODBYE );
Product p2 = new Product();
p2.setDiscount(20);
insert(p2);
end
rule "GoodBye"
no-loop true
when
$p2:Product(discount==20)
then
System.out.println(drools.getRule().getName());
end
rule "updateName"
no-loop true
when
$p2:Product(discount==20)
then
$p2.setDiscount(30);
update($p2);
System.out.println(drools.getRule().getName());
end
这是我的规则中使用的一个类。
package com.sample;
public class Product {
private int discount;
public Product() {
super();
}
public Product(int discount) {
super();
this.discount = discount;
}
public int getDiscount() {
return discount;
}
public void setDiscount(int discount) {
this.discount = discount;
}
}