Hi Edson,
Here is the details:
#------ rule -------
rule "input_check"
salience 9999;
when
(Edge.MINUS) ) )
$s : Student($startDate : startDate ->(utilService.dateWithin($startDate,(new
Date()),7, utilService.UNIT_DAY)),
$readTimes : readTimes,
$dailyHours : dailyHours,
$examDate : examDate,
$reExamTimes : reExamTimes,
$englishLevel: englishLevel,
$targetLevel: targetLevel);
eval(($dailyHours == null) || ($readTimes == null) || ($examDate == null)
|| ($reExamTimes == null) || ($englishLevel == null) || ($targetLevel ==
null) );
then
$s.store("ACTION_2_5",$readTimes == null ? "readTime" : null);
end
#---- sample codes -----
public class AbstractThreadBizRuleService extends Observable implements
Runnable, IBizRuleService {
...
public void execute() {
WorkingMemory workingMemory = ruleBase.newWorkingMemory();
WorkingMemoryFileLogger logger = new WorkingMemoryFileLogger(
workingMemory);
logger.setFileName("log/"+this.getName());
...
workingMemory.fireAllRules();
logger.writeToDisk();
}
public class Student extends Party implements Serializable {
/**
*
*/
private static final long serialVersionUID = 2497728027041604203L;
private String name;
private Integer age;
private Integer readTimes;
private Date examDate;
private Date startDate;
private Integer englishLevel;
private Integer reExamTimes;
private Integer dailyHours;
private Integer targetLevel;
private Set exams;
public Student(){
super();
}
// getter/setter.......
}
#---- exception ------
Exception in thread "Thread-9" java.lang.NullPointerException
at org.drools.base.beans.Student$getReadTimes.getValue(Unknown Source)
at org.drools.base.ClassFieldExtractor.getValue(ClassFieldExtractor.java
:79)
at org.drools.rule.Declaration.getValue(Declaration.java:156)
at org.drools.audit.WorkingMemoryLogger.extractDeclarations(
WorkingMemoryLogger.java:227)
at org.drools.audit.WorkingMemoryLogger.beforeActivationFired(
WorkingMemoryLogger.java:188)
at org.drools.event.AgendaEventSupport.fireBeforeActivationFired(
AgendaEventSupport.java:98)
at org.drools.common.DefaultAgenda.fireActivation(DefaultAgenda.java:429)
at org.drools.common.DefaultAgenda.fireNextItem(DefaultAgenda.java:411)
at org.drools.common.AbstractWorkingMemory.fireAllRules(
AbstractWorkingMemory.java:350)
at org.drools.common.AbstractWorkingMemory.fireAllRules(
AbstractWorkingMemory.java:333)
at AbstractThreadBizRuleService.execute(AbstractThreadBizRuleService.java
:198)
at AbstractThreadBizRuleService.run(AbstractThreadBizRuleService.java:70)
at java.lang.Thread.run(Thread.java:595)
Thanks!
Best Regards
Weily
On 11/25/06, Edson Tirelli <[EMAIL PROTECTED]> wrote:
Weily,
I'm sorry, but the stack trace does not say much to me... can you
provide more details? rule, exception message, etc?
[]s
Edson
weily li wrote:
> Hi Edson,
> Thanks!
> Your second solution works well!
>
> Here is an exception:
> when declaring workingMemory Logger:
> WorkingMemoryFileLogger logger = new WorkingMemoryFileLogger(
> workingMemory);
> logger.setFileName("log/"+this.getName());
>
> The rule will throw Exception:
> at org.drools.base.<package>Student$getReadTimes.getValue(Unknown
Source)
> at
> org.drools.base.ClassFieldExtractor.getValue(ClassFieldExtractor.java
:79)
> at org.drools.rule.Declaration.getValue(Declaration.java :156)
> at
> org.drools.audit.WorkingMemoryLogger.extractDeclarations(
WorkingMemoryLogger.java:227)
> at
> org.drools.audit.WorkingMemoryLogger.beforeActivationFired(
WorkingMemoryLogger.java:188)
> at org.drools.event.AgendaEventSupport.fireBeforeActivationFired
> (AgendaEventSupport.java:98)
> at org.drools.common.DefaultAgenda.fireActivation(DefaultAgenda.java
:429)
> at org.drools.common.DefaultAgenda.fireNextItem(DefaultAgenda.java:411)
> at org.drools.common.AbstractWorkingMemory.fireAllRules
> (AbstractWorkingMemory.java:350)
> at
> org.drools.common.AbstractWorkingMemory.fireAllRules(
AbstractWorkingMemory.java:333)
>
>
> I don't if it a defect of logging since here Student.getReadTimes()
> will return a Integer.
>
> Thanks
> Happy Thanksgiving Day!
>
> best regards
> Weily
>
>
>
>
>
>
> On 11/24/06, *Edson Tirelli* <[EMAIL PROTECTED]
> <mailto:[EMAIL PROTECTED]>> wrote:
>
> Weily,
>
> Rules are usually seen as a disjunction of conjunctions. So, your
> example would require 3 rules, one for each attribute that may be
> null.
> As a syntax sugar, there exists the OR operator, so you can write a
> single rule (but internally it will continue to be 3 rules:
>
> $s : ( Student( $startDate : startDate ->(...), examDate == null))
||
> Student( $startDate : startDate ->(...), reExamDate ==
> null)) ||
> Student( $startDate : startDate ->(...), dailyHours ==
null)))
>
> Why am I emphasysing that this is just syntax sugar? Because in
the
> above example, if more than one of your attributes is null, the rule
> will fire multiple times (once for each null attribute) as there
> are in
> fact 3 rules internally, one for each logical branch. Also, it will
> affect your variables binding. Please note that I didn't bound the
> null
> attribute as it would be different in each logical branch. So, be
> carefull that top level OR's behavior may cause surprise for those
not
> used to it in rules engines.
> BTW, this is not a JBRules characteristic. Rete Rules engines in
> general behave like that.
>
> So, if the above matches your needed behavior, thats ok.
Otherwise,
> using JBRules 3.0.x you will need to use eval:
>
> $s: Student( $startDate : startDate ->(...),
> $ed : examDate,
> $rd: reExamDate,
> $dh: dailyHours)
> eval( ($ed == null ) || ( $rd == null ) || ($dh == null ) )
>
> I think the above is what you are trying to achieve. In 3.1, the
> difference is that you will be able to put that "eval" inside the
> pattern (without the eval keyword). But the effect is the same...
> it is
> just a bit more optimized:
>
> $s: Student( $startDate : startDate ->(...),
> $ed : examDate,
> $rd: reExamDate,
> $dh: dailyHours,
> ( ($ed == null ) || ( $rd == null ) || ($dh ==
> null ) )
> )
>
> Hope it helps.
>
> []s
> Edson
>
> weily li wrote:
>
> > Thanks Edson!
> >
> > But I still can't find a complete workaround for current biz need:
> > Here Student is a complicate POJO, and there is a one-to-many
> mapping
> > between Student and exam ( we use hibernate as the data access
> layer).
> >
> > The complete biz requirement for the question is:
> > we want to filter out such students, who has started the
> > training in last 7 days, and if he still hasn't submitted all
> detail
> > index information.
> >
> > So I hope there is such a rule:
> > $s : (Student($startDate : startDate
> > ->(utilService.dateWithin($startDate,(new Date()),7,
> > utilService.UNIT_DAY)))
> > && ( Student($examDate :examDate == null)
> > || Student($reExamTimes: reExamTimes == null)
> > || Student($dailyHours : dailyHours == null) ));
> >
> > which will tell us these students,
> > whose startDate is in last 7 days.
> > and at least one of the index,examDate, reExamTimes and
> dailyHours,
> > is null.
> >
> > Could you give more suggestions for it?
> > Thanks!
> >
> > BTW, is there such rule sample which is closer real biz world?
> >
> > Best Regards
> > Weily
> >
> >
> >
> >
> >
> >
> > On 11/24/06, *Edson Tirelli* <[EMAIL PROTECTED]
> <mailto:[EMAIL PROTECTED]>
> > <mailto: [EMAIL PROTECTED] <mailto:[EMAIL PROTECTED]>>> wrote:
> >
> >
> > Weily,
> >
> > When you use AND between patterns, you are saying the
> engine: find
> > one fact that match the first pattern and find another fact
> that
> > matches
> > the second pattern. If you want the same fact to match more
> than one
> > "constraint", simply write all constraints inside the same
> pattern. I
> > guess this is what you are looking for:
> >
> > when
> > $student: Student(examDate == null, $startDate : startDate
> > ->(utilService.dateWithin($startDate,(new Date()),7,
> > utilService.UNIT_DAY)))
> > then
> > println("...")
> > end
> >
> > The above will match each single fact that complies to both
> > constraints.
> >
> > BTW, if you indeed want to match more than one fact using
AND
> > between
> > patterns, you don't need to explicit writing the AND as it
> is already
> > implicit:
> >
> > when
> > $s1 : Student(examDate == null)
> > $s2 : Student($startDate : startDate
> > ->(utilService.dateWithin($startDate,(new Date()),7,
> > utilService.UNIT_DAY))))
> > then
> > println("...")
> > end
> >
> > Above example will match all possible combinations of 2
> facts, as
> > long as the first fact matches the first pattern (and it
> will be bound
> > to variable $s1) and the second fact matches second pattern
(and
> > it will
> > be bound to variable $s2). The above is exactly the same of:
> >
> > when
> > $s1 : Student(examDate == null) AND
> > $s2 : Student($startDate : startDate
> > ->(utilService.dateWithin($startDate,(new Date()),7,
> > utilService.UNIT_DAY ))))
> > then
> > println("...")
> > end
> >
> > Regarding syntax, we are working on parser improvements
> just to
> > avoid
> > any confusion like the one you reported in the first e-mail,
> but the
> > semantics of conditional elements (and, or, not, exists,
> etc) will not
> > change and it is important you understand them.
> >
> > Hope it helps.
> >
> > []s
> > Edson
> >
> > weily li wrote:
> >
> > > Hi ALL,
> > >
> > > Here is several test cases:
> > >
> > > facts feeded: 5 Students.
> > >
> > > 1.
> > > When
> > > Student(examDate == null);
> > > Then
> > > println("..");
> > > <expected>: one line printed out
> > > <result>: one line printed out
> > >
> > > 2.
> > > When
> > > Student($startDate : startDate
> > > ->(utilService.dateWithin($startDate,(new Date()),7,
> > > utilService.UNIT_DAY)))
> > > Then
> > > println("...")
> > > <expected>: three lines printed out
> > > <result>: three lines printed out
> > >
> > > 3.
> > > when
> > > (Student(examDate == null) and Student($startDate :
> startDate
> > > ->(utilService.dateWithin($startDate,(new Date()),7,
> > > utilService.UNIT_DAY))))
> > > then
> > > println("...")
> > > <expected>: one line printed out
> > > <result>: three lines printed out(same as scenario 2)
> > >
> > > 4.
> > > when
> > > $s : (Student(examDate == null) and Student($startDate :
> startDate
> > > ->(utilService.dateWithin($startDate,(new Date()),7,
> > > utilService.UNIT_DAY))))
> > > then
> > > println($s.get....)
> > >
> > > At scenario 4, it should assign the Student which meet all
> > columns to
> > > $s. right?
> > >
> > > Could anyone help explain how to make 'AND' work as
expected?
> > >
> > > Thanks
> > > Best Regards
> > > Weily
> > >
> > >
> > >
> >
> >
> >
> > --
> > ---
> > Edson Tirelli
> > Software Engineer - JBoss Rules Core Developer
> > Office: +55 11 3124-6000
> > Mobile: +55 11 9218-4151
> > JBoss, a division of Red Hat @ www.jboss.com
> <http://www.jboss.com> <http://www.jboss.com>
> >
> > IT executives: Red Hat still #1 for value
> > http://www.redhat.com/promo/vendor/
> <http://www.redhat.com/promo/vendor/>
> >
> >
> >
>
---------------------------------------------------------------------
> > To unsubscribe from this list please visit:
> >
> > http://xircles.codehaus.org/manage_email
> > <http://xircles.codehaus.org/manage_email>
> >
> >
>
>
> --
> ---
> Edson Tirelli
> Software Engineer - JBoss Rules Core Developer
> Office: +55 11 3124-6000
> Mobile: +55 11 9218-4151
> JBoss, a division of Red Hat @ www.jboss.com <http://www.jboss.com>
>
> IT executives: Red Hat still #1 for value
> http://www.redhat.com/promo/vendor/
>
>
>
---------------------------------------------------------------------
> To unsubscribe from this list please visit:
>
> http://xircles.codehaus.org/manage_email
>
>
--
---
Edson Tirelli
Software Engineer - JBoss Rules Core Developer
Office: +55 11 3124-6000
Mobile: +55 11 9218-4151
JBoss, a division of Red Hat @ www.jboss.com
IT executives: Red Hat still #1 for value
http://www.redhat.com/promo/vendor/
---------------------------------------------------------------------
To unsubscribe from this list please visit:
http://xircles.codehaus.org/manage_email