Special Drools operations

We've seen, so far, the simplest cases to check attribute values against the boolean expressions in our rules. We've also discussed all the different ways in which rules can manage data updates, which might retrigger checking our rules. However, the power of rules doesn't stop there as there are many different ways in which the rule conditions can be written, which will allow us to create rules that are both powerful and simple to understand.

Drools already provides a set of operations that you can use to compare different objects against each other. These objects might be living directly on the working memory, global variables, literal values, or any combination of these types. We're going to enumerate the most used ones in the following sections, splitting them into the following:

  • Boolean and numeric operations
  • Collection-based operations
  • Regex operations
  • Custom operations

Boolean and numeric operations

We've seen some examples of these operations in our previous rules as they are the simplest to understand for anyone with programming experience. Boolean operations are the ones that use AND, OR, XOR, and so on. Numeric operations are the ones that compare two numeric values. Here's an example of some of these operations against an attribute of the Item type:

Item( salePrice > 100.00 && salePrice <= 500.00&& salePrice != 101.00 )

In the previous example of a condition, we checked whether the salePrice attribute of our Item object has a value greater than 100, lesser or equal to 500, and different from 101, in that order.

Some of these operations are intrinsic to Drools, such as the use of the AND operation. Using the && method is not necessary in the conditions of the previous example as any comparison that is separated by a comma is considered a new condition that must be checked as well. However, boolean conditions are required to express the situations where either one of the two conditions needs to be true (that is, an OR boolean expression).

Using boolean expressions is possible, but if required, they will usually mark places where the design of our rules needs revision. This is because the AND expressions are intrinsic to the language and rules that use OR expressions should be considered as more than one condition in the same rule (and therefore, non-atomic). Whenever an OR expression is required to express a rule, consider splitting the rule into two different rules, as shown in the following example:

rule "Add 5% discount for minors or seniors"
    when $o: Order(customer.age < 18 || customer.age > 60)
    then $o.increaseDiscount(0.05);
end

This could be broken into this two rules:

rule "Add 5% discount for minors"
    when $o: Order(customer.age < 18)
    then $o.increaseDiscount(0.05);
end
rule "Add 5% discount for seniors"
    when $o: Order(customer.age > 60)
    then $o.increaseDiscount(0.05);
end

It might seem that boolean expressions are something to avoid as much as possible, however, we will see some other uses that they have when combining other operations later in this chapter. For the moment, let's just remember that they exist and try to use them only if really needed.

Regex operations – matches

Matches is an operator that we can use against string-based objects and attributes. It allows us to check whether they follow a specific regular expression. Most common uses of them are to check whether a string represents a valid number, e-mail, or any special character order that we need to validate. Regular expressions are a very complex topic to cover here and you can learn more about them online. We will see a small example of how matches are used in a rule condition by creating a rule to check whether customers in our KieSession have a valid e-mail address, as follows:

rule "validate customer emails"
       when $c: Customer(email not matches "[A-Za-z0-9-.]+@[A-Za-z0-9-.]+$")
       then $c.setEmail(null); //invalidate email
   end

The previous rule has a simplified regular expression to validate e-mails. Any Java regular expression could be used with the matches and not matches operators and they can both work with variables and literal values. This means that the regular expression could be a global variable defined somewhere else.

Collection operations – contains and memberOf

The collection operations are the ones prepared to work with one or more collections, whether they are variables, attributes, or literal values. They are used to determine whether a collection has an element in them. An example of using these operations would be something similar to the following:

rule "print orders with pencils in them"
     when
       $i: Item(name == "pencil")
       $ol: OrderLine(item == $i)
       $o: Order($ol memberOf orderLines, orderLines contains $ol)
     then
       System.out.println("order with pencils: " + $o);
   end

In the previous rule, we're using both operations one after the other. They are both checking for the same condition, whether the found order line is in the orderLines collection of the order object.

Operations in Drools have an open syntax. This means that you can write your own operation if you need to. This is a useful tool when a comparison of two objects has too many complexities to be easily written as a simple boolean operation. Some common uses for custom operations are comparing GPS location data to determine facts near to each other in space or comparing time data to determine time relationships between events. We will see more about custom operations in the next chapter.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.143.0.85