2016-05-09 14 views
4

私はJAVAとDroolsの初心者ですので、なぜこれをやっているのか尋ねないでください:Dタスクは、関税と価格を計算する単純なシステムを実装することでした。 2アイテム(色違い)。私はgetterとsetterで単純なクラスを作った:2つのルールのうち1つが発射されない

package com.sample; 

public class Pen { 

    private String color; 
    private int quantity; 
    private double tariff; 
    private double subTotal; 

    public String getColor(){ 
     return color; 
    } 

    public void setColor(String color){ 
     this.color=color; 
    } 

    public int getQuantity(){ 
     return quantity; 
    } 

    public void setQuantity(int quantity){ 
     this.quantity=quantity; 
    } 

    public double getTariff(){ 
     return tariff; 
    } 

    public void setTariff(double tariff){ 
     this.tariff=tariff; 
    } 

    public double getSubTotal(){ 
     return subTotal; 
    } 

    public void setSubTotal(double subTotal){ 
     this.subTotal=subTotal; 
    } 

} 

タスクは、CSVファイルからいくつかの定義済みのデータを読み込み、別のCSV(まだ実装されていませんが書き込み)にそれを書くことでした。入力を処理してセッションを呼び出すクラスは次のとおりです。

public class CSVReader { 
    public void CSVToJava() { 
     String CSVFile = "csvExample.csv"; 
     BufferedReader buffer = null; 
     String line = ""; 
     String delimiter = ","; 
     List<Pen> penList = new ArrayList<Pen>(); 

     try { 
      // load up the knowledge base 
      KnowledgeBase kbase = readKnowledgeBase(); 
      StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession(); 
      buffer = new BufferedReader(new FileReader(CSVFile)); 
      while ((line = buffer.readLine()) != null) { 
       String[] pens = line.split(delimiter); 
       Pen redPen = new Pen(); 
       Pen bluePen = new Pen(); 
       if (pens[0].equalsIgnoreCase("Blue Pen")) { 
        bluePen.setColor(pens[0]); 
        bluePen.setQuantity(Integer.parseInt(pens[1].trim())); 
        penList.add(bluePen); 
        ksession.insert(bluePen); 
       } else { 
        redPen.setColor(pens[0]); 
        redPen.setQuantity(Integer.parseInt(pens[1].trim())); 
        penList.add(redPen); 
        ksession.insert(redPen); 
       } 
      } 
      ksession.fireAllRules(); 
      printPenList(penList);   
     } catch (FileNotFoundException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } catch (Throwable t) { 
      t.printStackTrace(); 
     } finally { 
      if (buffer != null) { 
       try { 
        buffer.close(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 
     } 
    } 

    public void printPenList(List<Pen> penListToPrint) { 
     for (int i = 0; i < penListToPrint.size(); i++) { 
      System.out.println(penListToPrint.get(i).getColor() + "," + penListToPrint.get(i).getQuantity() + "," 
        + penListToPrint.get(i).getTariff() + "," + penListToPrint.get(i).getSubTotal()); 
     } 

    } 

    private static KnowledgeBase readKnowledgeBase() throws Exception { 

     KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(); 

     kbuilder.add(ResourceFactory.newClassPathResource("com/Drools/BluePen.drl"), ResourceType.DRL); 
     kbuilder.add(ResourceFactory.newClassPathResource("com/Drools/RedPen.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; 
    } 

} 

また、各項目の色ごとに2つの別々のDRLファイルがあります。ルールの計算に基づいて、2つの追加プロパティ、単純な乗算(subTotal)を出力する必要があります。

public class App { 

    public static void main(String[] args) { 
      CSVReader csvReader = new CSVReader(); 
      csvReader.CSVToJava(); 
    } 

} 

すべては私の主な問題がある。このpackageExplorer

次のようになります。私は、プロセスを開始するため、全メソッドを呼び出すクラスがあり、また、

import com.sample.Pen; //FIRST ONE 

rule "less or equal to 10" 

    when 
     item : Pen(item.getColor().equalsIgnoreCase("BLUE PEN"), (item.getQuantity()) <= 10.0) 
    then 
     item.setTariff(3.0); 
     item.setSubTotal(3.0 * ((double) item.getQuantity()));  
end 

rule "more than 10" 
    when 
     item : Pen(item.getColor().equalsIgnoreCase("BLUE PEN"), (item.getQuantity()) > 10.0) 
    then 
     item.setTariff(2.5); 
     item.setSubTotal(2.5 * ((double) item.getQuantity())); 
end 



import com.sample.Pen; //SECOND ONE 


rule "less or equal to 10" 

     when 
      item : Pen(item.getColor().equalsIgnoreCase("RED PEN"), (item.getQuantity()) <= 10.0) 
     then 
      item.setTariff(3.5); 
      item.setSubTotal(3.5 * ((double) item.getQuantity()));  
    end 

    rule "more than 10" 
     when 
      item : Pen(item.getColor().equalsIgnoreCase("RED PEN"), (item.getQuantity()) > 10.0) 
     then 
      item.setTariff(3.0); 
      item.setSubTotal(3.0 * ((double) item.getQuantity())); 
    end 

:各ファイルには、2つのルールを持っていますプリントアウトは次のようになります - >

Red Pen,6,3.5,21.0 
Blue Pen,12,0.0,0.0 

各行sh ouldは4つのフィールドで構成され、最初の2つはwhileループのCSVReaderクラスで計算され、最後の2つ(ケースまたは赤いペンでは3.5と21.0)はDroolsで計算されます。あなたが見ることができるように、青いペンのためのルールはまったく発射していません。私は問題を解決することはできません。誰かが助けることができれば、私は感謝以上のことでしょう:)

EDIT:これを解決した後、 2つのDRLファイルを介して別の3ルールの広がりを持つコード:

package com.drools //First.drl 

import com.sample.Pen; 

rule "Subtotal for blue pen" salience 2 

    when 
     item : Pen(item.getColor().equalsIgnoreCase("BLUE PEN")) 
    then 
     item.setTotal(item.getTotal() + item.getSubTotal());  
end 

rule "Subtotal for red pen" salience 2 

    when 
     item : Pen(item.getColor().equalsIgnoreCase("RED PEN")) 
    then 
     item.setTotal(item.getTotal() + item.getSubTotal());  
end 


package com.drools //Second.drl 

import com.sample.Pen; 

rule "Discounted total price" salience 1 

    when 
     item : Pen((item.getTotal()) > 100.0) 
    then 
     item.setTotal(0.85 * item.getTotal()); 
end 

私は焼成可能であるために、また私のセッション内のファイルをクラスパスに追加しています。 fireAllメソッドが呼び出されると、合計金額に0.85を掛け合わせた2番目の火災のルールは発生しません(totalPenクラス内で宣言された静的変数ですので、それぞれからsuTotalを加算することができます)色)、顕著性が最も低い本家 - >最後の発砲すべきであるとの正しい量は140 * 0.85 = 119

すべきは次のようになります。

Red Pen,30,3.0,90.0 
Blue Pen,20,2.5,50.0 
140 

たぶん誰かが、またあなたをこれを理解することができますみんなはアドバイスを使って今まで素晴らしいです:)

答えて

2

両方のファイルがルール

rule "less or equal to 10" 
rule "more than 10" 

を持っています。ルールは名前で識別されます。別のものと同じ名前のルールは、最初のものを静かに上書きします。異なるDRLファイルからの読み込み順序は未定義です。

Drools 5.xでこれがうまくいくかどうか、またこれがどのように機能するかについては長い議論がありましたが、現在はブリッジの下にある水であり、それに固執する必要があります。 (Drools 6.xがこれを許可しているかどうか不明です)

Drools 6.xがコンパイルに同じ名前のルールがある場合、Drools 6.xがコンパイルエラーを発生させることを確認してくれてありがとう同じDRLファイルまたは別のファイルにあることを確認します。

+0

Drools 6.xのテストを行いました。重複する名前は許可されていません。 'java.lang.IllegalStateException:[4,0]:重複するルール名:10以下です。[12,0]:重複するルール名:10以上です。あなたの投稿を編集して完成させていただきます。 – Wis

+0

ルール名を変更しました。ありがとうございました。 – borgmater

+0

@Wisあなたがする前に、同じか違うファイルにあるルール間に違いがないことを確認してください。 – laune

1

私はエキスパートではありませんが、RED PENとBLUE PENを切り替えて最初のルールの後にルールをトリガしないかどうかを確認することをお勧めします。 CSVファイルの読み込みに問題がある可能性があります。 thx

+0

これはコメントであり、答えではありません。 – laune

+1

私は同意しますが、私は現在のポイントでコメントすることはできません。 – techi

1

ルール条件の文字列比較では、Java equalsメソッドを使用しないでください。 Droolsは独自のrule languageを使用しています。 (ただし、5.xの構文は参考文献に示されているものより幾分制限されていますが、マイナーバージョン、5.2/3/... [laune]でも異なります)

例を見てください4。4(私は例で行方不明"を修正):

when 
    item : Pen(color == "BLUE PEN", quantity > 10) 

として:あなたはあなたのルールの構文を試してみてください

1: rule simple_rule 
2: when 
3:  Student(name == "Andy") 
4: then 
5: end 

は(もあなたの量が整数ではなく浮動小数点数であることに注意してください)あなたのルールのアクション部分にあなたの (double)キャストは必須ではありません。 Javaでdoubleとintegerを掛け合わせるとdouble値になります。double値は既にあなたの関税とsubTotalメンバーの型です。あなたはそれを持つことができません

+0

引き続きequalsを使用できます。とにかく、equalsIgnoreCase(OPにあるように)は別の方法です。 – laune

+0

あなたはそうです、等しく働きます。私が誤解されていないなら、Javaの小さなサブセットしか条件に使用できません。私は、 'Calendar'メソッドのいくつかを使用できないことを覚えています。しかし、小さな違いがあります、drools ==演算子はnull安全です。 – Wis

+0

私は自由を取って、6.xと5.xの間の構文を注意深い発言に加えました。 – laune

関連する問題