[rules-users] Re: How check if all the values in a collection match a criteria
Edson Tirelli
tirelli at post.com
Mon May 19 09:32:51 EDT 2008
Alessandro,
I'm not sure what the problem in your case is, but the syntax I showed
you is the correct syntax for forall, since a forall is nothing more than
not( A() and not( B() ... ) ).
I created a JUnit 3 test case (since people was asking for junit
examples) to reproduce the scenario and it works just fine:
================
public void testExpenses() throws Exception {
Reader source = new InputStreamReader(
getClass().getResourceAsStream( "/expenses.drl" ) );
PackageBuilder builder = new PackageBuilder();
builder.addPackageFromDrl( source );
RuleBase ruleBase = RuleBaseFactory.newRuleBase();
ruleBase.addPackage( builder.getPackage() );
StatefulSession session = ruleBase.newStatefulSession();
ArrayList<ExpenseReport> results = new ArrayList<ExpenseReport>();
session.setGlobal( "results", results );
// CASE 1: empty expense report, should fire
ExpenseReport report1 = new ExpenseReport(new
ArrayList<ExpenseDetail>());
session.insert( report1 );
session.fireAllRules();
assertEquals( 1, results.size() );
assertEquals( report1, results.get( 0 ));
// CASE 2: non-empty expense report, with mixed details, should NOT
fire
ExpenseDetail[] details2 = new ExpenseDetail[] { new
ExpenseDetail(ExpenseType.TAX), new ExpenseDetail( ExpenseType.MEAL ) };
ExpenseReport report2 = new ExpenseReport(Arrays.asList( details2
));
session.insert( report2 );
session.fireAllRules();
assertEquals( 1, results.size() );
// CASE 3: non-empty expense report, with TAX-only details, should
fire
ExpenseDetail[] details3 = new ExpenseDetail[] { new
ExpenseDetail(ExpenseType.TAX), new ExpenseDetail( ExpenseType.TAX ) };
ExpenseReport report3 = new ExpenseReport(Arrays.asList( details3
));
session.insert( report3 );
session.fireAllRules();
assertEquals( 2, results.size() );
assertEquals( report3, results.get( 1 ));
}
==========
package com.sample
global java.util.List results;
rule "Check all expenses"
when
$report: ExpenseReport($expenseDetails: expenseDetails)
not ( $ed : ExpenseDetail() from $expenseDetails and
not ( ExpenseDetail( this == $ed, type == ExpenseType.TAX ) from
$expenseDetails )
)
then
results.add( $report );
end
===========
If you can make this test break showing your problem, I may be able to
help you out.
Thanks for opening the JIRA.
[]s
Edson
2008/5/19 Alessandro Di Bella <aldibella at gmail.com>:
> Hi,
>
> thanks for your help, I created the JIRA as requested (
> http://jira.jboss.org/jira/browse/JBRULES-1611).
>
> The workaround you suggest works only partially, if any of the
> ExpenseDetails is of type ExpenseType.TAX it will fire the rule.
>
> What I would like to do is to fire the rule only if all ExpenseDetails in
> the same report are of type ExpenseType.TAX.
>
> Any help is more than welcome.
>
> Thanks
>
> Alessandro
>
> Edson Tirelli wrote:
>
>>
>> Hmm, now that you mentioned, I see that our parser is limiting the
>> forall() CE, not allowing nested "from" CEs. This is something we should
>> fix, since the limitation is purely a parser limitation.
>>
>> Anyway, for your case, the workaround is simply to use the "raw"
>> forall-equivalence: not( A() and not( B() ) ). So try this:
>>
>> rule "Do Not Process TAX" when
>> $report: ExpenseReport($expenseDetails: expenseDetails)
>> not ( $ed : ExpenseDetails() from $expenseDetails and
>> not ( ExpenseDetails( this == $ed, expenseType ==
>> ExpenseType.TAX ) from $expenseDetails )
>> )
>> then
>> System.out.println("################ It works
>> ##################");
>> insertLogical("Bypass Process");
>> end
>>
>> This is just more verbose than the forall, but it is exactly the same.
>> Once the parser is fixed, you will be able to simply write:
>>
>> rule "Do Not Process TAX" when
>> $report: ExpenseReport($expenseDetails: expenseDetails)
>> forall ( ExpenseDetails( expenseType == ExpenseType.TAX )
>> from $expenseDetails )
>> then
>> System.out.println("################ It works
>> ##################");
>> insertLogical("Bypass Process");
>> end
>>
>> BTW, may I ask you please to open a JIRA so we don't forget to fix this
>> for 5.0?
>>
>> Thanks,
>> Edson
>>
>>
>>
>> 2008/5/18 Alessandro Di Bella <aldibella at gmail.com <mailto:
>> aldibella at gmail.com>>:
>>
>> Hi,
>>
>> I have these two classes:
>>
>> ExpenseReport{
>> Collection<ExpenseDetails> expenseDetails
>> }
>> ExpenseDetails{ ExpenseReport document
>> ExpenseType expenseType
>> }
>>
>> I am trying to create a rule that fires when all the ExpenseDetails in
>> a
>> ExpenseReport are of the same type:
>>
>> rule "Do Not Process TAX" when
>> $report: ExpenseReport($expenseDetails: expenseDetails)
>> forall (
>> ExpenseDetails(document==$report, expenseType
>> == ExpenseType.TAX)
>> ) then
>> System.out.println("################ It works
>> ##################");
>> insertLogical("Bypass Process");
>> end
>>
>> For some reasons, it fires regardless that value of
>> ExpenseDetails.expenseType.
>>
>> I just started with drools and any help i more than welcome.
>>
>> Thanks
>>
>> _______________________________________________
>> rules-users mailing list
>> rules-users at lists.jboss.org <mailto:rules-users at lists.jboss.org>
>> https://lists.jboss.org/mailman/listinfo/rules-users
>>
>>
>>
>>
>> --
>> Edson Tirelli
>> JBoss Drools Core Development
>> Office: +55 11 3529-6000
>> Mobile: +55 11 9287-5646
>> JBoss, a division of Red Hat @ www.jboss.com <http://www.jboss.com>
>>
>>
>> ------------------------------------------------------------------------
>>
>> _______________________________________________
>> rules-users mailing list
>> rules-users at lists.jboss.org
>> https://lists.jboss.org/mailman/listinfo/rules-users
>>
>
> _______________________________________________
> rules-users mailing list
> rules-users at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/rules-users
>
--
Edson Tirelli
JBoss Drools Core Development
Office: +55 11 3529-6000
Mobile: +55 11 9287-5646
JBoss, a division of Red Hat @ www.jboss.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/rules-users/attachments/20080519/31ab2bc7/attachment.html
More information about the rules-users
mailing list