????下午好,我是一个流口水的新秀,我想通过举例来学习。
我的示例处理了应用规则以对订单的某些产品征税的经典问题,所以我有两个类,即Order和Product,类似这样:
订单类
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public class Order {
private String id;
private List<Product> products;
private double totalPrize;
private double totalTaxes;
public Order() {
super();
this.id=UUID.randomUUID().toString();
this.products = new ArrayList<Product>();
this.totalPrize = 0d;
this.totalTaxes = 0d;
}
public List<Product> getProducts() {
return products;
}
public void addProduct(Product p) {
this.products.add(p);
}
public double getTotalPrize() {
return totalPrize;
}
public void setTotalPrize(double totalPrize) {
this.totalPrize += totalPrize;
}
public double getTotalTaxes() {
return totalTaxes;
}
public void setTotalTaxes(double totalTaxes) {
this.totalTaxes += totalTaxes;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("Order [id=").append(id).append(", products=").append(products).append(", totalPrize=")
.append(totalPrize).append(", totalTaxes=").append(totalTaxes).append("]");
return builder.toString();
}
}
产品类别
import java.util.UUID;
public class Product {
private String id;
private String description;
private double prize;
private boolean imported;
private boolean tax_exempt;
private double sale_tax;
public Product(String description, double prize) {
super();
this.id=UUID.randomUUID().toString();
this.description = description;
this.prize = prize;
this.tax_exempt = description.matches("(.*)book(.*)") ||
description.matches("(.*)food(.*)") ||
description.matches("(.*)medical(.*)");
this.imported = description.matches("(.*)imported(.*)");
}
public double getPrize() {
return prize;
}
public boolean isImported() {
return imported;
}
public boolean isTax_exempt() {
return tax_exempt;
}
public double getSale_tax() {
return sale_tax;
}
public void setSale_tax(double sale_tax) {
this.sale_tax = sale_tax;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("Product [id=").append(id).append(", description=").append(description).append(", prize=")
.append(prize).append(", imported=").append(imported).append(", tax_exempt=").append(tax_exempt)
.append(", sale_tax=").append(sale_tax).append("]");
return builder.toString();
}
}
订单有产品清单,如果产品是进口的,我将征收5%的税。我应用了要使用布尔值征税的产品。
这是我创建订单并将其链接到kSession的方式:
//This is part of main mathod.
public static Order createOrder2() {
/*
*
* 1 imported box of chocolate 10.00
* 1 imported bottle of perfume 47.50
* */
Product p1 = new Product("imported food box of chocolate", 10.00d); //exempted and imported
Product p2 = new Product("imported bottle of perfume",14.99); //not exempted imported
Order order = new Order();
order.addProduct(p1);
order.addProduct(p2);
return order;
}
@Inject
@KSession
private KieSession kSession;
// instantiating order2 from above method.
kSession.insert(order2);
kSession.fireAllRules();
// end of main class
这是规则文件的一部分
rule "Applying taxes to imported products."
when
$order: Order()
$products: Product() from $order.getProducts()
$product: Product($products.isImported())
then
$product.setSale_tax($product.getPrize() *5d/100);
$order.setTotalPrize($product.getSale_tax() + $product.getPrize());
$order.setTotalTaxes($product.getSale_tax());
System.out.println($order.toString());
System.out.println($order.getTotalPrize());
System.out.println($order.getTotalTaxes());
end
我向kSession插入命令并触发了规则,当我运行测试方法时,我在终端中获得了此输出,并且测试失败。
测试方法:
@Test
public void should_apply_rules_to_order1_exempted_imported_not_imported() {
//GIVEN
Assert.assertNotNull(kSession);
final Order order1 = Utilities.createOrder1();
//WHEN
kSession.insert(order1);
//THEN
Assert.assertEquals(1, kSession.fireAllRules());
Assert.assertEquals("Shoud be equals...",29.83d, order1.getTotalPrize(),0d);
Assert.assertEquals("Shoud be equals...",1.50d, order1.getTotalTaxes(),0d);
}
这是pom.xml文件:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.aironman.test.rumbo</groupId>
<artifactId>TaxPlanner</artifactId>
<version>0.0.1-SNAPSHOT</version>
<description>A pet test project</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<kie.version>6.3.0.Final</kie.version>
<junit.version>4.11</junit.version>
<cdi.version>1.2</cdi.version>
<weld.version>2.3.0.Final</weld.version>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.jboss.arquillian</groupId>
<artifactId>arquillian-bom</artifactId>
<version>1.1.10.Final</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.kie</groupId>
<artifactId>kie-api</artifactId>
<version>${kie.version}</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-compiler</artifactId>
<version>${kie.version}</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-core</artifactId>
<version>${kie.version}</version>
</dependency>
<dependency>
<groupId>javax.enterprise</groupId>
<artifactId>cdi-api</artifactId>
<version>${cdi.version}</version>
</dependency>
<dependency>
<groupId>org.jboss.weld.se</groupId>
<artifactId>weld-se-core</artifactId>
<version>${weld.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.junit</groupId>
<artifactId>arquillian-junit-container</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.container</groupId>
<artifactId>arquillian-weld-se-embedded-1.1</artifactId>
<version>1.0.0.CR9</version>
<scope>test</scope>
</dependency>
</dependencies>
请问两个问题,为了让流口水不应用规则,我在做错什么?一旦应用规则,如何从引擎中恢复对象?
@ ioannis-barakos,我在上一篇文章中看到您帮助了另一个有类似问题的人,您能帮我吗?
答案 0 :(得分:1)
您的工作内存中只有Order
,而没有Product
,因此您的规则不会触发。仅当左侧的所有条件(“ when”子句)都匹配时,规则才会触发。
以下规则应更像您期望的那样:
dialect "mvel"
rule "Applying taxes to imported products."
when
// Take the order from working memory and get the product list from it
$order: Order( $products: products != null )
// Get only the imported products
$product: Product( isImported == true ) from $products
then
$product.setSale_tax($product.getPrize() * (5d/100));
$order.setTotalPrize($product.getSale_tax() + $product.getPrize());
$order.setTotalTaxes($product.getSale_tax());
System.out.println($order.toString());
System.out.println($order.getTotalPrize());
System.out.println($order.getTotalTaxes());
end
我们要做的第一件事是从订单中获取产品列表,并将其别名为$products
。然后,我们从该列表中获取导入的产品-注意from $products
。
在您的原始图片中,您只是打了电话$product: Product( ... )
,上面写着“从工作内存中获得一个看起来像这样的产品。由于您的工作内存中没有任何内容,因此它无法正常工作。” >
(另外,您从订单中获取$products
的方式有点不知所措...不确定您要在此做什么)。