Search in sources :

Example 1 with ObjectMethodMatchConf

use of org.beetl.core.om.ObjectMethodMatchConf in project beetl2.0 by javamonkey.

the class MutipleFunctionWrapper method call.

@Override
public Object call(Object[] paras, Context ctx) {
    Class[] parameterType = null;
    try {
        // 比较慢的情况,要考虑到底哪个方法适合调用
        Class[] parameterContextType = null;
        Class[] parameterNoContextType = null;
        for (MethodContext mc : mcs) {
            if (mc.contextRequired) {
                if (parameterContextType == null) {
                    parameterContextType = new Class[paras.length + 1];
                    int i = 0;
                    for (Object para : paras) {
                        parameterContextType[i++] = para != null ? para.getClass() : null;
                    }
                    parameterContextType[i] = Context.class;
                }
                parameterType = parameterContextType;
            } else {
                if (parameterNoContextType == null) {
                    parameterNoContextType = new Class[paras.length];
                    int i = 0;
                    for (Object para : paras) {
                        parameterNoContextType[i++] = para != null ? para.getClass() : null;
                    }
                }
                parameterType = parameterNoContextType;
            }
            ObjectMethodMatchConf conf = ObjectUtil.match(mc.m, parameterType);
            if (conf == null) {
                continue;
            }
            Object[] newParas = null;
            if (mc.contextRequired) {
                newParas = this.getContextParas(paras, ctx);
            } else {
                newParas = paras;
            }
            newParas = conf.convert(newParas);
            return mc.m.invoke(target, newParas);
        }
    } catch (IllegalArgumentException e) {
        BeetlException ex = new BeetlException(BeetlException.NATIVE_CALL_EXCEPTION, "参数不匹配 " + this.functionName, e);
        throw ex;
    } catch (IllegalAccessException e) {
        BeetlException ex = new BeetlException(BeetlException.NATIVE_CALL_EXCEPTION, "非法访问方法 " + this.functionName, e);
        throw ex;
    } catch (InvocationTargetException e) {
        Throwable t = e.getTargetException();
        if (t instanceof BeetlException) {
            throw (BeetlException) t;
        } else {
            BeetlException be = new BeetlException(BeetlException.NATIVE_CALL_EXCEPTION, "调用方法出错 " + this.functionName, t);
            throw be;
        }
    }
    BeetlException ex = new BeetlException(BeetlException.NATIVE_CALL_INVALID, "找不到方法 " + this.functionName + BeetlUtil.getParameterDescription(parameterType));
    throw ex;
}
Also used : BeetlException(org.beetl.core.exception.BeetlException) ObjectMethodMatchConf(org.beetl.core.om.ObjectMethodMatchConf) InvocationTargetException(java.lang.reflect.InvocationTargetException)

Example 2 with ObjectMethodMatchConf

use of org.beetl.core.om.ObjectMethodMatchConf in project beetl2.0 by javamonkey.

the class NativeCallExpression method infer.

@Override
public void infer(InferContext inferCtx) {
    Type type = null;
    if (insNode != null) {
        insNode.ref.infer(inferCtx);
        type = insNode.ref.type.copy();
    } else {
        Class cls = inferCtx.gt.loadClassBySimpleName(this.clsNode.cls);
        if (cls == null) {
            BeetlException be = new BeetlException(BeetlException.NATIVE_CALL_EXCEPTION, "该类不存在");
            be.pushToken(GrammarToken.createToken(clsNode.cls, token.line));
            throw be;
        }
        type = new Type(cls);
    }
    for (NativeNode node : chain) {
        if (type.cls == Object.class) {
            this.type = type;
            // 以后生成代码有问题
            return;
        }
        if (node instanceof NativeAtrributeNode) {
            String attr = ((NativeAtrributeNode) node).attribute;
            try {
                Field f = type.cls.getField(attr);
                Class c = f.getType();
                type.cls = c;
            } catch (SecurityException e) {
                BeetlException be = new BeetlException(BeetlException.NATIVE_CALL_EXCEPTION, "无法访问属性", e);
                be.pushToken(GrammarToken.createToken(attr, token.line));
                throw be;
            } catch (NoSuchFieldException e) {
                BeetlException be = new BeetlException(BeetlException.NATIVE_CALL_EXCEPTION, "无此属性", e);
                be.pushToken(GrammarToken.createToken(attr, token.line));
                throw be;
            }
        } else if (node instanceof NativeArrayNode) {
            if (!type.cls.isArray()) {
                BeetlException be = new BeetlException(BeetlException.ARRAY_TYPE_ERROR);
                // 最好是把上一个字符显示出来
                be.pushToken(GrammarToken.createToken("[]", token.line));
                throw be;
            }
            type.cls = type.cls.getComponentType();
        } else if (node instanceof NativeMethodNode) {
            NativeMethodNode methodNode = (NativeMethodNode) node;
            String method = methodNode.method;
            Expression[] expList = methodNode.paras;
            Class[] argTypes = expList.length == 0 ? ObjectUtil.EMPTY_CLASS_ARRAY : new Class[expList.length];
            for (int i = 0; i < expList.length; i++) {
                expList[i].infer(inferCtx);
                argTypes[i] = expList[i].type.cls;
            }
            try {
                ObjectMethodMatchConf conf = ObjectUtil.findMethod(type.cls, method, argTypes);
                if (conf == null) {
                    type.cls = Object.class;
                } else {
                    type.cls = conf.method.getReturnType();
                }
            } catch (SecurityException e) {
                BeetlException be = new BeetlException(BeetlException.NATIVE_CALL_EXCEPTION, "不能调用方法");
                be.pushToken(GrammarToken.createToken(method, token.line));
                throw be;
            }
        }
    }
    this.type = type;
}
Also used : NativeArrayNode(org.beetl.core.statement.nat.NativeArrayNode) BeetlException(org.beetl.core.exception.BeetlException) NativeNode(org.beetl.core.statement.nat.NativeNode) NativeAtrributeNode(org.beetl.core.statement.nat.NativeAtrributeNode) Field(java.lang.reflect.Field) ObjectMethodMatchConf(org.beetl.core.om.ObjectMethodMatchConf) NativeMethodNode(org.beetl.core.statement.nat.NativeMethodNode)

Example 3 with ObjectMethodMatchConf

use of org.beetl.core.om.ObjectMethodMatchConf in project beetl2.0 by javamonkey.

the class MutipleFunctionWrapper method getReturnType.

public Class getReturnType(Class[] parameterType) {
    Class[] parameterContextType = null;
    Class[] parameterNoContextType = null;
    for (MethodContext mc : mcs) {
        if (mc.contextRequired) {
            parameterContextType = new Class[parameterType.length + 1];
            System.arraycopy(parameterType, 0, parameterContextType, 0, parameterType.length);
        } else {
            parameterContextType = parameterType;
        }
        ObjectMethodMatchConf matchConf = ObjectUtil.findMethod(target.getClass(), this.methodName, parameterContextType);
        if (matchConf != null) {
            return matchConf.method.getReturnType();
        }
    }
    // 如果找不到合适类型,则认为调用返回Object
    return Object.class;
}
Also used : ObjectMethodMatchConf(org.beetl.core.om.ObjectMethodMatchConf)

Example 4 with ObjectMethodMatchConf

use of org.beetl.core.om.ObjectMethodMatchConf in project beetl2.0 by javamonkey.

the class NativeCallExpression method evaluate.

public Object evaluate(Context ctx) {
    Class targetCls = null;
    Object targetObj = null;
    NativeNode lastNode = null;
    if (insNode != null) {
        targetObj = insNode.ref.evaluate(ctx);
        if (targetObj != null) {
            targetCls = targetObj.getClass();
        }
        lastNode = insNode;
    } else {
        targetCls = ctx.gt.loadClassBySimpleName(this.clsNode.cls);
        if (targetCls == null) {
            BeetlException be = new BeetlException(BeetlException.NATIVE_CALL_EXCEPTION, "该类不存在");
            be.pushToken(GrammarToken.createToken(clsNode.cls, token.line));
            throw be;
        }
        lastNode = clsNode;
    }
    for (NativeNode node : chain) {
        if (node instanceof NativeAtrributeNode) {
            String attr = ((NativeAtrributeNode) node).attribute;
            try {
                checkNull(targetCls, lastNode);
                Field f = targetCls.getField(attr);
                if (!Modifier.isStatic(f.getModifiers())) {
                    checkNull(targetObj, lastNode);
                }
                targetObj = f.get(targetObj);
                targetCls = f.getType();
            } catch (SecurityException e) {
                BeetlException be = new BeetlException(BeetlException.NATIVE_CALL_EXCEPTION, "不能调用属性", e);
                be.pushToken(GrammarToken.createToken(attr, token.line));
                throw be;
            } catch (NoSuchFieldException e) {
                BeetlException be = new BeetlException(BeetlException.NATIVE_CALL_EXCEPTION, "无此属性", e);
                be.pushToken(GrammarToken.createToken(attr, token.line));
                throw be;
            } catch (IllegalArgumentException e) {
                BeetlException be = new BeetlException(BeetlException.NATIVE_CALL_EXCEPTION, "访问属性出错", e);
                be.pushToken(GrammarToken.createToken(attr, token.line));
                throw be;
            } catch (IllegalAccessException e) {
                BeetlException be = new BeetlException(BeetlException.NATIVE_CALL_EXCEPTION, "访问属性出错", e);
                be.pushToken(GrammarToken.createToken(attr, token.line));
                throw be;
            }
        } else if (node instanceof NativeArrayNode) {
            checkNull(targetCls, lastNode);
            if (!targetCls.isArray()) {
                BeetlException be = new BeetlException(BeetlException.ARRAY_TYPE_ERROR);
                // 最好是把上一个字符显示出来
                be.pushToken(GrammarToken.createToken("[]", token.line));
                throw be;
            }
            Expression exp = ((NativeArrayNode) node).exp;
            Object value = exp.evaluate(ctx);
            if (value instanceof Number) {
                int index = ((Number) value).intValue();
                targetObj = ((Object[]) targetObj)[index];
                if (targetObj != null) {
                    targetCls = targetObj.getClass();
                } else {
                    // todo or component of array
                    targetCls = null;
                }
            } else {
                BeetlException be = new BeetlException(BeetlException.ARRAY_INDEX_ERROR, "数组指针必须是Number类型");
                be.pushToken(GrammarToken.createToken("[]", token.line));
                throw be;
            }
        } else if (node instanceof NativeMethodNode) {
            NativeMethodNode methodNode = (NativeMethodNode) node;
            String method = methodNode.method;
            Expression[] expList = methodNode.paras;
            this.checkPermit(ctx, targetCls, targetObj, method);
            Object[] args = expList.length == 0 ? ObjectUtil.EMPTY_OBJECT_ARRAY : new Object[expList.length];
            Class[] parameterType = new Class[args.length];
            for (int i = 0; i < expList.length; i++) {
                args[i] = expList[i].evaluate(ctx);
                parameterType[i] = args[i] == null ? null : args[i].getClass();
            }
            this.checkNull(targetCls, lastNode);
            ObjectMethodMatchConf mf = ObjectUtil.findMethod(targetCls, method, parameterType);
            if (mf == null) {
                BeetlException ex = new BeetlException(BeetlParserException.NATIVE_CALL_INVALID, "根据参数未找到匹配的方法" + method + BeetlUtil.getParameterDescription(parameterType));
                ex.pushToken(GrammarToken.createToken(lastNode.getName(), token.line));
                throw ex;
            }
            if (targetObj == null && !Modifier.isStatic(mf.method.getModifiers())) {
                BeetlException ex = new BeetlException(BeetlException.NULL);
                ex.pushToken(GrammarToken.createToken(lastNode.getName(), token.line));
                throw ex;
            }
            try {
                targetObj = ObjectUtil.invoke(targetObj, mf, args);
                if (targetObj != null) {
                    targetCls = targetObj.getClass();
                } else {
                    targetCls = null;
                }
            } catch (SecurityException e) {
                BeetlException be = new BeetlException(BeetlException.NATIVE_CALL_EXCEPTION, "不能调用方法", e);
                be.pushToken(GrammarToken.createToken(method, token.line));
                throw be;
            } catch (IllegalArgumentException e) {
                BeetlException be = new BeetlException(BeetlException.NATIVE_CALL_EXCEPTION, "错误的参数", e);
                be.pushToken(GrammarToken.createToken(method, token.line));
                throw be;
            } catch (IllegalAccessException e) {
                BeetlException be = new BeetlException(BeetlException.NATIVE_CALL_EXCEPTION, "无法访问方法", e);
                be.pushToken(GrammarToken.createToken(method, token.line));
                throw be;
            } catch (InvocationTargetException e) {
                BeetlException be = new BeetlException(BeetlException.NATIVE_CALL_EXCEPTION, "内部调用报错", e.getTargetException());
                be.pushToken(GrammarToken.createToken(method, token.line));
                throw be;
            }
        }
        lastNode = node;
    }
    return targetObj;
}
Also used : NativeArrayNode(org.beetl.core.statement.nat.NativeArrayNode) BeetlException(org.beetl.core.exception.BeetlException) NativeNode(org.beetl.core.statement.nat.NativeNode) InvocationTargetException(java.lang.reflect.InvocationTargetException) NativeAtrributeNode(org.beetl.core.statement.nat.NativeAtrributeNode) Field(java.lang.reflect.Field) ObjectMethodMatchConf(org.beetl.core.om.ObjectMethodMatchConf) NativeMethodNode(org.beetl.core.statement.nat.NativeMethodNode)

Aggregations

ObjectMethodMatchConf (org.beetl.core.om.ObjectMethodMatchConf)4 BeetlException (org.beetl.core.exception.BeetlException)3 Field (java.lang.reflect.Field)2 InvocationTargetException (java.lang.reflect.InvocationTargetException)2 NativeArrayNode (org.beetl.core.statement.nat.NativeArrayNode)2 NativeAtrributeNode (org.beetl.core.statement.nat.NativeAtrributeNode)2 NativeMethodNode (org.beetl.core.statement.nat.NativeMethodNode)2 NativeNode (org.beetl.core.statement.nat.NativeNode)2