-/*
-* 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
+
+ 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.
+==================================================================== */
-import org.apache.poi.hssf.record.formula.EqualPtg;
-import org.apache.poi.hssf.record.formula.Ptg;
+package org.apache.poi.hssf.record.formula.eval;
/**
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
*
*/
-public class EqualEval extends RelationalOperationEval {
-
- private EqualPtg delegate;
-
- 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 final class EqualEval extends RelationalOperationEval {
- public int getNumberOfOperands() {
- return delegate.getNumberOfOperands();
- }
+ public static final OperationEval instance = new EqualEval();
+
+ private EqualEval() {
+ }
- public int getType() {
- return delegate.getType();
- }
+ protected boolean convertComparisonResult(int cmpResult) {
+ return cmpResult == 0;
+ }
}
-/*
-* 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
+
+ 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.
+==================================================================== */
-import org.apache.poi.hssf.record.formula.GreaterEqualPtg;
-import org.apache.poi.hssf.record.formula.Ptg;
+package org.apache.poi.hssf.record.formula.eval;
/**
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
*
*/
-public 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 final class GreaterEqualEval extends RelationalOperationEval {
- public int getType() {
- return delegate.getType();
- }
+ public static final OperationEval instance = new GreaterEqualEval();
+
+ private GreaterEqualEval() {
+ }
+ protected boolean convertComparisonResult(int cmpResult) {
+ return cmpResult >= 0;
+ }
}
-/*
-* 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
+
+ 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.
+==================================================================== */
-import org.apache.poi.hssf.record.formula.GreaterThanPtg;
-import org.apache.poi.hssf.record.formula.Ptg;
+package org.apache.poi.hssf.record.formula.eval;
/**
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
*
*/
-public 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 final class GreaterThanEval extends RelationalOperationEval {
- public int getType() {
- return delegate.getType();
- }
+ public static final OperationEval instance = new GreaterThanEval();
+
+ private GreaterThanEval() {
+ }
+ protected boolean convertComparisonResult(int cmpResult) {
+ return cmpResult > 0;
+ }
}
-/*
-* 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 {
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();
+ }
}
+/* ====================================================================\r
+ Licensed to the Apache Software Foundation (ASF) under one or more\r
+ contributor license agreements. See the NOTICE file distributed with\r
+ this work for additional information regarding copyright ownership.\r
+ The ASF licenses this file to You under the Apache License, Version 2.0\r
+ (the "License"); you may not use this file except in compliance with\r
+ the License. You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+==================================================================== */\r
+\r
package org.apache.poi.hssf.record.formula.eval;\r
\r
import org.apache.poi.hssf.record.formula.AreaI;\r
import org.apache.poi.hssf.record.formula.AreaI.OffsetArea;\r
import org.apache.poi.hssf.record.formula.Ref3DPtg;\r
import org.apache.poi.hssf.record.formula.RefPtg;\r
+import org.apache.poi.hssf.usermodel.EvaluationCache;\r
import org.apache.poi.hssf.usermodel.HSSFCell;\r
import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator;\r
import org.apache.poi.hssf.usermodel.HSSFRow;\r
import org.apache.poi.hssf.usermodel.HSSFSheet;\r
import org.apache.poi.hssf.usermodel.HSSFWorkbook;\r
+import org.apache.poi.hssf.util.CellReference;\r
\r
+/**\r
+*\r
+* @author Josh Micich \r
+*/\r
public final class LazyRefEval extends RefEvalBase {\r
\r
private final HSSFSheet _sheet;\r
\r
return new LazyAreaEval(area, _sheet, _workbook);\r
}\r
+ \r
+ public String toString() {\r
+ CellReference cr = new CellReference(getRow(), getColumn());\r
+ StringBuffer sb = new StringBuffer();\r
+ sb.append(getClass().getName()).append("[");\r
+ String sheetName = _workbook.getSheetName(_workbook.getSheetIndex(_sheet));\r
+ sb.append(sheetName);\r
+ sb.append('!');\r
+ sb.append(cr.formatAsString());\r
+ sb.append("]");\r
+ return sb.toString();\r
+ }\r
}\r
-/*
-* 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
+
+ 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.
+==================================================================== */
-import org.apache.poi.hssf.record.formula.LessEqualPtg;
-import org.apache.poi.hssf.record.formula.Ptg;
+package org.apache.poi.hssf.record.formula.eval;
/**
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
*
*/
-public 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 final class LessEqualEval extends RelationalOperationEval {
- public int getType() {
- return delegate.getType();
- }
+ public static final OperationEval instance = new LessEqualEval();
+
+ private LessEqualEval() {
+ }
+ protected boolean convertComparisonResult(int cmpResult) {
+ return cmpResult <= 0;
+ }
}
-/*
-* 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
+
+ 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.
+==================================================================== */
-import org.apache.poi.hssf.record.formula.LessThanPtg;
-import org.apache.poi.hssf.record.formula.Ptg;
+package org.apache.poi.hssf.record.formula.eval;
/**
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
*
*/
-public 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 final class LessThanEval extends RelationalOperationEval {
- public int getType() {
- return delegate.getType();
- }
+ public static final OperationEval instance = new LessThanEval();
+
+ private LessThanEval() {
+ }
+ protected boolean convertComparisonResult(int cmpResult) {
+ return cmpResult < 0;
+ }
}
-/*
-* 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
+
+ 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.
+==================================================================== */
-import org.apache.poi.hssf.record.formula.NotEqualPtg;
-import org.apache.poi.hssf.record.formula.Ptg;
+package org.apache.poi.hssf.record.formula.eval;
/**
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
*
*/
-public 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 final class NotEqualEval extends RelationalOperationEval {
- public int getType() {
- return delegate.getType();
- }
+ public static final OperationEval instance = new NotEqualEval();
+
+ private NotEqualEval() {
+ }
+ protected boolean convertComparisonResult(int cmpResult) {
+ return cmpResult != 0;
+ }
}
-/*
-* 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 <code>true</code> or <code>false</code>
+ * 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.
+ *
+ * <pre>
+ * 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
+ * </pre>
+ */
+ public final Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
+ if (operands.length != 2) {
+ return ErrorEval.VALUE_INVALID;
+ }
+
+ 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);
+ }
+
+ 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() + ")");
+ }
-
- /*
- * 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;
- }
+ 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() + ")");
+ }
- // 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;
- }
+ public final int getNumberOfOperands() {
+ return 2;
+ }
- // 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;
- }
+ public final int getType() {
+ // TODO - get rid of this method
+ throw new RuntimeException("Obsolete code - should not be called");
+ }
}
*/
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
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);
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");
}
}
m.put(ptgClass, constructor);
}
-
+
/**
* returns the OperationEval concrete impl instance corresponding
* to the supplied operationPtg
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) {
throw new RuntimeException("Unexpected operation ptg class (" + ptgClass.getName() + ")");
}
- Object result;
Object[] initargs = { ptg };
try {
result = constructor.newInstance(initargs);
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);
--- /dev/null
+/* ====================================================================\r
+ Licensed to the Apache Software Foundation (ASF) under one or more\r
+ contributor license agreements. See the NOTICE file distributed with\r
+ this work for additional information regarding copyright ownership.\r
+ The ASF licenses this file to You under the Apache License, Version 2.0\r
+ (the "License"); you may not use this file except in compliance with\r
+ the License. You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+==================================================================== */\r
+\r
+package org.apache.poi.hssf.record.formula.eval;\r
+\r
+import junit.framework.AssertionFailedError;\r
+import junit.framework.TestCase;\r
+\r
+import org.apache.poi.hssf.record.formula.functions.EvalFactory;\r
+\r
+/**\r
+ * Test for unary plus operator evaluator.\r
+ *\r
+ * @author Josh Micich\r
+ */\r
+public final class TestEqualEval extends TestCase {\r
+\r
+ /**\r
+ * Test for bug observable at svn revision 692218 (Sep 2008)<br/>\r
+ * The value from a 1x1 area should be taken immediately, regardless of srcRow and srcCol\r
+ */\r
+ public void test1x1AreaOperand() {\r
+ \r
+ ValueEval[] values = { BoolEval.FALSE, };\r
+ Eval[] args = {\r
+ EvalFactory.createAreaEval("B1:B1", values),\r
+ BoolEval.FALSE,\r
+ };\r
+ Eval result = EqualEval.instance.evaluate(args, 10, (short)20);\r
+ if (result instanceof ErrorEval) {\r
+ if (result == ErrorEval.VALUE_INVALID) {\r
+ throw new AssertionFailedError("Identified bug in evaluation of 1x1 area");\r
+ }\r
+ }\r
+ assertEquals(BoolEval.class, result.getClass());\r
+ assertTrue(((BoolEval)result).getBooleanValue());\r
+ }\r
+ /**\r
+ * Empty string is equal to blank\r
+ */\r
+ public void testBlankEqualToEmptyString() {\r
+ \r
+ Eval[] args = {\r
+ new StringEval(""),\r
+ BlankEval.INSTANCE,\r
+ };\r
+ Eval result = EqualEval.instance.evaluate(args, 10, (short)20);\r
+ assertEquals(BoolEval.class, result.getClass());\r
+ BoolEval be = (BoolEval) result;\r
+ if (!be.getBooleanValue()) {\r
+ throw new AssertionFailedError("Identified bug blank/empty string equality");\r
+ }\r
+ assertTrue(be.getBooleanValue());\r
+ }\r
+}\r