Ejemplo n.º 1
0
 /**
  * Gets the value from a non-formula cell.
  *
  * @param cell may be <code>null</code>
  * @return {@link BlankEval} if cell is <code>null</code> or blank, never <code>null</code>
  */
 /* package */ static ValueEval getValueFromNonFormulaCell(EvaluationCell cell) {
   if (cell == null) {
     return BlankEval.INSTANCE;
   }
   int cellType = cell.getCellType();
   switch (cellType) {
     case Cell.CELL_TYPE_NUMERIC:
       return new NumberEval(cell.getNumericCellValue());
     case Cell.CELL_TYPE_STRING:
       return new StringEval(cell.getStringCellValue());
     case Cell.CELL_TYPE_BOOLEAN:
       return BoolEval.valueOf(cell.getBooleanCellValue());
     case Cell.CELL_TYPE_BLANK:
       return BlankEval.INSTANCE;
     case Cell.CELL_TYPE_ERROR:
       return ErrorEval.valueOf(cell.getErrorCellValue());
   }
   throw new RuntimeException("Unexpected cell type (" + cellType + ")");
 }
Ejemplo n.º 2
0
  /** @return never <code>null</code>, never {@link BlankEval} */
  private ValueEval evaluateAny(
      EvaluationCell srcCell,
      int sheetIndex,
      int rowIndex,
      int columnIndex,
      EvaluationTracker tracker) {

    // avoid tracking dependencies for cells that have constant definition
    boolean shouldCellDependencyBeRecorded =
        _stabilityClassifier == null
            ? true
            : !_stabilityClassifier.isCellFinal(sheetIndex, rowIndex, columnIndex);
    if (srcCell == null || srcCell.getCellType() != Cell.CELL_TYPE_FORMULA) {
      ValueEval result = getValueFromNonFormulaCell(srcCell);
      if (shouldCellDependencyBeRecorded) {
        tracker.acceptPlainValueDependency(_workbookIx, sheetIndex, rowIndex, columnIndex, result);
      }
      return result;
    }

    FormulaCellCacheEntry cce = _cache.getOrCreateFormulaCellEntry(srcCell);
    if (shouldCellDependencyBeRecorded || cce.isInputSensitive()) {
      tracker.acceptFormulaDependency(cce);
    }
    IEvaluationListener evalListener = _evaluationListener;
    ValueEval result;
    if (cce.getValue() == null) {
      if (!tracker.startEvaluate(cce)) {
        return ErrorEval.CIRCULAR_REF_ERROR;
      }
      OperationEvaluationContext ec =
          new OperationEvaluationContext(
              this, _workbook, sheetIndex, rowIndex, columnIndex, tracker);

      try {

        Ptg[] ptgs = _workbook.getFormulaTokens(srcCell);
        if (evalListener == null) {
          result = evaluateFormula(ec, ptgs);
        } else {
          evalListener.onStartEvaluate(srcCell, cce, ptgs);
          result = evaluateFormula(ec, ptgs);
          evalListener.onEndEvaluate(cce, result);
        }

        tracker.updateCacheResult(result);
      } catch (NotImplementedException e) {
        throw addExceptionInfo(e, sheetIndex, rowIndex, columnIndex);
      } finally {
        tracker.endEvaluate(cce);
      }
    } else {
      if (evalListener != null) {
        evalListener.onCacheHit(sheetIndex, rowIndex, columnIndex, cce.getValue());
      }
      return cce.getValue();
    }
    if (isDebugLogEnabled()) {
      String sheetName = getSheetName(sheetIndex);
      CellReference cr = new CellReference(rowIndex, columnIndex);
      logDebug("Evaluated " + sheetName + "!" + cr.formatAsString() + " to " + result.toString());
    }
    // Usually (result === cce.getValue())
    // But sometimes: (result==ErrorEval.CIRCULAR_REF_ERROR, cce.getValue()==null)
    // When circular references are detected, the cache entry is only updated for
    // the top evaluation frame
    return result;
  }