[rules-users] NullPointerException when using Drools rule template

Roger Smith rogersmith1711 at gmail.com
Thu Nov 11 04:14:11 EST 2010


Hi Wolfgang,
We were able to get the code to work based on your previous suggestions.
Your following recommendation is definitely more elegant and complete. Many
thanks for following up. Most grateful!

Roger


On Thu, Nov 11, 2010 at 12:56 AM, Wolfgang Laun <wolfgang.laun at gmail.com>wrote:

> [Note: I see that template parsing is rather wobbly. The JIRA has to
> be fixed in
> org.drools.template.parser.DefaultTemplateContainer, and I think there are
> other
> "holes" in the parseTemplate method.]
>
> Roger,
>
> while my previous suggestion avoids the NPE, it may not be the
> adequate solution for your situation. I see that you have several
> rules which classify ContractRule w.r.t. season and hourType. These do
> not rely on template parameters, and they would be better off in a
> separate simple .drl file.
>
> Now let's look at your reduced original template
>
> template contract_rate
>  rule "Summer on peak primary rate"
>  when
>    $r : ContractRule( season == "summer" && hourType == "onPeak" &&
> type == "primary")
>  then
>    $r.setRate(@{summerOnPeakPrimaryRate});
>  end
> end template
>
> From the other parameter names I can imagine that you have similar
> hand-written rules for all
> other combinations of these three field values; templating is just
> used to insert the rate values
> programmatically rather than hand-coded. (I suppose good old
> properties would solve this task
> quite well!)
>
> But templating may be used to save you the trouble of writing and
> maintaining all the set-rate
> rules themselves. (Just imagine of the Contractor comes up with the
> notion of adding a rebate
> for groups: You'll have to double your rules manually!)
>
> Here's the template to achieve everything with a single rule:
>
> template header
> theSeason
> theHour
> theType
> theRate
>
> package resource
> import resource.ContractRule
> template contract_rate
> rule "@{theSeason} @{theHour} @{theType} rate"    ### DO NOT INDENT
> THIS LINE. ARRGH!
>  when
>    $r : ContractRule( season == "@{theSeason}" && hourType ==
> "@{theHour}" && type == "@{theType}")
>  then
>    $r.setRate(@{theRate});
>  end
> end template
>
> Now you'll have to use more than one parameter map - one for each such
> combination. [[Aside: Adding
> the "group" rebate can be done by
> * adding the template parameter,
> * adding the restriction to the template rule
> * extending the rule name
> * extend addParamMap
> * write the additional addParamMap() calls ]]
>
> Collection<Map<String,Object>> paramMaps = new
> ArrayList<Map<String,Object>>();
>
>   private void addParamMap( String season, String hour, String type, int
> rate ){
>      Map<String,Object> params = new HashMap<String,Object>();
>      params.put( "theSeason", season );
>     params.put( "theHour",   hour );
>     params.put( "theType",   type );
>     params.put( "theRate",   rate );
>     paramMaps.add( params );
>  }
>
>    addParamMap( "summer", "onPeak",   "primary",   299 );
>    addParamMap( "summer", "onPeak",   "secondary", 524 );
>    addParamMap( "summer", "semiPeak", "primary",   176 );
>    addParamMap( "summer", "semiPeak", "secondary", 305 );
>    addParamMap( "summer", "offPeak",  "primary",   139 );
>    addParamMap( "summer", "offPeak",  "secondary", 243 );
>    addParamMap( "winter", "onPeak",   "primary",   249 );
>    addParamMap( "winter", "onPeak",   "secondary", 438 );
>    addParamMap( "winter", "semiPeak", "primary",   176 );
>    addParamMap( "winter", "semiPeak", "secondary", 305 );
>    addParamMap( "winter", "offPeak",  "primary",   139 );
>    addParamMap( "winter", "offPeak",  "secondary", 243 );
>
>    String drl = converter.compile(paramMaps, dis);
>
> And here we go: This is the generated DRL text:
>
> package resource
> import resource.ContractRule
>
> rule "winter offPeak secondary rate"
>  when
>    $r : ContractRule( season == "winter" && hourType == "offPeak" &&
> type == "secondary")
>  then
>    $r.setRate(243);
>  end
>
> rule "winter offPeak primary rate"
>  when
>    $r : ContractRule( season == "winter" && hourType == "offPeak" &&
> type == "primary")
>  then
>    $r.setRate(139);
>  end
>
> rule "winter semiPeak secondary rate"
>  when
>    $r : ContractRule( season == "winter" && hourType == "semiPeak" &&
> type == "secondary")
>  then
>    $r.setRate(305);
>  end
>
> rule "winter semiPeak primary rate"
>  when
>    $r : ContractRule( season == "winter" && hourType == "semiPeak" &&
> type == "primary")
>  then
>    $r.setRate(176);
>  end
>
> rule "winter onPeak secondary rate"
>  when
>    $r : ContractRule( season == "winter" && hourType == "onPeak" &&
> type == "secondary")
>  then
>    $r.setRate(438);
>  end
>
> rule "winter onPeak primary rate"
>  when
>    $r : ContractRule( season == "winter" && hourType == "onPeak" &&
> type == "primary")
>  then
>    $r.setRate(249);
>  end
>
> rule "summer offPeak secondary rate"
>  when
>    $r : ContractRule( season == "summer" && hourType == "offPeak" &&
> type == "secondary")
>  then
>    $r.setRate(243);
>  end
>
> rule "summer offPeak primary rate"
>  when
>    $r : ContractRule( season == "summer" && hourType == "offPeak" &&
> type == "primary")
>  then
>    $r.setRate(139);
>  end
>
> rule "summer semiPeak secondary rate"
>  when
>    $r : ContractRule( season == "summer" && hourType == "semiPeak" &&
> type == "secondary")
>  then
>    $r.setRate(305);
>  end
>
> rule "summer semiPeak primary rate"
>  when
>    $r : ContractRule( season == "summer" && hourType == "semiPeak" &&
> type == "primary")
>  then
>    $r.setRate(176);
>  end
>
> rule "summer onPeak secondary rate"
>   when
>    $r : ContractRule( season == "summer" && hourType == "onPeak" &&
> type == "secondary")
>  then
>    $r.setRate(524);
>  end
>
> rule "summer onPeak primary rate"
>   when
>    $r : ContractRule( season == "summer" && hourType == "onPeak" &&
> type == "primary")
>  then
>     $r.setRate(299);
>  end
>
> -W
>
> 2010/11/10 Roger Smith <rogersmith1711 at gmail.com>:
> > Wolfgang -
> > Thank you!!
> >
> > On Wed, Nov 10, 2010 at 11:07 AM, Wolfgang Laun <wolfgang.laun at gmail.com
> >
> > wrote:
> >>
> >> If you move the
> >>  template contract_rate
> >> up in front of the first rule "holiday july 4th" the NPE is gone. I
> >> haven't been able to validate the (presumably) generated rule set, but
> >> you should be able to do that now.
> >>
> >> Nevertheless, this warrants a JIRA, which I'll create forthwith. Also,
> >> the docs should indicate what is permitted up front, preceding the
> >> "template" statement.
> >>
> >> -W
> >>
> >>
> >> 2010/11/10 Roger Smith <rogersmith1711 at gmail.com>:
> >> > Wolfgang,
> >> >
> >> > I have enclosed the template. For debugging purpose, I have removed
> all
> >> > but
> >> > one rule.
> >> >
> >> > Thanks,
> >> >
> >> > Roger
> >> >
> >> > - O -
> >> >
> >> > template header
> >> > summerOnPeakPrimaryRate
> >> > summerOnPeakSecondaryRate
> >> > summerSemiPeakPrimaryRate
> >> > summerSemiPeakSecondaryRate
> >> > summerOffPeakPrimaryRate
> >> > summerOffPeakSecondaryRate
> >> > winterOnPeakPrimaryRate
> >> > winterOnPeakSecondaryRate
> >> > winterSemiPeakPrimaryRate
> >> > winterSemiPeakSecondaryRate
> >> > winterOffPeakPrimaryRate
> >> > winterOffPeakSecondaryRate
> >> >
> >> > package tradex.contract.sde
> >> >
> >> > import tradex.process.ruler.server.ContractRule
> >> >
> >> > rule "holiday july 4th"
> >> > when
> >> >   $r : ContractRule( year == 2010 && month == 7 && day == 4 && holiday
> >> > ==
> >> > false)
> >> > then
> >> >   modify($r){
> >> >     setHoliday(true)
> >> >   }
> >> > end
> >> >
> >> > rule "holiday xmas"
> >> > when
> >> >   $r : ContractRule( year == 2010 && month == 12 && day == 25 &&
> holiday
> >> > ==
> >> > false)
> >> > then
> >> >   modify($r){
> >> >     setHoliday(true)
> >> >   }
> >> > end
> >> >
> >> > rule "Season summer"
> >> > when
> >> >   $r : ContractRule( dayOfYear >= 121 && dayOfYear <= 273 && season ==
> >> > "undefined")
> >> > then
> >> >   modify($r){
> >> >     setSeason("summer")
> >> >   }
> >> > end
> >> >
> >> > rule "Season winter"
> >> > when
> >> >   $r : ContractRule( (dayOfYear >= 274 || dayOfYear <= 120) && season
> ==
> >> > "undefined")
> >> > then
> >> >   modify($r){
> >> >     setSeason("winter")
> >> >   }
> >> > end
> >> >
> >> >
> >> > rule "On peak hour"
> >> > when
> >> >   $r : ContractRule( holiday == false && dayOfWeek >= 1 && dayOfWeek
> <=
> >> > 6
> >> > && hourOfDay >= 1400 && hourOfDay <= 2000 &&
> >> >   hourType == "undefined")
> >> > then
> >> >   modify($r){
> >> >     setHourType("onPeak")
> >> >   }
> >> >
> >> > end
> >> >
> >> > rule "Semi peak hour"
> >> > when
> >> >   $r : ContractRule( holiday == false && dayOfWeek >= 1 && dayOfWeek
> <=
> >> > 6
> >> > && (hourOfDay >= 600 && hourOfDay < 1400 ||
> >> >   hourOfDay > 2000 && hourOfDay <= 2200) && hourType == "undefined")
> >> > then
> >> >   modify($r){
> >> >     setHourType("semiPeak")
> >> >   }
> >> > end
> >> >
> >> > rule "Off peak hour"
> >> > when
> >> >   $r : ContractRule( (holiday == true ||  dayOfWeek == 7  || hourOfDay
> <
> >> > 600
> >> > || hourOfDay > 2200) && hourType == "undefined" )
> >> > then
> >> >   modify($r){
> >> >     setHourType("offPeak")
> >> >   }
> >> > end
> >> >
> >> > template contract_rate
> >> >   rule "Summer on peak primary rate"
> >> >   when
> >> >     $r : ContractRule( season == "summer" && hourType == "onPeak" &&
> >> > type ==
> >> > "primary")
> >> >   then
> >> >     $r.setRate(@{summerOnPeakPrimaryRate});
> >> >   end
> >> > end template
> >> >
> >> >
> >> >
> >> >
> >> > 2010/11/9 Wolfgang Laun <wolfgang.laun at gmail.com>
> >> >>
> >> >> Seeing the template .drl would help to resolve this. Are all
> >> >> @{parameter}s
> >> >> declared in the template header?
> >> >> -W
> >> >>
> >> >> 2010/11/9 Roger Smith <rogersmith1711 at gmail.com>
> >> >>>
> >> >>>
> >> >>> All -
> >> >>>
> >> >>> I tried out Drools rule template with a with a proptotype app.
> Drools
> >> >>> is
> >> >>> throwing NullPointerException as below. I would much appreciate if
> >> >>> someone
> >> >>> on this list can help.
> >> >>> java.lang.NullPointerException
> >> >>>     at
> >> >>>
> >> >>>
> org.drools.template.parser.DefaultTemplateColumn.createCellCondition(DefaultTemplateColumn.java:68)
> >> >>>     at
> >> >>>
> >> >>>
> org.drools.template.parser.DefaultTemplateColumn.addCondition(DefaultTemplateColumn.java:91)
> >> >>>     at
> >> >>>
> >> >>>
> org.drools.template.parser.DefaultTemplateRuleBase.createColumnConditions(DefaultTemplateRuleBase.java:105)
> >> >>>     at
> >> >>>
> >> >>>
> org.drools.template.parser.DefaultTemplateRuleBase.createTemplateRule(DefaultTemplateRuleBase.java:98)
> >> >>>     at
> >> >>>
> >> >>>
> org.drools.template.parser.DefaultTemplateRuleBase.getDTRules(DefaultTemplateRuleBase.java:85)
> >> >>>     at
> >> >>>
> >> >>>
> org.drools.template.parser.DefaultTemplateRuleBase.<init>(DefaultTemplateRuleBase.java:64)
> >> >>>     at
> >> >>>
> >> >>>
> org.drools.template.parser.TemplateDataListener.<init>(TemplateDataListener.java:76)
> >> >>>     at
> >> >>>
> >> >>>
> org.drools.template.parser.TemplateDataListener.<init>(TemplateDataListener.java:52)
> >> >>>     at
> >> >>>
> >> >>>
> org.drools.template.ObjectDataCompiler.compile(ObjectDataCompiler.java:44)
> >> >>>
> >> >>>
> >> >>> Here is my code
> >> >>>
> >> >>>         KnowledgeBuilder kBuilder =
> >> >>> KnowledgeBuilderFactory.newKnowledgeBuilder();
> >> >>>         ObjectDataCompiler converter = new ObjectDataCompiler();
> >> >>>         InputStream dis = new FileInputStream( new File(
> >> >>> "/home/pranab/Projects/gridx/ct11_1.drl" ) );
> >> >>>         if (null == dis){
> >> >>>           System.out.println("null rule template stream");
> >> >>>           return;
> >> >>>         }
> >> >>>
> >> >>>         Collection<Map<String,Object>> paramMaps = new
> >> >>> ArrayList<Map<String,Object>>();
> >> >>>
> >> >>>         Map<String,Object> params = new HashMap<String,Object>();
> >> >>>
> >> >>>         params.put("summerOnPeakPrimaryRate", new Integer(299));
> >> >>>         params.put("summerOnPeakSecondaryRate", new Integer(524));
> >> >>>         params.put("summerSemiPeakPrimaryRate", new Integer(176));
> >> >>>         params.put("summerSemiPeakSecondaryRate", new Integer(305));
> >> >>>         params.put("summerOffPeakPrimaryRate", new Integer(139));
> >> >>>         params.put("summerOffPeakSecondaryRate", new Integer(243));
> >> >>>         params.put("winterOnPeakPrimaryRate", new Integer(249));
> >> >>>         params.put("winterOnPeakSecondaryRate", new Integer(438));
> >> >>>         params.put("winterSemiPeakPrimaryRate", new Integer(176));
> >> >>>         params.put("winterSemiPeakSecondaryRate", new Integer(305));
> >> >>>         params.put("winterOffPeakPrimaryRate", new Integer(139));
> >> >>>         params.put("winterOffPeakSecondaryRate", new Integer(243));
> >> >>>         paramMaps.add(params);
> >> >>>
> >> >>>         String drl = converter.compile(paramMaps, dis);
> >> >>>         Reader rdr = new StringReader( drl );
> >> >>>         kBuilder.add( ResourceFactory.newReaderResource(rdr),
> >> >>> ResourceType.DRL);
> >> >>>
> >> >>>
> >> >>> The line in blue is throwing the exception. This code is very
> similar
> >> >>> to
> >> >>> the example code in Drools Expert guide.
> >> >>>
> >> >>> Best,
> >> >>>
> >> >>> Roger
> >> >>>
> >> >>> _______________________________________________
> >> >>> 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
> >> >>
> >> >
> >> >
> >> > _______________________________________________
> >> > 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
> >
> >
> > _______________________________________________
> > rules-users mailing list
> > rules-users at lists.jboss.org
> > https://lists.jboss.org/mailman/listinfo/rules-users
> >
> >
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/rules-users/attachments/20101111/69fb6a86/attachment.html 


More information about the rules-users mailing list