在上篇文章中讲述了表达式解析的简答使用和注意事项。本文主要针对表达式解析的函数进行讲解。
1、系统自带函数
系统自带函数有max(obj,obj…..),abs(obj),judge(boolean,object,object1)。
max:求一类值的最大值,这一类值的类型要相同。
abs:求绝对值。
judge:三个参数,boolean,object,object1。用于判断,如果boolean为true,返回object,否则返回object1。这些参数不一定是固定值,也可以是各种表达式,或者继续嵌套其他函数。

系统还有自带的if语句,格式如下:

if (a>b) 
  a;
 else
  b;
 endif

每一个if的结束endif不能缺少,怎么嵌套使用就不详细描述了,本人也只是用过if else if endif endif的简单结构。

2、用户自定义函数(重点:敲黑板,咳咳咳)
零散的几个系统函数和简单的逻辑运算对于复杂的表达式配置根本不够用,所以这个API也支持用户自定义的函数。
用户自定义函数要继承Function类,下面是一个简单的截取字符串的自定义函数。

import neu.sxc.expression.syntax.ArgumentsMismatchException;
import neu.sxc.expression.syntax.function.Function;
import neu.sxc.expression.tokens.DataType;
import neu.sxc.expression.tokens.Valuable;

/**
 * 字符串截取 格式:subString(String str,int start,int end)
 */
public class SubString extends Function {

    public SubString() {
        super("subString", new DataType[] { DataType.STRING, DataType.NUMBER,DataType.NUMBER });
    }

    @Override
    public int getArgumentNum() {
        return 3;
    }

    @Override
    protected Object executeFunction(Valuable[] arguments)
            throws ArgumentsMismatchException {
        return arguments[0].getStringValue().substring(
                arguments[1].getNumberValue().intValue(),
                arguments[2].getNumberValue().intValue());
    }

}

整体结构分三块:
构造函数:可以直接调用父类的构造方法,指定函数的名称以及各个参数的类型。
getArgumentNum():获取函数参数的个数。
executeFunction():函数的执行,传递的是参数数组,可以进行核心的设计使得完成函数的功能。

函数的使用只需要在解析表达式的时候手动将函数添加到Expression对象即可。

public static String evaluate(String expression) {
        ExpressionFactory factory = ExpressionFactory.getInstance();
        Expression expr = factory.getExpression(expression);
        expr.addFunction(new SubString());
        Set<String> fieldSet = expr.getVariableNames();
                for (String fieldName : fieldSet) {
            if (null == expr.getVariableValue(fieldName)) {
                String fvalue = "1111";
                expr.setVariableValue(fieldName, fvalue);
            }
        }

        Valuable result = expr.evaluate();
        return (result.getValue() == null) ? "" : result.getValue().toString();
    }

单个的自定义函数设计与实现是非常简单的。麻烦的可能是表达式配置会多重嵌套函数或者表达式,这点就要自己摸索啦,熟能生巧,多配置一些复杂的表达式就明白了。