当前位置: 首页 > 工具软件 > QLExpress > 使用案例 >

QLExpress操作符底层实现原理(二)

越开畅
2023-12-01

QLExpress操作符底层实现原理(二)

1.OperatorEqualsLessMore

代码如下:

public class OperatorEqualsLessMore extends Operator {
    public OperatorEqualsLessMore(String name) {
        this.name = name;
    }

    public OperatorEqualsLessMore(String aliasName, String name, String errorInfo) {
        this.name = name;
        this.aliasName = aliasName;
        this.errorInfo = errorInfo;
    }

    @Override
    public Object executeInner(Object[] list) throws Exception {
        return executeInner(list[0], list[1]);
    }

    public Object executeInner(Object op1, Object op2) throws Exception {
        return executeInner(this.name, op1, op2);
    }

    public static boolean executeInner(String opStr, Object obj1, Object obj2) throws Exception {
        if ("==".equals(opStr)) {
            return Operator.objectEquals(obj1, obj2);
        }
        if ("!=".equals(opStr) || "<>".equals(opStr)) {
            return !Operator.objectEquals(obj1, obj2);
        }

        // 进行其他大小比较操作
        if (obj1 == null || obj2 == null) {
            if (isCompareNullLessMoreAsFalse()) {
                return false;
            }
            throw new QLException("空操作数无法进行数字比较操作:left = " + obj1 + ",right = " + obj2);
        }
        int i = Operator.compareData(obj1, obj2);
        boolean result = false;
        if (i > 0) {
            result = ">".equals(opStr) || ">=".equals(opStr) || "!=".equals(opStr) || "<>".equals(opStr);
        } else if (i == 0) {
            result = "=".equals(opStr) || "==".equals(opStr) || ">=".equals(opStr) || "<=".equals(opStr);
        } else if (i < 0) {
            result = "<".equals(opStr) || "<=".equals(opStr) || "!=".equals(opStr) || "<>".equals(opStr);
        }
        return result;
    }
}

该操作符的作用是处理比较操作符号。

2.OperatorEvaluate

public class OperatorEvaluate extends OperatorBase {
    public OperatorEvaluate(String name) {
        this.name = name;
    }

    public OperatorEvaluate(String aliasName, String name, String errorInfo) {
        this.name = name;
        this.aliasName = aliasName;
        this.errorInfo = errorInfo;
    }

    @Override
    public OperateData executeInner(InstructionSetContext parent, ArraySwap list) throws Exception {
        return executeInner(parent, list.get(0), list.get(1));
    }

    public OperateData executeInner(InstructionSetContext parent,
        OperateData op1, OperateData op2) throws Exception {
        Class<?> targetType = op1.getDefineType();
        Class<?> sourceType = op2.getType(parent);
        if (targetType != null) {
            if (!ExpressUtil.isAssignable(targetType, sourceType)) {
                throw new QLException("赋值时候,类型转换错误:" + ExpressUtil.getClassName(sourceType) + " 不能转换为 "
                    + ExpressUtil.getClassName(targetType));
            }

        }
        Object result = op2.getObject(parent);
        if (targetType != null) {
            result = ExpressUtil.castObject(result, targetType, false);
        }
        op1.setObject(parent, result);
        return op1;
    }
}

该操作符的作用是进行数据的类型转换。

3.OperatorIf

代码如下:

public class OperatorIf extends OperatorBase {
    public OperatorIf(String name) {
        this.name = name;
    }

    public OperatorIf(String aliasName, String name, String errorInfo) {
        this.name = name;
        this.aliasName = aliasName;
        this.errorInfo = errorInfo;
    }

    @Override
    public OperateData executeInner(InstructionSetContext parent, ArraySwap list) throws Exception {
        if (list.length < 2) {
            throw new QLException("\"" + this.aliasName + "\"操作至少要两个操作数");
        }
        Object obj = list.get(0).getObject(parent);
        if (obj == null) {
            String msg = "\"" + this.aliasName + "\"的判断条件不能为空";
            throw new QLException(msg);
        } else if (!(obj instanceof Boolean)) {
            String msg = "\"" + this.aliasName + "\"的判断条件 必须是 Boolean,不能是:";
            throw new QLException(msg + obj.getClass().getName());
        } else {
            if ((Boolean)obj) {
                return list.get(1);
            } else {
                if (list.length == 3) {
                    return list.get(2);
                }
            }
            return null;
        }
    }
}

该方法主要是条件判断,代码很好理解。

4.OperatorIn

代码如下:

public class OperatorIn extends Operator {
    public OperatorIn(String name) {
        this.name = name;
    }

    public OperatorIn(String aliasName, String name, String errorInfo) {
        this.name = name;
        this.aliasName = aliasName;
        this.errorInfo = errorInfo;
    }

    @Override
    public Object executeInner(Object[] list) throws Exception {
        Object obj = list[0];
        if (obj == null) {
            if (QLExpressRunStrategy.isAvoidNullPointer()) {
                //避免空指针策略异常则返回false
                return false;
            }
            // 对象为空,不能执行方法
            String msg = "对象为空,不能执行方法:";
            throw new QLException(msg + this.name);
        } else if (!((obj instanceof Number) || (obj instanceof String))) {
            String msg = "对象类型不匹配,只有数字和字符串类型才才能执行 in 操作,当前数据类型是:";
            throw new QLException(msg + obj.getClass().getName());
        } else if (list.length == 2 && (list[1].getClass().isArray() || list[1] instanceof List)) {
            if (obj.equals(list[1])) {
                return true;
            } else if (list[1].getClass().isArray()) {
                int len = Array.getLength(list[1]);
                for (int i = 0; i < len; i++) {
                    boolean f = OperatorEqualsLessMore.executeInner("==", obj, Array.get(list[1], i));
                    if (f) {
                        return Boolean.TRUE;
                    }
                }
            } else if (list[1] instanceof List) {
                @SuppressWarnings("unchecked")
                List<Object> array = (List<Object>)list[1];
                for (Object o : array) {
                    boolean f = OperatorEqualsLessMore.executeInner("==", obj, o);
                    if (f) {
                        return Boolean.TRUE;
                    }
                }
            }
            return false;
        } else {
            for (int i = 1; i < list.length; i++) {
                boolean f = OperatorEqualsLessMore.executeInner("==", obj, list[i]);
                if (f) {
                    return Boolean.TRUE;
                }
            }
            return Boolean.FALSE;
        }
    }
}

该操作符的作用是判断对象类型是否符合规定的类型或数组值是否在规定的数组中。如(obj instanceof Number) || (obj instanceof String)判断的是对象类型是否匹配,只有数字和字符串类型才才能执行 in 操作;list[1] instanceof List判断的是数组下标为1的数据是否在数组中。

5.OperatorInstanceOf

代码如下:

public class OperatorInstanceOf extends Operator {
    public OperatorInstanceOf(String anInstanceof) {
        this.name = anInstanceof;
    }

    @Override
    public Object executeInner(Object[] list) {
        Object obj = list[0];
        Object cls = list[1];
        if (obj != null && cls instanceof Class) {
            Class targetClass = (Class)cls;
            Class fromClass = obj.getClass();
            return targetClass.isAssignableFrom(fromClass);
        }
        return false;
    }
}

该操作符的作用是判断对象是否在类中,并返回类名。

6.OperatorLike

代码如下:

public class OperatorLike extends Operator {
    public OperatorLike(String name) {
        this.name = name;
    }

    public OperatorLike(String aliasName, String name, String errorInfo) {
        this.name = name;
        this.aliasName = aliasName;
        this.errorInfo = errorInfo;
    }

    @Override
    public Object executeInner(Object[] list) throws Exception {
        return executeInner(list[0], list[1]);
    }

    public Object executeInner(Object op1, Object op2) throws Exception {
        boolean result = true;
        String s1 = op1.toString();
        String s2 = op2.toString();
        if (s2.contains("%")) {
            String[] list = split(s2, "%");
            int index = 0;
            for (String s : list) {
                if (index >= s1.length()) {
                    result = false;
                    break;
                }
                index = s1.indexOf(s, index);
                if (index < 0) {
                    result = false;
                    break;
                }
                index = index + 1;
            }
        } else {
            result = s1.equals(s2);
        }

        return result;
    }

    public String[] split(String str, String s) {
        int start = 0;
        int end;
        String tmpStr;
        ArrayList<String> list = new ArrayList<>();
        do {
            end = str.indexOf(s, start);
            if (end < 0) {
                tmpStr = str.substring(start);
            } else {
                tmpStr = str.substring(start, end);
            }
            if (tmpStr.length() > 0) {
                list.add(tmpStr);
            }
            start = end + 1;
            if (start >= str.length()) {
                break;
            }
        } while (end >= 0);
        return list.toArray(new String[0]);
    }
}

该操作符的作用是判断两个对象的地址值的字符串编码是否相同。

7.OperatorMinMax

代码如下:

public class OperatorMinMax extends Operator {
    public OperatorMinMax(String name) {
        this.name = name;
    }

    @Override
    public Object executeInner(Object[] list) throws Exception {
        if (list.length == 0) {
            throw new QLException("操作数异常");
        }
        Object result = list[0];

        for (int i = 1; i < list.length; i++) {
            result = executeInner(result, list[i]);
        }
        return result;
    }

    public Object executeInner(Object op1, Object op2) throws Exception {
        Object result = null;
        int compareResult = Operator.compareData(op1, op2);
        if ("min".equals(this.name)) {
            if (compareResult < 0) {
                result = op1;
            } else {
                result = op2;
            }
        } else if ("max".equals(this.name)) {
            if (compareResult < 0) {
                result = op2;
            } else {
                result = op1;
            }
        }
        return result;
    }
}

该操作符的作用是比较两个对象的大小。

8.OperatorMinMax

代码如下:

public class OperatorMultiplyDivide extends Operator {
    public OperatorMultiplyDivide(String name) {
        this.name = name;
    }

    @Override
    public Object executeInner(Object[] list) throws Exception {
        return executeInner(list[0], list[1]);
    }

    public Object executeInner(Object op1, Object op2) throws Exception {
        Object result = null;
        switch (this.getName()) {
            case "*":
                result = OperatorOfNumber.multiply(op1, op2, this.isPrecise);
                break;
            case "/":
                result = OperatorOfNumber.divide(op1, op2, this.isPrecise);
                break;
            case "%"://和mod方法一样,求余运算。
            case "mod":
                result = OperatorOfNumber.modulo(op1, op2);
                break;
            default:
                break;
        }
        return result;
    }
}

该操作符的作用是两个对象进行乘法运算、除法运算、求余运算。

 类似资料: