В этой главе мы создадим проект Drools для следующей постановки задачи:
В зависимости от города и вида продукта (комбинация города и продукта) узнайте местный налог, связанный с этим городом.
У нас будет два файла DRL для нашего проекта Drools. Два файла DRL будут обозначать два рассматриваемых города (Пуна и Нагпур) и четыре типа товаров (продукты питания, лекарства, часы и предметы роскоши).
-
Налог на лекарства в обоих городах считается нулевым.
-
Для продуктов мы взяли налог в 2 рупии в Пуне и 1 рупию в Нагпуре.
Налог на лекарства в обоих городах считается нулевым.
Для продуктов мы взяли налог в 2 рупии в Пуне и 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
Как предлагалось ранее, мы использовали два файла DRL: Pune.drl и Nagpur.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, основанные на городе, поскольку это дает нам возможность добавлять любое количество файлов правил позже, если добавляются новые города.
Чтобы продемонстрировать, что все правила запускаются из наших файлов правил, мы использовали два типа элементов (лекарства и продукты питания); и медицина не облагается налогом, а продукты облагаются налогом в соответствии с городом.
Наш тестовый класс загружает файлы правил, вставляет факты в сеанс и выдает результат.
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
Здесь мы продемонстрируем, как вызывать статическую функцию из файла Java в вашем файле DRL.
Прежде всего, создайте класс HelloCity.java в том же пакете com.sample .
package com.sample; public class HelloCity { public static void writeHello(String name) { System.out.println("HELLO " + name + "!!!!!!"); } }
После этого добавьте оператор импорта в файл DRL, чтобы вызвать метод writeHello из файла DRL. В следующем блоке кода изменения в файле 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.