From a08b69df801bac0fdb40071fb2007b6bfac37bb1 Mon Sep 17 00:00:00 2001 From: Vladislav Galas Date: Sat, 26 Jan 2019 23:20:07 +0000 Subject: [PATCH] pulled *Cell.setCellValue(String), setCellValue(RichTextString) to the common base git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1852255 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/poi/hssf/usermodel/HSSFCell.java | 53 ++++++-------- .../org/apache/poi/ss/usermodel/CellBase.java | 70 ++++++++++++++++++- .../apache/poi/xssf/streaming/SXSSFCell.java | 61 +++++----------- .../apache/poi/xssf/usermodel/XSSFCell.java | 68 +++++++----------- .../poi/xssf/streaming/TestSXSSFCell.java | 9 +-- .../apache/poi/ss/usermodel/BaseTestCell.java | 2 +- 6 files changed, 141 insertions(+), 122 deletions(-) diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java b/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java index 9292004bb5..12788d5bf9 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java @@ -117,6 +117,14 @@ public class HSSFCell extends CellBase { setCellType(CellType.BLANK, false, row, col,xfindex); } + /** + * {@inheritDoc} + */ + @Override + protected SpreadsheetVersion getSpreadsheetVersion() { + return SpreadsheetVersion.EXCEL97; + } + /** * Returns the HSSFSheet this cell belongs to * @@ -461,43 +469,18 @@ public class HSSFCell extends CellBase { } /** - * set a string value for the cell. - * - * @param value value to set the cell to. For formulas we'll set the formula - * cached string result, for String cells we'll set its value. For other types we will - * change the cell to a string cell and set its value. - * If value is null then we will change the cell to a Blank cell. + * {@inheritDoc} */ - public void setCellValue(String value) { - HSSFRichTextString str = value == null ? null : new HSSFRichTextString(value); - setCellValue(str); + @Override + protected void setCellValueImpl(String value) { + setCellValueImpl(new HSSFRichTextString(value)); } /** - * Set a string value for the cell. - * - * @param value value to set the cell to. For formulas we'll set the formula - * string, for String cells we'll set its value. For other types we will - * change the cell to a string cell and set its value. - * If value is null then we will change the cell to a Blank cell. + * {@inheritDoc} */ - - public void setCellValue(RichTextString value) - { - int row=_record.getRow(); - short col=_record.getColumn(); - short styleIndex=_record.getXFIndex(); - if (value == null) - { - notifyFormulaChanging(); - setCellType(CellType.BLANK, false, row, col, styleIndex); - return; - } - - if(value.length() > SpreadsheetVersion.EXCEL97.getMaxTextLength()){ - throw new IllegalArgumentException("The maximum length of cell contents (text) is 32,767 characters"); - } - + @Override + protected void setCellValueImpl(RichTextString value) { if (_cellType == CellType.FORMULA) { // Set the 'pre-evaluated result' for the formula // note - formulas do not preserve text formatting. @@ -514,6 +497,9 @@ public class HSSFCell extends CellBase { // so handle things as a normal rich text cell if (_cellType != CellType.STRING) { + int row=_record.getRow(); + short col=_record.getColumn(); + short styleIndex=_record.getXFIndex(); setCellType(CellType.STRING, false, row, col, styleIndex); } int index; @@ -527,6 +513,9 @@ public class HSSFCell extends CellBase { _stringValue.setUnicodeString(_book.getWorkbook().getSSTString(index)); } + /** + * {@inheritDoc} + */ @Override protected void setCellFormulaImpl(String formula) { assert formula != null; diff --git a/src/java/org/apache/poi/ss/usermodel/CellBase.java b/src/java/org/apache/poi/ss/usermodel/CellBase.java index 7506ae3419..7193075fa7 100644 --- a/src/java/org/apache/poi/ss/usermodel/CellBase.java +++ b/src/java/org/apache/poi/ss/usermodel/CellBase.java @@ -17,6 +17,7 @@ package org.apache.poi.ss.usermodel; +import org.apache.poi.ss.SpreadsheetVersion; import org.apache.poi.ss.formula.FormulaParseException; import org.apache.poi.ss.util.CellAddress; import org.apache.poi.ss.util.CellRangeAddress; @@ -25,6 +26,7 @@ import org.apache.poi.util.Removal; import java.util.Calendar; import java.util.Date; +import java.util.Locale; /** * Common implementation-independent logic shared by all implementations of {@link Cell}. @@ -196,7 +198,7 @@ public abstract class CellBase implements Cell { * {@inheritDoc} */ @Override - public final void setCellValue(double value) { + public void setCellValue(double value) { if(Double.isInfinite(value)) { // Excel does not support positive/negative infinities, // rather, it gives a #DIV/0! error in these cases. @@ -239,7 +241,7 @@ public abstract class CellBase implements Cell { * {@inheritDoc} */ @Override - public final void setCellValue(Calendar value) { + public void setCellValue(Calendar value) { if(value == null) { setBlank(); return; @@ -255,4 +257,68 @@ public abstract class CellBase implements Cell { * @param value the new calendar value to set */ protected abstract void setCellValueImpl(Calendar value); + + /** + * {@inheritDoc} + */ + @Override + public void setCellValue(String value) { + if(value == null){ + setBlank(); + return; + } + + checkLength(value); + + setCellValueImpl(value); + } + + /** + * Implementation-specific way to set a string value. + * The value is guaranteed to be non-null and to satisfy the length limitation imposed by the spreadsheet version. + * The implementation is expected to adjust cell type accordingly, so that after this call + * getCellType() or getCachedFormulaResultType() (whichever appropriate) would return {@link CellType#STRING}. + * @param value the new value to set. + */ + protected abstract void setCellValueImpl(String value); + + private void checkLength(String value) { + if(value.length() > getSpreadsheetVersion().getMaxTextLength()){ + final String message = String.format(Locale.ROOT, + "The maximum length of cell contents (text) is %d characters", + getSpreadsheetVersion().getMaxTextLength()); + throw new IllegalArgumentException(message); + } + } + + /** + * {@inheritDoc} + */ + @Override + public void setCellValue(RichTextString value) { + if(value == null || value.getString() == null){ + setBlank(); + return; + } + + checkLength(value.getString()); + + setCellValueImpl(value); + } + + /** + * Implementation-specific way to set a RichTextString value. + * The value is guaranteed to be non-null, having non-null value, and to satisfy the length limitation imposed + * by the spreadsheet version. + * The implementation is expected to adjust cell type accordingly, so that after this call + * getCellType() or getCachedFormulaResultType() (whichever appropriate) would return {@link CellType#STRING}. + * @param value the new value to set. + */ + protected abstract void setCellValueImpl(RichTextString value); + + /** + * Get the spreadsheet version for the given implementation. + * @return the spreadsheet version + */ + protected abstract SpreadsheetVersion getSpreadsheetVersion(); } diff --git a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFCell.java b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFCell.java index be95a63114..afe9babe5c 100644 --- a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFCell.java +++ b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFCell.java @@ -58,7 +58,13 @@ public class SXSSFCell extends CellBase { setType(cellType); } -//start of interface implementation + /** + * {@inheritDoc} + */ + @Override + protected SpreadsheetVersion getSpreadsheetVersion() { + return SpreadsheetVersion.EXCEL2007; + } /** * Returns column index of this cell @@ -190,58 +196,29 @@ public class SXSSFCell extends CellBase { } /** - * Set a rich string value for the cell. - * - * @param value value to set the cell to. For formulas: we'll set the formula - * string, for String cells: we'll set its value. For other types we will - * change the cell to a string cell and set its value. - * If value is null then we will change the cell to a Blank cell. + * {@inheritDoc} */ @Override - public void setCellValue(RichTextString value) - { - if (value != null && value.getString() != null) { - if (value.length() > SpreadsheetVersion.EXCEL2007.getMaxTextLength()) { - throw new IllegalArgumentException("The maximum length of cell contents (text) is 32,767 characters"); - } - - ensureRichTextStringType(); + protected void setCellValueImpl(RichTextString value) { + ensureRichTextStringType(); - if(_value instanceof RichTextStringFormulaValue) { - ((RichTextStringFormulaValue) _value).setPreEvaluatedValue(value); - } else { - ((RichTextValue) _value).setValue(value); - } + if(_value instanceof RichTextStringFormulaValue) { + ((RichTextStringFormulaValue) _value).setPreEvaluatedValue(value); } else { - setBlank(); + ((RichTextValue) _value).setValue(value); } } /** - * Set a string value for the cell. - * - * @param value value to set the cell to. For formulas we'll set the formula - * string, for String cells we'll set its value. For other types we will - * change the cell to a string cell and set its value. - * If value is null then we will change the cell to a Blank cell. + * {@inheritDoc} */ @Override - public void setCellValue(String value) - { - if (value != null) { - if (value.length() > SpreadsheetVersion.EXCEL2007.getMaxTextLength()) { - throw new IllegalArgumentException("The maximum length of cell contents (text) is 32,767 characters"); - } - - ensureTypeOrFormulaType(CellType.STRING); - - if(_value.getType() == CellType.FORMULA) { - ((StringFormulaValue) _value).setPreEvaluatedValue(value); - } else { - ((PlainStringValue) _value).setValue(value); - } + protected void setCellValueImpl(String value) { + ensureTypeOrFormulaType(CellType.STRING); + if(_value.getType() == CellType.FORMULA) { + ((StringFormulaValue) _value).setPreEvaluatedValue(value); } else { - setBlank(); + ((PlainStringValue) _value).setValue(value); } } diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCell.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCell.java index ae9eaf7af5..93e265d250 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCell.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCell.java @@ -125,7 +125,15 @@ public final class XSSFCell extends CellBase { _sharedStringSource = row.getSheet().getWorkbook().getSharedStringSource(); _stylesSource = row.getSheet().getWorkbook().getStylesSource(); } - + + /** + * {@inheritDoc} + */ + @Override + protected SpreadsheetVersion getSpreadsheetVersion() { + return SpreadsheetVersion.EXCEL2007; + } + /** * Copy cell value, formula and style, from srcCell per cell copy policy * If srcCell is null, clears the cell value and cell style per cell copy policy @@ -391,55 +399,33 @@ public final class XSSFCell extends CellBase { } /** - * Set a string value for the cell. - * - * @param str value to set the cell to. For formulas we'll set the formula - * cached string result, for String cells we'll set its value. For other types we will - * change the cell to a string cell and set its value. - * If value is null then we will change the cell to a Blank cell. + * {@inheritDoc} */ @Override - public void setCellValue(String str) { - setCellValue(str == null ? null : new XSSFRichTextString(str)); + protected void setCellValueImpl(String value) { + setCellValueImpl(new XSSFRichTextString(value)); } /** - * Set a string value for the cell. - * - * @param str value to set the cell to. For formulas we'll set the 'pre-evaluated result string, - * for String cells we'll set its value. For other types we will - * change the cell to a string cell and set its value. - * If value is null then we will change the cell to a Blank cell. + * {@inheritDoc} */ @Override - public void setCellValue(RichTextString str) { - if(str == null || str.getString() == null){ - setBlank(); - return; - } - - if(str.length() > SpreadsheetVersion.EXCEL2007.getMaxTextLength()){ - throw new IllegalArgumentException("The maximum length of cell contents (text) is 32,767 characters"); - } - + protected void setCellValueImpl(RichTextString str) { CellType cellType = getCellType(); - switch (cellType){ - case FORMULA: + if (cellType == CellType.FORMULA) { + _cell.setV(str.getString()); + _cell.setT(STCellType.STR); + } else { + if(_cell.getT() == STCellType.INLINE_STR) { + //set the 'pre-evaluated result _cell.setV(str.getString()); - _cell.setT(STCellType.STR); - break; - default: - if(_cell.getT() == STCellType.INLINE_STR) { - //set the 'pre-evaluated result - _cell.setV(str.getString()); - } else { - _cell.setT(STCellType.S); - XSSFRichTextString rt = (XSSFRichTextString)str; - rt.setStylesTableReference(_stylesSource); - int sRef = _sharedStringSource.addSharedStringItem(rt); - _cell.setV(Integer.toString(sRef)); - } - break; + } else { + _cell.setT(STCellType.S); + XSSFRichTextString rt = (XSSFRichTextString)str; + rt.setStylesTableReference(_stylesSource); + int sRef = _sharedStringSource.addSharedStringItem(rt); + _cell.setV(Integer.toString(sRef)); + } } } diff --git a/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFCell.java b/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFCell.java index c834cd528b..31c0c61316 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFCell.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFCell.java @@ -25,6 +25,7 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import java.io.IOException; +import java.nio.charset.StandardCharsets; import javax.xml.namespace.QName; @@ -45,7 +46,6 @@ import org.junit.Ignore; import org.junit.Test; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRst; -import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; @@ -121,9 +121,10 @@ public class TestSXSSFCell extends BaseTestXCell { @Test(expected = IllegalArgumentException.class) public void setCellValue_withTooLongRichTextString_throwsIAE() { Cell cell = spy(new SXSSFCell(null, CellType.BLANK)); - RichTextString string = spy(new XSSFRichTextString("")); - doReturn(SpreadsheetVersion.EXCEL2007.getMaxTextLength() + 1).when(string).length(); - cell.setCellValue(string); + int length = SpreadsheetVersion.EXCEL2007.getMaxTextLength() + 1; + String string = new String(new byte[length], StandardCharsets.UTF_8).replace("\0", "x"); + RichTextString richTextString = new XSSFRichTextString(string); + cell.setCellValue(richTextString); } @Test diff --git a/src/testcases/org/apache/poi/ss/usermodel/BaseTestCell.java b/src/testcases/org/apache/poi/ss/usermodel/BaseTestCell.java index 1e2b4d4f96..41a2f5aa1c 100644 --- a/src/testcases/org/apache/poi/ss/usermodel/BaseTestCell.java +++ b/src/testcases/org/apache/poi/ss/usermodel/BaseTestCell.java @@ -967,7 +967,7 @@ public abstract class BaseTestCell { cell.setCellValue(b.toString()); fail("Expected exception"); } catch (IllegalArgumentException e){ - assertEquals("The maximum length of cell contents (text) is 32,767 characters", e.getMessage()); + assertEquals("The maximum length of cell contents (text) is 32767 characters", e.getMessage()); } wb.close(); } -- 2.39.5