Whitespace / indents

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1755068 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Nick Burch 2016-08-03 11:15:13 +00:00
parent 07dc4cecc4
commit b61ed84a8f
1 changed files with 310 additions and 313 deletions
src/java/org/apache/poi/hssf/usermodel

View File

@ -46,333 +46,330 @@ import org.apache.poi.util.Internal;
* calls to evaluate~ methods on this class. * calls to evaluate~ methods on this class.
*/ */
public class HSSFFormulaEvaluator implements FormulaEvaluator, WorkbookEvaluatorProvider { public class HSSFFormulaEvaluator implements FormulaEvaluator, WorkbookEvaluatorProvider {
private final WorkbookEvaluator _bookEvaluator;
private final HSSFWorkbook _book;
private final WorkbookEvaluator _bookEvaluator; public HSSFFormulaEvaluator(HSSFWorkbook workbook) {
private final HSSFWorkbook _book; this(workbook, null);
}
public HSSFFormulaEvaluator(HSSFWorkbook workbook) { /**
this(workbook, null); * @param workbook The workbook to perform the formula evaluations in
}
/**
* @param workbook The workbook to perform the formula evaluations in
* @param stabilityClassifier used to optimise caching performance. Pass <code>null</code>
* for the (conservative) assumption that any cell may have its definition changed after
* evaluation begins.
*/
public HSSFFormulaEvaluator(HSSFWorkbook workbook, IStabilityClassifier stabilityClassifier) {
this(workbook, stabilityClassifier, null);
}
/**
* @param workbook The workbook to perform the formula evaluations in
* @param stabilityClassifier used to optimise caching performance. Pass <code>null</code> * @param stabilityClassifier used to optimise caching performance. Pass <code>null</code>
* for the (conservative) assumption that any cell may have its definition changed after * for the (conservative) assumption that any cell may have its definition changed after
* evaluation begins. * evaluation begins.
* @param udfFinder pass <code>null</code> for default (AnalysisToolPak only) */
*/ public HSSFFormulaEvaluator(HSSFWorkbook workbook, IStabilityClassifier stabilityClassifier) {
private HSSFFormulaEvaluator(HSSFWorkbook workbook, IStabilityClassifier stabilityClassifier, UDFFinder udfFinder) { this(workbook, stabilityClassifier, null);
_book = workbook; }
_bookEvaluator = new WorkbookEvaluator(HSSFEvaluationWorkbook.create(workbook), stabilityClassifier, udfFinder);
}
/** /**
* @param workbook The workbook to perform the formula evaluations in * @param workbook The workbook to perform the formula evaluations in
* @param stabilityClassifier used to optimise caching performance. Pass <code>null</code> * @param stabilityClassifier used to optimise caching performance. Pass <code>null</code>
* for the (conservative) assumption that any cell may have its definition changed after * for the (conservative) assumption that any cell may have its definition changed after
* evaluation begins. * evaluation begins.
* @param udfFinder pass <code>null</code> for default (AnalysisToolPak only) * @param udfFinder pass <code>null</code> for default (AnalysisToolPak only)
*/ */
public static HSSFFormulaEvaluator create(HSSFWorkbook workbook, IStabilityClassifier stabilityClassifier, UDFFinder udfFinder) { private HSSFFormulaEvaluator(HSSFWorkbook workbook, IStabilityClassifier stabilityClassifier, UDFFinder udfFinder) {
return new HSSFFormulaEvaluator(workbook, stabilityClassifier, udfFinder); _book = workbook;
} _bookEvaluator = new WorkbookEvaluator(HSSFEvaluationWorkbook.create(workbook), stabilityClassifier, udfFinder);
}
/**
* @param workbook The workbook to perform the formula evaluations in
* @param stabilityClassifier used to optimise caching performance. Pass <code>null</code>
* for the (conservative) assumption that any cell may have its definition changed after
* evaluation begins.
* @param udfFinder pass <code>null</code> for default (AnalysisToolPak only)
*/
public static HSSFFormulaEvaluator create(HSSFWorkbook workbook, IStabilityClassifier stabilityClassifier, UDFFinder udfFinder) {
return new HSSFFormulaEvaluator(workbook, stabilityClassifier, udfFinder);
}
/** /**
* Coordinates several formula evaluators together so that formulas that involve external * Coordinates several formula evaluators together so that formulas that involve external
* references can be evaluated. * references can be evaluated.
* @param workbookNames the simple file names used to identify the workbooks in formulas * @param workbookNames the simple file names used to identify the workbooks in formulas
* with external links (for example "MyData.xls" as used in a formula "[MyData.xls]Sheet1!A1") * with external links (for example "MyData.xls" as used in a formula "[MyData.xls]Sheet1!A1")
* @param evaluators all evaluators for the full set of workbooks required by the formulas. * @param evaluators all evaluators for the full set of workbooks required by the formulas.
*/ */
public static void setupEnvironment(String[] workbookNames, HSSFFormulaEvaluator[] evaluators) { public static void setupEnvironment(String[] workbookNames, HSSFFormulaEvaluator[] evaluators) {
WorkbookEvaluator[] wbEvals = new WorkbookEvaluator[evaluators.length]; WorkbookEvaluator[] wbEvals = new WorkbookEvaluator[evaluators.length];
for (int i = 0; i < wbEvals.length; i++) { for (int i = 0; i < wbEvals.length; i++) {
wbEvals[i] = evaluators[i]._bookEvaluator; wbEvals[i] = evaluators[i]._bookEvaluator;
} }
CollaboratingWorkbooksEnvironment.setup(workbookNames, wbEvals); CollaboratingWorkbooksEnvironment.setup(workbookNames, wbEvals);
} }
@Override @Override
public void setupReferencedWorkbooks(Map<String, FormulaEvaluator> evaluators) { public void setupReferencedWorkbooks(Map<String, FormulaEvaluator> evaluators) {
CollaboratingWorkbooksEnvironment.setupFormulaEvaluator(evaluators); CollaboratingWorkbooksEnvironment.setupFormulaEvaluator(evaluators);
} }
@Override @Override
public WorkbookEvaluator _getWorkbookEvaluator() { public WorkbookEvaluator _getWorkbookEvaluator() {
return _bookEvaluator; return _bookEvaluator;
} }
/** /**
* Should be called whenever there are major changes (e.g. moving sheets) to input cells * Should be called whenever there are major changes (e.g. moving sheets) to input cells
* in the evaluated workbook. If performance is not critical, a single call to this method * in the evaluated workbook. If performance is not critical, a single call to this method
* may be used instead of many specific calls to the notify~ methods. * may be used instead of many specific calls to the notify~ methods.
* *
* Failure to call this method after changing cell values will cause incorrect behaviour * Failure to call this method after changing cell values will cause incorrect behaviour
* of the evaluate~ methods of this class * of the evaluate~ methods of this class
*/ */
@Override @Override
public void clearAllCachedResultValues() { public void clearAllCachedResultValues() {
_bookEvaluator.clearAllCachedResultValues(); _bookEvaluator.clearAllCachedResultValues();
} }
/** /**
* Should be called to tell the cell value cache that the specified (value or formula) cell * Should be called to tell the cell value cache that the specified (value or formula) cell
* has changed. * has changed.
* Failure to call this method after changing cell values will cause incorrect behaviour * Failure to call this method after changing cell values will cause incorrect behaviour
* of the evaluate~ methods of this class * of the evaluate~ methods of this class
*/ */
public void notifyUpdateCell(HSSFCell cell) { public void notifyUpdateCell(HSSFCell cell) {
_bookEvaluator.notifyUpdateCell(new HSSFEvaluationCell(cell)); _bookEvaluator.notifyUpdateCell(new HSSFEvaluationCell(cell));
} }
@Override @Override
public void notifyUpdateCell(Cell cell) { public void notifyUpdateCell(Cell cell) {
_bookEvaluator.notifyUpdateCell(new HSSFEvaluationCell((HSSFCell)cell)); _bookEvaluator.notifyUpdateCell(new HSSFEvaluationCell((HSSFCell)cell));
} }
/** /**
* Should be called to tell the cell value cache that the specified cell has just been * Should be called to tell the cell value cache that the specified cell has just been
* deleted. * deleted.
* Failure to call this method after changing cell values will cause incorrect behaviour * Failure to call this method after changing cell values will cause incorrect behaviour
* of the evaluate~ methods of this class * of the evaluate~ methods of this class
*/ */
public void notifyDeleteCell(HSSFCell cell) { public void notifyDeleteCell(HSSFCell cell) {
_bookEvaluator.notifyDeleteCell(new HSSFEvaluationCell(cell)); _bookEvaluator.notifyDeleteCell(new HSSFEvaluationCell(cell));
} }
@Override @Override
public void notifyDeleteCell(Cell cell) { public void notifyDeleteCell(Cell cell) {
_bookEvaluator.notifyDeleteCell(new HSSFEvaluationCell((HSSFCell)cell)); _bookEvaluator.notifyDeleteCell(new HSSFEvaluationCell((HSSFCell)cell));
} }
/** /**
* Should be called to tell the cell value cache that the specified (value or formula) cell * Should be called to tell the cell value cache that the specified (value or formula) cell
* has changed. * has changed.
* Failure to call this method after changing cell values will cause incorrect behaviour * Failure to call this method after changing cell values will cause incorrect behaviour
* of the evaluate~ methods of this class * of the evaluate~ methods of this class
*/ */
@Override @Override
public void notifySetFormula(Cell cell) { public void notifySetFormula(Cell cell) {
_bookEvaluator.notifyUpdateCell(new HSSFEvaluationCell((HSSFCell)cell)); _bookEvaluator.notifyUpdateCell(new HSSFEvaluationCell((HSSFCell)cell));
} }
/** /**
* If cell contains a formula, the formula is evaluated and returned, * If cell contains a formula, the formula is evaluated and returned,
* else the CellValue simply copies the appropriate cell value from * else the CellValue simply copies the appropriate cell value from
* the cell and also its cell type. This method should be preferred over * the cell and also its cell type. This method should be preferred over
* evaluateInCell() when the call should not modify the contents of the * evaluateInCell() when the call should not modify the contents of the
* original cell. * original cell.
* *
* @param cell may be <code>null</code> signifying that the cell is not present (or blank) * @param cell may be <code>null</code> signifying that the cell is not present (or blank)
* @return <code>null</code> if the supplied cell is <code>null</code> or blank * @return <code>null</code> if the supplied cell is <code>null</code> or blank
*/ */
@Override @Override
public CellValue evaluate(Cell cell) { public CellValue evaluate(Cell cell) {
if (cell == null) { if (cell == null) {
return null; return null;
} }
switch (cell.getCellTypeEnum()) { switch (cell.getCellTypeEnum()) {
case BOOLEAN: case BOOLEAN:
return CellValue.valueOf(cell.getBooleanCellValue()); return CellValue.valueOf(cell.getBooleanCellValue());
case ERROR: case ERROR:
return CellValue.getError(cell.getErrorCellValue()); return CellValue.getError(cell.getErrorCellValue());
case FORMULA: case FORMULA:
return evaluateFormulaCellValue(cell); return evaluateFormulaCellValue(cell);
case NUMERIC: case NUMERIC:
return new CellValue(cell.getNumericCellValue()); return new CellValue(cell.getNumericCellValue());
case STRING: case STRING:
return new CellValue(cell.getRichStringCellValue().getString()); return new CellValue(cell.getRichStringCellValue().getString());
case BLANK: case BLANK:
return null; return null;
default: default:
throw new IllegalStateException("Bad cell type (" + cell.getCellTypeEnum() + ")"); throw new IllegalStateException("Bad cell type (" + cell.getCellTypeEnum() + ")");
} }
}
}
/** /**
* If cell contains formula, it evaluates the formula, and saves the result of the formula. The * If cell contains formula, it evaluates the formula, and saves the result of the formula. The
* cell remains as a formula cell. If the cell does not contain formula, this method returns -1 * cell remains as a formula cell. If the cell does not contain formula, this method returns -1
* and leaves the cell unchanged. * and leaves the cell unchanged.
* *
* Note that the type of the <em>formula result</em> is returned, so you know what kind of * Note that the type of the <em>formula result</em> is returned, so you know what kind of
* cached formula result is also stored with the formula. * cached formula result is also stored with the formula.
* <pre> * <pre>
* int evaluatedCellType = evaluator.evaluateFormulaCell(cell); * int evaluatedCellType = evaluator.evaluateFormulaCell(cell);
* </pre> * </pre>
* Be aware that your cell will hold both the formula, and the result. If you want the cell * Be aware that your cell will hold both the formula, and the result. If you want the cell
* replaced with the result of the formula, use {@link #evaluateInCell(org.apache.poi.ss.usermodel.Cell)} * replaced with the result of the formula, use {@link #evaluateInCell(org.apache.poi.ss.usermodel.Cell)}
* @param cell The cell to evaluate * @param cell The cell to evaluate
* @return -1 for non-formula cells, or the type of the <em>formula result</em> * @return -1 for non-formula cells, or the type of the <em>formula result</em>
*/ */
@Override @Override
public int evaluateFormulaCell(Cell cell) { public int evaluateFormulaCell(Cell cell) {
return evaluateFormulaCellEnum(cell).getCode(); return evaluateFormulaCellEnum(cell).getCode();
} }
/**
* If cell contains formula, it evaluates the formula, and saves the result of the formula. The
* cell remains as a formula cell. If the cell does not contain formula, rather than throwing an
* exception, this method returns {@link CellType#_NONE} and leaves the cell unchanged.
*
* Note that the type of the <em>formula result</em> is returned, so you know what kind of
* cached formula result is also stored with the formula.
* <pre>
* CellType evaluatedCellType = evaluator.evaluateFormulaCell(cell);
* </pre>
* Be aware that your cell will hold both the formula, and the result. If you want the cell
* replaced with the result of the formula, use {@link #evaluateInCell(org.apache.poi.ss.usermodel.Cell)}
* @param cell The cell to evaluate
* @return {@link CellType#_NONE} for non-formula cells, or the type of the <em>formula result</em>
* @since POI 3.15 beta 3
* @deprecated POI 3.15 beta 3. Will be deleted when we make the CellType enum transition. See bug 59791.
*/
@Internal
@Override
public CellType evaluateFormulaCellEnum(Cell cell) {
if (cell == null || cell.getCellTypeEnum() != CellType.FORMULA) {
return CellType._NONE;
}
CellValue cv = evaluateFormulaCellValue(cell);
// cell remains a formula cell, but the cached value is changed
setCellValue(cell, cv);
return cv.getCellType();
}
/** /**
* If cell contains formula, it evaluates the formula, and * If cell contains formula, it evaluates the formula, and saves the result of the formula. The
* puts the formula result back into the cell, in place * cell remains as a formula cell. If the cell does not contain formula, rather than throwing an
* of the old formula. * exception, this method returns {@link CellType#_NONE} and leaves the cell unchanged.
* Else if cell does not contain formula, this method leaves *
* the cell unchanged. * Note that the type of the <em>formula result</em> is returned, so you know what kind of
* Note that the same instance of HSSFCell is returned to * cached formula result is also stored with the formula.
* allow chained calls like: * <pre>
* <pre> * CellType evaluatedCellType = evaluator.evaluateFormulaCell(cell);
* int evaluatedCellType = evaluator.evaluateInCell(cell).getCellType(); * </pre>
* </pre> * Be aware that your cell will hold both the formula, and the result. If you want the cell
* Be aware that your cell value will be changed to hold the * replaced with the result of the formula, use {@link #evaluateInCell(org.apache.poi.ss.usermodel.Cell)}
* result of the formula. If you simply want the formula * @param cell The cell to evaluate
* value computed for you, use {@link #evaluateFormulaCellEnum(Cell)}} * @return {@link CellType#_NONE} for non-formula cells, or the type of the <em>formula result</em>
*/ * @since POI 3.15 beta 3
@Override * @deprecated POI 3.15 beta 3. Will be deleted when we make the CellType enum transition. See bug 59791.
public HSSFCell evaluateInCell(Cell cell) { */
if (cell == null) { @Internal
return null; @Override
} public CellType evaluateFormulaCellEnum(Cell cell) {
HSSFCell result = (HSSFCell) cell; if (cell == null || cell.getCellTypeEnum() != CellType.FORMULA) {
if (cell.getCellTypeEnum() == CellType.FORMULA) { return CellType._NONE;
CellValue cv = evaluateFormulaCellValue(cell); }
setCellValue(cell, cv); CellValue cv = evaluateFormulaCellValue(cell);
setCellType(cell, cv); // cell will no longer be a formula cell // cell remains a formula cell, but the cached value is changed
} setCellValue(cell, cv);
return result; return cv.getCellType();
} }
private static void setCellType(Cell cell, CellValue cv) {
CellType cellType = cv.getCellType();
switch (cellType) {
case BOOLEAN:
case ERROR:
case NUMERIC:
case STRING:
cell.setCellType(cellType);
return;
case BLANK:
// never happens - blanks eventually get translated to zero
case FORMULA:
// this will never happen, we have already evaluated the formula
default:
throw new IllegalStateException("Unexpected cell value type (" + cellType + ")");
}
}
private static void setCellValue(Cell cell, CellValue cv) { /**
CellType cellType = cv.getCellType(); * If cell contains formula, it evaluates the formula, and
switch (cellType) { * puts the formula result back into the cell, in place
case BOOLEAN: * of the old formula.
cell.setCellValue(cv.getBooleanValue()); * Else if cell does not contain formula, this method leaves
break; * the cell unchanged.
case ERROR: * Note that the same instance of HSSFCell is returned to
cell.setCellErrorValue(cv.getErrorValue()); * allow chained calls like:
break; * <pre>
case NUMERIC: * int evaluatedCellType = evaluator.evaluateInCell(cell).getCellType();
cell.setCellValue(cv.getNumberValue()); * </pre>
break; * Be aware that your cell value will be changed to hold the
case STRING: * result of the formula. If you simply want the formula
cell.setCellValue(new HSSFRichTextString(cv.getStringValue())); * value computed for you, use {@link #evaluateFormulaCellEnum(Cell)}}
break; */
case BLANK: @Override
// never happens - blanks eventually get translated to zero public HSSFCell evaluateInCell(Cell cell) {
case FORMULA: if (cell == null) {
// this will never happen, we have already evaluated the formula return null;
default: }
throw new IllegalStateException("Unexpected cell value type (" + cellType + ")"); HSSFCell result = (HSSFCell) cell;
} if (cell.getCellTypeEnum() == CellType.FORMULA) {
} CellValue cv = evaluateFormulaCellValue(cell);
setCellValue(cell, cv);
setCellType(cell, cv); // cell will no longer be a formula cell
}
return result;
}
private static void setCellType(Cell cell, CellValue cv) {
CellType cellType = cv.getCellType();
switch (cellType) {
case BOOLEAN:
case ERROR:
case NUMERIC:
case STRING:
cell.setCellType(cellType);
return;
case BLANK:
// never happens - blanks eventually get translated to zero
case FORMULA:
// this will never happen, we have already evaluated the formula
default:
throw new IllegalStateException("Unexpected cell value type (" + cellType + ")");
}
}
/** private static void setCellValue(Cell cell, CellValue cv) {
* Loops over all cells in all sheets of the supplied CellType cellType = cv.getCellType();
* workbook. switch (cellType) {
* For cells that contain formulas, their formulas are case BOOLEAN:
* evaluated, and the results are saved. These cells cell.setCellValue(cv.getBooleanValue());
* remain as formula cells. break;
* For cells that do not contain formulas, no changes case ERROR:
* are made. cell.setCellErrorValue(cv.getErrorValue());
* This is a helpful wrapper around looping over all break;
* cells, and calling evaluateFormulaCell on each one. case NUMERIC:
*/ cell.setCellValue(cv.getNumberValue());
public static void evaluateAllFormulaCells(HSSFWorkbook wb) { break;
evaluateAllFormulaCells(wb, new HSSFFormulaEvaluator(wb)); case STRING:
} cell.setCellValue(new HSSFRichTextString(cv.getStringValue()));
break;
/** case BLANK:
* Loops over all cells in all sheets of the supplied // never happens - blanks eventually get translated to zero
* workbook. case FORMULA:
* For cells that contain formulas, their formulas are // this will never happen, we have already evaluated the formula
* evaluated, and the results are saved. These cells default:
* remain as formula cells. throw new IllegalStateException("Unexpected cell value type (" + cellType + ")");
* For cells that do not contain formulas, no changes }
* are made. }
* This is a helpful wrapper around looping over all
* cells, and calling evaluateFormulaCell on each one.
*/
public static void evaluateAllFormulaCells(Workbook wb) {
FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();
evaluateAllFormulaCells(wb, evaluator);
}
private static void evaluateAllFormulaCells(Workbook wb, FormulaEvaluator evaluator) {
for(int i=0; i<wb.getNumberOfSheets(); i++) {
Sheet sheet = wb.getSheetAt(i);
for(Row r : sheet) { /**
for (Cell c : r) { * Loops over all cells in all sheets of the supplied
if (c.getCellTypeEnum() == CellType.FORMULA) { * workbook.
evaluator.evaluateFormulaCellEnum(c); * For cells that contain formulas, their formulas are
} * evaluated, and the results are saved. These cells
* remain as formula cells.
* For cells that do not contain formulas, no changes
* are made.
* This is a helpful wrapper around looping over all
* cells, and calling evaluateFormulaCell on each one.
*/
public static void evaluateAllFormulaCells(HSSFWorkbook wb) {
evaluateAllFormulaCells(wb, new HSSFFormulaEvaluator(wb));
}
/**
* Loops over all cells in all sheets of the supplied
* workbook.
* For cells that contain formulas, their formulas are
* evaluated, and the results are saved. These cells
* remain as formula cells.
* For cells that do not contain formulas, no changes
* are made.
* This is a helpful wrapper around looping over all
* cells, and calling evaluateFormulaCell on each one.
*/
public static void evaluateAllFormulaCells(Workbook wb) {
FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();
evaluateAllFormulaCells(wb, evaluator);
}
private static void evaluateAllFormulaCells(Workbook wb, FormulaEvaluator evaluator) {
for(int i=0; i<wb.getNumberOfSheets(); i++) {
Sheet sheet = wb.getSheetAt(i);
for(Row r : sheet) {
for (Cell c : r) {
if (c.getCellTypeEnum() == CellType.FORMULA) {
evaluator.evaluateFormulaCellEnum(c);
}
}
} }
} }
} }
}
/**
/** * Loops over all cells in all sheets of the supplied
* Loops over all cells in all sheets of the supplied * workbook.
* workbook. * For cells that contain formulas, their formulas are
* For cells that contain formulas, their formulas are * evaluated, and the results are saved. These cells
* evaluated, and the results are saved. These cells * remain as formula cells.
* remain as formula cells. * For cells that do not contain formulas, no changes
* For cells that do not contain formulas, no changes * are made.
* are made. * This is a helpful wrapper around looping over all
* This is a helpful wrapper around looping over all * cells, and calling evaluateFormulaCell on each one.
* cells, and calling evaluateFormulaCell on each one. */
*/
@Override @Override
public void evaluateAll() { public void evaluateAll() {
evaluateAllFormulaCells(_book, this); evaluateAllFormulaCells(_book, this);
@ -383,24 +380,24 @@ public class HSSFFormulaEvaluator implements FormulaEvaluator, WorkbookEvaluator
* @param cell * @param cell
*/ */
private CellValue evaluateFormulaCellValue(Cell cell) { private CellValue evaluateFormulaCellValue(Cell cell) {
ValueEval eval = _bookEvaluator.evaluate(new HSSFEvaluationCell((HSSFCell)cell)); ValueEval eval = _bookEvaluator.evaluate(new HSSFEvaluationCell((HSSFCell)cell));
if (eval instanceof BoolEval) { if (eval instanceof BoolEval) {
BoolEval be = (BoolEval) eval; BoolEval be = (BoolEval) eval;
return CellValue.valueOf(be.getBooleanValue()); return CellValue.valueOf(be.getBooleanValue());
} }
if (eval instanceof NumericValueEval) { if (eval instanceof NumericValueEval) {
NumericValueEval ne = (NumericValueEval) eval; NumericValueEval ne = (NumericValueEval) eval;
return new CellValue(ne.getNumberValue()); return new CellValue(ne.getNumberValue());
} }
if (eval instanceof StringValueEval) { if (eval instanceof StringValueEval) {
StringValueEval ne = (StringValueEval) eval; StringValueEval ne = (StringValueEval) eval;
return new CellValue(ne.getStringValue()); return new CellValue(ne.getStringValue());
} }
if (eval instanceof ErrorEval) { if (eval instanceof ErrorEval) {
return CellValue.getError(((ErrorEval)eval).getErrorCode()); return CellValue.getError(((ErrorEval)eval).getErrorCode());
} }
throw new RuntimeException("Unexpected eval class (" + eval.getClass().getName() + ")"); throw new RuntimeException("Unexpected eval class (" + eval.getClass().getName() + ")");
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
@Override @Override