View Javadoc
1 /* 2 * GeoVISTA Center (Penn State, Dept. of Geography) 3 * Copyright (c), 1999 - 2002, GeoVISTA Center 4 * All Rights Researved. 5 * 6 * Description: 7 * Function classes used only by edu.psu.geovista.app.spreadsheet.formula.Formula to evaluate functions. 8 * Any function needs to have a function handler that implements 9 * the "evaluate" interface of the base class functions.Function. 10 * A function can accept zero, one, or more parameters. Each parameter 11 * is a number, a relative/absolute address or an address range (e.g., A1:B3). 12 13 * The code has some reference to code written by Hua Zhong from Columbia University 14 * 15 * Apr 2, 2003 16 * Time: 10:42:12 PM 17 * @author Jin Chen 18 */ 19 20 package edu.psu.geovista.app.spreadsheet.functions; 21 22 23 24 import edu.psu.geovista.app.spreadsheet.exception.ParserException; 25 26 import javax.swing.table.TableModel; 27 import java.util.*; 28 import java.io.*; 29 import java.awt.*; 30 31 import edu.psu.geovista.app.spreadsheet.formula.Node; 32 import edu.psu.geovista.app.spreadsheet.exception.NoReferenceException; 33 import edu.psu.geovista.app.spreadsheet.formula.Formula; 34 import edu.psu.geovista.app.spreadsheet.table.SSTableModel; 35 import edu.psu.geovista.app.spreadsheet.formula.Cell; 36 import edu.psu.geovista.app.spreadsheet.util.Debug; 37 38 39 public abstract class Function { 40 41 static private ParserException exception = new ParserException("#PARAM?"); 42 //protected HashSet owners;//who use the function now 43 protected Formula owner; 44 45 // whether the specified parameter node is an address range 46 protected boolean isRange(Node param) { 47 LinkedList exp = param.getExp(); 48 return exp.size() == 1 && 49 ((Node)exp.getFirst()).isType(Node.COLON); 50 //((edu.psu.geovista.app.spreadsheet.formula.Node)param.getExp().getFirst()).isType(edu.psu.geovista.app.spreadsheet.formula.Node.COLON); 51 } 52 53 // return the first node of a specified parameter 54 protected Node getFirst(Node param) { 55 return (Node)param.getExp().getFirst(); 56 } 57 58 // whether this function has any parameter 59 protected static void checkParamsExist(Node func) throws ParserException { 60 61 if (func.getParams().size()==0) 62 throw exception; 63 } 64 65 /*** 66 * This gets the first float number of a parameter list, for functions 67 * only accepting a single parameter such as <code>ABS</code>, <code>COS 68 * </code>, etc. 69 * 70 * @param table the SharpTabelModel 71 * @param node the edu.psu.geovista.app.spreadsheet.formula unit 72 * @param col the int column coordinate 73 * @param row the int row coordinate 74 * @return the float number 75 */ 76 protected float getSingleParameter( Node node) 77 throws ParserException,NoReferenceException { 78 // edu.psu.geovista.app.spreadsheet.formula.Node param = node.getNextParam(); 79 LinkedList params = node.getParams(); 80 Debug.showLinkedList(params,"getSingleParameter( ) show params of node "+node ); 81 if (params.size() != 1) 82 throw new ParserException("#PARAM?"); 83 84 LinkedList exp = ((Node)params.getFirst()).getExp(); //??? why first, what if there is multiple parameters 85 Debug.showLinkedList(exp,"getSingleParameter( ) show exp "+exp ); 86 //Formula f=new Formula(this.getOwners() ); 87 return this.getOwner().evaluate(exp) .floatValue(); 88 89 } 90 91 92 /*** 93 * This should be implemented in each function. 94 * 95 * @param table the SharpTabelModel 96 * @param node the function node starting with the funciton name 97 * with a chain of parameters 98 * @param col the int column coordinate 99 * @param row the int row coordinate 100 * @edu.psu.geovista.app.spreadsheet.exception ParserException 101 */ 102 public abstract Number evaluate(Node node) throws ParserException,NoReferenceException; 103 104 105 106 /*** 107 * Return the usage of the function 108 */ 109 public abstract String getUsage(); 110 111 /*** 112 * Return the description of the function 113 */ 114 public abstract String getDescription(); 115 116 /*** 117 * Whether this function requires parameters. 118 * By default yes. 119 * @see FunctionPI 120 * @see FunctionE 121 */ 122 public boolean requireParams() { return true; } 123 124 /*** 125 * Jin: 126 * Only for those function whose arguments is set of range. 127 * e.g.: SUM, AVG,MEAN... 128 * @param node the function node. 129 * @return address(x,y) in view 130 */ 131 public static SelectionRange getRangeArea(Node node) throws ParserException{ 132 SelectionRange range=null; 133 134 checkParamsExist(node); 135 LinkedList params = node.getParams();//only 1 element 136 Node exp=(Node)params.getFirst() ;// expresion Node(type=Node.EXP). e.g. a1:a2 137 Node colonNode=((Node)exp.getParams().getFirst());// colon Node(type=Node.COLON) e.g.: a1:a2 138 range=processColonNode(colonNode); 139 140 return range; 141 } 142 /*** 143 * convert a colon node(which contain 2 ranges) into a SelectionRange 144 */ 145 public static SelectionRange processColonNode(Node colonNode)throws ParserException { 146 SelectionRange range=null; 147 Point[] ps=new Point[2];//a 2 points(sp,ep) 148 Point sp=null,ep=null;//start point, end point of the range 149 //!!! following part is same as Formula's evalueExpression 150 Node start=colonNode.getNextRange() ;//start(upLeft) of the range 151 Node end=start.getNextRange() ;//end (downRight) of the range 152 153 if (start.getType() ==Node.REL_ADDR ){ 154 Cell cell=start.getReference() ; 155 sp=cell.getViewAddress(); 156 157 Debug.println("Cell address :"+cell.getViewAddress() ); 158 } 159 else if(start.getType() ==Node.ABS_ADDR ){ 160 sp=start.getAddress(); 161 Debug.println("AB address:"+start.getAddress() ); 162 } 163 else{ 164 assert false: "Unable to handle the expression"; 165 //throw edu.psu.geovista.app.spreadsheet.exception: unable to handle the expression 166 } 167 if (end.getType() ==Node.REL_ADDR ){ 168 Cell cell=end.getReference() ; 169 ep=cell.getViewAddress(); 170 Debug.println("Cell address :"+cell.getViewAddress() ); 171 } 172 else if(end.getType() ==Node.ABS_ADDR ){ 173 ep=end.getAddress() ; 174 Debug.println("AB address:"+end.getAddress() ); 175 } 176 else{ 177 178 assert false: "Unable to handle the expression"; 179 //throw edu.psu.geovista.app.spreadsheet.exception: unable to handle the expression 180 } 181 if (sp.getX()==ep.getX()){//a single column range 182 if (sp.getY() <=ep.getY()){ 183 ps[0]=sp; 184 ps[1]=ep; 185 } 186 else{ 187 ps[0]=ep; 188 ps[1]=sp; 189 } 190 range=new SelectionRange(ps,SelectionRange.SINGLE_ROW ); 191 } 192 else if (sp.getY()==ep.getY()){//a single row range 193 if (sp.getX() <=ep.getX()){ 194 ps[0]=sp; 195 ps[1]=ep; 196 } 197 else{ 198 ps[0]=ep; 199 ps[1]=sp; 200 } 201 range=new SelectionRange(ps,SelectionRange.SINGLE_COLUMN ); 202 203 } 204 else{ //assume only handle a single column range or a single row range with sp above ep 205 throw new ParserException("Unable to calculate on the given range."); 206 } 207 return range; 208 } 209 /* 210 public HashSet getOwners() { 211 return owners; 212 } 213 214 public void setOwners(HashSet owners) { 215 this.owners = owners; 216 } */ 217 218 protected Function getSupportFuntion(String fname, Formula owner){ 219 //Function sf=Formula.getFuncHandler(fname); 220 Function sf=owner.getFunctionManager().getFuncHandler(fname); 221 sf.setOwner(owner); 222 return sf; 223 } 224 225 public void setOwner(Formula owner) { 226 this.owner = owner; 227 } 228 229 public Formula getOwner() { 230 return owner; 231 } 232 } //edu.psu.geovista.app.spreadsheet.functions.Function Class 233 234 235 236 237 238 239 240

This page was automatically generated by Maven