From 176250c649ba0ca6e35ee7cd6135468cc863a259 Mon Sep 17 00:00:00 2001 From: Josh Micich Date: Thu, 4 Sep 2008 20:58:37 +0000 Subject: [PATCH] Fixed 2 small bugs in RelationalOperationEval (added junits). Refactored hierarchy. git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@692239 13f79535-47bb-0310-9956-ffa450edef68 --- .../hssf/record/formula/eval/EqualEval.java | 83 ++--- .../record/formula/eval/GreaterEqualEval.java | 83 ++--- .../record/formula/eval/GreaterThanEval.java | 83 ++--- .../record/formula/eval/LazyAreaEval.java | 52 ++- .../hssf/record/formula/eval/LazyRefEval.java | 35 ++ .../record/formula/eval/LessEqualEval.java | 83 ++--- .../record/formula/eval/LessThanEval.java | 84 ++--- .../record/formula/eval/NotEqualEval.java | 84 ++--- .../formula/eval/RelationalOperationEval.java | 339 +++++++----------- .../usermodel/OperationEvaluatorFactory.java | 38 +- .../poi/hssf/data/FormulaEvalTestData.xls | Bin 153600 -> 153600 bytes .../formula/eval/AllFormulaEvalTests.java | 1 + .../record/formula/eval/TestEqualEval.java | 69 ++++ 13 files changed, 451 insertions(+), 583 deletions(-) create mode 100644 src/testcases/org/apache/poi/hssf/record/formula/eval/TestEqualEval.java diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/EqualEval.java b/src/java/org/apache/poi/hssf/record/formula/eval/EqualEval.java index e7b169294e..8dca609066 100644 --- a/src/java/org/apache/poi/hssf/record/formula/eval/EqualEval.java +++ b/src/java/org/apache/poi/hssf/record/formula/eval/EqualEval.java @@ -1,67 +1,34 @@ -/* -* 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 - * - */ -package org.apache.poi.hssf.record.formula.eval; +/* ==================================================================== + 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 -import org.apache.poi.hssf.record.formula.EqualPtg; -import org.apache.poi.hssf.record.formula.Ptg; + 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 Amol S. Deshmukh < amolweb at ya hoo dot com > * */ -public class EqualEval extends RelationalOperationEval { +public final class EqualEval extends RelationalOperationEval { - private EqualPtg delegate; + public static final OperationEval instance = new EqualEval(); + + private EqualEval() { + } - public EqualEval(Ptg ptg) { - this.delegate = (EqualPtg) ptg; - } - - - public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { - ValueEval retval = null; - - RelationalValues rvs = super.doEvaluate(operands, srcRow, srcCol); - retval = rvs.ee; - int result = 0; - if (retval == null) { - result = doComparison(rvs.bs); - if (result == 0) { - result = doComparison(rvs.ss); - } - if (result == 0) { - result = doComparison(rvs.ds); - } - - retval = (result == 0) ? BoolEval.TRUE : BoolEval.FALSE; - } - - return retval; - } - - public int getNumberOfOperands() { - return delegate.getNumberOfOperands(); - } - - public int getType() { - return delegate.getType(); - } + protected boolean convertComparisonResult(int cmpResult) { + return cmpResult == 0; + } } diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/GreaterEqualEval.java b/src/java/org/apache/poi/hssf/record/formula/eval/GreaterEqualEval.java index 6a9a23217b..16dd48846e 100644 --- a/src/java/org/apache/poi/hssf/record/formula/eval/GreaterEqualEval.java +++ b/src/java/org/apache/poi/hssf/record/formula/eval/GreaterEqualEval.java @@ -1,67 +1,34 @@ -/* -* 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 - * - */ -package org.apache.poi.hssf.record.formula.eval; +/* ==================================================================== + 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 -import org.apache.poi.hssf.record.formula.GreaterEqualPtg; -import org.apache.poi.hssf.record.formula.Ptg; + 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 Amol S. Deshmukh < amolweb at ya hoo dot com > * */ -public class GreaterEqualEval extends RelationalOperationEval { +public final class GreaterEqualEval extends RelationalOperationEval { - private GreaterEqualPtg delegate; - - public GreaterEqualEval(Ptg ptg) { - this.delegate = (GreaterEqualPtg) ptg; - } - - public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { - ValueEval retval = null; - - RelationalValues rvs = super.doEvaluate(operands, srcRow, srcCol); - retval = rvs.ee; - int result = 0; - if (retval == null) { - result = doComparison(rvs.bs); - if (result == 0) { - result = doComparison(rvs.ss); - } - if (result == 0) { - result = doComparison(rvs.ds); - } - - retval = (result >= 0) ? BoolEval.TRUE : BoolEval.FALSE; - } - - return retval; - } - - public int getNumberOfOperands() { - return delegate.getNumberOfOperands(); - } - - public int getType() { - return delegate.getType(); - } + public static final OperationEval instance = new GreaterEqualEval(); + + private GreaterEqualEval() { + } + protected boolean convertComparisonResult(int cmpResult) { + return cmpResult >= 0; + } } diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/GreaterThanEval.java b/src/java/org/apache/poi/hssf/record/formula/eval/GreaterThanEval.java index 27da54a046..45605a41c0 100644 --- a/src/java/org/apache/poi/hssf/record/formula/eval/GreaterThanEval.java +++ b/src/java/org/apache/poi/hssf/record/formula/eval/GreaterThanEval.java @@ -1,67 +1,34 @@ -/* -* 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 - * - */ -package org.apache.poi.hssf.record.formula.eval; +/* ==================================================================== + 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 -import org.apache.poi.hssf.record.formula.GreaterThanPtg; -import org.apache.poi.hssf.record.formula.Ptg; + 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 Amol S. Deshmukh < amolweb at ya hoo dot com > * */ -public class GreaterThanEval extends RelationalOperationEval { +public final class GreaterThanEval extends RelationalOperationEval { - private GreaterThanPtg delegate; - - public GreaterThanEval(Ptg ptg) { - this.delegate = (GreaterThanPtg) ptg; - } - - public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { - ValueEval retval = null; - - RelationalValues rvs = super.doEvaluate(operands, srcRow, srcCol); - retval = rvs.ee; - int result = 0; - if (retval == null) { - result = doComparison(rvs.bs); - if (result == 0) { - result = doComparison(rvs.ss); - } - if (result == 0) { - result = doComparison(rvs.ds); - } - - retval = (result > 0) ? BoolEval.TRUE : BoolEval.FALSE;; - } - - return retval; - } - - public int getNumberOfOperands() { - return delegate.getNumberOfOperands(); - } - - public int getType() { - return delegate.getType(); - } + public static final OperationEval instance = new GreaterThanEval(); + + private GreaterThanEval() { + } + protected boolean convertComparisonResult(int cmpResult) { + return cmpResult > 0; + } } diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/LazyAreaEval.java b/src/java/org/apache/poi/hssf/record/formula/eval/LazyAreaEval.java index 828f054b11..d8d18bd53c 100644 --- a/src/java/org/apache/poi/hssf/record/formula/eval/LazyAreaEval.java +++ b/src/java/org/apache/poi/hssf/record/formula/eval/LazyAreaEval.java @@ -1,33 +1,35 @@ -/* -* 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.AreaI; import org.apache.poi.hssf.record.formula.AreaI.OffsetArea; +import org.apache.poi.hssf.usermodel.EvaluationCache; import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator; import org.apache.poi.hssf.usermodel.HSSFRow; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.hssf.util.CellReference; /** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * + * + * @author Josh Micich */ public final class LazyAreaEval extends AreaEvalBase { @@ -62,4 +64,18 @@ public final class LazyAreaEval extends AreaEvalBase { return new LazyAreaEval(area, _sheet, _workbook); } + public String toString() { + CellReference crA = new CellReference(getFirstRow(), getFirstColumn()); + CellReference crB = new CellReference(getLastRow(), getLastColumn()); + StringBuffer sb = new StringBuffer(); + sb.append(getClass().getName()).append("["); + String sheetName = _workbook.getSheetName(_workbook.getSheetIndex(_sheet)); + sb.append(sheetName); + sb.append('!'); + sb.append(crA.formatAsString()); + sb.append(':'); + sb.append(crB.formatAsString()); + sb.append("]"); + return sb.toString(); + } } diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/LazyRefEval.java b/src/java/org/apache/poi/hssf/record/formula/eval/LazyRefEval.java index 62da3c499c..f2516b6906 100644 --- a/src/java/org/apache/poi/hssf/record/formula/eval/LazyRefEval.java +++ b/src/java/org/apache/poi/hssf/record/formula/eval/LazyRefEval.java @@ -1,15 +1,38 @@ +/* ==================================================================== + 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.AreaI; import org.apache.poi.hssf.record.formula.AreaI.OffsetArea; import org.apache.poi.hssf.record.formula.Ref3DPtg; import org.apache.poi.hssf.record.formula.RefPtg; +import org.apache.poi.hssf.usermodel.EvaluationCache; import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator; import org.apache.poi.hssf.usermodel.HSSFRow; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.hssf.util.CellReference; +/** +* +* @author Josh Micich +*/ public final class LazyRefEval extends RefEvalBase { private final HSSFSheet _sheet; @@ -49,4 +72,16 @@ public final class LazyRefEval extends RefEvalBase { return new LazyAreaEval(area, _sheet, _workbook); } + + public String toString() { + CellReference cr = new CellReference(getRow(), getColumn()); + StringBuffer sb = new StringBuffer(); + sb.append(getClass().getName()).append("["); + String sheetName = _workbook.getSheetName(_workbook.getSheetIndex(_sheet)); + sb.append(sheetName); + sb.append('!'); + sb.append(cr.formatAsString()); + sb.append("]"); + return sb.toString(); + } } diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/LessEqualEval.java b/src/java/org/apache/poi/hssf/record/formula/eval/LessEqualEval.java index e45bf9e6bb..e62be04d0c 100644 --- a/src/java/org/apache/poi/hssf/record/formula/eval/LessEqualEval.java +++ b/src/java/org/apache/poi/hssf/record/formula/eval/LessEqualEval.java @@ -1,67 +1,34 @@ -/* -* 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 - * - */ -package org.apache.poi.hssf.record.formula.eval; +/* ==================================================================== + 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 -import org.apache.poi.hssf.record.formula.LessEqualPtg; -import org.apache.poi.hssf.record.formula.Ptg; + 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 Amol S. Deshmukh < amolweb at ya hoo dot com > * */ -public class LessEqualEval extends RelationalOperationEval { +public final class LessEqualEval extends RelationalOperationEval { - private LessEqualPtg delegate; - - public LessEqualEval(Ptg ptg) { - this.delegate = (LessEqualPtg) ptg; - } - - public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { - ValueEval retval = null; - - RelationalValues rvs = super.doEvaluate(operands, srcRow, srcCol); - retval = rvs.ee; - int result = 0; - if (retval == null) { - result = doComparison(rvs.bs); - if (result == 0) { - result = doComparison(rvs.ss); - } - if (result == 0) { - result = doComparison(rvs.ds); - } - - retval = (result <= 0) ? BoolEval.TRUE : BoolEval.FALSE;; - } - - return retval; - } - - public int getNumberOfOperands() { - return delegate.getNumberOfOperands(); - } - - public int getType() { - return delegate.getType(); - } + public static final OperationEval instance = new LessEqualEval(); + + private LessEqualEval() { + } + protected boolean convertComparisonResult(int cmpResult) { + return cmpResult <= 0; + } } diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/LessThanEval.java b/src/java/org/apache/poi/hssf/record/formula/eval/LessThanEval.java index 1aac6f73bf..cf1fc1befc 100644 --- a/src/java/org/apache/poi/hssf/record/formula/eval/LessThanEval.java +++ b/src/java/org/apache/poi/hssf/record/formula/eval/LessThanEval.java @@ -1,68 +1,34 @@ -/* -* 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 - * - */ -package org.apache.poi.hssf.record.formula.eval; +/* ==================================================================== + 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 -import org.apache.poi.hssf.record.formula.LessThanPtg; -import org.apache.poi.hssf.record.formula.Ptg; + 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 Amol S. Deshmukh < amolweb at ya hoo dot com > * */ -public class LessThanEval extends RelationalOperationEval { +public final class LessThanEval extends RelationalOperationEval { - private LessThanPtg delegate; - - public LessThanEval(Ptg ptg) { - this.delegate = (LessThanPtg) ptg; - } - - - public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { - ValueEval retval = null; - - RelationalValues rvs = super.doEvaluate(operands, srcRow, srcCol); - retval = rvs.ee; - int result = 0; - if (retval == null) { - result = doComparison(rvs.bs); - if (result == 0) { - result = doComparison(rvs.ss); - } - if (result == 0) { - result = doComparison(rvs.ds); - } - - retval = (result < 0) ? BoolEval.TRUE : BoolEval.FALSE;; - } - - return retval; - } - - public int getNumberOfOperands() { - return delegate.getNumberOfOperands(); - } - - public int getType() { - return delegate.getType(); - } + public static final OperationEval instance = new LessThanEval(); + + private LessThanEval() { + } + protected boolean convertComparisonResult(int cmpResult) { + return cmpResult < 0; + } } diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/NotEqualEval.java b/src/java/org/apache/poi/hssf/record/formula/eval/NotEqualEval.java index c5388f520f..da8f315490 100644 --- a/src/java/org/apache/poi/hssf/record/formula/eval/NotEqualEval.java +++ b/src/java/org/apache/poi/hssf/record/formula/eval/NotEqualEval.java @@ -1,68 +1,34 @@ -/* -* 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 - * - */ -package org.apache.poi.hssf.record.formula.eval; +/* ==================================================================== + 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 -import org.apache.poi.hssf.record.formula.NotEqualPtg; -import org.apache.poi.hssf.record.formula.Ptg; + 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 Amol S. Deshmukh < amolweb at ya hoo dot com > * */ -public class NotEqualEval extends RelationalOperationEval { +public final class NotEqualEval extends RelationalOperationEval { - private NotEqualPtg delegate; - - public NotEqualEval(Ptg ptg) { - this.delegate = (NotEqualPtg) ptg; - } - - - public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { - ValueEval retval = null; - - RelationalValues rvs = super.doEvaluate(operands, srcRow, srcCol); - retval = rvs.ee; - int result = 0; - if (retval == null) { - result = doComparison(rvs.bs); - if (result == 0) { - result = doComparison(rvs.ss); - } - if (result == 0) { - result = doComparison(rvs.ds); - } - - retval = (result != 0) ? BoolEval.TRUE : BoolEval.FALSE; - } - - return retval; - } - - public int getNumberOfOperands() { - return delegate.getNumberOfOperands(); - } - - public int getType() { - return delegate.getType(); - } + public static final OperationEval instance = new NotEqualEval(); + + private NotEqualEval() { + } + protected boolean convertComparisonResult(int cmpResult) { + return cmpResult != 0; + } } diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/RelationalOperationEval.java b/src/java/org/apache/poi/hssf/record/formula/eval/RelationalOperationEval.java index 9b1a2ece4f..058b00e1ad 100644 --- a/src/java/org/apache/poi/hssf/record/formula/eval/RelationalOperationEval.java +++ b/src/java/org/apache/poi/hssf/record/formula/eval/RelationalOperationEval.java @@ -1,216 +1,145 @@ -/* -* 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 10, 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; /** + * Base class for all comparison operator evaluators + * * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * */ public abstract class RelationalOperationEval implements OperationEval { - protected class RelationalValues { - public Double[] ds = new Double[2]; - public Boolean[] bs = new Boolean[2]; - public String[] ss = new String[3]; - public ErrorEval ee = null; - } + /** + * Converts a standard compare result (-1, 0, 1) to true or false + * according to subclass' comparison type. + */ + protected abstract boolean convertComparisonResult(int cmpResult); - - /* - * This is a description of how the relational operators apply in MS Excel. - * Use this as a guideline when testing/implementing the evaluate methods - * for the relational operators Evals. - * - * Bool > any number. ALWAYS - * Bool > any string. ALWAYS - * Bool.TRUE > Bool.FALSE - * - * String > any number. ALWAYS - * String > Blank. ALWAYS - * String are sorted dictionary wise - * - * Blank == 0 (numeric) - */ - public RelationalValues doEvaluate(Eval[] operands, int srcRow, short srcCol) { - RelationalValues retval = new RelationalValues(); - - switch (operands.length) { - default: - retval.ee = ErrorEval.VALUE_INVALID; - break; - case 2: - internalDoEvaluate(operands, srcRow, srcCol, retval, 0); - internalDoEvaluate(operands, srcRow, srcCol, retval, 1); - } // end switch - return retval; - } - - /** - * convenience method to avoid code duplication for multiple operands - * @param operands - * @param srcRow - * @param srcCol - * @param retval - * @param index - */ - private void internalDoEvaluate(Eval[] operands, int srcRow, short srcCol, RelationalValues retval, int index) { - if (operands[index] instanceof BoolEval) { - BoolEval be = (BoolEval) operands[index]; - retval.bs[index] = Boolean.valueOf(be.getBooleanValue()); - } - else if (operands[index] instanceof NumericValueEval) { - NumericValueEval ne = (NumericValueEval) operands[index]; - retval.ds[index] = new Double(ne.getNumberValue()); - } - else if (operands[index] instanceof StringValueEval) { - StringValueEval se = (StringValueEval) operands[index]; - retval.ss[index] = se.getStringValue(); - } - else if (operands[index] instanceof RefEval) { - RefEval re = (RefEval) operands[index]; - ValueEval ve = re.getInnerValueEval(); - if (ve instanceof BoolEval) { - BoolEval be = (BoolEval) ve; - retval.bs[index] = Boolean.valueOf(be.getBooleanValue()); - } - else if (ve instanceof BlankEval) { - retval.ds[index] = new Double(0); - } - else if (ve instanceof NumericValueEval) { - NumericValueEval ne = (NumericValueEval) ve; - retval.ds[index] = new Double(ne.getNumberValue()); - } - else if (ve instanceof StringValueEval) { - StringValueEval se = (StringValueEval) ve; - retval.ss[index] = se.getStringValue(); - } - } - else if (operands[index] instanceof AreaEval) { - AreaEval ae = (AreaEval) operands[index]; - if (ae.isRow()) { - if (ae.containsColumn(srcCol)) { - ValueEval ve = ae.getValueAt(ae.getFirstRow(), srcCol); - if (ve instanceof BoolEval) { - BoolEval be = (BoolEval) ve; - retval.bs[index] = Boolean.valueOf(be.getBooleanValue()); - } - else if (ve instanceof BlankEval) { - retval.ds[index] = new Double(0); - } - else if (ve instanceof NumericValueEval) { - NumericValueEval ne = (NumericValueEval) ve; - retval.ds[index] = new Double(ne.getNumberValue()); - } - else if (ve instanceof StringValueEval) { - StringValueEval se = (StringValueEval) ve; - retval.ss[index] = se.getStringValue(); - } - else { - retval.ee = ErrorEval.VALUE_INVALID; - } - } - else { - retval.ee = ErrorEval.VALUE_INVALID; - } - } - else if (ae.isColumn()) { - if (ae.containsRow(srcRow)) { - ValueEval ve = ae.getValueAt(srcRow, ae.getFirstColumn()); - if (ve instanceof BoolEval) { - BoolEval be = (BoolEval) ve; - retval.bs[index] = Boolean.valueOf(be.getBooleanValue()); - } - else if (ve instanceof BlankEval) { - retval.ds[index] = new Double(0); - } - else if (ve instanceof NumericValueEval) { - NumericValueEval ne = (NumericValueEval) ve; - retval.ds[index] = new Double(ne.getNumberValue()); - } - else if (ve instanceof StringValueEval) { - StringValueEval se = (StringValueEval) ve; - retval.ss[index] = se.getStringValue(); - } - else { - retval.ee = ErrorEval.VALUE_INVALID; - } - } - else { - retval.ee = ErrorEval.VALUE_INVALID; - } - } - else { - retval.ee = ErrorEval.VALUE_INVALID; - } - } - } - - // if both null return 0, else non null wins, else TRUE wins - protected int doComparison(Boolean[] bs) { - int retval = 0; - if (bs[0] != null || bs[1] != null) { - retval = bs[0] != null - ? bs[1] != null - ? bs[0].booleanValue() - ? bs[1].booleanValue() - ? 0 - : 1 - : bs[1].booleanValue() - ? -1 - : 0 - : 1 - : bs[1] != null - ? -1 - : 0; - } - return retval; - } + /** + * This is a description of how the relational operators apply in MS Excel. + * Use this as a guideline when testing/implementing the evaluate methods + * for the relational operators Evals. + * + *
+	 * Bool.TRUE > any number.
+	 * Bool > any string. ALWAYS
+	 * Bool.TRUE > Bool.FALSE
+	 * Bool.FALSE == Blank
+	 *
+	 * Strings are never converted to numbers or booleans
+	 * String > any number. ALWAYS
+	 * Non-empty String > Blank
+	 * Empty String == Blank
+	 * String are sorted dictionary wise
+	 *
+	 * Blank > Negative numbers
+	 * Blank == 0
+	 * Blank < Positive numbers
+	 * 
+ */ + public final Eval evaluate(Eval[] operands, int srcRow, short srcCol) { + if (operands.length != 2) { + return ErrorEval.VALUE_INVALID; + } - // if both null return 0, else non null wins, else string compare - protected int doComparison(String[] ss) { - int retval = 0; - if (ss[0] != null || ss[1] != null) { - retval = ss[0] != null - ? ss[1] != null - ? ss[0].compareTo(ss[1]) - : 1 - : ss[1] != null - ? -1 - : 0; - } - return retval; - } + ValueEval vA; + ValueEval vB; + try { + vA = OperandResolver.getSingleValue(operands[0], srcRow, srcCol); + vB = OperandResolver.getSingleValue(operands[1], srcRow, srcCol); + } catch (EvaluationException e) { + return e.getErrorEval(); + } + int cmpResult = doCompare(vA, vB); + boolean result = convertComparisonResult(cmpResult); + return BoolEval.valueOf(result); + } - // if both null return 0, else non null wins, else doublevalue compare - protected int doComparison(Double[] ds) { - int retval = 0; - if (ds[0] != null || ds[1] != null) { - retval = ds[0] != null - ? ds[1] != null - ? ds[0].compareTo(ds[1]) - : 1 - : ds[1] != null - ? -1 - : 0; - } - return retval; - } + private static int doCompare(ValueEval va, ValueEval vb) { + // special cases when one operand is blank + if (va == BlankEval.INSTANCE) { + return compareBlank(vb); + } + if (vb == BlankEval.INSTANCE) { + return -compareBlank(va); + } + + if (va instanceof BoolEval) { + if (vb instanceof BoolEval) { + BoolEval bA = (BoolEval) va; + BoolEval bB = (BoolEval) vb; + if (bA.getBooleanValue() == bB.getBooleanValue()) { + return 0; + } + return bA.getBooleanValue() ? 1 : -1; + } + return 1; + } + if (vb instanceof BoolEval) { + return -1; + } + if (va instanceof StringEval) { + if (vb instanceof StringEval) { + StringEval sA = (StringEval) va; + StringEval sB = (StringEval) vb; + return sA.getStringValue().compareTo(sB.getStringValue()); + } + return 1; + } + if (vb instanceof StringEval) { + return -1; + } + if (va instanceof NumberEval) { + if (vb instanceof NumberEval) { + NumberEval nA = (NumberEval) va; + NumberEval nB = (NumberEval) vb; + return Double.compare(nA.getNumberValue(), nB.getNumberValue()); + } + } + throw new IllegalArgumentException("Bad operand types (" + va.getClass().getName() + "), (" + + vb.getClass().getName() + ")"); + } + + private static int compareBlank(ValueEval v) { + if (v == BlankEval.INSTANCE) { + return 0; + } + if (v instanceof BoolEval) { + BoolEval boolEval = (BoolEval) v; + return boolEval.getBooleanValue() ? -1 : 0; + } + if (v instanceof NumberEval) { + NumberEval ne = (NumberEval) v; + return Double.compare(0, ne.getNumberValue()); + } + if (v instanceof StringEval) { + StringEval se = (StringEval) v; + return se.getStringValue().length() < 1 ? 0 : -1; + } + throw new IllegalArgumentException("bad value class (" + v.getClass().getName() + ")"); + } + + 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"); + } } diff --git a/src/java/org/apache/poi/hssf/usermodel/OperationEvaluatorFactory.java b/src/java/org/apache/poi/hssf/usermodel/OperationEvaluatorFactory.java index 1292009699..f7d3c9749b 100755 --- a/src/java/org/apache/poi/hssf/usermodel/OperationEvaluatorFactory.java +++ b/src/java/org/apache/poi/hssf/usermodel/OperationEvaluatorFactory.java @@ -69,8 +69,9 @@ import org.apache.poi.hssf.record.formula.eval.UnaryPlusEval; */ final class OperationEvaluatorFactory { private static final Class[] OPERATION_CONSTRUCTOR_CLASS_ARRAY = new Class[] { Ptg.class }; - + // TODO - use singleton instances directly instead of reflection private static final Map _constructorsByPtgClass = initialiseConstructorsMap(); + private static final Map _instancesByPtgClass = initialiseInstancesMap(); private OperationEvaluatorFactory() { // no instances of this class @@ -81,15 +82,9 @@ final class OperationEvaluatorFactory { add(m, AddPtg.class, AddEval.class); add(m, ConcatPtg.class, ConcatEval.class); add(m, DividePtg.class, DivideEval.class); - add(m, EqualPtg.class, EqualEval.class); add(m, FuncPtg.class, FuncVarEval.class); add(m, FuncVarPtg.class, FuncVarEval.class); - add(m, GreaterEqualPtg.class, GreaterEqualEval.class); - add(m, GreaterThanPtg.class, GreaterThanEval.class); - add(m, LessEqualPtg.class, LessEqualEval.class); - add(m, LessThanPtg.class, LessThanEval.class); add(m, MultiplyPtg.class, MultiplyEval.class); - add(m, NotEqualPtg.class, NotEqualEval.class); add(m, PercentPtg.class, PercentEval.class); add(m, PowerPtg.class, PowerEval.class); add(m, SubtractPtg.class, SubtractEval.class); @@ -97,13 +92,30 @@ final class OperationEvaluatorFactory { add(m, UnaryPlusPtg.class, UnaryPlusEval.class); return m; } + private static Map initialiseInstancesMap() { + Map m = new HashMap(32); + add(m, EqualPtg.class, EqualEval.instance); + add(m, GreaterEqualPtg.class, GreaterEqualEval.instance); + add(m, GreaterThanPtg.class, GreaterThanEval.instance); + add(m, LessEqualPtg.class, LessEqualEval.instance); + add(m, LessThanPtg.class, LessThanEval.instance); + add(m, NotEqualPtg.class, NotEqualEval.instance); + return m; + } + + private static void add(Map m, Class ptgClass, OperationEval evalInstance) { + if(!Ptg.class.isAssignableFrom(ptgClass)) { + throw new IllegalArgumentException("Expected Ptg subclass"); + } + m.put(ptgClass, evalInstance); + } private static void add(Map m, Class ptgClass, Class evalClass) { - // perform some validation now, to keep later exception handlers simple if(!Ptg.class.isAssignableFrom(ptgClass)) { throw new IllegalArgumentException("Expected Ptg subclass"); } + if(!OperationEval.class.isAssignableFrom(evalClass)) { throw new IllegalArgumentException("Expected OperationEval subclass"); } @@ -125,7 +137,7 @@ final class OperationEvaluatorFactory { } m.put(ptgClass, constructor); } - + /** * returns the OperationEval concrete impl instance corresponding * to the supplied operationPtg @@ -134,9 +146,16 @@ final class OperationEvaluatorFactory { if(ptg == null) { throw new IllegalArgumentException("ptg must not be null"); } + Object result; Class ptgClass = ptg.getClass(); + result = _instancesByPtgClass.get(ptgClass); + if (result != null) { + return (OperationEval) result; + } + + Constructor constructor = (Constructor) _constructorsByPtgClass.get(ptgClass); if(constructor == null) { if(ptgClass == ExpPtg.class) { @@ -147,7 +166,6 @@ final class OperationEvaluatorFactory { throw new RuntimeException("Unexpected operation ptg class (" + ptgClass.getName() + ")"); } - Object result; Object[] initargs = { ptg }; try { result = constructor.newInstance(initargs); diff --git a/src/testcases/org/apache/poi/hssf/data/FormulaEvalTestData.xls b/src/testcases/org/apache/poi/hssf/data/FormulaEvalTestData.xls index 51e370bfb96d6ba0c5c2429a0b8cdcebadad0b81..99cb61a58811b2246af6cc66651997d897dffe0c 100644 GIT binary patch delta 3053 zcmZuzYgAO%72f-tbLR!jfT9osBKYDZFv?>PP%vn1LQ{OC+Mva>Xw(&zh%3?9hSAkX zL?YnDUX8|(m{zbhp^kMxV=}F_A&D4lNh+udbXgTwlCq+C=`z!O?nTfpe%yV(``zz+ zd+&4RoVo5MtGmfsGatXv9HUs)pG!;eFnflX`i4Ke`=ni6E4HvZR`s@6X%F7tuSzEAcHWdK>%Q& z54430KAyFP+7l7M1@E$c#aU}~zlGIin1!p8Z1+a~(r&l7BtU`z=rRVhsK^xHpS2rO% zS%I*u5<%=j2;PG*?)Nn4Z5q&wu)h_lFiP|py}O8TrJGv2jM|z&wnj_%5)(Zo8&;Yz z*z<{dD~ek!p(f9w%{fB!N%Y#5b(|G9dWKgfqxhT{b=I~R;TwBFQJ>lNDPLaPsODEW zIXJ4-^;PeP>r#>M%A0(4+zGY)l>=hTI8tuhzD4xis!&v=I-R>|$h7L60=}zIJpZna z=Dd)!cXmwV5o9u6&E_t;m#FzXcVCU?kLsgB4gDw>W7Lq3hT~X0j??3KJx9`Vd@(!IeLd z*foT3>JVJk5M1^UT+R^Ova>3cE5={MuXbCr!+%h78u)KtbvWH3~Zz~uuKGCV25Yy-d=_QYS8NsC-2_9+o<2+ z4=_s0Hv{tpnIIbC!D4jKFNz1Vy5RMLvrRCD-aXhIY5g{;EKI=sxlhdOA8+(07g;8u zF+T)AB!(%vX6}yqif~y{Lcf=RjWM2z`gkkNca)rcV-D^fXVT?gOu270?1p6c|4mci z;A*JvG@jDaWa&o6EM$Qk0pKY+Sb`aqBWU5+C=l!*?S@d;fG_CxZrrEee}`N2`={_E z-DB9_D1OMgJoZDc28b(i!yocS@P%-YQB3m=U4EIzd# z54W14`4Zae*4|`ZN2fqmZz^y4(`;}O@g&`N`yr8g zr$W(sI3|d5-x6{NLZ>B~Ced3Gt&%8(4jOH*z(TQ0a($Akk|;{SWZ@>{ol7VI{o3Xf zEMoRrtvdxfj_*dz$e5xX_5OA{3=NJiW|9>UW949g9ffHA_q6g4isUWD3DckNYod* zRnc$}#>@7#q(zt}+|;=C^dkHXuUpWlU0X!{4GS8*5sNY0!e1tfjHT2L#L>W&5_QO0 zUt5ZaqFrWhTZ$hiiqn$ZyMr1il?}A+p!7bnLzNn+A(L#C8rVgkOr-?%1R7LopjBF6 z9oomzI%pwYoXXuwt@gMV=LolS+V92ZM2$p|&6p!{=e#epUo_(~u~(Me+Ki8jdii!# z3(gYFk}GM!0ue6DJ<@`Yh*Pq%J1tbt7*nm5dJGrv2Fkwu7-oqMsc$<*E9jG|=;N5o zo8nG*=N-p{kn(qllN(^VBIppHQzCCOnCK{=XUGK(%>(ZhI%vjO0eu4sMOPddP?)8H z{)-0{CVfAoP@OVI2neYNF%)KI2BFhP_N=MaR(E2$EZ`5F=oGtTj`N*3fy2T^ zO>~jEPEzSzMER(?;x4MrC#$RK!bBcQs^d}>Aw9q7B8wWSk2#O|qKc4r<#`MfqEP;5 zU+Tu0qFs(X(@nx2iFgmKTq_x;_25L_E;IB{h7$QJsFKJnQHzeG$JHMC;k#tAs7o|q zv6O$_C7dkgOKR&S+$3I>S?!n6W)_88|EXvZy|~OGQSO^%%7MyWM6_tzZeSc8W7^Rh zm~2m=e;4{sr_+^?UAuV$-wSx`D#EH;2;bit{P=Mm{Tz{b7k`O29j2?_AT%&-bs#I1 zA4c1}bNm<g)?$u zQeCNeX|A*xX_>}F{Er^ViE(AP(lRsh@@8h{r%%qz&yZKXH=&S?Ks80sDKv-Wp{4)h PoU6}n$ng5+vRvhVp5!TR delta 2820 zcmZve3s6+o8OOixoU_Y5cr1!MtWV+t1wnAd#X#I$SCUE4V#gSxB1DN|WQ?y`(Y9<& zVX4L{z2Hs66tqR1ViMzyt|&1Zv{tJDlVYQQ29Tx4oWa)Vea1l{oVif zI`^L0bso_>kLY*J!!Om4q3rQ@)~vy!ET3tuH^Sb%W>nURV)mR)xhGxU5SK&&U-q^>&mF#{M$RGlCApkJw z3p9idTz;qz3ywns3)Ha(jt}*tAEeM5?k9^>CK>um{j^^hQU|iM8^Qw-W;~oDEI99n zY2P#4PfMR}Zu}&E_>P;hrw~YAx%!3G%U;Y_xpdx(>o=?~f*}z1h2l$zU=HSvoPIB@ z@E_FxYij`xy$>*}0igb$09#rB%r^n<^#F8#4$%A`fN$;stojaM5mh!B5mG`CMu#Iz zib5DZ4B^;FgzM1=AB;t~8jCPL3E{6Z5QaR3uzxN>))Is>c?jNB2%A>Z^+tr11vm}t zPK4t{2=yfhIlB?^Uq^8MiGmJOz;OiMIi$v@&=tDZf?&OYu((al{tWlJa|>Pyz#w;{ z^LHq&HXH!=;;m^yv`O_w@dnOHE8T;)C7|dcqNHz+7FA12gp$Ag3Xl0?rQ&!sk)P1I zlufU`EqbLRcE^4`s@$bq-f>VIk{c zl&}9Vo;OjFu}Uh30GE=hI5@n0)?K4KEeeA`C!YfVhJcQlAQ})JWsmt`WBjnOe%Lra zZ2SN#{JwC^0Q{a!@WUqhVX=N#oF6vnN375U@jrqlNbtiZ6C3o%Y9;z%Nq*QAKg=vy z;Ufu?{TQeDVHQ7Zx*ztqAC~$Mo7(@}(;kBT>d&*E*ws*BV=#5VHOn}b_ zjzB=KBN&)BNDHH3A_Rbqtn$z21G?5plNPww5inrV^_isYzR9ShR{cdu*jMcSVBbW& zl2%jijyRl)(>@&x;9x^(Yp;ed`Y*uEedpa+{DboqSV-5=te!q!VfF5#Z|*UQyK>`X z)(+z(ip%|SZE4`q^MA&p=PqO5S5)|0pU-!P&Pwaw#=5I7Xh!p0v}fMzPT+a8n?C6_ zbLYuyCA`PR&(n5W*ptdmXDhGuB#U7IF5&*D=dCCa_{$2e{#JvrVvJO7Ql`!g*+R}# zfm)v)93kp^8jLb%XWmf>L?kKCSEOR`J9S(V zE@J;KQeR2JCT1&9pPzyqBG-EWJTuIg8YQ6d0H}qtF-BaLNo!_fGIy3%s-3gZ!mAXQ zI&u!0`5_YX=U@^)LSp+Id{*cv&eJ&uZwHC4&GVSrycnnQu5F3xpe)MZCEGJuI6)lQ zNL_7`$}3fM7EY84qJETxQ-y_=LNzYIUvY0uqPl$vi7b6fMhXoJ%q= zcm*kw?A5jc<3yyazIFv(j1!|Iw3g8TZE}G8GAiFi>8i_UfXkGmt&9d}BN0(f1-eLN zl+yq)GDUSc20unmMm=@{r}G?IpW7#JuIQDSo~*@<0+x|_zZTPk_t<`}vXi)6%#&^B zpTs%BB=4R+iRr>AneG&3h^w;Q1*dSPm@GT1JVpKFd|ISlJ%!H&^(wBu#~Yyu^$k_= zT?|t*>u|Vm>L`3|9cBhuC`i5l5t_liDCr1SJL}NI?YJwS$MDTXVjjurq`KCCBjx<}8ZeRT%3NxE zBbi3YxfV6jLg&jA+Z!=jWJvXnR1Q*}j~nsV1`#LW^UXMd#~e;nH#cKEx00wKA@<6d zt~b+~d;e9W4r;+{fD}kU2|RDa9q}Ki7&5ah8-P_&P=iary5QF`*r239F1<*G|SvsSdVd0*|D`*V=JB z&y*E9s6ww?mdR4VFGywesf*;_)fh%Ic7dr2Z(%}k6VuQpMrdNBG^%IpChtzD?8>{*o%8Y0_a`Y6;XD(E#G{cXFvAY(`_xvw|b+F77TZ+YEvpFnwd*Z`KbdbT3X-|tz zNl$TD(ruQML^`I~Qtlsg_sN-Q(KfR!*>1K^vCp)p*d6jPd&Xw6A?UHrWj54_i+#UY Pxw5ukn#cPyX4U*3eTx4J diff --git a/src/testcases/org/apache/poi/hssf/record/formula/eval/AllFormulaEvalTests.java b/src/testcases/org/apache/poi/hssf/record/formula/eval/AllFormulaEvalTests.java index 8887445ad3..3809a86a69 100755 --- a/src/testcases/org/apache/poi/hssf/record/formula/eval/AllFormulaEvalTests.java +++ b/src/testcases/org/apache/poi/hssf/record/formula/eval/AllFormulaEvalTests.java @@ -31,6 +31,7 @@ public class AllFormulaEvalTests { TestSuite result = new TestSuite(AllFormulaEvalTests.class.getName()); result.addTestSuite(TestAreaEval.class); result.addTestSuite(TestCircularReferences.class); + result.addTestSuite(TestEqualEval.class); result.addTestSuite(TestExternalFunction.class); result.addTestSuite(TestFormulaBugs.class); result.addTestSuite(TestFormulasFromSpreadsheet.class); diff --git a/src/testcases/org/apache/poi/hssf/record/formula/eval/TestEqualEval.java b/src/testcases/org/apache/poi/hssf/record/formula/eval/TestEqualEval.java new file mode 100644 index 0000000000..d1b1db0d16 --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/record/formula/eval/TestEqualEval.java @@ -0,0 +1,69 @@ +/* ==================================================================== + 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.AssertionFailedError; +import junit.framework.TestCase; + +import org.apache.poi.hssf.record.formula.functions.EvalFactory; + +/** + * Test for unary plus operator evaluator. + * + * @author Josh Micich + */ +public final class TestEqualEval extends TestCase { + + /** + * Test for bug observable at svn revision 692218 (Sep 2008)
+ * The value from a 1x1 area should be taken immediately, regardless of srcRow and srcCol + */ + public void test1x1AreaOperand() { + + ValueEval[] values = { BoolEval.FALSE, }; + Eval[] args = { + EvalFactory.createAreaEval("B1:B1", values), + BoolEval.FALSE, + }; + Eval result = EqualEval.instance.evaluate(args, 10, (short)20); + if (result instanceof ErrorEval) { + if (result == ErrorEval.VALUE_INVALID) { + throw new AssertionFailedError("Identified bug in evaluation of 1x1 area"); + } + } + assertEquals(BoolEval.class, result.getClass()); + assertTrue(((BoolEval)result).getBooleanValue()); + } + /** + * Empty string is equal to blank + */ + public void testBlankEqualToEmptyString() { + + Eval[] args = { + new StringEval(""), + BlankEval.INSTANCE, + }; + Eval result = EqualEval.instance.evaluate(args, 10, (short)20); + assertEquals(BoolEval.class, result.getClass()); + BoolEval be = (BoolEval) result; + if (!be.getBooleanValue()) { + throw new AssertionFailedError("Identified bug blank/empty string equality"); + } + assertTrue(be.getBooleanValue()); + } +}