예제 #1
0
        public PlainValueCellCacheEntry GetPlainValueEntry(int bookIndex, int sheetIndex,
                                                           int rowIndex, int columnIndex, ValueEval value)
        {
            Loc loc = new Loc(bookIndex, sheetIndex, rowIndex, columnIndex);
            PlainValueCellCacheEntry result = _plainCellCache.Get(loc);

            if (result == null)
            {
                result = new PlainValueCellCacheEntry(value);
                _plainCellCache.Put(loc, result);
                if (_evaluationListener != null)
                {
                    _evaluationListener.OnReadPlainValue(sheetIndex, rowIndex, columnIndex, result);
                }
            }
            else
            {
                // TODO - if we are confident that this sanity check is not required, we can Remove 'value' from plain value cache entry
                if (!AreValuesEqual(result.GetValue(), value))
                {
                    throw new InvalidOperationException("value changed");
                }
                if (_evaluationListener != null)
                {
                    _evaluationListener.OnCacheHit(sheetIndex, rowIndex, columnIndex, value);
                }
            }
            return(result);
        }
예제 #2
0
        /**
         * @return never <c>null</c>, never {@link BlankEval}
         */

        private ValueEval EvaluateAny(IEvaluationCell srcCell, int sheetIndex,
                                      int rowIndex, int columnIndex, EvaluationTracker tracker)
        {
            bool shouldCellDependencyBeRecorded = _stabilityClassifier == null ? true
                    : !_stabilityClassifier.IsCellFinal(sheetIndex, rowIndex, columnIndex);
            ValueEval result;

            if (srcCell == null || srcCell.CellType != CellType.Formula)
            {
                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;

            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);
                        result = EvaluateFormula(ec, ptgs);
                        evalListener.OnEndEvaluate(cce, result);
                    }

                    tracker.UpdateCacheResult(result);
                }
                catch (NotImplementedException e)
                {
                    throw AddExceptionInfo(e, sheetIndex, rowIndex, columnIndex);
                }
                catch (RuntimeException re)
                {
                    if (re.InnerException is WorkbookNotFoundException && _ignoreMissingWorkbooks)
                    {
                        LogInfo(re.InnerException.Message + " - Continuing with cached value!");
                        switch (srcCell.CachedFormulaResultType)
                        {
                        case CellType.Numeric:
                            result = new NumberEval(srcCell.NumericCellValue);
                            break;

                        case CellType.String:
                            result = new StringEval(srcCell.StringCellValue);
                            break;

                        case CellType.Blank:
                            result = BlankEval.instance;
                            break;

                        case CellType.Boolean:
                            result = BoolEval.ValueOf(srcCell.BooleanCellValue);
                            break;

                        case CellType.Error:
                            result = ErrorEval.ValueOf(srcCell.ErrorCellValue);
                            break;

                        case CellType.Formula:
                        default:
                            throw new RuntimeException("Unexpected cell type '" + srcCell.CellType + "' found!");
                        }
                    }
                    else
                    {
                        throw re;
                    }
                }
                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 " + cce.GetValue());
            }
            // 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 cce.GetValue();
            return(result);
        }
예제 #3
0
        /**
         * @return never <c>null</c>, never {@link BlankEval}
         */
        private ValueEval EvaluateAny(IEvaluationCell srcCell, int sheetIndex,
                                      int rowIndex, int columnIndex, EvaluationTracker tracker)
        {
            bool shouldCellDependencyBeRecorded = _stabilityClassifier == null ? true
                    : !_stabilityClassifier.IsCellFinal(sheetIndex, rowIndex, columnIndex);
            ValueEval result;

            if (srcCell == null || srcCell.CellType != CellType.FORMULA)
            {
                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;

            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);
                        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 " + cce.GetValue().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 cce.GetValue();
            return(result);
        }
예제 #4
0
        /**
         * @return never <c>null</c>, never {@link BlankEval}
         */
        private ValueEval EvaluateAny(EvaluationCell srcCell, int sheetIndex,
                                      int rowIndex, int columnIndex, EvaluationTracker tracker)
        {
            if (srcCell == null || srcCell.CellType != CellType.FORMULA)
            {
                ValueEval result = GetValueFromNonFormulaCell(srcCell);
                tracker.AcceptPlainValueDependency(_workbookIx, sheetIndex, rowIndex, columnIndex, result);
                return(result);
            }

            FormulaCellCacheEntry cce = _cache.GetOrCreateFormulaCellEntry(srcCell);

            tracker.AcceptFormulaDependency(cce);
            IEvaluationListener evalListener = _evaluationListener;

            if (cce.GetValue() == null)
            {
                if (!tracker.StartEvaluate(cce))
                {
                    return(ErrorEval.CIRCULAR_REF_ERROR);
                }
                OperationEvaluationContext ec = new OperationEvaluationContext(this, _workbook, sheetIndex, rowIndex, columnIndex, tracker);

                try
                {
                    ValueEval result;

                    Ptg[] ptgs = _workbook.GetFormulaTokens(srcCell);
                    if (evalListener == null)
                    {
                        result = EvaluateFormula(ec, ptgs);
                    }
                    else
                    {
                        evalListener.OnStartEvaluate(srcCell, cce);
                        result = EvaluateFormula(ec, ptgs);
                        evalListener.OnEndEvaluate(cce, result);
                    }

                    tracker.UpdateCacheResult(result);
                }
                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 " + cce.GetValue().ToString());
            }
            return(cce.GetValue());
        }