whitespace

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1716060 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Javen O'Neal 2015-11-24 08:15:42 +00:00
parent d58342dd9f
commit e25f69814c

View File

@ -44,177 +44,177 @@ import org.apache.poi.ss.usermodel.FormulaError;
*/ */
public final class Countif extends Fixed2ArgFunction { public final class Countif extends Fixed2ArgFunction {
private static final class CmpOp { private static final class CmpOp {
public static final int NONE = 0; public static final int NONE = 0;
public static final int EQ = 1; public static final int EQ = 1;
public static final int NE = 2; public static final int NE = 2;
public static final int LE = 3; public static final int LE = 3;
public static final int LT = 4; public static final int LT = 4;
public static final int GT = 5; public static final int GT = 5;
public static final int GE = 6; public static final int GE = 6;
public static final CmpOp OP_NONE = op("", NONE); public static final CmpOp OP_NONE = op("", NONE);
public static final CmpOp OP_EQ = op("=", EQ); public static final CmpOp OP_EQ = op("=", EQ);
public static final CmpOp OP_NE = op("<>", NE); public static final CmpOp OP_NE = op("<>", NE);
public static final CmpOp OP_LE = op("<=", LE); public static final CmpOp OP_LE = op("<=", LE);
public static final CmpOp OP_LT = op("<", LT); public static final CmpOp OP_LT = op("<", LT);
public static final CmpOp OP_GT = op(">", GT); public static final CmpOp OP_GT = op(">", GT);
public static final CmpOp OP_GE = op(">=", GE); public static final CmpOp OP_GE = op(">=", GE);
private final String _representation; private final String _representation;
private final int _code; private final int _code;
private static CmpOp op(String rep, int code) { private static CmpOp op(String rep, int code) {
return new CmpOp(rep, code); return new CmpOp(rep, code);
} }
private CmpOp(String representation, int code) { private CmpOp(String representation, int code) {
_representation = representation; _representation = representation;
_code = code; _code = code;
} }
/** /**
* @return number of characters used to represent this operator * @return number of characters used to represent this operator
*/ */
public int getLength() { public int getLength() {
return _representation.length(); return _representation.length();
} }
public int getCode() { public int getCode() {
return _code; return _code;
} }
public static CmpOp getOperator(String value) { public static CmpOp getOperator(String value) {
int len = value.length(); int len = value.length();
if (len < 1) { if (len < 1) {
return OP_NONE; return OP_NONE;
} }
char firstChar = value.charAt(0); char firstChar = value.charAt(0);
switch(firstChar) { switch(firstChar) {
case '=': case '=':
return OP_EQ; return OP_EQ;
case '>': case '>':
if (len > 1) { if (len > 1) {
switch(value.charAt(1)) { switch(value.charAt(1)) {
case '=': case '=':
return OP_GE; return OP_GE;
} }
} }
return OP_GT; return OP_GT;
case '<': case '<':
if (len > 1) { if (len > 1) {
switch(value.charAt(1)) { switch(value.charAt(1)) {
case '=': case '=':
return OP_LE; return OP_LE;
case '>': case '>':
return OP_NE; return OP_NE;
} }
} }
return OP_LT; return OP_LT;
} }
return OP_NONE; return OP_NONE;
} }
public boolean evaluate(boolean cmpResult) { public boolean evaluate(boolean cmpResult) {
switch (_code) { switch (_code) {
case NONE: case NONE:
case EQ: case EQ:
return cmpResult; return cmpResult;
case NE: case NE:
return !cmpResult; return !cmpResult;
} }
throw new RuntimeException("Cannot call boolean evaluate on non-equality operator '" throw new RuntimeException("Cannot call boolean evaluate on non-equality operator '"
+ _representation + "'"); + _representation + "'");
} }
public boolean evaluate(int cmpResult) { public boolean evaluate(int cmpResult) {
switch (_code) { switch (_code) {
case NONE: case NONE:
case EQ: case EQ:
return cmpResult == 0; return cmpResult == 0;
case NE: return cmpResult != 0; case NE: return cmpResult != 0;
case LT: return cmpResult < 0; case LT: return cmpResult < 0;
case LE: return cmpResult <= 0; case LE: return cmpResult <= 0;
case GT: return cmpResult > 0; case GT: return cmpResult > 0;
case GE: return cmpResult >= 0; case GE: return cmpResult >= 0;
} }
throw new RuntimeException("Cannot call boolean evaluate on non-equality operator '" throw new RuntimeException("Cannot call boolean evaluate on non-equality operator '"
+ _representation + "'"); + _representation + "'");
} }
public String toString() { public String toString() {
StringBuffer sb = new StringBuffer(64); StringBuffer sb = new StringBuffer(64);
sb.append(getClass().getName()); sb.append(getClass().getName());
sb.append(" [").append(_representation).append("]"); sb.append(" [").append(_representation).append("]");
return sb.toString(); return sb.toString();
} }
public String getRepresentation() { public String getRepresentation() {
return _representation; return _representation;
} }
} }
private static abstract class MatcherBase implements I_MatchPredicate { private static abstract class MatcherBase implements I_MatchPredicate {
private final CmpOp _operator; private final CmpOp _operator;
MatcherBase(CmpOp operator) { MatcherBase(CmpOp operator) {
_operator = operator; _operator = operator;
} }
protected final int getCode() { protected final int getCode() {
return _operator.getCode(); return _operator.getCode();
} }
protected final boolean evaluate(int cmpResult) { protected final boolean evaluate(int cmpResult) {
return _operator.evaluate(cmpResult); return _operator.evaluate(cmpResult);
} }
protected final boolean evaluate(boolean cmpResult) { protected final boolean evaluate(boolean cmpResult) {
return _operator.evaluate(cmpResult); return _operator.evaluate(cmpResult);
} }
@Override @Override
public final String toString() { public final String toString() {
StringBuffer sb = new StringBuffer(64); StringBuffer sb = new StringBuffer(64);
sb.append(getClass().getName()).append(" ["); sb.append(getClass().getName()).append(" [");
sb.append(_operator.getRepresentation()); sb.append(_operator.getRepresentation());
sb.append(getValueText()); sb.append(getValueText());
sb.append("]"); sb.append("]");
return sb.toString(); return sb.toString();
} }
protected abstract String getValueText(); protected abstract String getValueText();
} }
private static final class NumberMatcher extends MatcherBase { private static final class NumberMatcher extends MatcherBase {
private final double _value; private final double _value;
public NumberMatcher(double value, CmpOp operator) { public NumberMatcher(double value, CmpOp operator) {
super(operator); super(operator);
_value = value; _value = value;
} }
@Override @Override
protected String getValueText() { protected String getValueText() {
return String.valueOf(_value); return String.valueOf(_value);
} }
public boolean matches(ValueEval x) { public boolean matches(ValueEval x) {
double testValue; double testValue;
if(x instanceof StringEval) { if(x instanceof StringEval) {
// if the target(x) is a string, but parses as a number // if the target(x) is a string, but parses as a number
// it may still count as a match, only for the equality operator // it may still count as a match, only for the equality operator
switch (getCode()) { switch (getCode()) {
case CmpOp.EQ: case CmpOp.EQ:
case CmpOp.NONE: case CmpOp.NONE:
break; break;
case CmpOp.NE: case CmpOp.NE:
// Always matches (inconsistent with above two cases). // Always matches (inconsistent with above two cases).
// for example '<>123' matches '123', '4', 'abc', etc // for example '<>123' matches '123', '4', 'abc', etc
return true; return true;
default: default:
// never matches (also inconsistent with above three cases). // never matches (also inconsistent with above three cases).
// for example '>5' does not match '6', // for example '>5' does not match '6',
return false; return false;
} }
StringEval se = (StringEval)x; StringEval se = (StringEval)x;
Double val = OperandResolver.parseDouble(se.getStringValue()); Double val = OperandResolver.parseDouble(se.getStringValue());
if(val == null) { if(val == null) {
// x is text that is not a number // x is text that is not a number
return false; return false;
} }
return _value == val.doubleValue(); return _value == val.doubleValue();
} else if((x instanceof NumberEval)) { } else if((x instanceof NumberEval)) {
NumberEval ne = (NumberEval) x; NumberEval ne = (NumberEval) x;
testValue = ne.getNumberValue(); testValue = ne.getNumberValue();
} else if((x instanceof BlankEval)) { } else if((x instanceof BlankEval)) {
switch (getCode()) { switch (getCode()) {
case CmpOp.NE: case CmpOp.NE:
@ -223,48 +223,48 @@ public final class Countif extends Fixed2ArgFunction {
default: default:
return false; return false;
} }
} else { } else {
return false; return false;
} }
return evaluate(Double.compare(testValue, _value)); return evaluate(Double.compare(testValue, _value));
} }
} }
private static final class BooleanMatcher extends MatcherBase { private static final class BooleanMatcher extends MatcherBase {
private final int _value; private final int _value;
public BooleanMatcher(boolean value, CmpOp operator) { public BooleanMatcher(boolean value, CmpOp operator) {
super(operator); super(operator);
_value = boolToInt(value); _value = boolToInt(value);
} }
@Override @Override
protected String getValueText() { protected String getValueText() {
return _value == 1 ? "TRUE" : "FALSE"; return _value == 1 ? "TRUE" : "FALSE";
} }
private static int boolToInt(boolean value) { private static int boolToInt(boolean value) {
return value ? 1 : 0; return value ? 1 : 0;
} }
public boolean matches(ValueEval x) { public boolean matches(ValueEval x) {
int testValue; int testValue;
if(x instanceof StringEval) { if(x instanceof StringEval) {
if (true) { // change to false to observe more intuitive behaviour if (true) { // change to false to observe more intuitive behaviour
// Note - Unlike with numbers, it seems that COUNTIF never matches // Note - Unlike with numbers, it seems that COUNTIF never matches
// boolean values when the target(x) is a string // boolean values when the target(x) is a string
return false; return false;
} }
@SuppressWarnings("unused") @SuppressWarnings("unused")
StringEval se = (StringEval)x; StringEval se = (StringEval)x;
Boolean val = parseBoolean(se.getStringValue()); Boolean val = parseBoolean(se.getStringValue());
if(val == null) { if(val == null) {
// x is text that is not a boolean // x is text that is not a boolean
return false; return false;
} }
testValue = boolToInt(val.booleanValue()); testValue = boolToInt(val.booleanValue());
} else if((x instanceof BoolEval)) { } else if((x instanceof BoolEval)) {
BoolEval be = (BoolEval) x; BoolEval be = (BoolEval) x;
testValue = boolToInt(be.getBooleanValue()); testValue = boolToInt(be.getBooleanValue());
} else if((x instanceof BlankEval)) { } else if((x instanceof BlankEval)) {
switch (getCode()) { switch (getCode()) {
case CmpOp.NE: case CmpOp.NE:
@ -282,280 +282,280 @@ public final class Countif extends Fixed2ArgFunction {
return false; return false;
} }
} else { } else {
return false; return false;
} }
return evaluate(testValue - _value); return evaluate(testValue - _value);
} }
} }
public static final class ErrorMatcher extends MatcherBase { public static final class ErrorMatcher extends MatcherBase {
private final int _value; private final int _value;
public ErrorMatcher(int errorCode, CmpOp operator) { public ErrorMatcher(int errorCode, CmpOp operator) {
super(operator); super(operator);
_value = errorCode; _value = errorCode;
} }
@Override @Override
protected String getValueText() { protected String getValueText() {
return FormulaError.forInt(_value).getString(); return FormulaError.forInt(_value).getString();
} }
public boolean matches(ValueEval x) { public boolean matches(ValueEval x) {
if(x instanceof ErrorEval) { if(x instanceof ErrorEval) {
int testValue = ((ErrorEval)x).getErrorCode(); int testValue = ((ErrorEval)x).getErrorCode();
return evaluate(testValue - _value); return evaluate(testValue - _value);
} }
return false; return false;
} }
public int getValue() { public int getValue() {
return _value; return _value;
} }
} }
public static final class StringMatcher extends MatcherBase { public static final class StringMatcher extends MatcherBase {
private final String _value; private final String _value;
private final Pattern _pattern; private final Pattern _pattern;
public StringMatcher(String value, CmpOp operator) { public StringMatcher(String value, CmpOp operator) {
super(operator); super(operator);
_value = value; _value = value;
switch(operator.getCode()) { switch(operator.getCode()) {
case CmpOp.NONE: case CmpOp.NONE:
case CmpOp.EQ: case CmpOp.EQ:
case CmpOp.NE: case CmpOp.NE:
_pattern = getWildCardPattern(value); _pattern = getWildCardPattern(value);
break; break;
default: default:
// pattern matching is never used for < > <= => // pattern matching is never used for < > <= =>
_pattern = null; _pattern = null;
} }
} }
@Override @Override
protected String getValueText() { protected String getValueText() {
if (_pattern == null) { if (_pattern == null) {
return _value; return _value;
} }
return _pattern.pattern(); return _pattern.pattern();
} }
public boolean matches(ValueEval x) { public boolean matches(ValueEval x) {
if (x instanceof BlankEval) { if (x instanceof BlankEval) {
switch(getCode()) { switch(getCode()) {
case CmpOp.NONE: case CmpOp.NONE:
case CmpOp.EQ: case CmpOp.EQ:
return _value.length() == 0; return _value.length() == 0;
case CmpOp.NE: case CmpOp.NE:
// pred '<>' matches empty string but not blank cell // pred '<>' matches empty string but not blank cell
// pred '<>ABC' matches blank and 'not ABC' // pred '<>ABC' matches blank and 'not ABC'
return _value.length() != 0; return _value.length() != 0;
} }
// no other criteria matches a blank cell // no other criteria matches a blank cell
return false; return false;
} }
if(!(x instanceof StringEval)) { if(!(x instanceof StringEval)) {
// must always be string // must always be string
// even if match str is wild, but contains only digits // even if match str is wild, but contains only digits
// e.g. '4*7', NumberEval(4567) does not match // e.g. '4*7', NumberEval(4567) does not match
return false; return false;
} }
String testedValue = ((StringEval) x).getStringValue(); String testedValue = ((StringEval) x).getStringValue();
if (testedValue.length() < 1 && _value.length() < 1) { if (testedValue.length() < 1 && _value.length() < 1) {
// odd case: criteria '=' behaves differently to criteria '' // odd case: criteria '=' behaves differently to criteria ''
switch(getCode()) { switch(getCode()) {
case CmpOp.NONE: return true; case CmpOp.NONE: return true;
case CmpOp.EQ: return false; case CmpOp.EQ: return false;
case CmpOp.NE: return true; case CmpOp.NE: return true;
} }
return false; return false;
} }
if (_pattern != null) { if (_pattern != null) {
return evaluate(_pattern.matcher(testedValue).matches()); return evaluate(_pattern.matcher(testedValue).matches());
} }
// String criteria in COUNTIF are case insensitive: // String criteria in COUNTIF are case insensitive:
// for example, the string "apples" and the string "APPLES" will match the same cells. // for example, the string "apples" and the string "APPLES" will match the same cells.
return evaluate(testedValue.compareToIgnoreCase(_value)); return evaluate(testedValue.compareToIgnoreCase(_value));
} }
/** /**
* Translates Excel countif wildcard strings into java regex strings * Translates Excel countif wildcard strings into java regex strings
* @return <code>null</code> if the specified value contains no special wildcard characters. * @return <code>null</code> if the specified value contains no special wildcard characters.
*/ */
public static Pattern getWildCardPattern(String value) { public static Pattern getWildCardPattern(String value) {
int len = value.length(); int len = value.length();
StringBuffer sb = new StringBuffer(len); StringBuffer sb = new StringBuffer(len);
boolean hasWildCard = false; boolean hasWildCard = false;
for(int i=0; i<len; i++) { for(int i=0; i<len; i++) {
char ch = value.charAt(i); char ch = value.charAt(i);
switch(ch) { switch(ch) {
case '?': //Any single character case '?': //Any single character
hasWildCard = true; hasWildCard = true;
// match exactly one character // match exactly one character
sb.append('.'); sb.append('.');
continue; continue;
case '*': //Zero or more characters case '*': //Zero or more characters
hasWildCard = true; hasWildCard = true;
// match one or more occurrences of any character // match one or more occurrences of any character
sb.append(".*"); sb.append(".*");
continue; continue;
case '~': case '~':
if (i+1<len) { if (i+1<len) {
ch = value.charAt(i+1); ch = value.charAt(i+1);
switch (ch) { switch (ch) {
case '?': case '?':
case '*': case '*':
hasWildCard = true; hasWildCard = true;
sb.append('[').append(ch).append(']'); sb.append('[').append(ch).append(']');
i++; // Note - incrementing loop variable here i++; // Note - incrementing loop variable here
continue; continue;
} }
} }
// else not '~?' or '~*' // else not '~?' or '~*'
sb.append('~'); // just plain '~' sb.append('~'); // just plain '~'
continue; continue;
case '.': case '.':
case '$': case '$':
case '^': case '^':
case '[': case '[':
case ']': case ']':
case '(': case '(':
case ')': case ')':
// escape literal characters that would have special meaning in regex // escape literal characters that would have special meaning in regex
sb.append("\\").append(ch); sb.append("\\").append(ch);
continue; continue;
} }
sb.append(ch); sb.append(ch);
} }
if (hasWildCard) { if (hasWildCard) {
return Pattern.compile(sb.toString(), Pattern.CASE_INSENSITIVE); return Pattern.compile(sb.toString(), Pattern.CASE_INSENSITIVE);
} }
return null; return null;
} }
} }
public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) { public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) {
I_MatchPredicate mp = createCriteriaPredicate(arg1, srcRowIndex, srcColumnIndex); I_MatchPredicate mp = createCriteriaPredicate(arg1, srcRowIndex, srcColumnIndex);
if(mp == null) { if(mp == null) {
// If the criteria arg is a reference to a blank cell, countif always returns zero. // If the criteria arg is a reference to a blank cell, countif always returns zero.
return NumberEval.ZERO; return NumberEval.ZERO;
} }
double result = countMatchingCellsInArea(arg0, mp); double result = countMatchingCellsInArea(arg0, mp);
return new NumberEval(result); return new NumberEval(result);
} }
/** /**
* @return the number of evaluated cells in the range that match the specified criteria * @return the number of evaluated cells in the range that match the specified criteria
*/ */
private double countMatchingCellsInArea(ValueEval rangeArg, I_MatchPredicate criteriaPredicate) { private double countMatchingCellsInArea(ValueEval rangeArg, I_MatchPredicate criteriaPredicate) {
if (rangeArg instanceof RefEval) { if (rangeArg instanceof RefEval) {
return CountUtils.countMatchingCellsInRef((RefEval) rangeArg, criteriaPredicate); return CountUtils.countMatchingCellsInRef((RefEval) rangeArg, criteriaPredicate);
} else if (rangeArg instanceof ThreeDEval) { } else if (rangeArg instanceof ThreeDEval) {
return CountUtils.countMatchingCellsInArea((ThreeDEval) rangeArg, criteriaPredicate); return CountUtils.countMatchingCellsInArea((ThreeDEval) rangeArg, criteriaPredicate);
} else { } else {
throw new IllegalArgumentException("Bad range arg type (" + rangeArg.getClass().getName() + ")"); throw new IllegalArgumentException("Bad range arg type (" + rangeArg.getClass().getName() + ")");
} }
} }
/** /**
* Creates a criteria predicate object for the supplied criteria arg * Creates a criteria predicate object for the supplied criteria arg
* @return <code>null</code> if the arg evaluates to blank. * @return <code>null</code> if the arg evaluates to blank.
*/ */
/* package */ static I_MatchPredicate createCriteriaPredicate(ValueEval arg, int srcRowIndex, int srcColumnIndex) { /* package */ static I_MatchPredicate createCriteriaPredicate(ValueEval arg, int srcRowIndex, int srcColumnIndex) {
ValueEval evaluatedCriteriaArg = evaluateCriteriaArg(arg, srcRowIndex, srcColumnIndex); ValueEval evaluatedCriteriaArg = evaluateCriteriaArg(arg, srcRowIndex, srcColumnIndex);
if(evaluatedCriteriaArg instanceof NumberEval) { if(evaluatedCriteriaArg instanceof NumberEval) {
return new NumberMatcher(((NumberEval)evaluatedCriteriaArg).getNumberValue(), CmpOp.OP_NONE); return new NumberMatcher(((NumberEval)evaluatedCriteriaArg).getNumberValue(), CmpOp.OP_NONE);
} }
if(evaluatedCriteriaArg instanceof BoolEval) { if(evaluatedCriteriaArg instanceof BoolEval) {
return new BooleanMatcher(((BoolEval)evaluatedCriteriaArg).getBooleanValue(), CmpOp.OP_NONE); return new BooleanMatcher(((BoolEval)evaluatedCriteriaArg).getBooleanValue(), CmpOp.OP_NONE);
} }
if(evaluatedCriteriaArg instanceof StringEval) { if(evaluatedCriteriaArg instanceof StringEval) {
return createGeneralMatchPredicate((StringEval)evaluatedCriteriaArg); return createGeneralMatchPredicate((StringEval)evaluatedCriteriaArg);
} }
if(evaluatedCriteriaArg instanceof ErrorEval) { if(evaluatedCriteriaArg instanceof ErrorEval) {
return new ErrorMatcher(((ErrorEval)evaluatedCriteriaArg).getErrorCode(), CmpOp.OP_NONE); return new ErrorMatcher(((ErrorEval)evaluatedCriteriaArg).getErrorCode(), CmpOp.OP_NONE);
} }
if(evaluatedCriteriaArg == BlankEval.instance) { if(evaluatedCriteriaArg == BlankEval.instance) {
return null; return null;
} }
throw new RuntimeException("Unexpected type for criteria (" throw new RuntimeException("Unexpected type for criteria ("
+ evaluatedCriteriaArg.getClass().getName() + ")"); + evaluatedCriteriaArg.getClass().getName() + ")");
} }
/** /**
* *
* @return the de-referenced criteria arg (possibly {@link ErrorEval}) * @return the de-referenced criteria arg (possibly {@link ErrorEval})
*/ */
private static ValueEval evaluateCriteriaArg(ValueEval arg, int srcRowIndex, int srcColumnIndex) { private static ValueEval evaluateCriteriaArg(ValueEval arg, int srcRowIndex, int srcColumnIndex) {
try { try {
return OperandResolver.getSingleValue(arg, srcRowIndex, srcColumnIndex); return OperandResolver.getSingleValue(arg, srcRowIndex, srcColumnIndex);
} catch (EvaluationException e) { } catch (EvaluationException e) {
return e.getErrorEval(); return e.getErrorEval();
} }
} }
/** /**
* When the second argument is a string, many things are possible * When the second argument is a string, many things are possible
*/ */
private static I_MatchPredicate createGeneralMatchPredicate(StringEval stringEval) { private static I_MatchPredicate createGeneralMatchPredicate(StringEval stringEval) {
String value = stringEval.getStringValue(); String value = stringEval.getStringValue();
CmpOp operator = CmpOp.getOperator(value); CmpOp operator = CmpOp.getOperator(value);
value = value.substring(operator.getLength()); value = value.substring(operator.getLength());
Boolean booleanVal = parseBoolean(value); Boolean booleanVal = parseBoolean(value);
if(booleanVal != null) { if(booleanVal != null) {
return new BooleanMatcher(booleanVal.booleanValue(), operator); return new BooleanMatcher(booleanVal.booleanValue(), operator);
} }
Double doubleVal = OperandResolver.parseDouble(value); Double doubleVal = OperandResolver.parseDouble(value);
if(doubleVal != null) { if(doubleVal != null) {
return new NumberMatcher(doubleVal.doubleValue(), operator); return new NumberMatcher(doubleVal.doubleValue(), operator);
} }
ErrorEval ee = parseError(value); ErrorEval ee = parseError(value);
if (ee != null) { if (ee != null) {
return new ErrorMatcher(ee.getErrorCode(), operator); return new ErrorMatcher(ee.getErrorCode(), operator);
} }
//else - just a plain string with no interpretation. //else - just a plain string with no interpretation.
return new StringMatcher(value, operator); return new StringMatcher(value, operator);
} }
private static ErrorEval parseError(String value) { private static ErrorEval parseError(String value) {
if (value.length() < 4 || value.charAt(0) != '#') { if (value.length() < 4 || value.charAt(0) != '#') {
return null; return null;
} }
if (value.equals("#NULL!")) return ErrorEval.NULL_INTERSECTION; if (value.equals("#NULL!")) return ErrorEval.NULL_INTERSECTION;
if (value.equals("#DIV/0!")) return ErrorEval.DIV_ZERO; if (value.equals("#DIV/0!")) return ErrorEval.DIV_ZERO;
if (value.equals("#VALUE!")) return ErrorEval.VALUE_INVALID; if (value.equals("#VALUE!")) return ErrorEval.VALUE_INVALID;
if (value.equals("#REF!")) return ErrorEval.REF_INVALID; if (value.equals("#REF!")) return ErrorEval.REF_INVALID;
if (value.equals("#NAME?")) return ErrorEval.NAME_INVALID; if (value.equals("#NAME?")) return ErrorEval.NAME_INVALID;
if (value.equals("#NUM!")) return ErrorEval.NUM_ERROR; if (value.equals("#NUM!")) return ErrorEval.NUM_ERROR;
if (value.equals("#N/A")) return ErrorEval.NA; if (value.equals("#N/A")) return ErrorEval.NA;
return null; return null;
} }
/** /**
* Boolean literals ('TRUE', 'FALSE') treated similarly but NOT same as numbers. * Boolean literals ('TRUE', 'FALSE') treated similarly but NOT same as numbers.
*/ */
/* package */ static Boolean parseBoolean(String strRep) { /* package */ static Boolean parseBoolean(String strRep) {
if (strRep.length() < 1) { if (strRep.length() < 1) {
return null; return null;
} }
switch(strRep.charAt(0)) { switch(strRep.charAt(0)) {
case 't': case 't':
case 'T': case 'T':
if("TRUE".equalsIgnoreCase(strRep)) { if("TRUE".equalsIgnoreCase(strRep)) {
return Boolean.TRUE; return Boolean.TRUE;
} }
break; break;
case 'f': case 'f':
case 'F': case 'F':
if("FALSE".equalsIgnoreCase(strRep)) { if("FALSE".equalsIgnoreCase(strRep)) {
return Boolean.FALSE; return Boolean.FALSE;
} }
break; break;
} }
return null; return null;
} }
} }