29 由表达式求值器

maven依赖

 <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <surefire.redirectTestOutputToFile>true</surefire.redirectTestOutputToFile>
        <groovy.version>2.1.6</groovy.version>
        <slf4j.version>1.7.5</slf4j.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.codehaus.groovy</groupId>
            <artifactId>groovy-all</artifactId>
            <version>${groovy.version}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>${slf4j.version}</version>
        </dependency>
    </dependencies>

 

Groovy新版本依赖:官网地址:https://groovy.apache.org/download.html

 <dependency>
            <groupId>org.apache.groovy</groupId>
            <artifactId>groovy-all</artifactId>
            <version>4.0.5</version>
        </dependency>

 

代码:1、接口

package com.da.tool.util.expression;

import java.util.Map;

/**
 * 表达式处理器接口
 */
public interface IExpressionProcessor {

    /**
     * 配置项
     * @return
     */
    IExpressionProcessor withConf(Map<String,Object> map);

    /**
     * 设置表达式
     * @param expression
     * @return
     */
    IExpressionProcessor withExpression(String expression);

    /**
     * 设置数据    名称:值
     * @param data
     * @return
     */
    IExpressionProcessor withData(Map<String,Object> data);

    /**
     * 根据表达式和值计算表达是的值
     * @param <T>
     * @return
     */
    <T> T calculationExpression();

}

 

 

2、实现类

package com.da.tool.util.expression.impl;

import com.da.tool.util.expression.IExpressionProcessor;
import groovy.lang.Binding;
import groovy.lang.GroovyShell;
import groovy.lang.Script;
import org.codehaus.groovy.control.CompilerConfiguration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;

/**
 * 表达式处理器类
 */
public class ExpressionProcessor implements IExpressionProcessor{

    private static final Logger LOGGER = LoggerFactory.getLogger(ExpressionProcessor.class);
    /**
     * 配置属性
     */
    private Map<String, Object> map;

    /**
     * 表达式
     */
    private String expression;

    /**
     * 数据    名称:值
     * @param data
     * @return
     */
    private Map<String, Object> data;

    private static final GroovyShell shell;

    private Script expressionScript;

    static {

        CompilerConfiguration cfg = new CompilerConfiguration();

        cfg.setScriptBaseClass(Expression.class.getName());

        shell = new GroovyShell(ExpressionProcessor.class.getClassLoader(), new Binding(), cfg);
    }
    /**
     * 无参构造方法
     */
    public ExpressionProcessor() {
    }

    @Override
    public ExpressionProcessor withConf(Map<String, Object> map) {

        this.map = map;

        return this;
    }

    @Override
    public ExpressionProcessor withExpression(String expression) {

        if(null == expression || expression.trim().equals("")){

            LOGGER.error("expression is null or blank,can not generate rowkey");

            return null;

        }

        this.expression = expression;

        try {
            expressionScript = shell.parse(expression);
        } catch (Exception e) {
            LOGGER.error("Parser expression [{}] error", expression, e);
            throw e;
        }

        return this;
    }

    @Override
    public ExpressionProcessor withData(Map<String, Object> data) {

        this.data = data;

        if(null == data){

            LOGGER.error("data is null,can not generate rowkey");

            return null;

        }

        return this;
    }

    @Override
    public String calculationExpression() {

        String rowkey = null;

        try {
            expressionScript.setBinding(new Binding(data));

            rowkey = (String) expressionScript.run();

        } catch (Exception e){

            LOGGER.error("生成主键发生错误,请检查数据是否合法:{} ", data);

            return rowkey;
        }

        if (rowkey == null) LOGGER.error("存在一行数据无法生成rowkey,原始数据为:{}", data);

        return rowkey;

    }

    public Map<String, Object> getMap() {
        return map;
    }


    public String getExpression() {
        return expression;
    }


    public Map<String, Object> getData() {
        return data;
    }

}

 

3、支持的表达式类

package com.da.tool.util.expression.impl;

import groovy.lang.Script;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.Serializable;
import java.lang.reflect.Method;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 */
public class Expression extends Script implements Serializable {

    private static final Logger LOGGER = LoggerFactory.getLogger(Expression.class);


    /**
     * 格式化时间类型
     *
     * @author zhuchao 2016年1月25日 下午4:39:15
     * @param time
     * @param pattern
     * @return
     */
    public static String formatString(Object time, String pattern) {
        return String.format(pattern, time);
    }


    /**
     * 求hash值,并对hash取模,取模范围有rang和start确定
     *
     * @author zhuchao 2016年1月25日 下午4:41:54
     * @param s
     * @param rang
     * @param start
     * @return
     */
    public static int hash(String s, int rang, int start) {
        return Math.abs(s.hashCode()) % rang + 1 + start;
    }

    /**
     * 对传入字符串进行hash并将hash得到的值按指定格式进行格式化并插入到字符串指定位置中
     *
     * @author zhuchao 2016年1月26日 下午1:58:23
     * @param s
     * @param rang
     * @param start
     * @param pattern
     * @param offset
     * @return
     */
    public static String hashFormatAndInsert(String s, int rang, int start, String pattern, int offset) {
        return insert(offset, formatString(hash(s, rang, start), pattern), s);
    }

    /**
     * 字符串截取
     *
     * @author zhuchao 2016年1月25日 下午6:50:24
     * @param s
     * @param beginIndex
     * @param endIndex
     * @return
     */
    public static String substring(String s, int beginIndex, int endIndex) {
        if(null==s || s.isEmpty()){
            return "";
        }
        String result = null;
        try{
            result=s.substring(beginIndex,endIndex);
        }catch (StringIndexOutOfBoundsException e){
            LOGGER.error("获取字符串{}的substring出现异常,异常信息为:{}",s,e.getMessage());
        }
        return result;
    }


    /**
     * str为null或者“”是返回“”
     * @param str 字符串
     * @param defaultValue  默认值
     * @return str为null或者“”是返回“”  其它情况返回str本身
     */
    public static String emptyDefault(String str,String defaultValue){
        if(null==str || str.isEmpty()){
            return defaultValue;
        }
        return str;
    }

    /**
     * 插入s到src指定位置
     *
     * @author zhuchao 2016年1月26日 上午11:40:47
     * @param offset
     * @param s
     * @param src
     * @return
     */
    public static String insert(int offset, String s, String src) {
        StringBuilder sb = new StringBuilder(src);
        sb.insert(offset, s);
        return sb.toString();
    }

    /**
     * 去除两边的空格
     * @param str
     * @return
     */
    public static String trim(String str){return str.trim();}





    /**
     * 添加前缀
     * @param srcStr
     * @param prefix
     * @return
     */
    public static String addPrefix(String srcStr, String prefix){

        return prefix+srcStr;

    }

    /**
     * 将rowkey表达式中的数据转换为string
     * @param obj
     * @return
     */
    public static String toString(Object obj){
        if(null==obj){
            return "";
        }
        return obj.toString();

    }

    /**
     * 添加后缀
     * @return
     */
    public static String addSuffix(String srcStr, String suffix){

        return srcStr+suffix;

    }


    /**
     * 求hash值,并对hash取模,取模范围有rang和start确定
     * @param rang 取模范围
     * @param start 开始值
     * @param num 输出位数
     * @param s 根据column数组哈希
     * @return  hash值
     */
    public static String hashStringArray(int rang, int start,int num,Object... s) {
        int  hashValue=0;
        for (Object object : s) {
            hashValue=hashValue+object.hashCode();
        }
        String hashStringValue= Math.abs(hashValue) % rang  + start+"";
        int size = hashStringValue.length();
        while (size < num) {
            size++;
            hashStringValue = "0" + hashStringValue;
        }
        return hashStringValue;
    }


    /**
     * 交通rowKey生成规则定制函数,通过时间字段获取年月,目前不支持字段类型为String,字段值为空时返回null
     * @param time 时间字段,一般为pass_time
     * @return 返回格式为yyMM的字符串
     */
    public static String transDate(Object time){
        if(time==null )
            return null;
        if(time instanceof String){
            LOGGER.error("主键函数中transDate的入参不能是String类型,请确认json中的字段类型!");
        }
        DateFormat sdf = new SimpleDateFormat("yyMM");

        return sdf.format(time);
    }
    /**
     * 交通rowKey生成规则定制函数,将日期类型转换为long型
     * @param time 时间字段,一般为pass_time
     * @return 返回格式为long
     */
    public static Long dateToLong(Object time){

        Long date= Timestamp.valueOf(String.valueOf(time)).getTime();

        return date;

    }



    /**
     * fieldStrs 字符串拼接一起,然后获取hash值,再对remainder取余
     *  散列值    3位,(年月+数据类型+日+全局ID)的哈希值除999取余
     * @param remainder
     * @param fieldStrs
     * @return
     */
    public static String hashRemainder(int remainder,String ...fieldStrs){
        String sumStr = "";
        for (String fieldStr : fieldStrs) {
            sumStr=sumStr+fieldStr;
        }
        int remainderHash=sumStr.hashCode()%remainder;
        remainderHash=(remainderHash<0)? -remainderHash:remainderHash;
        String result=String.valueOf(remainderHash);
        int num=result.length();
        int size = String.valueOf(remainder).length();
        while (num < size) {
            num++;
            result = "0" + result;
        }
        return result;
    }


    /**
     * 把字符串转化成指定位数size
     * 不足,前面补充supplementValue
     * 超出,isCutFront为true截取前面的size位
     * @param original
     * @param size
     * @param supplementValue
     * @return
     */
    public static String supplementStringFront(String original,int size,String supplementValue){
        return cutString(original,size,true,supplementValue,true);
    }
    /**

     * @param original
     * @param size
     * @param supplementValue
     * @param front
     * @return
     */
    /**
     * 把字符串转化成指定位数size
     * 不足,isFrontSupplement为true,前面补充supplementValue,isFrontSupplement为false,后面补充supplementValue
     * 超出,isCutFront为true截取前面的size位,isCutFront为false,截取后面的size位
     * @param original
     * @param size
     * @param isFrontSupplement
     * @param supplementValue
     * @param isCutFront
     * @return
     */
    public static String cutString(String original,int size,Boolean isFrontSupplement,String supplementValue,Boolean isCutFront){
        int length=original.length();
        String result = null;
        if(length==size){
            result=original;
        }else if(length<size){
            if(isFrontSupplement){
                result=supplementValue+original;
                while(result.length()<size){
                    result=supplementValue+result;
                }
            }else{
                result=original+supplementValue;
                while(result.length()<size){
                    result=result+supplementValue;
                }
            }
        }
        //length>size
        else{
            if(isCutFront){
                result=original.substring(0,size);
            }else {
                result=original.substring(original.length()-size,original.length());
            }
        }
        return  result;
    }


    //rowKey需要的类型转换(智能算法组实现)
    public static String transformRowKey(String date){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat sdf1 = new SimpleDateFormat("yyyyMMdd");
        Date date1 = null;
        try {
            date1 = sdf.parse(date);
        } catch (ParseException e) {
            LOGGER.error("transformRowKey生成rowkey失败,日期格式转换出错!");
        }
        return  sdf1.format(date1);
    }


    /*
     * (non-Javadoc)
     *
     * @see groovy.lang.Script#run()
     */
    @Override
    public Object run() {
        // show usage
        Method[] methods = Expression.class.getDeclaredMethods();
        StringBuilder sb = new StringBuilder();
        for (Method method : methods) {
            sb.append(method);
        }
        return sb.substring(0, sb.length() - 1);
    }

}

 

4、测试类

package com.da.tool.util.expression;

import com.da.tool.util.expression.impl.ExpressionProcessor;

import java.util.HashMap;
import java.util.Map;

/**
* 表达式生成器例子
*/
public class ExpressionProcessorExample {

public static void main(String[] args) {

//表达式
String expression="addSuffix(A,'_suffix') + 123";
//数据
Map<String,Object> data= new HashMap<>();

data.put("A", "preffix");

String rowKey;

IExpressionProcessor expressionProcessor = new ExpressionProcessor()
.withExpression(expression)
.withData(data);

rowKey = expressionProcessor.calculationExpression();

System.out.println(rowKey);

}
}


执行结果: preffix_suffix123
posted @ 2017-01-23 10:21  life_start  阅读(351)  评论(0编辑  收藏  举报