Checking flag value before inserting flag in drools

Tags: , ,



I’ve produced a rule and it inserts a question in session. If the question is true, it inserts a FLAG and if the question is not true, it deletes the question and doesn’t update the flag. I need to check the value of the flag before inserting the question in the session. I have tried several ways to do this but not getting the drools thing to do this. Here are my rules:
Inserting question rule

rule "Threat: ATTACK_OTHER_USERS; insert question"
agenda-group "evaluate attack category"
dialect "mvel"

when
    Threat(this == Threat.ATTACK_OTHER_USERS)
//    $FLAGS(this == FLAGS.PUBLIC_READABLE)   // i need the check here, the existing doesn't work
then

    insertLogical(QRiskFactor.QRF1_S4_PUBLIC_READABLE);
end

question is true

rule "Threat: Public Readable  QRF_1.4 [true]"
agenda-group "evaluate attack category"
dialect "mvel"
when
     $q1: QRiskFactor(this == QRiskFactor.QRF1_S4_PUBLIC_READABLE)
     Application($rf : riskFactors[QRiskFactor.QRF1_S4_PUBLIC_READABLE.value], $rf!.factor == "true")
then
    delete($q1);
    insert(FLAGS.PUBLIC_READABLE);

end

question is false

rule "Threat: Public Readable -- QRF_1.4 [not true]"
agenda-group "evaluate attack category"
dialect "mvel"
when
     $q1: QRiskFactor(this == QRiskFactor.QRF1_S4_PUBLIC_READABLE)
     Application($rf : riskFactors[QRiskFactor.QRF1_S4_PUBLIC_READABLE.value], $rf!.factor != "true")
 then
   delete($q1);

end

Answer

You need to check for the presence of your specific flag in working memory. The commented out syntax in your rule is nearly correct, except you seem to have an extraneous $ present.

Since you’ve not shared what FLAGS is, it’s a little hard to answer your question specifically. I’m going to assume, based on how you’ve formulated your insert statement, that it’s an enum like this:

public enum FLAGS {
  PUBLIC_READABLE,
  // possibly other values
}

So if you want to verify that a FLAGS.PUBLIC_READABLE has been inserted into working memory, your rule would include:

when
  exists(FLAGS( this == FLAGS.PUBLIC_READABLE ))

I use exists because you’ve not indicated that you need to do anything with the flag, so I’m just checking for its presence.

Note that insert doesn’t re-execute previously evaluated rules. If you need to reevaluate all of working memory, you should use update instead.


Based on comments, here is how you’d implement a simple “quiz” application. A user presents an answer to a question; if the user answers correctly, they are presented with the next question. If the user answers incorrectly, it is “game over” for them and they are given the correct answer to the question they did incorrectly.

I’m using some very simple models:

class Question { 
  private int id;
  private String questionText;
  private String correctAnswer;
  // getters and setters
}
class QuizUtils {
  public static Question showNextQuestion();
  public static void doGameOver(Question questionMissed);
}

The user’s answer is a String entered directly into working memory.

rule "User got the question right"
when
  // the user's answer
  $userAnswer: String()
  
  // the current question
  Question( correctAnswer == $userAnswer )
then
  QuizUtils.showNextQuestion();
end

rule "User got the question wrong"
when
  $userAnswer: String
  $question: Question (correctAnswer != $userAnswer )
then
  QuizUtils.doGameOver($question);
end


Source: stackoverflow