001 /*
002 * Copyright (c) 2005 Einar Pehrson <einar@pehrson.nu>.
003 *
004 * This file is part of
005 * CleanSheets - a spreadsheet application for the Java platform.
006 *
007 * CleanSheets is free software; you can redistribute it and/or modify
008 * it under the terms of the GNU General Public License as published by
009 * the Free Software Foundation; either version 2 of the License, or
010 * (at your option) any later version.
011 *
012 * CleanSheets is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015 * GNU General Public License for more details.
016 *
017 * You should have received a copy of the GNU General Public License
018 * along with CleanSheets; if not, write to the Free Software
019 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020 */
021 package csheets.core.formula.lang;
022
023 import java.lang.reflect.InvocationTargetException;
024 import java.lang.reflect.Method;
025
026 import csheets.core.IllegalValueTypeException;
027 import csheets.core.Value;
028 import csheets.core.formula.Expression;
029 import csheets.core.formula.Function;
030 import csheets.core.formula.FunctionParameter;
031
032 /**
033 * A numeric function that invokes a method object.
034 * @author Einar Pehrson
035 */
036 public class NumericFunction implements Function {
037
038 /** The method that the function invokes */
039 private Method method;
040
041 /**
042 * Creates a new math reflection function.
043 */
044 public NumericFunction(Method method) {
045 this.method = method;
046 }
047
048 public String getIdentifier() {
049 return method.getName().toUpperCase();
050 }
051
052 public Value applyTo(Expression[] arguments) throws IllegalValueTypeException {
053 // Fetches values
054 double[] values = new double[arguments.length];
055 for (int i = 0; i < arguments.length; i++)
056 values[i] = arguments[i].evaluate().toDouble();
057
058 // Invokes method
059 try {
060 if (values.length == 0)
061 return new Value((Number)method.invoke(null));
062 else if (values.length == 1)
063 return new Value((Number)method.invoke(null, values[0]));
064 else if (values.length == 2)
065 return new Value((Number)method.invoke(null, values[0], values[1]));
066 else
067 return new Value((Number)method.invoke(null, values[0], values[1], values[2]));
068 } catch (IllegalAccessException e) {
069 return new Value(e);
070 } catch (IllegalArgumentException e) {
071 return new Value(e);
072 } catch (InvocationTargetException e) {
073 return new Value(e);
074 }
075 }
076
077 public FunctionParameter[] getParameters() {
078 Class[] paramTypes = method.getParameterTypes();
079 FunctionParameter[] params = new FunctionParameter[paramTypes.length];
080 for (int i = 0; i < paramTypes.length; i++)
081 params[i] = new FunctionParameter(Value.Type.NUMERIC, "Parameter " + i, false, "Unknown");
082 return params;
083 }
084
085 public boolean isVarArg() {
086 return method.isVarArgs();
087 }
088 }