155 lines
5.7 KiB
Java
155 lines
5.7 KiB
Java
/* ====================================================================
|
|
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.eval.forked;
|
|
|
|
import java.util.Arrays;
|
|
import java.util.HashMap;
|
|
import java.util.Map;
|
|
|
|
import org.apache.poi.ss.formula.EvaluationCell;
|
|
import org.apache.poi.ss.formula.EvaluationSheet;
|
|
import org.apache.poi.ss.formula.EvaluationWorkbook;
|
|
import org.apache.poi.ss.usermodel.Cell;
|
|
import org.apache.poi.ss.usermodel.Row;
|
|
import org.apache.poi.ss.usermodel.Sheet;
|
|
import org.apache.poi.ss.util.CellReference;
|
|
import org.apache.poi.util.Internal;
|
|
|
|
/**
|
|
* Represents a sheet being used for forked evaluation. Initially, objects of this class contain
|
|
* only the cells from the master workbook. By calling {@link #getOrCreateUpdatableCell(int, int)},
|
|
* the master cell object is logically replaced with a {@link ForkedEvaluationCell} instance, which
|
|
* will be used in all subsequent evaluations.<br/>
|
|
*
|
|
* For POI internal use only
|
|
*/
|
|
@Internal
|
|
final class ForkedEvaluationSheet implements EvaluationSheet {
|
|
|
|
private final EvaluationSheet _masterSheet;
|
|
/**
|
|
* Only cells which have been split are put in this map. (This has been done to conserve memory).
|
|
*/
|
|
private final Map<RowColKey, ForkedEvaluationCell> _sharedCellsByRowCol;
|
|
|
|
public ForkedEvaluationSheet(EvaluationSheet masterSheet) {
|
|
_masterSheet = masterSheet;
|
|
_sharedCellsByRowCol = new HashMap<RowColKey, ForkedEvaluationCell>();
|
|
}
|
|
|
|
@Override
|
|
public EvaluationCell getCell(int rowIndex, int columnIndex) {
|
|
RowColKey key = new RowColKey(rowIndex, columnIndex);
|
|
|
|
ForkedEvaluationCell result = _sharedCellsByRowCol.get(key);
|
|
if (result == null) {
|
|
return _masterSheet.getCell(rowIndex, columnIndex);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public ForkedEvaluationCell getOrCreateUpdatableCell(int rowIndex, int columnIndex) {
|
|
RowColKey key = new RowColKey(rowIndex, columnIndex);
|
|
|
|
ForkedEvaluationCell result = _sharedCellsByRowCol.get(key);
|
|
if (result == null) {
|
|
EvaluationCell mcell = _masterSheet.getCell(rowIndex, columnIndex);
|
|
if (mcell == null) {
|
|
CellReference cr = new CellReference(rowIndex, columnIndex);
|
|
throw new UnsupportedOperationException("Underlying cell '"
|
|
+ cr.formatAsString() + "' is missing in master sheet.");
|
|
}
|
|
result = new ForkedEvaluationCell(this, mcell);
|
|
_sharedCellsByRowCol.put(key, result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public void copyUpdatedCells(Sheet sheet) {
|
|
RowColKey[] keys = new RowColKey[_sharedCellsByRowCol.size()];
|
|
_sharedCellsByRowCol.keySet().toArray(keys);
|
|
Arrays.sort(keys);
|
|
for (int i = 0; i < keys.length; i++) {
|
|
RowColKey key = keys[i];
|
|
Row row = sheet.getRow(key.getRowIndex());
|
|
if (row == null) {
|
|
row = sheet.createRow(key.getRowIndex());
|
|
}
|
|
Cell destCell = row.getCell(key.getColumnIndex());
|
|
if (destCell == null) {
|
|
destCell = row.createCell(key.getColumnIndex());
|
|
}
|
|
|
|
ForkedEvaluationCell srcCell = _sharedCellsByRowCol.get(key);
|
|
srcCell.copyValue(destCell);
|
|
}
|
|
}
|
|
|
|
public int getSheetIndex(EvaluationWorkbook mewb) {
|
|
return mewb.getSheetIndex(_masterSheet);
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* leave the map alone, if it needs resetting, reusing this class is probably a bad idea.
|
|
* @see org.apache.poi.ss.formula.EvaluationSheet#clearAllCachedResultValues()
|
|
*
|
|
* @since POI 3.15 beta 3
|
|
*/
|
|
@Override
|
|
public void clearAllCachedResultValues() {
|
|
_masterSheet.clearAllCachedResultValues();
|
|
}
|
|
|
|
// FIXME: serves same purpose as org.apache.poi.xssf.usermodel.XSSFEvaluationSheet$CellKey
|
|
private static final class RowColKey implements Comparable<RowColKey>{
|
|
private final int _rowIndex;
|
|
private final int _columnIndex;
|
|
|
|
public RowColKey(int rowIndex, int columnIndex) {
|
|
_rowIndex = rowIndex;
|
|
_columnIndex = columnIndex;
|
|
}
|
|
@Override
|
|
public boolean equals(Object obj) {
|
|
if (!(obj instanceof RowColKey)) {
|
|
return false;
|
|
}
|
|
RowColKey other = (RowColKey) obj;
|
|
return _rowIndex == other._rowIndex && _columnIndex == other._columnIndex;
|
|
}
|
|
@Override
|
|
public int hashCode() {
|
|
return _rowIndex ^ _columnIndex;
|
|
}
|
|
@Override
|
|
public int compareTo(RowColKey o) {
|
|
int cmp = _rowIndex - o._rowIndex;
|
|
if (cmp != 0) {
|
|
return cmp;
|
|
}
|
|
return _columnIndex - o._columnIndex;
|
|
}
|
|
public int getRowIndex() {
|
|
return _rowIndex;
|
|
}
|
|
public int getColumnIndex() {
|
|
return _columnIndex;
|
|
}
|
|
}
|
|
}
|