]> source.dussan.org Git - poi.git/commitdiff
added fixed arg function interfaces, converted some functions
authorJosh Micich <josh@apache.org>
Sun, 22 Nov 2009 07:29:40 +0000 (07:29 +0000)
committerJosh Micich <josh@apache.org>
Sun, 22 Nov 2009 07:29:40 +0000 (07:29 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@883045 13f79535-47bb-0310-9956-ffa450edef68

37 files changed:
src/java/org/apache/poi/hssf/record/formula/eval/ConcatEval.java
src/java/org/apache/poi/hssf/record/formula/eval/IntersectionEval.java
src/java/org/apache/poi/hssf/record/formula/eval/PercentEval.java
src/java/org/apache/poi/hssf/record/formula/eval/RangeEval.java
src/java/org/apache/poi/hssf/record/formula/eval/RelationalOperationEval.java
src/java/org/apache/poi/hssf/record/formula/eval/TwoOperandNumericOperation.java
src/java/org/apache/poi/hssf/record/formula/eval/UnaryMinusEval.java
src/java/org/apache/poi/hssf/record/formula/eval/UnaryPlusEval.java
src/java/org/apache/poi/hssf/record/formula/functions/CalendarFieldFunction.java
src/java/org/apache/poi/hssf/record/formula/functions/Column.java
src/java/org/apache/poi/hssf/record/formula/functions/Columns.java
src/java/org/apache/poi/hssf/record/formula/functions/Countblank.java
src/java/org/apache/poi/hssf/record/formula/functions/Countif.java
src/java/org/apache/poi/hssf/record/formula/functions/DateFunc.java
src/java/org/apache/poi/hssf/record/formula/functions/Errortype.java
src/java/org/apache/poi/hssf/record/formula/functions/Fixed0ArgFunction.java [new file with mode: 0644]
src/java/org/apache/poi/hssf/record/formula/functions/Fixed1ArgFunction.java [new file with mode: 0644]
src/java/org/apache/poi/hssf/record/formula/functions/Fixed2ArgFunction.java [new file with mode: 0644]
src/java/org/apache/poi/hssf/record/formula/functions/Fixed3ArgFunction.java [new file with mode: 0644]
src/java/org/apache/poi/hssf/record/formula/functions/Fixed4ArgFunction.java [new file with mode: 0644]
src/java/org/apache/poi/hssf/record/formula/functions/Function0Arg.java [new file with mode: 0644]
src/java/org/apache/poi/hssf/record/formula/functions/Function1Arg.java [new file with mode: 0644]
src/java/org/apache/poi/hssf/record/formula/functions/Function2Arg.java [new file with mode: 0644]
src/java/org/apache/poi/hssf/record/formula/functions/Function3Arg.java [new file with mode: 0644]
src/java/org/apache/poi/hssf/record/formula/functions/Function4Arg.java [new file with mode: 0644]
src/java/org/apache/poi/hssf/record/formula/functions/Na.java
src/java/org/apache/poi/hssf/record/formula/functions/Now.java
src/java/org/apache/poi/hssf/record/formula/functions/NumericFunction.java
src/java/org/apache/poi/hssf/record/formula/functions/Replace.java
src/java/org/apache/poi/hssf/record/formula/functions/Row.java
src/java/org/apache/poi/hssf/record/formula/functions/Rows.java
src/java/org/apache/poi/hssf/record/formula/functions/T.java
src/java/org/apache/poi/hssf/record/formula/functions/Time.java
src/java/org/apache/poi/hssf/record/formula/functions/Today.java
src/java/org/apache/poi/hssf/record/formula/functions/Value.java
src/java/org/apache/poi/hssf/record/formula/functions/Var2or3ArgFunction.java
src/java/org/apache/poi/hssf/record/formula/functions/XYNumericFunction.java

index 0db4994b59693dfec262158a1ee78f8c9e685687..53d8c7bc29154c9d6e1560711ecf83e164c3393a 100644 (file)
 
 package org.apache.poi.hssf.record.formula.eval;
 
+import org.apache.poi.hssf.record.formula.functions.Fixed2ArgFunction;
 import org.apache.poi.hssf.record.formula.functions.Function;
 
 /**
  * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
  */
-public final class ConcatEval implements Function {
+public final class ConcatEval  extends Fixed2ArgFunction {
 
        public static final Function instance = new ConcatEval();
 
@@ -30,29 +31,30 @@ public final class ConcatEval implements Function {
                // enforce singleton
        }
 
-       public ValueEval evaluate(ValueEval[] args, int srcRow, int srcCol) {
-               if(args.length != 2) {
-                       return ErrorEval.VALUE_INVALID;
-               }
-               StringBuffer sb = new StringBuffer();
+       public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) {
+               ValueEval ve0;
+               ValueEval ve1;
                try {
-                       for (int i = 0; i < 2; i++) {
-
-                               ValueEval ve = OperandResolver.getSingleValue(args[i], srcRow, srcCol);
-                               if (ve instanceof StringValueEval) {
-                                       StringValueEval sve = (StringValueEval) ve;
-                                       sb.append(sve.getStringValue());
-                               } else if (ve == BlankEval.INSTANCE) {
-                                       // do nothing
-                               } else {
-                                       throw new RuntimeException("Unexpected value type ("
-                                                       + ve.getClass().getName() + ")");
-                               }
-                       }
+                       ve0 = OperandResolver.getSingleValue(arg0, srcRowIndex, srcColumnIndex);
+                       ve1 = OperandResolver.getSingleValue(arg1, srcRowIndex, srcColumnIndex);
                } catch (EvaluationException e) {
                        return e.getErrorEval();
                }
-
+               StringBuilder sb = new StringBuilder();
+               sb.append(getText(ve0));
+               sb.append(getText(ve1));
                return new StringEval(sb.toString());
        }
+
+       private Object getText(ValueEval ve) {
+               if (ve instanceof StringValueEval) {
+                       StringValueEval sve = (StringValueEval) ve;
+                       return sve.getStringValue();
+               }
+               if (ve == BlankEval.INSTANCE) {
+                       return "";
+               }
+               throw new IllegalAccessError("Unexpected value type ("
+                                       + ve.getClass().getName() + ")");
+       }
 }
index b208bcd6471c3a6016d5eb5bc31d2829bf1d2794..e30df36f59589580ee48362190db0c70b656f963 100644 (file)
 
 package org.apache.poi.hssf.record.formula.eval;
 
+import org.apache.poi.hssf.record.formula.functions.Fixed2ArgFunction;
 import org.apache.poi.hssf.record.formula.functions.Function;
 
 /**
  * @author Josh Micich
  */
-public final class IntersectionEval implements Function {
+public final class IntersectionEval  extends Fixed2ArgFunction {
 
        public static final Function instance = new IntersectionEval();
 
@@ -30,14 +31,11 @@ public final class IntersectionEval implements Function {
                // enforces singleton
        }
 
-       public ValueEval evaluate(ValueEval[] args, int srcRow, int srcCol) {
-               if(args.length != 2) {
-                       return ErrorEval.VALUE_INVALID;
-               }
+       public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) {
 
                try {
-                       AreaEval reA = evaluateRef(args[0]);
-                       AreaEval reB = evaluateRef(args[1]);
+                       AreaEval reA = evaluateRef(arg0);
+                       AreaEval reB = evaluateRef(arg1);
                        AreaEval result = resolveRange(reA, reB);
                        if (result == null) {
                                return ErrorEval.NULL_INTERSECTION;
index 0d509cc4388f718f12ec3b0d3193ade376dda043..93db027b301e6c52043c61a0af13b2598e8088e5 100644 (file)
@@ -17,6 +17,7 @@
 
 package org.apache.poi.hssf.record.formula.eval;
 
+import org.apache.poi.hssf.record.formula.functions.Fixed1ArgFunction;
 import org.apache.poi.hssf.record.formula.functions.Function;
 
 
@@ -24,7 +25,7 @@ import org.apache.poi.hssf.record.formula.functions.Function;
  * Implementation of Excel formula token '%'. <p/>
  * @author Josh Micich
  */
-public final class PercentEval implements Function {
+public final class PercentEval extends Fixed1ArgFunction {
 
        public static final Function instance = new PercentEval();
 
@@ -32,13 +33,10 @@ public final class PercentEval implements Function {
                // enforce singleton
        }
 
-       public ValueEval evaluate(ValueEval[] args, int srcRow, int srcCol) {
-               if (args.length != 1) {
-                       return ErrorEval.VALUE_INVALID;
-               }
+       public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) {
                double d;
                try {
-                       ValueEval ve = OperandResolver.getSingleValue(args[0], srcRow, srcCol);
+                       ValueEval ve = OperandResolver.getSingleValue(arg0, srcRowIndex, srcColumnIndex);
                        d = OperandResolver.coerceValueToDouble(ve);
                } catch (EvaluationException e) {
                        return e.getErrorEval();
index bd821f0acbee4ac01bccf8f609500532840e7178..6a8186c7b7ea65901bdbf7174f6be5cd6a867591 100644 (file)
@@ -17,6 +17,7 @@
 
 package org.apache.poi.hssf.record.formula.eval;
 
+import org.apache.poi.hssf.record.formula.functions.Fixed2ArgFunction;
 import org.apache.poi.hssf.record.formula.functions.Function;
 
 
@@ -24,7 +25,7 @@ import org.apache.poi.hssf.record.formula.functions.Function;
  *
  * @author Josh Micich
  */
-public final class RangeEval implements Function {
+public final class RangeEval extends Fixed2ArgFunction {
 
        public static final Function instance = new RangeEval();
 
@@ -32,14 +33,11 @@ public final class RangeEval implements Function {
                // enforces singleton
        }
 
-       public ValueEval evaluate(ValueEval[] args, int srcRow, int srcCol) {
-               if(args.length != 2) {
-                       return ErrorEval.VALUE_INVALID;
-               }
+       public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) {
 
                try {
-                       AreaEval reA = evaluateRef(args[0]);
-                       AreaEval reB = evaluateRef(args[1]);
+                       AreaEval reA = evaluateRef(arg0);
+                       AreaEval reB = evaluateRef(arg1);
                        return resolveRange(reA, reB);
                } catch (EvaluationException e) {
                        return e.getErrorEval();
index 35cf5b43476b4f3558a22741adc54d33acbeb9b9..63b68c441a059e17ebadc9b930c17ba1240b8d30 100644 (file)
@@ -17,6 +17,7 @@
 
 package org.apache.poi.hssf.record.formula.eval;
 
+import org.apache.poi.hssf.record.formula.functions.Fixed2ArgFunction;
 import org.apache.poi.hssf.record.formula.functions.Function;
 import org.apache.poi.ss.util.NumberComparer;
 
@@ -25,7 +26,7 @@ import org.apache.poi.ss.util.NumberComparer;
  *
  * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
  */
-public abstract class RelationalOperationEval implements Function {
+public abstract class RelationalOperationEval extends Fixed2ArgFunction {
 
        /**
         * Converts a standard compare result (-1, 0, 1) to <code>true</code> or <code>false</code>
@@ -55,16 +56,13 @@ public abstract class RelationalOperationEval implements Function {
         * Blank < Positive numbers
         * </pre>
         */
-       public final ValueEval evaluate(ValueEval[] operands, int srcRow, int srcCol) {
-               if (operands.length != 2) {
-                       return ErrorEval.VALUE_INVALID;
-               }
+       public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) {
 
                ValueEval vA;
                ValueEval vB;
                try {
-                       vA = OperandResolver.getSingleValue(operands[0], srcRow, srcCol);
-                       vB = OperandResolver.getSingleValue(operands[1], srcRow, srcCol);
+                       vA = OperandResolver.getSingleValue(arg0, srcRowIndex, srcColumnIndex);
+                       vB = OperandResolver.getSingleValue(arg1, srcRowIndex, srcColumnIndex);
                } catch (EvaluationException e) {
                        return e.getErrorEval();
                }
index 1584e17bba26493095bbd54473d9364ee92244c6..7e6ac8836453baa45e2ec1a59bfbf98e9debc05a 100644 (file)
 
 package org.apache.poi.hssf.record.formula.eval;
 
+import org.apache.poi.hssf.record.formula.functions.Fixed2ArgFunction;
 import org.apache.poi.hssf.record.formula.functions.Function;
 
 /**
  * @author Josh Micich
  */
-public abstract class TwoOperandNumericOperation implements Function {
+public abstract class TwoOperandNumericOperation extends Fixed2ArgFunction {
 
        protected final double singleOperandEvaluate(ValueEval arg, int srcCellRow, int srcCellCol) throws EvaluationException {
                ValueEval ve = OperandResolver.getSingleValue(arg, srcCellRow, srcCellCol);
                return OperandResolver.coerceValueToDouble(ve);
        }
-
-       public final ValueEval evaluate(ValueEval[] args, int srcCellRow, int srcCellCol) {
+       public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) {
                double result;
                try {
-                       double d0 = singleOperandEvaluate(args[0], srcCellRow, srcCellCol);
-                       double d1 = singleOperandEvaluate(args[1], srcCellRow, srcCellCol);
+                       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 '^'
@@ -49,6 +49,7 @@ public abstract class TwoOperandNumericOperation implements Function {
                }
                return new NumberEval(result);
        }
+
        protected abstract double evaluate(double d0, double d1) throws EvaluationException;
 
        public static final Function AddEval = new TwoOperandNumericOperation() {
index 0d87ab036a03d1cdfef66344ab78ac953875be06..ba5f197dce9ac8fe6672366da1379828399fcb4a 100644 (file)
 
 package org.apache.poi.hssf.record.formula.eval;
 
+import org.apache.poi.hssf.record.formula.functions.Fixed1ArgFunction;
 import org.apache.poi.hssf.record.formula.functions.Function;
 
-
 /**
  * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
- *
  */
-public final class UnaryMinusEval implements Function {
+public final class UnaryMinusEval extends Fixed1ArgFunction {
 
        public static final Function instance = new UnaryMinusEval();
 
@@ -32,13 +31,10 @@ public final class UnaryMinusEval implements Function {
                // enforce singleton
        }
 
-       public ValueEval evaluate(ValueEval[] args, int srcRow, int srcCol) {
-               if (args.length != 1) {
-                       return ErrorEval.VALUE_INVALID;
-               }
+       public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) {
                double d;
                try {
-                       ValueEval ve = OperandResolver.getSingleValue(args[0], srcRow, srcCol);
+                       ValueEval ve = OperandResolver.getSingleValue(arg0, srcRowIndex, srcColumnIndex);
                        d = OperandResolver.coerceValueToDouble(ve);
                } catch (EvaluationException e) {
                        return e.getErrorEval();
index e2b137b4b3d826b6514dc4efd548a102d7d91c57..b6f32e9b61c727358ec3441f88c4f19f4937e9a5 100644 (file)
 
 package org.apache.poi.hssf.record.formula.eval;
 
+import org.apache.poi.hssf.record.formula.functions.Fixed1ArgFunction;
 import org.apache.poi.hssf.record.formula.functions.Function;
 
 
 /**
  * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
- *
  */
-public final class UnaryPlusEval implements Function {
+public final class UnaryPlusEval extends Fixed1ArgFunction {
 
        public static final Function instance = new UnaryPlusEval();
 
@@ -32,13 +32,10 @@ public final class UnaryPlusEval implements Function {
                // enforce singleton
        }
 
-       public ValueEval evaluate(ValueEval[] args, int srcCellRow, int srcCellCol) {
-               if(args.length != 1) {
-                       return ErrorEval.VALUE_INVALID;
-               }
+       public ValueEval evaluate(int srcCellRow, int srcCellCol, ValueEval arg0) {
                double d;
                try {
-                       ValueEval ve = OperandResolver.getSingleValue(args[0], srcCellRow, srcCellCol);
+                       ValueEval ve = OperandResolver.getSingleValue(arg0, srcCellRow, srcCellCol);
                        if(ve instanceof StringEval) {
                                // Note - asymmetric with UnaryMinus
                                // -"hello" evaluates to #VALUE!
index a4c445aa55c44e8ac4cfbb7e2915a2e10f05b74d..3261f209be820a068b7066072a3959c601ee9a26 100644 (file)
@@ -34,7 +34,7 @@ import org.apache.poi.hssf.usermodel.HSSFDateUtil;
  *
  * @author Guenter Kickinger g.kickinger@gmx.net
  */
-public final class CalendarFieldFunction implements Function {
+public final class CalendarFieldFunction extends Fixed1ArgFunction {
 
        public static final Function YEAR = new CalendarFieldFunction(Calendar.YEAR, false);
        public static final Function MONTH = new CalendarFieldFunction(Calendar.MONTH, true);
@@ -48,14 +48,10 @@ public final class CalendarFieldFunction implements Function {
                _needsOneBaseAdjustment = needsOneBaseAdjustment;
        }
 
-       public ValueEval evaluate(ValueEval[] operands, int srcCellRow, int srcCellCol) {
-               if (operands.length != 1) {
-                       return ErrorEval.VALUE_INVALID;
-               }
-
+       public final ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) {
                int val;
                try {
-                       ValueEval ve = OperandResolver.getSingleValue(operands[0], srcCellRow, srcCellCol);
+                       ValueEval ve = OperandResolver.getSingleValue(arg0, srcRowIndex, srcColumnIndex);
                        val = OperandResolver.coerceValueToInt(ve);
                } catch (EvaluationException e) {
                        return e.getErrorEval();
index e984cc2c7b0d7da9d7105d0b95009cb5cc1109b9..02a34b4e27d00e12dd63215b66435a5f00a3e165 100644 (file)
@@ -23,39 +23,32 @@ import org.apache.poi.hssf.record.formula.eval.NumberEval;
 import org.apache.poi.hssf.record.formula.eval.RefEval;
 import org.apache.poi.hssf.record.formula.eval.ValueEval;
 
-public final class Column implements Function {
-    public ValueEval evaluate(ValueEval[] evals, int srcCellRow, int srcCellCol) {
-        ValueEval retval = null;
-        int cnum = -1;
-
-        switch (evals.length) {
-        default:
-            retval = ErrorEval.VALUE_INVALID;
-        case 1:
-            if (evals[0] instanceof AreaEval) {
-                AreaEval ae = (AreaEval) evals[0];
-                cnum = ae.getFirstColumn();
-            }
-            else if (evals[0] instanceof RefEval) {
-                RefEval re = (RefEval) evals[0];
-                cnum = re.getColumn();
-            }
-            else { // anything else is not valid argument
-                retval = ErrorEval.VALUE_INVALID;
-            }
-            break;
-        case 0:
-            cnum = srcCellCol;
-        }
+public final class Column implements Function0Arg, Function1Arg {
 
-        if (retval == null) {
-            retval = (cnum >= 0)
-                    ? new NumberEval(cnum + 1) // +1 since excel colnums are 1 based
-                    : (ValueEval) ErrorEval.VALUE_INVALID;
+    public ValueEval evaluate(int srcRowIndex, int srcColumnIndex) {
+        return new NumberEval(srcColumnIndex+1);
+    }
+    public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) {
+        int rnum;
+
+        if (arg0 instanceof AreaEval) {
+            rnum = ((AreaEval) arg0).getFirstColumn();
+        } else if (arg0 instanceof RefEval) {
+            rnum = ((RefEval) arg0).getColumn();
+        } else {
+            // anything else is not valid argument
+            return ErrorEval.VALUE_INVALID;
         }
 
-        return retval;
+        return new NumberEval(rnum + 1);
+    }
+    public ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
+        switch (args.length) {
+            case 1:
+                return evaluate(srcRowIndex, srcColumnIndex, args[0]);
+            case 0:
+                return new NumberEval(srcColumnIndex+1);
+        }
+        return ErrorEval.VALUE_INVALID;
     }
-
-
 }
index ca0e97f30558aad775b5f3f37ea2a99ab5b8cd74..0ef7e0632437acdc2ca4e0196344945d5671349f 100644 (file)
@@ -28,27 +28,14 @@ import org.apache.poi.hssf.record.formula.eval.ValueEval;
  *
  * @author Josh Micich
  */
-public final class Columns implements Function {
+public final class Columns extends Fixed1ArgFunction {
 
-       public ValueEval evaluate(ValueEval[] args, int srcCellRow, int srcCellCol) {
-               switch(args.length) {
-                       case 1:
-                               // expected
-                               break;
-                       case 0:
-                               // too few arguments
-                               return ErrorEval.VALUE_INVALID;
-                       default:
-                               // too many arguments
-                               return ErrorEval.VALUE_INVALID;
-               }
-               ValueEval firstArg = args[0];
+       public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) {
 
                int result;
-               if (firstArg instanceof AreaEval) {
-                       AreaEval ae = (AreaEval) firstArg;
-                       result = ae.getLastColumn() - ae.getFirstColumn() + 1;
-               } else if (firstArg instanceof RefEval) {
+               if (arg0 instanceof AreaEval) {
+                       result = ((AreaEval) arg0).getWidth();
+               } else if (arg0 instanceof RefEval) {
                        result = 1;
                } else { // anything else is not valid argument
                        return ErrorEval.VALUE_INVALID;
index 473976e330e1ea32dafcd41a8fbd575df7900173..a668225da42b1f2dbb1470a00ac3b7f0fc9a65ab 100644 (file)
@@ -19,7 +19,6 @@ package org.apache.poi.hssf.record.formula.functions;
 
 import org.apache.poi.hssf.record.formula.eval.AreaEval;
 import org.apache.poi.hssf.record.formula.eval.BlankEval;
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
 import org.apache.poi.hssf.record.formula.eval.NumberEval;
 import org.apache.poi.hssf.record.formula.eval.RefEval;
 import org.apache.poi.hssf.record.formula.eval.ValueEval;
@@ -36,17 +35,11 @@ import org.apache.poi.hssf.record.formula.functions.CountUtils.I_MatchPredicate;
  *
  * @author Mads Mohr Christensen
  */
-public final class Countblank implements Function {
+public final class Countblank extends Fixed1ArgFunction {
 
-       public ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
-               if (args.length != 1) {
-                       // TODO - it doesn't seem to be possible to enter COUNTBLANK() into Excel with the wrong arg count
-                       // perhaps this should be an exception
-                       return ErrorEval.VALUE_INVALID;
-               }
+       public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) {
 
                double result;
-               ValueEval arg0 = args[0];
                if (arg0 instanceof RefEval) {
                        result = CountUtils.countMatchingCell((RefEval) arg0, predicate);
                } else if (arg0 instanceof AreaEval) {
index 2b45debec9982896191883f565b819fb93133588..77fdf9bfc7915a69a7dd1b5e8439fbafd12958ec 100644 (file)
@@ -44,7 +44,7 @@ import org.apache.poi.ss.usermodel.ErrorConstants;
  *
  * @author Josh Micich
  */
-public final class Countif implements Function {
+public final class Countif extends Fixed2ArgFunction {
 
        private static final class CmpOp {
                public static final int NONE = 0;
@@ -400,23 +400,14 @@ public final class Countif implements Function {
                }
        }
 
-       public ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
-               switch(args.length) {
-                       case 2:
-                               // expected
-                               break;
-                       default:
-                               // TODO - it doesn't seem to be possible to enter COUNTIF() into Excel with the wrong arg count
-                               // perhaps this should be an exception
-                               return ErrorEval.VALUE_INVALID;
-               }
+       public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) {
 
-               I_MatchPredicate mp = createCriteriaPredicate(args[1], srcRowIndex, srcColumnIndex);
+               I_MatchPredicate mp = createCriteriaPredicate(arg1, srcRowIndex, srcColumnIndex);
                if(mp == null) {
                        // If the criteria arg is a reference to a blank cell, countif always returns zero.
                        return NumberEval.ZERO;
                }
-               double result = countMatchingCellsInArea(args[0], mp);
+               double result = countMatchingCellsInArea(arg0, mp);
                return new NumberEval(result);
        }
        /**
index 8c06837168da83300304082277c4550a381cd54d..ca6df7ae23abe78b2f60ca7c8334f673759be650 100644 (file)
@@ -22,23 +22,37 @@ import java.util.GregorianCalendar;
 
 import org.apache.poi.hssf.record.formula.eval.ErrorEval;
 import org.apache.poi.hssf.record.formula.eval.EvaluationException;
+import org.apache.poi.hssf.record.formula.eval.NumberEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
 import org.apache.poi.hssf.usermodel.HSSFDateUtil;
 
+
 /**
  * @author Pavel Krupets (pkrupets at palmtreebusiness dot com)
  */
-public final class DateFunc extends NumericFunction.MultiArg {
+public final class DateFunc extends Fixed3ArgFunction {
 
        public static final Function instance = new DateFunc();
 
        private DateFunc() {
-               super(3,3);
+               // no fields to initialise
+       }
+       public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1,
+                       ValueEval arg2) {
+               double result;
+               try {
+                       double d0 = NumericFunction.singleOperandEvaluate(arg0, srcRowIndex, srcColumnIndex);
+                       double d1 = NumericFunction.singleOperandEvaluate(arg1, srcRowIndex, srcColumnIndex);
+                       double d2 = NumericFunction.singleOperandEvaluate(arg2, srcRowIndex, srcColumnIndex);
+                       result = evaluate(getYear(d0), (int) (d1 - 1), (int) d2);
+                       NumericFunction.checkValue(result);
+               } catch (EvaluationException e) {
+                       return e.getErrorEval();
+               }
+               return new NumberEval(result);
        }
 
-       protected double evaluate(double[] ds) throws EvaluationException {
-               int year = getYear(ds[0]);
-               int month = (int) ds[1] - 1;
-               int day = (int) ds[2];
+       private static double evaluate(int year, int month, int day) throws EvaluationException {
 
                if (year < 0 || month < 0 || day < 0) {
                        throw new EvaluationException(ErrorEval.VALUE_INVALID);
index f96f3b2d8cbeb4e910462c39e279a774ec952019..72de76273c4facf4d09c982823805ff5dd70a44b 100644 (file)
@@ -50,12 +50,12 @@ import org.apache.poi.hssf.usermodel.HSSFErrorConstants;
  *
  * @author Josh Micich
  */
-public final class Errortype implements Function {
+public final class Errortype extends Fixed1ArgFunction {
 
-       public ValueEval evaluate(ValueEval[] args, int srcCellRow, int srcCellCol) {
+       public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) {
 
                try {
-                       OperandResolver.getSingleValue(args[0], srcCellRow, srcCellCol);
+                       OperandResolver.getSingleValue(arg0, srcRowIndex, srcColumnIndex);
                        return ErrorEval.NA;
                } catch (EvaluationException e) {
                        int result = translateErrorCodeToErrorTypeValue(e.getErrorEval().getErrorCode());
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Fixed0ArgFunction.java b/src/java/org/apache/poi/hssf/record/formula/functions/Fixed0ArgFunction.java
new file mode 100644 (file)
index 0000000..ff3207b
--- /dev/null
@@ -0,0 +1,35 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.hssf.record.formula.functions;
+
+import org.apache.poi.hssf.record.formula.eval.ErrorEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+
+/**
+ * Convenience base class for functions that only take zero arguments.
+ *
+ * @author Josh Micich
+ */
+public abstract class Fixed0ArgFunction implements Function0Arg {
+       public final ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
+               if (args.length != 0) {
+                       return ErrorEval.VALUE_INVALID;
+               }
+               return evaluate(srcRowIndex, srcColumnIndex);
+       }
+}
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Fixed1ArgFunction.java b/src/java/org/apache/poi/hssf/record/formula/functions/Fixed1ArgFunction.java
new file mode 100644 (file)
index 0000000..6a12d9e
--- /dev/null
@@ -0,0 +1,35 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.hssf.record.formula.functions;
+
+import org.apache.poi.hssf.record.formula.eval.ErrorEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+
+/**
+ * Convenience base class for functions that must take exactly one argument.
+ *
+ * @author Josh Micich
+ */
+public abstract class Fixed1ArgFunction implements Function1Arg {
+       public final ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
+               if (args.length != 1) {
+                       return ErrorEval.VALUE_INVALID;
+               }
+               return evaluate(srcRowIndex, srcColumnIndex, args[0]);
+       }
+}
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Fixed2ArgFunction.java b/src/java/org/apache/poi/hssf/record/formula/functions/Fixed2ArgFunction.java
new file mode 100644 (file)
index 0000000..7695920
--- /dev/null
@@ -0,0 +1,35 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.hssf.record.formula.functions;
+
+import org.apache.poi.hssf.record.formula.eval.ErrorEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+
+/**
+ * Convenience base class for functions that must take exactly two arguments.
+ *
+ * @author Josh Micich
+ */
+public abstract class Fixed2ArgFunction implements Function2Arg {
+       public final ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
+               if (args.length != 2) {
+                       return ErrorEval.VALUE_INVALID;
+               }
+               return evaluate(srcRowIndex, srcColumnIndex, args[0], args[1]);
+       }
+}
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Fixed3ArgFunction.java b/src/java/org/apache/poi/hssf/record/formula/functions/Fixed3ArgFunction.java
new file mode 100644 (file)
index 0000000..d4488ab
--- /dev/null
@@ -0,0 +1,35 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.hssf.record.formula.functions;
+
+import org.apache.poi.hssf.record.formula.eval.ErrorEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+
+/**
+ * Convenience base class for functions that must take exactly three arguments.
+ *
+ * @author Josh Micich
+ */
+public abstract class Fixed3ArgFunction implements Function3Arg {
+       public final ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
+               if (args.length != 3) {
+                       return ErrorEval.VALUE_INVALID;
+               }
+               return evaluate(srcRowIndex, srcColumnIndex, args[0], args[1], args[2]);
+       }
+}
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Fixed4ArgFunction.java b/src/java/org/apache/poi/hssf/record/formula/functions/Fixed4ArgFunction.java
new file mode 100644 (file)
index 0000000..5588714
--- /dev/null
@@ -0,0 +1,35 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.hssf.record.formula.functions;
+
+import org.apache.poi.hssf.record.formula.eval.ErrorEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+
+/**
+ * Convenience base class for functions that must take exactly four arguments.
+ *
+ * @author Josh Micich
+ */
+public abstract class Fixed4ArgFunction implements Function4Arg {
+       public final ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
+               if (args.length != 4) {
+                       return ErrorEval.VALUE_INVALID;
+               }
+               return evaluate(srcRowIndex, srcColumnIndex, args[0], args[1], args[2], args[3]);
+       }
+}
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Function0Arg.java b/src/java/org/apache/poi/hssf/record/formula/functions/Function0Arg.java
new file mode 100644 (file)
index 0000000..c61a87e
--- /dev/null
@@ -0,0 +1,32 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.hssf.record.formula.functions;
+
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+
+/**
+ * Implemented by all functions that can be called with zero arguments
+ *
+ * @author Josh Micich
+ */
+public interface Function0Arg extends Function {
+       /**
+        * see {@link Function#evaluate(ValueEval[], int, int)}
+        */
+       ValueEval evaluate(int srcRowIndex, int srcColumnIndex);
+}
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Function1Arg.java b/src/java/org/apache/poi/hssf/record/formula/functions/Function1Arg.java
new file mode 100644 (file)
index 0000000..42007fa
--- /dev/null
@@ -0,0 +1,32 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.hssf.record.formula.functions;
+
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+
+/**
+ * Implemented by all functions that can be called with one argument
+ *
+ * @author Josh Micich
+ */
+public interface Function1Arg extends Function {
+       /**
+        * see {@link Function#evaluate(ValueEval[], int, int)}
+        */
+       ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0);
+}
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Function2Arg.java b/src/java/org/apache/poi/hssf/record/formula/functions/Function2Arg.java
new file mode 100644 (file)
index 0000000..b0ef472
--- /dev/null
@@ -0,0 +1,32 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.hssf.record.formula.functions;
+
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+
+/**
+ * Implemented by all functions that can be called with two arguments
+ *
+ * @author Josh Micich
+ */
+public interface Function2Arg extends Function {
+       /**
+        * see {@link Function#evaluate(ValueEval[], int, int)}
+        */
+       ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1);
+}
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Function3Arg.java b/src/java/org/apache/poi/hssf/record/formula/functions/Function3Arg.java
new file mode 100644 (file)
index 0000000..7ee32b8
--- /dev/null
@@ -0,0 +1,32 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.hssf.record.formula.functions;
+
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+
+/**
+ * Implemented by all functions that can be called with three arguments
+ *
+ * @author Josh Micich
+ */
+public interface Function3Arg extends Function {
+       /**
+        * see {@link Function#evaluate(ValueEval[], int, int)}
+        */
+       ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1, ValueEval arg2);
+}
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Function4Arg.java b/src/java/org/apache/poi/hssf/record/formula/functions/Function4Arg.java
new file mode 100644 (file)
index 0000000..7089432
--- /dev/null
@@ -0,0 +1,32 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.hssf.record.formula.functions;
+
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+
+/**
+ * Implemented by all functions that can be called with four arguments
+ *
+ * @author Josh Micich
+ */
+public interface Function4Arg extends Function {
+       /**
+        * see {@link Function#evaluate(ValueEval[], int, int)}
+        */
+       ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1, ValueEval arg2, ValueEval arg3);
+}
index e1f9fa612a22f46ff55d8c695233f07466d6e8f3..c66080b9d51623099a6f47fa24feffc1a87a393a 100644 (file)
@@ -25,10 +25,9 @@ import org.apache.poi.hssf.record.formula.eval.ValueEval;
  *
  * @author Josh Micich
  */
-public final class Na implements Function {
+public final class Na extends Fixed0ArgFunction {
 
-       public ValueEval evaluate(ValueEval[] args, int srcCellRow, int srcCellCol) {
+       public ValueEval evaluate(int srcCellRow, int srcCellCol) {
                return ErrorEval.NA;
        }
-
 }
index a56bf27052eb7d71a45e119e5f151bf82465b362..766f5694d446c5ee80c3072e40696c28451c7fd0 100644 (file)
@@ -19,7 +19,6 @@ package org.apache.poi.hssf.record.formula.functions;
 
 import java.util.Date;
 
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
 import org.apache.poi.hssf.record.formula.eval.NumberEval;
 import org.apache.poi.hssf.record.formula.eval.ValueEval;
 import org.apache.poi.hssf.usermodel.HSSFDateUtil;
@@ -29,13 +28,9 @@ import org.apache.poi.hssf.usermodel.HSSFDateUtil;
  *
  * @author Frank Taffelt
  */
-public final class Now implements Function {
-
-       public ValueEval evaluate(ValueEval[] evals, int srcCellRow, int srcCellCol) {
-               if (evals.length > 0) {
-                       return ErrorEval.VALUE_INVALID;
-               }
+public final class Now extends Fixed0ArgFunction {
 
+       public ValueEval evaluate(int srcRowIndex, int srcColumnIndex) {
                Date now = new Date(System.currentTimeMillis());
                return new NumberEval(HSSFDateUtil.getExcelDate(now));
        }
index 01ef88c3c68d47e2dc27860ee956592739848824..24b0ae26920b3f67fc89f824fd4bcf410e7a1628 100644 (file)
@@ -39,7 +39,10 @@ public abstract class NumericFunction implements Function {
                return result;
        }
 
-       private static final void checkValue(double result) throws EvaluationException {
+       /**
+        * @throws EvaluationException (#NUM!) if <tt>result</tt> is <tt>NaN</> or <tt>Infinity</tt>
+        */
+       static final void checkValue(double result) throws EvaluationException {
                if (Double.isNaN(result) || Double.isInfinite(result)) {
                        throw new EvaluationException(ErrorEval.NUM_ERROR);
                }
index 2298656e7cdb117b49d778e81e153ce67aa0f7a5..f2af838f91c0189859fc5df044bee80fc43e0cdd 100644 (file)
@@ -37,18 +37,23 @@ import org.apache.poi.hssf.record.formula.eval.ValueEval;
  *
  * @author Manda Wilson &lt; wilson at c bio dot msk cc dot org &gt;
  */
-public final class Replace extends TextFunction {
+public final class Replace extends Fixed4ArgFunction {
 
-       protected ValueEval evaluateFunc(ValueEval[] args, int srcCellRow, int srcCellCol)
-               throws EvaluationException {
-               if (args.length != 4) {
-                       return ErrorEval.VALUE_INVALID;
-               }
+       public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1,
+                       ValueEval arg2, ValueEval arg3) {
 
-               String oldStr = evaluateStringArg(args[0], srcCellRow, srcCellCol);
-               int startNum = evaluateIntArg(args[1], srcCellRow, srcCellCol);
-               int numChars = evaluateIntArg(args[2], srcCellRow, srcCellCol);
-               String newStr = evaluateStringArg(args[3], srcCellRow, srcCellCol);
+               String oldStr;
+               int startNum;
+               int numChars;
+               String newStr;
+               try {
+                       oldStr = TextFunction.evaluateStringArg(arg0, srcRowIndex, srcColumnIndex);
+                       startNum = TextFunction.evaluateIntArg(arg1, srcRowIndex, srcColumnIndex);
+                       numChars = TextFunction.evaluateIntArg(arg2, srcRowIndex, srcColumnIndex);
+                       newStr = TextFunction.evaluateStringArg(arg3, srcRowIndex, srcColumnIndex);
+               } catch (EvaluationException e) {
+                       return e.getErrorEval();
+               }
 
                if (startNum < 1 || numChars < 0) {
                        return ErrorEval.VALUE_INVALID;
index d0d0acb2c57b28bfb5b2759fd273fa77ca9945f2..718ab7c27a76326fd5675483cd30cdab46f004d1 100644 (file)
@@ -23,39 +23,33 @@ import org.apache.poi.hssf.record.formula.eval.NumberEval;
 import org.apache.poi.hssf.record.formula.eval.RefEval;
 import org.apache.poi.hssf.record.formula.eval.ValueEval;
 
-public final class Row implements Function {
-
-    public ValueEval evaluate(ValueEval[] evals, int srcCellRow, int srcCellCol) {
-        ValueEval retval = null;
-        int rnum = -1;
-
-        switch (evals.length) {
-        default:
-            retval = ErrorEval.VALUE_INVALID;
-        case 1:
-            if (evals[0] instanceof AreaEval) {
-                AreaEval ae = (AreaEval) evals[0];
-                rnum = ae.getFirstRow();
-            }
-            else if (evals[0] instanceof RefEval) {
-                RefEval re = (RefEval) evals[0];
-                rnum = re.getRow();
-            }
-            else { // anything else is not valid argument
-                retval = ErrorEval.VALUE_INVALID;
-            }
-            break;
-        case 0:
-            rnum = srcCellRow;
-        }
+public final class Row implements Function0Arg, Function1Arg {
 
-        if (retval == null) {
-            retval = (rnum >= 0)
-                    ? new NumberEval(rnum + 1) // +1 since excel rownums are 1 based
-                    : (ValueEval) ErrorEval.VALUE_INVALID;
+    public ValueEval evaluate(int srcRowIndex, int srcColumnIndex) {
+        return new NumberEval(srcRowIndex+1);
+    }
+    public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) {
+        int rnum;
+
+        if (arg0 instanceof AreaEval) {
+            rnum = ((AreaEval) arg0).getFirstRow();
+        } else if (arg0 instanceof RefEval) {
+            rnum = ((RefEval) arg0).getRow();
+        } else {
+            // anything else is not valid argument
+            return ErrorEval.VALUE_INVALID;
         }
 
-        return retval;
+        return new NumberEval(rnum + 1);
+    }
+    public ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
+        switch (args.length) {
+            case 1:
+                return evaluate(srcRowIndex, srcColumnIndex, args[0]);
+            case 0:
+              return new NumberEval(srcRowIndex+1);
+        }
+        return ErrorEval.VALUE_INVALID;
     }
 
 }
index fb1b025342f859ce7a86d2ae9ff9e651aabd2160..dfde69ae3115185707c4c4df8eb76e598a515963 100644 (file)
@@ -28,27 +28,14 @@ import org.apache.poi.hssf.record.formula.eval.ValueEval;
  *
  * @author Josh Micich
  */
-public final class Rows implements Function {
+public final class Rows extends Fixed1ArgFunction {
 
-       public ValueEval evaluate(ValueEval[] args, int srcCellRow, int srcCellCol) {
-               switch(args.length) {
-                       case 1:
-                               // expected
-                               break;
-                       case 0:
-                               // too few arguments
-                               return ErrorEval.VALUE_INVALID;
-                       default:
-                               // too many arguments
-                               return ErrorEval.VALUE_INVALID;
-               }
-               ValueEval firstArg = args[0];
+       public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) {
 
                int result;
-               if (firstArg instanceof AreaEval) {
-                       AreaEval ae = (AreaEval) firstArg;
-                       result = ae.getLastRow() - ae.getFirstRow() + 1;
-               } else if (firstArg instanceof RefEval) {
+               if (arg0 instanceof AreaEval) {
+                       result = ((AreaEval) arg0).getHeight();
+               } else if (arg0 instanceof RefEval) {
                        result = 1;
                } else { // anything else is not valid argument
                        return ErrorEval.VALUE_INVALID;
index e4b43c0d1cf9f435fe568e20065b5554cb715207..70869e462e85c085b87cd745599d1308d7a6fe35 100644 (file)
@@ -30,16 +30,10 @@ import org.apache.poi.hssf.record.formula.eval.ValueEval;
  * cause an empty string result.  If the argument is an area, the first (top-left) cell is used
  * (regardless of the coordinates of the evaluating formula cell).
  */
-public final class T implements Function {
-
-    public ValueEval evaluate(ValueEval[] args, int srcCellRow, int srcCellCol) {
-        switch (args.length) {
-            default:
-                return ErrorEval.VALUE_INVALID;
-            case 1:
-                 break;
-        }
-        ValueEval arg = args[0];
+public final class T extends Fixed1ArgFunction {
+
+    public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) {
+        ValueEval arg = arg0;
         if (arg instanceof RefEval) {
             arg = ((RefEval) arg).getInnerValueEval();
         } else if (arg instanceof AreaEval) {
index 926ab3fed1fc9292897e0454d0d11c1bbc533887..85f474028ad974db368af1fa5061cee39aaec605 100644 (file)
@@ -29,7 +29,7 @@ import org.apache.poi.hssf.record.formula.eval.ValueEval;
  *
  * Based on POI org.apache.hssf.record.formula.DateFunc.java
  */
-public final class Time implements Function {
+public final class Time extends Fixed3ArgFunction {
 
        private static final int SECONDS_PER_MINUTE = 60;
        private static final int SECONDS_PER_HOUR = 3600;
@@ -37,25 +37,23 @@ public final class Time implements Function {
        private static final int SECONDS_PER_DAY = HOURS_PER_DAY * SECONDS_PER_HOUR;
 
 
-       public ValueEval evaluate(ValueEval[] args, int srcCellRow, int srcCellCol) {
-               if (args.length != 3) {
-                       return ErrorEval.VALUE_INVALID;
-               }
+       public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1,
+                       ValueEval arg2) {
                double result;
-
                try {
-                       result = evaluate(evalArg(args[0]), evalArg(args[1]), evalArg(args[2]));
+                       result = evaluate(evalArg(arg0, srcRowIndex, srcColumnIndex), evalArg(arg1, srcRowIndex, srcColumnIndex), evalArg(arg2, srcRowIndex, srcColumnIndex));
                } catch (EvaluationException e) {
                        return e.getErrorEval();
                }
                return new NumberEval(result);
        }
-       private static int evalArg(ValueEval arg) throws EvaluationException {
+       private static int evalArg(ValueEval arg, int srcRowIndex, int srcColumnIndex) throws EvaluationException {
                if (arg == MissingArgEval.instance) {
                        return 0;
                }
+               ValueEval ev = OperandResolver.getSingleValue(arg, srcRowIndex, srcColumnIndex);
                // Excel silently truncates double values to integers
-               return OperandResolver.coerceValueToInt(arg);
+               return OperandResolver.coerceValueToInt(ev);
        }
        /**
         * Converts the supplied hours, minutes and seconds to an Excel time value.
index f6705aae108bffb9d7b758159e2d0c5df68f3ab2..f50ea73c1ad93d6c3502e32f6e67f8a4a4898aa3 100644 (file)
@@ -20,7 +20,6 @@ package org.apache.poi.hssf.record.formula.functions;
 import java.util.Calendar;
 import java.util.GregorianCalendar;
 
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
 import org.apache.poi.hssf.record.formula.eval.NumberEval;
 import org.apache.poi.hssf.record.formula.eval.ValueEval;
 import org.apache.poi.hssf.usermodel.HSSFDateUtil;
@@ -30,12 +29,9 @@ import org.apache.poi.hssf.usermodel.HSSFDateUtil;
  *
  * @author Frank Taffelt
  */
-public final class Today implements Function {
+public final class Today extends Fixed0ArgFunction {
 
-       public ValueEval evaluate(ValueEval[] evals, int srcCellRow, int srcCellCol) {
-               if (evals.length > 0) {
-                       return ErrorEval.VALUE_INVALID;
-               }
+       public ValueEval evaluate(int srcRowIndex, int srcColumnIndex) {
 
                Calendar now = new GregorianCalendar();
                now.set(now.get(Calendar.YEAR), now.get(Calendar.MONTH), now.get(Calendar.DATE),0,0,0);
@@ -43,4 +39,3 @@ public final class Today implements Function {
                return new NumberEval(HSSFDateUtil.getExcelDate(now.getTime()));
        }
 }
-
index 8067e742e6e4e611cd22a0e2d65973fabcd05a7f..951f19cb402eb5c880de5fea587d2063bdcdd26b 100644 (file)
@@ -35,19 +35,16 @@ import org.apache.poi.hssf.record.formula.eval.ValueEval;
  *
  * @author Josh Micich
  */
-public final class Value implements Function {
+public final class Value extends Fixed1ArgFunction {
 
        /** "1,0000" is valid, "1,00" is not */
        private static final int MIN_DISTANCE_BETWEEN_THOUSANDS_SEPARATOR = 4;
        private static final Double ZERO = new Double(0.0);
 
-       public ValueEval evaluate(ValueEval[] args, int srcCellRow, int srcCellCol) {
-               if (args.length != 1) {
-                       return ErrorEval.VALUE_INVALID;
-               }
+       public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) {
                ValueEval veText;
                try {
-                       veText = OperandResolver.getSingleValue(args[0], srcCellRow, srcCellCol);
+                       veText = OperandResolver.getSingleValue(arg0, srcRowIndex, srcColumnIndex);
                } catch (EvaluationException e) {
                        return e.getErrorEval();
                }
index 9f5483fa05c0d0c9fb0fc8ddce17b07f5634aaa1..4928425f9949556e42c8b977993a5b68dce821f0 100644 (file)
@@ -26,7 +26,7 @@ import org.apache.poi.hssf.record.formula.eval.ValueEval;
  *
  * @author Josh Micich
  */
-abstract class Var2or3ArgFunction implements Function {
+abstract class Var2or3ArgFunction implements Function2Arg, Function3Arg {
 
        public final ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
                switch (args.length) {
@@ -37,10 +37,4 @@ abstract class Var2or3ArgFunction implements Function {
                }
                return ErrorEval.VALUE_INVALID;
        }
-
-       public abstract ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0,
-                       ValueEval arg1, ValueEval arg2);
-
-       public abstract ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0,
-                       ValueEval arg1);
 }
index 21c43d4855a2ab190a792caa2d98c1e852430e8f..e2c919489b609634f2ef8380522558c32db046ef 100644 (file)
@@ -27,9 +27,8 @@ import org.apache.poi.hssf.record.formula.functions.LookupUtils.ValueVector;
 
 /**
  * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
- *
  */
-public abstract class XYNumericFunction implements Function {
+public abstract class XYNumericFunction extends Fixed2ArgFunction {
 
        private static abstract class ValueArray implements ValueVector {
                private final int _size;
@@ -96,15 +95,12 @@ public abstract class XYNumericFunction implements Function {
         */
        protected abstract Accumulator createAccumulator();
 
-       public final ValueEval evaluate(ValueEval[] args, int srcCellRow, int srcCellCol) {
-               if (args.length != 2) {
-                       return ErrorEval.VALUE_INVALID;
-               }
+       public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) {
 
                double result;
                try {
-                       ValueVector vvX = createValueVector(args[0]);
-                       ValueVector vvY = createValueVector(args[1]);
+                       ValueVector vvX = createValueVector(arg0);
+                       ValueVector vvY = createValueVector(arg1);
                        int size = vvX.getSize();
                        if (size == 0 || vvY.getSize() != size) {
                                return ErrorEval.NA;