You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by fa...@apache.org on 2021/05/22 20:56:49 UTC
svn commit: r1890120 [18/43] - in /poi/trunk/poi/src:
main/java/org/apache/poi/ main/java/org/apache/poi/ddf/
main/java/org/apache/poi/extractor/ main/java/org/apache/poi/hpsf/
main/java/org/apache/poi/hssf/ main/java/org/apache/poi/hssf/dev/
main/java...
Modified: poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/eval/RelationalOperationEval.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/eval/RelationalOperationEval.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/eval/RelationalOperationEval.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/eval/RelationalOperationEval.java Sat May 22 20:56:44 2021
@@ -27,154 +27,154 @@ import org.apache.poi.ss.util.NumberComp
*/
public abstract class RelationalOperationEval extends Fixed2ArgFunction implements ArrayFunction {
- /**
- * 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 ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) {
-
- ValueEval vA;
- ValueEval vB;
- try {
- vA = OperandResolver.getSingleValue(arg0, srcRowIndex, srcColumnIndex);
- vB = OperandResolver.getSingleValue(arg1, srcRowIndex, srcColumnIndex);
- } catch (EvaluationException e) {
- return e.getErrorEval();
- }
- int cmpResult = doCompare(vA, vB);
- boolean result = convertComparisonResult(cmpResult);
- return BoolEval.valueOf(result);
- }
-
- @Override
- public ValueEval evaluateArray(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
- ValueEval arg0 = args[0];
- ValueEval arg1 = args[1];
- return evaluateTwoArrayArgs(arg0, arg1, srcRowIndex, srcColumnIndex, (vA, vB) -> {
- 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 or missing
- if (va == BlankEval.instance || va instanceof MissingArgEval) {
- return compareBlank(vb);
- }
- if (vb == BlankEval.instance || vb instanceof MissingArgEval) {
- 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().compareToIgnoreCase(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 NumberComparer.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 || v instanceof MissingArgEval) {
- return 0;
- }
- if (v instanceof BoolEval) {
- BoolEval boolEval = (BoolEval) v;
- return boolEval.getBooleanValue() ? -1 : 0;
- }
- if (v instanceof NumberEval) {
- NumberEval ne = (NumberEval) v;
- return NumberComparer.compare(0.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 static final Function EqualEval = new RelationalOperationEval() {
- protected boolean convertComparisonResult(int cmpResult) {
- return cmpResult == 0;
- }
- };
- public static final Function GreaterEqualEval = new RelationalOperationEval() {
- protected boolean convertComparisonResult(int cmpResult) {
- return cmpResult >= 0;
- }
- };
- public static final Function GreaterThanEval = new RelationalOperationEval() {
- protected boolean convertComparisonResult(int cmpResult) {
- return cmpResult > 0;
- }
- };
- public static final Function LessEqualEval = new RelationalOperationEval() {
- protected boolean convertComparisonResult(int cmpResult) {
- return cmpResult <= 0;
- }
- };
- public static final Function LessThanEval = new RelationalOperationEval() {
- protected boolean convertComparisonResult(int cmpResult) {
- return cmpResult < 0;
- }
- };
- public static final Function NotEqualEval = new RelationalOperationEval() {
- protected boolean convertComparisonResult(int cmpResult) {
- return cmpResult != 0;
- }
- };
+ /**
+ * 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 ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) {
+
+ ValueEval vA;
+ ValueEval vB;
+ try {
+ vA = OperandResolver.getSingleValue(arg0, srcRowIndex, srcColumnIndex);
+ vB = OperandResolver.getSingleValue(arg1, srcRowIndex, srcColumnIndex);
+ } catch (EvaluationException e) {
+ return e.getErrorEval();
+ }
+ int cmpResult = doCompare(vA, vB);
+ boolean result = convertComparisonResult(cmpResult);
+ return BoolEval.valueOf(result);
+ }
+
+ @Override
+ public ValueEval evaluateArray(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
+ ValueEval arg0 = args[0];
+ ValueEval arg1 = args[1];
+ return evaluateTwoArrayArgs(arg0, arg1, srcRowIndex, srcColumnIndex, (vA, vB) -> {
+ 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 or missing
+ if (va == BlankEval.instance || va instanceof MissingArgEval) {
+ return compareBlank(vb);
+ }
+ if (vb == BlankEval.instance || vb instanceof MissingArgEval) {
+ 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().compareToIgnoreCase(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 NumberComparer.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 || v instanceof MissingArgEval) {
+ return 0;
+ }
+ if (v instanceof BoolEval) {
+ BoolEval boolEval = (BoolEval) v;
+ return boolEval.getBooleanValue() ? -1 : 0;
+ }
+ if (v instanceof NumberEval) {
+ NumberEval ne = (NumberEval) v;
+ return NumberComparer.compare(0.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 static final Function EqualEval = new RelationalOperationEval() {
+ protected boolean convertComparisonResult(int cmpResult) {
+ return cmpResult == 0;
+ }
+ };
+ public static final Function GreaterEqualEval = new RelationalOperationEval() {
+ protected boolean convertComparisonResult(int cmpResult) {
+ return cmpResult >= 0;
+ }
+ };
+ public static final Function GreaterThanEval = new RelationalOperationEval() {
+ protected boolean convertComparisonResult(int cmpResult) {
+ return cmpResult > 0;
+ }
+ };
+ public static final Function LessEqualEval = new RelationalOperationEval() {
+ protected boolean convertComparisonResult(int cmpResult) {
+ return cmpResult <= 0;
+ }
+ };
+ public static final Function LessThanEval = new RelationalOperationEval() {
+ protected boolean convertComparisonResult(int cmpResult) {
+ return cmpResult < 0;
+ }
+ };
+ public static final Function NotEqualEval = new RelationalOperationEval() {
+ protected boolean convertComparisonResult(int cmpResult) {
+ return cmpResult != 0;
+ }
+ };
}
Modified: poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/eval/StringEval.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/eval/StringEval.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/eval/StringEval.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/eval/StringEval.java Sat May 22 20:56:44 2021
@@ -24,29 +24,29 @@ import org.apache.poi.ss.formula.ptg.Str
public final class StringEval implements StringValueEval {
- public static final StringEval EMPTY_INSTANCE = new StringEval("");
+ public static final StringEval EMPTY_INSTANCE = new StringEval("");
- //@NotNull
- private final String _value;
+ //@NotNull
+ private final String _value;
- public StringEval(Ptg ptg) {
- this(((StringPtg) ptg).getValue());
- }
-
- public StringEval(String value) {
- if (value == null) {
- throw new IllegalArgumentException("value must not be null");
- }
- _value = value;
- }
-
- public String getStringValue() {
- return _value;
- }
-
- public String toString() {
- return getClass().getName() + " [" +
- _value +
- "]";
- }
+ public StringEval(Ptg ptg) {
+ this(((StringPtg) ptg).getValue());
+ }
+
+ public StringEval(String value) {
+ if (value == null) {
+ throw new IllegalArgumentException("value must not be null");
+ }
+ _value = value;
+ }
+
+ public String getStringValue() {
+ return _value;
+ }
+
+ public String toString() {
+ return getClass().getName() + " [" +
+ _value +
+ "]";
+ }
}
Modified: poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/eval/TwoOperandNumericOperation.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/eval/TwoOperandNumericOperation.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/eval/TwoOperandNumericOperation.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/eval/TwoOperandNumericOperation.java Sat May 22 20:56:44 2021
@@ -23,94 +23,94 @@ import org.apache.poi.ss.formula.functio
public abstract class TwoOperandNumericOperation extends Fixed2ArgFunction implements ArrayFunction {
- protected final double singleOperandEvaluate(ValueEval arg, int srcCellRow, int srcCellCol) throws EvaluationException {
- ValueEval ve = OperandResolver.getSingleValue(arg, srcCellRow, srcCellCol);
- return OperandResolver.coerceValueToDouble(ve);
- }
+ protected final double singleOperandEvaluate(ValueEval arg, int srcCellRow, int srcCellCol) throws EvaluationException {
+ ValueEval ve = OperandResolver.getSingleValue(arg, srcCellRow, srcCellCol);
+ return OperandResolver.coerceValueToDouble(ve);
+ }
- @Override
+ @Override
public ValueEval evaluateArray(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
- if (args.length != 2) {
- return ErrorEval.VALUE_INVALID;
- }
- //return new ArrayEval().evaluate(srcRowIndex, srcColumnIndex, args[0], args[1]);
-
- return evaluateTwoArrayArgs(args[0], args[1], srcRowIndex, srcColumnIndex,
- (vA, vB) -> {
- try {
- double d0 = OperandResolver.coerceValueToDouble(vA);
- double d1 = OperandResolver.coerceValueToDouble(vB);
- double result = evaluate(d0, d1);
- return new NumberEval(result);
- } catch (EvaluationException e){
- return e.getErrorEval();
- }
- });
-
- }
-
- @Override
- public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) {
- double result;
- try {
- double d0 = singleOperandEvaluate(arg0, srcRowIndex, srcColumnIndex);
- double d1 = singleOperandEvaluate(arg1, srcRowIndex, srcColumnIndex);
- result = evaluate(d0, d1);
- if (result == 0.0) { // this '==' matches +0.0 and -0.0
- // Excel converts -0.0 to +0.0 for '*', '/', '%', '+' and '^'
- if (!(this instanceof SubtractEvalClass)) {
- return NumberEval.ZERO;
- }
- }
- if (Double.isNaN(result) || Double.isInfinite(result)) {
- return ErrorEval.NUM_ERROR;
- }
- } catch (EvaluationException e) {
- return e.getErrorEval();
- }
- return new NumberEval(result);
- }
-
- protected abstract double evaluate(double d0, double d1) throws EvaluationException;
-
- public static final Function AddEval = new TwoOperandNumericOperation() {
- @Override
- protected double evaluate(double d0, double d1) {
- return d0+d1;
- }
- };
- public static final Function DivideEval = new TwoOperandNumericOperation() {
- @Override
- protected double evaluate(double d0, double d1) throws EvaluationException {
- if (d1 == 0.0) {
- throw new EvaluationException(ErrorEval.DIV_ZERO);
- }
- return d0/d1;
- }
- };
- public static final Function MultiplyEval = new TwoOperandNumericOperation() {
- @Override
- protected double evaluate(double d0, double d1) {
- return d0*d1;
- }
- };
- public static final Function PowerEval = new TwoOperandNumericOperation() {
- @Override
- protected double evaluate(double d0, double d1) {
- if(d0 < 0 && Math.abs(d1) > 0.0 && Math.abs(d1) < 1.0) {
- return -1 * Math.pow(d0 * -1, d1);
- }
- return Math.pow(d0, d1);
- }
- };
- private static final class SubtractEvalClass extends TwoOperandNumericOperation {
- public SubtractEvalClass() {
- //
- }
- @Override
- protected double evaluate(double d0, double d1) {
- return d0-d1;
- }
- }
- public static final Function SubtractEval = new SubtractEvalClass();
+ if (args.length != 2) {
+ return ErrorEval.VALUE_INVALID;
+ }
+ //return new ArrayEval().evaluate(srcRowIndex, srcColumnIndex, args[0], args[1]);
+
+ return evaluateTwoArrayArgs(args[0], args[1], srcRowIndex, srcColumnIndex,
+ (vA, vB) -> {
+ try {
+ double d0 = OperandResolver.coerceValueToDouble(vA);
+ double d1 = OperandResolver.coerceValueToDouble(vB);
+ double result = evaluate(d0, d1);
+ return new NumberEval(result);
+ } catch (EvaluationException e){
+ return e.getErrorEval();
+ }
+ });
+
+ }
+
+ @Override
+ public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) {
+ double result;
+ try {
+ double d0 = singleOperandEvaluate(arg0, srcRowIndex, srcColumnIndex);
+ double d1 = singleOperandEvaluate(arg1, srcRowIndex, srcColumnIndex);
+ result = evaluate(d0, d1);
+ if (result == 0.0) { // this '==' matches +0.0 and -0.0
+ // Excel converts -0.0 to +0.0 for '*', '/', '%', '+' and '^'
+ if (!(this instanceof SubtractEvalClass)) {
+ return NumberEval.ZERO;
+ }
+ }
+ if (Double.isNaN(result) || Double.isInfinite(result)) {
+ return ErrorEval.NUM_ERROR;
+ }
+ } catch (EvaluationException e) {
+ return e.getErrorEval();
+ }
+ return new NumberEval(result);
+ }
+
+ protected abstract double evaluate(double d0, double d1) throws EvaluationException;
+
+ public static final Function AddEval = new TwoOperandNumericOperation() {
+ @Override
+ protected double evaluate(double d0, double d1) {
+ return d0+d1;
+ }
+ };
+ public static final Function DivideEval = new TwoOperandNumericOperation() {
+ @Override
+ protected double evaluate(double d0, double d1) throws EvaluationException {
+ if (d1 == 0.0) {
+ throw new EvaluationException(ErrorEval.DIV_ZERO);
+ }
+ return d0/d1;
+ }
+ };
+ public static final Function MultiplyEval = new TwoOperandNumericOperation() {
+ @Override
+ protected double evaluate(double d0, double d1) {
+ return d0*d1;
+ }
+ };
+ public static final Function PowerEval = new TwoOperandNumericOperation() {
+ @Override
+ protected double evaluate(double d0, double d1) {
+ if(d0 < 0 && Math.abs(d1) > 0.0 && Math.abs(d1) < 1.0) {
+ return -1 * Math.pow(d0 * -1, d1);
+ }
+ return Math.pow(d0, d1);
+ }
+ };
+ private static final class SubtractEvalClass extends TwoOperandNumericOperation {
+ public SubtractEvalClass() {
+ //
+ }
+ @Override
+ protected double evaluate(double d0, double d1) {
+ return d0-d1;
+ }
+ }
+ public static final Function SubtractEval = new SubtractEvalClass();
}
Modified: poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/eval/UnaryMinusEval.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/eval/UnaryMinusEval.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/eval/UnaryMinusEval.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/eval/UnaryMinusEval.java Sat May 22 20:56:44 2021
@@ -23,34 +23,34 @@ import org.apache.poi.ss.formula.functio
public final class UnaryMinusEval extends Fixed1ArgFunction implements ArrayFunction {
- public static final Function instance = new UnaryMinusEval();
+ public static final Function instance = new UnaryMinusEval();
- private UnaryMinusEval() {
- // enforce singleton
- }
-
- public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) {
- double d;
- try {
- ValueEval ve = OperandResolver.getSingleValue(arg0, srcRowIndex, srcColumnIndex);
- d = OperandResolver.coerceValueToDouble(ve);
- } catch (EvaluationException e) {
- return e.getErrorEval();
- }
- if (d == 0.0) { // this '==' matches +0.0 and -0.0
- return NumberEval.ZERO;
- }
- return new NumberEval(-d);
- }
-
- @Override
- public ValueEval evaluateArray(ValueEval[] args, int srcRowIndex, int srcColumnIndex){
- if (args.length != 1) {
- return ErrorEval.VALUE_INVALID;
- }
- return evaluateOneArrayArg(args[0], srcRowIndex, srcColumnIndex, (valA) ->
- evaluate(srcRowIndex, srcColumnIndex, valA)
- );
- }
+ private UnaryMinusEval() {
+ // enforce singleton
+ }
+
+ public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) {
+ double d;
+ try {
+ ValueEval ve = OperandResolver.getSingleValue(arg0, srcRowIndex, srcColumnIndex);
+ d = OperandResolver.coerceValueToDouble(ve);
+ } catch (EvaluationException e) {
+ return e.getErrorEval();
+ }
+ if (d == 0.0) { // this '==' matches +0.0 and -0.0
+ return NumberEval.ZERO;
+ }
+ return new NumberEval(-d);
+ }
+
+ @Override
+ public ValueEval evaluateArray(ValueEval[] args, int srcRowIndex, int srcColumnIndex){
+ if (args.length != 1) {
+ return ErrorEval.VALUE_INVALID;
+ }
+ return evaluateOneArrayArg(args[0], srcRowIndex, srcColumnIndex, (valA) ->
+ evaluate(srcRowIndex, srcColumnIndex, valA)
+ );
+ }
}
Modified: poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/eval/UnaryPlusEval.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/eval/UnaryPlusEval.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/eval/UnaryPlusEval.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/eval/UnaryPlusEval.java Sat May 22 20:56:44 2021
@@ -24,37 +24,37 @@ import org.apache.poi.ss.formula.functio
public final class UnaryPlusEval extends Fixed1ArgFunction implements ArrayFunction {
- public static final Function instance = new UnaryPlusEval();
+ public static final Function instance = new UnaryPlusEval();
- private UnaryPlusEval() {
- // enforce singleton
- }
-
- public ValueEval evaluate(int srcCellRow, int srcCellCol, ValueEval arg0) {
- double d;
- try {
- ValueEval ve = OperandResolver.getSingleValue(arg0, srcCellRow, srcCellCol);
- if(ve instanceof StringEval) {
- // Note - asymmetric with UnaryMinus
- // -"hello" evaluates to #VALUE!
- // but +"hello" evaluates to "hello"
- return ve;
- }
- d = OperandResolver.coerceValueToDouble(ve);
- } catch (EvaluationException e) {
- return e.getErrorEval();
- }
- return new NumberEval(+d);
- }
-
- @Override
- public ValueEval evaluateArray(ValueEval[] args, int srcRowIndex, int srcColumnIndex){
- if (args.length != 1) {
- return ErrorEval.VALUE_INVALID;
- }
- return evaluateOneArrayArg(args[0], srcRowIndex, srcColumnIndex, (valA) ->
- evaluate(srcRowIndex, srcColumnIndex, valA)
- );
- }
+ private UnaryPlusEval() {
+ // enforce singleton
+ }
+
+ public ValueEval evaluate(int srcCellRow, int srcCellCol, ValueEval arg0) {
+ double d;
+ try {
+ ValueEval ve = OperandResolver.getSingleValue(arg0, srcCellRow, srcCellCol);
+ if(ve instanceof StringEval) {
+ // Note - asymmetric with UnaryMinus
+ // -"hello" evaluates to #VALUE!
+ // but +"hello" evaluates to "hello"
+ return ve;
+ }
+ d = OperandResolver.coerceValueToDouble(ve);
+ } catch (EvaluationException e) {
+ return e.getErrorEval();
+ }
+ return new NumberEval(+d);
+ }
+
+ @Override
+ public ValueEval evaluateArray(ValueEval[] args, int srcRowIndex, int srcColumnIndex){
+ if (args.length != 1) {
+ return ErrorEval.VALUE_INVALID;
+ }
+ return evaluateOneArrayArg(args[0], srcRowIndex, srcColumnIndex, (valA) ->
+ evaluate(srcRowIndex, srcColumnIndex, valA)
+ );
+ }
}
Modified: poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/eval/ValueEval.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/eval/ValueEval.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/eval/ValueEval.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/eval/ValueEval.java Sat May 22 20:56:44 2021
@@ -18,5 +18,5 @@
package org.apache.poi.ss.formula.eval;
public interface ValueEval {
- // no methods
+ // no methods
}
Modified: poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluationCell.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluationCell.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluationCell.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluationCell.java Sat May 22 20:56:44 2021
@@ -35,124 +35,124 @@ import org.apache.poi.ss.util.CellRangeA
*/
final class ForkedEvaluationCell implements EvaluationCell {
- private final EvaluationSheet _sheet;
- /** corresponding cell from master workbook */
- private final EvaluationCell _masterCell;
- private boolean _booleanValue;
- private CellType _cellType;
- private int _errorValue;
- private double _numberValue;
- private String _stringValue;
-
- public ForkedEvaluationCell(ForkedEvaluationSheet sheet, EvaluationCell masterCell) {
- _sheet = sheet;
- _masterCell = masterCell;
- // start with value blank, but expect construction to be immediately
- setValue(BlankEval.instance); // followed by a proper call to setValue()
- }
-
- @Override
- public Object getIdentityKey() {
- return _masterCell.getIdentityKey();
- }
-
- public void setValue(ValueEval value) {
- Class<? extends ValueEval> cls = value.getClass();
-
- if (cls == NumberEval.class) {
- _cellType = CellType.NUMERIC;
- _numberValue = ((NumberEval)value).getNumberValue();
- return;
- }
- if (cls == StringEval.class) {
- _cellType = CellType.STRING;
- _stringValue = ((StringEval)value).getStringValue();
- return;
- }
- if (cls == BoolEval.class) {
- _cellType = CellType.BOOLEAN;
- _booleanValue = ((BoolEval)value).getBooleanValue();
- return;
- }
- if (cls == ErrorEval.class) {
- _cellType = CellType.ERROR;
- _errorValue = ((ErrorEval)value).getErrorCode();
- return;
- }
- if (cls == BlankEval.class) {
- _cellType = CellType.BLANK;
- return;
- }
- throw new IllegalArgumentException("Unexpected value class (" + cls.getName() + ")");
- }
- public void copyValue(Cell destCell) {
- switch (_cellType) {
- case BLANK: destCell.setBlank(); return;
- case NUMERIC: destCell.setCellValue(_numberValue); return;
- case BOOLEAN: destCell.setCellValue(_booleanValue); return;
- case STRING: destCell.setCellValue(_stringValue); return;
- case ERROR: destCell.setCellErrorValue((byte)_errorValue); return;
- default: throw new IllegalStateException("Unexpected data type (" + _cellType + ")");
- }
- }
-
- private void checkCellType(CellType expectedCellType) {
- if (_cellType != expectedCellType) {
- throw new RuntimeException("Wrong data type (" + _cellType + ")");
- }
- }
-
- @Override
- public CellType getCellType() {
- return _cellType;
- }
- @Override
- public boolean getBooleanCellValue() {
- checkCellType(CellType.BOOLEAN);
- return _booleanValue;
- }
- @Override
- public int getErrorCellValue() {
- checkCellType(CellType.ERROR);
- return _errorValue;
- }
- @Override
- public double getNumericCellValue() {
- checkCellType(CellType.NUMERIC);
- return _numberValue;
- }
- @Override
- public String getStringCellValue() {
- checkCellType(CellType.STRING);
- return _stringValue;
- }
- @Override
- public EvaluationSheet getSheet() {
- return _sheet;
- }
- @Override
- public int getRowIndex() {
- return _masterCell.getRowIndex();
- }
- @Override
- public int getColumnIndex() {
- return _masterCell.getColumnIndex();
- }
-
- @Override
- public CellRangeAddress getArrayFormulaRange() {
- return _masterCell.getArrayFormulaRange();
- }
-
- @Override
- public boolean isPartOfArrayFormulaGroup() {
- return _masterCell.isPartOfArrayFormulaGroup();
- }
- /**
- * @return cell type of cached formula result
- */
- @Override
- public CellType getCachedFormulaResultType() {
- return _masterCell.getCachedFormulaResultType();
- }
+ private final EvaluationSheet _sheet;
+ /** corresponding cell from master workbook */
+ private final EvaluationCell _masterCell;
+ private boolean _booleanValue;
+ private CellType _cellType;
+ private int _errorValue;
+ private double _numberValue;
+ private String _stringValue;
+
+ public ForkedEvaluationCell(ForkedEvaluationSheet sheet, EvaluationCell masterCell) {
+ _sheet = sheet;
+ _masterCell = masterCell;
+ // start with value blank, but expect construction to be immediately
+ setValue(BlankEval.instance); // followed by a proper call to setValue()
+ }
+
+ @Override
+ public Object getIdentityKey() {
+ return _masterCell.getIdentityKey();
+ }
+
+ public void setValue(ValueEval value) {
+ Class<? extends ValueEval> cls = value.getClass();
+
+ if (cls == NumberEval.class) {
+ _cellType = CellType.NUMERIC;
+ _numberValue = ((NumberEval)value).getNumberValue();
+ return;
+ }
+ if (cls == StringEval.class) {
+ _cellType = CellType.STRING;
+ _stringValue = ((StringEval)value).getStringValue();
+ return;
+ }
+ if (cls == BoolEval.class) {
+ _cellType = CellType.BOOLEAN;
+ _booleanValue = ((BoolEval)value).getBooleanValue();
+ return;
+ }
+ if (cls == ErrorEval.class) {
+ _cellType = CellType.ERROR;
+ _errorValue = ((ErrorEval)value).getErrorCode();
+ return;
+ }
+ if (cls == BlankEval.class) {
+ _cellType = CellType.BLANK;
+ return;
+ }
+ throw new IllegalArgumentException("Unexpected value class (" + cls.getName() + ")");
+ }
+ public void copyValue(Cell destCell) {
+ switch (_cellType) {
+ case BLANK: destCell.setBlank(); return;
+ case NUMERIC: destCell.setCellValue(_numberValue); return;
+ case BOOLEAN: destCell.setCellValue(_booleanValue); return;
+ case STRING: destCell.setCellValue(_stringValue); return;
+ case ERROR: destCell.setCellErrorValue((byte)_errorValue); return;
+ default: throw new IllegalStateException("Unexpected data type (" + _cellType + ")");
+ }
+ }
+
+ private void checkCellType(CellType expectedCellType) {
+ if (_cellType != expectedCellType) {
+ throw new RuntimeException("Wrong data type (" + _cellType + ")");
+ }
+ }
+
+ @Override
+ public CellType getCellType() {
+ return _cellType;
+ }
+ @Override
+ public boolean getBooleanCellValue() {
+ checkCellType(CellType.BOOLEAN);
+ return _booleanValue;
+ }
+ @Override
+ public int getErrorCellValue() {
+ checkCellType(CellType.ERROR);
+ return _errorValue;
+ }
+ @Override
+ public double getNumericCellValue() {
+ checkCellType(CellType.NUMERIC);
+ return _numberValue;
+ }
+ @Override
+ public String getStringCellValue() {
+ checkCellType(CellType.STRING);
+ return _stringValue;
+ }
+ @Override
+ public EvaluationSheet getSheet() {
+ return _sheet;
+ }
+ @Override
+ public int getRowIndex() {
+ return _masterCell.getRowIndex();
+ }
+ @Override
+ public int getColumnIndex() {
+ return _masterCell.getColumnIndex();
+ }
+
+ @Override
+ public CellRangeAddress getArrayFormulaRange() {
+ return _masterCell.getArrayFormulaRange();
+ }
+
+ @Override
+ public boolean isPartOfArrayFormulaGroup() {
+ return _masterCell.isPartOfArrayFormulaGroup();
+ }
+ /**
+ * @return cell type of cached formula result
+ */
+ @Override
+ public CellType getCachedFormulaResultType() {
+ return _masterCell.getCachedFormulaResultType();
+ }
}
Modified: poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluator.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluator.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluator.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluator.java Sat May 22 20:56:44 2021
@@ -43,84 +43,84 @@ import org.apache.poi.ss.usermodel.Workb
*/
public final class ForkedEvaluator {
- private final WorkbookEvaluator _evaluator;
- private final ForkedEvaluationWorkbook _sewb;
+ private final WorkbookEvaluator _evaluator;
+ private final ForkedEvaluationWorkbook _sewb;
- private ForkedEvaluator(EvaluationWorkbook masterWorkbook, IStabilityClassifier stabilityClassifier, UDFFinder udfFinder) {
- _sewb = new ForkedEvaluationWorkbook(masterWorkbook);
- _evaluator = new WorkbookEvaluator(_sewb, stabilityClassifier, udfFinder);
- }
-
- /**
- * @param udfFinder pass {@code null} for default (AnalysisToolPak only)
- */
- public static ForkedEvaluator create(Workbook wb, IStabilityClassifier stabilityClassifier, UDFFinder udfFinder) {
- return new ForkedEvaluator(wb.createEvaluationWorkbook(), stabilityClassifier, udfFinder);
- }
-
- /**
- * Sets the specified cell to the supplied {@code value}
- * @param sheetName the name of the sheet containing the cell
- * @param rowIndex zero based
- * @param columnIndex zero based
- */
- public void updateCell(String sheetName, int rowIndex, int columnIndex, ValueEval value) {
-
- ForkedEvaluationCell cell = _sewb.getOrCreateUpdatableCell(sheetName, rowIndex, columnIndex);
- cell.setValue(value);
- _evaluator.notifyUpdateCell(cell);
- }
- /**
- * Copies the values of all updated cells (modified by calls to {@link
- * #updateCell(String, int, int, ValueEval)}) to the supplied {@code workbook}.<br>
- * Typically, the supplied {@code workbook} is a writable copy of the 'master workbook',
- * but at the very least it must contain sheets with the same names.
- */
- public void copyUpdatedCells(Workbook workbook) {
- _sewb.copyUpdatedCells(workbook);
- }
-
- /**
- * If cell contains a formula, the formula is evaluated and returned,
- * else the CellValue simply copies the appropriate cell value from
- * the cell and also its cell type. This method should be preferred over
- * evaluateInCell() when the call should not modify the contents of the
- * original cell.
- *
+ private ForkedEvaluator(EvaluationWorkbook masterWorkbook, IStabilityClassifier stabilityClassifier, UDFFinder udfFinder) {
+ _sewb = new ForkedEvaluationWorkbook(masterWorkbook);
+ _evaluator = new WorkbookEvaluator(_sewb, stabilityClassifier, udfFinder);
+ }
+
+ /**
+ * @param udfFinder pass {@code null} for default (AnalysisToolPak only)
+ */
+ public static ForkedEvaluator create(Workbook wb, IStabilityClassifier stabilityClassifier, UDFFinder udfFinder) {
+ return new ForkedEvaluator(wb.createEvaluationWorkbook(), stabilityClassifier, udfFinder);
+ }
+
+ /**
+ * Sets the specified cell to the supplied {@code value}
+ * @param sheetName the name of the sheet containing the cell
+ * @param rowIndex zero based
+ * @param columnIndex zero based
+ */
+ public void updateCell(String sheetName, int rowIndex, int columnIndex, ValueEval value) {
+
+ ForkedEvaluationCell cell = _sewb.getOrCreateUpdatableCell(sheetName, rowIndex, columnIndex);
+ cell.setValue(value);
+ _evaluator.notifyUpdateCell(cell);
+ }
+ /**
+ * Copies the values of all updated cells (modified by calls to {@link
+ * #updateCell(String, int, int, ValueEval)}) to the supplied {@code workbook}.<br>
+ * Typically, the supplied {@code workbook} is a writable copy of the 'master workbook',
+ * but at the very least it must contain sheets with the same names.
+ */
+ public void copyUpdatedCells(Workbook workbook) {
+ _sewb.copyUpdatedCells(workbook);
+ }
+
+ /**
+ * If cell contains a formula, the formula is evaluated and returned,
+ * else the CellValue simply copies the appropriate cell value from
+ * the cell and also its cell type. This method should be preferred over
+ * evaluateInCell() when the call should not modify the contents of the
+ * original cell.
+ *
* @param sheetName the name of the sheet containing the cell
* @param rowIndex zero based
* @param columnIndex zero based
- * @return {@code null} if the supplied cell is {@code null} or blank
- */
- public ValueEval evaluate(String sheetName, int rowIndex, int columnIndex) {
- EvaluationCell cell = _sewb.getEvaluationCell(sheetName, rowIndex, columnIndex);
-
- switch (cell.getCellType()) {
- case BOOLEAN:
- return BoolEval.valueOf(cell.getBooleanCellValue());
- case ERROR:
- return ErrorEval.valueOf(cell.getErrorCellValue());
- case FORMULA:
- return _evaluator.evaluate(cell);
- case NUMERIC:
- return new NumberEval(cell.getNumericCellValue());
- case STRING:
- return new StringEval(cell.getStringCellValue());
- case BLANK:
- return null;
- default:
- throw new IllegalStateException("Bad cell type (" + cell.getCellType() + ")");
- }
- }
- /**
- * Coordinates several formula evaluators together so that formulas that involve external
- * references can be evaluated.
- * @param workbookNames the simple file names used to identify the workbooks in formulas
- * with external links (for example "MyData.xls" as used in a formula "[MyData.xls]Sheet1!A1")
- * @param evaluators all evaluators for the full set of workbooks required by the formulas.
- */
- public static void setupEnvironment(String[] workbookNames, ForkedEvaluator[] evaluators) {
- WorkbookEvaluator[] wbEvals = Stream.of(evaluators).map(e -> e._evaluator).toArray(WorkbookEvaluator[]::new);
- CollaboratingWorkbooksEnvironment.setup(workbookNames, wbEvals);
- }
+ * @return {@code null} if the supplied cell is {@code null} or blank
+ */
+ public ValueEval evaluate(String sheetName, int rowIndex, int columnIndex) {
+ EvaluationCell cell = _sewb.getEvaluationCell(sheetName, rowIndex, columnIndex);
+
+ switch (cell.getCellType()) {
+ case BOOLEAN:
+ return BoolEval.valueOf(cell.getBooleanCellValue());
+ case ERROR:
+ return ErrorEval.valueOf(cell.getErrorCellValue());
+ case FORMULA:
+ return _evaluator.evaluate(cell);
+ case NUMERIC:
+ return new NumberEval(cell.getNumericCellValue());
+ case STRING:
+ return new StringEval(cell.getStringCellValue());
+ case BLANK:
+ return null;
+ default:
+ throw new IllegalStateException("Bad cell type (" + cell.getCellType() + ")");
+ }
+ }
+ /**
+ * Coordinates several formula evaluators together so that formulas that involve external
+ * references can be evaluated.
+ * @param workbookNames the simple file names used to identify the workbooks in formulas
+ * with external links (for example "MyData.xls" as used in a formula "[MyData.xls]Sheet1!A1")
+ * @param evaluators all evaluators for the full set of workbooks required by the formulas.
+ */
+ public static void setupEnvironment(String[] workbookNames, ForkedEvaluator[] evaluators) {
+ WorkbookEvaluator[] wbEvals = Stream.of(evaluators).map(e -> e._evaluator).toArray(WorkbookEvaluator[]::new);
+ CollaboratingWorkbooksEnvironment.setup(workbookNames, wbEvals);
+ }
}
Modified: poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/function/FunctionDataBuilder.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/function/FunctionDataBuilder.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/function/FunctionDataBuilder.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/function/FunctionDataBuilder.java Sat May 22 20:56:44 2021
@@ -27,62 +27,62 @@ import java.util.Set;
* {@code FunctionMetadataRegistry}.
*/
final class FunctionDataBuilder {
- private int _maxFunctionIndex;
- private final Map<String,FunctionMetadata> _functionDataByName;
- private final Map<Integer,FunctionMetadata> _functionDataByIndex;
- /** stores indexes of all functions with footnotes (i.e. whose definitions might change) */
- private final Set<Integer> _mutatingFunctionIndexes;
-
- public FunctionDataBuilder(int sizeEstimate) {
- _maxFunctionIndex = -1;
- _functionDataByName = new HashMap<>(sizeEstimate * 3 / 2);
- _functionDataByIndex = new HashMap<>(sizeEstimate * 3 / 2);
- _mutatingFunctionIndexes = new HashSet<>();
- }
-
- public void add(int functionIndex, String functionName, int minParams, int maxParams,
- byte returnClassCode, byte[] parameterClassCodes, boolean hasFootnote) {
- FunctionMetadata fm = new FunctionMetadata(functionIndex, functionName, minParams, maxParams,
- returnClassCode, parameterClassCodes);
-
- Integer indexKey = functionIndex;
-
-
- if(functionIndex > _maxFunctionIndex) {
- _maxFunctionIndex = functionIndex;
- }
- // allow function definitions to change only if both previous and the new items have footnotes
- FunctionMetadata prevFM;
- prevFM = _functionDataByName.get(functionName);
- if(prevFM != null) {
- if(!hasFootnote || !_mutatingFunctionIndexes.contains(indexKey)) {
- throw new RuntimeException("Multiple entries for function name '" + functionName + "'");
- }
- _functionDataByIndex.remove(prevFM.getIndex());
- }
- prevFM = _functionDataByIndex.get(indexKey);
- if(prevFM != null) {
- if(!hasFootnote || !_mutatingFunctionIndexes.contains(indexKey)) {
- throw new RuntimeException("Multiple entries for function index (" + functionIndex + ")");
- }
- _functionDataByName.remove(prevFM.getName());
- }
- if(hasFootnote) {
- _mutatingFunctionIndexes.add(indexKey);
- }
- _functionDataByIndex.put(indexKey, fm);
- _functionDataByName.put(functionName, fm);
- }
-
- public FunctionMetadataRegistry build() {
-
- FunctionMetadata[] jumbledArray = new FunctionMetadata[_functionDataByName.size()];
- _functionDataByName.values().toArray(jumbledArray);
- FunctionMetadata[] fdIndexArray = new FunctionMetadata[_maxFunctionIndex+1];
- for (FunctionMetadata fd : jumbledArray) {
- fdIndexArray[fd.getIndex()] = fd;
- }
+ private int _maxFunctionIndex;
+ private final Map<String,FunctionMetadata> _functionDataByName;
+ private final Map<Integer,FunctionMetadata> _functionDataByIndex;
+ /** stores indexes of all functions with footnotes (i.e. whose definitions might change) */
+ private final Set<Integer> _mutatingFunctionIndexes;
+
+ public FunctionDataBuilder(int sizeEstimate) {
+ _maxFunctionIndex = -1;
+ _functionDataByName = new HashMap<>(sizeEstimate * 3 / 2);
+ _functionDataByIndex = new HashMap<>(sizeEstimate * 3 / 2);
+ _mutatingFunctionIndexes = new HashSet<>();
+ }
+
+ public void add(int functionIndex, String functionName, int minParams, int maxParams,
+ byte returnClassCode, byte[] parameterClassCodes, boolean hasFootnote) {
+ FunctionMetadata fm = new FunctionMetadata(functionIndex, functionName, minParams, maxParams,
+ returnClassCode, parameterClassCodes);
+
+ Integer indexKey = functionIndex;
+
+
+ if(functionIndex > _maxFunctionIndex) {
+ _maxFunctionIndex = functionIndex;
+ }
+ // allow function definitions to change only if both previous and the new items have footnotes
+ FunctionMetadata prevFM;
+ prevFM = _functionDataByName.get(functionName);
+ if(prevFM != null) {
+ if(!hasFootnote || !_mutatingFunctionIndexes.contains(indexKey)) {
+ throw new RuntimeException("Multiple entries for function name '" + functionName + "'");
+ }
+ _functionDataByIndex.remove(prevFM.getIndex());
+ }
+ prevFM = _functionDataByIndex.get(indexKey);
+ if(prevFM != null) {
+ if(!hasFootnote || !_mutatingFunctionIndexes.contains(indexKey)) {
+ throw new RuntimeException("Multiple entries for function index (" + functionIndex + ")");
+ }
+ _functionDataByName.remove(prevFM.getName());
+ }
+ if(hasFootnote) {
+ _mutatingFunctionIndexes.add(indexKey);
+ }
+ _functionDataByIndex.put(indexKey, fm);
+ _functionDataByName.put(functionName, fm);
+ }
+
+ public FunctionMetadataRegistry build() {
+
+ FunctionMetadata[] jumbledArray = new FunctionMetadata[_functionDataByName.size()];
+ _functionDataByName.values().toArray(jumbledArray);
+ FunctionMetadata[] fdIndexArray = new FunctionMetadata[_maxFunctionIndex+1];
+ for (FunctionMetadata fd : jumbledArray) {
+ fdIndexArray[fd.getIndex()] = fd;
+ }
- return new FunctionMetadataRegistry(fdIndexArray, _functionDataByName);
- }
+ return new FunctionMetadataRegistry(fdIndexArray, _functionDataByName);
+ }
}
Modified: poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/function/FunctionMetadata.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/function/FunctionMetadata.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/function/FunctionMetadata.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/function/FunctionMetadata.java Sat May 22 20:56:44 2021
@@ -6,7 +6,7 @@
(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
+ 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,
@@ -21,74 +21,74 @@ package org.apache.poi.ss.formula.functi
* Holds information about Excel built-in functions.
*/
public final class FunctionMetadata {
- /**
- * maxParams=30 in functionMetadata.txt means the maximum number arguments supported
- * by the given version of Excel. Validation routines should take the actual limit (Excel 97 or 2007)
- * from the SpreadsheetVersion enum.
- * Perhaps a value like 'M' should be used instead of '30' in functionMetadata.txt
- * to make that file more version neutral.
- * @see org.apache.poi.ss.formula.FormulaParser#validateNumArgs(int, FunctionMetadata)
- */
- @SuppressWarnings("JavadocReference")
- private static final short FUNCTION_MAX_PARAMS = 30;
-
- private final int _index;
- private final String _name;
- private final int _minParams;
- private final int _maxParams;
- private final byte _returnClassCode;
- private final byte[] _parameterClassCodes;
-
- /* package */ FunctionMetadata(int index, String name, int minParams, int maxParams,
- byte returnClassCode, byte[] parameterClassCodes) {
- _index = index;
- _name = name;
- _minParams = minParams;
- _maxParams = maxParams;
- _returnClassCode = returnClassCode;
- _parameterClassCodes = (parameterClassCodes == null) ? null : parameterClassCodes.clone();
- }
-
- public int getIndex() {
- return _index;
- }
-
- public String getName() {
- return _name;
- }
-
- public int getMinParams() {
- return _minParams;
- }
-
- public int getMaxParams() {
- return _maxParams;
- }
-
- public boolean hasFixedArgsLength() {
- return _minParams == _maxParams;
- }
-
- public byte getReturnClassCode() {
- return _returnClassCode;
- }
-
- public byte[] getParameterClassCodes() {
- return _parameterClassCodes.clone();
- }
-
- /**
- * Some varags functions (like VLOOKUP) have a specific limit to the number of arguments that
- * can be passed. Other functions (like SUM) don't have such a limit. For those functions,
- * the spreadsheet version determines the maximum number of arguments that can be passed.
- * @return <code>true</code> if this function can the maximum number of arguments allowable by
- * the {@link org.apache.poi.ss.SpreadsheetVersion}
- */
- public boolean hasUnlimitedVarags() {
- return FUNCTION_MAX_PARAMS == _maxParams;
- }
-
- public String toString() {
- return getClass().getName() + " [" + _index + " " + _name + "]";
- }
+ /**
+ * maxParams=30 in functionMetadata.txt means the maximum number arguments supported
+ * by the given version of Excel. Validation routines should take the actual limit (Excel 97 or 2007)
+ * from the SpreadsheetVersion enum.
+ * Perhaps a value like 'M' should be used instead of '30' in functionMetadata.txt
+ * to make that file more version neutral.
+ * @see org.apache.poi.ss.formula.FormulaParser#validateNumArgs(int, FunctionMetadata)
+ */
+ @SuppressWarnings("JavadocReference")
+ private static final short FUNCTION_MAX_PARAMS = 30;
+
+ private final int _index;
+ private final String _name;
+ private final int _minParams;
+ private final int _maxParams;
+ private final byte _returnClassCode;
+ private final byte[] _parameterClassCodes;
+
+ /* package */ FunctionMetadata(int index, String name, int minParams, int maxParams,
+ byte returnClassCode, byte[] parameterClassCodes) {
+ _index = index;
+ _name = name;
+ _minParams = minParams;
+ _maxParams = maxParams;
+ _returnClassCode = returnClassCode;
+ _parameterClassCodes = (parameterClassCodes == null) ? null : parameterClassCodes.clone();
+ }
+
+ public int getIndex() {
+ return _index;
+ }
+
+ public String getName() {
+ return _name;
+ }
+
+ public int getMinParams() {
+ return _minParams;
+ }
+
+ public int getMaxParams() {
+ return _maxParams;
+ }
+
+ public boolean hasFixedArgsLength() {
+ return _minParams == _maxParams;
+ }
+
+ public byte getReturnClassCode() {
+ return _returnClassCode;
+ }
+
+ public byte[] getParameterClassCodes() {
+ return _parameterClassCodes.clone();
+ }
+
+ /**
+ * Some varags functions (like VLOOKUP) have a specific limit to the number of arguments that
+ * can be passed. Other functions (like SUM) don't have such a limit. For those functions,
+ * the spreadsheet version determines the maximum number of arguments that can be passed.
+ * @return <code>true</code> if this function can the maximum number of arguments allowable by
+ * the {@link org.apache.poi.ss.SpreadsheetVersion}
+ */
+ public boolean hasUnlimitedVarags() {
+ return FUNCTION_MAX_PARAMS == _maxParams;
+ }
+
+ public String toString() {
+ return getClass().getName() + " [" + _index + " " + _name + "]";
+ }
}
Modified: poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/function/FunctionMetadataReader.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/function/FunctionMetadataReader.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/function/FunctionMetadataReader.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/function/FunctionMetadataReader.java Sat May 22 20:56:44 2021
@@ -6,7 +6,7 @@
(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
+ 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,
@@ -35,162 +35,162 @@ import org.apache.poi.util.IOUtils;
*/
final class FunctionMetadataReader {
- //arbitrarily selected; may need to increase
- private static final int MAX_RECORD_LENGTH = 100_000;
+ //arbitrarily selected; may need to increase
+ private static final int MAX_RECORD_LENGTH = 100_000;
- private static final String METADATA_FILE_NAME = "functionMetadata.txt";
- private static final String METADATA_FILE_NAME_CETAB = "functionMetadataCetab.txt";
+ private static final String METADATA_FILE_NAME = "functionMetadata.txt";
+ private static final String METADATA_FILE_NAME_CETAB = "functionMetadataCetab.txt";
- /** plain ASCII text metadata file uses three dots for ellipsis */
- private static final String ELLIPSIS = "...";
+ /** plain ASCII text metadata file uses three dots for ellipsis */
+ private static final String ELLIPSIS = "...";
- private static final Pattern TAB_DELIM_PATTERN = Pattern.compile("\t");
- private static final Pattern SPACE_DELIM_PATTERN = Pattern.compile(" ");
- private static final byte[] EMPTY_BYTE_ARRAY = { };
-
- private static final String[] DIGIT_ENDING_FUNCTION_NAMES = {
- // Digits at the end of a function might be due to a left-over footnote marker.
- // except in these cases
- "LOG10", "ATAN2", "DAYS360", "SUMXMY2", "SUMX2MY2", "SUMX2PY2", "A1.R1C1",
- };
- private static final Set<String> DIGIT_ENDING_FUNCTION_NAMES_SET = new HashSet<>(Arrays.asList(DIGIT_ENDING_FUNCTION_NAMES));
-
- public static FunctionMetadataRegistry createRegistry() {
- FunctionDataBuilder fdb = new FunctionDataBuilder(800);
- readResourceFile(fdb, METADATA_FILE_NAME);
- return fdb.build();
- }
-
- public static FunctionMetadataRegistry createRegistryCetab() {
- FunctionDataBuilder fdb = new FunctionDataBuilder(800);
- readResourceFile(fdb, METADATA_FILE_NAME_CETAB);
- return fdb.build();
- }
-
- private static void readResourceFile(FunctionDataBuilder fdb, String resourceFile) {
- try (InputStream is = FunctionMetadataReader.class.getResourceAsStream(resourceFile)) {
- if (is == null) {
- throw new RuntimeException("resource '" + resourceFile + "' not found");
- }
-
- try(BufferedReader br = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))) {
-
- while (true) {
- String line = br.readLine();
- if (line == null) {
- break;
- }
- if (line.length() < 1 || line.charAt(0) == '#') {
- continue;
- }
- String trimLine = line.trim();
- if (trimLine.length() < 1) {
- continue;
- }
- processLine(fdb, line);
- }
- }
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
- private static void processLine(FunctionDataBuilder fdb, String line) {
-
- String[] parts = TAB_DELIM_PATTERN.split(line, -2);
- if(parts.length != 8) {
- throw new RuntimeException("Bad line format '" + line + "' - expected 8 data fields delimited by tab, " +
- "but had " + parts.length + ": " + Arrays.toString(parts));
- }
- int functionIndex = parseInt(parts[0]);
- String functionName = parts[1];
- int minParams = parseInt(parts[2]);
- int maxParams = parseInt(parts[3]);
- byte returnClassCode = parseReturnTypeCode(parts[4]);
- byte[] parameterClassCodes = parseOperandTypeCodes(parts[5]);
- // 6 isVolatile
- boolean hasNote = parts[7].length() > 0;
-
- validateFunctionName(functionName);
- // TODO - make POI use isVolatile
- fdb.add(functionIndex, functionName, minParams, maxParams,
- returnClassCode, parameterClassCodes, hasNote);
- }
-
-
- private static byte parseReturnTypeCode(String code) {
- if(code.length() == 0) {
- return Ptg.CLASS_REF; // happens for GETPIVOTDATA
- }
- return parseOperandTypeCode(code);
- }
-
- private static byte[] parseOperandTypeCodes(String codes) {
- if(codes.length() < 1) {
- return EMPTY_BYTE_ARRAY; // happens for GETPIVOTDATA
- }
- if(isDash(codes)) {
- // '-' means empty:
- return EMPTY_BYTE_ARRAY;
- }
- String[] array = SPACE_DELIM_PATTERN.split(codes);
- int nItems = array.length;
- if(ELLIPSIS.equals(array[nItems-1])) {
- // final ellipsis is optional, and ignored
- // (all unspecified params are assumed to be the same as the last)
- nItems --;
- }
- byte[] result = IOUtils.safelyAllocate(nItems, MAX_RECORD_LENGTH);
- for (int i = 0; i < nItems; i++) {
- result[i] = parseOperandTypeCode(array[i]);
- }
- return result;
- }
-
- private static boolean isDash(String codes) {
- return codes.length() == 1 && codes.charAt(0) == '-';
- }
-
- private static byte parseOperandTypeCode(String code) {
- if(code.length() != 1) {
- throw new RuntimeException("Bad operand type code format '" + code + "' expected single char");
- }
- switch(code.charAt(0)) {
- case 'V': return Ptg.CLASS_VALUE;
- case 'R': return Ptg.CLASS_REF;
- case 'A': return Ptg.CLASS_ARRAY;
- }
- throw new IllegalArgumentException("Unexpected operand type code '" + code + "' (" + (int)code.charAt(0) + ")");
- }
-
- /**
- * Makes sure that footnote digits from the original OOO document have not been accidentally
- * left behind
- */
- private static void validateFunctionName(String functionName) {
- int len = functionName.length();
- int ix = len - 1;
- if (!Character.isDigit(functionName.charAt(ix))) {
- return;
- }
- while(ix >= 0) {
- if (!Character.isDigit(functionName.charAt(ix))) {
- break;
- }
- ix--;
- }
- if(DIGIT_ENDING_FUNCTION_NAMES_SET.contains(functionName)) {
- return;
- }
- throw new RuntimeException("Invalid function name '" + functionName
- + "' (is footnote number incorrectly appended)");
- }
-
- private static int parseInt(String valStr) {
- try {
- return Integer.parseInt(valStr);
- } catch (NumberFormatException e) {
- throw new RuntimeException("Value '" + valStr + "' could not be parsed as an integer");
- }
- }
+ private static final Pattern TAB_DELIM_PATTERN = Pattern.compile("\t");
+ private static final Pattern SPACE_DELIM_PATTERN = Pattern.compile(" ");
+ private static final byte[] EMPTY_BYTE_ARRAY = { };
+
+ private static final String[] DIGIT_ENDING_FUNCTION_NAMES = {
+ // Digits at the end of a function might be due to a left-over footnote marker.
+ // except in these cases
+ "LOG10", "ATAN2", "DAYS360", "SUMXMY2", "SUMX2MY2", "SUMX2PY2", "A1.R1C1",
+ };
+ private static final Set<String> DIGIT_ENDING_FUNCTION_NAMES_SET = new HashSet<>(Arrays.asList(DIGIT_ENDING_FUNCTION_NAMES));
+
+ public static FunctionMetadataRegistry createRegistry() {
+ FunctionDataBuilder fdb = new FunctionDataBuilder(800);
+ readResourceFile(fdb, METADATA_FILE_NAME);
+ return fdb.build();
+ }
+
+ public static FunctionMetadataRegistry createRegistryCetab() {
+ FunctionDataBuilder fdb = new FunctionDataBuilder(800);
+ readResourceFile(fdb, METADATA_FILE_NAME_CETAB);
+ return fdb.build();
+ }
+
+ private static void readResourceFile(FunctionDataBuilder fdb, String resourceFile) {
+ try (InputStream is = FunctionMetadataReader.class.getResourceAsStream(resourceFile)) {
+ if (is == null) {
+ throw new RuntimeException("resource '" + resourceFile + "' not found");
+ }
+
+ try(BufferedReader br = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))) {
+
+ while (true) {
+ String line = br.readLine();
+ if (line == null) {
+ break;
+ }
+ if (line.length() < 1 || line.charAt(0) == '#') {
+ continue;
+ }
+ String trimLine = line.trim();
+ if (trimLine.length() < 1) {
+ continue;
+ }
+ processLine(fdb, line);
+ }
+ }
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private static void processLine(FunctionDataBuilder fdb, String line) {
+
+ String[] parts = TAB_DELIM_PATTERN.split(line, -2);
+ if(parts.length != 8) {
+ throw new RuntimeException("Bad line format '" + line + "' - expected 8 data fields delimited by tab, " +
+ "but had " + parts.length + ": " + Arrays.toString(parts));
+ }
+ int functionIndex = parseInt(parts[0]);
+ String functionName = parts[1];
+ int minParams = parseInt(parts[2]);
+ int maxParams = parseInt(parts[3]);
+ byte returnClassCode = parseReturnTypeCode(parts[4]);
+ byte[] parameterClassCodes = parseOperandTypeCodes(parts[5]);
+ // 6 isVolatile
+ boolean hasNote = parts[7].length() > 0;
+
+ validateFunctionName(functionName);
+ // TODO - make POI use isVolatile
+ fdb.add(functionIndex, functionName, minParams, maxParams,
+ returnClassCode, parameterClassCodes, hasNote);
+ }
+
+
+ private static byte parseReturnTypeCode(String code) {
+ if(code.length() == 0) {
+ return Ptg.CLASS_REF; // happens for GETPIVOTDATA
+ }
+ return parseOperandTypeCode(code);
+ }
+
+ private static byte[] parseOperandTypeCodes(String codes) {
+ if(codes.length() < 1) {
+ return EMPTY_BYTE_ARRAY; // happens for GETPIVOTDATA
+ }
+ if(isDash(codes)) {
+ // '-' means empty:
+ return EMPTY_BYTE_ARRAY;
+ }
+ String[] array = SPACE_DELIM_PATTERN.split(codes);
+ int nItems = array.length;
+ if(ELLIPSIS.equals(array[nItems-1])) {
+ // final ellipsis is optional, and ignored
+ // (all unspecified params are assumed to be the same as the last)
+ nItems --;
+ }
+ byte[] result = IOUtils.safelyAllocate(nItems, MAX_RECORD_LENGTH);
+ for (int i = 0; i < nItems; i++) {
+ result[i] = parseOperandTypeCode(array[i]);
+ }
+ return result;
+ }
+
+ private static boolean isDash(String codes) {
+ return codes.length() == 1 && codes.charAt(0) == '-';
+ }
+
+ private static byte parseOperandTypeCode(String code) {
+ if(code.length() != 1) {
+ throw new RuntimeException("Bad operand type code format '" + code + "' expected single char");
+ }
+ switch(code.charAt(0)) {
+ case 'V': return Ptg.CLASS_VALUE;
+ case 'R': return Ptg.CLASS_REF;
+ case 'A': return Ptg.CLASS_ARRAY;
+ }
+ throw new IllegalArgumentException("Unexpected operand type code '" + code + "' (" + (int)code.charAt(0) + ")");
+ }
+
+ /**
+ * Makes sure that footnote digits from the original OOO document have not been accidentally
+ * left behind
+ */
+ private static void validateFunctionName(String functionName) {
+ int len = functionName.length();
+ int ix = len - 1;
+ if (!Character.isDigit(functionName.charAt(ix))) {
+ return;
+ }
+ while(ix >= 0) {
+ if (!Character.isDigit(functionName.charAt(ix))) {
+ break;
+ }
+ ix--;
+ }
+ if(DIGIT_ENDING_FUNCTION_NAMES_SET.contains(functionName)) {
+ return;
+ }
+ throw new RuntimeException("Invalid function name '" + functionName
+ + "' (is footnote number incorrectly appended)");
+ }
+
+ private static int parseInt(String valStr) {
+ try {
+ return Integer.parseInt(valStr);
+ } catch (NumberFormatException e) {
+ throw new RuntimeException("Value '" + valStr + "' could not be parsed as an integer");
+ }
+ }
}
Modified: poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/function/FunctionMetadataRegistry.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/function/FunctionMetadataRegistry.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/function/FunctionMetadataRegistry.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/function/FunctionMetadataRegistry.java Sat May 22 20:56:44 2021
@@ -24,86 +24,86 @@ import java.util.Set;
* Allows clients to get {@link FunctionMetadata} instances for any built-in function of Excel.
*/
public final class FunctionMetadataRegistry {
- /**
- * The name of the IF function (i.e. "IF"). Extracted as a constant for clarity.
- */
- public static final String FUNCTION_NAME_IF = "IF";
-
- public static final int FUNCTION_INDEX_IF = 1;
- public static final short FUNCTION_INDEX_SUM = 4;
- public static final int FUNCTION_INDEX_CHOOSE = 100;
- public static final short FUNCTION_INDEX_INDIRECT = 148;
- public static final short FUNCTION_INDEX_EXTERNAL = 255;
-
- private static FunctionMetadataRegistry _instance;
- private static FunctionMetadataRegistry _instanceCetab;
-
- private final FunctionMetadata[] _functionDataByIndex;
- private final Map<String, FunctionMetadata> _functionDataByName;
-
- private static FunctionMetadataRegistry getInstance() {
- if (_instance == null) {
- _instance = FunctionMetadataReader.createRegistry();
- }
- return _instance;
- }
-
- private static FunctionMetadataRegistry getInstanceCetab() {
- if (_instanceCetab == null) {
- _instanceCetab = FunctionMetadataReader.createRegistryCetab();
- }
- return _instanceCetab;
- }
-
- /* package */ FunctionMetadataRegistry(FunctionMetadata[] functionDataByIndex, Map<String, FunctionMetadata> functionDataByName) {
- _functionDataByIndex = (functionDataByIndex == null) ? null : functionDataByIndex.clone();
- _functionDataByName = functionDataByName;
- }
-
- /* package */ Set<String> getAllFunctionNames() {
- return _functionDataByName.keySet();
- }
-
-
- public static FunctionMetadata getFunctionByIndex(int index) {
- return getInstance().getFunctionByIndexInternal(index);
- }
-
- public static FunctionMetadata getCetabFunctionByIndex(int index) {
- return getInstanceCetab().getFunctionByIndexInternal(index);
- }
-
- private FunctionMetadata getFunctionByIndexInternal(int index) {
- return _functionDataByIndex[index];
- }
- /**
- * Resolves a built-in function index.
- * @param name uppercase function name
- * @return a negative value if the function name is not found.
- * This typically occurs for external functions.
- */
- public static short lookupIndexByName(String name) {
- FunctionMetadata fd = getInstance().getFunctionByNameInternal(name);
- if (fd == null) {
- // also try the cetab functions
- fd = getInstanceCetab().getFunctionByNameInternal(name);
- if (fd == null) {
- return -1;
- }
- }
- return (short) fd.getIndex();
- }
-
- private FunctionMetadata getFunctionByNameInternal(String name) {
- return _functionDataByName.get(name);
- }
-
- public static FunctionMetadata getFunctionByName(String name) {
- FunctionMetadata fm = getInstance().getFunctionByNameInternal(name);
- if(fm == null) {
- return getInstanceCetab().getFunctionByNameInternal(name);
- }
+ /**
+ * The name of the IF function (i.e. "IF"). Extracted as a constant for clarity.
+ */
+ public static final String FUNCTION_NAME_IF = "IF";
+
+ public static final int FUNCTION_INDEX_IF = 1;
+ public static final short FUNCTION_INDEX_SUM = 4;
+ public static final int FUNCTION_INDEX_CHOOSE = 100;
+ public static final short FUNCTION_INDEX_INDIRECT = 148;
+ public static final short FUNCTION_INDEX_EXTERNAL = 255;
+
+ private static FunctionMetadataRegistry _instance;
+ private static FunctionMetadataRegistry _instanceCetab;
+
+ private final FunctionMetadata[] _functionDataByIndex;
+ private final Map<String, FunctionMetadata> _functionDataByName;
+
+ private static FunctionMetadataRegistry getInstance() {
+ if (_instance == null) {
+ _instance = FunctionMetadataReader.createRegistry();
+ }
+ return _instance;
+ }
+
+ private static FunctionMetadataRegistry getInstanceCetab() {
+ if (_instanceCetab == null) {
+ _instanceCetab = FunctionMetadataReader.createRegistryCetab();
+ }
+ return _instanceCetab;
+ }
+
+ /* package */ FunctionMetadataRegistry(FunctionMetadata[] functionDataByIndex, Map<String, FunctionMetadata> functionDataByName) {
+ _functionDataByIndex = (functionDataByIndex == null) ? null : functionDataByIndex.clone();
+ _functionDataByName = functionDataByName;
+ }
+
+ /* package */ Set<String> getAllFunctionNames() {
+ return _functionDataByName.keySet();
+ }
+
+
+ public static FunctionMetadata getFunctionByIndex(int index) {
+ return getInstance().getFunctionByIndexInternal(index);
+ }
+
+ public static FunctionMetadata getCetabFunctionByIndex(int index) {
+ return getInstanceCetab().getFunctionByIndexInternal(index);
+ }
+
+ private FunctionMetadata getFunctionByIndexInternal(int index) {
+ return _functionDataByIndex[index];
+ }
+ /**
+ * Resolves a built-in function index.
+ * @param name uppercase function name
+ * @return a negative value if the function name is not found.
+ * This typically occurs for external functions.
+ */
+ public static short lookupIndexByName(String name) {
+ FunctionMetadata fd = getInstance().getFunctionByNameInternal(name);
+ if (fd == null) {
+ // also try the cetab functions
+ fd = getInstanceCetab().getFunctionByNameInternal(name);
+ if (fd == null) {
+ return -1;
+ }
+ }
+ return (short) fd.getIndex();
+ }
+
+ private FunctionMetadata getFunctionByNameInternal(String name) {
+ return _functionDataByName.get(name);
+ }
+
+ public static FunctionMetadata getFunctionByName(String name) {
+ FunctionMetadata fm = getInstance().getFunctionByNameInternal(name);
+ if(fm == null) {
+ return getInstanceCetab().getFunctionByNameInternal(name);
+ }
- return fm;
- }
+ return fm;
+ }
}
Modified: poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/Address.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/Address.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/Address.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/Address.java Sat May 22 20:56:44 2021
@@ -44,7 +44,7 @@ public class Address implements Function
if (args.length > 2 && args[2] != MissingArgEval.instance) {
refType = (int)NumericFunction.singleOperandEvaluate(args[2], srcRowIndex, srcColumnIndex);
} else {
- refType = REF_ABSOLUTE; // this is also the default if parameter is not given
+ refType = REF_ABSOLUTE; // this is also the default if parameter is not given
}
switch (refType){
case REF_ABSOLUTE:
Modified: poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/BooleanFunction.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/BooleanFunction.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/BooleanFunction.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/BooleanFunction.java Sat May 22 20:56:44 2021
@@ -37,45 +37,45 @@ import org.apache.poi.ss.formula.eval.Va
*/
public abstract class BooleanFunction implements Function,ArrayFunction {
- public final ValueEval evaluate(ValueEval[] args, int srcRow, int srcCol) {
- if (args.length < 1) {
- return ErrorEval.VALUE_INVALID;
- }
- boolean boolResult;
- try {
- boolResult = calculate(args);
- } catch (EvaluationException e) {
- return e.getErrorEval();
- }
- return BoolEval.valueOf(boolResult);
- }
-
- private boolean calculate(ValueEval[] args) throws EvaluationException {
-
- boolean result = getInitialResultValue();
- boolean atLeastOneNonBlank = false;
-
- /*
- * Note: no short-circuit boolean loop exit because any ErrorEvals will override the result
- */
- for (final ValueEval arg : args) {
+ public final ValueEval evaluate(ValueEval[] args, int srcRow, int srcCol) {
+ if (args.length < 1) {
+ return ErrorEval.VALUE_INVALID;
+ }
+ boolean boolResult;
+ try {
+ boolResult = calculate(args);
+ } catch (EvaluationException e) {
+ return e.getErrorEval();
+ }
+ return BoolEval.valueOf(boolResult);
+ }
+
+ private boolean calculate(ValueEval[] args) throws EvaluationException {
+
+ boolean result = getInitialResultValue();
+ boolean atLeastOneNonBlank = false;
+
+ /*
+ * Note: no short-circuit boolean loop exit because any ErrorEvals will override the result
+ */
+ for (final ValueEval arg : args) {
Boolean tempVe;
- if (arg instanceof TwoDEval) {
- TwoDEval ae = (TwoDEval) arg;
- int height = ae.getHeight();
- int width = ae.getWidth();
- for (int rrIx=0; rrIx<height; rrIx++) {
- for (int rcIx=0; rcIx<width; rcIx++) {
- ValueEval ve = ae.getValue(rrIx, rcIx);
- tempVe = OperandResolver.coerceValueToBoolean(ve, true);
- if (tempVe != null) {
- result = partialEvaluate(result, tempVe);
- atLeastOneNonBlank = true;
- }
- }
- }
- continue;
- }
+ if (arg instanceof TwoDEval) {
+ TwoDEval ae = (TwoDEval) arg;
+ int height = ae.getHeight();
+ int width = ae.getWidth();
+ for (int rrIx=0; rrIx<height; rrIx++) {
+ for (int rcIx=0; rcIx<width; rcIx++) {
+ ValueEval ve = ae.getValue(rrIx, rcIx);
+ tempVe = OperandResolver.coerceValueToBoolean(ve, true);
+ if (tempVe != null) {
+ result = partialEvaluate(result, tempVe);
+ atLeastOneNonBlank = true;
+ }
+ }
+ }
+ continue;
+ }
if (arg instanceof RefEval) {
RefEval re = (RefEval) arg;
final int firstSheetIndex = re.getFirstSheetIndex();
@@ -91,84 +91,84 @@ public abstract class BooleanFunction im
continue;
}
- if (arg == MissingArgEval.instance) {
- tempVe = false; // missing parameters are treated as FALSE
- } else {
- tempVe = OperandResolver.coerceValueToBoolean(arg, false);
- }
-
- if (tempVe != null) {
- result = partialEvaluate(result, tempVe);
- atLeastOneNonBlank = true;
- }
- }
-
- if (!atLeastOneNonBlank) {
- throw new EvaluationException(ErrorEval.VALUE_INVALID);
- }
- return result;
- }
-
-
- protected abstract boolean getInitialResultValue();
- protected abstract boolean partialEvaluate(boolean cumulativeResult, boolean currentValue);
-
-
- public static final Function AND = new BooleanFunction() {
- protected boolean getInitialResultValue() {
- return true;
- }
- protected boolean partialEvaluate(boolean cumulativeResult, boolean currentValue) {
- return cumulativeResult && currentValue;
- }
- };
- public static final Function OR = new BooleanFunction() {
- protected boolean getInitialResultValue() {
- return false;
- }
- protected boolean partialEvaluate(boolean cumulativeResult, boolean currentValue) {
- return cumulativeResult || currentValue;
- }
- };
-
- public static final Function FALSE = BooleanFunction::evaluateFalse;
-
- public static final Function TRUE = BooleanFunction::evaluateTrue;
-
- public static final Function NOT = BooleanFunction::evaluateNot;
-
- @Override
- public ValueEval evaluateArray(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
- if (args.length != 1) {
- return ErrorEval.VALUE_INVALID;
- }
- return evaluateOneArrayArg(args[0], srcRowIndex, srcColumnIndex,
- vA -> evaluate(new ValueEval[]{vA}, srcRowIndex, srcColumnIndex));
- }
-
- private static ValueEval evaluateFalse(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
- return args.length != 0 ? ErrorEval.VALUE_INVALID : BoolEval.FALSE;
- }
-
- private static ValueEval evaluateTrue(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
- return args.length != 0 ? ErrorEval.VALUE_INVALID : BoolEval.TRUE;
- }
-
- private static ValueEval evaluateNot(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
- if (args.length != 1) {
- return ErrorEval.VALUE_INVALID;
- }
- java.util.function.Function<ValueEval, ValueEval> notInner = (va) -> {
- try {
- ValueEval ve = OperandResolver.getSingleValue(va, srcRowIndex, srcColumnIndex);
- Boolean b = OperandResolver.coerceValueToBoolean(ve, false);
- boolean boolArgVal = b != null && b;
- return BoolEval.valueOf(!boolArgVal);
- } catch (EvaluationException e) {
- return e.getErrorEval();
- }
- };
+ if (arg == MissingArgEval.instance) {
+ tempVe = false; // missing parameters are treated as FALSE
+ } else {
+ tempVe = OperandResolver.coerceValueToBoolean(arg, false);
+ }
+
+ if (tempVe != null) {
+ result = partialEvaluate(result, tempVe);
+ atLeastOneNonBlank = true;
+ }
+ }
+
+ if (!atLeastOneNonBlank) {
+ throw new EvaluationException(ErrorEval.VALUE_INVALID);
+ }
+ return result;
+ }
+
+
+ protected abstract boolean getInitialResultValue();
+ protected abstract boolean partialEvaluate(boolean cumulativeResult, boolean currentValue);
+
+
+ public static final Function AND = new BooleanFunction() {
+ protected boolean getInitialResultValue() {
+ return true;
+ }
+ protected boolean partialEvaluate(boolean cumulativeResult, boolean currentValue) {
+ return cumulativeResult && currentValue;
+ }
+ };
+ public static final Function OR = new BooleanFunction() {
+ protected boolean getInitialResultValue() {
+ return false;
+ }
+ protected boolean partialEvaluate(boolean cumulativeResult, boolean currentValue) {
+ return cumulativeResult || currentValue;
+ }
+ };
+
+ public static final Function FALSE = BooleanFunction::evaluateFalse;
+
+ public static final Function TRUE = BooleanFunction::evaluateTrue;
+
+ public static final Function NOT = BooleanFunction::evaluateNot;
+
+ @Override
+ public ValueEval evaluateArray(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
+ if (args.length != 1) {
+ return ErrorEval.VALUE_INVALID;
+ }
+ return evaluateOneArrayArg(args[0], srcRowIndex, srcColumnIndex,
+ vA -> evaluate(new ValueEval[]{vA}, srcRowIndex, srcColumnIndex));
+ }
+
+ private static ValueEval evaluateFalse(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
+ return args.length != 0 ? ErrorEval.VALUE_INVALID : BoolEval.FALSE;
+ }
+
+ private static ValueEval evaluateTrue(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
+ return args.length != 0 ? ErrorEval.VALUE_INVALID : BoolEval.TRUE;
+ }
+
+ private static ValueEval evaluateNot(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
+ if (args.length != 1) {
+ return ErrorEval.VALUE_INVALID;
+ }
+ java.util.function.Function<ValueEval, ValueEval> notInner = (va) -> {
+ try {
+ ValueEval ve = OperandResolver.getSingleValue(va, srcRowIndex, srcColumnIndex);
+ Boolean b = OperandResolver.coerceValueToBoolean(ve, false);
+ boolean boolArgVal = b != null && b;
+ return BoolEval.valueOf(!boolArgVal);
+ } catch (EvaluationException e) {
+ return e.getErrorEval();
+ }
+ };
- return ArrayFunction._evaluateOneArrayArg(args[0], srcRowIndex, srcColumnIndex, notInner);
- }
+ return ArrayFunction._evaluateOneArrayArg(args[0], srcRowIndex, srcColumnIndex, notInner);
+ }
}
\ No newline at end of file
Modified: poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/CalendarFieldFunction.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/CalendarFieldFunction.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/CalendarFieldFunction.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/CalendarFieldFunction.java Sat May 22 20:56:44 2021
@@ -32,56 +32,56 @@ import org.apache.poi.ss.usermodel.DateU
* Time - HOUR, MINUTE and SECOND
*/
public final class CalendarFieldFunction extends Fixed1ArgFunction {
- public static final Function YEAR = new CalendarFieldFunction(Calendar.YEAR);
- public static final Function MONTH = new CalendarFieldFunction(Calendar.MONTH);
- public static final Function DAY = new CalendarFieldFunction(Calendar.DAY_OF_MONTH);
- public static final Function HOUR = new CalendarFieldFunction(Calendar.HOUR_OF_DAY);
+ public static final Function YEAR = new CalendarFieldFunction(Calendar.YEAR);
+ public static final Function MONTH = new CalendarFieldFunction(Calendar.MONTH);
+ public static final Function DAY = new CalendarFieldFunction(Calendar.DAY_OF_MONTH);
+ public static final Function HOUR = new CalendarFieldFunction(Calendar.HOUR_OF_DAY);
public static final Function MINUTE = new CalendarFieldFunction(Calendar.MINUTE);
public static final Function SECOND = new CalendarFieldFunction(Calendar.SECOND);
- private final int _dateFieldId;
+ private final int _dateFieldId;
- private CalendarFieldFunction(int dateFieldId) {
- _dateFieldId = dateFieldId;
- }
-
- public final ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) {
- double val;
- try {
- ValueEval ve = OperandResolver.getSingleValue(arg0, srcRowIndex, srcColumnIndex);
- val = OperandResolver.coerceValueToDouble(ve);
- } catch (EvaluationException e) {
- return e.getErrorEval();
- }
- if (val < 0) {
- return ErrorEval.NUM_ERROR;
- }
- return new NumberEval(getCalField(val));
- }
-
- private int getCalField(double serialDate) {
- // For some reason, a date of 0 in Excel gets shown
- // as the non existant 1900-01-00
- if (((int)serialDate) == 0) {
- switch (_dateFieldId) {
- case Calendar.YEAR: return 1900;
- case Calendar.MONTH: return 1;
- case Calendar.DAY_OF_MONTH: return 0;
- }
- // They want time, that's normal
- }
-
- // TODO Figure out if we're in 1900 or 1904
- // EXCEL functions round up nearly a half second (probably to prevent floating point
- // rounding issues); use UTC here to prevent daylight saving issues for HOUR
- Calendar c = DateUtil.getJavaCalendarUTC(serialDate + 0.4995 / DateUtil.SECONDS_PER_DAY, false);
- int result = c.get(_dateFieldId);
-
- // Month is a special case due to C semantics
- if (_dateFieldId == Calendar.MONTH) {
- result++;
- }
+ private CalendarFieldFunction(int dateFieldId) {
+ _dateFieldId = dateFieldId;
+ }
+
+ public final ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) {
+ double val;
+ try {
+ ValueEval ve = OperandResolver.getSingleValue(arg0, srcRowIndex, srcColumnIndex);
+ val = OperandResolver.coerceValueToDouble(ve);
+ } catch (EvaluationException e) {
+ return e.getErrorEval();
+ }
+ if (val < 0) {
+ return ErrorEval.NUM_ERROR;
+ }
+ return new NumberEval(getCalField(val));
+ }
+
+ private int getCalField(double serialDate) {
+ // For some reason, a date of 0 in Excel gets shown
+ // as the non existant 1900-01-00
+ if (((int)serialDate) == 0) {
+ switch (_dateFieldId) {
+ case Calendar.YEAR: return 1900;
+ case Calendar.MONTH: return 1;
+ case Calendar.DAY_OF_MONTH: return 0;
+ }
+ // They want time, that's normal
+ }
+
+ // TODO Figure out if we're in 1900 or 1904
+ // EXCEL functions round up nearly a half second (probably to prevent floating point
+ // rounding issues); use UTC here to prevent daylight saving issues for HOUR
+ Calendar c = DateUtil.getJavaCalendarUTC(serialDate + 0.4995 / DateUtil.SECONDS_PER_DAY, false);
+ int result = c.get(_dateFieldId);
+
+ // Month is a special case due to C semantics
+ if (_dateFieldId == Calendar.MONTH) {
+ result++;
+ }
- return result;
- }
+ return result;
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org