Skip to content

Latest commit

 

History

History
174 lines (145 loc) · 6.84 KB

README_en.md

File metadata and controls

174 lines (145 loc) · 6.84 KB

Simply Expression Language

📖 English Documentation | 📖 中文文档

Java support GitHub release Maven Central License

Introduction

Simple expression language designed to simplify tasks involving logic, calculation, value retrieval, and structural transformation, which are logically simple but often involve complex coding.
Main Application Scenarios: Dynamic rule calculation scenarios, type adaptation (message conversion).

The English document comes from the ChatGPT, please let me know if there is any problem or you can't understand it.

Environment & Dependencies

  • JDK 1.8
  • fastjson2 2.0.49
  • slf4j 1.7.30

Characteristic

  • Support hierarchical structures: Quickly operate and convert JSON or various types of POJOs, etc.
  • Safe value retrieval: Say goodbye to frequent and tedious null checks.
  • Branching logic: Support complex compound statements, including if-else/for and other related branching syntax.
  • Method invocation: Directly call object methods, support custom utility methods.
  • Convenient to use: No need to build additional context objects for calculations; directly calculate native objects through the API.

Introduce the configuration

Since org domain name is not easy to renew in China, the subsequent versions are replaced by net domain name.

New dependencies (after 1.1.1)

<dependency>
    <groupId>net.fanjr.simplify</groupId>
    <artifactId>simplify-el</artifactId>
    <version>1.2.0</version>
</dependency>

Old dependencies (before 1.1.0)

<dependency>
    <groupId>org.fanjr.simplify</groupId>
    <artifactId>simplify-el</artifactId>
    <version>1.1.0</version>
</dependency>

Documentation

↓↓↓↓↓↓↓↓↓↓
Click Here View detailed documentation
↑↑↑↑↑↑↑↑↑↑

Feature Overview

  • Simple expression calculation, placeholder calculation, four operations, regular matching.
  • Support assignment operations, type conversion, and scenarios such as JSON format conversion.
  • Support complex statements and the mixed use of multiple statements.
  • Support calling Java object methods and custom function method calls.
  • Support conditional branches, ternary expressions, and loops.

Expression Call Examples

// Basic call example
boolean result = ELExecutor.eval(
        // Expression string; separate compound statements with semicolons, return the result of the last executed statement
        "a==100",
        // Expected context or object for calculation, mainly supports Java beans, Map, strings, etc.
        "{'a':100}",
        // Expected return type, supports generics
        boolean.class);
Assertions.assertTrue(result);

// Arithmetic operation example
int result = ELExecutor.eval("2 * a - (b + c) * d", "{'a':1,'b':2,'c':3,'d':4}", int.class);
// 2*1-(2+3)*4 = -18
Assertions.assertEquals(-18, result);

// Assignment & calculation example
Map<String, Object> context = new HashMap<>();
context.put("val", 10);
ELExecutor.eval("a=10;val=val+1;val++;result=a+val;", context);
// a=10;
Assertions.assertEquals(10, ElUtils.cast(context.get("a"), int.class));
// val=val+1;val++;
Assertions.assertEquals(12, ElUtils.cast(context.get("val"), int.class));
// result=a+val;
Assertions.assertEquals(22, ElUtils.cast(context.get("result"), int.class));

// Assigning values to sub-object properties in a POJO through an expression
TestReq req = new TestReq();
ELExecutor.eval("head.serialId='123456'", req);
System.out.println(req.getHead().getSerialId());

// Calling Java methods
Map<String, Object> context = new HashMap<>();
context.put("val", "010");
// Convert the string "010" to int type, call the toString() method, and then call the length() method; expected return value is 2
Assertions.assertEquals(2, ELExecutor.eval("((int)val).toString().length()", context, int.class));

Ternary Expression

Map<String, Object> context = new HashMap<>();
context.put("flag", 100);
context.put("val", 10);
// If flag is greater than or equal to 100, return val*10; here the result is 100
Assertions.assertEquals(100, ELExecutor.eval("flag>=100?val*10:val/10", context, int.class));
// If flag is less than 100, return val/10; here the result is 1
Assertions.assertEquals(1, ELExecutor.eval("flag<100?val*10:val/10", context, int.class));

IF-ELSE Branch Syntax

// Create a context for calculations
Map<String, Object> context = new HashMap<>();

// Branch 1 (IF) a=1
context.put("flag", 1);
ELExecutor.eval("if(flag==1){\n a=1;\n }", context);
Assertions.assertEquals(ElUtils.cast(context.get("a"), int.class), 1);
context.clear();

// Branch 2 (IF-ELSE-IF) a=3
context.put("flag", 2);
ELExecutor.eval("if(flag==1){a=1; }else if(flag==2){ a=2;a++; }", context);
Assertions.assertEquals(ElUtils.cast(context.get("a"), int.class), 3);
context.clear();

// Branch 3 (IF-ELSE-IF-ELSE) a=0
context.put("flag", 3);
ELExecutor.eval("if(flag==1){\n a=1;\n }else if(flag==2){ a=2;a++; }else{ a=0; }", context);
Assertions.assertEquals(ElUtils.cast(context.get("a"), int.class), 0);
context.clear();

FOR Loop Syntax

// Reference group: Java code loop
int[] arr = new int[10];
for (int i = 0; i < 10; i++) {
    arr[i] = 3 * (i + 1234) - i;
}

// Create a context for calculations
Map<String, Object> context = new HashMap<>();

// C-like mode
ELExecutor.eval("for(i=0;i<10;i++){arr[i]=3 * (i + 1234) - i}", context);
// Assertion of calculation result correctness
Assertions.assertArrayEquals(arr, ElUtils.cast(context.get("arr"), int[].class));
context.clear();

// Iterator mode, can iterate over arrays, List, Map, etc.
context.put("num", new int[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9});
ELExecutor.eval("for(i:num){arr[i]=3 * (i + 1234) - i}", context);
// Assertion of calculation result correctness
Assertions.assertArrayEquals(arr, ElUtils.cast(context.get("arr"), int[].class));
context.clear();

// Number mode, equivalent to i=0;i<10;i++
ELExecutor.eval("for(i:10){arr[i]=3 * (i + 1234) - i}", context);
// Assertion of calculation result correctness
Assertions.assertArrayEquals(arr, ElUtils.cast(context.get("arr"), int[].class));
context.clear();

Future Plans

  • Support logging (or console output) and other built-in functions.
  • Analyze Java's built-in library methods and consider integrating some frequently used methods into built-in functions.