[rules-users] Finding matching values in composite constraint

Wolfgang Laun wolfgang.laun at gmail.com
Sun Jan 6 03:34:52 EST 2013


(1) It could be possible to create distinct rules, each rule matching
just one single potential substring - but I would not do that.

(2) It's better to insert the substrings that should be detected in
the transaction field as individual objects of a class Key:
  public class Key {
    String key;
    public Key( String key ){ this.key = key; }
    public String getKey(){ return key; }
    public boolean matches( String field ){ return field.contains( key ); }
 }
with a simple rule:
  rule r1
  when
    $key: Key()
    $t: Transaction( $code: code, eval( $key.matches( $code ) ) )
  then
    System.out.println( '"' + $code + "\" matches \"" + $key.getKey() + '"');
  end

(3) If you absolutely want to have the potential matches in the rule
text you can use a helper class Multikey
  public class Multikey {
    private static Map<String,String> field2key = new HashMap<String,String>();
    public static boolean matches( String field, String... keys ){
        for( String key: keys ){
	    if( field.contains( key ) ){
		field2key.put( field, key );
                return true;
	    }
	}
        return false;
    }
    public static String matchingKey( String field ){
	return field2key.get( field );
    }
  }
and the rule would be:
  rule r2
  when
    Transaction( $code: code )
    eval( Multikey.matches( $code, "foo", "bar", "plan" ) )
  then
    System.out.println( '"' + $code + "\" matches \"" +
Multikey.matchingKey( $code ) + '"' );
  end
Some strategy for removing Map entries may have to be devised; that
would depend on the application scenario.

-W



On 05/01/2013, Jeremy Ary <jeremy.ary at gmail.com> wrote:
> Reading it back over, I can simplify this a bit if we're solely dealing
> with strings...
>
> ...
>
> public class Transaction {
>
>         private String field;
>
>         // ... getter and setter for field, as well as all your other
> methods in transaction, just showing this to say I'm assuming 'field' to be
> of type String
> }
>
> rule "find value substring match"
> when
>     $s : String ( )
>     $t : Transaction( field.contains($s) )
> then
>     sendAlert("Transaction " + $t.getName() + "matches criteria: " + $s);
> end
>
> ...
>
> session.insert(transaction);
> for (int i = 0; i < listOfUserValueStrings.length; i++) {
>      session.insert(listOfUserValueStrings[i];
> }
>
>
>
> On Sat, Jan 5, 2013 at 1:29 PM, Jeremy Ary <jeremy.ary at gmail.com> wrote:
>
>> If your matcher doesn't equate to a boolean value, I don't think that
>> condition will evaluate as you suspect it will. Functions in your
>> conditions isn't going to be as clean or easy as you suspect. Consider
>> inserting the user-supplied values into your session and matching with a
>> rule:
>>
>> ...
>> public class Transaction {
>>
>>         private String field;
>>
>>         // ... getter and setter for field, as well as all your other
>> methods in transaction, just showing this to say I'm assuming 'field' to
>> be
>> of type String
>> }
>>
>> ...
>>
>> public class Value {
>>
>> private String value;
>>
>> public String getValue() {
>> return value;
>>  }
>>
>> public void setValue(String value) {
>>  this.value = value;
>> }
>> }
>>
>> ...
>>
>> rule "find value substring match"
>> when
>>     Value ( $v : value )
>>     $t : Transaction( field.contains($v) )
>> then
>>     sendAlert("Transaction " + $t.getName() + "matches criteria: " + $v);
>> end
>>
>> ...
>>
>> session.insert(transaction);
>> for (int i = 0; i < listOfUserValues.length; i++) {
>>      session.insert(listOfUserValues[i];
>> }
>>
>>
>> On Sat, Jan 5, 2013 at 12:29 PM, bdolbeare <bdolbeare at yahoo.com> wrote:
>>
>>> Suppose we have a Transaction object with a String field.  Users want to
>>> create a rule through our application that says alert me whenever the
>>> value
>>> of that field contains a value in a list of values provided in the rule.
>>> It's easy enough to write this type of rule and send an alert; however,
>>> it
>>> would be helpful to include the value from the list that matched.
>>>
>>> The only way I can think to do this type of thing is to create a
>>> function
>>> somewhere that checks if the field contains any of the values in the
>>> user
>>> list and if so return that value.  Then call that function in the rule
>>> condition and bind the result.  Something like what follows:
>>>
>>>
>>> public class ExternalMatcher
>>> {
>>>   public static String contains(String field, String...list)
>>>   {
>>>   // return the first string that satisfies the contains logic or null
>>> if
>>> no
>>> strings succeed
>>>   }
>>> }
>>>
>>> rule "test"
>>> when
>>> Transaction( $matchedValue : ExternalMatcher.contains(field, "value1",
>>> "value2", "value3") != null)
>>> then
>>> sendAlert("I found a transaction that matched your criteria because
>>> field
>>> foo equals: " + $matchedValue);
>>> end
>>>
>>>
>>>
>>>
>>>
>>> --
>>> View this message in context:
>>> http://drools.46999.n3.nabble.com/Finding-matching-values-in-composite-constraint-tp4021343p4021346.html
>>> Sent from the Drools: User forum mailing list archive at Nabble.com.
>>> _______________________________________________
>>> rules-users mailing list
>>> rules-users at lists.jboss.org
>>> https://lists.jboss.org/mailman/listinfo/rules-users
>>>
>>
>>
>


More information about the rules-users mailing list