KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jxl > biff > formula > BuiltInFunction


1 /*********************************************************************
2 *
3 * Copyright (C) 2002 Andrew Khan
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 ***************************************************************************/

19
20 package jxl.biff.formula;
21
22 import java.util.Stack JavaDoc;
23
24 import common.Assert;
25 import common.Logger;
26 import jxl.WorkbookSettings;
27 import jxl.Sheet;
28 import jxl.biff.IntegerHelper;
29
30 /**
31  * A built in function in a formula
32  */

33 class BuiltInFunction extends Operator implements ParsedThing
34 {
35   /**
36    * The logger
37    */

38   private static Logger logger = Logger.getLogger(BuiltInFunction.class);
39
40   /**
41    * The function
42    */

43   private Function function;
44   
45   /**
46    * The workbook settings
47    */

48   private WorkbookSettings settings;
49
50   /**
51    * Constructor
52    * @param ws the workbook settings
53    */

54   public BuiltInFunction(WorkbookSettings ws)
55   {
56     settings = ws;
57   }
58
59   /**
60    * Constructor used when parsing a formula from a string
61    *
62    * @param f the function
63    * @param ws the workbook settings
64    */

65   public BuiltInFunction(Function f, WorkbookSettings ws)
66   {
67     function = f;
68     settings = ws;
69   }
70
71   /**
72    * Reads the ptg data from the array starting at the specified position
73    *
74    * @param data the RPN array
75    * @param pos the current position in the array, excluding the ptg identifier
76    * @return the number of bytes read
77    */

78   public int read(byte[] data, int pos)
79   {
80     int index = IntegerHelper.getInt(data[pos], data[pos+1]);
81     function = Function.getFunction(index);
82     Assert.verify(function != function.UNKNOWN, "function code " + index);
83     return 2;
84   }
85
86   /**
87    * Gets the operands for this operator from the stack
88    */

89   public void getOperands(Stack JavaDoc s)
90   {
91     // parameters are in the correct order, god damn them
92
ParseItem[] items = new ParseItem[function.getNumArgs()];
93     // modified in 2.4.3
94
for (int i = function.getNumArgs() - 1; i >= 0 ; i--)
95     {
96       ParseItem pi = (ParseItem) s.pop();
97       
98       items[i] = pi;
99     }
100
101     for (int i = 0 ; i < function.getNumArgs(); i++)
102     {
103       add(items[i]);
104     }
105     
106     /*
107     for (int i = 0 ; i < function.getNumArgs(); i++)
108     {
109       ParseItem pi = (ParseItem) s.pop();
110       add(pi);
111     }
112     */

113   }
114
115   /**
116    * Gets the string for this functions
117    *
118    * @param buf the buffer to append
119    */

120   public void getString(StringBuffer JavaDoc buf)
121   {
122     buf.append(function.getName(settings));
123     buf.append('(');
124
125     int numArgs = function.getNumArgs();
126     
127     if (numArgs > 0)
128     {
129       ParseItem[] operands = getOperands();
130
131       // arguments are in the same order they were specified
132
operands[0].getString(buf);
133         
134       for (int i = 1; i < numArgs; i++)
135       {
136         buf.append(',');
137         operands[i].getString(buf);
138       }
139
140       /*
141       // operands are in the correct order
142       operands[numArgs - 1].getString(buf);
143       
144       for (int i = numArgs - 2; i >= 0 ; i--)
145       {
146         buf.append(',');
147         operands[i].getString(buf);
148       }
149       */

150     }
151
152     buf.append(')');
153   }
154
155   /**
156    * Adjusts all the relative cell references in this formula by the
157    * amount specified. Used when copying formulas
158    *
159    * @param colAdjust the amount to add on to each relative cell reference
160    * @param rowAdjust the amount to add on to each relative row reference
161    */

162   public void adjustRelativeCellReferences(int colAdjust, int rowAdjust)
163   {
164     ParseItem[] operands = getOperands();
165
166     for (int i = 0 ; i < operands.length ; i++)
167     {
168       operands[i].adjustRelativeCellReferences(colAdjust, rowAdjust);
169     }
170   }
171
172   /**
173    * Called when a column is inserted on the specified sheet. Tells
174    * the formula parser to update all of its cell references beyond this
175    * column
176    *
177    * @param sheetIndex the sheet on which the column was inserted
178    * @param col the column number which was inserted
179    * @param currentSheet TRUE if this formula is on the sheet in which the
180    * column was inserted, FALSE otherwise
181    */

182   void columnInserted(int sheetIndex, int col, boolean currentSheet)
183   {
184     ParseItem[] operands = getOperands();
185     for (int i = 0 ; i < operands.length ; i++)
186     {
187       operands[i].columnInserted(sheetIndex, col, currentSheet);
188     }
189   }
190
191   /**
192    * Called when a column is inserted on the specified sheet. Tells
193    * the formula parser to update all of its cell references beyond this
194    * column
195    *
196    * @param sheetIndex the sheet on which the column was removed
197    * @param col the column number which was removed
198    * @param currentSheet TRUE if this formula is on the sheet in which the
199    * column was inserted, FALSE otherwise
200    */

201   void columnRemoved(int sheetIndex, int col, boolean currentSheet)
202   {
203     ParseItem[] operands = getOperands();
204     for (int i = 0 ; i < operands.length ; i++)
205     {
206       operands[i].columnRemoved(sheetIndex, col, currentSheet);
207     }
208   }
209
210
211   /**
212    * Called when a column is inserted on the specified sheet. Tells
213    * the formula parser to update all of its cell references beyond this
214    * column
215    *
216    * @param sheetIndex the sheet on which the row was inserted
217    * @param row the row number which was inserted
218    * @param currentSheet TRUE if this formula is on the sheet in which the
219    * column was inserted, FALSE otherwise
220    */

221   void rowInserted(int sheetIndex, int row, boolean currentSheet)
222   {
223     ParseItem[] operands = getOperands();
224     for (int i = 0 ; i < operands.length ; i++)
225     {
226       operands[i].rowInserted(sheetIndex, row, currentSheet);
227     }
228   }
229
230   /**
231    * Called when a column is inserted on the specified sheet. Tells
232    * the formula parser to update all of its cell references beyond this
233    * column
234    *
235    * @param sheetIndex the sheet on which the row was removed
236    * @param row the row number which was removed
237    * @param currentSheet TRUE if this formula is on the sheet in which the
238    * column was inserted, FALSE otherwise
239    */

240  void rowRemoved(int sheetIndex, int row, boolean currentSheet)
241   {
242     ParseItem[] operands = getOperands();
243     for (int i = 0 ; i < operands.length ; i++)
244     {
245       operands[i].rowRemoved(sheetIndex, row, currentSheet);
246     }
247   }
248
249   /**
250    * Gets the token representation of this item in RPN
251    *
252    * @return the bytes applicable to this formula
253    */

254   byte[] getBytes()
255   {
256     // Get the data for the operands
257
ParseItem[] operands = getOperands();
258     byte[] data = new byte[0];
259
260     for (int i = 0 ; i < operands.length; i++)
261     {
262       byte[] opdata = operands[i].getBytes();
263
264       // Grow the array
265
byte[] newdata = new byte[data.length + opdata.length];
266       System.arraycopy(data, 0, newdata, 0, data.length);
267       System.arraycopy(opdata, 0, newdata, data.length, opdata.length);
268       data = newdata;
269     }
270
271     // Add on the operator byte
272
byte[] newdata = new byte[data.length + 3];
273     System.arraycopy(data, 0, newdata, 0, data.length);
274     newdata[data.length] = !useAlternateCode() ? Token.FUNCTION.getCode() :
275                                                  Token.FUNCTION.getCode2();
276     IntegerHelper.getTwoBytes(function.getCode(), newdata, data.length+1);
277
278     return newdata;
279   }
280
281   /**
282    * Gets the precedence for this operator. Operator precedents run from
283    * 1 to 5, one being the highest, 5 being the lowest
284    *
285    * @return the operator precedence
286    */

287   int getPrecedence()
288   {
289     return 3;
290   }
291
292 }
293  
294
Popular Tags