[Application engine design patterns of use of the vehicle code refactoring] Aviator financial products based computing center

Aviator is an open source Java expression evaluator, not only supports four operations, three operations, logic operations, and its powerful interface supports custom extension functions. In view of this, financial products optimized reconstruction team in financial product platform, select this google calculation engine, in order to expand our business needs, we customize a range of custom functions to support our business scenario.

#### 1, simple API call sample
first step: we need to introduce rely maven project

<!-- 表达式解析引擎 -->
<dependency>
   <groupId>com.googlecode.aviator</groupId>
   <artifactId>aviator</artifactId>
   <version>3.0.0</version>
</dependency>

Step two: the static method call AviatorEvaluator.execute, return type Object type, the following example

import com.googlecode.aviator.AviatorEvaluator;
public class SimpleExample {
    public static void main(String[] args) {
        Long result = (Long) AviatorEvaluator.execute("1+2+3");
        System.out.println(result);
    }
}

#### 2, how to customize a function
first step: we can inherit AbstractVariadicFunction, implement the interface accordingly. Here we have a custom function more digital sum.

import com.googlecode.aviator.runtime.function.AbstractVariadicFunction;
import com.googlecode.aviator.runtime.function.FunctionUtils;
import com.googlecode.aviator.runtime.type.AviatorDecimal;
import com.googlecode.aviator.runtime.type.AviatorObject;

import java.math.BigDecimal;
import java.util.Map;

/**
 * @description: 多个数字求和计算(其中任何一个数字为空则作为0处理)
 * @Date : 2018/9/7 下午5:40
 * @Author : 石冬冬-Seig Heil
 */
public class SumFunction extends AbstractVariadicFunction {
    @Override
    public AviatorObject variadicCall(Map<String, Object> env, AviatorObject... args) {
        BigDecimal sum = new BigDecimal(0);
        for(AviatorObject each : args){
            if(each.getValue(env) == null){
                continue;
            }
            Number value = FunctionUtils.getNumberValue(each, env);
            sum = sum.add(new BigDecimal(value.toString()));
        }
        return new AviatorDecimal(new BigDecimal(sum.toString()));
    }

    @Override
    public String getName() {
        return "sum";
    }
}

Step two: the function of registration and call

AviatorEvaluator.addFunction(new SumFunction());
System.out.println(AviatorEvaluator.execute("sum(1,2)"));

#### 3, various expression type
#### 3.1, ternary expressions, logical operations

Map<String,Object> evn = new HashMap<String,Object>(){{
  put("a",3);
  put("b",2);
  put("c",5);
  put("d",-2);
}};
String expression = " (a > b) && (c > 0 || d > 0) ? a : b";
System.out.println(AviatorEvaluator.execute(expression,evn));

#### 3.2, a variety of built-in functions and math string

AviatorEvaluator.execute("string.length('hello')");    // 求字符串长度
AviatorEvaluator.execute("string.contains('hello','h')");  //判断字符串是否包含字符串
AviatorEvaluator.execute("string.startsWith('hello','h')");  //是否以子串开头
AviatorEvaluator.execute("string.endsWith('hello','llo')");  是否以子串结尾

AviatorEvaluator.execute("math.pow(-3,2)");   // 求n次方
AviatorEvaluator.execute("math.sqrt(14.0)");   //开平方根
AviatorEvaluator.execute("math.sin(20)");    //正弦函数

#### 4, supported data types
• Number Type: numeric types, supports two types, corresponding to the Java Long and Double, means that any integer will be converted to a Long, and any floating-point numbers will be converted as Double, including incoming user value is also true conversion. It does not support scientific notation, decimal only support. As -1,100,2.3 and so on.
• String Type: string type, single or double quotes enclosed text string, such as 'helloworld', is variable if the incoming or Character String will be converted to a String.
• Bool type: constants true and false, for true and false values, and the java and Boolean.False Boolean.TRUE correspondence.
• Pattern Type: Similar Ruby, perl regular expression to // the quoted string, such as / \ d + /, the internal implementation of java.util.Pattern.
• Variable type: With Java variable naming conventions same value of the variable passed in by the user, such as "a", "b", etc.
• nil type: Constants nil, similar to java in null, nil but is rather special, not only to nil participation ==,! = comparison, can also participate>,> =, <, <= the comparison, any types Aviator n is greater than a predetermined nil nil except itself, nilnil returns true. If the user passed variable value is null, it will also be treated as nil, nil print is null.
5 ####, support operator
##### arithmetic operators
Aviator support common arithmetic operators, including + - * /% five binary operators, unary operators and "-." Wherein - * /% monobasic and "-" Number can only be applied to the type. "+" Number not only for type, it may also be used for adding a String, and the string concatenation or other objects. Aviator, any type String and the result is a String.
##### logical operators
Avaitor logical operator support comprises monohydric negation operator "!", And the logic and the "&&" logical or "||." The number of logical operators to only Boolean. Relational operators
Aviator supported relational operators include "<", "<=" ">" "> =", and "
"And"! = ". && and || rules are the short-circuit.
Relationship relationship between the operator may act Number, between String, among Pattern, between Boolean, variable between nil and as well as other types of comparison of different types can not be compared to each other except nil.
Aviator require any large objects than nil except nil.
##### bitwise
Aviator supports all Java-bit operators, including "&" "|" " ^ "" ~ "," >> "," << "" >>>. "
##### match operator
match operator" = ~ "and String Pattern matching is used, which must be left operand String , right operand must be the Pattern. after successfully matched, Pattern packets stored in the variable $ num, num packet index.
##### ternary operator
Aviator if else statement is not provided, but provides ternary operator ":?", in the form of bool exp1:? exp2 which must be bool result is a Boolean expression, and exp1 and exp2 Aviator can be any valid expression, and does not require exp1 and consistent results exp2 return type.
6 ####, in order to expand the demand needs, expanded the related letter
nvl: if empty, set the default value

/**
 * @description: 为空时,设置一个默认值
 * @Date : 2018/9/7 下午5:40
 * @Author : 石冬冬-Seig Heil
 */
public class Nvl extends AbstractVariadicFunction {
    @Override
    public AviatorObject variadicCall(Map<String, Object> env, AviatorObject... args) {
        Number originValue = FunctionUtils.getNumberValue(args[0], env);
        Number defaultValue = FunctionUtils.getNumberValue(args[1], env);
        return new AviatorDecimal(new BigDecimal(Optional.ofNullable(originValue).orElse(defaultValue).toString()));
    }

    @Override
    public String getName() {
        return "nvl";
    }
}

sum: a plurality of digital sum

/**
 * @description: 多个数字求和计算(其中任何一个数字为空则作为0处理)
 * @Date : 2018/9/7 下午5:40
 * @Author : 石冬冬-Seig Heil
 */
public class Sum extends AbstractVariadicFunction {
    @Override
    public AviatorObject variadicCall(Map<String, Object> env, AviatorObject... args) {
        BigDecimal sum = new BigDecimal(0);
        for(AviatorObject each : args){
            if(each.getValue(env) == null){
                continue;
            }
            Number value = FunctionUtils.getNumberValue(each, env);
            sum = sum.add(new BigDecimal(value.toString()));
        }
        return new AviatorDecimal(new BigDecimal(sum.toString()));
    }

    @Override
    public String getName() {
        return "sum";
    }
}

min: a plurality of digital for the minimum

/**
 * @description: 多个数字求最小值(其中任何一个数字为空则作为0处理)
 * @Date : 2018/9/7 下午5:40
 * @Author : 石冬冬-Seig Heil
 */
public class Min extends AbstractVariadicFunction {
    @Override
    public AviatorObject variadicCall(Map<String, Object> env, AviatorObject... args) {
        List<BigDecimal> list = new ArrayList<>();
        for(AviatorObject each : args){
            if(each.getValue(env) == null){
                continue;
            }
            Number value = FunctionUtils.getNumberValue(each, env);
            list.add(new BigDecimal(value.toString()));
        }
        list.sort(Comparator.comparing(BigDecimal::doubleValue));
        return new AviatorDecimal(new BigDecimal(list.get(0).toString()));
    }

    @Override
    public String getName() {
        return "min";
    }
}

max: maximum value of a plurality of digital seek

/**
 * @description: 多个数字求最大值(其中任何一个数字为空则作为0处理)
 * @Date : 2018/9/7 下午5:40
 * @Author : 石冬冬-Seig Heil
 */
public class Max extends AbstractVariadicFunction {
    @Override
    public AviatorObject variadicCall(Map<String, Object> env, AviatorObject... args) {
        List<BigDecimal> list = new ArrayList<>();
        for(AviatorObject each : args){
            if(each.getValue(env) == null){
                continue;
            }
            Number value = FunctionUtils.getNumberValue(each, env);
            list.add(new BigDecimal(value.toString()));
        }
        list.sort(Comparator.comparing(BigDecimal::doubleValue).reversed());
        return new AviatorDecimal(new BigDecimal(list.get(0).toString()));
    }

    @Override
    public String getName() {
        return "max";
    }
}

round: rounding

/**
 * @description: 四舍五入
 * @Date : 2018/9/7 下午5:40
 * @Author : 石冬冬-Seig Heil
 */
public class Round extends AbstractVariadicFunction {
    @Override
    public AviatorObject variadicCall(Map<String, Object> env, AviatorObject... args) {
        Number value = FunctionUtils.getNumberValue(args[0], env);
        return new AviatorDecimal(Math.round(value.doubleValue()));
    }

    @Override
    public String getName() {
        return "round";
    }
}

ceil: improvement ToSei

/**
 * @description: 向上取整
 * @Date : 2018/9/7 下午5:40
 * @Author : 石冬冬-Seig Heil
 */
public class Ceil extends AbstractVariadicFunction {
    @Override
    public AviatorObject variadicCall(Map<String, Object> env, AviatorObject... args) {
        Number value = FunctionUtils.getNumberValue(args[0], env);
        return new AviatorDecimal(Math.ceil(value.doubleValue()));
    }

    @Override
    public String getName() {
        return "ceil";
    }
}

floor: rounding down

/**
 * @description: 向下取整
 * @Date : 2018/9/7 下午5:40
 * @Author : 石冬冬-Seig Heil
 */
public class Floor extends AbstractVariadicFunction {
    @Override
    public AviatorObject variadicCall(Map<String, Object> env, AviatorObject... args) {
        Number value = FunctionUtils.getNumberValue(args[0], env);
        return new AviatorDecimal(Math.floor(value.doubleValue()));
    }

    @Override
    public String getName() {
        return "floor";
    }
}

The following is my number two-dimensional code images public, welcome attention.
Autumn frost

Published 46 original articles · won praise 27 · views 160 000 +

Guess you like

Origin blog.csdn.net/shichen2010/article/details/82630334