@Override public final short getResultType() { FunctionsDefinitions def = FunctionsDefinitions.getInstance(); Function function = def.getFunction(key); if (function == null) { return Expression.TYPE_UNDEF; } else { Method method = function.getMethod(); if (method.getReturnType() == Integer.TYPE) { return Expression.TYPE_INTEGER; } else if (method.getReturnType() == Short.TYPE) { return Expression.TYPE_INTEGER; } else if (method.getReturnType() == Double.TYPE) { return Expression.TYPE_FLOAT; } else if (method.getReturnType() == Float.TYPE) { return Expression.TYPE_FLOAT; } else if (method.getReturnType() == String.class) { return Expression.TYPE_NUMERIC; } else { return Expression.TYPE_UNDEF; } } }
@Override public final Object eval() throws ArithmeticException { FunctionsDefinitions def = FunctionsDefinitions.getInstance(); Function function = def.getFunction(key); if (function == null) { throw new ArithmeticException( "Function " + key.getName() + "( " + key.getParamsSize() + " parameters) does not exist"); } else { Method method = function.getMethod(); if (fields == null) { initFieldsArray(function, method); } Object obj = function.getObject(); if (varargs) { Class clazz = method.getParameterTypes()[fields.length - 1]; Class ctype = getVarargType(clazz); if (ctype == Integer.TYPE) { fillIntField(fields); } else if (ctype == Float.TYPE) { fillFloatField(fields); } else { fillObjectField(fields); } } else { for (int i = 0; i < exprs.size(); i++) { Expression expr = exprs.get(i); Object _f = null; if (expr.getResultType() == TYPE_INTEGER) { _f = getField(expr.evalAsInt(), method.getParameterTypes()[i]); } else if (expr.getResultType() == TYPE_FLOAT) { _f = getField(expr.evalAsFloat(), method.getParameterTypes()[i]); } else if (expr.getResultType() == TYPE_BOOL) { _f = getField(expr.evalAsBoolean(), method.getParameterTypes()[i]); } else { _f = getField(expr.eval(), method.getParameterTypes()[i]); } fields[i] = _f; } } try { Object result = null; if (varargs) { result = method.invoke(obj, fields); } else { result = method.invoke(obj, fields); } if (method.getReturnType() == Integer.TYPE) { return result; } else if (method.getReturnType() == Short.TYPE) { return ((Short) result).intValue(); } else if (method.getReturnType() == Double.TYPE) { return ((Double) result).floatValue(); } else if (method.getReturnType() == Float.TYPE) { Float f = (Float) result; if (f.isInfinite()) { throw newArithmeticException(function); } return f; } else if (method.getReturnType() == Boolean.TYPE) { return ((Boolean) result).booleanValue(); } else { return result; } } catch (IllegalAccessException ex) { ArithmeticException e = new ArithmeticException("IllegalAccessException for function " + function.getName()); throw e; } catch (IllegalArgumentException ex) { ArithmeticException e = new ArithmeticException("Illegal argument for function " + function.getName()); throw e; } catch (InvocationTargetException ex) { Throwable _ex = ex.getCause(); String message = null; if (_ex != null) { message = "Exception in function " + function.getName() + " (" + _ex.getMessage() + ")"; } else { message = "Exception in function " + function.getName(); } ArithmeticException e = new ArithmeticException(message); e.initCause(_ex); e.setStackTrace(_ex.getStackTrace()); throw e; } } }