org.apache.poi.ss.formula.eval
Class EvaluationException

java.lang.Object
  extended by java.lang.Throwable
      extended by java.lang.Exception
          extended by org.apache.poi.ss.formula.eval.EvaluationException
All Implemented Interfaces:
java.io.Serializable

public final class EvaluationException
extends java.lang.Exception

This class is used to simplify error handling logic within operator and function implementations. Note - OperationEval.evaluate() and Function.evaluate() method signatures do not throw this exception so it cannot propagate outside.

Here is an example coded without EvaluationException, to show how it can help:

 public Eval evaluate(Eval[] args, int srcRow, short srcCol) {
        // ...
        Eval arg0 = args[0];
        if(arg0 instanceof ErrorEval) {
                return arg0;
        }
        if(!(arg0 instanceof AreaEval)) {
                return ErrorEval.VALUE_INVALID;
        }
        double temp = 0;
        AreaEval area = (AreaEval)arg0;
        ValueEval[] values = area.getValues();
        for (int i = 0; i < values.length; i++) {
                ValueEval ve = values[i];
                if(ve instanceof ErrorEval) {
                        return ve;
                }
                if(!(ve instanceof NumericValueEval)) {
                        return ErrorEval.VALUE_INVALID;
                }
                temp += ((NumericValueEval)ve).getNumberValue();
        }
        // ...
 }       
 
In this example, if any error is encountered while processing the arguments, an error is returned immediately. This code is difficult to refactor due to all the points where errors are returned.
Using EvaluationException allows the error returning code to be consolidated to one place.

 public Eval evaluate(Eval[] args, int srcRow, short srcCol) {
        try {
                // ...
                AreaEval area = getAreaArg(args[0]);
                double temp = sumValues(area.getValues());
                // ...
        } catch (EvaluationException e) {
                return e.getErrorEval();
        }
}

private static AreaEval getAreaArg(Eval arg0) throws EvaluationException {
        if (arg0 instanceof ErrorEval) {
                throw new EvaluationException((ErrorEval) arg0);
        }
        if (arg0 instanceof AreaEval) {
                return (AreaEval) arg0;
        }
        throw EvaluationException.invalidValue();
}

private double sumValues(ValueEval[] values) throws EvaluationException {
        double temp = 0;
        for (int i = 0; i < values.length; i++) {
                ValueEval ve = values[i];
                if (ve instanceof ErrorEval) {
                        throw new EvaluationException((ErrorEval) ve);
                }
                if (!(ve instanceof NumericValueEval)) {
                        throw EvaluationException.invalidValue();
                }
                temp += ((NumericValueEval) ve).getNumberValue();
        }
        return temp;
}
 
It is not mandatory to use EvaluationException, doing so might give the following advantages:
- Methods can more easily be extracted, allowing for re-use.
- Type management (typecasting etc) is simpler because error conditions have been separated from intermediate calculation values.
- Fewer local variables are required. Local variables can have stronger types.
- It is easier to mimic common Excel error handling behaviour (exit upon encountering first error), because exceptions conveniently propagate up the call stack regardless of execution points or the number of levels of nested calls.

Note - Only standard evaluation errors are represented by EvaluationException ( i.e. conditions expected to be encountered when evaluating arbitrary Excel formulas). Conditions that could never occur in an Excel spreadsheet should result in runtime exceptions. Care should be taken to not translate any POI internal error into an Excel evaluation error code.

Author:
Josh Micich
See Also:
Serialized Form

Constructor Summary
EvaluationException(ErrorEval errorEval)
           
 
Method Summary
 ErrorEval getErrorEval()
           
static EvaluationException invalidRef()
          #REF! - Illegal or deleted cell reference
static EvaluationException invalidValue()
          #VALUE! - Wrong type of operand
static EvaluationException numberError()
          #NUM! - Value range overflow
 
Methods inherited from class java.lang.Throwable
fillInStackTrace, getCause, getLocalizedMessage, getMessage, getStackTrace, initCause, printStackTrace, printStackTrace, printStackTrace, setStackTrace, toString
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Constructor Detail

EvaluationException

public EvaluationException(ErrorEval errorEval)
Method Detail

invalidValue

public static EvaluationException invalidValue()
#VALUE! - Wrong type of operand


invalidRef

public static EvaluationException invalidRef()
#REF! - Illegal or deleted cell reference


numberError

public static EvaluationException numberError()
#NUM! - Value range overflow


getErrorEval

public ErrorEval getErrorEval()


Copyright 2012 The Apache Software Foundation or its licensors, as applicable.