Search code examples
javadrools

is it possible to extend a rule using a specified set of parameters or pass parameters into a rule in Drools?


I have a large number of almost duplicate rules to implement. They are the exact same but the right hand sides are slightly different. eg

rule "AS77" extends "IVD01"
  @description(" IF Individual Identifier = E, THEN Other Description is required. ")
  when
    $source : Owner($errCode : "427")
  then
end

rule "AS78" extends "IVD01"
  @description(" IF Individual Identifier = E, THEN Other Description is required. ")
  when
    $source : JntOwner($errCode : "428")
  then
end

rule "IDV01"
  @description("IF Individual Identifier = E, THEN Other Description is required. ")
  when
    IDVerify(idType == "E", otherDscrp == null) from $source
  then
    _reject.getErrorCode().add($errCode.toString());
end

I would like to do something like the above but I know that I can't because "$source" is in the child rule. I also know that I can't switch it around and have the rule with the condition extend the other rules because a Drools rule can only extend one other rule. In java I would make a method like,

static void evalIdVerify(IDVerify idv, String errorCode) {
  if ("E".equals(idv.getIdType()) && idv.getOtherDescript() == null) {
    _reject.getErrorCode().add(errorCode);
  }
}

and use it as required. Is there any way to write a rule that can be called like a method and takes parameters? Or some other solution that isn't just writing the same rule over and over again? I have no control over the classes and these rules are modified every year by a third party so for maintainability I would really like them to only be defined once. Any help would be appreciated. Thanks.


Solution

  • But you can "switch it around". All you need to do is to insert the IDVerify object as a fact.

    rule "IDV01"
      @description("IF Individual Identifier = E, THEN Other Description is required. ")
    when
      $id: IDVerify(idType == "E", otherDscrp == null)
    then
    end
    
    rule "IDV01 for Owner" extends "IVD01"
    when
      $source: Owner($errCode : "427", id == $id)
    then
      _reject.getErrorCode().add($errCode.toString());
    end
    

    Another option is to write it as a single rule for each check:

    rule "IDV01 for Owner"
    when
      $source: Owner($errCode : "427",
                     $id.idType == "E", $id.otherDscrp == null)
    then
      _reject.getErrorCode().add($errCode.toString());
    end
    

    You can put the IDVerify test into a boolean function or static method, reduces the amount of code duplication.