Search code examples
drools

Drools: Get identifier from LHS pattern


I am using Drools 6.3.0 Final. Assuming I have a rule like this

rule "Child of Person over 18"
when
    $person : Person(age > 18)
    $child : from $person.children
then
end

Let us further assume I build my KieSession with this rule, add some facts and now I want to know the identifiers used in all rules / in all rules that matched my facts.

So what I want to get here is $person and $child.

I know I can get the rules, which fired using an AgendaEventListener and from the event I can get the name of the rule, as well as the objects for $person and $child. But I fail to find a way to get the identifiers $person and $child from my match. Using a debugger I can see the information is there... actually the Rule I get from the event, is a RuleImpl, which has a lhsRoot, in which I can find that information... but this sounds much more complicated than it should be and not the intended way.

So I was wondering if there is not a better way for this.


Solution

  • Your requirement can be easily achieved by using Drools' public API. You were looking at the right place (AgendaEventListener) but Match.getObjects() is not what you need. What you need is a combination of Match.getDeclarationIds() (to get the list of identifiers) and then Match.getDeclarationValue(String id) (to get the value for each identifier). As an example, this is how an AgendaEventListener that logs this information in the console will look like:

    import org.kie.api.event.rule.BeforeMatchFiredEvent;
    import org.kie.api.event.rule.DefaultAgendaEventListener;
    
    ...
    
    ksession.addEventListener(new DefaultAgendaEventListener() {
    
        @Override
        public void beforeMatchFired(BeforeMatchFiredEvent event) {
    
            String ruleName = event.getMatch().getRule().getName();
            List<String> declarationIds = event.getMatch().getDeclarationIds();
    
            System.out.println("\n\n\tRule: "+ruleName);
    
            for (String declarationId : declarationIds) {
                Object declarationValue = event.getMatch().getDeclarationValue(declarationId);
    
                System.out.println("\t\tId: "+declarationId);
                System.out.println("\t\tValue: "+declarationValue);
            }
            System.out.println("\n\n");
        }
    });
    

    As @laune mentioned,you can also get an instance of the match that activated a rule in the RHS of the rules themselves. In this case, the Match object is accessible through drools.getMatch().

    Hope it helps,