/* ====================================================================
   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.ss.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;
	}
}
