流口水无法正常工作。规则不适用

时间:2019-12-12 18:04:23

标签: java drools

????下午好,我是一个流口水的新秀,我想通过举例来学习。

我的示例处理了应用规则以对订单的某些产品征税的经典问题,所以我有两个类,即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,我在上一篇文章中看到您帮助了另一个有类似问题的人,您能帮我吗?

1 个答案:

答案 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的方式有点不知所措...不确定您要在此做什么)。