See the License for the specific language governing permissions and
limitations under the License.
==================================================================== */
+
package org.apache.poi.hssf.record.formula;
/**
- * Common interface for AreaPtg and Area3DPtg, and their
- * child classes.
+ * Common interface for AreaPtg and Area3DPtg, and their child classes.
*/
public interface AreaI {
- /**
- * @return the first row in the area
- */
- public int getFirstRow();
-
- /**
- * @return last row in the range (x2 in x1,y1-x2,y2)
- */
- public int getLastRow();
-
- /**
- * @return the first column number in the area.
- */
- public int getFirstColumn();
-
- /**
- * @return lastcolumn in the area
- */
- public int getLastColumn();
+ /**
+ * @return the first row in the area
+ */
+ public int getFirstRow();
+
+ /**
+ * @return last row in the range (x2 in x1,y1-x2,y2)
+ */
+ public int getLastRow();
+
+ /**
+ * @return the first column number in the area.
+ */
+ public int getFirstColumn();
+
+ /**
+ * @return lastcolumn in the area
+ */
+ public int getLastColumn();
+
+ class OffsetArea implements AreaI {
+
+ private final int _firstColumn;
+ private final int _firstRow;
+ private final int _lastColumn;
+ private final int _lastRow;
+
+ public OffsetArea(int baseRow, int baseColumn, int relFirstRowIx, int relLastRowIx,
+ int relFirstColIx, int relLastColIx) {
+ _firstRow = baseRow + relFirstRowIx;
+ _lastRow = baseRow + relLastRowIx;
+ _firstColumn = baseColumn + relFirstColIx;
+ _lastColumn = baseColumn + relLastColIx;
+ }
+
+ public int getFirstColumn() {
+ return _firstColumn;
+ }
+
+ public int getFirstRow() {
+ return _firstRow;
+ }
+
+ public int getLastColumn() {
+ return _lastColumn;
+ }
+
+ public int getLastRow() {
+ return _lastRow;
+ }
+ }
+
}
\ No newline at end of file
field_2_col=colRelative.setBoolean(field_2_col,rel);
}
- public final void setColumnRawX(int col) { // TODO
- field_2_col = col;
- }
-
- public int getColumnRawX() { // TODO
- return field_2_col;
- }
-
public final void setColumn(int col) {
if(col < 0 || col >= 0x100) {
throw new IllegalArgumentException("Specified colIx (" + col + ") is out of range");
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
-package org.apache.poi.hssf.record.formula.eval;
-
-import org.apache.poi.hssf.record.formula.AreaPtg;
-import org.apache.poi.hssf.record.formula.Ptg;
-
-/**
- * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
- *
- */
-public final class Area2DEval extends AreaEvalBase {
-
- public Area2DEval(Ptg ptg, ValueEval[] values) {
- super((AreaPtg) ptg, values);
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
-package org.apache.poi.hssf.record.formula.eval;
-
-import org.apache.poi.hssf.record.formula.Area3DPtg;
-import org.apache.poi.hssf.record.formula.Ptg;
-
-/**
- * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
- *
- */
-public final class Area3DEval extends AreaEvalBase {
-
- private final int _externSheetIndex;
-
- public Area3DEval(Ptg ptg, ValueEval[] values) {
- super((Area3DPtg) ptg, values);
- _externSheetIndex = ((Area3DPtg) ptg).getExternSheetIndex();
- }
-
- public int getExternSheetIndex() {
- return _externSheetIndex;
- }
-}
* specified indexes should relative to the top left corner of this area.
*/
ValueEval getRelativeValue(int relativeRowIndex, int relativeColumnIndex);
+
+ /**
+ * Creates an {@link AreaEval} offset by a relative amount from from the upper left cell
+ * of this area
+ */
+ AreaEval offset(int relFirstRowIx, int relLastRowIx, int relFirstColIx, int relLastColIx);
}
/**
* @author Josh Micich
*/
-abstract class AreaEvalBase implements AreaEval {
+public abstract class AreaEvalBase implements AreaEval {
private final int _firstColumn;
private final int _firstRow;
private final int _lastColumn;
private final int _lastRow;
- private final ValueEval[] _values;
private final int _nColumns;
private final int _nRows;
- protected AreaEvalBase(AreaI ptg, ValueEval[] values) {
- if (values == null) {
- throw new IllegalArgumentException("values must not be null");
- }
+ protected AreaEvalBase(AreaI ptg) {
_firstRow = ptg.getFirstRow();
_firstColumn = ptg.getFirstColumn();
_lastRow = ptg.getLastRow();
_nColumns = _lastColumn - _firstColumn + 1;
_nRows = _lastRow - _firstRow + 1;
-
- int expectedItemCount = _nRows * _nColumns;
- if ((values.length != expectedItemCount)) {
- // Note - this math may need alteration when POI starts to support full column or full row refs
- throw new IllegalArgumentException("Array size should be (" + expectedItemCount
- + ") but was (" + values.length + ")");
- }
-
-
-
- for (int i = values.length - 1; i >= 0; i--) {
- if (values[i] == null) {
- throw new IllegalArgumentException("value array elements must not be null");
- }
- }
- _values = values;
}
public final int getFirstColumn() {
return _lastRow-_firstRow+1;
}
- public ValueEval getRelativeValue(int relativeRowIndex, int relativeColumnIndex) {
- int index = relativeRowIndex * _nColumns + relativeColumnIndex;
- ValueEval result = _values[index];
- if (result == null) {
- return BlankEval.INSTANCE;
- }
- return result;
- }
+ public abstract ValueEval getRelativeValue(int relativeRowIndex, int relativeColumnIndex);
public int getWidth() {
return _lastColumn-_firstColumn+1;
static {
Map m = new HashMap();
- addMapping(m, ID.OFFSET, new Offset());
addMapping(m, ID.INDIRECT, new Indirect());
addMapping(m, ID.EXTERNAL_FUNC, new ExternalFunction());
freeRefFunctionsByIdMap = m;
retval[75] = new Areas(); // AREAS
retval[76] = new Rows(); // ROWS
retval[77] = new Columns(); // COLUMNS
- retval[ID.OFFSET] = null; // Offset.evaluate has a different signature
+ retval[ID.OFFSET] = new Offset(); // OFFSET
retval[79] = new Absref(); // ABSREF
retval[80] = new Relref(); // RELREF
retval[81] = new Argument(); // ARGUMENT
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package org.apache.poi.hssf.record.formula.eval;
+
+import org.apache.poi.hssf.record.formula.AreaI;
+import org.apache.poi.hssf.record.formula.AreaI.OffsetArea;
+import org.apache.poi.hssf.usermodel.HSSFCell;
+import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator;
+import org.apache.poi.hssf.usermodel.HSSFRow;
+import org.apache.poi.hssf.usermodel.HSSFSheet;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+
+/**
+ * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
+ *
+ */
+public final class LazyAreaEval extends AreaEvalBase {
+
+ private final HSSFSheet _sheet;
+ private HSSFWorkbook _workbook;
+
+ public LazyAreaEval(AreaI ptg, HSSFSheet sheet, HSSFWorkbook workbook) {
+ super(ptg);
+ _sheet = sheet;
+ _workbook = workbook;
+ }
+
+ public ValueEval getRelativeValue(int relativeRowIndex, int relativeColumnIndex) {
+
+ int rowIx = (relativeRowIndex + getFirstRow() ) & 0xFFFF;
+ int colIx = (relativeColumnIndex + getFirstColumn() ) & 0x00FF;
+
+ HSSFRow row = _sheet.getRow(rowIx);
+ if (row == null) {
+ return BlankEval.INSTANCE;
+ }
+ HSSFCell cell = row.getCell(colIx);
+ if (cell == null) {
+ return BlankEval.INSTANCE;
+ }
+ return HSSFFormulaEvaluator.getEvalForCell(cell, _sheet, _workbook);
+ }
+
+ public AreaEval offset(int relFirstRowIx, int relLastRowIx, int relFirstColIx, int relLastColIx) {
+ AreaI area = new OffsetArea(getFirstRow(), getFirstColumn(),
+ relFirstRowIx, relLastRowIx, relFirstColIx, relLastColIx);
+
+ return new LazyAreaEval(area, _sheet, _workbook);
+ }
+}
--- /dev/null
+package org.apache.poi.hssf.record.formula.eval;\r
+\r
+import org.apache.poi.hssf.record.formula.AreaI;\r
+import org.apache.poi.hssf.record.formula.AreaI.OffsetArea;\r
+import org.apache.poi.hssf.record.formula.Ref3DPtg;\r
+import org.apache.poi.hssf.record.formula.RefPtg;\r
+import org.apache.poi.hssf.usermodel.HSSFCell;\r
+import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator;\r
+import org.apache.poi.hssf.usermodel.HSSFRow;\r
+import org.apache.poi.hssf.usermodel.HSSFSheet;\r
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;\r
+\r
+public final class LazyRefEval extends RefEvalBase {\r
+\r
+ private final HSSFSheet _sheet;\r
+ private final HSSFWorkbook _workbook;\r
+\r
+\r
+ public LazyRefEval(RefPtg ptg, HSSFSheet sheet, HSSFWorkbook workbook) {\r
+ super(ptg.getRow(), ptg.getColumn());\r
+ _sheet = sheet;\r
+ _workbook = workbook;\r
+ }\r
+ public LazyRefEval(Ref3DPtg ptg, HSSFSheet sheet, HSSFWorkbook workbook) {\r
+ super(ptg.getRow(), ptg.getColumn());\r
+ _sheet = sheet;\r
+ _workbook = workbook;\r
+ }\r
+\r
+ public ValueEval getInnerValueEval() {\r
+ int rowIx = getRow();\r
+ int colIx = getColumn();\r
+ \r
+ HSSFRow row = _sheet.getRow(rowIx);\r
+ if (row == null) {\r
+ return BlankEval.INSTANCE;\r
+ }\r
+ HSSFCell cell = row.getCell(colIx);\r
+ if (cell == null) {\r
+ return BlankEval.INSTANCE;\r
+ }\r
+ return HSSFFormulaEvaluator.getEvalForCell(cell, _sheet, _workbook);\r
+ }\r
+ \r
+ public AreaEval offset(int relFirstRowIx, int relLastRowIx, int relFirstColIx, int relLastColIx) {\r
+ \r
+ AreaI area = new OffsetArea(getRow(), getColumn(),\r
+ relFirstRowIx, relLastRowIx, relFirstColIx, relLastColIx);\r
+\r
+ return new LazyAreaEval(area, _sheet, _workbook);\r
+ }\r
+}\r
public int getColumn() {
return delegate.getColumn();
}
+ public AreaEval offset(int relFirstRowIx, int relLastRowIx, int relFirstColIx, int relLastColIx) {
+ throw new RuntimeException("should not be called"); // TODO - delete this whole class
+ }
}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
-package org.apache.poi.hssf.record.formula.eval;
-
-import org.apache.poi.hssf.record.formula.Ref3DPtg;
-
-/**
- * @author Amol S. Deshmukh
- *
- */
-public final class Ref3DEval implements RefEval {
-
- private final ValueEval value;
- private final Ref3DPtg delegate;
-
- public Ref3DEval(Ref3DPtg ptg, ValueEval ve) {
- if(ve == null) {
- throw new IllegalArgumentException("ve must not be null");
- }
- if(ptg == null) {
- throw new IllegalArgumentException("ptg must not be null");
- }
- value = ve;
- delegate = ptg;
- }
- public ValueEval getInnerValueEval() {
- return value;
- }
- public int getRow() {
- return delegate.getRow();
- }
- public int getColumn() {
- return delegate.getColumn();
- }
- public int getExternSheetIndex() {
- return delegate.getExternSheetIndex();
- }
-}
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
package org.apache.poi.hssf.record.formula.eval;
public interface RefEval extends ValueEval {
/**
- * The (possibly evaluated) ValueEval contained
- * in this RefEval. eg. if cell A1 contains "test"
- * then in a formula referring to cell A1
- * the RefEval representing
- * A1 will return as the getInnerValueEval() the
- * object of concrete type StringEval
+ * @return the evaluated value of the cell referred to by this RefEval.
*/
- public ValueEval getInnerValueEval();
+ ValueEval getInnerValueEval();
/**
* returns the zero based column index.
*/
- public int getColumn();
+ int getColumn();
/**
* returns the zero based row index.
*/
- public int getRow();
+ int getRow();
+
+ /**
+ * Creates an {@link AreaEval} offset by a relative amount from this RefEval
+ */
+ AreaEval offset(int relFirstRowIx, int relLastRowIx, int relFirstColIx, int relLastColIx);
}
--- /dev/null
+package org.apache.poi.hssf.record.formula.eval;\r
+\r
+public abstract class RefEvalBase implements RefEval {\r
+\r
+ private final int _rowIndex;\r
+ private final int _columnIndex;\r
+\r
+ protected RefEvalBase(int rowIndex, int columnIndex) {\r
+ _rowIndex = rowIndex;\r
+ _columnIndex = columnIndex;\r
+ }\r
+ public final int getRow() {\r
+ return _rowIndex;\r
+ }\r
+ public final int getColumn() {\r
+ return _columnIndex;\r
+ }\r
+}\r
for (int rrIx=0; rrIx<height; rrIx++) {
for (int rcIx=0; rcIx<width; rcIx++) {
ValueEval ve = areaEval.getRelativeValue(rrIx, rcIx);
- if(criteriaPredicate.matches(ve)) {
- result++;
- }
+ if(criteriaPredicate.matches(ve)) {
+ result++;
+ }
}
}
return result;
return 0;
}
public static int countArg(Eval eval, I_MatchPredicate criteriaPredicate) {
+ if (eval == null) {
+ throw new IllegalArgumentException("eval must not be null");
+ }
if (eval instanceof AreaEval) {
return CountUtils.countMatchingCellsInArea((AreaEval) eval, criteriaPredicate);
}
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-/*
- * Created on Nov 25, 2006
- *
- */
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
package org.apache.poi.hssf.record.formula.functions;
import org.apache.poi.hssf.record.formula.eval.BoolEval;
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
import org.apache.poi.hssf.record.formula.eval.Eval;
+import org.apache.poi.hssf.record.formula.eval.EvaluationException;
+import org.apache.poi.hssf.record.formula.eval.OperandResolver;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
/**
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
Eval evalWhenFalse = BoolEval.FALSE;
switch (args.length) {
- case 3:
- evalWhenFalse = args[2];
- case 2:
- BoolEval beval = (BoolEval) args[0]; // TODO - class cast exception
- if (beval.getBooleanValue()) {
- return args[1];
- }
- return evalWhenFalse;
- default:
- return ErrorEval.VALUE_INVALID;
+ case 3:
+ evalWhenFalse = args[2];
+ case 2:
+ boolean b;
+ try {
+ b = evaluateFirstArg(args[0], srcCellRow, srcCellCol);
+ } catch (EvaluationException e) {
+ return e.getErrorEval();
+ }
+ if (b) {
+ return args[1];
+ }
+ return evalWhenFalse;
+ default:
+ return ErrorEval.VALUE_INVALID;
}
}
+
+ private static boolean evaluateFirstArg(Eval arg, int srcCellRow, short srcCellCol) throws EvaluationException {
+ ValueEval ve = OperandResolver.getSingleValue(arg, srcCellRow, srcCellCol);
+ Boolean b = OperandResolver.coerceValueToBoolean(ve, false);
+ if (b == null) {
+ return false;
+ }
+ return b.booleanValue();
+ }
}
package org.apache.poi.hssf.record.formula.functions;
-import org.apache.poi.hssf.record.formula.AreaPtg;
-import org.apache.poi.hssf.record.formula.eval.Area2DEval;
import org.apache.poi.hssf.record.formula.eval.AreaEval;
import org.apache.poi.hssf.record.formula.eval.BlankEval;
import org.apache.poi.hssf.record.formula.eval.BoolEval;
// Make this cell ref look like a 1x1 area ref.
// It doesn't matter if eval is a 2D or 3D ref, because that detail is never asked of AreaEval.
- // This code only requires the value array item.
- // anything would be ok for rowIx and colIx, but may as well get it right.
- int rowIx = refEval.getRow();
- int colIx = refEval.getColumn();
- AreaPtg ap = new AreaPtg(rowIx, rowIx, colIx, colIx, false, false, false, false);
- ValueEval value = refEval.getInnerValueEval();
- return new Area2DEval(ap, new ValueEval[] { value, });
+ return refEval.offset(0, 0, 0, 0);
}
throw EvaluationException.invalidValue();
}
return d;
}
- /**
- * returns the sum of difference of squares of corresponding double
- * value in each subarray: ie. sigma (xarr[i]^2-yarr[i]^2)
- * <br/>
- * It is the responsibility of the caller
- * to ensure that the two subarrays are of equal length. If the
- * subarrays are not of equal length, the return value can be
- * unpredictable.
- * @param xarr
- * @param yarr
- */
- public static double sumx2my2(double[] xarr, double[] yarr) {
- double d = 0;
-
- try {
- for (int i=0, iSize=xarr.length; i<iSize; i++) {
- d += (xarr[i] + yarr[i]) * (xarr[i] - yarr[i]);
- }
- }
- catch (ArrayIndexOutOfBoundsException ae) {
- d = Double.NaN;
- }
-
- return d;
- }
-
- /**
- * returns the sum of sum of squares of corresponding double
- * value in each subarray: ie. sigma (xarr[i]^2 + yarr[i]^2)
- * <br/>
- * It is the responsibility of the caller
- * to ensure that the two subarrays are of equal length. If the
- * subarrays are not of equal length, the return value can be
- * unpredictable.
- * @param xarr
- * @param yarr
- */
- public static double sumx2py2(double[] xarr, double[] yarr) {
- double d = 0;
-
- try {
- for (int i=0, iSize=xarr.length; i<iSize; i++) {
- d += (xarr[i] * xarr[i]) + (yarr[i] * yarr[i]);
- }
- }
- catch (ArrayIndexOutOfBoundsException ae) {
- d = Double.NaN;
- }
-
- return d;
- }
-
-
- /**
- * returns the sum of squares of difference of corresponding double
- * value in each subarray: ie. sigma ( (xarr[i]-yarr[i])^2 )
- * <br/>
- * It is the responsibility of the caller
- * to ensure that the two subarrays are of equal length. If the
- * subarrays are not of equal length, the return value can be
- * unpredictable.
- * @param xarr
- * @param yarr
- */
- public static double sumxmy2(double[] xarr, double[] yarr) {
- double d = 0;
-
- try {
- for (int i=0, iSize=xarr.length; i<iSize; i++) {
- double t = (xarr[i] - yarr[i]);
- d += t * t;
- }
- }
- catch (ArrayIndexOutOfBoundsException ae) {
- d = Double.NaN;
- }
-
- return d;
- }
/**
* returns the total number of combinations possible when
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
package org.apache.poi.hssf.record.formula.functions;
-import org.apache.poi.hssf.record.formula.Area3DPtg;
-import org.apache.poi.hssf.record.formula.AreaPtg;
-import org.apache.poi.hssf.record.formula.eval.Area3DEval;
import org.apache.poi.hssf.record.formula.eval.AreaEval;
import org.apache.poi.hssf.record.formula.eval.BoolEval;
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
import org.apache.poi.hssf.record.formula.eval.EvaluationException;
import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
import org.apache.poi.hssf.record.formula.eval.OperandResolver;
-import org.apache.poi.hssf.record.formula.eval.Ref3DEval;
import org.apache.poi.hssf.record.formula.eval.RefEval;
import org.apache.poi.hssf.record.formula.eval.StringEval;
import org.apache.poi.hssf.record.formula.eval.ValueEval;
-import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator;
-import org.apache.poi.hssf.usermodel.HSSFSheet;
-import org.apache.poi.hssf.usermodel.HSSFWorkbook;
/**
* Implementation for Excel function OFFSET()<p/>
*
*
* @author Josh Micich
*/
-public final class Offset implements FreeRefFunction {
+public final class Offset implements Function {
// These values are specific to BIFF8
private static final int LAST_VALID_ROW_INDEX = 0xFFFF;
private static final int LAST_VALID_COLUMN_INDEX = 0xFF;
* Encapsulates either an area or cell reference which may be 2d or 3d.
*/
private static final class BaseRef {
- private static final int INVALID_SHEET_INDEX = -1;
private final int _firstRowIndex;
private final int _firstColumnIndex;
private final int _width;
private final int _height;
- private final int _externalSheetIndex;
+ private final RefEval _refEval;
+ private final AreaEval _areaEval;
public BaseRef(RefEval re) {
+ _refEval = re;
+ _areaEval = null;
_firstRowIndex = re.getRow();
_firstColumnIndex = re.getColumn();
_height = 1;
_width = 1;
- if (re instanceof Ref3DEval) {
- Ref3DEval r3e = (Ref3DEval) re;
- _externalSheetIndex = r3e.getExternSheetIndex();
- } else {
- _externalSheetIndex = INVALID_SHEET_INDEX;
- }
}
public BaseRef(AreaEval ae) {
+ _refEval = null;
+ _areaEval = ae;
_firstRowIndex = ae.getFirstRow();
_firstColumnIndex = ae.getFirstColumn();
_height = ae.getLastRow() - ae.getFirstRow() + 1;
_width = ae.getLastColumn() - ae.getFirstColumn() + 1;
- if (ae instanceof Area3DEval) {
- Area3DEval a3e = (Area3DEval) ae;
- _externalSheetIndex = a3e.getExternSheetIndex();
- } else {
- _externalSheetIndex = INVALID_SHEET_INDEX;
- }
}
public int getWidth() {
public int getFirstColumnIndex() {
return _firstColumnIndex;
}
- public boolean isIs3d() {
- return _externalSheetIndex > 0;
- }
- public short getExternalSheetIndex() {
- if(_externalSheetIndex < 0) {
- throw new IllegalStateException("external sheet index only available for 3d refs");
+ public AreaEval offset(int relFirstRowIx, int relLastRowIx,
+ int relFirstColIx, int relLastColIx) {
+ if (_refEval == null) {
+ return _areaEval.offset(relFirstRowIx, relLastRowIx, relFirstColIx, relLastColIx);
}
- return (short) _externalSheetIndex;
+ return _refEval.offset(relFirstRowIx, relLastRowIx, relFirstColIx, relLastColIx);
}
}
- public ValueEval evaluate(Eval[] args, int srcCellRow, short srcCellCol, HSSFWorkbook workbook, HSSFSheet sheet) {
+ public Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) {
if(args.length < 3 || args.length > 5) {
return ErrorEval.VALUE_INVALID;
}
LinearOffsetRange rowOffsetRange = new LinearOffsetRange(rowOffset, height);
LinearOffsetRange colOffsetRange = new LinearOffsetRange(columnOffset, width);
- return createOffset(baseRef, rowOffsetRange, colOffsetRange, workbook, sheet);
+ return createOffset(baseRef, rowOffsetRange, colOffsetRange);
} catch (EvaluationException e) {
return e.getErrorEval();
}
}
private static AreaEval createOffset(BaseRef baseRef,
- LinearOffsetRange rowOffsetRange, LinearOffsetRange colOffsetRange,
- HSSFWorkbook workbook, HSSFSheet sheet) throws EvaluationException {
+ LinearOffsetRange orRow, LinearOffsetRange orCol) throws EvaluationException {
- LinearOffsetRange rows = rowOffsetRange.normaliseAndTranslate(baseRef.getFirstRowIndex());
- LinearOffsetRange cols = colOffsetRange.normaliseAndTranslate(baseRef.getFirstColumnIndex());
+ LinearOffsetRange absRows = orRow.normaliseAndTranslate(baseRef.getFirstRowIndex());
+ LinearOffsetRange absCols = orCol.normaliseAndTranslate(baseRef.getFirstColumnIndex());
- if(rows.isOutOfBounds(0, LAST_VALID_ROW_INDEX)) {
+ if(absRows.isOutOfBounds(0, LAST_VALID_ROW_INDEX)) {
throw new EvaluationException(ErrorEval.REF_INVALID);
}
- if(cols.isOutOfBounds(0, LAST_VALID_COLUMN_INDEX)) {
+ if(absCols.isOutOfBounds(0, LAST_VALID_COLUMN_INDEX)) {
throw new EvaluationException(ErrorEval.REF_INVALID);
}
- if(baseRef.isIs3d()) {
- Area3DPtg a3dp = new Area3DPtg(rows.getFirstIndex(), rows.getLastIndex(),
- cols.getFirstIndex(), cols.getLastIndex(),
- false, false, false, false,
- baseRef.getExternalSheetIndex());
- return HSSFFormulaEvaluator.evaluateArea3dPtg(workbook, a3dp);
- }
-
- AreaPtg ap = new AreaPtg(rows.getFirstIndex(), rows.getLastIndex(),
- cols.getFirstIndex(), cols.getLastIndex(),
- false, false, false, false);
- return HSSFFormulaEvaluator.evaluateAreaPtg(sheet, workbook, ap);
+ return baseRef.offset(orRow.getFirstIndex(), orRow.getLastIndex(), orCol.getFirstIndex(), orCol.getLastIndex());
}
private static BaseRef evaluateBaseRef(Eval eval) throws EvaluationException {
package org.apache.poi.hssf.usermodel;
-import java.lang.reflect.Constructor;
-import java.util.HashMap;
import java.util.Iterator;
-import java.util.Map;
import java.util.Stack;
import org.apache.poi.hssf.model.FormulaParser;
import org.apache.poi.hssf.record.formula.AreaPtg;
import org.apache.poi.hssf.record.formula.BoolPtg;
import org.apache.poi.hssf.record.formula.ControlPtg;
+import org.apache.poi.hssf.record.formula.ErrPtg;
import org.apache.poi.hssf.record.formula.IntPtg;
import org.apache.poi.hssf.record.formula.MemErrPtg;
import org.apache.poi.hssf.record.formula.MissingArgPtg;
import org.apache.poi.hssf.record.formula.StringPtg;
import org.apache.poi.hssf.record.formula.UnionPtg;
import org.apache.poi.hssf.record.formula.UnknownPtg;
-import org.apache.poi.hssf.record.formula.eval.Area2DEval;
-import org.apache.poi.hssf.record.formula.eval.Area3DEval;
import org.apache.poi.hssf.record.formula.eval.AreaEval;
import org.apache.poi.hssf.record.formula.eval.BlankEval;
import org.apache.poi.hssf.record.formula.eval.BoolEval;
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
import org.apache.poi.hssf.record.formula.eval.Eval;
import org.apache.poi.hssf.record.formula.eval.FunctionEval;
+import org.apache.poi.hssf.record.formula.eval.LazyAreaEval;
+import org.apache.poi.hssf.record.formula.eval.LazyRefEval;
import org.apache.poi.hssf.record.formula.eval.NameEval;
import org.apache.poi.hssf.record.formula.eval.NameXEval;
import org.apache.poi.hssf.record.formula.eval.NumberEval;
import org.apache.poi.hssf.record.formula.eval.OperationEval;
-import org.apache.poi.hssf.record.formula.eval.Ref2DEval;
-import org.apache.poi.hssf.record.formula.eval.Ref3DEval;
import org.apache.poi.hssf.record.formula.eval.RefEval;
import org.apache.poi.hssf.record.formula.eval.StringEval;
import org.apache.poi.hssf.record.formula.eval.ValueEval;
*/
public class HSSFFormulaEvaluator {
- // params to lookup the right constructor using reflection
- private static final Class[] VALUE_CONTRUCTOR_CLASS_ARRAY = new Class[] { Ptg.class };
-
- private static final Class[] AREA3D_CONSTRUCTOR_CLASS_ARRAY = new Class[] { Ptg.class, ValueEval[].class };
-
- private static final Class[] REFERENCE_CONSTRUCTOR_CLASS_ARRAY = new Class[] { Ptg.class, ValueEval.class };
-
- private static final Class[] REF3D_CONSTRUCTOR_CLASS_ARRAY = new Class[] { Ptg.class, ValueEval.class };
-
- // Maps for mapping *Eval to *Ptg
- private static final Map VALUE_EVALS_MAP = new HashMap();
-
- /*
- * Following is the mapping between the Ptg tokens returned
- * by the FormulaParser and the *Eval classes that are used
- * by the FormulaEvaluator
- */
- static {
- VALUE_EVALS_MAP.put(BoolPtg.class, BoolEval.class);
- VALUE_EVALS_MAP.put(IntPtg.class, NumberEval.class);
- VALUE_EVALS_MAP.put(NumberPtg.class, NumberEval.class);
- VALUE_EVALS_MAP.put(StringPtg.class, StringEval.class);
-
- }
-
-
protected HSSFSheet _sheet;
protected HSSFWorkbook _workbook;
* This is a helpful wrapper around looping over all
* cells, and calling evaluateFormulaCell on each one.
*/
- public static void evaluateAllFormulaCells(HSSFWorkbook wb) {
- for(int i=0; i<wb.getNumberOfSheets(); i++) {
- HSSFSheet sheet = wb.getSheetAt(i);
- HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(sheet, wb);
-
- for (Iterator rit = sheet.rowIterator(); rit.hasNext();) {
- HSSFRow r = (HSSFRow)rit.next();
-
- for (Iterator cit = r.cellIterator(); cit.hasNext();) {
- HSSFCell c = (HSSFCell)cit.next();
- if (c.getCellType() == HSSFCell.CELL_TYPE_FORMULA)
- evaluator.evaluateFormulaCell(c);
- }
- }
- }
- }
+ public static void evaluateAllFormulaCells(HSSFWorkbook wb) {
+ for(int i=0; i<wb.getNumberOfSheets(); i++) {
+ HSSFSheet sheet = wb.getSheetAt(i);
+ HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(sheet, wb);
+
+ for (Iterator rit = sheet.rowIterator(); rit.hasNext();) {
+ HSSFRow r = (HSSFRow)rit.next();
+
+ for (Iterator cit = r.cellIterator(); cit.hasNext();) {
+ HSSFCell c = (HSSFCell)cit.next();
+ if (c.getCellType() == HSSFCell.CELL_TYPE_FORMULA)
+ evaluator.evaluateFormulaCell(c);
+ }
+ }
+ }
+ }
/**
* Returns a CellValue wrapper around the supplied ValueEval instance.
* @param eval
*/
- protected static CellValue getCellValueForEval(ValueEval eval) {
+ private static CellValue getCellValueForEval(ValueEval eval) {
CellValue retval = null;
if (eval != null) {
if (eval instanceof NumberEval) {
private static ValueEval evaluateCell(HSSFWorkbook workbook, HSSFSheet sheet,
int srcRowNum, short srcColNum, String cellFormulaText) {
- Ptg[] ptgs = FormulaParser.parse(cellFormulaText, workbook);
+ Ptg[] ptgs = FormulaParser.parse(cellFormulaText, workbook);
Stack stack = new Stack();
for (int i = 0, iSize = ptgs.length; i < iSize; i++) {
continue;
}
if (ptg instanceof UnknownPtg) { continue; }
-
+ Eval opResult;
if (ptg instanceof OperationPtg) {
OperationPtg optg = (OperationPtg) ptg;
Eval p = (Eval) stack.pop();
ops[j] = p;
}
- Eval opresult = invokeOperation(operation, ops, srcRowNum, srcColNum, workbook, sheet);
- stack.push(opresult);
- }
- else if (ptg instanceof RefPtg) {
- RefPtg refPtg = (RefPtg) ptg;
- int colIx = refPtg.getColumn();
- int rowIx = refPtg.getRow();
- HSSFRow row = sheet.getRow(rowIx);
- HSSFCell cell = (row != null) ? row.getCell(colIx) : null;
- stack.push(createRef2DEval(refPtg, cell, sheet, workbook));
- }
- else if (ptg instanceof Ref3DPtg) {
- Ref3DPtg refPtg = (Ref3DPtg) ptg;
- int colIx = refPtg.getColumn();
- int rowIx = refPtg.getRow();
- Workbook wb = workbook.getWorkbook();
- HSSFSheet xsheet = workbook.getSheetAt(wb.getSheetIndexFromExternSheetIndex(refPtg.getExternSheetIndex()));
- HSSFRow row = xsheet.getRow(rowIx);
- HSSFCell cell = (row != null) ? row.getCell(colIx) : null;
- stack.push(createRef3DEval(refPtg, cell, xsheet, workbook));
- }
- else if (ptg instanceof AreaPtg) {
- AreaPtg ap = (AreaPtg) ptg;
- AreaEval ae = evaluateAreaPtg(sheet, workbook, ap);
- stack.push(ae);
- }
- else if (ptg instanceof Area3DPtg) {
- Area3DPtg a3dp = (Area3DPtg) ptg;
- AreaEval ae = evaluateArea3dPtg(workbook, a3dp);
- stack.push(ae);
- }
- else {
- Eval ptgEval = getEvalForPtg(ptg);
- stack.push(ptgEval);
+ opResult = invokeOperation(operation, ops, srcRowNum, srcColNum, workbook, sheet);
+ } else {
+ opResult = getEvalForPtg(ptg, sheet, workbook);
}
+ stack.push(opResult);
}
ValueEval value = ((ValueEval) stack.pop());
}
value = dereferenceValue(value, srcRowNum, srcColNum);
if (value instanceof BlankEval) {
- // Note Excel behaviour here. A blank final final value is converted to zero.
+ // Note Excel behaviour here. A blank final final value is converted to zero.
return NumberEval.ZERO;
// Formulas _never_ evaluate to blank. If a formula appears to have evaluated to
// blank, the actual value is empty string. This can be verified with ISBLANK().
/**
* Dereferences a single value from any AreaEval or RefEval evaluation result.
* If the supplied evaluationResult is just a plain value, it is returned as-is.
- * @return a <tt>NumberEval</tt>, <tt>StringEval</tt>, <tt>BoolEval</tt>,
- * <tt>BlankEval</tt> or <tt>ErrorEval</tt>. Never <code>null</code>.
+ * @return a <tt>NumberEval</tt>, <tt>StringEval</tt>, <tt>BoolEval</tt>,
+ * <tt>BlankEval</tt> or <tt>ErrorEval</tt>. Never <code>null</code>.
*/
private static ValueEval dereferenceValue(ValueEval evaluationResult, int srcRowNum, short srcColNum) {
if (evaluationResult instanceof RefEval) {
return operation.evaluate(ops, srcRowNum, srcColNum);
}
- public static AreaEval evaluateAreaPtg(HSSFSheet sheet, HSSFWorkbook workbook, AreaPtg ap) {
- int row0 = ap.getFirstRow();
- int col0 = ap.getFirstColumn();
- int row1 = ap.getLastRow();
- int col1 = ap.getLastColumn();
-
- // If the last row is -1, then the
- // reference is for the rest of the column
- // (eg C:C)
- // TODO: Handle whole column ranges properly
- if(row1 == -1 && row0 >= 0) {
- row1 = (short)sheet.getLastRowNum();
- }
- ValueEval[] values = evalArea(workbook, sheet, row0, col0, row1, col1);
- return new Area2DEval(ap, values);
- }
-
- public static AreaEval evaluateArea3dPtg(HSSFWorkbook workbook, Area3DPtg a3dp) {
- int row0 = a3dp.getFirstRow();
- int col0 = a3dp.getFirstColumn();
- int row1 = a3dp.getLastRow();
- int col1 = a3dp.getLastColumn();
- Workbook wb = workbook.getWorkbook();
- HSSFSheet xsheet = workbook.getSheetAt(wb.getSheetIndexFromExternSheetIndex(a3dp.getExternSheetIndex()));
-
- // If the last row is -1, then the
- // reference is for the rest of the column
- // (eg C:C)
- // TODO: Handle whole column ranges properly
- if(row1 == -1 && row0 >= 0) {
- row1 = (short)xsheet.getLastRowNum();
- }
-
- ValueEval[] values = evalArea(workbook, xsheet, row0, col0, row1, col1);
- return new Area3DEval(a3dp, values);
- }
-
- private static ValueEval[] evalArea(HSSFWorkbook workbook, HSSFSheet sheet,
- int row0, int col0, int row1, int col1) {
- ValueEval[] values = new ValueEval[(row1 - row0 + 1) * (col1 - col0 + 1)];
- for (int x = row0; sheet != null && x < row1 + 1; x++) {
- HSSFRow row = sheet.getRow(x);
- for (int y = col0; y < col1 + 1; y++) {
- ValueEval cellEval;
- if(row == null) {
- cellEval = BlankEval.INSTANCE;
- } else {
- cellEval = getEvalForCell(row.getCell(y), row, sheet, workbook);
- }
- values[(x - row0) * (col1 - col0 + 1) + (y - col0)] = cellEval;
- }
- }
- return values;
- }
-
/**
* returns an appropriate Eval impl instance for the Ptg. The Ptg must be
* one of: Area3DPtg, AreaPtg, ReferencePtg, Ref3DPtg, IntPtg, NumberPtg,
* StringPtg, BoolPtg <br/>special Note: OperationPtg subtypes cannot be
* passed here!
- *
- * @param ptg
*/
- protected static Eval getEvalForPtg(Ptg ptg) {
- Eval retval = null;
-
- Class clazz = (Class) VALUE_EVALS_MAP.get(ptg.getClass());
- try {
- if (ptg instanceof Area3DPtg) {
- Constructor constructor = clazz.getConstructor(AREA3D_CONSTRUCTOR_CLASS_ARRAY);
- retval = (OperationEval) constructor.newInstance(new Ptg[] { ptg });
- }
- else if (ptg instanceof AreaPtg) {
- Constructor constructor = clazz.getConstructor(AREA3D_CONSTRUCTOR_CLASS_ARRAY);
- retval = (OperationEval) constructor.newInstance(new Ptg[] { ptg });
- }
- else if (ptg instanceof RefPtg) {
- Constructor constructor = clazz.getConstructor(REFERENCE_CONSTRUCTOR_CLASS_ARRAY);
- retval = (OperationEval) constructor.newInstance(new Ptg[] { ptg });
- }
- else if (ptg instanceof Ref3DPtg) {
- Constructor constructor = clazz.getConstructor(REF3D_CONSTRUCTOR_CLASS_ARRAY);
- retval = (OperationEval) constructor.newInstance(new Ptg[] { ptg });
- }
- else {
- if (ptg instanceof IntPtg || ptg instanceof NumberPtg || ptg instanceof StringPtg
- || ptg instanceof BoolPtg) {
- Constructor constructor = clazz.getConstructor(VALUE_CONTRUCTOR_CLASS_ARRAY);
- retval = (ValueEval) constructor.newInstance(new Ptg[] { ptg });
- }
- }
+ private static Eval getEvalForPtg(Ptg ptg, HSSFSheet sheet, HSSFWorkbook workbook) {
+ if (ptg instanceof RefPtg) {
+ return new LazyRefEval(((RefPtg) ptg), sheet, workbook);
}
- catch (Exception e) {
- throw new RuntimeException("Fatal Error: ", e);
+ if (ptg instanceof Ref3DPtg) {
+ Ref3DPtg refPtg = (Ref3DPtg) ptg;
+ Workbook wb = workbook.getWorkbook();
+ HSSFSheet xsheet = workbook.getSheetAt(wb.getSheetIndexFromExternSheetIndex(refPtg.getExternSheetIndex()));
+ return new LazyRefEval(refPtg, xsheet, workbook);
+ }
+ if (ptg instanceof AreaPtg) {
+ return new LazyAreaEval(((AreaPtg) ptg), sheet, workbook);
+ }
+ if (ptg instanceof Area3DPtg) {
+ Area3DPtg a3dp = (Area3DPtg) ptg;
+ Workbook wb = workbook.getWorkbook();
+ HSSFSheet xsheet = workbook.getSheetAt(wb.getSheetIndexFromExternSheetIndex(a3dp.getExternSheetIndex()));
+ return new LazyAreaEval(a3dp, xsheet, workbook);
}
- return retval;
+ if (ptg instanceof IntPtg) {
+ return new NumberEval(((IntPtg)ptg).getValue());
+ }
+ if (ptg instanceof NumberPtg) {
+ return new NumberEval(((NumberPtg)ptg).getValue());
+ }
+ if (ptg instanceof StringPtg) {
+ return new StringEval(((StringPtg) ptg).getValue());
+ }
+ if (ptg instanceof BoolPtg) {
+ return BoolEval.valueOf(((BoolPtg) ptg).getValue());
+ }
+ if (ptg instanceof ErrPtg) {
+ return ErrorEval.valueOf(((ErrPtg) ptg).getErrorCode());
+ }
+ throw new RuntimeException("Unexpected ptg class (" + ptg.getClass().getName() + ")");
}
-
/**
* Given a cell, find its type and from that create an appropriate ValueEval
* impl instance and return that. Since the cell could be an external
* @param sheet
* @param workbook
*/
- protected static ValueEval getEvalForCell(HSSFCell cell, HSSFRow row, HSSFSheet sheet, HSSFWorkbook workbook) {
+ public static ValueEval getEvalForCell(HSSFCell cell, HSSFSheet sheet, HSSFWorkbook workbook) {
if (cell == null) {
return BlankEval.INSTANCE;
throw new RuntimeException("Unexpected cell type (" + cell.getCellType() + ")");
}
- /**
- * Creates a Ref2DEval for ReferencePtg.
- * Non existent cells are treated as RefEvals containing BlankEval.
- */
- private static Ref2DEval createRef2DEval(RefPtg ptg, HSSFCell cell,
- HSSFSheet sheet, HSSFWorkbook workbook) {
- if (cell == null) {
- return new Ref2DEval(ptg, BlankEval.INSTANCE);
- }
-
- switch (cell.getCellType()) {
- case HSSFCell.CELL_TYPE_NUMERIC:
- return new Ref2DEval(ptg, new NumberEval(cell.getNumericCellValue()));
- case HSSFCell.CELL_TYPE_STRING:
- return new Ref2DEval(ptg, new StringEval(cell.getRichStringCellValue().getString()));
- case HSSFCell.CELL_TYPE_FORMULA:
- return new Ref2DEval(ptg, internalEvaluate(cell, sheet, workbook));
- case HSSFCell.CELL_TYPE_BOOLEAN:
- return new Ref2DEval(ptg, BoolEval.valueOf(cell.getBooleanCellValue()));
- case HSSFCell.CELL_TYPE_BLANK:
- return new Ref2DEval(ptg, BlankEval.INSTANCE);
- case HSSFCell.CELL_TYPE_ERROR:
- return new Ref2DEval(ptg, ErrorEval.valueOf(cell.getErrorCellValue()));
- }
- throw new RuntimeException("Unexpected cell type (" + cell.getCellType() + ")");
- }
-
- /**
- * create a Ref3DEval for Ref3DPtg.
- */
- private static Ref3DEval createRef3DEval(Ref3DPtg ptg, HSSFCell cell,
- HSSFSheet sheet, HSSFWorkbook workbook) {
- if (cell == null) {
- return new Ref3DEval(ptg, BlankEval.INSTANCE);
- }
- switch (cell.getCellType()) {
- case HSSFCell.CELL_TYPE_NUMERIC:
- return new Ref3DEval(ptg, new NumberEval(cell.getNumericCellValue()));
- case HSSFCell.CELL_TYPE_STRING:
- return new Ref3DEval(ptg, new StringEval(cell.getRichStringCellValue().getString()));
- case HSSFCell.CELL_TYPE_FORMULA:
- return new Ref3DEval(ptg, internalEvaluate(cell, sheet, workbook));
- case HSSFCell.CELL_TYPE_BOOLEAN:
- return new Ref3DEval(ptg, BoolEval.valueOf(cell.getBooleanCellValue()));
- case HSSFCell.CELL_TYPE_BLANK:
- return new Ref3DEval(ptg, BlankEval.INSTANCE);
- case HSSFCell.CELL_TYPE_ERROR:
- return new Ref3DEval(ptg, ErrorEval.valueOf(cell.getErrorCellValue()));
- }
- throw new RuntimeException("Unexpected cell type (" + cell.getCellType() + ")");
- }
-
/**
* Mimics the 'data view' of a cell. This allows formula evaluator
* to return a CellValue instead of precasting the value to String
/**
* debug method
- *
- * @param formula
- * @param sheet
- * @param workbook
*/
void inspectPtgs(String formula) {
- FormulaParser fp = new FormulaParser(formula, _workbook);
- fp.parse();
- Ptg[] ptgs = fp.getRPNPtg();
+ Ptg[] ptgs = FormulaParser.parse(formula, _workbook);
System.out.println("<ptg-group>");
for (int i = 0, iSize = ptgs.length; i < iSize; i++) {
System.out.println("<ptg>");
import junit.framework.AssertionFailedError;
import junit.framework.TestCase;
-import org.apache.poi.hssf.record.formula.Area3DPtg;
+import org.apache.poi.hssf.record.formula.AreaPtg;
+import org.apache.poi.hssf.record.formula.functions.EvalFactory;
/**
* Tests for <tt>AreaEval</tt>
public final class TestAreaEval extends TestCase {
public void testGetValue_bug44950() {
-
- Area3DPtg ptg = new Area3DPtg("B2:D3", (short)0);
+ // TODO - this test probably isn't testing much anymore
+ AreaPtg ptg = new AreaPtg("B2:D3");
NumberEval one = new NumberEval(1);
ValueEval[] values = {
one,
new NumberEval(5),
new NumberEval(6),
};
- AreaEval ae = new Area3DEval(ptg, values);
+ AreaEval ae = EvalFactory.createAreaEval(ptg, values);
if (one == ae.getValueAt(1, 2)) {
throw new AssertionFailedError("Identified bug 44950 a");
}
package org.apache.poi.hssf.record.formula.eval;
+import junit.framework.TestCase;
+
import org.apache.poi.hssf.record.formula.AreaPtg;
import org.apache.poi.hssf.record.formula.UnaryPlusPtg;
+import org.apache.poi.hssf.record.formula.functions.EvalFactory;
import org.apache.poi.hssf.record.formula.functions.NumericFunctionInvoker;
-import junit.framework.TestCase;
-
/**
* Test for unary plus operator evaluator.
- *
+ *
* @author Josh Micich
*/
public final class TestUnaryPlusEval extends TestCase {
-
+
/**
* Test for bug observable at svn revision 618865 (5-Feb-2008)<br/>
- * The code for handling column operands had been copy-pasted from the row handling code.
+ * The code for handling column operands had been copy-pasted from the row handling code.
*/
public void testColumnOperand() {
short colNum = (short)5;
AreaPtg areaPtg = new AreaPtg(firstRow, lastRow, colNum, colNum, false, false, false, false);
ValueEval[] values = {
- new NumberEval(27),
- new NumberEval(29),
- new NumberEval(35), // value in row 10
- new NumberEval(37),
- new NumberEval(38),
+ new NumberEval(27),
+ new NumberEval(29),
+ new NumberEval(35), // value in row 10
+ new NumberEval(37),
+ new NumberEval(38),
};
- Eval areaEval = new Area2DEval(areaPtg, values);
- Eval[] args = {
- areaEval,
+ Eval[] args = {
+ EvalFactory.createAreaEval(areaPtg, values),
};
double result = NumericFunctionInvoker.invoke(new UnaryPlusEval(UnaryPlusPtg.instance), args, 10, (short)20);
See the License for the specific language governing permissions and
limitations under the License.
==================================================================== */
-
package org.apache.poi.hssf.record.formula.functions;
import org.apache.poi.hssf.record.formula.AreaPtg;
+import org.apache.poi.hssf.record.formula.Ref3DPtg;
import org.apache.poi.hssf.record.formula.RefPtg;
-import org.apache.poi.hssf.record.formula.eval.Area2DEval;
import org.apache.poi.hssf.record.formula.eval.AreaEval;
+import org.apache.poi.hssf.record.formula.eval.AreaEvalBase;
import org.apache.poi.hssf.record.formula.eval.NumberEval;
-import org.apache.poi.hssf.record.formula.eval.Ref2DEval;
import org.apache.poi.hssf.record.formula.eval.RefEval;
+import org.apache.poi.hssf.record.formula.eval.RefEvalBase;
import org.apache.poi.hssf.record.formula.eval.ValueEval;
/**
*
* @author Josh Micich
*/
-final class EvalFactory {
+public final class EvalFactory {
private EvalFactory() {
// no instances of this class
*/
public static AreaEval createAreaEval(String areaRefStr, ValueEval[] values) {
AreaPtg areaPtg = new AreaPtg(areaRefStr);
+ return createAreaEval(areaPtg, values);
+ }
+
+ /**
+ * Creates a dummy AreaEval
+ * @param values empty (<code>null</code>) entries in this array will be converted to NumberEval.ZERO
+ */
+ public static AreaEval createAreaEval(AreaPtg areaPtg, ValueEval[] values) {
int nCols = areaPtg.getLastColumn() - areaPtg.getFirstColumn() + 1;
int nRows = areaPtg.getLastRow() - areaPtg.getFirstRow() + 1;
int nExpected = nRows * nCols;
values[i] = NumberEval.ZERO;
}
}
- return new Area2DEval(areaPtg, values);
+ return new MockAreaEval(areaPtg, values);
}
/**
* Creates a single RefEval (with value zero)
*/
public static RefEval createRefEval(String refStr) {
- return new Ref2DEval(new RefPtg(refStr), NumberEval.ZERO);
+ return createRefEval(refStr, NumberEval.ZERO);
+ }
+ public static RefEval createRefEval(String refStr, ValueEval value) {
+ return new MockRefEval(new RefPtg(refStr), value);
+ }
+
+ private static final class MockAreaEval extends AreaEvalBase {
+ private final ValueEval[] _values;
+ public MockAreaEval(AreaPtg areaPtg, ValueEval[] values) {
+ super(areaPtg);
+ _values = values;
+ }
+ public ValueEval getRelativeValue(int relativeRowIndex, int relativeColumnIndex) {
+ if (relativeRowIndex < 0 || relativeRowIndex >=getHeight()) {
+ throw new IllegalArgumentException("row index out of range");
+ }
+ int width = getWidth();
+ if (relativeColumnIndex < 0 || relativeColumnIndex >=width) {
+ throw new IllegalArgumentException("column index out of range");
+ }
+ int oneDimensionalIndex = relativeRowIndex * width + relativeColumnIndex;
+ return _values[oneDimensionalIndex];
+ }
+ public AreaEval offset(int relFirstRowIx, int relLastRowIx, int relFirstColIx, int relLastColIx) {
+ throw new RuntimeException("Operation not implemented on this mock object");
+ }
+ }
+
+ private static final class MockRefEval extends RefEvalBase {
+ private final ValueEval _value;
+ public MockRefEval(RefPtg ptg, ValueEval value) {
+ super(ptg.getRow(), ptg.getColumn());
+ _value = value;
+ }
+ public MockRefEval(Ref3DPtg ptg, ValueEval value) {
+ super(ptg.getRow(), ptg.getColumn());
+ _value = value;
+ }
+ public ValueEval getInnerValueEval() {
+ return _value;
+ }
+ public AreaEval offset(int relFirstRowIx, int relLastRowIx, int relFirstColIx, int relLastColIx) {
+ throw new RuntimeException("Operation not implemented on this mock object");
+ }
}
+
}
import junit.framework.TestCase;
import org.apache.poi.hssf.HSSFTestDataSamples;
-import org.apache.poi.hssf.record.formula.AreaPtg;
import org.apache.poi.hssf.record.formula.RefPtg;
-import org.apache.poi.hssf.record.formula.eval.Area2DEval;
import org.apache.poi.hssf.record.formula.eval.AreaEval;
import org.apache.poi.hssf.record.formula.eval.BlankEval;
import org.apache.poi.hssf.record.formula.eval.BoolEval;
BoolEval.TRUE,
BlankEval.INSTANCE,
};
- range = createAreaEval("A1:B3", values);
+ range = EvalFactory.createAreaEval("A1:B3", values);
confirmCountIf(2, range, BoolEval.TRUE);
// when criteria is numeric
new NumberEval(2),
BoolEval.TRUE,
};
- range = createAreaEval("A1:B3", values);
+ range = EvalFactory.createAreaEval("A1:B3", values);
confirmCountIf(3, range, new NumberEval(2));
// note - same results when criteria is a string that parses as the number with the same value
confirmCountIf(3, range, new StringEval("2.00"));
new NumberEval(25),
new NumberEval(25),
};
- Area2DEval arg0 = new Area2DEval(new AreaPtg("C1:C6"), values);
+ AreaEval arg0 = EvalFactory.createAreaEval("C1:C6", values);
- Ref2DEval criteriaArg = new Ref2DEval(new RefPtg("A1"), new NumberEval(25));
+ ValueEval criteriaArg = EvalFactory.createRefEval("A1", new NumberEval(25));
Eval[] args= { arg0, criteriaArg, };
double actual = NumericFunctionInvoker.invoke(new Countif(), args);
assertEquals(4, actual, 0D);
}
-
- private static AreaEval createAreaEval(String areaRefStr, ValueEval[] values) {
- return new Area2DEval(new AreaPtg(areaRefStr), values);
- }
-
private static void confirmCountA(int expected, Eval[] args) {
double result = NumericFunctionInvoker.invoke(new Counta(), args);
assertEquals(expected, result, 0);
import junit.framework.TestCase;
-import org.apache.poi.hssf.record.formula.AreaPtg;
-import org.apache.poi.hssf.record.formula.eval.Area2DEval;
+import org.apache.poi.hssf.record.formula.eval.AreaEval;
import org.apache.poi.hssf.record.formula.eval.Eval;
import org.apache.poi.hssf.record.formula.eval.NumberEval;
import org.apache.poi.hssf.record.formula.eval.ValueEval;
for (int i = 0; i < values.length; i++) {
values[i] = new NumberEval(dValues[i]);
}
- Area2DEval arg0 = new Area2DEval(new AreaPtg(areaRefString), values);
+ AreaEval arg0 = EvalFactory.createAreaEval(areaRefString, values);
Eval[] args;
if (colNum > 0) {
import junit.framework.TestCase;
-import org.apache.poi.hssf.record.formula.AreaPtg;
-import org.apache.poi.hssf.record.formula.eval.Area2DEval;
import org.apache.poi.hssf.record.formula.eval.AreaEval;
import org.apache.poi.hssf.record.formula.eval.BoolEval;
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
/**
* Test cases for MATCH()
- *
+ *
* @author Josh Micich
*/
public final class TestMatch extends TestCase {
private static final NumberEval MATCH_EXACT = new NumberEval(0);
/** greater than or equal to */
private static final NumberEval MATCH_SMALLEST_GTE = new NumberEval(-1);
-
-
+
+
private static Eval invokeMatch(Eval lookup_value, Eval lookup_array, Eval match_type) {
Eval[] args = { lookup_value, lookup_array, match_type, };
return new Match().evaluate(args, -1, (short)-1);
NumericValueEval nve = (NumericValueEval)actualEval;
assertEquals(expected, nve.getNumberValue(), 0);
}
- /**
- * Convenience method
- * @return <code>new Area2DEval(new AreaPtg(ref), values)</code>
- */
- private static AreaEval createAreaEval(String ref, ValueEval[] values) {
- return new Area2DEval(new AreaPtg(ref), values);
- }
-
+
public void testSimpleNumber() {
-
+
ValueEval[] values = {
- new NumberEval(4),
- new NumberEval(5),
- new NumberEval(10),
- new NumberEval(10),
- new NumberEval(25),
+ new NumberEval(4),
+ new NumberEval(5),
+ new NumberEval(10),
+ new NumberEval(10),
+ new NumberEval(25),
};
-
- AreaEval ae = createAreaEval("A1:A5", values);
-
+
+ AreaEval ae = EvalFactory.createAreaEval("A1:A5", values);
+
confirmInt(2, invokeMatch(new NumberEval(5), ae, MATCH_LARGEST_LTE));
confirmInt(2, invokeMatch(new NumberEval(5), ae, MATCH_EXACT));
confirmInt(4, invokeMatch(new NumberEval(10), ae, MATCH_LARGEST_LTE));
confirmInt(4, invokeMatch(new NumberEval(20), ae, MATCH_LARGEST_LTE));
assertEquals(ErrorEval.NA, invokeMatch(new NumberEval(20), ae, MATCH_EXACT));
}
-
+
public void testReversedNumber() {
-
+
ValueEval[] values = {
- new NumberEval(25),
- new NumberEval(10),
- new NumberEval(10),
- new NumberEval(10),
- new NumberEval(4),
+ new NumberEval(25),
+ new NumberEval(10),
+ new NumberEval(10),
+ new NumberEval(10),
+ new NumberEval(4),
};
-
- AreaEval ae = createAreaEval("A1:A5", values);
-
+
+ AreaEval ae = EvalFactory.createAreaEval("A1:A5", values);
+
confirmInt(2, invokeMatch(new NumberEval(10), ae, MATCH_SMALLEST_GTE));
confirmInt(2, invokeMatch(new NumberEval(10), ae, MATCH_EXACT));
confirmInt(4, invokeMatch(new NumberEval(9), ae, MATCH_SMALLEST_GTE));
assertEquals(ErrorEval.NA, invokeMatch(new NumberEval(20), ae, MATCH_EXACT));
assertEquals(ErrorEval.NA, invokeMatch(new NumberEval(26), ae, MATCH_SMALLEST_GTE));
}
-
+
public void testSimpleString() {
-
+
ValueEval[] values = {
- new StringEval("Albert"),
- new StringEval("Charles"),
- new StringEval("Ed"),
- new StringEval("Greg"),
- new StringEval("Ian"),
+ new StringEval("Albert"),
+ new StringEval("Charles"),
+ new StringEval("Ed"),
+ new StringEval("Greg"),
+ new StringEval("Ian"),
};
-
- AreaEval ae = createAreaEval("A1:A5", values);
-
+
+ AreaEval ae = EvalFactory.createAreaEval("A1:A5", values);
+
// Note String comparisons are case insensitive
confirmInt(3, invokeMatch(new StringEval("Ed"), ae, MATCH_LARGEST_LTE));
confirmInt(3, invokeMatch(new StringEval("eD"), ae, MATCH_LARGEST_LTE));
confirmInt(4, invokeMatch(new StringEval("Hugh"), ae, MATCH_LARGEST_LTE));
assertEquals(ErrorEval.NA, invokeMatch(new StringEval("Hugh"), ae, MATCH_EXACT));
}
-
+
public void testSimpleBoolean() {
-
+
ValueEval[] values = {
- BoolEval.FALSE,
- BoolEval.FALSE,
- BoolEval.TRUE,
- BoolEval.TRUE,
+ BoolEval.FALSE,
+ BoolEval.FALSE,
+ BoolEval.TRUE,
+ BoolEval.TRUE,
};
-
- AreaEval ae = createAreaEval("A1:A4", values);
-
+
+ AreaEval ae = EvalFactory.createAreaEval("A1:A4", values);
+
// Note String comparisons are case insensitive
confirmInt(2, invokeMatch(BoolEval.FALSE, ae, MATCH_LARGEST_LTE));
confirmInt(1, invokeMatch(BoolEval.FALSE, ae, MATCH_EXACT));
confirmInt(4, invokeMatch(BoolEval.TRUE, ae, MATCH_LARGEST_LTE));
confirmInt(3, invokeMatch(BoolEval.TRUE, ae, MATCH_EXACT));
}
-
+
public void testHeterogeneous() {
-
+
ValueEval[] values = {
- new NumberEval(4),
- BoolEval.FALSE,
+ new NumberEval(4),
+ BoolEval.FALSE,
new NumberEval(5),
- new StringEval("Albert"),
- BoolEval.FALSE,
- BoolEval.TRUE,
- new NumberEval(10),
- new StringEval("Charles"),
- new StringEval("Ed"),
- new NumberEval(10),
- new NumberEval(25),
- BoolEval.TRUE,
- new StringEval("Ed"),
+ new StringEval("Albert"),
+ BoolEval.FALSE,
+ BoolEval.TRUE,
+ new NumberEval(10),
+ new StringEval("Charles"),
+ new StringEval("Ed"),
+ new NumberEval(10),
+ new NumberEval(25),
+ BoolEval.TRUE,
+ new StringEval("Ed"),
};
-
- AreaEval ae = createAreaEval("A1:A13", values);
-
+
+ AreaEval ae = EvalFactory.createAreaEval("A1:A13", values);
+
assertEquals(ErrorEval.NA, invokeMatch(new StringEval("Aaron"), ae, MATCH_LARGEST_LTE));
-
+
confirmInt(5, invokeMatch(BoolEval.FALSE, ae, MATCH_LARGEST_LTE));
confirmInt(2, invokeMatch(BoolEval.FALSE, ae, MATCH_EXACT));
confirmInt(3, invokeMatch(new NumberEval(5), ae, MATCH_LARGEST_LTE));
confirmInt(3, invokeMatch(new NumberEval(5), ae, MATCH_EXACT));
-
+
confirmInt(8, invokeMatch(new StringEval("CHARLES"), ae, MATCH_EXACT));
-
+
confirmInt(4, invokeMatch(new StringEval("Ben"), ae, MATCH_LARGEST_LTE));
-
+
confirmInt(13, invokeMatch(new StringEval("ED"), ae, MATCH_LARGEST_LTE));
confirmInt(9, invokeMatch(new StringEval("ED"), ae, MATCH_EXACT));
-
+
confirmInt(13, invokeMatch(new StringEval("Hugh"), ae, MATCH_LARGEST_LTE));
assertEquals(ErrorEval.NA, invokeMatch(new StringEval("Hugh"), ae, MATCH_EXACT));
-
+
confirmInt(11, invokeMatch(new NumberEval(30), ae, MATCH_LARGEST_LTE));
confirmInt(12, invokeMatch(BoolEval.TRUE, ae, MATCH_LARGEST_LTE));
}
-
+
/**
* Ensures that the match_type argument can be an <tt>AreaEval</tt>.<br/>
* Bugzilla 44421
*/
public void testMatchArgTypeArea() {
-
+
ValueEval[] values = {
- new NumberEval(4),
- new NumberEval(5),
- new NumberEval(10),
- new NumberEval(10),
- new NumberEval(25),
+ new NumberEval(4),
+ new NumberEval(5),
+ new NumberEval(10),
+ new NumberEval(10),
+ new NumberEval(25),
};
-
- AreaEval ae = createAreaEval("A1:A5", values);
- AreaEval matchAE = createAreaEval("C1:C1", new ValueEval[] { MATCH_LARGEST_LTE, });
-
+ AreaEval ae = EvalFactory.createAreaEval("A1:A5", values);
+
+ AreaEval matchAE = EvalFactory.createAreaEval("C1:C1", new ValueEval[] { MATCH_LARGEST_LTE, });
+
try {
confirmInt(4, invokeMatch(new NumberEval(10), ae, matchAE));
} catch (RuntimeException e) {
if(e.getMessage().startsWith("Unexpected match_type type")) {
- // identified bug 44421
+ // identified bug 44421
fail(e.getMessage());
}
// some other error ??
*/
package org.apache.poi.hssf.record.formula.functions;
+import org.apache.poi.hssf.record.formula.functions.XYNumericFunction.Accumulator;
+
/**
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
}
public void testSumx2my2() {
- double d = 0;
double[] xarr = null;
double[] yarr = null;
xarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
yarr = new double[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
- d = MathX.sumx2my2(xarr, yarr);
- assertEquals("sumx2my2 ", 100, d);
+ confirmSumx2my2(xarr, yarr, 100);
xarr = new double[]{-1, -2, -3, -4, -5, -6, -7, -8, -9, -10};
yarr = new double[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
- d = MathX.sumx2my2(xarr, yarr);
- assertEquals("sumx2my2 ", 100, d);
+ confirmSumx2my2(xarr, yarr, 100);
xarr = new double[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
yarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
- d = MathX.sumx2my2(xarr, yarr);
- assertEquals("sumx2my2 ", -100, d);
+ confirmSumx2my2(xarr, yarr, -100);
xarr = new double[]{10};
yarr = new double[]{9};
- d = MathX.sumx2my2(xarr, yarr);
- assertEquals("sumx2my2 ", 19, d);
+ confirmSumx2my2(xarr, yarr, 19);
xarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
yarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
- d = MathX.sumx2my2(xarr, yarr);
- assertEquals("sumx2my2 ", 0, d);
-
+ confirmSumx2my2(xarr, yarr, 0);
}
public void testSumx2py2() {
- double d = 0;
double[] xarr = null;
double[] yarr = null;
xarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
yarr = new double[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
- d = MathX.sumx2py2(xarr, yarr);
- assertEquals("sumx2py2 ", 670, d);
+ confirmSumx2py2(xarr, yarr, 670);
xarr = new double[]{-1, -2, -3, -4, -5, -6, -7, -8, -9, -10};
yarr = new double[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
- d = MathX.sumx2py2(xarr, yarr);
- assertEquals("sumx2py2 ", 670, d);
+ confirmSumx2py2(xarr, yarr, 670);
xarr = new double[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
yarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
- d = MathX.sumx2py2(xarr, yarr);
- assertEquals("sumx2py2 ", 670, d);
+ confirmSumx2py2(xarr, yarr, 670);
xarr = new double[]{10};
yarr = new double[]{9};
- d = MathX.sumx2py2(xarr, yarr);
- assertEquals("sumx2py2 ", 181, d);
+ confirmSumx2py2(xarr, yarr, 181);
xarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
yarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
- d = MathX.sumx2py2(xarr, yarr);
- assertEquals("sumx2py2 ", 770, d);
+ confirmSumx2py2(xarr, yarr, 770);
}
public void testSumxmy2() {
- double d = 0;
double[] xarr = null;
double[] yarr = null;
xarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
yarr = new double[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
- d = MathX.sumxmy2(xarr, yarr);
- assertEquals("sumxmy2 ", 10, d);
+ confirmSumxmy2(xarr, yarr, 10);
xarr = new double[]{-1, -2, -3, -4, -5, -6, -7, -8, -9, -10};
yarr = new double[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
- d = MathX.sumxmy2(xarr, yarr);
- assertEquals("sumxmy2 ", 1330, d);
+ confirmSumxmy2(xarr, yarr, 1330);
xarr = new double[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
yarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
- d = MathX.sumxmy2(xarr, yarr);
- assertEquals("sumxmy2 ", 10, d);
+ confirmSumxmy2(xarr, yarr, 10);
xarr = new double[]{10};
yarr = new double[]{9};
- d = MathX.sumxmy2(xarr, yarr);
- assertEquals("sumxmy2 ", 1, d);
+ confirmSumxmy2(xarr, yarr, 1);
xarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
yarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
- d = MathX.sumxmy2(xarr, yarr);
- assertEquals("sumxmy2 ", 0, d);
+ confirmSumxmy2(xarr, yarr, 0);
}
+ private static void confirmSumx2my2(double[] xarr, double[] yarr, double expectedResult) {
+ confirmXY(new Sumx2my2().createAccumulator(), xarr, yarr, expectedResult);
+ }
+ private static void confirmSumx2py2(double[] xarr, double[] yarr, double expectedResult) {
+ confirmXY(new Sumx2py2().createAccumulator(), xarr, yarr, expectedResult);
+ }
+ private static void confirmSumxmy2(double[] xarr, double[] yarr, double expectedResult) {
+ confirmXY(new Sumxmy2().createAccumulator(), xarr, yarr, expectedResult);
+ }
+
+ private static void confirmXY(Accumulator acc, double[] xarr, double[] yarr,
+ double expectedResult) {
+ double result = 0.0;
+ for (int i = 0; i < xarr.length; i++) {
+ result += acc.accumulate(xarr[i], yarr[i]);
+ }
+ assertEquals(expectedResult, result, 0.0);
+ }
+
public void testRound() {
double d = 0;
int p = 0;
package org.apache.poi.hssf.record.formula.functions;
-import org.apache.poi.hssf.record.formula.AreaPtg;
-import org.apache.poi.hssf.record.formula.RefPtg;
-import org.apache.poi.hssf.record.formula.eval.Area2DEval;
+import junit.framework.TestCase;
+
import org.apache.poi.hssf.record.formula.eval.AreaEval;
import org.apache.poi.hssf.record.formula.eval.BlankEval;
import org.apache.poi.hssf.record.formula.eval.BoolEval;
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
import org.apache.poi.hssf.record.formula.eval.Eval;
import org.apache.poi.hssf.record.formula.eval.NumberEval;
-import org.apache.poi.hssf.record.formula.eval.Ref2DEval;
import org.apache.poi.hssf.record.formula.eval.RefEval;
import org.apache.poi.hssf.record.formula.eval.StringEval;
import org.apache.poi.hssf.record.formula.eval.ValueEval;
-
-import junit.framework.TestCase;
/**
* Tests for Excel function MID()
- *
+ *
* @author Josh Micich
*/
public final class TestMid extends TestCase {
-
+
private static Eval invokeMid(Eval text, Eval startPos, Eval numChars) {
Eval[] args = new Eval[] { text, startPos, numChars, };
return new Mid().evaluate(args, -1, (short)-1);
assertEquals(ErrorEval.class, result.getClass());
assertEquals(expectedError.getErrorCode(), ((ErrorEval)result).getErrorCode());
}
-
+
public void testBasic() {
-
+
confirmMid(new StringEval("galactic"), new NumberEval(3), new NumberEval(4), "lact");
}
-
+
/**
* Valid cases where args are not precisely (string, int, int) but can be resolved OK.
*/
public void testUnusualArgs() {
// startPos with fractional digits
confirmMid(new StringEval("galactic"), new NumberEval(3.1), new NumberEval(4), "lact");
-
+
// string startPos
confirmMid(new StringEval("galactic"), new StringEval("3"), new NumberEval(4), "lact");
-
- // text (first) arg type is number, other args are strings with fractional digits
+
+ // text (first) arg type is number, other args are strings with fractional digits
confirmMid(new NumberEval(123456), new StringEval("3.1"), new StringEval("2.9"), "34");
-
+
// startPos is 1x1 area ref, numChars is cell ref
- AreaEval aeStart = new Area2DEval(new AreaPtg("A1:A1"), new ValueEval[] { new NumberEval(2), } );
- RefEval reNumChars = new Ref2DEval(new RefPtg("B1"), new NumberEval(3));
+ AreaEval aeStart = EvalFactory.createAreaEval("A1:A1", new ValueEval[] { new NumberEval(2), } );
+ RefEval reNumChars = EvalFactory.createRefEval("B1", new NumberEval(3));
confirmMid(new StringEval("galactic"), aeStart, reNumChars, "ala");
confirmMid(new StringEval("galactic"), new NumberEval(3.1), BlankEval.INSTANCE, "");
confirmMid(new StringEval("galactic"), new NumberEval(3), BoolEval.FALSE, "");
confirmMid(new StringEval("galactic"), new NumberEval(3), BoolEval.TRUE, "l");
confirmMid(BlankEval.INSTANCE, new NumberEval(3), BoolEval.TRUE, "");
-
+
}
/**
*/
public void testExtremes() {
confirmMid(new StringEval("galactic"), new NumberEval(4), new NumberEval(400), "actic");
-
+
confirmMid(new StringEval("galactic"), new NumberEval(30), new NumberEval(4), "");
confirmMid(new StringEval("galactic"), new NumberEval(3), new NumberEval(0), "");
}
confirmMid(new StringEval("galactic"), ErrorEval.NAME_INVALID, new NumberEval(4), ErrorEval.NAME_INVALID);
confirmMid(new StringEval("galactic"), new NumberEval(3), ErrorEval.NAME_INVALID, ErrorEval.NAME_INVALID);
confirmMid(new StringEval("galactic"), ErrorEval.DIV_ZERO, ErrorEval.NAME_INVALID, ErrorEval.DIV_ZERO);
-
+
confirmMid(new StringEval("galactic"), BlankEval.INSTANCE, new NumberEval(3.1), ErrorEval.VALUE_INVALID);
-
+
confirmMid(new StringEval("galactic"), new NumberEval(0), new NumberEval(4), ErrorEval.VALUE_INVALID);
confirmMid(new StringEval("galactic"), new NumberEval(1), new NumberEval(-1), ErrorEval.VALUE_INVALID);
}
package org.apache.poi.hssf.record.formula.functions;
-import org.apache.poi.hssf.record.formula.RefPtg;
+import junit.framework.TestCase;
+
import org.apache.poi.hssf.record.formula.eval.AreaEval;
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
import org.apache.poi.hssf.record.formula.eval.Eval;
import org.apache.poi.hssf.record.formula.eval.NumberEval;
import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
-import org.apache.poi.hssf.record.formula.eval.Ref2DEval;
import org.apache.poi.hssf.record.formula.eval.RefEval;
import org.apache.poi.hssf.record.formula.eval.ValueEval;
-import junit.framework.TestCase;
-
/**
* Test cases for SUMPRODUCT()
*
public void testScalarSimple() {
- RefEval refEval = new Ref2DEval(new RefPtg("A1"), new NumberEval(3));
+ RefEval refEval = EvalFactory.createRefEval("A1", new NumberEval(3));
Eval[] args = {
refEval,
new NumberEval(2),
package org.apache.poi.hssf.record.formula.functions;
-import org.apache.poi.hssf.record.formula.RefPtg;
+import junit.framework.TestCase;
+
import org.apache.poi.hssf.record.formula.eval.BlankEval;
import org.apache.poi.hssf.record.formula.eval.BoolEval;
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
import org.apache.poi.hssf.record.formula.eval.Eval;
import org.apache.poi.hssf.record.formula.eval.NumberEval;
-import org.apache.poi.hssf.record.formula.eval.Ref2DEval;
import org.apache.poi.hssf.record.formula.eval.StringEval;
import org.apache.poi.hssf.record.formula.eval.ValueEval;
-import junit.framework.TestCase;
-
/**
* Test cases for Excel function T()
*
* where cell A1 has the specified innerValue
*/
private Eval invokeTWithReference(ValueEval innerValue) {
- Eval arg = new Ref2DEval(new RefPtg((short)1, (short)1, false, false), innerValue);
+ Eval arg = EvalFactory.createRefEval("$B$2", innerValue);
return invokeT(arg);
}
import junit.framework.TestCase;
-import org.apache.poi.hssf.record.formula.AreaPtg;
-import org.apache.poi.hssf.record.formula.eval.Area2DEval;
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
import org.apache.poi.hssf.record.formula.eval.Eval;
import org.apache.poi.hssf.record.formula.eval.NumberEval;
private static ValueEval createAreaEval(ValueEval[] values) {
String refStr = "A1:A" + values.length;
- return new Area2DEval(new AreaPtg(refStr), values);
+ return EvalFactory.createAreaEval(refStr, values);
}
public void testErrors() {