]> source.dussan.org Git - poi.git/commitdiff
Refactored finance functions.
authorJosh Micich <josh@apache.org>
Wed, 10 Sep 2008 22:43:30 +0000 (22:43 +0000)
committerJosh Micich <josh@apache.org>
Wed, 10 Sep 2008 22:43:30 +0000 (22:43 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@694050 13f79535-47bb-0310-9956-ffa450edef68

14 files changed:
src/java/org/apache/poi/hssf/record/formula/eval/FunctionEval.java
src/java/org/apache/poi/hssf/record/formula/eval/ValueEvalToNumericXlator.java
src/java/org/apache/poi/hssf/record/formula/functions/AggregateFunction.java
src/java/org/apache/poi/hssf/record/formula/functions/FinanceFunction.java
src/java/org/apache/poi/hssf/record/formula/functions/Fv.java [deleted file]
src/java/org/apache/poi/hssf/record/formula/functions/Maxa.java
src/java/org/apache/poi/hssf/record/formula/functions/Mina.java
src/java/org/apache/poi/hssf/record/formula/functions/Mode.java
src/java/org/apache/poi/hssf/record/formula/functions/MultiOperandNumericFunction.java
src/java/org/apache/poi/hssf/record/formula/functions/Nper.java [deleted file]
src/java/org/apache/poi/hssf/record/formula/functions/Pmt.java [deleted file]
src/java/org/apache/poi/hssf/record/formula/functions/Pv.java [deleted file]
src/testcases/org/apache/poi/hssf/data/FormulaEvalTestData.xls
src/testcases/org/apache/poi/hssf/record/formula/functions/TestPmt.java

index e78ab5f8e6020a540bdf821caae9a01a43ef6722..6f14a1e856bd5207a7ee82dba58c663e5e5f4d3e 100644 (file)
@@ -129,10 +129,10 @@ public abstract class FunctionEval implements OperationEval {
         retval[52] = new Growth(); // GROWTH
         retval[53] = new Goto(); // GOTO
         retval[54] = new Halt(); // HALT
-        retval[56] = new Pv(); // PV
-        retval[57] = new Fv(); // FV
-        retval[58] = new Nper(); // NPER
-        retval[59] = new Pmt(); // PMT
+        retval[56] = FinanceFunction.PV;
+        retval[57] = FinanceFunction.FV;
+        retval[58] = FinanceFunction.NPER;
+        retval[59] = FinanceFunction.PMT;
         retval[60] = new Rate(); // RATE
         retval[61] = new Mirr(); // MIRR
         retval[62] = new Irr(); // IRR
index 46aa0ddf6990e7e72dd968bb0cdc2799a13b8e82..37f0b9b4b1ea1f6bb25e2dd1cce1b588359bcd58 100644 (file)
@@ -1,23 +1,20 @@
-/*
-* 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.
-*/
-/*
- * Created on May 14, 2005
- *
- */
+/* ====================================================================
+   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.eval;
 
 /**
@@ -30,11 +27,7 @@ public final class ValueEvalToNumericXlator {
     public static final int BOOL_IS_PARSED = 0x0002;
     public static final int BLANK_IS_PARSED = 0x0004; // => blanks are not ignored, converted to 0
     
-    public static final int REF_STRING_IS_PARSED = 0x0008;
-    public static final int REF_BOOL_IS_PARSED = 0x0010;
-    public static final int REF_BLANK_IS_PARSED = 0x0020;
-    
-    public static final int STRING_IS_INVALID_VALUE = 0x0800;
+    public static final int REF_BOOL_IS_PARSED = 0x0008;
     
     private final int flags;
     
@@ -68,11 +61,11 @@ public final class ValueEvalToNumericXlator {
         if (eval instanceof BoolEval) {
             return ((flags & BOOL_IS_PARSED) > 0)
                 ? (NumericValueEval) eval
-                : xlateBlankEval(BLANK_IS_PARSED);
+                : xlateBlankEval();
         } 
         
         if (eval instanceof StringEval) {
-            return xlateStringEval((StringEval) eval); // TODO: recursive call needed
+            return xlateStringEval((StringEval) eval);
         }
         
         if (eval instanceof RefEval) {
@@ -84,7 +77,7 @@ public final class ValueEvalToNumericXlator {
         }
         
         if (eval instanceof BlankEval) {
-            return xlateBlankEval(BLANK_IS_PARSED);
+            return xlateBlankEval();
         }
         
         // probably AreaEval? then not acceptable.
@@ -97,8 +90,8 @@ public final class ValueEvalToNumericXlator {
      * valued numbereval is returned, else BlankEval.INSTANCE
      * is returned.
      */
-    private ValueEval xlateBlankEval(int flag) {
-        return ((flags & flag) > 0)
+    private ValueEval xlateBlankEval() {
+        return ((flags & BLANK_IS_PARSED) > 0)
                 ? (ValueEval) NumberEval.ZERO
                 : BlankEval.INSTANCE;
     }
@@ -122,7 +115,8 @@ public final class ValueEvalToNumericXlator {
         } 
         
         if (eval instanceof StringEval) {
-            return xlateRefStringEval((StringEval) eval);
+            // all ref strings are blanks
+                       return BlankEval.INSTANCE;
         }
         
         if (eval instanceof ErrorEval) {
@@ -130,7 +124,7 @@ public final class ValueEvalToNumericXlator {
         }
         
         if (eval instanceof BlankEval) {
-            return xlateBlankEval(REF_BLANK_IS_PARSED);
+            return xlateBlankEval();
         }
         
         throw new RuntimeException("Invalid ValueEval type passed for conversion: ("
@@ -151,29 +145,7 @@ public final class ValueEvalToNumericXlator {
             }
             return new NumberEval(d.doubleValue());
         }
-        // strings are errors?
-        if ((flags & STRING_IS_INVALID_VALUE) > 0) {
-            return ErrorEval.VALUE_INVALID;
-        }
-        
-        // ignore strings
-        return xlateBlankEval(BLANK_IS_PARSED);
-    }
-    
-    /**
-     * uses the relevant flags to decode the StringEval
-     * @param eval
-     */
-    private ValueEval xlateRefStringEval(StringEval sve) {
-        if ((flags & REF_STRING_IS_PARSED) > 0) {
-            String s = sve.getStringValue();
-            Double d = OperandResolver.parseDouble(s);
-            if(d == null) {
-                return ErrorEval.VALUE_INVALID;
-            }
-            return new NumberEval(d.doubleValue());
-        }
-        // strings are blanks
-        return BlankEval.INSTANCE;
+        // else strings are errors?
+        return ErrorEval.VALUE_INVALID;
     }
 }
index be0b1e44c7f8cfba7c3de70eb8b66fa50b96d26d..f04e64070bc9a4b47c4fae94ee44397bbb854ff6 100644 (file)
@@ -19,6 +19,7 @@ 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.EvaluationException;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
 import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator;
 
 /**
@@ -32,8 +33,8 @@ public abstract class AggregateFunction extends MultiOperandNumericFunction {
                                | ValueEvalToNumericXlator.STRING_IS_PARSED
                                 ));
 
-       protected final ValueEvalToNumericXlator getXlator() {
-               return DEFAULT_NUM_XLATOR;
+       protected ValueEval attemptXlateToNumeric(ValueEval ve) {
+               return DEFAULT_NUM_XLATOR.attemptXlateToNumeric(ve);
        }
 
 
index a6956752be3c87d895bdd46e76b5f0ca9aeb5743..01fcf9ef0b1791c05b40bcaac0a101a92866d441 100644 (file)
-/*
-* 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.
-*/
+/* ====================================================================
+   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
 
-package org.apache.poi.hssf.record.formula.functions;
+       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.
+==================================================================== */
 
-import org.apache.poi.hssf.record.formula.eval.AreaEval;
-import org.apache.poi.hssf.record.formula.eval.BoolEval;
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
-import org.apache.poi.hssf.record.formula.eval.Eval;
-import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator;
+package org.apache.poi.hssf.record.formula.functions;
 
+import org.apache.poi.hssf.record.formula.eval.EvaluationException;
 
 /**
  * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
  * Super class for all Evals for financial function evaluation.
- * 
+ *
  */
-public abstract class FinanceFunction implements Function {
-    private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR =
-        new ValueEvalToNumericXlator((short) (0
-                | ValueEvalToNumericXlator.BOOL_IS_PARSED  
-                | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED  
-                | ValueEvalToNumericXlator.STRING_IS_PARSED  
-                | ValueEvalToNumericXlator.REF_STRING_IS_PARSED  
-                | ValueEvalToNumericXlator.BLANK_IS_PARSED  
-                | ValueEvalToNumericXlator.REF_BLANK_IS_PARSED  
-              //| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED  
-              //| ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE  
-              //| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE
-                ));
-    
-    /**
-     * this is the default impl of the factory(ish) method getXlator.
-     * Subclasses can override this method
-     * if they desire to return a different ValueEvalToNumericXlator instance
-     * than the default.
-     */
-    protected final ValueEvalToNumericXlator getXlator() {
-        return DEFAULT_NUM_XLATOR;
-    }
-    
-    protected final ValueEval singleOperandNumericAsBoolean(Eval eval, int srcRow, short srcCol) {
-        ValueEval retval = null;
-        retval = singleOperandEvaluate(eval, srcRow, srcCol);
-        if (retval instanceof NumericValueEval) {
-            NumericValueEval nve = (NumericValueEval) retval;
-            retval = (nve.getNumberValue() == 0)
-                    ? BoolEval.FALSE
-                    : BoolEval.TRUE;
-        }
-        else {
-            retval = ErrorEval.VALUE_INVALID;
-        }
-        return retval;
-    }
-    
-    protected final ValueEval singleOperandEvaluate(Eval eval, int srcRow, short srcCol) {
+public abstract class FinanceFunction extends NumericFunction.MultiArg {
+
+       protected FinanceFunction() {
+               super (3, 5);
+       }
+
+       protected double evaluate(double[] ds) throws EvaluationException {
+               // All finance functions have 3 to 5 args, first 4 are numbers, last is boolean
+               // default for last 2 args are 0.0 and false
+               // Text boolean literals are not valid for the last arg
+               
+               double arg3 = 0.0;
+               double arg4 = 0.0;
+
+               switch(ds.length) {
+                       case 5:
+                               arg4 = ds[4];
+                       case 4:
+                               arg3 = ds[3];
+                       case 3:
+                               break;
+                       default:
+                               throw new IllegalStateException("Wrong number of arguments");
+               }
+               return evaluate(ds[0], ds[1], ds[2], arg3, arg4!=0.0);
+       }
+
+       protected abstract double evaluate(double rate, double arg1, double arg2, double arg3, boolean type) throws EvaluationException ;
+
 
-        if (eval instanceof AreaEval) {
-            AreaEval ae = (AreaEval) eval;
-            if (ae.contains(srcRow, srcCol)) { // circular ref!
-                return ErrorEval.CIRCULAR_REF_ERROR;
-            }
-            if (ae.isRow()) {
-                if (ae.isColumn()) {
-                       return ae.getRelativeValue(0, 0);
-                }
-                if (ae.containsColumn(srcCol)) {
-                    ValueEval ve = ae.getValueAt(ae.getFirstRow(), srcCol);
-                    ve = getXlator().attemptXlateToNumeric(ve);
-                    return getXlator().attemptXlateToNumeric(ve);
-                }
-                return ErrorEval.VALUE_INVALID;
-            }
-            if (ae.isColumn()) {
-                if (ae.containsRow(srcRow)) {
-                    ValueEval ve = ae.getValueAt(srcRow, ae.getFirstColumn());
-                    return getXlator().attemptXlateToNumeric(ve);
-                }
-                return ErrorEval.VALUE_INVALID;
-            }
-            return ErrorEval.VALUE_INVALID;
-        }
-        return getXlator().attemptXlateToNumeric((ValueEval) eval);
-    }
-    
+       public static final Function FV = new FinanceFunction() {
+               protected double evaluate(double rate, double arg1, double arg2, double arg3, boolean type) {
+                       return FinanceLib.fv(rate, arg1, arg2, arg3, type);
+               }
+       };
+       public static final Function NPER = new FinanceFunction() {
+               protected double evaluate(double rate, double arg1, double arg2, double arg3, boolean type) {
+                       return FinanceLib.nper(rate, arg1, arg2, arg3, type);
+               }
+       };
+       public static final Function PMT = new FinanceFunction() {
+               protected double evaluate(double rate, double arg1, double arg2, double arg3, boolean type) {
+                       return FinanceLib.pmt(rate, arg1, arg2, arg3, type);
+               }
+       };
+       public static final Function PV = new FinanceFunction() {
+               protected double evaluate(double rate, double arg1, double arg2, double arg3, boolean type) {
+                       return FinanceLib.pv(rate, arg1, arg2, arg3, type);
+               }
+       };
 }
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Fv.java b/src/java/org/apache/poi/hssf/record/formula/functions/Fv.java
deleted file mode 100644 (file)
index fd0335c..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
-* 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.
-*/
-/*
- * Created on May 15, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-import org.apache.poi.hssf.record.formula.eval.BoolEval;
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
-import org.apache.poi.hssf.record.formula.eval.Eval;
-import org.apache.poi.hssf.record.formula.eval.NumberEval;
-import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-
-public class Fv extends FinanceFunction {
-
-    public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
-        double rate = 0, nper = 0, pmt = 0, pv = 0, d = 0;
-        boolean type = false;
-        ValueEval retval = null;
-        ValueEval ve = null;
-        
-        switch (operands.length) {
-        default:
-            retval = ErrorEval.VALUE_INVALID;
-            break;
-        case 5:
-            ve = singleOperandNumericAsBoolean(operands[4], srcRow, srcCol);
-            if (ve instanceof ErrorEval) { retval = ErrorEval.VALUE_INVALID; break; }
-            type = ((BoolEval) ve).getBooleanValue();
-        case 4:
-            ve = singleOperandEvaluate(operands[3], srcRow, srcCol);
-            if (ve instanceof NumericValueEval) pv   = ((NumericValueEval) ve).getNumberValue();
-            else { retval = ErrorEval.VALUE_INVALID; break; }
-        case 3:
-            ve = singleOperandEvaluate(operands[1], srcRow, srcCol);
-            if (ve instanceof NumericValueEval) nper = ((NumericValueEval) ve).getNumberValue();
-            else { retval = ErrorEval.VALUE_INVALID; break; }
-
-            ve = singleOperandEvaluate(operands[2], srcRow, srcCol);
-            if (ve instanceof NumericValueEval) pmt  = ((NumericValueEval) ve).getNumberValue();
-            else { retval = ErrorEval.VALUE_INVALID; break; }
-
-            ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
-            if (ve instanceof NumericValueEval) rate = ((NumericValueEval) ve).getNumberValue();
-            else { retval = ErrorEval.VALUE_INVALID; break; }
-        }
-        
-        if (retval == null) {
-            d = FinanceLib.fv(rate, nper, pmt, pv, type);
-            retval = (Double.isNaN(d))
-                    ? (ValueEval) ErrorEval.VALUE_INVALID
-                    : (Double.isInfinite(d)) 
-                        ? (ValueEval) ErrorEval.NUM_ERROR 
-                        : new NumberEval(d);
-        }
-        return retval;
-    }
-
-}
index 9d7011f049aa85ddb4c7fb7de60aa38b1412df3e..7ae722889ed80cc2b6e1d263f0a55bbc91999cb4 100644 (file)
@@ -17,6 +17,7 @@
 
 package org.apache.poi.hssf.record.formula.functions;
 
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
 import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator;
 
 /**
@@ -29,19 +30,12 @@ public final class Maxa extends MultiOperandNumericFunction {
                   ValueEvalToNumericXlator.BOOL_IS_PARSED  
                 | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED  
                 | ValueEvalToNumericXlator.STRING_IS_PARSED  
-              //| ValueEvalToNumericXlator.REF_STRING_IS_PARSED  
-              //| ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED  
-              //| ValueEvalToNumericXlator.STRING_TO_BOOL_IS_PARSED  
-              //| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED  
-                | ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE  
-              //| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE  
                 | ValueEvalToNumericXlator.BLANK_IS_PARSED
-                | ValueEvalToNumericXlator.REF_BLANK_IS_PARSED
                 ));
     
-    protected ValueEvalToNumericXlator getXlator() {
-        return DEFAULT_NUM_XLATOR;
-    }
+       protected ValueEval attemptXlateToNumeric(ValueEval ve) {
+               return DEFAULT_NUM_XLATOR.attemptXlateToNumeric(ve);
+       }
     
     public double evaluate(double[] values) {
         return values.length > 0 ? MathX.max(values) : 0;
index bbc7da824831aeacaa6ecfb31299c60e0e0b257a..b3965eefd4788997a97713952832658ba321ac73 100644 (file)
 
 package org.apache.poi.hssf.record.formula.functions;
 
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
 import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator;
 
 /**
  * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt; 
  *
  */
-public class Mina extends MultiOperandNumericFunction {
+public final class Mina extends MultiOperandNumericFunction {
     private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR =
         new ValueEvalToNumericXlator((short) (
                   ValueEvalToNumericXlator.BOOL_IS_PARSED  
                 | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED  
                 | ValueEvalToNumericXlator.STRING_IS_PARSED  
-              //| ValueEvalToNumericXlator.REF_STRING_IS_PARSED  
-              //| ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED  
-              //| ValueEvalToNumericXlator.STRING_TO_BOOL_IS_PARSED  
-              //| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED  
-                | ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE  
-              //| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE
-                | ValueEvalToNumericXlator.REF_BLANK_IS_PARSED
                 | ValueEvalToNumericXlator.BLANK_IS_PARSED
                 ));
     
-    protected ValueEvalToNumericXlator getXlator() {
-        return DEFAULT_NUM_XLATOR;
-    }
+       protected ValueEval attemptXlateToNumeric(ValueEval ve) {
+               return DEFAULT_NUM_XLATOR.attemptXlateToNumeric(ve);
+       }
 
     public double evaluate(double[] values) {
         return values.length > 0 ? MathX.min(values) : 0;
index 940b9f40e60bef5fa32d2641212391ea7da038ee..64f017e8e2a54af52a9df1e3bc90b53cdd8b225b 100644 (file)
@@ -19,6 +19,7 @@ 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.EvaluationException;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
 import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator;
 
 /**
@@ -26,39 +27,25 @@ import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator;
  *
  */
 public class Mode extends MultiOperandNumericFunction {
-    private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR =
-        new ValueEvalToNumericXlator((short) (0
-              //| ValueEvalToNumericXlator.BOOL_IS_PARSED  
-              //| ValueEvalToNumericXlator.REF_BOOL_IS_PARSED  
-              //| ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED  
-              //| ValueEvalToNumericXlator.STRING_IS_PARSED  
-              //| ValueEvalToNumericXlator.REF_STRING_IS_PARSED  
-              //| ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED  
-              //| ValueEvalToNumericXlator.STRING_TO_BOOL_IS_PARSED  
-              //| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED  
-                | ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE  
-              //| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE
-              //| ValueEvalToNumericXlator.EVALUATED_REF_BLANK_IS_PARSED
-              //| ValueEvalToNumericXlator.REF_BLANK_IS_PARSED
-              //| ValueEvalToNumericXlator.BLANK_IS_PARSED
-                ));
-    
-    /**
-     * this is the default impl for the factory method getXlator
-     * of the super class NumericFunction. Subclasses can override this method
-     * if they desire to return a different ValueEvalToNumericXlator instance
-     * than the default.
-     */
-    protected ValueEvalToNumericXlator getXlator() {
-        return DEFAULT_NUM_XLATOR;
-    }
+       private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR =
+               new ValueEvalToNumericXlator(0);
 
-    protected double evaluate(double[] values) throws EvaluationException {
-        double d = StatsLib.mode(values);
-        if (Double.isNaN(d)) {
-               // TODO - StatsLib is returning NaN to denote 'no duplicate values'
-               throw new EvaluationException(ErrorEval.NA);
-        }
-        return d;
-    }
+       /**
+        * this is the default impl for the factory method getXlator
+        * of the super class NumericFunction. Subclasses can override this method
+        * if they desire to return a different ValueEvalToNumericXlator instance
+        * than the default.
+        */
+       protected ValueEval attemptXlateToNumeric(ValueEval ve) {
+               return DEFAULT_NUM_XLATOR.attemptXlateToNumeric(ve);
+       }
+
+       protected double evaluate(double[] values) throws EvaluationException {
+               double d = StatsLib.mode(values);
+               if (Double.isNaN(d)) {
+                       // TODO - StatsLib is returning NaN to denote 'no duplicate values'
+                       throw new EvaluationException(ErrorEval.NA);
+               }
+               return d;
+       }
 }
index 1337e2fe4dd8b701808b5102c1cd8b9f5c63dc6a..ec65d0f127e7cc176ecaf7fe2ecdaba678401af8 100644 (file)
@@ -27,7 +27,6 @@ import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
 import org.apache.poi.hssf.record.formula.eval.Ref2DEval;
 import org.apache.poi.hssf.record.formula.eval.RefEval;
 import org.apache.poi.hssf.record.formula.eval.ValueEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator;
 
 /**
  * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
@@ -74,9 +73,6 @@ public abstract class MultiOperandNumericFunction implements Function {
 
        private static final int DEFAULT_MAX_NUM_OPERANDS = 30;
 
-       protected abstract ValueEvalToNumericXlator getXlator();
-
-       
        public final Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) {
                
                double d;
@@ -185,7 +181,5 @@ public abstract class MultiOperandNumericFunction implements Function {
        }
 
 
-       protected ValueEval attemptXlateToNumeric(ValueEval ve) {
-               return getXlator().attemptXlateToNumeric(ve);
-       }
+       protected abstract ValueEval attemptXlateToNumeric(ValueEval ve);
 }
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Nper.java b/src/java/org/apache/poi/hssf/record/formula/functions/Nper.java
deleted file mode 100644 (file)
index 95411ed..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
-* 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.
-*/
-/*
- * Created on May 15, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-import org.apache.poi.hssf.record.formula.eval.BoolEval;
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
-import org.apache.poi.hssf.record.formula.eval.Eval;
-import org.apache.poi.hssf.record.formula.eval.NumberEval;
-import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-
-public class Nper extends FinanceFunction {
-
-    public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
-        double rate = 0, fv = 0, pmt = 0, pv = 0, d = 0;
-        boolean type = false;
-        ValueEval retval = null;
-        ValueEval ve = null;
-        
-        switch (operands.length) {
-        default:
-            retval = ErrorEval.VALUE_INVALID;
-            break;
-        case 5:
-            ve = singleOperandNumericAsBoolean(operands[4], srcRow, srcCol);
-            if (ve instanceof ErrorEval) { retval = ErrorEval.VALUE_INVALID; break; }
-            type = ((BoolEval) ve).getBooleanValue();
-        case 4:
-            ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
-            if (ve instanceof NumericValueEval) rate = ((NumericValueEval) ve).getNumberValue();
-            else { retval = ErrorEval.VALUE_INVALID; break; }
-            
-            ve = singleOperandEvaluate(operands[1], srcRow, srcCol);
-            if (ve instanceof NumericValueEval) pmt  = ((NumericValueEval) ve).getNumberValue();
-            else { retval = ErrorEval.VALUE_INVALID; break; }
-            
-            ve = singleOperandEvaluate(operands[2], srcRow, srcCol);
-            if (ve instanceof NumericValueEval) pv   = ((NumericValueEval) ve).getNumberValue();
-            else { retval = ErrorEval.VALUE_INVALID; break; }
-            
-            ve = singleOperandEvaluate(operands[3], srcRow, srcCol);
-            if (ve instanceof NumericValueEval) fv = ((NumericValueEval) ve).getNumberValue();
-            else { retval = ErrorEval.VALUE_INVALID; break; }
-        }
-        
-        if (retval == null) {
-            d = FinanceLib.nper(rate, pmt, pv, fv, type);
-            retval = (Double.isNaN(d))
-                    ? (ValueEval) ErrorEval.VALUE_INVALID
-                    : (Double.isInfinite(d)) 
-                        ? (ValueEval) ErrorEval.NUM_ERROR 
-                        : new NumberEval(d);
-        }
-        return retval;
-    }
-
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Pmt.java b/src/java/org/apache/poi/hssf/record/formula/functions/Pmt.java
deleted file mode 100644 (file)
index 68a8d43..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
-* 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.BoolEval;
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
-import org.apache.poi.hssf.record.formula.eval.Eval;
-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.NumericValueEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-
-/**
- * Implementation for the PMT() Excel function.<p/>
- * 
- * <b>Syntax:</b><br/>
- * <b>PMT</b>(<b>rate</b>, <b>nper</b>, <b>pv</b>, fv, type)<p/>
- * 
- * Returns the constant repayment amount required for a loan assuming a constant interest rate.<p/>
- * 
- * <b>rate</b> the loan interest rate.<br/>
- * <b>nper</b> the number of loan repayments.<br/>
- * <b>pv</b> the present value of the future payments (or principle).<br/>
- * <b>fv</b> the future value (default zero) surplus cash at the end of the loan lifetime.<br/>
- * <b>type</b> whether payments are due at the beginning(1) or end(0 - default) of each payment period.<br/>
- * 
- */
-public final class Pmt extends FinanceFunction {
-
-       public Eval evaluate(Eval[] args, int srcRow, short srcCol) {
-               
-               if(args.length < 3 || args.length > 5) {
-                       return ErrorEval.VALUE_INVALID;
-               }
-
-               try {
-                       // evaluate first three (always present) args
-                       double rate = evalArg(args[0], srcRow, srcCol);
-                       double nper = evalArg(args[1], srcRow, srcCol);
-                       double pv  = evalArg(args[2], srcRow, srcCol);
-                       double fv = 0;
-                       boolean arePaymentsAtPeriodBeginning = false;
-
-                       switch (args.length) {
-                               case 5:
-                                       ValueEval ve = singleOperandNumericAsBoolean(args[4], srcRow, srcCol);
-                                       if (ve instanceof ErrorEval) { 
-                                               return ve;
-                                       }
-                                       arePaymentsAtPeriodBeginning = ((BoolEval) ve).getBooleanValue();
-                               case 4:
-                                       fv = evalArg(args[3], srcRow, srcCol);
-                       }
-                       double d = FinanceLib.pmt(rate, nper, pv, fv, arePaymentsAtPeriodBeginning);
-                       if (Double.isNaN(d)) {
-                               return ErrorEval.VALUE_INVALID;
-                       }
-                       if (Double.isInfinite(d)) {
-                               return ErrorEval.NUM_ERROR;
-                       }
-                       return new NumberEval(d);
-               } catch (EvaluationException e) {
-                       return e.getErrorEval();
-               }
-       }
-
-       private double evalArg(Eval arg, int srcRow, short srcCol) throws EvaluationException {
-               ValueEval ve = singleOperandEvaluate(arg, srcRow, srcCol);
-               if(ve instanceof ErrorEval) {
-                       throw new EvaluationException((ErrorEval) ve);
-               }
-               if (ve instanceof NumericValueEval) {
-                       return ((NumericValueEval) ve).getNumberValue();
-               }
-               throw new EvaluationException(ErrorEval.VALUE_INVALID); 
-       }
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Pv.java b/src/java/org/apache/poi/hssf/record/formula/functions/Pv.java
deleted file mode 100644 (file)
index 1d54bee..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
-* 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.
-*/
-/*
- * Created on May 15, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-import org.apache.poi.hssf.record.formula.eval.BoolEval;
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
-import org.apache.poi.hssf.record.formula.eval.Eval;
-import org.apache.poi.hssf.record.formula.eval.NumberEval;
-import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-
-public class Pv extends FinanceFunction {
-
-    public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
-        double rate = 0, fv = 0, nper = 0, pmt = 0, d = 0;
-        boolean type = false;
-        ValueEval retval = null;
-        ValueEval ve = null;
-        
-        switch (operands.length) {
-        default:
-            retval = ErrorEval.VALUE_INVALID;
-            break;
-        case 5:
-            ve = singleOperandNumericAsBoolean(operands[4], srcRow, srcCol);
-            if (ve instanceof ErrorEval) { retval = ErrorEval.VALUE_INVALID; break; }
-            type = ((BoolEval) ve).getBooleanValue();
-        case 4:
-            ve = singleOperandEvaluate(operands[3], srcRow, srcCol);
-            if (ve instanceof NumericValueEval) fv = ((NumericValueEval) ve).getNumberValue();
-            else { retval = ErrorEval.VALUE_INVALID; break; }
-        case 3:
-            ve = singleOperandEvaluate(operands[1], srcRow, srcCol);
-            if (ve instanceof NumericValueEval) nper  = ((NumericValueEval) ve).getNumberValue();
-            else { retval = ErrorEval.VALUE_INVALID; break; }
-            
-            ve = singleOperandEvaluate(operands[2], srcRow, srcCol);
-            if (ve instanceof NumericValueEval) pmt   = ((NumericValueEval) ve).getNumberValue();
-            else { retval = ErrorEval.VALUE_INVALID; break; }
-
-            ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
-            if (ve instanceof NumericValueEval) rate = ((NumericValueEval) ve).getNumberValue();
-            else { retval = ErrorEval.VALUE_INVALID; break; }
-        }
-        
-        if (retval == null) {
-            d = FinanceLib.pv(rate, nper, pmt, fv, type);
-            retval = (Double.isNaN(d))
-                    ? (ValueEval) ErrorEval.VALUE_INVALID
-                    : (Double.isInfinite(d)) 
-                        ? (ValueEval) ErrorEval.NUM_ERROR 
-                        : new NumberEval(d);
-        }
-        return retval;
-    }
-}
index ad41de8efc8f5b842a38675d3bf81210b71444d3..acf9c8b166c6232dcf06d900cd4db20613b26621 100644 (file)
Binary files a/src/testcases/org/apache/poi/hssf/data/FormulaEvalTestData.xls and b/src/testcases/org/apache/poi/hssf/data/FormulaEvalTestData.xls differ
index 2fecef7046d3a38b5ff48afb1da33a883df96eb7..9a4cded9af68cfbac3b6ae2a793864724487e52e 100644 (file)
@@ -36,7 +36,7 @@ public final class TestPmt extends TestCase {
                assertEquals(expected, ne.getNumberValue(), 0.00005);
        }
        private static Eval invoke(Eval[] args) {
-               return new Pmt().evaluate(args, -1, (short)-1);
+               return FinanceFunction.PMT.evaluate(args, -1, (short)-1);
        }
        /**
         * Invocation when not expecting an error result