I'm trying to create a rule in Drools that would trigger based on a hypothetical student getting straight As.
import Student
import Semester
import java.util.*
dialect "mvel"
rule "straight As1"
when
$s : Student(
grades != null,
$g : grades
)
forall(
Semester(reading == "A", writing == "A", math == "A") from $g
)
then
System.out.println($s.getId() + ": s all As1: " + $s);
System.out.println($s.getId() + ": g all As1: " + $g);
end
rule "straight As2"
when
$s : Student(
grades != null,
$g : grades
)
$a : List(size() == $g.size) from
collect (Semester(reading == "A", writing == "A", math == "A") from $g)
then
System.out.println($s.getId() + ": s all As2: " + $s);
System.out.println($s.getId() + ": g all As2: " + $g);
end
The output of this:
001: s all As1: Student{id='001', grades=[{writing=A, reading=A, math=A}, {writing=A, reading=A, math=A}], name='Albert'}
001: g all As1: [{writing=A, reading=A, math=A}, {writing=A, reading=A, math=A}]
----------------
002: s all As1: Student{id='002', grades=[{writing=B, reading=B, math=B}], name='Bob'}
002: g all As1: [{writing=B, reading=B, math=B}]
The problem here is that Bob doesn't have All As. I am not sure how to get either of the straight As
rules to fire for Albert and not Bob - the As1
attempt fires for everything while As2
attempt doesn't fire for anything.
I've been able to write rules to filter based on name. In debugging this I've had the breakpoint on getGrades()
trigger... but none of the breakpoints on getMath()
, getWriting()
or getReading()
have been hit.
A Student object (tightened up and toString() removed) is:
public class Student {
private String id;
private List<Semester> grades;
private String name;
public Student() { }
public String getName() { return name; }
public String getId() { return id; }
public List<Semester> getGrades() { return grades; }
public void setName(String name) { this.name = name; }
public void setId(String id) { this.id = id; }
public void setGrades(List<Semester> grades) { this.grades = grades; }
}
The corresponding Semester object (also tightened up and toString() removed):
public class Semester {
private String reading;
private String writing;
private String math;
public Semester() { }
public String getReading() { return reading; }
public String getWriting() { return writing; }
public String getMath() { return math; }
public void setReading(String reading) { this.reading = reading; }
public void setWriting(String writing) { this.writing = writing; }
public void setMath(String math) { this.math = math; }
}
These objects are instantiated with the code snippet:
YamlReader reader = new YamlReader(new FileReader(file));
Student student = reader.read(Student.class);
System.out.println(student.toString());
rv.add(student);
and an yaml object such as:
id:
001
grades:
-
reading: A
writing: A
math: A
-
reading: A
writing: A
math: A
name:
Albert
Use the simplest possible approach:
rule "straight As1"
when
$s : Student( grades != null, $g : grades )
not Semester(reading != "A" || writing != "A" || math != "A") from $g
then
System.out.println($s.getId() + ": s all As1: " + $s);
System.out.println($s.getId() + ": g all As1: " + $g);
end
My Main, using your Student and Semester:
public class Main {
private KieSession kieSession;
private KieScanner kieScanner;
public void build() throws Exception {
KieServices kieServices = KieServices.Factory.get();
KieFileSystem kfs = kieServices.newKieFileSystem();
FileInputStream fis = new FileInputStream( "alla/alla.drl" );
kfs.write( "src/main/resources/simple.drl",
kieServices.getResources().newInputStreamResource( fis ) );
KieBuilder kieBuilder = kieServices.newKieBuilder( kfs ).buildAll();
Results results = kieBuilder.getResults();
if( results.hasMessages( Message.Level.ERROR ) ){
System.out.println( results.getMessages() );
throw new IllegalStateException( "### errors ###" );
}
KieContainer kieContainer =
kieServices.newKieContainer( kieServices.getRepository().getDefaultReleaseId() );
KieBase kieBase = kieContainer.getKieBase();
kieSession = kieBase.newKieSession();
}
public void exec(){
Student albert = new Student();
albert.setName( "Albert" );
albert.setId( "001" );
albert.getGrades().add( new Semester( "A", "A", "A" ) );
albert.getGrades().add( new Semester( "A", "A", "A" ) );
kieSession.insert( albert );
Student bob = new Student();
bob.setName( "Bob" );
bob.setId( "002" );
bob.getGrades().add( new Semester( "B", "B", "B" ) );
kieSession.insert( bob );
kieSession.fireAllRules();
}
public static void main( String[] args ) throws Exception {
Main m = new Main();
m.build();
m.exec();
}
}