Skip to content

Commit fc9bf77

Browse files
committed
BAEL-9162: Simple Rule Engine
1 parent b2625cc commit fc9bf77

File tree

13 files changed

+288
-0
lines changed

13 files changed

+288
-0
lines changed

rule-engines-modules/pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
<module>evrete</module>
1919
<module>openl-tablets</module>
2020
<module>rulebook</module>
21+
<module>simple-rule-engine</module>
2122
<!-- <module>jess</module> --> <!-- requires dependencies which are not publicly available -->
2223
</modules>
2324

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
<groupId>com.baeldung.simpleruleengine</groupId>
7+
<artifactId>simple-rule-engine</artifactId>
8+
<version>1.0</version>
9+
<name>simple-rule-engine</name>
10+
<build>
11+
<plugins>
12+
<plugin>
13+
<groupId>org.apache.maven.plugins</groupId>
14+
<artifactId>maven-compiler-plugin</artifactId>
15+
<configuration>
16+
<source>9</source>
17+
<target>9</target>
18+
</configuration>
19+
</plugin>
20+
</plugins>
21+
</build>
22+
23+
<parent>
24+
<groupId>com.baeldung</groupId>
25+
<artifactId>rule-engines-modules</artifactId>
26+
<version>1.0.0-SNAPSHOT</version>
27+
</parent>
28+
29+
<dependencies>
30+
<dependency>
31+
<groupId>org.projectlombok</groupId>
32+
<artifactId>lombok</artifactId>
33+
<version>${lombok.version}</version>
34+
<scope>provided</scope>
35+
</dependency>
36+
<dependency>
37+
<groupId>org.springframework</groupId>
38+
<artifactId>spring-expression</artifactId>
39+
<version>7.0.0-M7</version>
40+
</dependency>
41+
</dependencies>
42+
43+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package com.baeldung.ruleengine;
2+
3+
import com.baeldung.ruleengine.model.Order;
4+
5+
public class FirstOrderHighValueSpecialDiscountRule implements IRule {
6+
7+
@Override
8+
public boolean evaluate(Order order) {
9+
return order.getCustomer()
10+
.isFirstOrder() && order.getAmount() > 500;
11+
}
12+
13+
@Override
14+
public String description() {
15+
return "First Order Special Discount Rule: First Time customer with high value order";
16+
}
17+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package com.baeldung.ruleengine;
2+
3+
import com.baeldung.ruleengine.model.Order;
4+
5+
public interface IRule {
6+
boolean evaluate(Order order);
7+
String description();
8+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package com.baeldung.ruleengine;
2+
3+
import com.baeldung.ruleengine.model.Order;
4+
5+
public class LoyaltyDiscountRule implements IRule{
6+
7+
@Override
8+
public boolean evaluate(Order order) {
9+
return order.getCustomer().getLoyaltyPoints() > 500;
10+
}
11+
12+
@Override
13+
public String description() {
14+
return "Loyalty Discount Rule: Customer has more than 500 points";
15+
}
16+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package com.baeldung.ruleengine;
2+
3+
import java.util.List;
4+
import java.util.stream.Collectors;
5+
6+
import com.baeldung.ruleengine.model.Order;
7+
8+
public class RuleEngine {
9+
private final List<IRule> rules;
10+
11+
public RuleEngine(List<IRule> rules) {
12+
this.rules = rules;
13+
}
14+
15+
public List<String> evaluate(Order order) {
16+
return rules.stream()
17+
.filter(rule -> rule.evaluate(order))
18+
.map(IRule::description)
19+
.collect(Collectors.toList());
20+
}
21+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package com.baeldung.ruleengine;
2+
3+
import org.springframework.expression.ExpressionParser;
4+
import org.springframework.expression.spel.standard.SpelExpressionParser;
5+
import org.springframework.expression.spel.support.StandardEvaluationContext;
6+
7+
import com.baeldung.ruleengine.model.Order;
8+
9+
10+
public class SpelRule {
11+
12+
private final String expression;
13+
private final String description;
14+
15+
public SpelRule(String expression, String description) {
16+
this.expression = expression;
17+
this.description = description;
18+
}
19+
20+
public boolean evaluate(Order order) {
21+
ExpressionParser parser = new SpelExpressionParser();
22+
StandardEvaluationContext context = new StandardEvaluationContext(order);
23+
context.setVariable("order", order);
24+
return parser.parseExpression(expression)
25+
.getValue(context, Boolean.class);
26+
}
27+
28+
public String getDescription() {
29+
return description;
30+
}
31+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.baeldung.ruleengine.model;
2+
3+
import lombok.AccessLevel;
4+
import lombok.Getter;
5+
import lombok.Setter;
6+
import lombok.experimental.FieldDefaults;
7+
8+
@Setter
9+
@Getter
10+
@FieldDefaults(level = AccessLevel.PRIVATE)
11+
public class Customer {
12+
13+
String name;
14+
int loyaltyPoints;
15+
boolean firstOrder;
16+
17+
public Customer() {
18+
}
19+
20+
public Customer(String name, int loyaltyPoints, boolean firstOrder) {
21+
this.name = name;
22+
this.loyaltyPoints = loyaltyPoints;
23+
this.firstOrder = firstOrder;
24+
}
25+
26+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.baeldung.ruleengine.model;
2+
3+
import lombok.AccessLevel;
4+
import lombok.AllArgsConstructor;
5+
import lombok.Data;
6+
import lombok.Getter;
7+
import lombok.NoArgsConstructor;
8+
import lombok.Setter;
9+
import lombok.experimental.FieldDefaults;
10+
11+
@Getter
12+
@Setter
13+
public class Order {
14+
15+
private Double amount;
16+
private Customer customer;
17+
18+
public Order() {
19+
}
20+
21+
public Order(Double amount, Customer customer) {
22+
this.amount = amount;
23+
this.customer = customer;
24+
}
25+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<configuration>
3+
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
4+
<encoder>
5+
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
6+
</pattern>
7+
</encoder>
8+
</appender>
9+
10+
<root level="INFO">
11+
<appender-ref ref="STDOUT" />
12+
</root>
13+
</configuration>

0 commit comments

Comments
 (0)