Move the FormulaEvaluator code out of scratchpad
[poi.git] / src / java / org / apache / poi / hssf / record / formula / eval / RelationalOperationEval.java
blob9b1a2ece4ff678a5db9e5b198d0ae0d3fdcf2692
1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
18 * Created on May 10, 2005
21 package org.apache.poi.hssf.record.formula.eval;
23 /**
24 * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
27 public abstract class RelationalOperationEval implements OperationEval {
29 protected class RelationalValues {
30 public Double[] ds = new Double[2];
31 public Boolean[] bs = new Boolean[2];
32 public String[] ss = new String[3];
33 public ErrorEval ee = null;
38 * This is a description of how the relational operators apply in MS Excel.
39 * Use this as a guideline when testing/implementing the evaluate methods
40 * for the relational operators Evals.
42 * Bool > any number. ALWAYS
43 * Bool > any string. ALWAYS
44 * Bool.TRUE > Bool.FALSE
46 * String > any number. ALWAYS
47 * String > Blank. ALWAYS
48 * String are sorted dictionary wise
50 * Blank == 0 (numeric)
52 public RelationalValues doEvaluate(Eval[] operands, int srcRow, short srcCol) {
53 RelationalValues retval = new RelationalValues();
55 switch (operands.length) {
56 default:
57 retval.ee = ErrorEval.VALUE_INVALID;
58 break;
59 case 2:
60 internalDoEvaluate(operands, srcRow, srcCol, retval, 0);
61 internalDoEvaluate(operands, srcRow, srcCol, retval, 1);
62 } // end switch
63 return retval;
66 /**
67 * convenience method to avoid code duplication for multiple operands
68 * @param operands
69 * @param srcRow
70 * @param srcCol
71 * @param retval
72 * @param index
74 private void internalDoEvaluate(Eval[] operands, int srcRow, short srcCol, RelationalValues retval, int index) {
75 if (operands[index] instanceof BoolEval) {
76 BoolEval be = (BoolEval) operands[index];
77 retval.bs[index] = Boolean.valueOf(be.getBooleanValue());
79 else if (operands[index] instanceof NumericValueEval) {
80 NumericValueEval ne = (NumericValueEval) operands[index];
81 retval.ds[index] = new Double(ne.getNumberValue());
83 else if (operands[index] instanceof StringValueEval) {
84 StringValueEval se = (StringValueEval) operands[index];
85 retval.ss[index] = se.getStringValue();
87 else if (operands[index] instanceof RefEval) {
88 RefEval re = (RefEval) operands[index];
89 ValueEval ve = re.getInnerValueEval();
90 if (ve instanceof BoolEval) {
91 BoolEval be = (BoolEval) ve;
92 retval.bs[index] = Boolean.valueOf(be.getBooleanValue());
94 else if (ve instanceof BlankEval) {
95 retval.ds[index] = new Double(0);
97 else if (ve instanceof NumericValueEval) {
98 NumericValueEval ne = (NumericValueEval) ve;
99 retval.ds[index] = new Double(ne.getNumberValue());
101 else if (ve instanceof StringValueEval) {
102 StringValueEval se = (StringValueEval) ve;
103 retval.ss[index] = se.getStringValue();
106 else if (operands[index] instanceof AreaEval) {
107 AreaEval ae = (AreaEval) operands[index];
108 if (ae.isRow()) {
109 if (ae.containsColumn(srcCol)) {
110 ValueEval ve = ae.getValueAt(ae.getFirstRow(), srcCol);
111 if (ve instanceof BoolEval) {
112 BoolEval be = (BoolEval) ve;
113 retval.bs[index] = Boolean.valueOf(be.getBooleanValue());
115 else if (ve instanceof BlankEval) {
116 retval.ds[index] = new Double(0);
118 else if (ve instanceof NumericValueEval) {
119 NumericValueEval ne = (NumericValueEval) ve;
120 retval.ds[index] = new Double(ne.getNumberValue());
122 else if (ve instanceof StringValueEval) {
123 StringValueEval se = (StringValueEval) ve;
124 retval.ss[index] = se.getStringValue();
126 else {
127 retval.ee = ErrorEval.VALUE_INVALID;
130 else {
131 retval.ee = ErrorEval.VALUE_INVALID;
134 else if (ae.isColumn()) {
135 if (ae.containsRow(srcRow)) {
136 ValueEval ve = ae.getValueAt(srcRow, ae.getFirstColumn());
137 if (ve instanceof BoolEval) {
138 BoolEval be = (BoolEval) ve;
139 retval.bs[index] = Boolean.valueOf(be.getBooleanValue());
141 else if (ve instanceof BlankEval) {
142 retval.ds[index] = new Double(0);
144 else if (ve instanceof NumericValueEval) {
145 NumericValueEval ne = (NumericValueEval) ve;
146 retval.ds[index] = new Double(ne.getNumberValue());
148 else if (ve instanceof StringValueEval) {
149 StringValueEval se = (StringValueEval) ve;
150 retval.ss[index] = se.getStringValue();
152 else {
153 retval.ee = ErrorEval.VALUE_INVALID;
156 else {
157 retval.ee = ErrorEval.VALUE_INVALID;
160 else {
161 retval.ee = ErrorEval.VALUE_INVALID;
166 // if both null return 0, else non null wins, else TRUE wins
167 protected int doComparison(Boolean[] bs) {
168 int retval = 0;
169 if (bs[0] != null || bs[1] != null) {
170 retval = bs[0] != null
171 ? bs[1] != null
172 ? bs[0].booleanValue()
173 ? bs[1].booleanValue()
176 : bs[1].booleanValue()
177 ? -1
180 : bs[1] != null
181 ? -1
182 : 0;
184 return retval;
187 // if both null return 0, else non null wins, else string compare
188 protected int doComparison(String[] ss) {
189 int retval = 0;
190 if (ss[0] != null || ss[1] != null) {
191 retval = ss[0] != null
192 ? ss[1] != null
193 ? ss[0].compareTo(ss[1])
195 : ss[1] != null
196 ? -1
197 : 0;
199 return retval;
202 // if both null return 0, else non null wins, else doublevalue compare
203 protected int doComparison(Double[] ds) {
204 int retval = 0;
205 if (ds[0] != null || ds[1] != null) {
206 retval = ds[0] != null
207 ? ds[1] != null
208 ? ds[0].compareTo(ds[1])
210 : ds[1] != null
211 ? -1
212 : 0;
214 return retval;