You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

FormulaCellCacheEntry.java 4.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. /* ====================================================================
  2. Licensed to the Apache Software Foundation (ASF) under one or more
  3. contributor license agreements. See the NOTICE file distributed with
  4. this work for additional information regarding copyright ownership.
  5. The ASF licenses this file to You under the Apache License, Version 2.0
  6. (the "License"); you may not use this file except in compliance with
  7. the License. You may obtain a copy of the License at
  8. http://www.apache.org/licenses/LICENSE-2.0
  9. Unless required by applicable law or agreed to in writing, software
  10. distributed under the License is distributed on an "AS IS" BASIS,
  11. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. See the License for the specific language governing permissions and
  13. limitations under the License.
  14. ==================================================================== */
  15. package org.apache.poi.ss.formula;
  16. import java.util.Collections;
  17. import java.util.HashSet;
  18. import java.util.Set;
  19. import org.apache.poi.ss.formula.eval.ValueEval;
  20. import org.apache.poi.ss.formula.FormulaUsedBlankCellSet.BookSheetKey;
  21. /**
  22. * Stores the cached result of a formula evaluation, along with the set of sensitive input cells
  23. */
  24. final class FormulaCellCacheEntry extends CellCacheEntry {
  25. /**
  26. * Cells 'used' in the current evaluation of the formula corresponding to this cache entry
  27. *
  28. * If any of the following cells change, this cache entry needs to be cleared
  29. */
  30. private CellCacheEntry[] _sensitiveInputCells;
  31. private FormulaUsedBlankCellSet _usedBlankCellGroup;
  32. public FormulaCellCacheEntry() {
  33. // leave fields un-set
  34. }
  35. public boolean isInputSensitive() {
  36. if (_sensitiveInputCells != null) {
  37. if (_sensitiveInputCells.length > 0 ) {
  38. return true;
  39. }
  40. }
  41. return _usedBlankCellGroup == null ? false : !_usedBlankCellGroup.isEmpty();
  42. }
  43. public void setSensitiveInputCells(CellCacheEntry[] sensitiveInputCells) {
  44. // need to tell all cells that were previously used, but no longer are,
  45. // that they are not consumed by this cell any more
  46. if (sensitiveInputCells == null) {
  47. _sensitiveInputCells = null;
  48. changeConsumingCells(CellCacheEntry.EMPTY_ARRAY);
  49. } else {
  50. _sensitiveInputCells = sensitiveInputCells.clone();
  51. changeConsumingCells(_sensitiveInputCells);
  52. }
  53. }
  54. public void clearFormulaEntry() {
  55. CellCacheEntry[] usedCells = _sensitiveInputCells;
  56. if (usedCells != null) {
  57. for (int i = usedCells.length-1; i>=0; i--) {
  58. usedCells[i].clearConsumingCell(this);
  59. }
  60. }
  61. _sensitiveInputCells = null;
  62. clearValue();
  63. }
  64. private void changeConsumingCells(CellCacheEntry[] usedCells) {
  65. CellCacheEntry[] prevUsedCells = _sensitiveInputCells;
  66. int nUsed = usedCells.length;
  67. for (int i = 0; i < nUsed; i++) {
  68. usedCells[i].addConsumingCell(this);
  69. }
  70. if (prevUsedCells == null) {
  71. return;
  72. }
  73. int nPrevUsed = prevUsedCells.length;
  74. if (nPrevUsed < 1) {
  75. return;
  76. }
  77. Set<CellCacheEntry> usedSet;
  78. if (nUsed < 1) {
  79. usedSet = Collections.emptySet();
  80. } else {
  81. usedSet = new HashSet<>(nUsed * 3 / 2);
  82. for (int i = 0; i < nUsed; i++) {
  83. usedSet.add(usedCells[i]);
  84. }
  85. }
  86. for (int i = 0; i < nPrevUsed; i++) {
  87. CellCacheEntry prevUsed = prevUsedCells[i];
  88. if (!usedSet.contains(prevUsed)) {
  89. // previously was used by cellLoc, but not anymore
  90. prevUsed.clearConsumingCell(this);
  91. }
  92. }
  93. }
  94. public void updateFormulaResult(ValueEval result, CellCacheEntry[] sensitiveInputCells, FormulaUsedBlankCellSet usedBlankAreas) {
  95. updateValue(result);
  96. setSensitiveInputCells(sensitiveInputCells);
  97. _usedBlankCellGroup = usedBlankAreas;
  98. }
  99. public void notifyUpdatedBlankCell(BookSheetKey bsk, int rowIndex, int columnIndex, IEvaluationListener evaluationListener) {
  100. if (_usedBlankCellGroup != null) {
  101. if (_usedBlankCellGroup.containsCell(bsk, rowIndex, columnIndex)) {
  102. clearFormulaEntry();
  103. recurseClearCachedFormulaResults(evaluationListener);
  104. }
  105. }
  106. }
  107. }