diff options
author | Nick Burch <nick@apache.org> | 2014-07-25 14:50:44 +0000 |
---|---|---|
committer | Nick Burch <nick@apache.org> | 2014-07-25 14:50:44 +0000 |
commit | eb66cf9a089050c1d950ab5a9801b40e0c817c7c (patch) | |
tree | b7b2c9a201997ad9f4c43cbb5ebfd1b0deaf5888 /src | |
parent | a0ebce023bd451aa3bb75e917ddad868b70b6a29 (diff) | |
download | poi-eb66cf9a089050c1d950ab5a9801b40e0c817c7c.tar.gz poi-eb66cf9a089050c1d950ab5a9801b40e0c817c7c.zip |
Start preparing LazyAreaEval and LazyRefEval to handle sheet ranges, for #55906
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1613443 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src')
5 files changed, 88 insertions, 41 deletions
diff --git a/src/java/org/apache/poi/ss/formula/LazyAreaEval.java b/src/java/org/apache/poi/ss/formula/LazyAreaEval.java index c23fb4f4e4..9791641a9d 100644 --- a/src/java/org/apache/poi/ss/formula/LazyAreaEval.java +++ b/src/java/org/apache/poi/ss/formula/LazyAreaEval.java @@ -17,28 +17,28 @@ package org.apache.poi.ss.formula; -import org.apache.poi.ss.formula.ptg.AreaI; -import org.apache.poi.ss.formula.ptg.AreaI.OffsetArea; import org.apache.poi.ss.formula.eval.AreaEval; import org.apache.poi.ss.formula.eval.AreaEvalBase; import org.apache.poi.ss.formula.eval.ValueEval; +import org.apache.poi.ss.formula.ptg.AreaI; +import org.apache.poi.ss.formula.ptg.AreaI.OffsetArea; import org.apache.poi.ss.util.CellReference; /** - * - * @author Josh Micich + * Provides Lazy Evaluation to a 3D Ranges + * + * TODO Provide access to multiple sheets where present */ final class LazyAreaEval extends AreaEvalBase { + private final SheetRangeEvaluator _evaluator; - private final SheetRefEvaluator _evaluator; - - LazyAreaEval(AreaI ptg, SheetRefEvaluator evaluator) { + LazyAreaEval(AreaI ptg, SheetRangeEvaluator evaluator) { super(ptg); _evaluator = evaluator; } public LazyAreaEval(int firstRowIndex, int firstColumnIndex, int lastRowIndex, - int lastColumnIndex, SheetRefEvaluator evaluator) { + int lastColumnIndex, SheetRangeEvaluator evaluator) { super(firstRowIndex, firstColumnIndex, lastRowIndex, lastColumnIndex); _evaluator = evaluator; } @@ -48,7 +48,7 @@ final class LazyAreaEval extends AreaEvalBase { int rowIx = (relativeRowIndex + getFirstRow() ) ; int colIx = (relativeColumnIndex + getFirstColumn() ) ; - return _evaluator.getEvalForCell(rowIx, colIx); + return _evaluator.getEvalForCell(_evaluator.getFirstSheetIndex(), rowIx, colIx); } public AreaEval offset(int relFirstRowIx, int relLastRowIx, int relFirstColIx, int relLastColIx) { @@ -79,7 +79,7 @@ final class LazyAreaEval extends AreaEvalBase { CellReference crB = new CellReference(getLastRow(), getLastColumn()); StringBuffer sb = new StringBuffer(); sb.append(getClass().getName()).append("["); - sb.append(_evaluator.getSheetName()); + sb.append(_evaluator.getSheetNameRange()); sb.append('!'); sb.append(crA.formatAsString()); sb.append(':'); @@ -93,6 +93,7 @@ final class LazyAreaEval extends AreaEvalBase { */ public boolean isSubTotal(int rowIndex, int columnIndex){ // delegate the query to the sheet evaluator which has access to internal ptgs - return _evaluator.isSubTotal(getFirstRow() + rowIndex, getFirstColumn() + columnIndex); + SheetRefEvaluator _sre = _evaluator.getSheetEvaluator(_evaluator.getFirstSheetIndex()); + return _sre.isSubTotal(getFirstRow() + rowIndex, getFirstColumn() + columnIndex); } } diff --git a/src/java/org/apache/poi/ss/formula/LazyRefEval.java b/src/java/org/apache/poi/ss/formula/LazyRefEval.java index 167fd102e5..b813cb7ebc 100644 --- a/src/java/org/apache/poi/ss/formula/LazyRefEval.java +++ b/src/java/org/apache/poi/ss/formula/LazyRefEval.java @@ -17,22 +17,22 @@ package org.apache.poi.ss.formula; -import org.apache.poi.ss.formula.ptg.AreaI; -import org.apache.poi.ss.formula.ptg.AreaI.OffsetArea; import org.apache.poi.ss.formula.eval.AreaEval; import org.apache.poi.ss.formula.eval.RefEvalBase; import org.apache.poi.ss.formula.eval.ValueEval; +import org.apache.poi.ss.formula.ptg.AreaI; +import org.apache.poi.ss.formula.ptg.AreaI.OffsetArea; import org.apache.poi.ss.util.CellReference; /** -* -* @author Josh Micich -*/ + * Provides Lazy Evaluation to a 3D Reference + * + * TODO Provide access to multiple sheets where present + */ final class LazyRefEval extends RefEvalBase { + private final SheetRangeEvaluator _evaluator; - private final SheetRefEvaluator _evaluator; - - public LazyRefEval(int rowIndex, int columnIndex, SheetRefEvaluator sre) { + public LazyRefEval(int rowIndex, int columnIndex, SheetRangeEvaluator sre) { super(rowIndex, columnIndex); if (sre == null) { throw new IllegalArgumentException("sre must not be null"); @@ -41,7 +41,7 @@ final class LazyRefEval extends RefEvalBase { } public ValueEval getInnerValueEval() { - return _evaluator.getEvalForCell(getRow(), getColumn()); + return _evaluator.getEvalForCell(_evaluator.getFirstSheetIndex(), getRow(), getColumn()); } public AreaEval offset(int relFirstRowIx, int relLastRowIx, int relFirstColIx, int relLastColIx) { @@ -56,7 +56,7 @@ final class LazyRefEval extends RefEvalBase { CellReference cr = new CellReference(getRow(), getColumn()); StringBuffer sb = new StringBuffer(); sb.append(getClass().getName()).append("["); - sb.append(_evaluator.getSheetName()); + sb.append(_evaluator.getSheetNameRange()); sb.append('!'); sb.append(cr.formatAsString()); sb.append("]"); diff --git a/src/java/org/apache/poi/ss/formula/OperationEvaluationContext.java b/src/java/org/apache/poi/ss/formula/OperationEvaluationContext.java index 6cbc9c95b7..6dba12aba8 100644 --- a/src/java/org/apache/poi/ss/formula/OperationEvaluationContext.java +++ b/src/java/org/apache/poi/ss/formula/OperationEvaluationContext.java @@ -21,6 +21,7 @@ import org.apache.poi.ss.SpreadsheetVersion; import org.apache.poi.ss.formula.CollaboratingWorkbooksEnvironment.WorkbookNotFoundException; import org.apache.poi.ss.formula.EvaluationWorkbook.ExternalName; import org.apache.poi.ss.formula.EvaluationWorkbook.ExternalSheet; +import org.apache.poi.ss.formula.EvaluationWorkbook.ExternalSheetRange; import org.apache.poi.ss.formula.eval.AreaEval; import org.apache.poi.ss.formula.eval.ErrorEval; import org.apache.poi.ss.formula.eval.ExternalNameEval; @@ -75,24 +76,30 @@ public final class OperationEvaluationContext { return _columnIndex; } - SheetRefEvaluator createExternSheetRefEvaluator(ExternSheetReferenceToken ptg) { + SheetRangeEvaluator createExternSheetRefEvaluator(ExternSheetReferenceToken ptg) { return createExternSheetRefEvaluator(ptg.getExternSheetIndex()); } - SheetRefEvaluator createExternSheetRefEvaluator(String sheetName, int externalWorkbookNumber) { + SheetRangeEvaluator createExternSheetRefEvaluator(String sheetName, int externalWorkbookNumber) { ExternalSheet externalSheet = _workbook.getExternalSheet(sheetName, null, externalWorkbookNumber); return createExternSheetRefEvaluator(externalSheet); } - SheetRefEvaluator createExternSheetRefEvaluator(int externSheetIndex) { + SheetRangeEvaluator createExternSheetRefEvaluator(int externSheetIndex) { ExternalSheet externalSheet = _workbook.getExternalSheet(externSheetIndex); return createExternSheetRefEvaluator(externalSheet); } - SheetRefEvaluator createExternSheetRefEvaluator(ExternalSheet externalSheet) { + SheetRangeEvaluator createExternSheetRefEvaluator(ExternalSheet externalSheet) { WorkbookEvaluator targetEvaluator; - int otherSheetIndex; + int otherFirstSheetIndex; + int otherLastSheetIndex = -1; if (externalSheet == null || externalSheet.getWorkbookName() == null) { // sheet is in same workbook - otherSheetIndex = _workbook.getSheetIndex(externalSheet.getSheetName()); targetEvaluator = _bookEvaluator; + otherFirstSheetIndex = _workbook.getSheetIndex(externalSheet.getSheetName()); + + if (externalSheet instanceof ExternalSheetRange) { + String lastSheetName = ((ExternalSheetRange)externalSheet).getLastSheetName(); + otherLastSheetIndex = _workbook.getSheetIndex(lastSheetName); + } } else { // look up sheet by name from external workbook String workbookName = externalSheet.getWorkbookName(); @@ -101,13 +108,30 @@ public final class OperationEvaluationContext { } catch (WorkbookNotFoundException e) { throw new RuntimeException(e.getMessage(), e); } - otherSheetIndex = targetEvaluator.getSheetIndex(externalSheet.getSheetName()); - if (otherSheetIndex < 0) { + + otherFirstSheetIndex = targetEvaluator.getSheetIndex(externalSheet.getSheetName()); + if (externalSheet instanceof ExternalSheetRange) { + String lastSheetName = ((ExternalSheetRange)externalSheet).getLastSheetName(); + otherLastSheetIndex = targetEvaluator.getSheetIndex(lastSheetName); + } + + if (otherFirstSheetIndex < 0) { throw new RuntimeException("Invalid sheet name '" + externalSheet.getSheetName() + "' in bool '" + workbookName + "'."); } } - return new SheetRefEvaluator(targetEvaluator, _tracker, otherSheetIndex); + + if (otherLastSheetIndex == -1) { + // Reference to just one sheet + otherLastSheetIndex = otherFirstSheetIndex; + } + + SheetRefEvaluator[] evals = new SheetRefEvaluator[otherLastSheetIndex-otherFirstSheetIndex+1]; + for (int i=0; i<evals.length; i++) { + int otherSheetIndex = i+otherFirstSheetIndex; + evals[i] = new SheetRefEvaluator(targetEvaluator, _tracker, otherSheetIndex); + } + return new SheetRangeEvaluator(otherFirstSheetIndex, otherLastSheetIndex, evals); } /** @@ -134,8 +158,9 @@ public final class OperationEvaluationContext { return new SheetRefEvaluator(targetEvaluator, _tracker, otherSheetIndex); } - public SheetRefEvaluator getRefEvaluatorForCurrentSheet() { - return new SheetRefEvaluator(_bookEvaluator, _tracker, _sheetIndex); + public SheetRangeEvaluator getRefEvaluatorForCurrentSheet() { + SheetRefEvaluator sre = new SheetRefEvaluator(_bookEvaluator, _tracker, _sheetIndex); + return new SheetRangeEvaluator(_sheetIndex, sre); } @@ -162,10 +187,12 @@ public final class OperationEvaluationContext { if (!isA1Style) { throw new RuntimeException("R1C1 style not supported yet"); } - SheetRefEvaluator sre = createExternSheetRefEvaluator(workbookName, sheetName); - if (sre == null) { + SheetRefEvaluator se = createExternSheetRefEvaluator(workbookName, sheetName); + if (se == null) { return ErrorEval.REF_INVALID; } + SheetRangeEvaluator sre = new SheetRangeEvaluator(_sheetIndex, se); + // ugly typecast - TODO - make spreadsheet version more easily accessible SpreadsheetVersion ssVersion = ((FormulaParsingWorkbook)_workbook).getSpreadsheetVersion(); @@ -271,30 +298,30 @@ public final class OperationEvaluationContext { } public ValueEval getRefEval(int rowIndex, int columnIndex) { - SheetRefEvaluator sre = getRefEvaluatorForCurrentSheet(); + SheetRangeEvaluator sre = getRefEvaluatorForCurrentSheet(); return new LazyRefEval(rowIndex, columnIndex, sre); } public ValueEval getRef3DEval(Ref3DPtg rptg) { - SheetRefEvaluator sre = createExternSheetRefEvaluator(rptg.getExternSheetIndex()); + SheetRangeEvaluator sre = createExternSheetRefEvaluator(rptg.getExternSheetIndex()); return new LazyRefEval(rptg.getRow(), rptg.getColumn(), sre); } public ValueEval getRef3DEval(Ref3DPxg rptg) { - SheetRefEvaluator sre = createExternSheetRefEvaluator(rptg.getSheetName(), rptg.getExternalWorkbookNumber()); + SheetRangeEvaluator sre = createExternSheetRefEvaluator(rptg.getSheetName(), rptg.getExternalWorkbookNumber()); return new LazyRefEval(rptg.getRow(), rptg.getColumn(), sre); } public ValueEval getAreaEval(int firstRowIndex, int firstColumnIndex, int lastRowIndex, int lastColumnIndex) { - SheetRefEvaluator sre = getRefEvaluatorForCurrentSheet(); + SheetRangeEvaluator sre = getRefEvaluatorForCurrentSheet(); return new LazyAreaEval(firstRowIndex, firstColumnIndex, lastRowIndex, lastColumnIndex, sre); } public ValueEval getArea3DEval(Area3DPtg aptg) { - SheetRefEvaluator sre = createExternSheetRefEvaluator(aptg.getExternSheetIndex()); + SheetRangeEvaluator sre = createExternSheetRefEvaluator(aptg.getExternSheetIndex()); return new LazyAreaEval(aptg.getFirstRow(), aptg.getFirstColumn(), aptg.getLastRow(), aptg.getLastColumn(), sre); } public ValueEval getArea3DEval(Area3DPxg aptg) { - SheetRefEvaluator sre = createExternSheetRefEvaluator(aptg.getSheetName(), aptg.getExternalWorkbookNumber()); + SheetRangeEvaluator sre = createExternSheetRefEvaluator(aptg.getSheetName(), aptg.getExternalWorkbookNumber()); return new LazyAreaEval(aptg.getFirstRow(), aptg.getFirstColumn(), aptg.getLastRow(), aptg.getLastColumn(), sre); } diff --git a/src/java/org/apache/poi/ss/formula/SheetRangeEvaluator.java b/src/java/org/apache/poi/ss/formula/SheetRangeEvaluator.java index 9157a1d0da..92200dd642 100644 --- a/src/java/org/apache/poi/ss/formula/SheetRangeEvaluator.java +++ b/src/java/org/apache/poi/ss/formula/SheetRangeEvaluator.java @@ -38,6 +38,9 @@ final class SheetRangeEvaluator { _lastSheetIndex = lastSheetIndex; _sheetEvaluators = sheetEvaluators; } + public SheetRangeEvaluator(int onlySheetIndex, SheetRefEvaluator sheetEvaluator) { + this(onlySheetIndex, onlySheetIndex, new SheetRefEvaluator[] {sheetEvaluator}); + } public SheetRefEvaluator getSheetEvaluator(int sheetIndex) { if (sheetIndex < _firstSheetIndex || sheetIndex > _lastSheetIndex) { @@ -46,10 +49,26 @@ final class SheetRangeEvaluator { } return _sheetEvaluators[sheetIndex-_firstSheetIndex]; } + + public int getFirstSheetIndex() { + return _firstSheetIndex; + } + public int getLastSheetIndex() { + return _lastSheetIndex; + } public String getSheetName(int sheetIndex) { return getSheetEvaluator(sheetIndex).getSheetName(); } + public String getSheetNameRange() { + StringBuilder sb = new StringBuilder(); + sb.append(getSheetName(_firstSheetIndex)); + if (_firstSheetIndex != _lastSheetIndex) { + sb.append(':'); + sb.append(getSheetName(_lastSheetIndex)); + } + return sb.toString(); + } public ValueEval getEvalForCell(int sheetIndex, int rowIndex, int columnIndex) { return getSheetEvaluator(sheetIndex).getEvalForCell(rowIndex, columnIndex); diff --git a/src/java/org/apache/poi/ss/formula/WorkbookEvaluator.java b/src/java/org/apache/poi/ss/formula/WorkbookEvaluator.java index 92318d87d9..8a32c9c8b1 100644 --- a/src/java/org/apache/poi/ss/formula/WorkbookEvaluator.java +++ b/src/java/org/apache/poi/ss/formula/WorkbookEvaluator.java @@ -427,7 +427,7 @@ public final class WorkbookEvaluator { dbgIndentStr = " "; dbgIndentStr = dbgIndentStr.substring(0, Math.min(dbgIndentStr.length(), dbgEvaluationOutputIndent*2)); EVAL_LOG.log(POILogger.WARN, dbgIndentStr - + "- evaluateFormula('" + ec.getRefEvaluatorForCurrentSheet().getSheetName() + + "- evaluateFormula('" + ec.getRefEvaluatorForCurrentSheet().getSheetNameRange() + "'/" + new CellReference(ec.getRowIndex(), ec.getColumnIndex()).formatAsString() + "): " + Arrays.toString(ptgs).replaceAll("\\Qorg.apache.poi.ss.formula.ptg.\\E", "")); dbgEvaluationOutputIndent++; |