Zied Koubaa
Zied Koubaa

Reputation: 213

How to access nested class in Drools

I am beginner in Drools. I have this model in scala :

case class OuterClass (int parentValue ) {
   lazy val childs: Seq[InnerClass] = getChilds()

   case class InnerClass (int childValue ) {
   }
}

I need to create a Drools rule that checks parents with parentValue = 1, and having at least one child with childValue = 2

I created this rule:

dialect "mvel"
import com.models.OuterClass
rule "1"
when
 $parent: OuterClass($pv: parentValue, $c: childs, $pv == 1)
 $parent.InnerClass($cv: childValue, $cv == 2) from $c
then
 "do something"
end

But I get following error: "Unable to resolve ObjectType '$parent.InnerClass'"

How can I access nested class in Drools ?

Upvotes: 1

Views: 1530

Answers (1)

Esteban Aliverti
Esteban Aliverti

Reputation: 6322

You almost got it!

The rule you are looking for is something like this:

rule "1"
when
  $parent: OuterClass($pv: parentValue == 1)
  $inner: InnerClass($cv: childValue == 2) from $parent.childs
then
  "do something"
end

As you can see, the relation between the parent and the child is stated in the right side of the from.

The problem with this rule is that is going to be executed as many times as children with a value == 2 an OuterClass object has. If you just want to check for the presence of at least one child with value ==2, then you can try something like this:

rule "1"
when
  $parent: OuterClass($pv: parentValue == 1)
  exists( InnerClass(childValue == 2)) from $parent.childs
then
  "do something"
end

Note that in this case, you can't bind variables to the second pattern because you don't know which one it will be.

If you need to get information about the InnerClass object/s matching the pattern, but you still want to get the rule executed only once, a strategy could be to collect all the InnerClass objects in a collection:

rule "1"
when
  $parent: OuterClass($pv: parentValue == 1)
  $list: List(size > 0) from collect( 
    InnerClass(childValue == 2) from $parent.childs
  )
then
  "do something"
end  

Hope it helps,

Upvotes: 1

Related Questions