blob: 75e7fd9a814a6047f88b1d158c1f80d34b198df1 [file] [log] [blame]
/*
* ====================================================================
* 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.usermodel.charts;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.util.Beta;
/**
* Class {@code DataSources} is a factory for {@link ChartDataSource} instances.
*
* @author Roman Kashitsyn
*/
@Beta
public class DataSources {
private DataSources() {
}
public static <T> ChartDataSource<T> fromArray(T[] elements) {
return new ArrayDataSource<T>(elements);
}
public static ChartDataSource<Number> fromNumericCellRange(Sheet sheet, CellRangeAddress cellRangeAddress) {
return new AbstractCellRangeDataSource<Number>(sheet, cellRangeAddress) {
public Number getPointAt(int index) {
CellValue cellValue = getCellValueAt(index);
if (cellValue != null && cellValue.getCellTypeEnum() == CellType.NUMERIC) {
return Double.valueOf(cellValue.getNumberValue());
} else {
return null;
}
}
public boolean isNumeric() {
return true;
}
};
}
public static ChartDataSource<String> fromStringCellRange(Sheet sheet, CellRangeAddress cellRangeAddress) {
return new AbstractCellRangeDataSource<String>(sheet, cellRangeAddress) {
public String getPointAt(int index) {
CellValue cellValue = getCellValueAt(index);
if (cellValue != null && cellValue.getCellTypeEnum() == CellType.STRING) {
return cellValue.getStringValue();
} else {
return null;
}
}
public boolean isNumeric() {
return false;
}
};
}
private static class ArrayDataSource<T> implements ChartDataSource<T> {
private final T[] elements;
public ArrayDataSource(T[] elements) {
this.elements = elements.clone();
}
public int getPointCount() {
return elements.length;
}
public T getPointAt(int index) {
return elements[index];
}
public boolean isReference() {
return false;
}
public boolean isNumeric() {
Class<?> arrayComponentType = elements.getClass().getComponentType();
return (Number.class.isAssignableFrom(arrayComponentType));
}
public String getFormulaString() {
throw new UnsupportedOperationException("Literal data source can not be expressed by reference.");
}
}
private abstract static class AbstractCellRangeDataSource<T> implements ChartDataSource<T> {
private final Sheet sheet;
private final CellRangeAddress cellRangeAddress;
private final int numOfCells;
private FormulaEvaluator evaluator;
protected AbstractCellRangeDataSource(Sheet sheet, CellRangeAddress cellRangeAddress) {
this.sheet = sheet;
// Make copy since CellRangeAddress is mutable.
this.cellRangeAddress = cellRangeAddress.copy();
this.numOfCells = this.cellRangeAddress.getNumberOfCells();
this.evaluator = sheet.getWorkbook().getCreationHelper().createFormulaEvaluator();
}
public int getPointCount() {
return numOfCells;
}
public boolean isReference() {
return true;
}
public String getFormulaString() {
return cellRangeAddress.formatAsString(sheet.getSheetName(), true);
}
protected CellValue getCellValueAt(int index) {
if (index < 0 || index >= numOfCells) {
throw new IndexOutOfBoundsException("Index must be between 0 and " +
(numOfCells - 1) + " (inclusive), given: " + index);
}
int firstRow = cellRangeAddress.getFirstRow();
int firstCol = cellRangeAddress.getFirstColumn();
int lastCol = cellRangeAddress.getLastColumn();
int width = lastCol - firstCol + 1;
int rowIndex = firstRow + index / width;
int cellIndex = firstCol + index % width;
Row row = sheet.getRow(rowIndex);
return (row == null) ? null : evaluator.evaluate(row.getCell(cellIndex));
}
}
}