リファレンス agenda-groupとauto-focus
agendaというのはルールのマッチングなど実行制御をおこなう中心人物で、agenda-groupはその実行のパーティション的なものになります。今までのサンプルでは特に記述してませんでしたがその場合は"Main"というagenda-groupの上で実行されていたのです。Mainが一番の実行制御のrootになります。パーティション、もしくはアクティビティ図、BPMNのスイムレーンに近く、もともとはその制御を目的として用意された宣言になる。ただ最近のDroolsではDroolsFlowというのがあり使い方によってはあまり差がない他の宣言方法もあったりします。DroolsFlowについてはまたおいおい紹介しまっす。
ということでagenda-groupの例です。
import com.sample.Person; rule "left" agenda-group "left" when $p : Person() then System.out.println("左通行"); end rule "middle" when $p : Person() then System.out.println("真ん中"); retract($p); end rule "right1" agenda-group "right" auto-focus true when $p : Person() then System.out.println("右通行1"); end rule "right2" agenda-group "right" when $p : Person() then System.out.println("右通行2"); end
これを実行すると右通行2->右通行1->真ん中と出力されるよん。
まず、Mainグループよりauto-focusが宣言されているグループ"right"が実行パスとして制御が遷移します。前にも書いたとおり、LIFOなのでそのグループではright2->right1のルールの順で実行され、"Main"のグループに制御が戻ります。(この場合では何も宣言していない"middle"のルールがMainグループになり、このような出力順序になります。この時、Leftは実行されないです。ここがミソです。基本的にはひとつのグループのみが実行されるようになっています(本当はMainだけの実行なんだけどauto-focusでrightグループが実行制御をもぎとった感じです)
じゃ、フォーカスの制御って何ができるかというと「drools.setFocus(グループ名)」をthenの中に記述することで制御をコントロールできます。
上記の例でいうとright2のルールのthenに
System.out.println("右通行1"); drools.setFocus("left");
と記述して実行すると右通行2->右通行1->左通行->真ん中と制御されることがわかりますよ。ちなみに、ちなみにauto-focusを複数宣言した場合、何パターンか試したかぎり(そこはソースをまだおいきれてない)LIFOでみてるようです。