I have written a dynamic rules for a straightforward conditions like.
an example object;
public class Student {
private String name;
private String surName;
private Integer age;
private Address address;
}
we can write any straightforward conditions like below
- student.name == ‘test’
- student.address.street == ‘test’
- student.age > 10
I want to achieve a condition where I need to iterate over a list of object and do the filter.
an example object;
public class Student {
private String name;
private String surName;
private Integer age;
private Address address;
private List<Subject> subjects;
}
enter code here
I want to write a condition for subjects and do the filter.
When your rule has a condition like MyObject( ... ) from $list
, Drools will iterate over each object in the list and execute the consequences once for each object in the list that matches your criteria.
If you have a class that contains a list of students like —
class School {
List<Student> students
}
You’d write your rule like:
rule "Test students over age 10"
when
School( $students: students != null )
$student: Student( name == "test", age > 10, /* other conditions */ ) from $students
then
// this will execute for each student that matches the condition
System.out.println("Found student " + $student.name + " of age " + $student.age);
end
Assuming that students
contains the following students (simplified model for example purposes):
[
{ name: "test", age: 5 },
{ name: "Alice", age: 5 },
{ name: "Bob", age: 12 },
{ name: "test", age: 100 },
{ name: "Charlie", age: 18 },
{ name: "Darius", age: 8 },
{ name: "Elizabeth", age: 10 },
{ name: "test", age: 11 }
]
Then the above rule would expect to print:
Found student test of age 100
Found student test of age 11
This line in the rule:
$student: Student( name == "test", age > 10, /* other conditions */ ) from $students
iterates across the $students
list and considers each individual record. If the record matches the conditions you’re looking for, the right hand side (“then”) will trigger with $student
assigned to the matching record. If you have no records that match your criteria, the rule will never fire. If you have one record that matches, it will fire once. If you have 100 records that match, it will fire once for every match.
2
I have achieved it by below contion
School($subject : student.subjects) Student(teacher!=null && teacher.name=='L1') from $subject
The Classes are
public class School {
private String name;
private Student student;
}
public class Student {
private String name;
private List<Subject> subjects;
}
public class Subject {
private String name;
private Teacher teacher;
}
public class Teacher {
private String name;
}
Thanks to Roddy of the Frozen Peas, with his answer I was able to get it done.
FYI: the classes are for example, not an actual classes.