Слюни, не совпадающие с вложенным объектом, полученным в результате десериализации

Я пытаюсь создать правило в Drools, которое будет срабатывать на основе гипотетического студента, получающего прямую 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

Выход этого:

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}]

Проблема в том, что у Боба нет All As. Я не уверен, как получить любой из straight As правила увольнять для Альберта, а не для Боба As1 Попытка пожара для всего, пока As2 Попытка ни к чему не приводит.

Я был в состоянии написать правила для фильтрации на основе имени. При отладке этого у меня была точка останова на getGrades() триггер... но ни одна из точек останова на getMath(), getWriting() или же getReading() был поражен.

Объект Student (затянутый и удаленный toString()):

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; }
}

Соответствующий объект Semester (также подтянутый и toString() удален):

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; }
}

Эти объекты создаются с помощью фрагмента кода:

YamlReader reader = new YamlReader(new FileReader(file));
Student student = reader.read(Student.class);
System.out.println(student.toString());
rv.add(student);

и объект yaml, такой как:

id:
  001
grades:
  -
    reading: A
    writing: A
    math: A
  -
    reading: A
    writing: A
    math: A
name:
  Albert

1 ответ

Решение

Используйте самый простой подход:

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, используя ваш студент и семестр:

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();
}
}
Другие вопросы по тегам