123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134 |
- /* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- ==================================================================== */
-
- package org.apache.poi.hssf.record.formula.eval;
-
- /**
- * This class is used to simplify error handling logic <i>within</i> operator and function
- * implementations. Note - <tt>OperationEval.evaluate()</tt> and <tt>Function.evaluate()</tt>
- * method signatures do not throw this exception so it cannot propagate outside.<p/>
- *
- * Here is an example coded without <tt>EvaluationException</tt>, to show how it can help:
- * <pre>
- * 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();
- * }
- * // ...
- * }
- * </pre>
- * 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.<br/>
- * Using <tt>EvaluationException</tt> allows the error returning code to be consolidated to one
- * place.<p/>
- * <pre>
- * 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;
- *}
- * </pre>
- * It is not mandatory to use EvaluationException, doing so might give the following advantages:<br/>
- * - Methods can more easily be extracted, allowing for re-use.<br/>
- * - Type management (typecasting etc) is simpler because error conditions have been separated from
- * intermediate calculation values.<br/>
- * - Fewer local variables are required. Local variables can have stronger types.<br/>
- * - 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.<p/>
- *
- * <b>Note</b> - Only standard evaluation errors are represented by <tt>EvaluationException</tt> (
- * 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
- */
- public final class EvaluationException extends Exception {
- private final ErrorEval _errorEval;
-
- public EvaluationException(ErrorEval errorEval) {
- _errorEval = errorEval;
- }
- // some convenience factory methods
-
- /** <b>#VALUE!</b> - Wrong type of operand */
- public static EvaluationException invalidValue() {
- return new EvaluationException(ErrorEval.VALUE_INVALID);
- }
- /** <b>#REF!</b> - Illegal or deleted cell reference */
- public static EvaluationException invalidRef() {
- return new EvaluationException(ErrorEval.REF_INVALID);
- }
- /** <b>#NUM!</b> - Value range overflow */
- public static EvaluationException numberError() {
- return new EvaluationException(ErrorEval.NUM_ERROR);
- }
-
- public ErrorEval getErrorEval() {
- return _errorEval;
- }
- }
|