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