}
@SuppressWarnings("unchecked")
@Override
public ValueHolder evaluate(final FormulaContext ctx, final ValueHolder[] params) throws FormulaReturnException {
ValueHolder ret = null;
Object result = null;
// Errors cannt be used in a simple function. You must implement them as generic functions
if (params != null) {
for (int i = 0; i < params.length; i++) {
if (params[i].dataType == DataType.ERROR)
return params[i];
}
}
try {
if (varArgClass != null) {
Collection<Object[]> values = new ParameterCollectionObject<Object>(params, (Class<Object>) varArgClass, false);
// Our last parameter is a "varArg" this means, the LAST parameter is an array[]
Object[] tmpParams = new Object[paramCount];
for (Object[] value : values) {
int i = 0;
if (useContext) {
tmpParams[i++] = ctx;
}
if (i == paramCount) {
// that's not possible when useContext is true unless you specify FormulaContext... ctx
} else if (i == paramCount - 1) {
// exactly one parameter left. this is our vararg
tmpParams[i++] = value;
}
result = method.invoke(null, tmpParams);
if (result != null) {
if (ret == null) {
ret = ValueHolder.createValueHolder(result.getClass(), values.size());
}
ret.add(result);
}
}
} else {
Collection<Object[]> values = new ParameterCollectionObject<Object>(params, Object.class, false);
for (Object[] value : values) {
if (useContext) {
Object[] tmpParams;
if (value == null) {
tmpParams = new Object[1];
} else {
tmpParams = new Object[value.length + 1];
System.arraycopy(value, 0, tmpParams, 1, value.length);
}
tmpParams[0] = ctx;
result = method.invoke(null, tmpParams);
} else {
result = method.invoke(null, value);
}
if (result != null) {
if (ret == null) {
ret = ValueHolder.createValueHolder(result.getClass(), values.size());
}
ret.add(result);
}
}
}
return ret;