/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package reportgen.math.reference.function.values;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import reportgen.utils.ReportException;
import reportgen.math.MathExpressionOperand;
/**
*
* @author axe
*/
public abstract class MathFunctionGeneric extends MathFunctionType {
private final boolean canBeNullArg;
public MathFunctionGeneric(String name, String title,
int minArgumentCount, int maxArgumentCount, boolean canBeNullArg) {
super(name, title, minArgumentCount, maxArgumentCount);
this.canBeNullArg = canBeNullArg;
}
@Override
public Object getValue(List<MathExpressionOperand> args, Map constants)
throws ReportException {
List<Object> arguments = new ArrayList<Object>();
List<Class> operandClasses = new ArrayList<Class>();
checkArgumentsCount(args.size());
for(int i=0; i<args.size(); i++) {
//dont check static cast, because of validation earlier
MathExpressionOperand operand = args.get(i);
Object arg = operand.getValue(constants);
arguments.add(arg);
operandClasses.add(arg != null ? arg.getClass() : null);
}
List<Class> cls = new ArrayList<Class>();
for (int i = 0; i < arguments.size(); i++) {
Class object = arguments.get(i) != null ?
arguments.get(i).getClass() : null;
if(object == null
&& !canBeNullArg) {
return null;
}
cls.add(object);
}
checkArgumentsTypes(cls);
return calculate(arguments);
}
@Override
protected void checkArgumentsTypes(List<Class> operands) throws ReportException {
Integer errorIndex = checkArgumentClass(operands);
if(errorIndex != null) {
throw new ReportException("Несоответствие типа аргумента функции '"
+ getTitle()
+ "'. Аргумент #" + errorIndex+1 + " имеет тип "
//@todo replace class name by human readable string
+ (operands.get(errorIndex) != null ?
operands.get(errorIndex).toString() : "null"));
}
}
protected abstract Integer checkArgumentClass(List<Class> operands);
protected abstract Object calculate(List<Object> arguments) throws ReportException;
}