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 */ 021package csheets.core.formula.lang; 022 023import java.lang.reflect.InvocationTargetException; 024import java.lang.reflect.Method; 025 026import csheets.core.IllegalValueTypeException; 027import csheets.core.Value; 028import csheets.core.formula.Expression; 029import csheets.core.formula.Function; 030import csheets.core.formula.FunctionParameter; 031 032/** 033 * A numeric function that invokes a method object. 034 * @author Einar Pehrson 035 */ 036public 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}