Esempio n. 1
0
 /**
  * Case-insensitive.
  *
  * @return -1 if sheet with specified name does not exist
  */
 /* package */ int getSheetIndex(String sheetName) {
   Integer result = _sheetIndexesByName.get(sheetName);
   if (result == null) {
     int sheetIndex = _workbook.getSheetIndex(sheetName);
     if (sheetIndex < 0) {
       return -1;
     }
     result = new Integer(sheetIndex);
     _sheetIndexesByName.put(sheetName, result);
   }
   return result.intValue();
 }
Esempio n. 2
0
 private int getSheetIndex(EvaluationSheet sheet) {
   Integer result = _sheetIndexesBySheet.get(sheet);
   if (result == null) {
     int sheetIndex = _workbook.getSheetIndex(sheet);
     if (sheetIndex < 0) {
       throw new RuntimeException("Specified sheet from a different book");
     }
     result = new Integer(sheetIndex);
     _sheetIndexesBySheet.put(sheet, result);
   }
   return result.intValue();
 }
Esempio n. 3
0
  /**
   * Adds the current cell reference to the exception for easier debugging. Would be nice to get the
   * formula text as well, but that seems to require too much digging around and casting to get the
   * FormulaRenderingWorkbook.
   */
  private NotImplementedException addExceptionInfo(
      NotImplementedException inner, int sheetIndex, int rowIndex, int columnIndex) {

    try {
      String sheetName = _workbook.getSheetName(sheetIndex);
      CellReference cr = new CellReference(sheetName, rowIndex, columnIndex, false, false);
      String msg = "Error evaluating cell " + cr.formatAsString();
      return new NotImplementedException(msg, inner);
    } catch (Exception e) {
      // avoid bombing out during exception handling
      e.printStackTrace();
      return inner; // preserve original exception
    }
  }
Esempio n. 4
0
  /**
   * 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!
   */
  private ValueEval getEvalForPtg(Ptg ptg, OperationEvaluationContext ec) {
    //  consider converting all these (ptg instanceof XxxPtg) expressions to (ptg.getClass() ==
    // XxxPtg.class)

    if (ptg instanceof NamePtg) {
      // named ranges, macro functions
      NamePtg namePtg = (NamePtg) ptg;
      EvaluationName nameRecord = _workbook.getName(namePtg);
      if (nameRecord.isFunctionName()) {
        return new NameEval(nameRecord.getNameText());
      }
      if (nameRecord.hasFormula()) {
        return evaluateNameFormula(nameRecord.getNameDefinition(), ec);
      }

      throw new RuntimeException(
          "Don't now how to evalate name '" + nameRecord.getNameText() + "'");
    }
    if (ptg instanceof NameXPtg) {
      return new NameXEval(((NameXPtg) ptg));
    }

    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());
    }
    if (ptg instanceof MissingArgPtg) {
      return MissingArgEval.instance;
    }
    if (ptg instanceof AreaErrPtg
        || ptg instanceof RefErrorPtg
        || ptg instanceof DeletedArea3DPtg
        || ptg instanceof DeletedRef3DPtg) {
      return ErrorEval.REF_INVALID;
    }
    if (ptg instanceof Ref3DPtg) {
      Ref3DPtg refPtg = (Ref3DPtg) ptg;
      SheetRefEvaluator sre = ec.createExternSheetRefEvaluator(refPtg);
      return new LazyRefEval(refPtg, sre);
    }
    if (ptg instanceof Area3DPtg) {
      Area3DPtg aptg = (Area3DPtg) ptg;
      SheetRefEvaluator sre = ec.createExternSheetRefEvaluator(aptg);
      return new LazyAreaEval(aptg, sre);
    }
    SheetRefEvaluator sre = ec.getRefEvaluatorForCurrentSheet();
    if (ptg instanceof RefPtg) {
      return new LazyRefEval(((RefPtg) ptg), sre);
    }
    if (ptg instanceof AreaPtg) {
      return new LazyAreaEval(((AreaPtg) ptg), sre);
    }

    if (ptg instanceof UnknownPtg) {
      // POI uses UnknownPtg when the encoded Ptg array seems to be corrupted.
      // This seems to occur in very rare cases (e.g. unused name formulas in bug 44774, attachment
      // 21790)
      // In any case, formulas are re-parsed before execution, so UnknownPtg should not get here
      throw new RuntimeException("UnknownPtg not allowed");
    }
    if (ptg instanceof ExpPtg) {
      // ExpPtg is used for array formulas and shared formulas.
      // it is currently unsupported, and may not even get implemented here
      throw new RuntimeException("ExpPtg currently not supported");
    }

    throw new RuntimeException("Unexpected ptg class (" + ptg.getClass().getName() + ")");
  }
Esempio n. 5
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;
  }
Esempio n. 6
0
 /* package */ EvaluationSheet getSheet(int sheetIndex) {
   return _workbook.getSheet(sheetIndex);
 }
Esempio n. 7
0
 /** also for debug use. Used in toString methods */
 /* package */ String getSheetName(int sheetIndex) {
   return _workbook.getSheetName(sheetIndex);
 }