123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203 |
- /* ====================================================================
- 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.ss.formula;
-
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
-
- import org.apache.poi.ss.util.CellReference;
-
- /**
- * Optimization - compacts many blank cell references used by a single formula.
- */
- final class FormulaUsedBlankCellSet {
- public static final class BookSheetKey {
-
- private final int _bookIndex;
- private final int _sheetIndex;
-
- public BookSheetKey(int bookIndex, int sheetIndex) {
- _bookIndex = bookIndex;
- _sheetIndex = sheetIndex;
- }
- @Override
- public int hashCode() {
- return _bookIndex * 17 + _sheetIndex;
- }
- @Override
- public boolean equals(Object obj) {
- if (!(obj instanceof BookSheetKey)) {
- return false;
- }
- BookSheetKey other = (BookSheetKey) obj;
- return _bookIndex == other._bookIndex && _sheetIndex == other._sheetIndex;
- }
- }
-
- private static final class BlankCellSheetGroup {
- private final List<BlankCellRectangleGroup> _rectangleGroups;
- private int _currentRowIndex;
- private int _firstColumnIndex;
- private int _lastColumnIndex;
- private BlankCellRectangleGroup _currentRectangleGroup;
- private int _lastDefinedRow;
-
- public BlankCellSheetGroup(int lastDefinedRow) {
- _rectangleGroups = new ArrayList<>();
- _currentRowIndex = -1;
- _lastDefinedRow = lastDefinedRow;
- }
-
- public void addCell(int rowIndex, int columnIndex) {
- if (rowIndex > _lastDefinedRow) return;
-
- if (_currentRowIndex == -1) {
- _currentRowIndex = rowIndex;
- _firstColumnIndex = columnIndex;
- _lastColumnIndex = columnIndex;
- } else {
- if (_currentRowIndex == rowIndex && _lastColumnIndex+1 == columnIndex) {
- _lastColumnIndex = columnIndex;
- } else {
- // cell does not fit on end of current row
- if (_currentRectangleGroup == null) {
- _currentRectangleGroup = new BlankCellRectangleGroup(_currentRowIndex, _firstColumnIndex, _lastColumnIndex);
- } else {
- if (!_currentRectangleGroup.acceptRow(_currentRowIndex, _firstColumnIndex, _lastColumnIndex)) {
- _rectangleGroups.add(_currentRectangleGroup);
- _currentRectangleGroup = new BlankCellRectangleGroup(_currentRowIndex, _firstColumnIndex, _lastColumnIndex);
- }
- }
- _currentRowIndex = rowIndex;
- _firstColumnIndex = columnIndex;
- _lastColumnIndex = columnIndex;
- }
- }
- }
-
- public boolean containsCell(int rowIndex, int columnIndex) {
- if (rowIndex > _lastDefinedRow) return true;
-
- for (int i=_rectangleGroups.size()-1; i>=0; i--) {
- BlankCellRectangleGroup bcrg = _rectangleGroups.get(i);
- if (bcrg.containsCell(rowIndex, columnIndex)) {
- return true;
- }
- }
- if(_currentRectangleGroup != null && _currentRectangleGroup.containsCell(rowIndex, columnIndex)) {
- return true;
- }
- if (_currentRowIndex != -1 && _currentRowIndex == rowIndex) {
- if (_firstColumnIndex <= columnIndex && columnIndex <= _lastColumnIndex) {
- return true;
- }
- }
- return false;
- }
- }
-
- private static final class BlankCellRectangleGroup {
-
- private final int _firstRowIndex;
- private final int _firstColumnIndex;
- private final int _lastColumnIndex;
- private int _lastRowIndex;
-
- public BlankCellRectangleGroup(int firstRowIndex, int firstColumnIndex, int lastColumnIndex) {
- _firstRowIndex = firstRowIndex;
- _firstColumnIndex = firstColumnIndex;
- _lastColumnIndex = lastColumnIndex;
- _lastRowIndex = firstRowIndex;
- }
-
- public boolean containsCell(int rowIndex, int columnIndex) {
- if (columnIndex < _firstColumnIndex) {
- return false;
- }
- if (columnIndex > _lastColumnIndex) {
- return false;
- }
- if (rowIndex < _firstRowIndex) {
- return false;
- }
- if (rowIndex > _lastRowIndex) {
- return false;
- }
- return true;
- }
-
- public boolean acceptRow(int rowIndex, int firstColumnIndex, int lastColumnIndex) {
- if (firstColumnIndex != _firstColumnIndex) {
- return false;
- }
- if (lastColumnIndex != _lastColumnIndex) {
- return false;
- }
- if (rowIndex != _lastRowIndex+1) {
- return false;
- }
- _lastRowIndex = rowIndex;
- return true;
- }
- @Override
- public String toString() {
- StringBuffer sb = new StringBuffer(64);
- CellReference crA = new CellReference(_firstRowIndex, _firstColumnIndex, false, false);
- CellReference crB = new CellReference(_lastRowIndex, _lastColumnIndex, false, false);
- sb.append(getClass().getName());
- sb.append(" [").append(crA.formatAsString()).append(':').append(crB.formatAsString()).append("]");
- return sb.toString();
- }
- }
-
- private final Map<BookSheetKey, BlankCellSheetGroup> _sheetGroupsByBookSheet;
-
- public FormulaUsedBlankCellSet() {
- _sheetGroupsByBookSheet = new HashMap<>();
- }
-
- public void addCell(EvaluationWorkbook evalWorkbook, int bookIndex, int sheetIndex, int rowIndex, int columnIndex) {
- BlankCellSheetGroup sbcg = getSheetGroup(evalWorkbook, bookIndex, sheetIndex);
- sbcg.addCell(rowIndex, columnIndex);
- }
-
- private BlankCellSheetGroup getSheetGroup(EvaluationWorkbook evalWorkbook, int bookIndex, int sheetIndex) {
- BookSheetKey key = new BookSheetKey(bookIndex, sheetIndex);
-
- BlankCellSheetGroup result = _sheetGroupsByBookSheet.get(key);
- if (result == null) {
- result = new BlankCellSheetGroup(evalWorkbook.getSheet(sheetIndex).getlastRowNum());
- _sheetGroupsByBookSheet.put(key, result);
- }
- return result;
- }
-
- public boolean containsCell(BookSheetKey key, int rowIndex, int columnIndex) {
- BlankCellSheetGroup bcsg = _sheetGroupsByBookSheet.get(key);
- if (bcsg == null) {
- return false;
- }
- return bcsg.containsCell(rowIndex, columnIndex);
- }
-
- public boolean isEmpty() {
- return _sheetGroupsByBookSheet.isEmpty();
- }
- }
|