せっかくEclipseIDEをインストールしたので、IDEを使っていくつかサンプルプログラムを動かしてみましょう。Droolsの概念的な動きについてはすでにDrools 4.0 入門4 (Droolsの動き)で書いているのでそちらを参照するとして、ここでは具体的なプログラムを見ていきましょう。
サンプルプログラムの仕様0
まずはごく簡単に・・・スーパーでのキャンペーン割引ということで
・5000円以上お買い上げの場合一律に500円を割引する
というルールがあったとしましょう。以下でこのルールを具体化します。それと同時にルールを動かすための準備やデバッグの情報の表示についてなどについても見てみましょう。
プログラム
ルールを適用していくためには、そのための準備が必要です。Droolsの動き(Drools 4.0 入門4 (Droolsの動き))でも説明したワーキングメモリ(WorkingMemory)やルールベース(RuleBase)の設定、それからワーキングメモリの要素となるファクト(fact)の構造の宣言などが必要となります。
ではプログラムにそって見ていきましょう。 まずはルールを実行する前の準備としてルールベース、ワーキングメモリの環境を設定します。Droolsでは、まずKnowledgeBuilderを作り、そこへルールファイルをコンパイルして追加します(ここでは追加するルールファイルは一つですが、複数のルールファイルを追加することもできます)。ルールを追加し終えたKnowledgeBuilderからパッケージを取得し、さらにパッケージをKnowledgeBaseにデプロイすることで、いわゆるルールベースが有効になります。さらにこのKnowledgeBase(ルールベース)からStatefulセッションを作成することでワーキングメモリも有効となります。
これで最低限の準備はできたわけですが、今回はさらにIDEでルールの実行の様子(Agendaの内容、WorkingMemoryの内容)を見るためにそれぞれのEventListenerを追加し、さらにAuditログの設定も追加しておきましょう。
DroolsTest1.java
package jp.co.iluminado.example;
import java.util.Collection; import org.drools.KnowledgeBase; /** public static final void main(final String[] args) throws Exception { // ルールファイルをコンパイルしてKnowledgeBuilderへ追加する // 上記コンパイル時のエラー処理 // KnowledgeBuilderからコンパイル済みのパッケージを取得する // 取得したパッケージをKnowledgebaseに追加する(パッケージのデプロイ) // Statefulセッションを作成 // Agenda,WorkingMemoryのView表示準備 // Auditログのセット // ルールの実行 // Auditログを閉じる // Statefulセッションなので、実行が終わったところでdisposeして領域を開放する public static class Sales { private long sales; // 売り上げ public int getStatus() { public void setStatus(int status) { public void setSales(long sales) { public long getSales() { } } |
さて、ここではルールの実行に行く前に、ファクト(fact)をあらわすクラスSalesを見ておきましょう。売り上げの価格をあらわすsalesというフィールドと、割引を未適用か適用済かをあらわすstatusというフィールドを持つクラスです。 さらに、ファクトで用いるクラスはJavaBeansになるので各フィールドに対して、accessorメソッドが追加されています。
DroolsTest1.drl
package jp.co.iluminado.example; import jp.co.iluminado.example.DroolsTest1.Sales; rule “Discount” |
次にルールを見てみましょう。
・5000円以上お買い上げの場合一律に500円を割引する
という仕様に対しwhen節(条件節)は、ワーキングメモリ中にSalesファクトがあって、そのファクトのstatusが未適用(NOT_APPLIED)であり、salesが5000円以上であると解釈できます。また$s,$salesValueは、それぞれマッチしたSalesファクトに紐づく変数、salesフィールドに紐づく変数でthen節で参照されます。then節ではマッチしたSalesファクトに対して、salesを500円割引して、statusを適用済(APPLIED)にセットしてファクトをupdateします。
最後にルールの実行部分を。
DroolsTest1.java(一部を再録)
// ルールの実行 final Sales sale = new Sales(); sale.setSales(6000); sale.setStatus(Sales.NOT_APPLIED); ksession.insert(sale); ksession.fireAllRules(); // Auditログを閉じる // Statefulセッションなので、実行が終わったところでdisposeして領域を開放する |
salesを6000円に設定し、statusを未適用の状態にしてワーキングメモリへinsertします。ここでfireAllRules()を動かせばルールが実行されます。実行が終わったところでAuditログを閉じ、セッションも閉じて領域を開放します。
ルールプロジェクトの作成
まずは、Droolsのプロジェクトを作成して、上記のファイルを作っておきましょう。Droolsのプロジェクト(ここでは、DroolsTest1としておきます)を作成して、DroolsTest1.Javaファイルは、javaのソースの場所にパッケージjp.co.iluminado.exampleを作って、そこに作っておきます。DroolsTest1.drlファイルは、ルールのソースの場所で、右クリックして新しいRule Resourceを作成します。
パッケージ名とルールファイル(drlファイル)名を入力してFinishを押すと、Drlファイルのスケルトンができます。ここにDroolsTest1.drlの中身を記述しましょう。
最後にAuditログを出力するフォルダを作っておかないといけません。作っておかないと実行時にエラーになります。DroolsTest1のプロジェクトを右クリックして、直下に log というフォルダを作っておきましょう。
ルールの実行
ここで、DroolsTest1.javaを動かしてみましょう。
6000円から500円割引となった結果System.outに”5500″が表示されています。Agenda、WorkingMemoryのイベントリスナーが設定されているので、System.errにその情報が表示されています。 また、DroolsのAuditビューを表示させておく(Windowメニューのビューの表示(Show View)からできます)と、Auditログの内容が表示されます。
(表示されない場合は、ビューの右上のOpen Logボタンを押して、Auditログファイル(DroolsTest1.log)を選択してください。)
WorkingMemory、Agendaの表示実行
さらにWorkingMemoryやAgendaの中身を表示させるために、Debugのパースペクティブにし(windowメニューで変更できます) fireAllRules()の行の左端をダブルクリックしてブレークポイントをつけておきましょう。 この状態で、Drools ApplicationとしてDebug実行をすると、ワーキングメモリにファクトを追加した実行直前の状態で一度ブレークします。
実際にやってみましょう。ブレークしたところでWorkingMemoryビューを表示し、右上のVariablesビューでksession変数を選択するとワーキングメモリの中身が表示されます。
フィールドsalesの値が6000と設定されたSalesというファクトができていることがわかります。
また、Agendaビューを表示し、同様にksession変数を選択するとアジェンダの中身が表示されます。
アジェンダに見えているActivationの中身がルール”Discount”とそれにマッチしたSalesファクトの組み合わせになっていることにご注意ください。ルールを発火させることで実行が始まりますので、引き続き実行させてみましょう。
コンソールにさきほどと同じ結果が表示されているのがわかります。