Drools Instanceof with Inheritance

Viewed 1079

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?

2 Answers

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,

Quick update: I was also able to use:

rule "MyRow"
    dialect "mvel"
    when
        f1 : Wrapper( eval( nestedProperty#MyNestedClass  ), ... )
    then
        ...
end

Which is handy for testing classes of (nested) properties.

Related