Drools - Beispiel für ein Drools-Programm
In diesem Kapitel erstellen wir ein Drools-Projekt für die folgende Problemstellung:
Informieren Sie sich je nach Stadt und Art des Produkts (Kombination aus Stadt und Produkt) über die lokale Steuer für diese Stadt.
Wir werden zwei DRL-Dateien für unser Drools-Projekt haben. Die beiden DRL-Dateien kennzeichnen zwei betrachtete Städte (Pune und Nagpur) und vier Arten von Produkten (Lebensmittel, Medikamente, Uhren und Luxusgüter).
Die Steuer auf Arzneimittel in beiden Städten wird als Null angesehen.
Für Lebensmittel haben wir eine Steuer von Rs 2 in Pune und Rs 1 in Nagpur angenommen.
Wir haben den gleichen Verkaufspreis verwendet, um unterschiedliche Ergebnisse zu demonstrieren. Beachten Sie, dass alle Regeln in der Anwendung ausgelöst werden.
Hier ist das Modell für jeden 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-Dateien
Wie bereits erwähnt, haben wir hier zwei DRL-Dateien verwendet: Pune.drl und Nagpur.drl.
Pune.drl
Dies ist die DRL-Datei, die Regeln für Pune City ausführt.
// 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
Dies ist die DRL-Datei, die Regeln für die Stadt Nagpur ausführt.
// 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
Wir haben die DRL-Dateien basierend auf der Stadt geschrieben, da wir später beliebig viele Regeldateien hinzufügen können, wenn neue Städte hinzugefügt werden.
Um zu demonstrieren, dass alle Regeln aus unseren Regeldateien ausgelöst werden, haben wir zwei Artikeltypen verwendet (Medikamente und Lebensmittel). und Medizin ist steuerfrei und Lebensmittel werden nach Stadt besteuert.
Unsere Testklasse lädt die Regeldateien, fügt die Fakten in die Sitzung ein und erzeugt die Ausgabe.
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;
}
}
Wenn Sie dieses Programm ausführen, lautet die Ausgabe wie folgt:
PUNE 0
PUNE 20
NAGPUR 0
NAGPUR 10
Sowohl für Pune als auch für Nagpur beträgt die lokale Steuer Null, wenn es sich bei dem Artikel um ein Arzneimittel handelt. Wenn es sich bei dem Artikel um ein Lebensmittel handelt, richtet sich die Steuer nach der Stadt. Weitere Regeln können in den DRL-Dateien für andere Produkte hinzugefügt werden. Dies ist nur ein Beispielprogramm.
Rufen Sie eine externe Funktion aus einer DRL-Datei auf
Hier zeigen wir, wie Sie eine statische Funktion aus einer Java-Datei in Ihrer DRL-Datei aufrufen.
Erstellen Sie zunächst eine Klasse HelloCity.java im gleichen Paket com.sample.
package com.sample;
public class HelloCity {
public static void writeHello(String name) {
System.out.println("HELLO " + name + "!!!!!!");
}
}
Fügen Sie anschließend die import-Anweisung in die DRL-Datei ein, um die writeHello-Methode aus der DRL-Datei aufzurufen. Im folgenden Codeblock werden die Änderungen in der DRL-Datei Pune.drl gelb hervorgehoben.
// 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
Führen Sie das Programm erneut aus, und die Ausgabe lautet wie folgt:
HELLO PUNE!!!!!!
PUNE 0
PUNE 20
NAGPUR 0
NAGPUR 10
Der Unterschied in der Ausgabe ist jetzt gelb markiert, wodurch die Ausgabe der statischen Methode in der Java-Klasse angezeigt wird.
Der Vorteil des Aufrufs einer Java-Methode besteht darin, dass wir jede Dienstprogramm- / Hilfsfunktion in Java schreiben und diese aus einer DRL-Datei aufrufen können.