mirror of https://github.com/apache/poi.git
Fixed HSSFCell/FormulaRecordAggregate to properly remove StringRecord when cached result type changes.
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@736476 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
bd48c3cf1e
commit
b5a5ac13db
|
@ -147,7 +147,7 @@ public final class FormulaRecordAggregate extends RecordAggregate implements Cel
|
||||||
rv.visitRecord(sharedFormulaRecord);
|
rv.visitRecord(sharedFormulaRecord);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (_stringRecord != null) {
|
if (_formulaRecord.hasCachedResultString() && _stringRecord != null) {
|
||||||
rv.visitRecord(_stringRecord);
|
rv.visitRecord(_stringRecord);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -180,6 +180,10 @@ public final class FormulaRecordAggregate extends RecordAggregate implements Cel
|
||||||
_stringRecord = null;
|
_stringRecord = null;
|
||||||
_formulaRecord.setCachedResultErrorCode(errorCode);
|
_formulaRecord.setCachedResultErrorCode(errorCode);
|
||||||
}
|
}
|
||||||
|
public void setCachedDoubleResult(double value) {
|
||||||
|
_stringRecord = null;
|
||||||
|
_formulaRecord.setValue(value);
|
||||||
|
}
|
||||||
|
|
||||||
public Ptg[] getFormulaTokens() {
|
public Ptg[] getFormulaTokens() {
|
||||||
if (_sharedFormulaRecord == null) {
|
if (_sharedFormulaRecord == null) {
|
||||||
|
|
|
@ -72,7 +72,6 @@ import org.apache.poi.ss.formula.FormulaType;
|
||||||
* @author Dan Sherman (dsherman at isisph.com)
|
* @author Dan Sherman (dsherman at isisph.com)
|
||||||
* @author Brian Sanders (kestrel at burdell dot org) Active Cell support
|
* @author Brian Sanders (kestrel at burdell dot org) Active Cell support
|
||||||
* @author Yegor Kozlov cell comments support
|
* @author Yegor Kozlov cell comments support
|
||||||
* @version 1.0-pre
|
|
||||||
*/
|
*/
|
||||||
public class HSSFCell implements Cell {
|
public class HSSFCell implements Cell {
|
||||||
/** Numeric Cell type (0) @see #setCellType(int) @see #getCellType() */
|
/** Numeric Cell type (0) @see #setCellType(int) @see #getCellType() */
|
||||||
|
@ -481,7 +480,7 @@ public class HSSFCell implements Cell {
|
||||||
(( NumberRecord ) record).setValue(value);
|
(( NumberRecord ) record).setValue(value);
|
||||||
break;
|
break;
|
||||||
case CELL_TYPE_FORMULA:
|
case CELL_TYPE_FORMULA:
|
||||||
((FormulaRecordAggregate)record).getFormulaRecord().setValue(value);
|
((FormulaRecordAggregate)record).setCachedDoubleResult(value);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -743,7 +742,6 @@ public class HSSFCell implements Cell {
|
||||||
* precalculated value, for booleans we'll set its value. For other types we
|
* precalculated value, for booleans we'll set its value. For other types we
|
||||||
* will change the cell to a boolean cell and set its value.
|
* will change the cell to a boolean cell and set its value.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public void setCellValue(boolean value) {
|
public void setCellValue(boolean value) {
|
||||||
int row=record.getRow();
|
int row=record.getRow();
|
||||||
short col=record.getColumn();
|
short col=record.getColumn();
|
||||||
|
@ -756,7 +754,7 @@ public class HSSFCell implements Cell {
|
||||||
(( BoolErrRecord ) record).setValue(value);
|
(( BoolErrRecord ) record).setValue(value);
|
||||||
break;
|
break;
|
||||||
case CELL_TYPE_FORMULA:
|
case CELL_TYPE_FORMULA:
|
||||||
((FormulaRecordAggregate)record).getFormulaRecord().setCachedResultBoolean(value);
|
((FormulaRecordAggregate)record).setCachedBooleanResult(value);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -780,7 +778,7 @@ public class HSSFCell implements Cell {
|
||||||
(( BoolErrRecord ) record).setValue(errorCode);
|
(( BoolErrRecord ) record).setValue(errorCode);
|
||||||
break;
|
break;
|
||||||
case CELL_TYPE_FORMULA:
|
case CELL_TYPE_FORMULA:
|
||||||
((FormulaRecordAggregate)record).getFormulaRecord().setCachedResultErrorCode(errorCode);
|
((FormulaRecordAggregate)record).setCachedErrorResult(errorCode);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,12 @@ import junit.framework.TestCase;
|
||||||
|
|
||||||
import org.apache.poi.hssf.HSSFTestDataSamples;
|
import org.apache.poi.hssf.HSSFTestDataSamples;
|
||||||
import org.apache.poi.hssf.model.Sheet;
|
import org.apache.poi.hssf.model.Sheet;
|
||||||
|
import org.apache.poi.hssf.record.DBCellRecord;
|
||||||
|
import org.apache.poi.hssf.record.FormulaRecord;
|
||||||
|
import org.apache.poi.hssf.record.Record;
|
||||||
|
import org.apache.poi.hssf.record.StringRecord;
|
||||||
import org.apache.poi.hssf.util.HSSFColor;
|
import org.apache.poi.hssf.util.HSSFColor;
|
||||||
|
import org.apache.poi.ss.usermodel.ErrorConstants;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests various functionality having to do with {@link HSSFCell}. For instance support for
|
* Tests various functionality having to do with {@link HSSFCell}. For instance support for
|
||||||
|
@ -123,8 +128,7 @@ public final class TestHSSFCell extends TestCase {
|
||||||
|
|
||||||
assertEquals("Date from file using 1900 Date Windowing",
|
assertEquals("Date from file using 1900 Date Windowing",
|
||||||
date.getTime(),
|
date.getTime(),
|
||||||
sheet.getRow(0).getCell(0)
|
sheet.getRow(0).getCell(0).getDateCellValue().getTime());
|
||||||
.getDateCellValue().getTime());
|
|
||||||
|
|
||||||
// now check a file with 1904 Date Windowing
|
// now check a file with 1904 Date Windowing
|
||||||
workbook = openSample("1904DateWindowing.xls");
|
workbook = openSample("1904DateWindowing.xls");
|
||||||
|
@ -132,8 +136,7 @@ public final class TestHSSFCell extends TestCase {
|
||||||
|
|
||||||
assertEquals("Date from file using 1904 Date Windowing",
|
assertEquals("Date from file using 1904 Date Windowing",
|
||||||
date.getTime(),
|
date.getTime(),
|
||||||
sheet.getRow(0).getCell(0)
|
sheet.getRow(0).getCell(0).getDateCellValue().getTime());
|
||||||
.getDateCellValue().getTime());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -306,7 +309,7 @@ public final class TestHSSFCell extends TestCase {
|
||||||
assertEquals(1, link2.getFirstColumn());
|
assertEquals(1, link2.getFirstColumn());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*tests the toString() method of HSSFCell*/
|
/**tests the toString() method of HSSFCell*/
|
||||||
public void testToString() {
|
public void testToString() {
|
||||||
HSSFWorkbook wb = new HSSFWorkbook();
|
HSSFWorkbook wb = new HSSFWorkbook();
|
||||||
HSSFRow r = wb.createSheet("Sheet1").createRow(0);
|
HSSFRow r = wb.createSheet("Sheet1").createRow(0);
|
||||||
|
@ -361,11 +364,15 @@ public final class TestHSSFCell extends TestCase {
|
||||||
try {
|
try {
|
||||||
styA.verifyBelongsToWorkbook(wbB);
|
styA.verifyBelongsToWorkbook(wbB);
|
||||||
fail();
|
fail();
|
||||||
} catch (IllegalArgumentException e) {}
|
} catch (IllegalArgumentException e) {
|
||||||
|
// expected during successful test
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
styB.verifyBelongsToWorkbook(wbA);
|
styB.verifyBelongsToWorkbook(wbA);
|
||||||
fail();
|
fail();
|
||||||
} catch (IllegalArgumentException e) {}
|
} catch (IllegalArgumentException e) {
|
||||||
|
// expected during successful test
|
||||||
|
}
|
||||||
|
|
||||||
HSSFCell cellA = wbA.createSheet().createRow(0).createCell(0);
|
HSSFCell cellA = wbA.createSheet().createRow(0).createCell(0);
|
||||||
HSSFCell cellB = wbB.createSheet().createRow(0).createCell(0);
|
HSSFCell cellB = wbB.createSheet().createRow(0).createCell(0);
|
||||||
|
@ -375,11 +382,15 @@ public final class TestHSSFCell extends TestCase {
|
||||||
try {
|
try {
|
||||||
cellA.setCellStyle(styB);
|
cellA.setCellStyle(styB);
|
||||||
fail();
|
fail();
|
||||||
} catch (IllegalArgumentException e) {}
|
} catch (IllegalArgumentException e) {
|
||||||
|
// expected during successful test
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
cellB.setCellStyle(styA);
|
cellB.setCellStyle(styA);
|
||||||
fail();
|
fail();
|
||||||
} catch (IllegalArgumentException e) {}
|
} catch (IllegalArgumentException e) {
|
||||||
|
// expected during successful test
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testChangeTypeStringToBool() {
|
public void testChangeTypeStringToBool() {
|
||||||
|
@ -463,5 +474,52 @@ public final class TestHSSFCell extends TestCase {
|
||||||
}
|
}
|
||||||
assertEquals(true, cell.getBooleanCellValue());
|
assertEquals(true, cell.getBooleanCellValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test for small bug observable around r736460 (prior to version 3.5). POI fails to remove
|
||||||
|
* the {@link StringRecord} following the {@link FormulaRecord} after the result type had been
|
||||||
|
* changed to number/boolean/error. Excel silently ignores the extra record, but some POI
|
||||||
|
* versions (prior to bug 46213 / r717883) crash instead.
|
||||||
|
*/
|
||||||
|
public void testCachedTypeChange() {
|
||||||
|
HSSFSheet sheet = new HSSFWorkbook().createSheet("Sheet1");
|
||||||
|
HSSFCell cell = sheet.createRow(0).createCell(0);
|
||||||
|
cell.setCellFormula("A1");
|
||||||
|
cell.setCellValue("abc");
|
||||||
|
confirmStringRecord(sheet, true);
|
||||||
|
cell.setCellValue(123);
|
||||||
|
Record[] recs = RecordInspector.getRecords(sheet, 0);
|
||||||
|
if (recs.length == 28 && recs[23] instanceof StringRecord) {
|
||||||
|
throw new AssertionFailedError("Identified bug - leftover StringRecord");
|
||||||
|
}
|
||||||
|
confirmStringRecord(sheet, false);
|
||||||
|
|
||||||
|
// string to error code
|
||||||
|
cell.setCellValue("abc");
|
||||||
|
confirmStringRecord(sheet, true);
|
||||||
|
cell.setCellErrorValue((byte)ErrorConstants.ERROR_REF);
|
||||||
|
confirmStringRecord(sheet, false);
|
||||||
|
|
||||||
|
// string to boolean
|
||||||
|
cell.setCellValue("abc");
|
||||||
|
confirmStringRecord(sheet, true);
|
||||||
|
cell.setCellValue(false);
|
||||||
|
confirmStringRecord(sheet, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void confirmStringRecord(HSSFSheet sheet, boolean isPresent) {
|
||||||
|
Record[] recs = RecordInspector.getRecords(sheet, 0);
|
||||||
|
assertEquals(isPresent ? 28 : 27, recs.length);
|
||||||
|
int index = 22;
|
||||||
|
Record fr = recs[index++];
|
||||||
|
assertEquals(FormulaRecord.class, fr.getClass());
|
||||||
|
if (isPresent) {
|
||||||
|
assertEquals(StringRecord.class, recs[index++].getClass());
|
||||||
|
} else {
|
||||||
|
assertFalse(StringRecord.class == recs[index].getClass());
|
||||||
|
}
|
||||||
|
Record dbcr = recs[index++];
|
||||||
|
assertEquals(DBCellRecord.class, dbcr.getClass());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue