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;
}
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;
}
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;
}
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;
}
Aggregations