-/*
-* 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;
-import org.apache.poi.hssf.record.formula.AddPtg;
-import org.apache.poi.hssf.record.formula.Ptg;
/**
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
* <li> 1+A1 = 2 if A1 contains TRUE or =TRUE
* <li> 1+A1 = #VALUE! if A1 contains "TRUE" or ="TRUE"
*/
-public class AddEval extends NumericOperationEval {
-
- private AddPtg delegate;
- private static final ValueEvalToNumericXlator NUM_XLATOR =
- new ValueEvalToNumericXlator((short)
- ( ValueEvalToNumericXlator.BOOL_IS_PARSED
- | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED
- | ValueEvalToNumericXlator.STRING_IS_PARSED
- | ValueEvalToNumericXlator.REF_STRING_IS_PARSED
- ));
-
- public AddEval(Ptg ptg) {
- delegate = (AddPtg) ptg;
- }
+public final class AddEval extends TwoOperandNumericOperation {
- public ValueEvalToNumericXlator getXlator() {
- return NUM_XLATOR;
- }
-
-
- public Eval evaluate(Eval[] args, int srcRow, short srcCol) {
- if(args.length != 2) {
- return ErrorEval.VALUE_INVALID;
- }
-
- double d = 0;
- for (int i = 0; i < 2; i++) {
- ValueEval ve = singleOperandEvaluate(args[i], srcRow, srcCol);
- if(ve instanceof ErrorEval) {
- return ve;
- }
- if (ve instanceof NumericValueEval) {
- d += ((NumericValueEval) ve).getNumberValue();
- }
- else if (ve instanceof BlankEval) {
- // do nothing
- }
- else {
- return ErrorEval.VALUE_INVALID;
- }
- }
- if(Double.isNaN(d) || Double.isInfinite(d)) {
- return ErrorEval.NUM_ERROR;
- }
- return new NumberEval(d);
- }
+ public static final OperationEval instance = new AddEval();
- public int getNumberOfOperands() {
- return delegate.getNumberOfOperands();
- }
+ private AddEval() {
+ }
- public int getType() {
- return delegate.getType();
- }
+ protected double evaluate(double d0, double d1) {
+ return d0 + d1;
+ }
}
-/*
-* 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;
-import org.apache.poi.hssf.record.formula.Ptg;
-import org.apache.poi.hssf.record.formula.DividePtg;
-
/**
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
- *
*/
-public final class DivideEval extends NumericOperationEval {
-
- private DividePtg delegate;
-
- private static final ValueEvalToNumericXlator NUM_XLATOR =
- new ValueEvalToNumericXlator((short)
- ( ValueEvalToNumericXlator.BOOL_IS_PARSED
- | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED
- | ValueEvalToNumericXlator.STRING_IS_PARSED
- | ValueEvalToNumericXlator.REF_STRING_IS_PARSED
- ));
-
- public DivideEval(Ptg ptg) {
- delegate = (DividePtg) ptg;
- }
-
- protected ValueEvalToNumericXlator getXlator() {
- return NUM_XLATOR;
- }
-
- public Eval evaluate(Eval[] args, int srcRow, short srcCol) {
- if(args.length != 2) {
- return ErrorEval.VALUE_INVALID;
- }
- Eval retval = null;
- double d0 = 0;
- double d1 = 0;
- ValueEval ve = singleOperandEvaluate(args[0], srcRow, srcCol);
- if (ve instanceof NumericValueEval) {
- d0 = ((NumericValueEval) ve).getNumberValue();
- }
- else if (ve instanceof BlankEval) {
- // do nothing
- }
- else {
- retval = ErrorEval.VALUE_INVALID;
- }
-
- if (retval == null) { // no error yet
- ve = singleOperandEvaluate(args[1], srcRow, srcCol);
- if (ve instanceof NumericValueEval) {
- d1 = ((NumericValueEval) ve).getNumberValue();
- }
- else if (ve instanceof BlankEval) {
- // do nothing
- }
- else {
- retval = ErrorEval.VALUE_INVALID;
- }
- }
+public final class DivideEval extends TwoOperandNumericOperation {
- if (retval == null) {
- retval = (d1 == 0)
- ? ErrorEval.DIV_ZERO
- : (Double.isNaN(d0) || Double.isNaN(d1))
- ? (ValueEval) ErrorEval.VALUE_INVALID
- : new NumberEval(d0 / d1);
- }
- return retval;
- }
+ public static final OperationEval instance = new DivideEval();
- public int getNumberOfOperands() {
- return delegate.getNumberOfOperands();
- }
+ private DivideEval() {
+ }
- public int getType() {
- return delegate.getType();
- }
+ protected double evaluate(double d0, double d1) throws EvaluationException {
+ if (d1 == 0.0) {
+ throw new EvaluationException(ErrorEval.DIV_ZERO);
+ }
+ return d0 / d1;
+ }
}
-/*
-* 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;
-import org.apache.poi.hssf.record.formula.Ptg;
-import org.apache.poi.hssf.record.formula.MultiplyPtg;
-
/**
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
- *
*/
-public final class MultiplyEval extends NumericOperationEval {
-
- private MultiplyPtg delegate;
-
- private static final ValueEvalToNumericXlator NUM_XLATOR =
- new ValueEvalToNumericXlator((short)
- ( ValueEvalToNumericXlator.BOOL_IS_PARSED
- | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED
- | ValueEvalToNumericXlator.STRING_IS_PARSED
- | ValueEvalToNumericXlator.REF_STRING_IS_PARSED
- ));
-
- public MultiplyEval(Ptg ptg) {
- delegate = (MultiplyPtg) ptg;
- }
-
- protected ValueEvalToNumericXlator getXlator() {
- return NUM_XLATOR;
- }
+public final class MultiplyEval extends TwoOperandNumericOperation {
- public Eval evaluate(Eval[] args, int srcRow, short srcCol) {
- if(args.length != 2) {
- return ErrorEval.VALUE_INVALID;
- }
-
- double d0 = 0;
- double d1 = 0;
- ValueEval ve = singleOperandEvaluate(args[0], srcRow, srcCol);
- if (ve instanceof NumericValueEval) {
- d0 = ((NumericValueEval) ve).getNumberValue();
- }
- else if (ve instanceof BlankEval) {
- // do nothing
- }
- else {
- return ErrorEval.VALUE_INVALID;
- }
-
- ve = singleOperandEvaluate(args[1], srcRow, srcCol);
- if (ve instanceof NumericValueEval) {
- d1 = ((NumericValueEval) ve).getNumberValue();
- }
- else if (ve instanceof BlankEval) {
- // do nothing
- }
- else {
- return ErrorEval.VALUE_INVALID;
- }
-
- if (Double.isNaN(d0) || Double.isNaN(d1)) {
- return ErrorEval.NUM_ERROR;
- }
- return new NumberEval(d0 * d1);
- }
+ public static final OperationEval instance = new MultiplyEval();
- public int getNumberOfOperands() {
- return delegate.getNumberOfOperands();
- }
+ private MultiplyEval() {
+ }
- public int getType() {
- return delegate.getType();
- }
+ protected double evaluate(double d0, double d1) {
+ return d0 * d1;
+ }
}
+++ /dev/null
-/*
-* 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 14, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.eval;
-
-/**
- * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
- *
- */
-public abstract class NumericOperationEval implements OperationEval {
-
- protected abstract ValueEvalToNumericXlator getXlator();
-
- protected ValueEval singleOperandEvaluate(Eval eval, int srcRow, short srcCol) {
- ValueEval retval;
- if (eval instanceof AreaEval) {
- AreaEval ae = (AreaEval) eval;
- if (ae.contains(srcRow, srcCol)) { // circular ref!
- retval = ErrorEval.CIRCULAR_REF_ERROR;
- }
- else if (ae.isRow()) {
- if (ae.containsColumn(srcCol)) {
- ValueEval ve = ae.getValueAt(ae.getFirstRow(), srcCol);
- ve = getXlator().attemptXlateToNumeric(ve);
- retval = getXlator().attemptXlateToNumeric(ve);
- }
- else {
- retval = ErrorEval.VALUE_INVALID;
- }
- }
- else if (ae.isColumn()) {
- if (ae.containsRow(srcRow)) {
- ValueEval ve = ae.getValueAt(srcRow, ae.getFirstColumn());
- retval = getXlator().attemptXlateToNumeric(ve);
- }
- else {
- retval = ErrorEval.VALUE_INVALID;
- }
- }
- else {
- retval = ErrorEval.VALUE_INVALID;
- }
- }
- else {
- retval = getXlator().attemptXlateToNumeric((ValueEval) eval);
- }
- return retval;
- }
-}
package org.apache.poi.hssf.record.formula.eval;
-import org.apache.poi.hssf.record.formula.PercentPtg;
-import org.apache.poi.hssf.record.formula.Ptg;
/**
* Implementation of Excel formula token '%'. <p/>
* @author Josh Micich
*/
-public final class PercentEval extends NumericOperationEval {
+public final class PercentEval implements OperationEval {
- private PercentPtg _delegate;
+ public static final OperationEval instance = new PercentEval();
- private static final ValueEvalToNumericXlator NUM_XLATOR = new ValueEvalToNumericXlator(
- (short) (ValueEvalToNumericXlator.BOOL_IS_PARSED
- | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED
- | ValueEvalToNumericXlator.STRING_IS_PARSED | ValueEvalToNumericXlator.REF_STRING_IS_PARSED));
-
- public PercentEval(Ptg ptg) {
- _delegate = (PercentPtg) ptg;
- }
-
- protected ValueEvalToNumericXlator getXlator() {
- return NUM_XLATOR;
+ private PercentEval() {
}
public Eval evaluate(Eval[] args, int srcRow, short srcCol) {
if (args.length != 1) {
return ErrorEval.VALUE_INVALID;
}
-
- ValueEval ve = singleOperandEvaluate(args[0], srcRow, srcCol);
- if (ve instanceof NumericValueEval) {
- double d0 = ((NumericValueEval) ve).getNumberValue();
- return new NumberEval(d0 / 100);
+ double d0;
+ try {
+ ValueEval ve = OperandResolver.getSingleValue(args[0], srcRow, srcCol);
+ if (ve instanceof BlankEval) {
+ return NumberEval.ZERO;
+ }
+ d0 = OperandResolver.coerceValueToDouble(ve);
+ } catch (EvaluationException e) {
+ return e.getErrorEval();
}
-
- if (ve instanceof BlankEval) {
- return NumberEval.ZERO;
- }
- if (ve instanceof ErrorEval) {
- return ve;
- }
- return ErrorEval.VALUE_INVALID;
+ return new NumberEval(d0 / 100);
}
public int getNumberOfOperands() {
- return _delegate.getNumberOfOperands();
- }
-
- public int getType() {
- return _delegate.getType();
+ 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;
-import org.apache.poi.hssf.record.formula.Ptg;
-import org.apache.poi.hssf.record.formula.PowerPtg;
-
/**
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
- *
*/
-public final class PowerEval extends NumericOperationEval {
-
- private PowerPtg delegate;
-
- private static final ValueEvalToNumericXlator NUM_XLATOR =
- new ValueEvalToNumericXlator((short)
- ( ValueEvalToNumericXlator.BOOL_IS_PARSED
- | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED
- | ValueEvalToNumericXlator.STRING_IS_PARSED
- | ValueEvalToNumericXlator.REF_STRING_IS_PARSED
- ));
-
- public PowerEval(Ptg ptg) {
- delegate = (PowerPtg) ptg;
- }
-
- protected ValueEvalToNumericXlator getXlator() {
- return NUM_XLATOR;
- }
-
- public Eval evaluate(Eval[] args, int srcRow, short srcCol) {
- if(args.length != 2) {
- return ErrorEval.VALUE_INVALID;
- }
- double d0 = 0;
- double d1 = 0;
-
- ValueEval ve = singleOperandEvaluate(args[0], srcRow, srcCol);
- if (ve instanceof NumericValueEval) {
- d0 = ((NumericValueEval) ve).getNumberValue();
- }
- else if (ve instanceof BlankEval) {
- // do nothing
- }
- else {
- return ErrorEval.VALUE_INVALID;
- }
-
- ve = singleOperandEvaluate(args[1], srcRow, srcCol);
- if (ve instanceof NumericValueEval) {
- d1 = ((NumericValueEval) ve).getNumberValue();
- }
- else if (ve instanceof BlankEval) {
- // do nothing
- }
- else {
- return ErrorEval.VALUE_INVALID;
- }
+public final class PowerEval extends TwoOperandNumericOperation {
- double p = Math.pow(d0, d1);
- if (Double.isNaN(p)) {
- return ErrorEval.VALUE_INVALID;
- }
- return new NumberEval(p);
- }
+ public static final OperationEval instance = new PowerEval();
- public int getNumberOfOperands() {
- return delegate.getNumberOfOperands();
- }
+ private PowerEval() {
+ }
- public int getType() {
- return delegate.getType();
- }
+ protected double evaluate(double d0, double d1) {
+ return Math.pow(d0, d1);
+ }
}
-/*
-* 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;
-import org.apache.poi.hssf.record.formula.Ptg;
-import org.apache.poi.hssf.record.formula.SubtractPtg;
-
/**
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
- *
*/
-public final class SubtractEval extends NumericOperationEval {
-
- private SubtractPtg delegate;
-
- private static final ValueEvalToNumericXlator NUM_XLATOR =
- new ValueEvalToNumericXlator((short)
- ( ValueEvalToNumericXlator.BOOL_IS_PARSED
- | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED
- | ValueEvalToNumericXlator.STRING_IS_PARSED
- | ValueEvalToNumericXlator.REF_STRING_IS_PARSED
- ));
-
- public SubtractEval(Ptg ptg) {
- delegate = (SubtractPtg) ptg;
- }
-
- protected ValueEvalToNumericXlator getXlator() {
- return NUM_XLATOR;
- }
+public final class SubtractEval extends TwoOperandNumericOperation {
- public Eval evaluate(Eval[] args, int srcRow, short srcCol) {
- if(args.length != 2) {
- return ErrorEval.VALUE_INVALID;
- }
- Eval retval = null;
- double d0 = 0;
- double d1 = 0;
- ValueEval ve = singleOperandEvaluate(args[0], srcRow, srcCol);
- if (ve instanceof NumericValueEval) {
- d0 = ((NumericValueEval) ve).getNumberValue();
- }
- else if (ve instanceof BlankEval) {
- // do nothing
- }
- else {
- retval = ErrorEval.VALUE_INVALID;
- }
-
- if (retval == null) { // no error yet
- ve = singleOperandEvaluate(args[1], srcRow, srcCol);
- if (ve instanceof NumericValueEval) {
- d1 = ((NumericValueEval) ve).getNumberValue();
- }
- else if (ve instanceof BlankEval) {
- // do nothing
- }
- else {
- retval = ErrorEval.VALUE_INVALID;
- }
- }
-
- if (retval == null) {
- retval = (Double.isNaN(d0) || Double.isNaN(d1))
- ? (ValueEval) ErrorEval.VALUE_INVALID
- : new NumberEval(d0 - d1);
- }
- return retval;
- }
+ public static final OperationEval instance = new SubtractEval();
- public int getNumberOfOperands() {
- return delegate.getNumberOfOperands();
- }
+ private SubtractEval() {
+ }
- public int getType() {
- return delegate.getType();
- }
+ protected double evaluate(double d0, double d1) {
+ return d0 - d1;
+ }
}
--- /dev/null
+/* ====================================================================
+ 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;
+
+/**
+ * @author Josh Micich
+ */
+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);
+ if (ve instanceof BlankEval) {
+ return 0.0;
+ }
+ return OperandResolver.coerceValueToDouble(ve);
+ }
+
+ public final Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) {
+ double result;
+ try {
+ double d0 = singleOperandEvaluate(args[0], srcCellRow, srcCellCol);
+ double d1 = singleOperandEvaluate(args[1], srcCellRow, srcCellCol);
+ result = evaluate(d0, d1);
+ if (Double.isNaN(result) || Double.isInfinite(result)) {
+ return ErrorEval.NUM_ERROR;
+ }
+ } catch (EvaluationException e) {
+ return e.getErrorEval();
+ }
+ return new NumberEval(result);
+ }
+ protected abstract double evaluate(double d0, double d1) throws EvaluationException;
+ public final int getNumberOfOperands() {
+ return 2;
+ }
+}
-/*
-* 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;
-import org.apache.poi.hssf.record.formula.Ptg;
-import org.apache.poi.hssf.record.formula.UnaryMinusPtg;
/**
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
*
*/
-public final class UnaryMinusEval extends NumericOperationEval {
-
- private UnaryMinusPtg delegate;
- private static final ValueEvalToNumericXlator NUM_XLATOR =
- new ValueEvalToNumericXlator((short)
- ( ValueEvalToNumericXlator.BOOL_IS_PARSED
- | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED
- | ValueEvalToNumericXlator.STRING_IS_PARSED
- | ValueEvalToNumericXlator.REF_STRING_IS_PARSED
- ));
-
-
- public UnaryMinusEval(Ptg ptg) {
- this.delegate = (UnaryMinusPtg) ptg;
- }
-
- protected ValueEvalToNumericXlator getXlator() {
- return NUM_XLATOR;
- }
-
- public Eval evaluate(Eval[] args, int srcRow, short srcCol) {
- if(args.length != 1) {
- return ErrorEval.VALUE_INVALID;
- }
- double d = 0;
-
- ValueEval ve = singleOperandEvaluate(args[0], srcRow, srcCol);
- if (ve instanceof NumericValueEval) {
- d = ((NumericValueEval) ve).getNumberValue();
- }
- else if (ve instanceof BlankEval) {
- // do nothing
- }
- else if (ve instanceof ErrorEval) {
- return ve;
- }
-
- return new NumberEval(-d);
+public final class UnaryMinusEval implements OperationEval {
+
+ public static final OperationEval instance = new UnaryMinusEval();
+
+ private UnaryMinusEval() {
+ }
+
+ public Eval evaluate(Eval[] args, int srcRow, short srcCol) {
+ if (args.length != 1) {
+ return ErrorEval.VALUE_INVALID;
+ }
+ double d;
+ try {
+ ValueEval ve = OperandResolver.getSingleValue(args[0], srcRow, srcCol);
+ if (ve instanceof BlankEval) {
+ return NumberEval.ZERO;
+ }
+ d = OperandResolver.coerceValueToDouble(ve);
+ } catch (EvaluationException e) {
+ return e.getErrorEval();
+ }
+ return new NumberEval(-d);
+ }
+
+ public int getNumberOfOperands() {
+ return 1;
+ }
+ public final int getType() {
+ // TODO - remove
+ throw new RuntimeException("obsolete code should not be called");
}
-
- public int getNumberOfOperands() {
- return delegate.getNumberOfOperands();
- }
-
- public int getType() {
- return delegate.getType();
- }
-
}
package org.apache.poi.hssf.record.formula.eval;
-import org.apache.poi.hssf.record.formula.Ptg;
-import org.apache.poi.hssf.record.formula.UnaryPlusPtg;
/**
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
*/
public final class UnaryPlusEval implements OperationEval {
- private UnaryPlusPtg delegate;
+ public static final OperationEval instance = new UnaryPlusEval();
- /**
- * called by reflection
- */
- public UnaryPlusEval(Ptg ptg) {
- this.delegate = (UnaryPlusPtg) ptg;
+ private UnaryPlusEval() {
}
public Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) {
}
public int getNumberOfOperands() {
- return delegate.getNumberOfOperands();
+ return 1;
}
public int getType() {
- return delegate.getType();
+ throw new RuntimeException("obsolete code should not be called");
}
}
* @param eval
*/
public ValueEval attemptXlateToNumeric(ValueEval eval) {
- ValueEval retval = null;
if (eval == null) {
- retval = BlankEval.INSTANCE;
+ throw new IllegalArgumentException("eval must not be null");
}
// most common case - least worries :)
- else if (eval instanceof NumberEval) {
- retval = eval;
+ if (eval instanceof NumberEval) {
+ return eval;
}
- // booleval
- else if (eval instanceof BoolEval) {
- retval = ((flags & BOOL_IS_PARSED) > 0)
+ if (eval instanceof BoolEval) {
+ return ((flags & BOOL_IS_PARSED) > 0)
? (NumericValueEval) eval
: xlateBlankEval(BLANK_IS_PARSED);
}
- // stringeval
- else if (eval instanceof StringEval) {
- retval = xlateStringEval((StringEval) eval); // TODO: recursive call needed
+ if (eval instanceof StringEval) {
+ return xlateStringEval((StringEval) eval); // TODO: recursive call needed
}
- // refeval
- else if (eval instanceof RefEval) {
- retval = xlateRefEval((RefEval) eval);
+ if (eval instanceof RefEval) {
+ return xlateRefEval((RefEval) eval);
}
- // erroreval
- else if (eval instanceof ErrorEval) {
- retval = eval;
+ if (eval instanceof ErrorEval) {
+ return eval;
}
- else if (eval instanceof BlankEval) {
- retval = xlateBlankEval(BLANK_IS_PARSED);
+ if (eval instanceof BlankEval) {
+ return xlateBlankEval(BLANK_IS_PARSED);
}
// probably AreaEval? then not acceptable.
- else {
- throw new RuntimeException("Invalid ValueEval type passed for conversion: " + eval.getClass());
- }
-
- return retval;
+ throw new RuntimeException("Invalid ValueEval type passed for conversion: " + eval.getClass());
}
/**
private static Map initialiseConstructorsMap() {
Map m = new HashMap(32);
- add(m, AddPtg.class, AddEval.class);
add(m, ConcatPtg.class, ConcatEval.class);
- add(m, DividePtg.class, DivideEval.class);
add(m, FuncPtg.class, FuncVarEval.class);
add(m, FuncVarPtg.class, FuncVarEval.class);
- add(m, MultiplyPtg.class, MultiplyEval.class);
- add(m, PercentPtg.class, PercentEval.class);
- add(m, PowerPtg.class, PowerEval.class);
- add(m, SubtractPtg.class, SubtractEval.class);
- add(m, UnaryMinusPtg.class, UnaryMinusEval.class);
- add(m, UnaryPlusPtg.class, UnaryPlusEval.class);
return m;
}
private static Map initialiseInstancesMap() {
add(m, LessEqualPtg.class, LessEqualEval.instance);
add(m, LessThanPtg.class, LessThanEval.instance);
add(m, NotEqualPtg.class, NotEqualEval.instance);
+
+ add(m, AddPtg.class, AddEval.instance);
+ add(m, DividePtg.class, DivideEval.instance);
+ add(m, MultiplyPtg.class, MultiplyEval.instance);
+ add(m, PercentPtg.class, PercentEval.instance);
+ add(m, PowerPtg.class, PowerEval.instance);
+ add(m, SubtractPtg.class, SubtractEval.instance);
+ add(m, UnaryMinusPtg.class, UnaryMinusEval.instance);
+ add(m, UnaryPlusPtg.class, UnaryPlusEval.instance);
return m;
}
TestSuite result = new TestSuite(AllFormulaEvalTests.class.getName());
result.addTestSuite(TestAreaEval.class);
result.addTestSuite(TestCircularReferences.class);
+ result.addTestSuite(TestDivideEval.class);
result.addTestSuite(TestEqualEval.class);
result.addTestSuite(TestExternalFunction.class);
result.addTestSuite(TestFormulaBugs.class);
--- /dev/null
+/* ====================================================================
+ 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;
+
+import junit.framework.TestCase;
+
+import org.apache.poi.hssf.record.formula.functions.EvalFactory;
+import org.apache.poi.hssf.record.formula.functions.NumericFunctionInvoker;
+
+/**
+ * Test for divide operator evaluator.
+ *
+ * @author Josh Micich
+ */
+public final class TestDivideEval extends TestCase {
+
+ private static void confirm(ValueEval arg0, ValueEval arg1, double expectedResult) {
+ Eval[] args = {
+ arg0, arg1,
+ };
+
+ double result = NumericFunctionInvoker.invoke(DivideEval.instance, args, 0, 0);
+
+ assertEquals(expectedResult, result, 0);
+ }
+
+ public void testBasic() {
+ confirm(new NumberEval(5), new NumberEval(2), 2.5);
+ confirm(new NumberEval(3), new NumberEval(16), 0.1875);
+ confirm(new NumberEval(-150), new NumberEval(-15), 10.0);
+ confirm(new StringEval("0.2"), new NumberEval(0.05), 4.0);
+ confirm(BoolEval.TRUE, new StringEval("-0.2"), -5.0);
+ }
+
+ public void test1x1Area() {
+ AreaEval ae0 = EvalFactory.createAreaEval("B2:B2", new ValueEval[] { new NumberEval(50), });
+ AreaEval ae1 = EvalFactory.createAreaEval("C2:C2", new ValueEval[] { new NumberEval(10), });
+ confirm(ae0, ae1, 5);
+ }
+ public void testDivZero() {
+ Eval[] args = {
+ new NumberEval(5), NumberEval.ZERO,
+ };
+ Eval result = DivideEval.instance.evaluate(args, 0, (short) 0);
+ assertEquals(ErrorEval.DIV_ZERO, result);
+ }
+}
import junit.framework.AssertionFailedError;
import junit.framework.TestCase;
-import org.apache.poi.hssf.record.formula.PercentPtg;
+import org.apache.poi.hssf.record.formula.functions.EvalFactory;
import org.apache.poi.hssf.record.formula.functions.NumericFunctionInvoker;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator;
arg,
};
- PercentEval opEval = new PercentEval(PercentPtg.instance);
- double result = NumericFunctionInvoker.invoke(opEval, args, -1, (short)-1);
+ OperationEval opEval = PercentEval.instance;
+ double result = NumericFunctionInvoker.invoke(opEval, args, 0, 0);
assertEquals(expectedResult, result, 0);
}
confirm(BoolEval.TRUE, 0.01);
}
+ public void test1x1Area() {
+ AreaEval ae = EvalFactory.createAreaEval("B2:B2", new ValueEval[] { new NumberEval(50), });
+ confirm(ae, 0.5);
+ }
public void testInSpreadSheet() {
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("Sheet1");
-/*
-* 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;
import junit.framework.TestCase;
import org.apache.poi.hssf.record.formula.AreaPtg;
-import org.apache.poi.hssf.record.formula.UnaryPlusPtg;
import org.apache.poi.hssf.record.formula.functions.EvalFactory;
import org.apache.poi.hssf.record.formula.functions.NumericFunctionInvoker;
EvalFactory.createAreaEval(areaPtg, values),
};
- double result = NumericFunctionInvoker.invoke(new UnaryPlusEval(UnaryPlusPtg.instance), args, 10, (short)20);
+ double result = NumericFunctionInvoker.invoke(UnaryPlusEval.instance, args, 10, (short)20);
assertEquals(35, result, 0);
}