Search code examples
drools

Drools Instanceof with Inheritance


I have 5 fact types: BaseFact, AFact, BFact, CFact and DFact.

AFact, BFact, CFact and DFact all inherit from BaseFact.

I have some rules that run on BaseFacts, that I can no longer run on CFacts or DFacts.

What is the best way to modify my BaseFact rules so that they only run on BaseFacts, AFacts and BFacts.

Is there some sort of instanceOf function I can check, like the following?

rule "BaseRule"
    when
        fact : BaseFact(this instanceOf AFact || this instanceOf BFact)
        ...
    then
        ...
end

Or do I need to split this rule into 2 new rules, for AFact and BFact?


Solution

  • Even if there is no instanceOf operator, there are several ways to achieve what you are looking for.

    These are some ideas:

    rule "BaseRule"
    when
        fact : BaseFact(class == AFact.class || == BFact.class)
        ...
    then
        //note that the variable fact is still of type BaseFact
        ...
    end
    

    A nastier version:

    rule "BaseRule"
    when
        fact : BaseFact()
        not CFact(this == fact)
        not DFact(this == fact)
        ...
    then
        //note that the variable fact is still of type BaseFact
        ...
    end
    

    Or:

    rule "BaseRule"
    when
        AFact() OR
        BFact()
        ...
    then
        //note you can't bind a variable to AFact or BFact
        ...
    end
    

    If you only have 2 concrete types you want to match, then having 2 individual rules doesn't sound like a bad idea either.

    Hope it helps,