用Mvel构建表达式<三>

Mvel表达式的编译与计算

在做流程执行时,我们可以用Mvel表达式做条件表达式,判断是否执行下一步的操作。

I 抽象顶级Complier接口和Evaluator接口

package mvel;

import java.io.Serializable;

/**
 * @Description 编译er
 * @Author taren.Tian
 * @Date 11:07 2019/7/11
 **/
public interface Complier {

//自己写的内置Mvel脚本函数文件
String MVEL_BUILT_IN_FUNCTIONS_FILE = "built-in.mvel";

//编译表达式(这是有内置函数的基础上)
Serializable compile(String expression);

//编译表达式(这是没有内置函数的基础上)
Serializable compileWithoutBuiltIn(String expression);
}

接口Complier是抽象出来的用来编译表达式

package mvel;

import java.util.Map;

/**
 * @Description 计算er
 * @Author taren.Tian
 * @Date 14:34 2019/7/11
 **/
public interface Evaluator {
Object eval(String expression, Map context);
}

接口Evaluator是抽象出来执行表达式的超类

II 提供MVEL脚本加载器

package mvel;

import org.apache.commons.io.IOUtils;
import java.io.IOException;
import java.net.URL;
import java.nio.charset.StandardCharsets;

/**
 * @Description Mvel内置函数加载器loader
 * @Authror taren
 * @DATE 2019/7/11 10:53
 */
public class BuiltInExpressionLoader {

public static String load() {
    StringBuffer sb = new StringBuffer();

    URL url = BuiltInExpressionLoader.class.getClassLoader().getResource(Complier.MVEL_BUILT_IN_FUNCTIONS_FILE);

    if (url != null) {
        try {
            String builtInExpr = IOUtils.toString(url, StandardCharsets.UTF_8);
            sb.append(builtInExpr);
            sb.append("\n");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    return sb.toString();
}
}

III 采用MVEL实现ComplierEvaluator

package mvel;

import org.apache.commons.lang3.StringUtils;
import org.mvel2.MVEL;

import java.io.Serializable;

/**
 * @Description Mvel表达式编译er
 * @Authror taren
 * @DATE 2019/7/11 10:52
 */
public class MvelComplier implements Complier {

@Override
public Serializable compile(String expression) {
    StringBuffer sb = new StringBuffer();
    //读取内置函数脚本
    String builtIn = BuiltInExpressionLoader.load();
    if (StringUtils.isNotBlank(builtIn)) {
        sb.append(builtIn);
    }
    sb.append(expression);
    return sb.toString();
}

@Override
public Serializable compileWithoutBuiltIn(String expression) {
    //直接用Mvel自带的编译
    return MVEL.compileExpression(expression);
}
}

package mvel;

import org.apache.commons.lang3.StringUtils;
import org.mvel2.MVEL;
import java.util.HashMap;
import java.util.Map;

/**
 * @Description Mvel表达式计算er
 * @Authror taren
 * @DATE 2019/7/11 10:59
 */
public class MvelEvaluator implements Evaluator {

/**
 * @param expression 表达式
 * @param context  计算条件
 * @return
 * @Description
 */
@Override
public Object eval(String expression, Map context) {
    Map ctx = new HashMap<>();
    if (context != null) {
        context.forEach(ctx::put);
    }
    StringBuilder sb = new StringBuilder();
    String builtInExpr = BuiltInExpressionLoader.load();
    if (StringUtils.isNotBlank(builtInExpr)) {
        sb.append(builtInExpr);
    }
    sb.append(expression);
    return MVEL.eval(sb.toString(), ctx);
}

}

IV 使用工厂来获取各自对应的实现

package mvel;
/**
 * @Description 通过工厂获取 compiler
 * @Author taren.Tian
 * @Date 15:00 2019/7/12
 **/
public class MvelComplierFactory {

private  static final Complier compiler = new MvelComplier();

static Complier get() {
    return compiler;
}
}

package mvel;

/**
 * @Description
 * @Authror taren
 * @DATE 2019/7/12 14:59
 */
public class MvelEvaluatorFactory {
private static final Evaluator evaluator = new MvelEvaluator();

static Evaluator get() {
    return evaluator;
}
}

V 另外展示部分MVEL函数脚本文件内容

import java.util.*;
import java.time.*;
import java.time.format.*;
import java.text.*;

def abs(value) {
return Math.abs(value);
}

def dtGetDay(dt){
sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
calendar = Calendar.getInstance();
calendar.setTime(sdf.parse(dt));
return calendar.get(Calendar.DAY_OF_MONTH);
}

你可能感兴趣的:(用Mvel构建表达式<三>)