/*
* DIFCell.java
*
* Created on January 28, 2008, 8:10 PM
*
* Copyright 2008 Clarke, Solomou & Associates Microsystems Ltd.
*
* This file is part of DIF
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
package com.csam.dif;
import java.math.BigDecimal;
import java.sql.Date;
import java.text.SimpleDateFormat;
/**
*
* This class represents a single data cell in the spreadsheet. It is comprised
* primarily of a type marker and a value holder.
*
*
* Any of the setXXX methods will also set the cell's type
* to more closely represent the data within the cell. However, this dynamic
* typing of the data does mean that using setCellType may lead
* to unexpected behavior, as this method makes no attempt at type-casting
* of any existing values.
*
* @author Nathan Crause
*/
public final class DIFCell {
/**
* enum of the available cell types supported
*/
public enum CellType {
/**
* "empty" cell type - should typically not be used directly
*/
BLANK,
/**
* boolean (true/false) cell type
*/
BOOLEAN,
/**
* numeric cell type
*/
NUMERIC,
/**
* string cell type
*/
STRING,
/**
* date (yyyy/mm/dd) cell type (excludes time)
*/
DATE
}
private Object value;
private DIFSheet sheet;
private int rowNumber;
private int cellNumber;
private CellType cellType;
/**
* Creates a new instance of DIFCell, with a default value (based on the type).
* If the cell type is BLANK or STRING, the default value is an empty string. If
* the cell type is BOOLEAN, the default value is false. If the
* cell type is NUMERIC, the default value is 0 (zero). If the cell type is
* DATE, the default is the current date.
* @param sheet The sheet to which this cell belongs.
* @param rowNumber The row number which contains this cell.
* @param cellNumber The cell number within the parent row of this cell.
* @param cellType The type of data stored in this cell.
*/
protected DIFCell(DIFSheet sheet, int rowNumber, int cellNumber, CellType cellType) {
this.sheet = sheet;
this.rowNumber = rowNumber;
this.cellNumber = cellNumber;
setCellType(cellType);
if (cellType.equals(CellType.BLANK) || cellType.equals(CellType.STRING))
value = "";
else if (cellType.equals(CellType.BOOLEAN))
value = Boolean.FALSE;
else if (cellType.equals(CellType.NUMERIC))
value = BigDecimal.ZERO;
else if (cellType.equals(CellType.DATE))
value = new Date(System.currentTimeMillis());
}
/**
* Returns the sheet to which this cell belongs.
* @return sheet to which this cell belongs.
*/
protected DIFSheet getSheet() {
return sheet;
}
/**
* Sets the current cell type. This method should generally be avoided, as no
* type-conversion takes place when the cell type is being set. If there is
* already data stored in the cell, the results of accessing this object will
* become unreliable.
* @param cellType CellType of data in this cell.
*/
public void setCellType(CellType cellType) {
this.cellType = cellType;
}
/**
* Returns an indication of the type of data stored in this cell.
* @return type of data stored in this cell.
*/
public CellType getCellType() {
return cellType;
}
/**
* Returns the physical row number within the sheet where this cell exists
* (see DIFRow.getRowNumber() for a detailed description of this).
* @return int row number
*/
public int getRowNumber() {
return rowNumber;
}
/**
* Returns the physical cell number within the row where this cell exists. A
* "physical" number is defined as the visual position of the cell as opposed to
* a "logical" position. What this means in real-terms is that in any given row,
* several cells may be "empty". Thus, these cells may not be represented in the
* row model. If the first cell within a row which contains data is located on
* the third cell of the spreadsheet, then the "physical number" is 2 (the numbers
* are zero-based, meaning the first cell is 0, not 1).
* @return int cell number
*/
public int getCellNumber() {
return cellNumber;
}
/**
* Sets this cell's value, and changes the CellType to BOOLEAN
* @param value the boolean value of this cell
*/
public void setCellValue(boolean value) {
setCellType(CellType.BOOLEAN);
this.value = Boolean.valueOf(value);
}
/**
* Sets this cell's value, and changes the CellType to NUMERIC
* @param value the numeric value of this cell
*/
public void setCellValue(BigDecimal value) {
setCellType(CellType.NUMERIC);
this.value = value;
}
/**
* Identical to setCellValue(BigDecimal), except using a native
* data type of double.
* @param value the numeric value of this cell
*/
public void setCellValue(double value) {
setCellValue(BigDecimal.valueOf(value));
}
/**
* Identical to setCellValue(BigDecimal), except using a native
* data type of long.
* @param value the numeric value of this cell
*/
public void setCellValue(long value) {
setCellValue((double)value);
}
/**
* Identical to setCellValue(BigDecimal), except using a native
* data type of int.
* @param value the numeric value of this cell
*/
public void setCellValue(int value) {
setCellValue((double)value);
}
/**
* Sets this cell's value, and changes the CellType to STRING
* @param value the string value of this cell
*/
public void setCellValue(String value) {
setCellType(CellType.STRING);
this.value = value;
}
/**
* Sets this cell's value, and changes the CellType to DATE
* @param value the date value of this cell
*/
public void setCellValue(Date value) {
setCellType(CellType.DATE);
this.value = value;
}
/**
* Returns the value of this cell expressed as a boolean value. If
* the cell type is BOOLEAN, the value returned is an exact reflection
* of this. This the cell type is BLANK then false is
* returned. If the cell type is NUMERIC then true is
* returned for any non-zero value, otherwise false. If the cell type
* is STRING, then the string value is parsed (using
* Boolean.valueOf(String)) and the result returned.
* @return true or alse
* @throws com.csam.dif.DIFDataException if the underlying data type cannot be expressed as a boolean value
*/
public boolean getBooleanCellValue() throws DIFDataException {
if (getCellType().equals(CellType.BLANK))
return false;
if (getCellType().equals(CellType.BOOLEAN))
return (Boolean)value;
if (getCellType().equals(CellType.NUMERIC))
return getNumericCellValue().compareTo(BigDecimal.ZERO) != 0;
if (getCellType().equals(CellType.STRING))
return Boolean.valueOf(getStringCellValue());
throw new DIFDataException("Type '" + getCellType().name() + "' cannot be cast to boolean");
}
/**
* Returns the value of this cell expressed as a numeric value (enclosed in a
* BigDecimal). If the cell type is BLANK the 0 (zero)
* is returned. If the cell type is BOOLEAN then 1 (one) is returned
* for true values, otherwise 0 (zero). If the cell type is
* NUMERIC then the value is returned as-is. If the cell type is
* STRING, then a conversion is attempted (using
* new BigDecimal(String)) and the value of this returned.
* @return numeric value enclosed in a BigDecimal
* @throws com.csam.dif.DIFDataException if the underlying data type cannot be expressed as a numeric value
*/
public BigDecimal getNumericCellValue() throws DIFDataException {
if (getCellType().equals(CellType.BLANK))
return BigDecimal.ZERO;
if (getCellType().equals(CellType.BOOLEAN))
return (Boolean)value ? BigDecimal.ONE : BigDecimal.ZERO;
if (getCellType().equals(CellType.NUMERIC))
return (BigDecimal)value;
if (getCellType().equals(CellType.STRING))
return new BigDecimal(getStringCellValue());
throw new DIFDataException("Type '" + getCellType().name() + "' cannot be cast to boolean");
}
/**
* Returns the value of this cell expressed as a numeric. If the cell type is
* STRING then the value is returned as-is. All other data types
* are converted using String.valueOf(Object).
* @return string representation of cell data
* @throws com.csam.dif.DIFDataException if the underlying data type cannot be expressed as a string value
*/
public String getStringCellValue() throws DIFDataException {
if (getCellType().equals(CellType.BLANK))
return "";
else if (getCellType().equals(CellType.DATE)) {
SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
return fmt.format(getDateCellValue());
}
return String.valueOf(value);
}
/**
* Returns the Date value stored at this cell. No other type
* conversion occurs here. Any other cell type will cause an exception.
* @return Date value of this cell
* @throws com.csam.dif.DIFDataException if the underlying data type cannot be expressed as a date value (i.e. anything
* other than DATE).
*/
public Date getDateCellValue() throws DIFDataException {
if (getCellType().equals(CellType.DATE))
return (Date)value;
throw new DIFDataException("Type '" + getCellType().name() + "' cannot be cast to boolean");
}
/**
* Identical to getNumericCellValue() except the result is expressed
* as a native double type.
* @throws com.csam.dif.DIFDataException if the underlying data type cannot be expressed as a numeric value
* @return numeric value expressed as a double
*/
public double getDoubleCellValue() throws DIFDataException {
return getNumericCellValue().doubleValue();
}
/**
* Identical to getNumericCellValue() except the result is expressed
* as a native double type
* @throws com.csam.dif.DIFDataException if the underlying data type cannot be expressed as a numeric value
* @return numeric value expressed a long
*/
public long getLongCellValue() throws DIFDataException {
return getNumericCellValue().longValueExact();
}
/**
* Identical to getNumericCellValue() except the result is expressed
* as a native double type
* @throws com.csam.dif.DIFDataException if the underlying data type cannot be expressed as a numeric value
* @return numeric value expressed an int
*/
public long getIntCellValue() throws DIFDataException {
return getNumericCellValue().intValueExact();
}
/**
* Used internally to remove the value of this cell.
*/
protected void cleanUp() {
setCellValue("");
}
}
Ads help maintain this website.