public byte getDefaultOperandClass() {
return Ptg.CLASS_VALUE;
}
- public final int getType() {
- // TODO remove "int getType();" from Eval hierarchy
- throw new RuntimeException("remove this method");
- }
}
public int getNumberOfOperands() {
return delegate.getNumberOfOperands();
}
-
- public int getType() {
- return delegate.getType();
- }
}
*
*/
public interface Eval {
-
+ // TODO - remove this interface
}
return delegate.getNumberOfOperands();
}
- public int getType() {
- return delegate.getType();
- }
-
public short getFunctionIndex() {
return delegate.getFunctionIndex();
}
/**
* @author Josh Micich
*/
-public final class NameEval implements Eval {
+public final class NameEval implements ValueEval {
private final String _functionName;
/**
* @author Josh Micich
*/
-public final class NameXEval implements Eval {
+public final class NameXEval implements ValueEval {
private final NameXPtg _ptg;
-/*
-* 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.
-*/
-/*
- * Created on May 8, 2005
- *
- */
+/* ====================================================================
+ 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;
/**
+ * Common interface for implementations of Excel formula operations.
+ *
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
*
*/
-public interface OperationEval extends Eval {
-
- /*
- * Read this, this will make your work easier when coding
- * an "evaluate()"
- *
- * Things to note when implementing evaluate():
- * 1. Check the length of operands
- * (use "switch(operands[x])" if possible)
- *
- * 2. The possible Evals that you can get as args to evaluate are one of:
- * NumericValueEval, StringValueEval, RefEval, AreaEval
- * 3. If it is RefEval, the innerValueEval could be one of:
- * NumericValueEval, StringValueEval, BlankEval
- * 4. If it is AreaEval, each of the values could be one of:
- * NumericValueEval, StringValueEval, BlankEval, RefEval
- *
- * 5. For numeric functions/operations, keep the result in double
- * till the end and before returning a new NumberEval, check to see
- * if the double is a NaN - if NaN, return ErrorEval.ERROR_503
- */
- public abstract Eval evaluate(Eval[] evals, int srcCellRow, short srcCellCol);
+public interface OperationEval {
- public abstract int getNumberOfOperands();
+ /**
+ * @param args the evaluated operation arguments. Elements of this array typically implement
+ * {@link ValueEval}. Empty values are represented with {@link BlankEval} or {@link
+ * MissingArgEval}, never <code>null</code>.
+ * @param srcRowIndex row index of the cell containing the formula under evaluation
+ * @param srcColumnIndex column index of the cell containing the formula under evaluation
+ * @return The evaluated result, possibly an {@link ErrorEval}, never <code>null</code>.
+ */
+ Eval evaluate(Eval[] args, int srcRowIndex, short srcColumnIndex);
- public abstract int getType();
+ int getNumberOfOperands();
}
public static final OperationEval instance = new PercentEval();
private PercentEval() {
+ // enforce singleton
}
public Eval evaluate(Eval[] args, int srcRow, short srcCol) {
public int getNumberOfOperands() {
return 1;
}
- public final int getType() {
- // TODO - remove
- throw new RuntimeException("obsolete code should not be called");
- }
}
public static final OperationEval instance = new RangeEval();
private RangeEval() {
+ // enforces singleton
}
public Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) {
public int getNumberOfOperands() {
return 2;
}
-
- public int getType() {
- throw new RuntimeException("obsolete code should not be called");
- }
}
public final int getNumberOfOperands() {
return 2;
}
-
- public final int getType() {
- // TODO - get rid of this method
- throw new RuntimeException("Obsolete code - should not be called");
- }
}
*/
abstract class TwoOperandNumericOperation implements OperationEval {
- public final int getType() {
- // TODO - remove
- throw new RuntimeException("obsolete code should not be called");
- }
protected final double singleOperandEvaluate(Eval arg, int srcCellRow, short srcCellCol) throws EvaluationException {
ValueEval ve = OperandResolver.getSingleValue(arg, srcCellRow, srcCellCol);
return OperandResolver.coerceValueToDouble(ve);
public static final OperationEval instance = new UnaryMinusEval();
private UnaryMinusEval() {
+ // enforce singleton
}
public Eval evaluate(Eval[] args, int srcRow, short srcCol) {
public int getNumberOfOperands() {
return 1;
}
- public final int getType() {
- // TODO - remove
- throw new RuntimeException("obsolete code should not be called");
- }
}
-/*
-* 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.
-*/
+/* ====================================================================
+ 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;
public static final OperationEval instance = new UnaryPlusEval();
private UnaryPlusEval() {
+ // enforce singleton
}
public Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) {
public int getNumberOfOperands() {
return 1;
}
-
- public int getType() {
- throw new RuntimeException("obsolete code should not be called");
- }
}
-/*
-* 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.
-*/
-/*
- * Created on May 9, 2005
- *
- */
+/* ====================================================================
+ 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.functions;
+import org.apache.poi.hssf.record.formula.eval.BlankEval;
+import org.apache.poi.hssf.record.formula.eval.ErrorEval;
import org.apache.poi.hssf.record.formula.eval.Eval;
+import org.apache.poi.hssf.record.formula.eval.MissingArgEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
/**
+ * Common interface for all implementations of Excel built-in functions.
+ *
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
- * Function serves as a marker interface.
*/
public interface Function {
- public Eval evaluate(Eval[] evals, int srcCellRow, short srcCellCol);
-
+ /**
+ * @param args the evaluated function arguments. Elements of this array typically implement
+ * {@link ValueEval}. Empty values are represented with {@link BlankEval} or {@link
+ * MissingArgEval}, never <code>null</code>.
+ * @param srcRowIndex row index of the cell containing the formula under evaluation
+ * @param srcColumnIndex column index of the cell containing the formula under evaluation
+ * @return The evaluated result, possibly an {@link ErrorEval}, never <code>null</code>.
+ * <b>Note</b> - Excel uses the error code <i>#NUM!</i> instead of IEEE <i>NaN</i>, so when
+ * numeric functions evaluate to {@link Double#NaN} be sure to translate the result to {@link
+ * ErrorEval#NUM_ERROR}.
+ *
+ */
+ Eval evaluate(Eval[] args, int srcRowIndex, short srcColumnIndex);
}
// visibility raised for testing
/* package */ ValueEval evaluateFormula(int sheetIndex, int srcRowNum, int srcColNum, Ptg[] ptgs, EvaluationTracker tracker) {
- Stack<Eval> stack = new Stack<Eval>();
+ Stack<ValueEval> stack = new Stack<ValueEval>();
for (int i = 0, iSize = ptgs.length; i < iSize; i++) {
// since we don't know how to handle these yet :(
}
if (ptg instanceof MemErrPtg) { continue; }
- Eval opResult;
+ ValueEval opResult;
if (ptg instanceof OperationPtg) {
OperationPtg optg = (OperationPtg) ptg;
OperationEval operation = OperationEvaluatorFactory.create(optg);
int numops = operation.getNumberOfOperands();
- Eval[] ops = new Eval[numops];
+ ValueEval[] ops = new ValueEval[numops];
// storing the ops in reverse order since they are popping
for (int j = numops - 1; j >= 0; j--) {
- Eval p = stack.pop();
+ ValueEval p = stack.pop();
ops[j] = p;
}
// logDebug("invoke " + operation + " (nAgs=" + numops + ")");
stack.push(opResult);
}
- ValueEval value = (ValueEval) stack.pop();
+ ValueEval value = stack.pop();
if (!stack.isEmpty()) {
throw new IllegalStateException("evaluation stack not empty");
}
return evaluationResult;
}
- private static Eval invokeOperation(OperationEval operation, Eval[] ops,
+ private static ValueEval invokeOperation(OperationEval operation, Eval[] ops,
EvaluationWorkbook workbook, int sheetIndex, int srcRowNum, int srcColNum) {
if(operation instanceof FunctionEval) {
return fe.getFreeRefFunction().evaluate(ops, workbook, sheetIndex, srcRowNum, srcColNum);
}
}
- return operation.evaluate(ops, srcRowNum, (short)srcColNum);
+ // TODO - fix return type of this evaluate method:
+ return (ValueEval) operation.evaluate(ops, srcRowNum, (short)srcColNum);
}
private SheetRefEvaluator createExternSheetRefEvaluator(EvaluationTracker tracker,
ExternSheetReferenceToken ptg) {
* StringPtg, BoolPtg <br/>special Note: OperationPtg subtypes cannot be
* passed here!
*/
- private Eval getEvalForPtg(Ptg ptg, int sheetIndex, EvaluationTracker tracker) {
+ private ValueEval getEvalForPtg(Ptg ptg, int sheetIndex, EvaluationTracker tracker) {
// consider converting all these (ptg instanceof XxxPtg) expressions to (ptg.getClass() == XxxPtg.class)
if (ptg instanceof NamePtg) {
throw new RuntimeException("Unexpected ptg class (" + ptg.getClass().getName() + ")");
}
- private Eval evaluateNameFormula(Ptg[] ptgs, int sheetIndex, EvaluationTracker tracker) {
+ private ValueEval evaluateNameFormula(Ptg[] ptgs, int sheetIndex, EvaluationTracker tracker) {
if (ptgs.length > 1) {
throw new RuntimeException("Complex name formulas not supported yet");
}