Drools - Esempio di programma Drools
In questo capitolo, creeremo un progetto Drools per la seguente dichiarazione del problema:
A seconda della città e del tipo di prodotto (combinazione di città e prodotto), scopri la tassa locale relativa a quella città.
Avremo due file DRL per il nostro progetto Drools. I due file DRL indicheranno due città in considerazione (Pune e Nagpur) e quattro tipi di prodotti (generi alimentari, medicinali, orologi e beni di lusso).
L'imposta sui medicinali in entrambe le città è considerata pari a zero.
Per i generi alimentari, abbiamo ipotizzato una tassa di Rs 2 a Pune e Rs 1 a Nagpur.
Abbiamo utilizzato lo stesso prezzo di vendita per dimostrare risultati diversi. Nota che tutte le regole vengono attivate nell'applicazione.
Ecco il modello per contenere ogni oggetto
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;
}
}
File DRL
Come suggerito in precedenza, abbiamo utilizzato due file DRL qui: Pune.drl e Nagpur.drl.
Pune.drl
Questo è il file DRL che esegue le regole per la città di Pune.
// 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
Questo è il file DRL che esegue le regole per la città di Nagpur.
// 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
Abbiamo scritto i file DRL in base alla città, in quanto ci offre l'estensibilità per aggiungere un numero qualsiasi di file di regole in un secondo momento se vengono aggiunte nuove città.
Per dimostrare che tutte le regole vengono attivate dai nostri file di regole, abbiamo utilizzato due tipi di articoli (medicinali e generi alimentari); e la medicina è esentasse e la spesa è tassata come per la città.
La nostra classe di test carica i file delle regole, inserisce i fatti nella sessione e produce l'output.
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;
}
}
Se esegui questo programma, il suo output sarà il seguente:
PUNE 0
PUNE 20
NAGPUR 0
NAGPUR 10
Sia per Pune che per Nagpur, quando l'articolo è un medicinale, la tassa locale è zero; mentre quando l'articolo è un prodotto alimentare, l'imposta è come per la città. È possibile aggiungere più regole nei file DRL per altri prodotti. Questo è solo un programma di esempio.
Chiama una funzione esterna da un file DRL
Qui mostreremo come chiamare una funzione statica da un file Java all'interno del tuo file DRL.
Prima di tutto, crea una classe HelloCity.java nello stesso pacchetto com.sample.
package com.sample;
public class HelloCity {
public static void writeHello(String name) {
System.out.println("HELLO " + name + "!!!!!!");
}
}
Successivamente, aggiungi l'istruzione import nel file DRL per chiamare il metodo writeHello dal file DRL. Nel seguente blocco di codice, le modifiche nel file DRL Pune.drl sono evidenziate in giallo.
// 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
Esegui di nuovo il programma e il suo output sarà il seguente:
HELLO PUNE!!!!!!
PUNE 0
PUNE 20
NAGPUR 0
NAGPUR 10
La differenza ora nell'output è contrassegnata in giallo che mostra l'output del metodo statico nella classe Java.
Il vantaggio di chiamare un metodo Java è che possiamo scrivere qualsiasi funzione di utilità / aiuto in Java e chiamare lo stesso da un file DRL.