8

does anybody know if there is a way to do for loops in drools ?.

I am trying to loop through a list of string to see if one of the strings matches a pattern e.g.

def listOfStrings = ['a','a.b','a.b.c']

for(String s:listOfStrings){
 if(s matches "^a.b.*$"){
 return true 
 }
}

I have written the following rule based on what documentation I could find, but I dont think the syntax is correct

rule "Matcher"
   when
      TestClass : TestClass(($s matches "^a.b.*$") from listOfStrings, count($s))
   then
      TestClass.setResponse( "Condition is True !!" );
end

I am finding it hard to find good documentation on the drl language

I would appreciate any help that anybody can give me


Based on the previous answer, I have tried the following

rule "Matcher"
  when
 TestClass:TestClass(String( this matches "^a.b.*$" ) from listOfStrings)
then
       TestClass.setResponse( "Condition is True !!" );
end 

However, I now get the following error message:

[43,197]: unknown:43:197 Unexpected token 'this'
casperOne
  • 73,706
  • 19
  • 184
  • 253
mh377
  • 1,656
  • 5
  • 22
  • 41

4 Answers4

14

I think you've misunderstood the fundamentals of a rules engine; you need to think a bit differently.

Instead of 'iterating' over the list, you need to break the list into its component strings and insert them individually as facts into working memory.

Only the strings/facts which match the 'when' condition will fire the rule.

You might also want to look into globals and queries. global will allow you to inject a service into your working memory for your consequences to call, and the query might be a way by which you can obtain the matched strings out of working memory.

Mechanical snail
  • 29,755
  • 14
  • 88
  • 113
Steven Herod
  • 764
  • 8
  • 20
4

I had used this command when I used this drl file as rules for my project

Hope this may be helpful to you.

package com.sample

import com.sample.HelloProcessModel;

rule "NYuser_Rule"

    no-loop true
    ruleflow-group "EvalLoopcondition"
    when
        m:HelloProcessModel(userlocation in ("NewYorkUser"), count < 4)
    then
        m.setLoopcondition(6);update(m);
end


rule "ChileUser_Rule"

    no-loop true
    ruleflow-group "EvalLoopcondition"
    when
        m:HelloProcessModel(userlocation in ("ChileUser"), count < 3)
    then
        m.setLoopcondition(5);update(m);
end


rule "BelgiumUser_Rule"

    no-loop true
    ruleflow-group "EvalLoopcondition"
    when
        m:HelloProcessModel(userlocation in ("BelgiumUser"), count < 6)
    then
        m.setLoopcondition(8);update(m);
end
Derrick
  • 3,669
  • 5
  • 35
  • 50
Dhaval Shah
  • 9,042
  • 2
  • 14
  • 21
2

The Rete algorithm doesn't work this way.

I think you want to try regex in Drools.

duffymo
  • 305,152
  • 44
  • 369
  • 561
  • Thanks for the link, but the example there only searches a string to see if it matches a regex. In my example I could use "a.b.c" matches "^a.b.*$" But that isnt what I am trying to achieve, I am trying to search a list of strings to see if any of them match a regular expression. I dont think it is the regex part that is causing me problems. It is the fact that I dont know how to iterate through a list of string in drools. Do you know how I might be able to do this ? thanks – mh377 Jul 31 '10 at 14:53
  • I'm not certain, but I'm guessing you want to see about applying the regex to a list. "matches at least one", "matches one or more" are the kinds of things I'd be looking for. If you aren't find loops in Drools, it's because it's not supposed to work that way. – duffymo Jul 31 '10 at 15:02
  • do you know if there is a way to embed java code into a rule? – mh377 Jul 31 '10 at 16:01
  • @MTH you can use the eval() function of Drools, to see if an expression in Java is true/false. I have made the experience, that eval is limited and a takes some try/error to get it to work properly – Sören Aug 09 '11 at 17:48
0

I am also iterating over the String[] and using this functions of String on each String from the String[]. This is what I am using...

String ( $vvl.indexOf( String.valueOf( charAt($idx)) ) >= 0 ) from $m.stringArray

So you can call different functions of String on each String placed in String Array.

Saghir A. Khatri
  • 3,429
  • 6
  • 45
  • 76
Rizwan
  • 71
  • 1
  • 1