Search code examples
drools

How to access common declared types from a function in Drools?


Here am having multiple Rules in a .drl file. They are updating 6 different JSONArray. These updates are happening in the "then" section of the Drools. Rather than having the similar logic inside the rule, am trying to write a function which will update the 6 JSONArray. How would that be possible ?

declare USER1_LIST
     querysetUser1 :JSONArray
end
declare USER2_LIST
     querysetUser2 :JSONArray
end
......
......
......

The initialization is happening in a "Set Up" rule with highest Salience -

rule "setUp"
salience 25
when
then
USER1_LIST user1_list = new USER1_LIST();
user1_list.setQuerysetUser1(new JSONArray());
insert(user1_list);
....

In the rule am using one of the list based on the logic -

rule "RULE_XYZ"
salience 5
when
USER1_LIST($querysetUser1 :querysetUser1)
...<Some code>
then
...<Some code>
$querysetUser1.add(...);

Here I want to perform the operation "$querysetUser1.add(...);" inside a function. These JSONArray are updated by different rules. So my aim is to move the logic of selecting the JSONArray and updating it in a function, so that only this function would be called from different rules.


Solution

  • Declared types can be accessed in declared functions. However, from your example, it sounds like you just need to be able to do work against the JSONArray objects contained within the declared types.

    The function would look something like this:

    function void addToQuerySet(JSONArray querySet, JSONObject object) {// I have guessed the type of 'object'
      querySet.add(object);
    }
    

    And you would invoke it from the then clause:

    rule "RULE_XYZ"
    when
      USER1_LIST($querysetUser1 :querysetUser1)
      // ...<Some code>
      someObject: JSONObject() // the thing to insert
    then
      addToQuerySet($querysetUser1, someObject);
    end
    

    What you cannot do is write a generic method that will take any of your USER1_LIST, USER2_LIST, etc declared types because they're all unique and unrelated types, even if they all share the same structure.

    Note that the fact that your declared types sharing the same structure is indicative of poor design -- it is likely they should all be instances of a single type, with somet other way of identifying which user it belongs to. For example, something like this:

    declare UserList 
      querySet: JSONArray
      userNum: int
    end
    

    Where userNum would indicate which user this is for. Then you could write a function that takes a UserList and a JSONObject (or whatever the type is of that thing is you're adding to the query set) like so:

    function void addToQuerySet(UserList userList, JSONObject object) {
      userList.getQuerySet().add(object);
    }
    

    And invoke it in a then clause like so:

    rule "RULE XYZ version 2"
    when
      $user1List: UserList( userNum == 1, querySet != null)
      // more code
      $someObject: JSONObject() // to insert
    then
      addToQuerySet( $user1List, $someObject );
    end
    

    Please refer to the documentation here. I have linked to the Drools 7.11.0.Final documentation, specifically the section on functions; the section on declared types is the following section and quite extensive.