001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: /*
018: * Created on May 10, 2005
019: *
020: */
021: package org.apache.poi.hssf.record.formula.eval;
022:
023: /**
024: * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
025: *
026: */
027: public abstract class RelationalOperationEval implements OperationEval {
028:
029: protected class RelationalValues {
030: public Double[] ds = new Double[2];
031: public Boolean[] bs = new Boolean[2];
032: public String[] ss = new String[3];
033: public ErrorEval ee = null;
034: }
035:
036: /*
037: * This is a description of how the relational operators apply in MS Excel.
038: * Use this as a guideline when testing/implementing the evaluate methods
039: * for the relational operators Evals.
040: *
041: * Bool > any number. ALWAYS
042: * Bool > any string. ALWAYS
043: * Bool.TRUE > Bool.FALSE
044: *
045: * String > any number. ALWAYS
046: * String > Blank. ALWAYS
047: * String are sorted dictionary wise
048: *
049: * Blank == 0 (numeric)
050: */
051: public RelationalValues doEvaluate(Eval[] operands, int srcRow,
052: short srcCol) {
053: RelationalValues retval = new RelationalValues();
054:
055: switch (operands.length) {
056: default:
057: retval.ee = ErrorEval.VALUE_INVALID;
058: break;
059: case 2:
060: internalDoEvaluate(operands, srcRow, srcCol, retval, 0);
061: internalDoEvaluate(operands, srcRow, srcCol, retval, 1);
062: } // end switch
063: return retval;
064: }
065:
066: /**
067: * convenience method to avoid code duplication for multiple operands
068: * @param operands
069: * @param srcRow
070: * @param srcCol
071: * @param retval
072: * @param index
073: */
074: private void internalDoEvaluate(Eval[] operands, int srcRow,
075: short srcCol, RelationalValues retval, int index) {
076: if (operands[index] instanceof BoolEval) {
077: BoolEval be = (BoolEval) operands[index];
078: retval.bs[index] = Boolean.valueOf(be.getBooleanValue());
079: } else if (operands[index] instanceof NumericValueEval) {
080: NumericValueEval ne = (NumericValueEval) operands[index];
081: retval.ds[index] = new Double(ne.getNumberValue());
082: } else if (operands[index] instanceof StringValueEval) {
083: StringValueEval se = (StringValueEval) operands[index];
084: retval.ss[index] = se.getStringValue();
085: } else if (operands[index] instanceof RefEval) {
086: RefEval re = (RefEval) operands[index];
087: ValueEval ve = re.getInnerValueEval();
088: if (ve instanceof BoolEval) {
089: BoolEval be = (BoolEval) ve;
090: retval.bs[index] = Boolean
091: .valueOf(be.getBooleanValue());
092: } else if (ve instanceof BlankEval) {
093: retval.ds[index] = new Double(0);
094: } else if (ve instanceof NumericValueEval) {
095: NumericValueEval ne = (NumericValueEval) ve;
096: retval.ds[index] = new Double(ne.getNumberValue());
097: } else if (ve instanceof StringValueEval) {
098: StringValueEval se = (StringValueEval) ve;
099: retval.ss[index] = se.getStringValue();
100: }
101: } else if (operands[index] instanceof AreaEval) {
102: AreaEval ae = (AreaEval) operands[index];
103: if (ae.isRow()) {
104: if (ae.containsColumn(srcCol)) {
105: ValueEval ve = ae.getValueAt(ae.getFirstRow(),
106: srcCol);
107: if (ve instanceof BoolEval) {
108: BoolEval be = (BoolEval) ve;
109: retval.bs[index] = Boolean.valueOf(be
110: .getBooleanValue());
111: } else if (ve instanceof BlankEval) {
112: retval.ds[index] = new Double(0);
113: } else if (ve instanceof NumericValueEval) {
114: NumericValueEval ne = (NumericValueEval) ve;
115: retval.ds[index] = new Double(ne
116: .getNumberValue());
117: } else if (ve instanceof StringValueEval) {
118: StringValueEval se = (StringValueEval) ve;
119: retval.ss[index] = se.getStringValue();
120: } else {
121: retval.ee = ErrorEval.VALUE_INVALID;
122: }
123: } else {
124: retval.ee = ErrorEval.VALUE_INVALID;
125: }
126: } else if (ae.isColumn()) {
127: if (ae.containsRow(srcRow)) {
128: ValueEval ve = ae.getValueAt(srcRow, ae
129: .getFirstColumn());
130: if (ve instanceof BoolEval) {
131: BoolEval be = (BoolEval) ve;
132: retval.bs[index] = Boolean.valueOf(be
133: .getBooleanValue());
134: } else if (ve instanceof BlankEval) {
135: retval.ds[index] = new Double(0);
136: } else if (ve instanceof NumericValueEval) {
137: NumericValueEval ne = (NumericValueEval) ve;
138: retval.ds[index] = new Double(ne
139: .getNumberValue());
140: } else if (ve instanceof StringValueEval) {
141: StringValueEval se = (StringValueEval) ve;
142: retval.ss[index] = se.getStringValue();
143: } else {
144: retval.ee = ErrorEval.VALUE_INVALID;
145: }
146: } else {
147: retval.ee = ErrorEval.VALUE_INVALID;
148: }
149: } else {
150: retval.ee = ErrorEval.VALUE_INVALID;
151: }
152: }
153: }
154:
155: // if both null return 0, else non null wins, else TRUE wins
156: protected int doComparison(Boolean[] bs) {
157: int retval = 0;
158: if (bs[0] != null || bs[1] != null) {
159: retval = bs[0] != null ? bs[1] != null ? bs[0]
160: .booleanValue() ? bs[1].booleanValue() ? 0 : 1
161: : bs[1].booleanValue() ? -1 : 0 : 1
162: : bs[1] != null ? -1 : 0;
163: }
164: return retval;
165: }
166:
167: // if both null return 0, else non null wins, else string compare
168: protected int doComparison(String[] ss) {
169: int retval = 0;
170: if (ss[0] != null || ss[1] != null) {
171: retval = ss[0] != null ? ss[1] != null ? ss[0]
172: .compareTo(ss[1]) : 1 : ss[1] != null ? -1 : 0;
173: }
174: return retval;
175: }
176:
177: // if both null return 0, else non null wins, else doublevalue compare
178: protected int doComparison(Double[] ds) {
179: int retval = 0;
180: if (ds[0] != null || ds[1] != null) {
181: retval = ds[0] != null ? ds[1] != null ? ds[0]
182: .compareTo(ds[1]) : 1 : ds[1] != null ? -1 : 0;
183: }
184: return retval;
185: }
186: }
|