add test case for bug 61701 and use StringBuilder in more places

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1813863 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
PJ Fanning 2017-10-31 09:48:23 +00:00
parent 722ab2d4f1
commit e623808539
19 changed files with 119 additions and 49 deletions

View File

@ -547,8 +547,8 @@ final class LinkTable {
// Workbook scoped name, not actually external after all
NameRecord nr = getNameRecord(definedNameIndex);
int sheetNumber = nr.getSheetNumber();
StringBuffer text = new StringBuffer();
StringBuilder text = new StringBuilder(64);
if (sheetNumber > 0) {
String sheetName = workbook.getSheetName(sheetNumber-1);
SheetNameFormatter.appendFormat(text, sheetName);

View File

@ -1650,7 +1650,7 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss
// adding one here because 0 indicates a global named region; doesn't make sense for print areas
}
String[] parts = COMMA_PATTERN.split(reference);
StringBuffer sb = new StringBuffer(32);
StringBuilder sb = new StringBuilder(32);
for (int i = 0; i < parts.length; i++) {
if(i>0) {
sb.append(",");

View File

@ -47,15 +47,17 @@ public final class SheetNameFormatter {
* sheet name will be converted to double single quotes ('').
*/
public static String format(String rawSheetName) {
StringBuffer sb = new StringBuffer(rawSheetName.length() + 2);
StringBuilder sb = new StringBuilder(rawSheetName.length() + 2);
appendFormat(sb, rawSheetName);
return sb.toString();
}
/**
* Convenience method for ({@link #format(String)}) when a StringBuffer is already available.
*
* @param out - sheet name will be appended here possibly with delimiting quotes
*
* @param out - sheet name will be appended here possibly with delimiting quotes
* @param rawSheetName - sheet name
* @deprecated use <code>appendFormat(StringBuilder out, String rawSheetName)</code> instead
*/
public static void appendFormat(StringBuffer out, String rawSheetName) {
boolean needsQuotes = needsDelimiting(rawSheetName);
@ -67,6 +69,10 @@ public final class SheetNameFormatter {
out.append(rawSheetName);
}
}
/**
* @deprecated use <code>appendFormat(StringBuilder out, String workbookName, String rawSheetName)</code> instead
*/
public static void appendFormat(StringBuffer out, String workbookName, String rawSheetName) {
boolean needsQuotes = needsDelimiting(workbookName) || needsDelimiting(rawSheetName);
if(needsQuotes) {
@ -84,17 +90,54 @@ public final class SheetNameFormatter {
}
}
private static void appendAndEscape(StringBuffer sb, String rawSheetName) {
int len = rawSheetName.length();
for(int i=0; i<len; i++) {
char ch = rawSheetName.charAt(i);
if(ch == DELIMITER) {
// single quotes (') are encoded as ('')
sb.append(DELIMITER);
}
sb.append(ch);
/**
* Convenience method for ({@link #format(String)}) when a StringBuilder is already available.
*
* @param out - sheet name will be appended here possibly with delimiting quotes
* @param rawSheetName - sheet name
*/
public static void appendFormat(StringBuilder out, String rawSheetName) {
boolean needsQuotes = needsDelimiting(rawSheetName);
if(needsQuotes) {
out.append(DELIMITER);
appendAndEscape(out, rawSheetName);
out.append(DELIMITER);
} else {
out.append(rawSheetName);
}
}
public static void appendFormat(StringBuilder out, String workbookName, String rawSheetName) {
boolean needsQuotes = needsDelimiting(workbookName) || needsDelimiting(rawSheetName);
if(needsQuotes) {
out.append(DELIMITER);
out.append('[');
appendAndEscape(out, workbookName.replace('[', '(').replace(']', ')'));
out.append(']');
appendAndEscape(out, rawSheetName);
out.append(DELIMITER);
} else {
out.append('[');
out.append(workbookName);
out.append(']');
out.append(rawSheetName);
}
}
private static void appendAndEscape(Appendable sb, String rawSheetName) {
int len = rawSheetName.length();
for(int i=0; i<len; i++) {
char ch = rawSheetName.charAt(i);
try {
if(ch == DELIMITER) {
// single quotes (') are encoded as ('')
sb.append(DELIMITER);
}
sb.append(ch);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
private static boolean needsDelimiting(String rawSheetName) {
int len = rawSheetName.length();

View File

@ -87,7 +87,7 @@ public class Address implements Function {
}
CellReference ref = new CellReference(row - 1, col - 1, pAbsRow, pAbsCol);
StringBuffer sb = new StringBuffer(32);
StringBuilder sb = new StringBuilder(32);
if(sheetName != null) {
SheetNameFormatter.appendFormat(sb, sheetName);
sb.append('!');

View File

@ -101,7 +101,7 @@ public final class Area3DPxg extends AreaPtgBase implements Pxg3D {
}
public String toFormulaString() {
StringBuffer sb = new StringBuffer();
StringBuilder sb = new StringBuilder(64);
if (externalWorkbookNumber >= 0) {
sb.append('[');
sb.append(externalWorkbookNumber);

View File

@ -65,7 +65,7 @@ public final class Deleted3DPxg extends OperandPtg implements Pxg {
}
public String toFormulaString() {
StringBuffer sb = new StringBuffer();
StringBuilder sb = new StringBuilder(64);
if (externalWorkbookNumber >= 0) {
sb.append('[');
sb.append(externalWorkbookNumber);

View File

@ -32,15 +32,15 @@ final class ExternSheetNameResolver {
public static String prependSheetName(FormulaRenderingWorkbook book, int field_1_index_extern_sheet, String cellRefText) {
ExternalSheet externalSheet = book.getExternalSheet(field_1_index_extern_sheet);
StringBuffer sb;
StringBuilder sb;
if (externalSheet != null) {
String wbName = externalSheet.getWorkbookName();
String sheetName = externalSheet.getSheetName();
if (wbName != null) {
sb = new StringBuffer(wbName.length() + sheetName.length() + cellRefText.length() + 4);
sb = new StringBuilder(wbName.length() + sheetName.length() + cellRefText.length() + 4);
SheetNameFormatter.appendFormat(sb, wbName, sheetName);
} else {
sb = new StringBuffer(sheetName.length() + cellRefText.length() + 4);
sb = new StringBuilder(sheetName.length() + cellRefText.length() + 4);
SheetNameFormatter.appendFormat(sb, sheetName);
}
if (externalSheet instanceof ExternalSheetRange) {
@ -53,7 +53,7 @@ final class ExternSheetNameResolver {
} else {
String firstSheetName = book.getSheetFirstNameByExternSheet(field_1_index_extern_sheet);
String lastSheetName = book.getSheetLastNameByExternSheet(field_1_index_extern_sheet);
sb = new StringBuffer(firstSheetName.length() + cellRefText.length() + 4);
sb = new StringBuilder(firstSheetName.length() + cellRefText.length() + 4);
if (firstSheetName.length() < 1) {
// What excel does if sheet has been deleted
sb.append("#REF"); // note - '!' added just once below

View File

@ -76,7 +76,7 @@ public final class NameXPxg extends OperandPtg implements Pxg {
}
public String toFormulaString() {
StringBuffer sb = new StringBuffer();
StringBuilder sb = new StringBuilder(64);
boolean needsExclamation = false;
if (externalWorkbookNumber >= 0) {
sb.append('[');

View File

@ -100,7 +100,7 @@ public final class Ref3DPxg extends RefPtgBase implements Pxg3D {
}
public String toFormulaString() {
StringBuffer sb = new StringBuffer();
StringBuilder sb = new StringBuilder(64);
if (externalWorkbookNumber >= 0) {
sb.append('[');
sb.append(externalWorkbookNumber);

View File

@ -295,8 +295,8 @@ public class AreaReference {
+ ":" +
CellReference.convertNumToColString(_lastCell.getCol());
}
StringBuffer sb = new StringBuffer(32);
StringBuilder sb = new StringBuilder(32);
sb.append(_firstCell.formatAsString());
if(!_isSingleCell) {
sb.append(CELL_DELIMITER);
@ -311,10 +311,14 @@ public class AreaReference {
}
public String toString() {
StringBuffer sb = new StringBuffer(64);
StringBuilder sb = new StringBuilder(64);
sb.append(getClass().getName()).append(" [");
sb.append(formatAsString());
sb.append("]");
try {
sb.append(formatAsString());
} catch(Exception e) {
sb.append(e.toString());
}
sb.append(']');
return sb.toString();
}

View File

@ -484,7 +484,7 @@ public class CellReference {
* @return the text representation of this cell reference as it would appear in a formula.
*/
public String formatAsString() {
StringBuffer sb = new StringBuffer(32);
StringBuilder sb = new StringBuilder(32);
if(_sheetName != null) {
SheetNameFormatter.appendFormat(sb, _sheetName);
sb.append(SHEET_NAME_DELIMITER);
@ -523,7 +523,7 @@ public class CellReference {
* Appends cell reference with '$' markers for absolute values as required.
* Sheet name is not included.
*/
/* package */ void appendCellReference(StringBuffer sb) {
/* package */ void appendCellReference(StringBuilder sb) {
if (_colIndex != -1) {
if(_isColAbs) {
sb.append(ABSOLUTE_REFERENCE_MARKER);

View File

@ -104,7 +104,7 @@ public abstract class POIXMLTextExtractor extends POITextExtractor {
super.close();
}
protected void checkMaxTextSize(StringBuffer text, String string) {
protected void checkMaxTextSize(CharSequence text, String string) {
if(string == null) {
return;
}

View File

@ -135,7 +135,7 @@ public class XSSFExcelExtractor extends POIXMLTextExtractor
formatter = new DataFormatter(locale);
}
StringBuffer text = new StringBuffer();
StringBuilder text = new StringBuilder(64);
for(Sheet sh : workbook) {
XSSFSheet sheet = (XSSFSheet) sh;
if(includeSheetNames) {
@ -229,13 +229,13 @@ public class XSSFExcelExtractor extends POIXMLTextExtractor
return text.toString();
}
private void handleStringCell(StringBuffer text, Cell cell) {
private void handleStringCell(StringBuilder text, Cell cell) {
String contents = cell.getRichStringCellValue().getString();
checkMaxTextSize(text, contents);
text.append(contents);
}
private void handleNonStringCell(StringBuffer text, Cell cell, DataFormatter formatter) {
private void handleNonStringCell(StringBuilder text, Cell cell, DataFormatter formatter) {
CellType type = cell.getCellType();
if (type == CellType.FORMULA) {
type = cell.getCachedFormulaResultType();

View File

@ -121,7 +121,7 @@ public class SXSSFRow implements Row, Comparable<SXSSFRow>
{
return createCell(column, CellType.BLANK);
}
/**
* Use this to create new cells within the row and return it.
* <p>

View File

@ -283,7 +283,7 @@ public final class XSSFName implements Name {
* Get the sheets name which this named range is referenced to
*
* @return sheet name, which this named range referred to.
* Empty string if the referenced sheet name weas not found.
* Empty string if the referenced sheet name was not found.
*/
public String getSheetName() {
if (_ctName.isSetLocalSheetId()) {

View File

@ -1490,13 +1490,13 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
//short externSheetIndex = getWorkbook().checkExternSheet(sheetIndex);
//name.setExternSheetNumber(externSheetIndex);
String[] parts = COMMA_PATTERN.split(reference);
StringBuffer sb = new StringBuffer(32);
StringBuilder sb = new StringBuilder(32);
for (int i = 0; i < parts.length; i++) {
if(i>0) {
sb.append(",");
sb.append(',');
}
SheetNameFormatter.appendFormat(sb, getSheetName(sheetIndex));
sb.append("!");
sb.append('!');
sb.append(parts[i]);
}
name.setRefersToFormula(sb.toString());

View File

@ -18,7 +18,6 @@
package org.apache.poi.xssf;
import org.apache.poi.ss.format.TestCellFormatPart;
import org.apache.poi.xssf.eventusermodel.TestXSSFReader;
import org.apache.poi.xssf.extractor.TestXSSFExcelExtractor;
import org.apache.poi.xssf.io.TestLoadSaveXSSF;
import org.apache.poi.xssf.model.TestCommentsTable;
@ -29,14 +28,13 @@ import org.apache.poi.xssf.util.TestNumericRanges;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
/**
* Collects all tests for <tt>org.apache.poi.xssf</tt> and sub-packages.
*/
@RunWith(Suite.class)
@Suite.SuiteClasses({
AllXSSFUsermodelTests.class,
TestXSSFReader.class,
//TestXSSFReader.class, //converted to junit4
TestXSSFExcelExtractor.class,
TestLoadSaveXSSF.class,
TestCommentsTable.class,

View File

@ -19,6 +19,7 @@ package org.apache.poi.xssf.eventusermodel;
import static org.apache.poi.POITestCase.assertContains;
import static org.apache.poi.POITestCase.assertNotContained;
import static org.junit.Assert.*;
import java.io.InputStream;
import java.util.Iterator;
@ -29,6 +30,8 @@ import java.util.HashSet;
import org.apache.poi.POIDataSamples;
import org.apache.poi.POIXMLException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.ss.usermodel.Name;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.util.IOUtils;
import org.apache.poi.xssf.XSSFTestDataSamples;
import org.apache.poi.xssf.model.CommentsTable;
@ -36,21 +39,23 @@ import org.apache.poi.xssf.model.StylesTable;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
import org.apache.poi.xssf.usermodel.XSSFShape;
import org.apache.poi.xssf.usermodel.XSSFSimpleShape;
import junit.framework.TestCase;
import org.junit.Ignore;
import org.junit.Test;
/**
* Tests for {@link XSSFReader}
*/
public final class TestXSSFReader extends TestCase {
public final class TestXSSFReader {
private static POIDataSamples _ssTests = POIDataSamples.getSpreadSheetInstance();
@Test
public void testGetBits() throws Exception {
OPCPackage pkg = OPCPackage.open(_ssTests.openResourceAsStream("SampleSS.xlsx"));
XSSFReader r = new XSSFReader(pkg);
assertNotNull(r.getWorkbookData());
assertNotNull(r.getWorkbookData());
assertNotNull(r.getSharedStringsData());
assertNotNull(r.getStylesData());
@ -58,6 +63,7 @@ public final class TestXSSFReader extends TestCase {
assertNotNull(r.getStylesTable());
}
@Test
public void testStyles() throws Exception {
OPCPackage pkg = OPCPackage.open(_ssTests.openResourceAsStream("SampleSS.xlsx"));
@ -74,6 +80,7 @@ public final class TestXSSFReader extends TestCase {
assertNotNull(r.getThemesData());
}
@Test
public void testStrings() throws Exception {
OPCPackage pkg = OPCPackage.open(_ssTests.openResourceAsStream("SampleSS.xlsx"));
@ -83,6 +90,7 @@ public final class TestXSSFReader extends TestCase {
assertEquals("Test spreadsheet", new XSSFRichTextString(r.getSharedStringsTable().getEntryAt(0)).toString());
}
@Test
public void testSheets() throws Exception {
OPCPackage pkg = OPCPackage.open(_ssTests.openResourceAsStream("SampleSS.xlsx"));
@ -115,6 +123,7 @@ public final class TestXSSFReader extends TestCase {
* Check that the sheet iterator returns sheets in the logical order
* (as they are defined in the workbook.xml)
*/
@Test
public void testOrderOfSheets() throws Exception {
OPCPackage pkg = OPCPackage.open(_ssTests.openResourceAsStream("reordered_sheets.xlsx"));
@ -134,7 +143,8 @@ public final class TestXSSFReader extends TestCase {
}
assertEquals(4, count);
}
@Test
public void testComments() throws Exception {
OPCPackage pkg = XSSFTestDataSamples.openSamplePackage("comments.xlsx");
XSSFReader r = new XSSFReader(pkg);
@ -163,6 +173,7 @@ public final class TestXSSFReader extends TestCase {
* XSSFReader method
* @throws Exception
*/
@Test
public void test50119() throws Exception {
OPCPackage pkg = XSSFTestDataSamples.openSamplePackage("WithChartSheet.xlsx");
XSSFReader r = new XSSFReader(pkg);
@ -180,6 +191,7 @@ public final class TestXSSFReader extends TestCase {
*
* @throws Exception
*/
@Test
public void testShapes() throws Exception {
OPCPackage pkg = XSSFTestDataSamples.openSamplePackage("WithTextBox.xlsx");
XSSFReader r = new XSSFReader(pkg);
@ -208,6 +220,7 @@ public final class TestXSSFReader extends TestCase {
return sb.toString();
}
@Test
public void testBug57914() throws Exception {
OPCPackage pkg = XSSFTestDataSamples.openSamplePackage("57914.xlsx");
final XSSFReader r;
@ -234,6 +247,7 @@ public final class TestXSSFReader extends TestCase {
* NPE from XSSFReader$SheetIterator.<init> on XLSX files generated by
* the openpyxl library
*/
@Test
public void test58747() throws Exception {
OPCPackage pkg = XSSFTestDataSamples.openSamplePackage("58747.xlsx");
ReadOnlySharedStringsTable strings = new ReadOnlySharedStringsTable(pkg);
@ -256,6 +270,7 @@ public final class TestXSSFReader extends TestCase {
* NPE when sheet has no relationship id in the workbook
* 60825
*/
@Test
public void testSheetWithNoRelationshipId() throws Exception {
OPCPackage pkg = XSSFTestDataSamples.openSamplePackage("60825.xlsx");
ReadOnlySharedStringsTable strings = new ReadOnlySharedStringsTable(pkg);
@ -283,6 +298,7 @@ public final class TestXSSFReader extends TestCase {
* While this one works correctly:
* &lt;sheet name="Sheet6" sheetId="4" r:id="rId6"/&gt;
*/
@Test
public void test61034() throws Exception {
OPCPackage pkg = XSSFTestDataSamples.openSamplePackage("61034.xlsx");
XSSFReader reader = new XSSFReader(pkg);
@ -297,4 +313,13 @@ public final class TestXSSFReader extends TestCase {
}
pkg.close();
}
@Test
@Ignore("until we fix issue https://bz.apache.org/bugzilla/show_bug.cgi?id=61701")
public void test61701() throws Exception {
try(Workbook workbook = XSSFTestDataSamples.openSampleWorkbook("simple-table-named-range.xlsx")) {
Name name = workbook.getName("total");
System.out.println("workbook.getName(\"total\").getSheetName() returned: " + name.getSheetName());
}
}
}

View File

@ -206,7 +206,7 @@ public final class POIDataSamples {
}
File dataDir = new File(dataDirName, _moduleDir);
if (!dataDir.exists()) {
throw new RuntimeException("Data dir '" + _moduleDir + " does not exist");
throw new RuntimeException("Data dir '" + _moduleDir + "' does not exist");
}
// convert to canonical file, to make any subsequent error messages
// clearer.