Drools-sample-drools-program

提供:Dev Guides
移動先:案内検索

Drools-サンプルDroolsプログラム

この章では、次の問題ステートメントのためのDroolsプロジェクトを作成します-

'__都市と製品の種類(都市と製品の組み合わせ)に応じて、その都市に関連する地方税を調べます。'__

Droolsプロジェクト用に2つのDRLファイルを作成します。 2つのDRLファイルは、検討中の2つの都市(PuneとNagpur)と4つのタイプの製品(食料品、医薬品、時計、高級品)を意味します。

  • 両都市の医薬品に対する税金はゼロとみなされます。
  • 食料品については、プネでRs 2、ナグプールでRs 1の税を想定しています。

同じ販売価格を使用して、異なる出力を示しました。 アプリケーションですべてのルールが実行されることに注意してください。

ここに各itemTypeを保持するモデルがあります-

package com.sample;
import java.math.BigDecimal;
public class ItemCity {
   public enum City {
      PUNE, NAGPUR
   }
   public enum Type {
      GROCERIES, MEDICINES, WATCHES, LUXURYGOODS
   }
   private City purchaseCity;
   private BigDecimal sellPrice;
   private Type typeofItem;
   private BigDecimal localTax;

   public City getPurchaseCity() {
      return purchaseCity;
   }
   public void setPurchaseCity(City purchaseCity) {
      this.purchaseCity = purchaseCity;
   }
   public BigDecimal getSellPrice() {
      return sellPrice;
   }
   public void setSellPrice(BigDecimal sellPrice) {
      this.sellPrice = sellPrice;
   }
   public Type getTypeofItem() {
      return typeofItem;
   }
   public void setTypeofItem(Type typeofItem) {
      this.typeofItem = typeofItem;
   }
   public BigDecimal getLocalTax() {
      return localTax;
   }
   public void setLocalTax(BigDecimal localTax) {
      this.localTax = localTax;
   }
}

DRLファイル

前述のとおり、ここではPune.drlとNagpur.drlの2つのDRLファイルを使用しました。

Pune.drl

これは、プネ市のルールを実行するDRLファイルです。

//created on: Dec 24, 2014
package droolsexample

//list any import classes here.
import com.sample.ItemCity;
import java.math.BigDecimal;

//declare any global variables here
dialect "java"
rule "Pune Medicine Item"
   when
      item : ItemCity (purchaseCity == ItemCity.City.PUNE,
         typeofItem == ItemCity.Type.MEDICINES)
   then
      BigDecimal tax = new BigDecimal(0.0);
      item.setLocalTax(tax.multiply(item.getSellPrice()));
end

rule "Pune Groceries Item"
   when
      item : ItemCity(purchaseCity == ItemCity.City.PUNE,
         typeofItem == ItemCity.Type.GROCERIES)
   then
      BigDecimal tax = new BigDecimal(2.0);
      item.setLocalTax(tax.multiply(item.getSellPrice()));
end

Nagpur.drl

これは、ナグプール市のルールを実行するDRLファイルです。

//created on: Dec 26, 2014
package droolsexample

//list any import classes here.
import com.sample.ItemCity;
import java.math.BigDecimal;

//declare any global variables here
dialect "java"
rule "Nagpur Medicine Item"
   when
      item : ItemCity(purchaseCity == ItemCity.City.NAGPUR,
         typeofItem == ItemCity.Type.MEDICINES)
   then
      BigDecimal tax = new BigDecimal(0.0);
      item.setLocalTax(tax.multiply(item.getSellPrice()));
end

rule "Nagpur Groceries Item"
   when
      item : ItemCity(purchaseCity == ItemCity.City.NAGPUR,
         typeofItem == ItemCity.Type.GROCERIES)
   then
      BigDecimal tax = new BigDecimal(1.0);
      item.setLocalTax(tax.multiply(item.getSellPrice()));
end

新しい都市が追加される場合、後で任意の数のルールファイルを追加する拡張性を提供するため、都市に基づいてDRLファイルを作成しました。

すべてのルールがルールファイルからトリガーされることを示すために、2つのアイテムタイプ(薬と食料品)を使用しました。薬は非課税であり、食料品は市ごとに課税されます。

テストクラスはルールファイルを読み込み、ファクトをセッションに挿入し、出力を生成します。

Droolstest.java

package com.sample;

import java.math.BigDecimal;
import org.drools.KnowledgeBase;
import org.drools.KnowledgeBaseFactory;
import org.drools.builder.KnowledgeBuilder;
import org.drools.builder.KnowledgeBuilderError;
import org.drools.builder.KnowledgeBuilderErrors;
import org.drools.builder.KnowledgeBuilderFactory;
import org.drools.builder.ResourceType;
import org.drools.io.ResourceFactory;
import org.drools.runtime.StatefulKnowledgeSession;
import com.sample.ItemCity.City;
import com.sample.ItemCity.Type;

/*
  * This is a sample class to launch a rule.
*/

public class DroolsTest {
   public static final void main(String[] args) {
      try {
        //load up the knowledge base
         KnowledgeBase kbase = readKnowledgeBase();
         StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();

         ItemCity item1 = new ItemCity();
         item1.setPurchaseCity(City.PUNE);
         item1.setTypeofItem(Type.MEDICINES);
         item1.setSellPrice(new BigDecimal(10));
         ksession.insert(item1);

         ItemCity item2 = new ItemCity();
         item2.setPurchaseCity(City.PUNE);
         item2.setTypeofItem(Type.GROCERIES);
         item2.setSellPrice(new BigDecimal(10));
         ksession.insert(item2);

         ItemCity item3 = new ItemCity();
         item3.setPurchaseCity(City.NAGPUR);
         item3.setTypeofItem(Type.MEDICINES);
         item3.setSellPrice(new BigDecimal(10));
         ksession.insert(item3);

         ItemCity item4 = new ItemCity();
         item4.setPurchaseCity(City.NAGPUR);
         item4.setTypeofItem(Type.GROCERIES);
         item4.setSellPrice(new BigDecimal(10));
         ksession.insert(item4);

         ksession.fireAllRules();

         System.out.println(item1.getPurchaseCity().toString() + " "
            + item1.getLocalTax().intValue());

         System.out.println(item2.getPurchaseCity().toString() + " "
            + item2.getLocalTax().intValue());

         System.out.println(item3.getPurchaseCity().toString() + " "
            + item3.getLocalTax().intValue());

         System.out.println(item4.getPurchaseCity().toString() + " "
            + item4.getLocalTax().intValue());

      } catch (Throwable t) {
         t.printStackTrace();
      }
   }
   private static KnowledgeBase readKnowledgeBase() throws Exception {
      KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
      kbuilder.add(ResourceFactory.newClassPathResource("Pune.drl"), ResourceType.DRL);
      kbuilder.add(ResourceFactory.newClassPathResource("Nagpur.drl"), ResourceType.DRL);
      KnowledgeBuilderErrors errors = kbuilder.getErrors();

      if (errors.size() > 0) {
         for (KnowledgeBuilderError error: errors) {
            System.err.println(error);
         }
         throw new IllegalArgumentException("Could not parse knowledge.");
      }
      KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
      kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
      return kbase;
   }
}

このプログラムを実行すると、その出力は次のようになります-

PUNE 0
PUNE 20
NAGPUR 0
NAGPUR 10

プネとナグプールの両方で、品目が医薬品の場合、地方税はゼロです。一方、アイテムが食料品である場合、税は市ごとに課されます。 他の製品のルールをDRLファイルに追加できます。 これは単なるサンプルプログラムです。

DRLファイルから外部関数を呼び出す

ここでは、DRLファイル内のJavaファイルから静的関数を呼び出す方法を示します。

まず、同じパッケージ com.sampleHelloCity.java クラスを作成します。

package com.sample;

public class HelloCity {
   public static void writeHello(String name) {
      System.out.println("HELLO " + name + "!!!!!!");
   }
}

その後、DRLファイルにimportステートメントを追加して、DRLファイルからwriteHelloメソッドを呼び出します。 次のコードブロックでは、DRLファイルPune.drlの変更が黄色で強調表示されています。

//created on: Dec 24, 2014
package droolsexample

//list any import classes here.
import com.sample.ItemCity;
import java.math.BigDecimal;

import com.sample.HelloCity;

//declare any global variables here
dialect "java"

rule "Pune Medicine Item"
   when
      item : ItemCity(purchaseCity == ItemCity.City.PUNE,
         typeofItem == ItemCity.Type.MEDICINES)
   then
      BigDecimal tax = new BigDecimal(0.0);
      item.setLocalTax(tax.multiply(item.getSellPrice()));
      HelloCity.writeHello(item.getPurchaseCity().toString());
end

rule "Pune Groceries Item"
   when
      item : ItemCity(purchaseCity == ItemCity.City.PUNE,
         typeofItem == ItemCity.Type.GROCERIES)
   then
      BigDecimal tax = new BigDecimal(2.0);
      item.setLocalTax(tax.multiply(item.getSellPrice()));
end

プログラムを再度実行すると、その出力は次のようになります-

HELLO PUNE!!!!!!
PUNE 0
PUNE 20
NAGPUR 0
NAGPUR 10

現在の出力の違いは黄色でマークされ、Javaクラスの静的メソッドの出力を示しています。

Javaメソッドを呼び出す利点は、任意のユーティリティ/ヘルパー関数をJavaで記述し、DRLファイルから呼び出すことができることです。