]> source.dussan.org Git - poi.git/commitdiff
Added getRow() and getColumn() functions to TwoDEval to simplify logic in INDEX imple...
authorJosh Micich <josh@apache.org>
Tue, 22 Dec 2009 03:00:21 +0000 (03:00 +0000)
committerJosh Micich <josh@apache.org>
Tue, 22 Dec 2009 03:00:21 +0000 (03:00 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@893063 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/poi/hssf/record/formula/functions/Index.java
src/java/org/apache/poi/ss/formula/LazyAreaEval.java
src/java/org/apache/poi/ss/formula/TwoDEval.java
src/testcases/org/apache/poi/hssf/record/formula/eval/TestRangeEval.java
src/testcases/org/apache/poi/hssf/record/formula/functions/EvalFactory.java

index badb84640bb3300bad6fd08a9d859f2a716ff581..fd3816b9946e07db7523c4c26617f89316182e95 100644 (file)
@@ -17,7 +17,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.EvaluationException;
@@ -53,7 +52,7 @@ public final class Index implements Function2Arg, Function3Arg, Function4Arg {
                int columnIx = 0;
                try {
                        int rowIx = resolveIndexArg(arg1, srcRowIndex, srcColumnIndex);
-                       
+
                        if (!reference.isColumn()) {
                                if (!reference.isRow()) {
                                        // always an error with 2-D area refs
@@ -65,7 +64,7 @@ public final class Index implements Function2Arg, Function3Arg, Function4Arg {
                                columnIx = rowIx;
                                rowIx = 0;
                        }
+
                        return getValueFromArea(reference, rowIx, columnIx);
                } catch (EvaluationException e) {
                        return e.getErrorEval();
@@ -125,45 +124,27 @@ public final class Index implements Function2Arg, Function3Arg, Function4Arg {
                        throws EvaluationException {
                assert pRowIx >= 0;
                assert pColumnIx >= 0;
-       
-               int width = ae.getWidth();
-               int height = ae.getHeight();
-               
-               int relFirstRowIx;
-               int relLastRowIx;
-
-               if ((pRowIx == 0)) {
-                       relFirstRowIx = 0;
-                       relLastRowIx = height-1;
-               } else {
+
+               TwoDEval result = ae;
+
+               if (pRowIx != 0) {
                        // Slightly irregular logic for bounds checking errors
-                       if (pRowIx > height) {
+                       if (pRowIx > ae.getHeight()) {
                                // high bounds check fail gives #REF! if arg was explicitly passed
                                throw new EvaluationException(ErrorEval.REF_INVALID);
                        }
-                       int rowIx = pRowIx-1;
-                       relFirstRowIx = rowIx;
-                       relLastRowIx = rowIx;
+                       result = result.getRow(pRowIx-1);
                }
 
-               int relFirstColIx;
-               int relLastColIx;
-               if ((pColumnIx == 0)) {
-                       relFirstColIx = 0;
-                       relLastColIx = width-1;
-               } else {
+               if (pColumnIx != 0) {
                        // Slightly irregular logic for bounds checking errors
-                       if (pColumnIx > width) {
+                       if (pColumnIx > ae.getWidth()) {
                                // high bounds check fail gives #REF! if arg was explicitly passed
                                throw new EvaluationException(ErrorEval.REF_INVALID);
                        }
-                       int columnIx = pColumnIx-1;
-                       relFirstColIx = columnIx;
-                       relLastColIx = columnIx;
+                       result = result.getColumn(pColumnIx-1);
                }
-
-               AreaEval x = ((AreaEval) ae);
-               return x.offset(relFirstRowIx, relLastRowIx, relFirstColIx, relLastColIx);
+               return result;
        }
 
 
index b8e186a7d755fed0ce31d79dc3cf917ce78e7c30..5063d1e6e8b2fb73a93d0dc2cc2443526e044f17 100644 (file)
@@ -57,6 +57,23 @@ final class LazyAreaEval extends AreaEvalBase {
 
                return new LazyAreaEval(area, _evaluator);
        }
+       public LazyAreaEval getRow(int rowIndex) {
+               if (rowIndex >= getHeight()) {
+                       throw new IllegalArgumentException("Invalid rowIndex " + rowIndex
+                                       + ".  Allowable range is (0.." + getHeight() + ").");
+               }
+               int absRowIx = getFirstRow() + rowIndex;
+               return new LazyAreaEval(absRowIx, getFirstColumn(), absRowIx, getLastColumn(), _evaluator);
+       }
+       public LazyAreaEval getColumn(int columnIndex) {
+               if (columnIndex >= getWidth()) {
+                       throw new IllegalArgumentException("Invalid columnIndex " + columnIndex
+                                       + ".  Allowable range is (0.." + getWidth() + ").");
+               }
+               int absColIx = getFirstColumn() + columnIndex;
+               return new LazyAreaEval(getFirstRow(), absColIx, getLastRow(), absColIx, _evaluator);
+       }
+
        public String toString() {
                CellReference crA = new CellReference(getFirstRow(), getFirstColumn());
                CellReference crB = new CellReference(getLastRow(), getLastColumn());
index f2e51459a3409c7d5954f60e5469ea32a8bb9e6a..ff3b933f9649426ac1c652057e784f3d96fb23cc 100644 (file)
@@ -28,11 +28,11 @@ import org.apache.poi.hssf.record.formula.eval.ValueEval;
 public interface TwoDEval extends ValueEval {
 
        /**
-        * @param row relative row index (zero based)
-        * @param col relative column index (zero based)
-        * @return element at the specified row and col position
+        * @param rowIndex relative row index (zero based)
+        * @param columnIndex relative column index (zero based)
+        * @return element at the specified row and column position
         */
-       public ValueEval getValue(int row, int col);
+       ValueEval getValue(int rowIndex, int columnIndex);
 
        int getWidth();
        int getHeight();
@@ -48,4 +48,15 @@ public interface TwoDEval extends ValueEval {
         * the trivial case when the area has just a single cell.
         */
        boolean isColumn();
+
+       /**
+        * @param rowIndex relative row index (zero based)
+        * @return a single row {@link TwoDEval}
+        */
+       TwoDEval getRow(int rowIndex);
+       /**
+        * @param columnIndex relative column index (zero based)
+        * @return a single column {@link TwoDEval}
+        */
+       TwoDEval getColumn(int columnIndex);
 }
index be456a755678d83f25d473fc4017631902eb49a2..80af1b924b027e0ad4ceeb1bbf91f8587ce7b9d1 100644 (file)
@@ -28,6 +28,7 @@ import org.apache.poi.hssf.usermodel.HSSFRow;
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 import org.apache.poi.hssf.util.AreaReference;
 import org.apache.poi.hssf.util.CellReference;
+import org.apache.poi.ss.formula.TwoDEval;
 import org.apache.poi.ss.usermodel.CellValue;
 
 /**
@@ -90,6 +91,9 @@ public final class TestRangeEval extends TestCase {
                public MockAreaEval(AreaI ptg) {
                        super(ptg);
                }
+               private MockAreaEval(int firstRow, int firstColumn, int lastRow, int lastColumn) {
+                       super(firstRow, firstColumn, lastRow, lastColumn);
+               }
                public ValueEval getRelativeValue(int relativeRowIndex, int relativeColumnIndex) {
                        throw new RuntimeException("not expected to be called during this test");
                }
@@ -100,6 +104,20 @@ public final class TestRangeEval extends TestCase {
 
                        return new MockAreaEval(area);
                }
+               public TwoDEval getRow(int rowIndex) {
+                       if (rowIndex >= getHeight()) {
+                               throw new IllegalArgumentException("Invalid rowIndex " + rowIndex
+                                               + ".  Allowable range is (0.." + getHeight() + ").");
+                       }
+                       return new MockAreaEval(rowIndex, getFirstColumn(), rowIndex, getLastColumn());
+               }
+               public TwoDEval getColumn(int columnIndex) {
+                       if (columnIndex >= getWidth()) {
+                               throw new IllegalArgumentException("Invalid columnIndex " + columnIndex
+                                               + ".  Allowable range is (0.." + getWidth() + ").");
+                       }
+                       return new MockAreaEval(getFirstRow(), columnIndex, getLastRow(), columnIndex);
+               }
        }
 
        public void testRangeUsingOffsetFunc_bug46948() {
index 57d707262b12b888994b56420ae098b6a0a26050..fb2091911a4560311e95b5be930505aa686d10d1 100644 (file)
@@ -27,6 +27,7 @@ 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.RefEvalBase;
 import org.apache.poi.hssf.record.formula.eval.ValueEval;
+import org.apache.poi.ss.formula.TwoDEval;
 
 /**
  * Test helper class for creating mock <code>Eval</code> objects
@@ -119,7 +120,7 @@ public final class EvalFactory {
                        int width = relLastColIx - relFirstColIx + 1;
                        ValueEval[] result = new ValueEval[height * width];
                        for (int r=0; r<height; r++) {
-                               int srcRowIx = r + relFirstRowIx; 
+                               int srcRowIx = r + relFirstRowIx;
                                for (int c=0; c<width; c++) {
                                        int srcColIx = c + relFirstColIx;
                                        int destIx = r * width + c;
@@ -129,6 +130,28 @@ public final class EvalFactory {
                        }
                        return result;
                }
+               public TwoDEval getRow(int rowIndex) {
+                       if (rowIndex >= getHeight()) {
+                               throw new IllegalArgumentException("Invalid rowIndex " + rowIndex
+                                               + ".  Allowable range is (0.." + getHeight() + ").");
+                       }
+                       ValueEval[] values = new ValueEval[getWidth()];
+                       for (int i = 0; i < values.length; i++) {
+                               values[i] = getRelativeValue(rowIndex, i);
+                       }
+                       return new MockAreaEval(rowIndex, getFirstColumn(), rowIndex, getLastColumn(), values);
+               }
+               public TwoDEval getColumn(int columnIndex) {
+                       if (columnIndex >= getWidth()) {
+                               throw new IllegalArgumentException("Invalid columnIndex " + columnIndex
+                                               + ".  Allowable range is (0.." + getWidth() + ").");
+                       }
+                       ValueEval[] values = new ValueEval[getHeight()];
+                       for (int i = 0; i < values.length; i++) {
+                               values[i] = getRelativeValue(i, columnIndex);
+                       }
+                       return new MockAreaEval(getFirstRow(), columnIndex, getLastRow(), columnIndex, values);
+               }
        }
 
        private static final class MockRefEval extends RefEvalBase {