]> source.dussan.org Git - poi.git/commitdiff
Refactoring MultiOperandNumericFunction - removed Ref2DEval.
authorJosh Micich <josh@apache.org>
Thu, 11 Sep 2008 07:16:20 +0000 (07:16 +0000)
committerJosh Micich <josh@apache.org>
Thu, 11 Sep 2008 07:16:20 +0000 (07:16 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@694153 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/poi/hssf/record/formula/eval/FunctionEval.java
src/java/org/apache/poi/hssf/record/formula/eval/Ref2DEval.java [deleted file]
src/java/org/apache/poi/hssf/record/formula/eval/ValueEvalToNumericXlator.java [deleted file]
src/java/org/apache/poi/hssf/record/formula/functions/AggregateFunction.java
src/java/org/apache/poi/hssf/record/formula/functions/Maxa.java [deleted file]
src/java/org/apache/poi/hssf/record/formula/functions/Mina.java [deleted file]
src/java/org/apache/poi/hssf/record/formula/functions/MinaMaxa.java [new file with mode: 0644]
src/java/org/apache/poi/hssf/record/formula/functions/MultiOperandNumericFunction.java

index 6f14a1e856bd5207a7ee82dba58c663e5e5f4d3e..719349a1c8de97660809547d2b2b24bbcb042a97 100644 (file)
@@ -420,8 +420,8 @@ public abstract class FunctionEval implements OperationEval {
         retval[359] = new Hyperlink(); // HYPERLINK
         retval[360] = new NotImplementedFunction(); // PHONETIC
         retval[361] = new Averagea(); // AVERAGEA
-        retval[362] = new Maxa(); // MAXA
-        retval[363] = new Mina(); // MINA
+        retval[362] = MinaMaxa.MAXA;
+        retval[363] = MinaMaxa.MINA;
         retval[364] = new Stdevpa(); // STDEVPA
         retval[365] = new Varpa(); // VARPA
         retval[366] = new Stdeva(); // STDEVA
diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/Ref2DEval.java b/src/java/org/apache/poi/hssf/record/formula/eval/Ref2DEval.java
deleted file mode 100644 (file)
index e4bb47a..0000000
+++ /dev/null
@@ -1,53 +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.eval;
-
-import org.apache.poi.hssf.record.formula.RefPtg;
-
-/**
- * @author adeshmukh
- *  
- */
-public final class Ref2DEval implements RefEval {
-
-    private final ValueEval value;
-    private final RefPtg delegate;
-    
-    public Ref2DEval(RefPtg ptg, ValueEval ve) {
-        if(ve == null) {
-            throw new IllegalArgumentException("ve must not be null");
-        }
-        if(false && ptg == null) { // TODO - fix dodgy code in MultiOperandNumericFunction
-            throw new IllegalArgumentException("ptg must not be null");
-        }
-        value = ve;
-        delegate = ptg;
-    }
-    public ValueEval getInnerValueEval() {
-        return value;
-    }
-    public int getRow() {
-        return delegate.getRow();
-    }
-    public int getColumn() {
-        return delegate.getColumn();
-    }
-    public AreaEval offset(int relFirstRowIx, int relLastRowIx, int relFirstColIx, int relLastColIx) {
-        throw new RuntimeException("should not be called"); // TODO - delete this whole class
-    }
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/ValueEvalToNumericXlator.java b/src/java/org/apache/poi/hssf/record/formula/eval/ValueEvalToNumericXlator.java
deleted file mode 100644 (file)
index bb04e41..0000000
+++ /dev/null
@@ -1,143 +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.eval;
-
-/**
- * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
- *
- */
-public final class ValueEvalToNumericXlator {
-
-    public static final int BLANK_IS_PARSED = 0x0001; // => blanks are not ignored, converted to 0
-    
-    public static final int REF_BOOL_IS_PARSED = 0x0002;
-    
-    private final int flags;
-    
-    
-    public ValueEvalToNumericXlator(int flags) {
-       
-       if (false) { // uncomment to see who is using this class
-                       System.err.println(new Throwable().getStackTrace()[1].getClassName() + "\t0x"
-                                       + Integer.toHexString(flags).toUpperCase());
-               }
-               this.flags = flags;
-    }
-    
-    /**
-     * returned value can be either A NumericValueEval, BlankEval or ErrorEval.
-     * The params can be either NumberEval, BoolEval, StringEval, or
-     * RefEval
-     * @param eval
-     */
-    public ValueEval attemptXlateToNumeric(ValueEval eval) {
-        
-        if (eval == null) {
-            throw new IllegalArgumentException("eval must not be null");
-        }
-        
-        // most common case - least worries :)
-        if (eval instanceof NumberEval) {
-            return eval; 
-        }
-        
-        if (eval instanceof BoolEval) {
-            return eval;
-        } 
-        
-        if (eval instanceof StringEval) {
-            return xlateStringEval((StringEval) eval);
-        }
-        
-        if (eval instanceof RefEval) {
-            return xlateRefEval((RefEval) eval);
-        }
-        
-        if (eval instanceof ErrorEval) {
-            return eval;
-        }
-        
-        if (eval instanceof BlankEval) {
-            return xlateBlankEval();
-        }
-        
-        // probably AreaEval? then not acceptable.
-        throw new RuntimeException("Invalid ValueEval type passed for conversion: " + eval.getClass());
-    }
-    
-    /**
-     * no args are required since BlankEval has only one 
-     * instance. If flag is set, a zero
-     * valued numbereval is returned, else BlankEval.INSTANCE
-     * is returned.
-     */
-    private ValueEval xlateBlankEval() {
-        return ((flags & BLANK_IS_PARSED) > 0)
-                ? (ValueEval) NumberEval.ZERO
-                : BlankEval.INSTANCE;
-    }
-    
-    /**
-     * uses the relevant flags to decode the supplied RefVal
-     * @param eval
-     */
-    private ValueEval xlateRefEval(RefEval reval) {
-        ValueEval eval = reval.getInnerValueEval();
-        
-        // most common case - least worries :)
-        if (eval instanceof NumberEval) {
-            return eval;
-        }
-        
-        if (eval instanceof BoolEval) {
-            return ((flags & REF_BOOL_IS_PARSED) > 0)
-                    ? (ValueEval) eval
-                    : BlankEval.INSTANCE;
-        } 
-        
-        if (eval instanceof StringEval) {
-            // all ref strings are blanks
-                       return BlankEval.INSTANCE;
-        }
-        
-        if (eval instanceof ErrorEval) {
-            return eval;
-        }
-        
-        if (eval instanceof BlankEval) {
-            return xlateBlankEval();
-        }
-        
-        throw new RuntimeException("Invalid ValueEval type passed for conversion: ("
-                       + eval.getClass().getName() + ")");
-    }
-    
-    /**
-     * uses the relevant flags to decode the StringEval
-     * @param eval
-     */
-    private static ValueEval xlateStringEval(StringEval eval) {
-
-        String s = eval.getStringValue();
-        Double d = OperandResolver.parseDouble(s);
-        if(d == null) {
-            return ErrorEval.VALUE_INVALID;
-        }
-        return new NumberEval(d.doubleValue());
-    }
-}
index 0758686228250ce3bcad374e25a0d4d4792dbc6e..0495ee3fc4d89253539b2c792bba93308706b763 100644 (file)
@@ -19,22 +19,17 @@ 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;
 
 /**
  * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
  *
  */
 public abstract class AggregateFunction extends MultiOperandNumericFunction {
-       private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR =
-               new ValueEvalToNumericXlator(0);
 
-       protected ValueEval attemptXlateToNumeric(ValueEval ve) {
-               return DEFAULT_NUM_XLATOR.attemptXlateToNumeric(ve);
+       protected AggregateFunction() {
+               super(false, false);
        }
 
-
        /* ---------------------------------------------------------------------- */
 
        public static final Function AVEDEV = new AggregateFunction() {
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Maxa.java b/src/java/org/apache/poi/hssf/record/formula/functions/Maxa.java
deleted file mode 100644 (file)
index 95c4c8c..0000000
+++ /dev/null
@@ -1,41 +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.ValueEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator;
-
-/**
- * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt; 
- *
- */
-public final class Maxa extends MultiOperandNumericFunction {
-    private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR =
-        new ValueEvalToNumericXlator((short) (
-                  ValueEvalToNumericXlator.REF_BOOL_IS_PARSED  
-                | ValueEvalToNumericXlator.BLANK_IS_PARSED
-                ));
-    
-       protected ValueEval attemptXlateToNumeric(ValueEval ve) {
-               return DEFAULT_NUM_XLATOR.attemptXlateToNumeric(ve);
-       }
-    
-    public double evaluate(double[] values) {
-        return values.length > 0 ? MathX.max(values) : 0;
-    }
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Mina.java b/src/java/org/apache/poi/hssf/record/formula/functions/Mina.java
deleted file mode 100644 (file)
index 7344936..0000000
+++ /dev/null
@@ -1,41 +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.ValueEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator;
-
-/**
- * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt; 
- *
- */
-public final class Mina extends MultiOperandNumericFunction {
-    private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR =
-        new ValueEvalToNumericXlator((short) (
-                  ValueEvalToNumericXlator.REF_BOOL_IS_PARSED  
-                 | ValueEvalToNumericXlator.BLANK_IS_PARSED
-                ));
-    
-       protected ValueEval attemptXlateToNumeric(ValueEval ve) {
-               return DEFAULT_NUM_XLATOR.attemptXlateToNumeric(ve);
-       }
-
-    public double evaluate(double[] values) {
-        return values.length > 0 ? MathX.min(values) : 0;
-    }
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/MinaMaxa.java b/src/java/org/apache/poi/hssf/record/formula/functions/MinaMaxa.java
new file mode 100644 (file)
index 0000000..70e5e7f
--- /dev/null
@@ -0,0 +1,40 @@
+/* ====================================================================
+   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;
+
+/**
+ * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
+ * 
+ */
+public abstract class MinaMaxa extends MultiOperandNumericFunction {
+
+       protected MinaMaxa() {
+               super(true, true);
+       }
+
+       public static final Function MAXA = new MinaMaxa() {
+               protected double evaluate(double[] values) {
+                       return values.length > 0 ? MathX.max(values) : 0;
+               }
+       };
+       public static final Function MINA = new MinaMaxa() {
+               protected double evaluate(double[] values) {
+                       return values.length > 0 ? MathX.min(values) : 0;
+               }
+       };
+}
index ec65d0f127e7cc176ecaf7fe2ecdaba678401af8..b3feac6a07a27437f321e6ed08207ac48f55cd7d 100644 (file)
@@ -19,13 +19,14 @@ 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.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.Ref2DEval;
+import org.apache.poi.hssf.record.formula.eval.OperandResolver;
 import org.apache.poi.hssf.record.formula.eval.RefEval;
+import org.apache.poi.hssf.record.formula.eval.StringEval;
 import org.apache.poi.hssf.record.formula.eval.ValueEval;
 
 /**
@@ -35,6 +36,16 @@ import org.apache.poi.hssf.record.formula.eval.ValueEval;
  * where the order of operands does not matter
  */
 public abstract class MultiOperandNumericFunction implements Function {
+
+       private final boolean _isReferenceBoolCounted;
+       private final boolean _isBlankCounted;
+
+       protected MultiOperandNumericFunction(boolean isReferenceBoolCounted, boolean isBlankCounted) {
+               _isReferenceBoolCounted = isReferenceBoolCounted;
+               _isBlankCounted = isBlankCounted;
+       }
+
+
        static final double[] EMPTY_DOUBLE_ARRAY = { };
 
        private static class DoubleList {
@@ -74,7 +85,7 @@ public abstract class MultiOperandNumericFunction implements Function {
        private static final int DEFAULT_MAX_NUM_OPERANDS = 30;
 
        public final Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) {
-               
+
                double d;
                try {
                        double[] values = getNumberArray(args);
@@ -82,16 +93,16 @@ public abstract class MultiOperandNumericFunction implements Function {
                } catch (EvaluationException e) {
                        return e.getErrorEval();
                }
-               
+
                if (Double.isNaN(d) || Double.isInfinite(d))
                        return ErrorEval.NUM_ERROR;
-               
+
                return new NumberEval(d);
        }
 
        protected abstract double evaluate(double[] values) throws EvaluationException;
-       
-       
+
+
        /**
         * Maximum number of operands accepted by this function.
         * Subclasses may override to change default value.
@@ -132,54 +143,58 @@ public abstract class MultiOperandNumericFunction implements Function {
                        int height = ae.getHeight();
                        for (int rrIx=0; rrIx<height; rrIx++) {
                                for (int rcIx=0; rcIx<width; rcIx++) {
-                                       ValueEval ve1 = ae.getRelativeValue(rrIx, rcIx);
-                                        /*
-                                        * TODO: For an AreaEval, we are constructing a RefEval
-                                        * per element.
-                                        * For now this is a tempfix solution since this may
-                                        * require a more generic fix at the level of
-                                        * HSSFFormulaEvaluator where we store an array
-                                        * of RefEvals as the "values" array.
-                                        */
-                                       RefEval re = new Ref2DEval(null, ve1);
-                                       ValueEval ve = attemptXlateToNumeric(re);
-                                       if (ve instanceof ErrorEval) {
-                                               throw new EvaluationException((ErrorEval)ve);
-                                       }
-                                       if (ve instanceof BlankEval) {
-                                               // note - blanks are ignored, so returned array will be smaller.
-                                               continue;
-                                       }
-                                       if (ve instanceof NumericValueEval) {
-                                               NumericValueEval nve = (NumericValueEval) ve;
-                                               temp.add(nve.getNumberValue());
-                                       } else {
-                                               throw new RuntimeException("Unexpected value class (" + ve.getClass().getName() + ")");
-                                       }
+                                       ValueEval ve = ae.getRelativeValue(rrIx, rcIx);
+                                       collectValue(ve, true, temp);
                                }
                        }
                        return;
                }
-
-               // for ValueEvals other than AreaEval
-               ValueEval ve = attemptXlateToNumeric((ValueEval) operand);
-
-               if (ve instanceof NumericValueEval) {
-                       NumericValueEval nve = (NumericValueEval) ve;
-                       temp.add(nve.getNumberValue());
+               if (operand instanceof RefEval) {
+                       RefEval re = (RefEval) operand;
+                       collectValue(re.getInnerValueEval(), true, temp);
                        return;
                }
-
-               if (ve instanceof BlankEval) {
-                       // ignore blanks
+               collectValue((ValueEval)operand, false, temp);
+       }
+       private void collectValue(ValueEval ve, boolean isViaReference, DoubleList temp)  throws EvaluationException {
+               if (ve == null) {
+                       throw new IllegalArgumentException("ve must not be null");
+               }
+               if (ve instanceof NumberEval) {
+                       NumberEval ne = (NumberEval) ve;
+                       temp.add(ne.getNumberValue());
                        return;
                }
                if (ve instanceof ErrorEval) {
-                       throw new EvaluationException((ErrorEval)ve);
+                       throw new EvaluationException((ErrorEval) ve);
                }
-               throw new RuntimeException("Unexpected value class (" + ve.getClass().getName() + ")");
+               if (ve instanceof StringEval) {
+                       if (isViaReference) {
+                               // ignore all ref strings
+                               return;
+                       }
+                       String s = ((StringEval) ve).getStringValue();
+                       Double d = OperandResolver.parseDouble(s);
+                       if(d == null) {
+                               throw new EvaluationException(ErrorEval.VALUE_INVALID);
+                       }
+                       temp.add(d.doubleValue());
+                       return;
+               }
+               if (ve instanceof BoolEval) {
+                       if (!isViaReference || _isReferenceBoolCounted) {
+                               BoolEval boolEval = (BoolEval) ve;
+                               temp.add(boolEval.getNumberValue());
+                       }
+                       return;
+               }
+               if (ve == BlankEval.INSTANCE) {
+                       if (_isBlankCounted) {
+                               temp.add(0.0);
+                       }
+                       return;
+               }
+               throw new RuntimeException("Invalid ValueEval type passed for conversion: ("
+                               + ve.getClass() + ")");
        }
-
-
-       protected abstract ValueEval attemptXlateToNumeric(ValueEval ve);
 }