如何获取被解雇的规则的LHS中的所有事实并在RHS中包含插入?

时间:2018-01-22 02:56:31

标签: java drools

当规则在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中存在插入并且规则被触发。

2 个答案:

答案 0 :(得分:0)

嗯,这是一个棘手的问题。首先,让我告诉您,并非所有ObjectInsertedEvents都与规则相关联。您可以使用KieSession引用自行插入事实。

不幸的是,你想要做的事情在Drools中并不简单。您需要两个侦听器的组合,并假设规则激活按顺序执行(我认为这是默认行为)。

除了RuleRuntimeEventListener之外,您还需要在会话中注册AgendaEventListener的实例。 在将要触发规则(BeforeMatchFiredEvent)和触发规则(AfterMatchFiredEvent)之后,将调用此侦听器 - 以及其他时间。

所以现在你有3条信息(这里的顺序很重要):

  • 规则-X即将被解雇 - >来自AgendaEventListener
  • 插入了对象并ObjectInsertedEvent.rule.name == "Rule-X" - >来自RuleRuntimeEventListener
  • 规则-X被解雇 - >来自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;
    }
}