From 4d543f165d219389e06ba7296bd97bab17dd58a1 Mon Sep 17 00:00:00 2001 From: Andreas Beeker Date: Fri, 2 Nov 2018 22:59:58 +0000 Subject: [PATCH 01/28] Bug 62872 - Writing large files with 800k rows gives java.io.IOException: This archive contains unclosed entries. git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1845629 13f79535-47bb-0310-9956-ffa450edef68 --- .../poi/xssf/streaming/SXSSFWorkbook.java | 5 +- .../poi/xssf/usermodel/TestSXSSFBugs.java | 47 +++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java index 6fbcb14035..ed52e0e16b 100644 --- a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java +++ b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java @@ -381,7 +381,10 @@ public class SXSSFWorkbook implements Workbook { Enumeration en = zipEntrySource.getEntries(); while (en.hasMoreElements()) { ZipArchiveEntry ze = en.nextElement(); - zos.putArchiveEntry(new ZipArchiveEntry(ze.getName())); + ZipArchiveEntry zeOut = new ZipArchiveEntry(ze.getName()); + zeOut.setSize(ze.getSize()); + zeOut.setTime(ze.getTime()); + zos.putArchiveEntry(zeOut); try (final InputStream is = zipEntrySource.getInputStream(ze)) { if (is instanceof ZipArchiveThresholdInputStream) { // #59743 - disable Threshold handling for SXSSF copy diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestSXSSFBugs.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestSXSSFBugs.java index 3958aa2f6e..73d56c7a77 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestSXSSFBugs.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestSXSSFBugs.java @@ -21,7 +21,10 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.fail; +import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; +import java.util.Date; import org.apache.poi.ss.ITestDataProvider; import org.apache.poi.ss.usermodel.BaseTestBugzillaIssues; @@ -34,6 +37,9 @@ import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.xssf.SXSSFITestDataProvider; import org.apache.poi.xssf.XSSFITestDataProvider; +import org.apache.poi.xssf.streaming.SXSSFCell; +import org.apache.poi.xssf.streaming.SXSSFRow; +import org.apache.poi.xssf.streaming.SXSSFSheet; import org.apache.poi.xssf.streaming.SXSSFWorkbook; import org.junit.Ignore; import org.junit.Test; @@ -166,4 +172,45 @@ public final class TestSXSSFBugs extends BaseTestBugzillaIssues { CellRangeAddress range = new CellRangeAddress(rowIndex, rowIndex, colIndex, colIndex); sheet.setArrayFormula(col1Value, range); } + + @Test + @Ignore("takes too long for the normal test run") + public void test62872() throws Exception { + final int COLUMN_COUNT = 300; + final int ROW_COUNT = 600000; + final int TEN_MINUTES = 1000*60*10; + + SXSSFWorkbook workbook = new SXSSFWorkbook(100); + workbook.setCompressTempFiles(true); + SXSSFSheet sheet = workbook.createSheet("RawData"); + + SXSSFRow row = sheet.createRow(0); + SXSSFCell cell; + + for (int i = 1; i <= COLUMN_COUNT; i++) { + cell = row.createCell(i - 1); + cell.setCellValue("Column " + i); + } + + for (int i = 1; i < ROW_COUNT; i++) { + row = sheet.createRow(i); + for (int j = 1; j <= COLUMN_COUNT; j++) { + cell = row.createCell(j - 1); + + //make some noise + cell.setCellValue(new Date(i*TEN_MINUTES+(j*TEN_MINUTES)/COLUMN_COUNT)); + } + i++; + // if (i % 1000 == 0) + // logger.info("Created Row " + i); + } + + try (FileOutputStream out = new FileOutputStream(File.createTempFile("test62872", ".xlsx"))) { + workbook.write(out); + workbook.dispose(); + workbook.close(); + out.flush(); + } + // logger.info("File written!"); + } } From f006c8ee6b278f16c5abd8649f0dd131e5a4aae1 Mon Sep 17 00:00:00 2001 From: PJ Fanning Date: Tue, 13 Nov 2018 08:20:47 +0000 Subject: [PATCH 02/28] add testcase for https://bz.apache.org/bugzilla/show_bug.cgi?id=62906 git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1846489 13f79535-47bb-0310-9956-ffa450edef68 --- .../xssf/usermodel/examples/CreateTable.java | 4 +- .../apache/poi/xssf/usermodel/XSSFSheet.java | 9 +- .../poi/xssf/usermodel/TestXSSFSheet.java | 16 ++- .../poi/xssf/usermodel/TestXSSFTable.java | 98 ++++++++++++------- 4 files changed, 75 insertions(+), 52 deletions(-) diff --git a/src/examples/src/org/apache/poi/xssf/usermodel/examples/CreateTable.java b/src/examples/src/org/apache/poi/xssf/usermodel/examples/CreateTable.java index c2fc068afe..079aa163b0 100644 --- a/src/examples/src/org/apache/poi/xssf/usermodel/examples/CreateTable.java +++ b/src/examples/src/org/apache/poi/xssf/usermodel/examples/CreateTable.java @@ -36,8 +36,8 @@ public class CreateTable { public static void main(String[] args) throws IOException { - try (Workbook wb = new XSSFWorkbook()) { - XSSFSheet sheet = (XSSFSheet) wb.createSheet(); + try (XSSFWorkbook wb = new XSSFWorkbook()) { + XSSFSheet sheet = wb.createSheet(); // Set which area the table should be placed in AreaReference reference = wb.getCreationHelper().createAreaReference( diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java index d776f8fc00..bbd7eda838 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java @@ -4109,18 +4109,17 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet { int tableNumber = getPackagePart().getPackage().getPartsByContentType(XSSFRelation.TABLE.getContentType()).size() + 1; // the id could already be taken after insertion/deletion of different tables - outerloop: - while(true) { + boolean loop = true; + while(loop) { + loop = false; for (PackagePart packagePart : getPackagePart().getPackage().getPartsByContentType(XSSFRelation.TABLE.getContentType())) { String fileName = XSSFRelation.TABLE.getFileName(tableNumber); if(fileName.equals(packagePart.getPartName().getName())) { // duplicate found, increase the number and start iterating again tableNumber++; - continue outerloop; + loop = true; } } - - break; } RelationPart rp = createRelationship(XSSFRelation.TABLE, XSSFFactory.getInstance(), tableNumber, false); diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheet.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheet.java index 63fbf8b616..de828ba1c9 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheet.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheet.java @@ -55,10 +55,7 @@ import org.apache.poi.ss.usermodel.IndexedColors; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.util.CellAddress; -import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.ss.util.CellReference; -import org.apache.poi.ss.util.CellUtil; +import org.apache.poi.ss.util.*; import org.apache.poi.util.LocaleUtil; import org.apache.poi.xssf.XSSFITestDataProvider; import org.apache.poi.xssf.XSSFTestDataSamples; @@ -1993,12 +1990,11 @@ public final class TestXSSFSheet extends BaseTestXSheet { @Test public void testGetHeaderFooterProperties() throws IOException { - XSSFWorkbook wb = new XSSFWorkbook(); - XSSFSheet sh = wb.createSheet(); + try (XSSFWorkbook wb = new XSSFWorkbook()) { + XSSFSheet sh = wb.createSheet(); - XSSFHeaderFooterProperties hfProp = sh.getHeaderFooterProperties(); - assertNotNull(hfProp); - - wb.close(); + XSSFHeaderFooterProperties hfProp = sh.getHeaderFooterProperties(); + assertNotNull(hfProp); + } } } diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFTable.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFTable.java index e8cda3ee92..7b0331a658 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFTable.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFTable.java @@ -348,15 +348,45 @@ public final class TestXSSFTable { IOUtils.closeQuietly(wb); } - + + @Test + public void testCreateTableIds() throws IOException { + try (XSSFWorkbook wb = new XSSFWorkbook()) { + XSSFSheet sheet = wb.createSheet(); + + AreaReference reference1 = wb.getCreationHelper().createAreaReference( + new CellReference(0, 0), new CellReference(2, 2)); + + XSSFTable table1 = sheet.createTable(reference1); + + assertEquals(1, table1.getCTTable().getTableColumns().getTableColumnArray(0).getId()); + assertEquals(2, table1.getCTTable().getTableColumns().getTableColumnArray(1).getId()); + assertEquals(3, table1.getCTTable().getTableColumns().getTableColumnArray(2).getId()); + + assertEquals(1, table1.getCTTable().getId()); + + AreaReference reference2 = wb.getCreationHelper().createAreaReference( + new CellReference(10, 10), new CellReference(12, 12)); + + XSSFTable table2 = sheet.createTable(reference2); + + // these IDs dupplicate those from table1 and may be cause of https://bz.apache.org/bugzilla/show_bug.cgi?id=62906 + assertEquals(1, table2.getCTTable().getTableColumns().getTableColumnArray(0).getId()); + assertEquals(2, table2.getCTTable().getTableColumns().getTableColumnArray(1).getId()); + assertEquals(3, table2.getCTTable().getTableColumns().getTableColumnArray(2).getId()); + + assertEquals(2, table2.getCTTable().getId()); + } + } + @Test public void testSetArea() throws IOException { - XSSFWorkbook wb = new XSSFWorkbook(); + try (XSSFWorkbook wb = new XSSFWorkbook()) { XSSFSheet sh = wb.createSheet(); - + AreaReference tableArea = new AreaReference("B10:D12", wb.getSpreadsheetVersion()); XSSFTable table = sh.createTable(tableArea); - + assertEquals(3, table.getColumnCount()); assertEquals(3, table.getRowCount()); @@ -366,11 +396,11 @@ public final class TestXSSFTable { assertEquals(3, table.getColumnCount()); assertEquals(3, table.getRowCount()); - + // increase size by 1 row and 1 column AreaReference tableArea3 = new AreaReference("B11:E14", wb.getSpreadsheetVersion()); table.setArea(tableArea3); - + assertEquals(4, table.getColumnCount()); assertEquals(4, table.getRowCount()); @@ -380,43 +410,41 @@ public final class TestXSSFTable { assertEquals(2, table.getColumnCount()); assertEquals(2, table.getRowCount()); - - IOUtils.closeQuietly(wb); + } } @Test - public void testCreateColumn() { - XSSFWorkbook wb = new XSSFWorkbook(); - XSSFSheet sh = wb.createSheet(); - - AreaReference tableArea = new AreaReference("A2:A3", wb.getSpreadsheetVersion()); - XSSFTable table = sh.createTable(tableArea); + public void testCreateColumn() throws IOException { + try (XSSFWorkbook wb = new XSSFWorkbook()) { + XSSFSheet sh = wb.createSheet(); - assertEquals(1, table.getColumnCount()); - assertEquals(2, table.getRowCount()); + AreaReference tableArea = new AreaReference("A2:A3", wb.getSpreadsheetVersion()); + XSSFTable table = sh.createTable(tableArea); - // add columns - XSSFTableColumn c1 = table.getColumns().get(0); - XSSFTableColumn cB = table.createColumn("Column B"); - XSSFTableColumn cD = table.createColumn("Column D"); - XSSFTableColumn cC = table.createColumn("Column C", 2); // add between B and D - table.updateReferences(); - table.updateHeaders(); + assertEquals(1, table.getColumnCount()); + assertEquals(2, table.getRowCount()); - assertEquals(4, table.getColumnCount()); - assertEquals(2, table.getRowCount()); + // add columns + XSSFTableColumn c1 = table.getColumns().get(0); + XSSFTableColumn cB = table.createColumn("Column B"); + XSSFTableColumn cD = table.createColumn("Column D"); + XSSFTableColumn cC = table.createColumn("Column C", 2); // add between B and D + table.updateReferences(); + table.updateHeaders(); - // column IDs start at 1, and increase in the order columns are added (see bug #62740) - assertEquals("Column c ID", 1, c1.getId()); - assertTrue("Column B ID", c1.getId() < cB.getId()); - assertTrue("Column D ID", cB.getId() < cD.getId()); - assertTrue("Column C ID", cD.getId() < cC.getId()); - assertEquals("Column 1", table.getColumns().get(0).getName()); // generated name - assertEquals("Column B", table.getColumns().get(1).getName()); - assertEquals("Column C", table.getColumns().get(2).getName()); - assertEquals("Column D", table.getColumns().get(3).getName()); + assertEquals(4, table.getColumnCount()); + assertEquals(2, table.getRowCount()); - IOUtils.closeQuietly(wb); + // column IDs start at 1, and increase in the order columns are added (see bug #62740) + assertEquals("Column c ID", 1, c1.getId()); + assertTrue("Column B ID", c1.getId() < cB.getId()); + assertTrue("Column D ID", cB.getId() < cD.getId()); + assertTrue("Column C ID", cD.getId() < cC.getId()); + assertEquals("Column 1", table.getColumns().get(0).getName()); // generated name + assertEquals("Column B", table.getColumns().get(1).getName()); + assertEquals("Column C", table.getColumns().get(2).getName()); + assertEquals("Column D", table.getColumns().get(3).getName()); + } } @Test(expected = IllegalArgumentException.class) From 0e5c563ccfd13c0742cfac09898f6d55954e6058 Mon Sep 17 00:00:00 2001 From: PJ Fanning Date: Tue, 13 Nov 2018 08:37:11 +0000 Subject: [PATCH 03/28] add testcase for https://bz.apache.org/bugzilla/show_bug.cgi?id=62906 git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1846492 13f79535-47bb-0310-9956-ffa450edef68 --- .../testcases/org/apache/poi/xssf/usermodel/TestXSSFTable.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFTable.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFTable.java index 7b0331a658..a43c8ca6ac 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFTable.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFTable.java @@ -358,6 +358,7 @@ public final class TestXSSFTable { new CellReference(0, 0), new CellReference(2, 2)); XSSFTable table1 = sheet.createTable(reference1); + assertEquals("A1:C3", table1.getCTTable().getRef()); assertEquals(1, table1.getCTTable().getTableColumns().getTableColumnArray(0).getId()); assertEquals(2, table1.getCTTable().getTableColumns().getTableColumnArray(1).getId()); @@ -369,6 +370,7 @@ public final class TestXSSFTable { new CellReference(10, 10), new CellReference(12, 12)); XSSFTable table2 = sheet.createTable(reference2); + assertEquals("K11:M13", table2.getCTTable().getRef()); // these IDs dupplicate those from table1 and may be cause of https://bz.apache.org/bugzilla/show_bug.cgi?id=62906 assertEquals(1, table2.getCTTable().getTableColumns().getTableColumnArray(0).getId()); From d0af7b3a9a13535aa5c6a964e680b1999989c53a Mon Sep 17 00:00:00 2001 From: PJ Fanning Date: Tue, 13 Nov 2018 09:19:05 +0000 Subject: [PATCH 04/28] fix typo git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1846497 13f79535-47bb-0310-9956-ffa450edef68 --- .../testcases/org/apache/poi/xssf/usermodel/TestXSSFTable.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFTable.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFTable.java index a43c8ca6ac..b004319426 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFTable.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFTable.java @@ -372,7 +372,7 @@ public final class TestXSSFTable { XSSFTable table2 = sheet.createTable(reference2); assertEquals("K11:M13", table2.getCTTable().getRef()); - // these IDs dupplicate those from table1 and may be cause of https://bz.apache.org/bugzilla/show_bug.cgi?id=62906 + // these IDs duplicate those from table1 and may be cause of https://bz.apache.org/bugzilla/show_bug.cgi?id=62906 assertEquals(1, table2.getCTTable().getTableColumns().getTableColumnArray(0).getId()); assertEquals(2, table2.getCTTable().getTableColumns().getTableColumnArray(1).getId()); assertEquals(3, table2.getCTTable().getTableColumns().getTableColumnArray(2).getId()); From d1deecfc9c54bafa78e6e328c9f024174fb6db63 Mon Sep 17 00:00:00 2001 From: PJ Fanning Date: Tue, 13 Nov 2018 16:08:11 +0000 Subject: [PATCH 05/28] [bug-62908] populate NamedColors git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1846520 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/poi/ss/format/CellFormatPart.java | 26 ++++++++----------- .../poi/ss/format/TestCellFormatPart.java | 16 ++++++++++++ 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/src/java/org/apache/poi/ss/format/CellFormatPart.java b/src/java/org/apache/poi/ss/format/CellFormatPart.java index 2651edd8c6..e56aa3d867 100644 --- a/src/java/org/apache/poi/ss/format/CellFormatPart.java +++ b/src/java/org/apache/poi/ss/format/CellFormatPart.java @@ -54,26 +54,22 @@ public class CellFormatPart { private final CellFormatter format; private final CellFormatType type; - private static final Map NAMED_COLORS; + static final Map NAMED_COLORS; static { NAMED_COLORS = new TreeMap<>( String.CASE_INSENSITIVE_ORDER); - Map colors = HSSFColor.getIndexHash(); - for (HSSFColor color : colors.values()) { - Class type = color.getClass(); - String name = type.getSimpleName(); - if (name.equals(name.toUpperCase(Locale.ROOT))) { - short[] rgb = color.getTriplet(); - Color c = new Color(rgb[0], rgb[1], rgb[2]); - NAMED_COLORS.put(name, c); - if (name.indexOf('_') > 0) - NAMED_COLORS.put(name.replace('_', ' '), c); - if (name.indexOf("_PERCENT") > 0) - NAMED_COLORS.put(name.replace("_PERCENT", "%").replace('_', - ' '), c); - } + for (HSSFColor.HSSFColorPredefined color : HSSFColor.HSSFColorPredefined.values()) { + String name = color.name(); + short[] rgb = color.getTriplet(); + Color c = new Color(rgb[0], rgb[1], rgb[2]); + NAMED_COLORS.put(name, c); + if (name.indexOf('_') > 0) + NAMED_COLORS.put(name.replace('_', ' '), c); + if (name.indexOf("_PERCENT") > 0) + NAMED_COLORS.put(name.replace("_PERCENT", "%").replace('_', + ' '), c); } } diff --git a/src/ooxml/testcases/org/apache/poi/ss/format/TestCellFormatPart.java b/src/ooxml/testcases/org/apache/poi/ss/format/TestCellFormatPart.java index bc66fc4463..583fa8b851 100644 --- a/src/ooxml/testcases/org/apache/poi/ss/format/TestCellFormatPart.java +++ b/src/ooxml/testcases/org/apache/poi/ss/format/TestCellFormatPart.java @@ -17,12 +17,15 @@ package org.apache.poi.ss.format; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; import java.util.Locale; import java.util.TimeZone; import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.apache.poi.hssf.util.HSSFColor; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.util.LocaleUtil; import org.apache.poi.xssf.XSSFITestDataProvider; @@ -153,6 +156,19 @@ public class TestCellFormatPart extends CellFormatTestBase { }); } + @Test + public void testNamedColors() { + assertTrue(CellFormatPart.NAMED_COLORS.size() >= HSSFColor.HSSFColorPredefined.values().length); + assertNotNull(CellFormatPart.NAMED_COLORS.get("GREEN")); + assertNotNull(CellFormatPart.NAMED_COLORS.get("Green")); + assertNotNull(CellFormatPart.NAMED_COLORS.get("RED")); + assertNotNull(CellFormatPart.NAMED_COLORS.get("Red")); + assertNotNull(CellFormatPart.NAMED_COLORS.get("BLUE")); + assertNotNull(CellFormatPart.NAMED_COLORS.get("Blue")); + assertNotNull(CellFormatPart.NAMED_COLORS.get("YELLOW")); + assertNotNull(CellFormatPart.NAMED_COLORS.get("Yellow")); + } + private double extractNumber(String str) { Matcher m = NUMBER_EXTRACT_FMT.matcher(str); if (!m.find()) From 85f6277c27a2179abd150409a8e9019945e0f741 Mon Sep 17 00:00:00 2001 From: PJ Fanning Date: Tue, 13 Nov 2018 21:30:49 +0000 Subject: [PATCH 06/28] remove unused import git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1846548 13f79535-47bb-0310-9956-ffa450edef68 --- .../src/org/apache/poi/xssf/usermodel/examples/CreateTable.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/examples/src/org/apache/poi/xssf/usermodel/examples/CreateTable.java b/src/examples/src/org/apache/poi/xssf/usermodel/examples/CreateTable.java index 079aa163b0..482184face 100644 --- a/src/examples/src/org/apache/poi/xssf/usermodel/examples/CreateTable.java +++ b/src/examples/src/org/apache/poi/xssf/usermodel/examples/CreateTable.java @@ -19,7 +19,6 @@ package org.apache.poi.xssf.usermodel.examples; import java.io.FileOutputStream; import java.io.IOException; -import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.util.AreaReference; import org.apache.poi.ss.util.CellReference; import org.apache.poi.xssf.usermodel.XSSFCell; From 218a7190ba3e87013b141dcefa112039ba5e76e3 Mon Sep 17 00:00:00 2001 From: PJ Fanning Date: Tue, 13 Nov 2018 21:34:03 +0000 Subject: [PATCH 07/28] remove duplicate attempt to add column headers git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1846549 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/poi/xssf/usermodel/examples/CreateTable.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/examples/src/org/apache/poi/xssf/usermodel/examples/CreateTable.java b/src/examples/src/org/apache/poi/xssf/usermodel/examples/CreateTable.java index 482184face..ad2b6adcdd 100644 --- a/src/examples/src/org/apache/poi/xssf/usermodel/examples/CreateTable.java +++ b/src/examples/src/org/apache/poi/xssf/usermodel/examples/CreateTable.java @@ -77,10 +77,6 @@ public class CreateTable { } } } - // Create the columns - table.createColumn("Column 1"); - table.createColumn("Column 2"); - table.createColumn("Column 3"); // Save try (FileOutputStream fileOut = new FileOutputStream("ooxml-table.xlsx")) { From 46f6c45f6c2b7b899cb877591a06dac338ab6d91 Mon Sep 17 00:00:00 2001 From: PJ Fanning Date: Fri, 16 Nov 2018 07:57:49 +0000 Subject: [PATCH 08/28] put back XSSFColor(java.awt.Color clr) constructor git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1846701 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/poi/xssf/usermodel/XSSFColor.java | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFColor.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFColor.java index ae206f3c34..be632b3c46 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFColor.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFColor.java @@ -47,7 +47,7 @@ public class XSSFColor extends ExtendedColor { * @deprecated 3.17 beta 1 - pass the workbook styles indexed color map, if any */ @Deprecated - @Removal(version="3.19") + @Removal(version="4.2") public XSSFColor(CTColor color) { this(color, new DefaultIndexedColorMap()); } @@ -59,6 +59,7 @@ public class XSSFColor extends ExtendedColor { * @deprecated 4.0.0 - use the factory {@link #from(CTColor, IndexedColorMap)} method instead to check for null CTColor instances. Make private eventually */ @Deprecated + @Removal(version = "4.2") public XSSFColor(CTColor color, IndexedColorMap map) { this.ctColor = color; this.indexedColorMap = map; @@ -72,7 +73,7 @@ public class XSSFColor extends ExtendedColor { * @see #from(CTColor, IndexedColorMap) */ @Deprecated - @Removal(version="4.1") + @Removal(version="4.2") public XSSFColor() { this(CTColor.Factory.newInstance(), new DefaultIndexedColorMap()); } @@ -84,7 +85,18 @@ public class XSSFColor extends ExtendedColor { public XSSFColor(IndexedColorMap colorMap) { this(CTColor.Factory.newInstance(), colorMap); } - + + /** + * Create an instance of XSSFColor from the awt Color + * @param clr awt Color + * @deprecated 3.17 beta 1 - pass the workbook styles indexed color map, if any + */ + @Deprecated + @Removal(version="4.2") + public XSSFColor(java.awt.Color clr) { + this(clr, new DefaultIndexedColorMap()); + } + /** * TEST ONLY * @param clr awt Color From 03abb9edf410f0b6b199127f950209e63ae03161 Mon Sep 17 00:00:00 2001 From: Dominik Stadler Date: Fri, 16 Nov 2018 11:25:59 +0000 Subject: [PATCH 09/28] Try to create the temporary directory for ImageIO to see if that makes the tests work again when built with Maven git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1846706 13f79535-47bb-0310-9956-ffa450edef68 --- .../hssf/usermodel/TestHSSFPictureData.java | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFPictureData.java b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFPictureData.java index 5326e759d9..df7d7cf213 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFPictureData.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFPictureData.java @@ -19,6 +19,7 @@ package org.apache.poi.hssf.usermodel; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; +import java.io.File; import java.io.IOException; import java.util.List; @@ -27,6 +28,7 @@ import javax.imageio.ImageIO; import junit.framework.TestCase; import org.apache.poi.hssf.HSSFTestDataSamples; +import org.junit.BeforeClass; /** * Test HSSFPictureData. @@ -36,7 +38,19 @@ import org.apache.poi.hssf.HSSFTestDataSamples; * @author Trejkaz (trejkaz at trypticon dot org) */ public final class TestHSSFPictureData extends TestCase{ - + @BeforeClass + public static void setUpClass() { + // ensure that temp-dir exists because ImageIO requires it + String tmpDirProperty = System.getProperty("java.io.tmpdir"); + if(tmpDirProperty != null) { + final File tmpDir = new File(tmpDirProperty); + if(!tmpDir.exists()) { + if(!tmpDir.mkdirs()) { + throw new IllegalStateException("Could not create temporary directory " + tmpDirProperty + ", full path " + tmpDir.getAbsolutePath()); + } + } + } + } public void testPictures() throws IOException { HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("SimpleWithImages.xls"); @@ -64,8 +78,8 @@ public final class TestHSSFPictureData extends TestCase{ assertEquals(300, png.getHeight()); assertEquals(HSSFWorkbook.PICTURE_TYPE_PNG, pict.getFormat()); assertEquals("image/png", pict.getMimeType()); - } else { - //TODO: test code for PICT, WMF and EMF + /*} else { + //TODO: test code for PICT, WMF and EMF*/ } } } @@ -93,7 +107,7 @@ public final class TestHSSFPictureData extends TestCase{ assertEquals("image/png", pict.getMimeType()); } - public void testNotNullPictures() throws IOException { + public void testNotNullPictures() { HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("SheetWithDrawing.xls"); @@ -103,5 +117,4 @@ public final class TestHSSFPictureData extends TestCase{ assertNotNull(pict); } } - } From b54c63f113e706e037058a4ba5b03c3bc1413fc2 Mon Sep 17 00:00:00 2001 From: Dominik Stadler Date: Fri, 16 Nov 2018 15:08:59 +0000 Subject: [PATCH 10/28] One more try to avoid the test-failures related to ImageIO-cache dir git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1846719 13f79535-47bb-0310-9956-ffa450edef68 --- .../hssf/usermodel/TestHSSFPictureData.java | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFPictureData.java b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFPictureData.java index df7d7cf213..d82423b86e 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFPictureData.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFPictureData.java @@ -19,7 +19,6 @@ package org.apache.poi.hssf.usermodel; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; -import java.io.File; import java.io.IOException; import java.util.List; @@ -28,6 +27,7 @@ import javax.imageio.ImageIO; import junit.framework.TestCase; import org.apache.poi.hssf.HSSFTestDataSamples; +import org.junit.AfterClass; import org.junit.BeforeClass; /** @@ -37,19 +37,19 @@ import org.junit.BeforeClass; * @author Yegor Kozlov (yegor at apache dot org) * @author Trejkaz (trejkaz at trypticon dot org) */ -public final class TestHSSFPictureData extends TestCase{ +public final class TestHSSFPictureData extends TestCase { + private static boolean cacheBefore = ImageIO.getUseCache(); + @BeforeClass public static void setUpClass() { - // ensure that temp-dir exists because ImageIO requires it - String tmpDirProperty = System.getProperty("java.io.tmpdir"); - if(tmpDirProperty != null) { - final File tmpDir = new File(tmpDirProperty); - if(!tmpDir.exists()) { - if(!tmpDir.mkdirs()) { - throw new IllegalStateException("Could not create temporary directory " + tmpDirProperty + ", full path " + tmpDir.getAbsolutePath()); - } - } - } + // disable cache to avoid strange errors related to temporary directories in CI-builds + ImageIO.setUseCache(false); + } + + @AfterClass + public static void tearDownClass() { + // reset image cache to previous state + ImageIO.setUseCache(cacheBefore); } public void testPictures() throws IOException { From c0e2f60d9eb6fd9a20e41a8d6bb381a7e7dc1ee5 Mon Sep 17 00:00:00 2001 From: Andreas Beeker Date: Fri, 16 Nov 2018 15:39:51 +0000 Subject: [PATCH 11/28] Try to fix ImageIO cache error git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1846723 13f79535-47bb-0310-9956-ffa450edef68 --- sonar/main/pom.xml | 2 +- sonar/ooxml/pom.xml | 2 +- sonar/pom.xml | 2 +- .../hssf/usermodel/TestHSSFPictureData.java | 24 +++++++++---------- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/sonar/main/pom.xml b/sonar/main/pom.xml index d188c14f56..b4ed72f4a1 100644 --- a/sonar/main/pom.xml +++ b/sonar/main/pom.xml @@ -103,7 +103,7 @@ maven-surefire-plugin ${maven.plugin.surefire.version} - @{argLine} -Duser.language=en -Duser.country=US -Xmx1024m -Djava.io.tmpdir=target/tmp -XX:-OmitStackTraceInFastThrow + @{argLine} -Duser.language=en -Duser.country=US -Xmx1024m -Djava.io.tmpdir=${basedir}/target/tmp -XX:-OmitStackTraceInFastThrow diff --git a/sonar/ooxml/pom.xml b/sonar/ooxml/pom.xml index c61f42ecde..fad8ac5642 100644 --- a/sonar/ooxml/pom.xml +++ b/sonar/ooxml/pom.xml @@ -93,7 +93,7 @@ maven-surefire-plugin ${maven.plugin.surefire.version} - @{argLine} -Duser.language=en -Duser.country=US -Xmx1024m -Djava.io.tmpdir=target/tmp -XX:-OmitStackTraceInFastThrow + @{argLine} -Duser.language=en -Duser.country=US -Xmx1024m -Djava.io.tmpdir=${basedir}/target/tmp -XX:-OmitStackTraceInFastThrow diff --git a/sonar/pom.xml b/sonar/pom.xml index 0316403a05..87c2daf37c 100644 --- a/sonar/pom.xml +++ b/sonar/pom.xml @@ -117,7 +117,7 @@ org.apache.poi.util.NullLogger - @{argLine} -Duser.language=en -Duser.country=US -Xmx1024m -Djava.io.tmpdir=target/tmp + @{argLine} -Duser.language=en -Duser.country=US -Xmx1024m -Djava.io.tmpdir=${basedir}/target/tmp **/All*Tests.java diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFPictureData.java b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFPictureData.java index d82423b86e..c65b0252d8 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFPictureData.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFPictureData.java @@ -19,6 +19,7 @@ package org.apache.poi.hssf.usermodel; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; +import java.io.File; import java.io.IOException; import java.util.List; @@ -27,7 +28,6 @@ import javax.imageio.ImageIO; import junit.framework.TestCase; import org.apache.poi.hssf.HSSFTestDataSamples; -import org.junit.AfterClass; import org.junit.BeforeClass; /** @@ -37,19 +37,19 @@ import org.junit.BeforeClass; * @author Yegor Kozlov (yegor at apache dot org) * @author Trejkaz (trejkaz at trypticon dot org) */ -public final class TestHSSFPictureData extends TestCase { - private static boolean cacheBefore = ImageIO.getUseCache(); - +public final class TestHSSFPictureData extends TestCase{ @BeforeClass public static void setUpClass() { - // disable cache to avoid strange errors related to temporary directories in CI-builds - ImageIO.setUseCache(false); - } - - @AfterClass - public static void tearDownClass() { - // reset image cache to previous state - ImageIO.setUseCache(cacheBefore); + final String tmpDirProperty = System.getProperty("java.io.tmpdir"); + if(tmpDirProperty == null || "".equals(tmpDirProperty)) { + return; + } + // ensure that temp-dir exists because ImageIO requires it + final File tmpDir = new File(tmpDirProperty); + if(!tmpDir.exists() && !tmpDir.mkdirs()) { + throw new IllegalStateException("Could not create temporary directory " + tmpDirProperty + ", full path " + tmpDir.getAbsolutePath()); + } + ImageIO.setCacheDirectory(tmpDir); } public void testPictures() throws IOException { From e4144133e5d9cca73c1d76b7daa4a9217d1a67fb Mon Sep 17 00:00:00 2001 From: Andreas Beeker Date: Fri, 16 Nov 2018 18:41:46 +0000 Subject: [PATCH 12/28] exclude H35 because of strange file permission errors git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1846744 13f79535-47bb-0310-9956-ffa450edef68 --- jenkins/create_jobs.groovy | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/jenkins/create_jobs.groovy b/jenkins/create_jobs.groovy index 6e683bfb83..008539de31 100644 --- a/jenkins/create_jobs.groovy +++ b/jenkins/create_jobs.groovy @@ -18,8 +18,9 @@ def poijobs = [ ], [ name: 'POI-DSL-OpenJDK', jdk: 'OpenJDK', trigger: 'H */12 * * *', // H13-H20 (Ubuntu 16.04) do not have OpenJDK 6 installed, see https://issues.apache.org/jira/browse/INFRA-12880 + // H35 fails with ImageIO create cache file errors, although the java.io.tmpdir is writable slaveAdd: '&&!beam1&&!beam2&&!beam3&&!beam4&&!beam5&&!beam6&&!beam7&&!beam8' + - '&&!H0&&!H1&&!H2&&!H3&&!H4&&!H5&&!H6&&!H7&&!H8&&!H9&&!H10&&!H11' + + '&&!H0&&!H1&&!H2&&!H3&&!H4&&!H5&&!H6&&!H7&&!H8&&!H9&&!H10&&!H11&&!H35' + '&&!qnode3' + '&&!ubuntu-1&&!ubuntu-2&&!ubuntu-4&&!ubuntu-5&&!ubuntu-6&&!ubuntu-eu2&&!ubuntu-us1', // the JDK is missing on some slaves so builds are unstable From 27b3bc23ceaaf0cf6debf08e2070447dc3866a05 Mon Sep 17 00:00:00 2001 From: Andreas Beeker Date: Fri, 16 Nov 2018 18:49:26 +0000 Subject: [PATCH 13/28] exclude H35 because of strange file permission errors git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1846746 13f79535-47bb-0310-9956-ffa450edef68 --- jenkins/create_jobs.groovy | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/jenkins/create_jobs.groovy b/jenkins/create_jobs.groovy index 008539de31..baa7021702 100644 --- a/jenkins/create_jobs.groovy +++ b/jenkins/create_jobs.groovy @@ -18,9 +18,8 @@ def poijobs = [ ], [ name: 'POI-DSL-OpenJDK', jdk: 'OpenJDK', trigger: 'H */12 * * *', // H13-H20 (Ubuntu 16.04) do not have OpenJDK 6 installed, see https://issues.apache.org/jira/browse/INFRA-12880 - // H35 fails with ImageIO create cache file errors, although the java.io.tmpdir is writable slaveAdd: '&&!beam1&&!beam2&&!beam3&&!beam4&&!beam5&&!beam6&&!beam7&&!beam8' + - '&&!H0&&!H1&&!H2&&!H3&&!H4&&!H5&&!H6&&!H7&&!H8&&!H9&&!H10&&!H11&&!H35' + + '&&!H0&&!H1&&!H2&&!H3&&!H4&&!H5&&!H6&&!H7&&!H8&&!H9&&!H10&&!H11' + '&&!qnode3' + '&&!ubuntu-1&&!ubuntu-2&&!ubuntu-4&&!ubuntu-5&&!ubuntu-6&&!ubuntu-eu2&&!ubuntu-us1', // the JDK is missing on some slaves so builds are unstable @@ -115,7 +114,8 @@ def defaultTrigger = 'H/15 * * * *' // check SCM every 60/15 = 4 minutes def defaultEmail = 'dev@poi.apache.org' def defaultAnt = 'Ant 1.9.9' // currently a lot of H?? slaves don't have Ant installed ... H21 seems to have a SVN problem -def defaultSlaves = '(ubuntu||beam)&&!cloud-slave&&!H15&&!H17&&!H18&&!H24&&!ubuntu-4&&!H21' +// H35 fails with ImageIO create cache file errors, although the java.io.tmpdir is writable +def defaultSlaves = '(ubuntu||beam)&&!cloud-slave&&!H15&&!H17&&!H18&&!H24&&!ubuntu-4&&!H21&&!H35' def jdkMapping = [ '1.6': 'JDK 1.6 (latest)', From 0bb47ba1e4c0d52bc021c9fabccc4fb3ea6bb478 Mon Sep 17 00:00:00 2001 From: Andreas Beeker Date: Fri, 16 Nov 2018 22:28:23 +0000 Subject: [PATCH 14/28] Multiproject test including Windows slaves git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1846773 13f79535-47bb-0310-9956-ffa450edef68 --- jenkins/create_jobs.groovy | 73 +++++++++++++++++++++++--------------- 1 file changed, 44 insertions(+), 29 deletions(-) diff --git a/jenkins/create_jobs.groovy b/jenkins/create_jobs.groovy index baa7021702..5638a03407 100644 --- a/jenkins/create_jobs.groovy +++ b/jenkins/create_jobs.groovy @@ -530,20 +530,18 @@ on that machine correctly. */ matrixJob('POI-DSL-Test-Environment') { description( - ''' -Check installed version of Java/Ant on all build-nodes +'''Check installed version of Java/Ant on all build-nodes This job is used to verify which machines actually have the required programs installed. -Unfortunately we often see builds break because of changes/new machines...''' - ) +Unfortunately we often see builds break because of changes/new machines...''') /*throttleConcurrentBuilds { maxPerNode(1) maxTotal(1) }*/ logRotator { - numToKeep(5) + numToKeep(1) artifactNumToKeep(1) } axes { @@ -560,37 +558,54 @@ Unfortunately we often see builds break because of changes/new machines...''' 'JDK 11 b23 (early access build) (Windows Only)', 'JDK 12 (latest)', - 'JDK 12 b8 (early access build) (Windows Only)' - ) - label('Nodes', - 'arm1', - 'beam1','beam2','beam3','beam4','beam5','beam6','beam7','beam8','beam9', - 'beam10','beam11','beam12','beam13','beam14','beam15','beam16', - 'H0','H1','H10','H11','H12','H13','H14','H15','H16','H17','H18','H19', - 'H2','H20','H21','H22','H23','H24','H25','H26','H27','H28','H29', - 'H3','H30','H31','H32','H33','H34','H35', - 'H4','H5','H6','H7','H8','H9', - 'ubuntu-1','ubuntu-2','ubuntu-4','ubuntu-6','ubuntu-eu2','ubuntu-eu3','ubuntu-ppc64le','ubuntu-us1', - 'windows-2012-1','windows-2012-2','windows-2012-3','windows-2016-1','windows-2016-2','windows-2016-3' + 'OpenJDK 12 b18 (early access build)' ) + elasticAxis { + name('Nodes') + labelString('!cloud-slave&&!H15&&!H17&&!H18&&!H24&&!ubuntu-4&&!H21&&!H35&&!websites1&&!couchdb&&!plc4x&&!ppc64le') + ignoreOffline(true) + } } steps { - /*if (poijob.windows) { - context.batchFile(cmd) - } else {*/ - shell(''' -which javac + conditionalSteps { + condition { + fileExists('/usr', BaseDir.WORKSPACE) + runner('DontRun') + steps { + shell( +'''which javac javac -version echo 'Using Ant: ${ant.version} from ${ant.home}' > build.xml ''') - //} - ant { - antInstallation(defaultAnt) - } - } + ant { + antInstallation(defaultAnt) + } - publishers { - mailer('centic@poi.apache.org' /* defaultEmail */, false, false) + } + } + } + conditionalSteps { + condition { + fileExists('c:\\windows', BaseDir.WORKSPACE) + runner('DontRun') + steps { + batchFile { + command( +'''@echo off +echo . +where javac.exe +echo . +javac -version +echo . +echo ^^^^Using Ant: ${ant.version} from ${ant.home}^^^ > build.xml +''') + } + ant { + antInstallation(defaultAnt + ' (Windows)') + } + } + } + } } } From 42af181065e99775ed94698e8fa8d8ffea2ddade Mon Sep 17 00:00:00 2001 From: Andreas Beeker Date: Sun, 18 Nov 2018 00:01:40 +0000 Subject: [PATCH 15/28] #62921 - Provide OOXMLLite alternative for Java 12+ git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1846809 13f79535-47bb-0310-9956-ffa450edef68 --- build.xml | 147 ++++--- .../org/apache/poi/ooxml/util/OOXMLLite.java | 375 ------------------ .../apache/poi/ooxml/util/OOXMLLiteAgent.java | 78 ++++ .../poi/ss/format/TestCellFormatPart.java | 2 +- .../org/apache/poi/hmef/TestAttachments.java | 5 +- .../hmef/attribute/TestMAPIAttributes.java | 5 +- .../hmef/attribute/TestTNEFAttributes.java | 5 +- .../TestExcelStyleDateFormatter.java | 159 ++++---- 8 files changed, 223 insertions(+), 553 deletions(-) delete mode 100644 src/ooxml/testcases/org/apache/poi/ooxml/util/OOXMLLite.java create mode 100644 src/ooxml/testcases/org/apache/poi/ooxml/util/OOXMLLiteAgent.java diff --git a/build.xml b/build.xml index d15b45b74b..89f0423e78 100644 --- a/build.xml +++ b/build.xml @@ -130,8 +130,12 @@ under the License. - - + + + + + + @@ -397,7 +401,8 @@ under the License. - + + @@ -1015,8 +1020,6 @@ under the License. compile-scratchpad, compile-examples, compile-excelant" description="Compiles the POI main classes, scratchpad and examples"/> - - - @@ -1385,9 +1388,7 @@ under the License. - + @@ -1564,6 +1565,7 @@ under the License. + @@ -1598,6 +1600,7 @@ under the License. + @@ -1620,7 +1623,7 @@ under the License. - @@ -1638,7 +1641,7 @@ under the License. - @@ -1650,6 +1653,7 @@ under the License. + @@ -1677,57 +1681,28 @@ under the License. - - - - - - - - - + + + + - - - + + - - + + + + + - - - + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1736,6 +1711,15 @@ under the License. + + + + + + + + + @@ -1953,11 +1937,11 @@ under the License. - + - + @@ -1971,33 +1955,39 @@ under the License. + + + + + - + + - - - - - - - + + + + + + + - - - - - - + + + + + + - + @@ -2112,6 +2102,7 @@ under the License. lib/**, bin/**, out/**, + tmp/**, sonar/**/target/**, sonar/*/src/**, compile-lib/**, @@ -2167,14 +2158,12 @@ under the License. - - - diff --git a/src/ooxml/testcases/org/apache/poi/ooxml/util/OOXMLLite.java b/src/ooxml/testcases/org/apache/poi/ooxml/util/OOXMLLite.java deleted file mode 100644 index 450f958ae6..0000000000 --- a/src/ooxml/testcases/org/apache/poi/ooxml/util/OOXMLLite.java +++ /dev/null @@ -1,375 +0,0 @@ -/* ==================================================================== - 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.ooxml.util; - -import java.io.File; -import java.io.IOException; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.net.URL; -import java.security.AccessController; -import java.security.CodeSource; -import java.security.PrivilegedAction; -import java.security.ProtectionDomain; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.Vector; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; -import java.util.regex.Pattern; - -import org.apache.poi.util.IOUtils; -import org.apache.poi.util.StringUtil; -import org.apache.poi.util.SuppressForbidden; -import org.apache.xmlbeans.StringEnumAbstractBase; -import org.junit.Test; -import org.junit.internal.TextListener; -import org.junit.runner.Description; -import org.junit.runner.JUnitCore; -import org.junit.runner.Result; -import org.reflections.Reflections; - -import junit.framework.TestCase; - -/** - * Build a 'lite' version of the ooxml-schemas.jar - * - * @author Yegor Kozlov - */ -public final class OOXMLLite { - private static final Pattern SCHEMA_PATTERN = Pattern.compile("schemaorg_apache_xmlbeans/(system|element)/.*\\.xsb"); - - /** - * Destination directory to copy filtered classes - */ - private File _destDest; - - /** - * Directory with the compiled ooxml tests - */ - private File _testDir; - - /** - * Reference to the ooxml-schemas.jar - */ - private File _ooxmlJar; - - - OOXMLLite(String dest, String test, String ooxmlJar) { - _destDest = new File(dest); - _testDir = new File(test); - _ooxmlJar = new File(ooxmlJar); - } - - public static void main(String[] args) throws IOException { - System.out.println("Free memory (bytes): " + - Runtime.getRuntime().freeMemory()); - long maxMemory = Runtime.getRuntime().maxMemory(); - System.out.println("Maximum memory (bytes): " + - (maxMemory == Long.MAX_VALUE ? "no limit" : maxMemory)); - System.out.println("Total memory (bytes): " + - Runtime.getRuntime().totalMemory()); - - String dest = null, test = null, ooxml = null; - - for (int i = 0; i < args.length; i++) { - switch (args[i]) { - case "-dest": - dest = args[++i]; // lgtm[java/index-out-of-bounds] - break; - case "-test": - test = args[++i]; // lgtm[java/index-out-of-bounds] - break; - case "-ooxml": - ooxml = args[++i]; // lgtm[java/index-out-of-bounds] - break; - } - } - OOXMLLite builder = new OOXMLLite(dest, test, ooxml); - builder.build(); - } - - void build() throws IOException { - List> lst = new ArrayList<>(); - //collect unit tests - String exclude = StringUtil.join("|", - "BaseTestXWorkbook", - "BaseTestXSheet", - "BaseTestXRow", - "BaseTestXCell", - "BaseTestXSSFPivotTable", - "TestSXSSFWorkbook\\$\\d", - "TestUnfixedBugs", - "MemoryUsage", - "TestDataProvider", - "TestDataSamples", - "All.+Tests", - "ZipFileAssert", - "AesZipFileZipEntrySource", - "TempFileRecordingSXSSFWorkbookWithCustomZipEntrySource", - "PkiTestUtils", - "TestCellFormatPart\\$\\d", - "TestSignatureInfo\\$\\d", - "TestCertificateEncryption\\$CertData", - "TestPOIXMLDocument\\$OPCParser", - "TestPOIXMLDocument\\$TestFactory", - "TestXSLFTextParagraph\\$DrawTextParagraphProxy", - "TestXSSFExportToXML\\$\\d", - "TestXSSFExportToXML\\$DummyEntityResolver", - "TestFormulaEvaluatorOnXSSF\\$Result", - "TestFormulaEvaluatorOnXSSF\\$SS", - "TestMultiSheetFormulaEvaluatorOnXSSF\\$Result", - "TestMultiSheetFormulaEvaluatorOnXSSF\\$SS", - "TestXSSFBugs\\$\\d", - "AddImageBench", - "AddImageBench_jmhType_B\\d", - "AddImageBench_benchCreatePicture_jmhTest", - "TestEvilUnclosedBRFixingInputStream\\$EvilUnclosedBRFixingInputStream", - "TempFileRecordingSXSSFWorkbookWithCustomZipEntrySource\\$TempFileRecordingSheetDataWriterWithDecorator", - "TestXSSFBReader\\$1", - "TestXSSFBReader\\$TestSheetHandler", - "TestFormulaEvaluatorOnXSSF\\$1", - "TestMultiSheetFormulaEvaluatorOnXSSF\\$1", - "TestZipPackagePropertiesMarshaller\\$1", - "SLCommonUtils", - "TestPPTX2PNG\\$1", - "TestMatrixFormulasFromXMLSpreadsheet\\$1", - "TestMatrixFormulasFromXMLSpreadsheet\\$Navigator", - "TestPOIXMLDocument\\$UncaughtHandler", - "TestOleShape\\$Api", - "TestOleShape\\$1", - "TestPOIXMLDocument\\$1", - "TestXMLSlideShow\\$1", - "TestXMLSlideShow\\$BufAccessBAOS", - "TestXDDFChart\\$1", - "TestOOXMLLister\\$1", - "TestOOXMLPrettyPrint\\$1" - ); - System.out.println("Collecting unit tests from " + _testDir); - collectTests(_testDir, _testDir, lst, ".+.class$", ".+(" + exclude + ").class"); - System.out.println("Found " + lst.size() + " classes"); - - //run tests - JUnitCore jUnitCore = new JUnitCore(); - jUnitCore.addListener(new TextListener(System.out) { - private final Set classes = new HashSet<>(); - private int count; - - @Override - public void testStarted(Description description) { - // count how many test-classes we already saw - classes.add(description.getClassName()); - count++; - if(count % 100 == 0) { - System.out.println(); - System.out.println(classes.size() + "/" + lst.size() + ": " + description.getDisplayName()); - } - - super.testStarted(description); - } - }); - Result result = jUnitCore.run(lst.toArray(new Class[0])); - if (!result.wasSuccessful()) { - throw new RuntimeException("Tests did not succeed, cannot build ooxml-lite jar"); - } - - //see what classes from the ooxml-schemas.jar are loaded - System.out.println("Copying classes to " + _destDest); - Set> classes = getLoadedClasses(_ooxmlJar.getName()); - Set packages = new HashSet<>(); - for (Class cls : classes) { - copyFile(cls); - packages.add(cls.getPackage().getName()); - - if (cls.isInterface()) { - /// Copy classes and interfaces declared as members of this class - for (Class fc : cls.getDeclaredClasses()) { - copyFile(fc); - } - } - } - for (String pkg : packages) { - Reflections reflections = new Reflections(pkg); - Set> listClasses = reflections.getSubTypesOf(List.class); - listClasses.removeAll(classes); - for (Class listClass : listClasses) { - for (Class compare : classes) { - if (listClass.getName().startsWith(compare.getName())) { - copyFile(listClass); - } - } - } - Set> enumClasses = reflections.getSubTypesOf(StringEnumAbstractBase.class); - listClasses.removeAll(classes); - for (Class enumClass : enumClasses) { - for (Class compare : classes) { - if (enumClass.getName().startsWith(compare.getName())) { - copyFile(enumClass); - } - } - } - } - - //finally copy the compiled .xsb files - System.out.println("Copying .xsb resources"); - try (JarFile jar = new JarFile(_ooxmlJar)) { - for (Enumeration e = jar.entries(); e.hasMoreElements(); ) { - JarEntry je = e.nextElement(); - if (SCHEMA_PATTERN.matcher(je.getName()).matches()) { - File destFile = new File(_destDest, je.getName()); - IOUtils.copy(jar.getInputStream(je), destFile); - } - } - } - } - - private void copyFile(Class cls) throws IOException { - String className = cls.getName(); - String classRef = className.replace('.', '/') + ".class"; - File destFile = new File(_destDest, classRef); - IOUtils.copy(cls.getResourceAsStream('/' + classRef), destFile); - } - - private static boolean checkForTestAnnotation(Class testclass) { - for (Method m : testclass.getDeclaredMethods()) { - if(m.isAnnotationPresent(Test.class)) { - return true; - } - } - - // also check super classes - if(testclass.getSuperclass() != null) { - for (Method m : testclass.getSuperclass().getDeclaredMethods()) { - if(m.isAnnotationPresent(Test.class)) { - return true; - } - } - } - - System.out.println("Class " + testclass.getName() + " does not derive from TestCase and does not have a @Test annotation"); - - // Should we also look at superclasses to find cases - // where we have abstract base classes with derived tests? - // if(checkForTestAnnotation(testclass.getSuperclass())) return true; - - return false; - } - - /** - * Recursively collect classes from the supplied directory - * - * @param arg the directory to search in - * @param out output - * @param ptrn the pattern (regexp) to filter found files - */ - private static void collectTests(File root, File arg, List> out, String ptrn, String exclude) { - if (arg.isDirectory()) { - File files[] = arg.listFiles(); - if (files != null) { - for (File f : files) { - collectTests(root, f, out, ptrn, exclude); - } - } - } else { - String path = arg.getAbsolutePath(); - String prefix = root.getAbsolutePath(); - String cls = path.substring(prefix.length() + 1).replace(File.separator, "."); - if(!cls.matches(ptrn)) { - return; - } - if (cls.matches(exclude)) { - return; - } - //ignore inner classes defined in tests - if (cls.indexOf('$') != -1) { - System.out.println("Inner class " + cls + " not included"); - return; - } - - cls = cls.replace(".class", ""); - - try { - Class testclass = Class.forName(cls); - if (TestCase.class.isAssignableFrom(testclass) - || checkForTestAnnotation(testclass)) { - out.add(testclass); - } - } catch (Throwable e) { // NOSONAR - System.out.println("Class " + cls + " is not in classpath"); - } - } - } - - /** - * - * @param ptrn the pattern to filter output - * @return the classes loaded by the system class loader - */ - @SuppressWarnings("unchecked") - private static Set> getLoadedClasses(String ptrn) { - // make the field accessible, we defer this from static initialization to here to - // allow JDKs which do not have this field (e.g. IBM JDK) to at least load the class - // without failing, see https://issues.apache.org/bugzilla/show_bug.cgi?id=56550 - final Field _classes = AccessController.doPrivileged(new PrivilegedAction() { - @Override - @SuppressForbidden("TODO: Reflection works until Java 8 on Oracle/Sun JDKs, but breaks afterwards (different classloader types, access checks)") - public Field run() { - try { - Field fld = ClassLoader.class.getDeclaredField("classes"); - fld.setAccessible(true); - return fld; - } catch (Exception e) { - throw new RuntimeException(e); - } - - } - }); - - ClassLoader appLoader = ClassLoader.getSystemClassLoader(); - try { - Vector> classes = (Vector>) _classes.get(appLoader); - Set> set = new HashSet<>(); - for (Class cls : classes) { - // e.g. proxy-classes, ... - ProtectionDomain pd = cls.getProtectionDomain(); - if (pd == null) { - continue; - } - CodeSource cs = pd.getCodeSource(); - if (cs == null) { - continue; - } - URL loc = cs.getLocation(); - if (loc == null) { - continue; - } - - String jar = loc.toString(); - if (jar.contains(ptrn)) { - set.add(cls); - } - } - return set; - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } - } -} diff --git a/src/ooxml/testcases/org/apache/poi/ooxml/util/OOXMLLiteAgent.java b/src/ooxml/testcases/org/apache/poi/ooxml/util/OOXMLLiteAgent.java new file mode 100644 index 0000000000..48c9240e98 --- /dev/null +++ b/src/ooxml/testcases/org/apache/poi/ooxml/util/OOXMLLiteAgent.java @@ -0,0 +1,78 @@ +/* ==================================================================== + 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.ooxml.util; + +import java.io.IOException; +import java.lang.instrument.ClassFileTransformer; +import java.lang.instrument.Instrumentation; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; +import java.security.ProtectionDomain; +import java.util.HashSet; +import java.util.Set; +import java.util.regex.Pattern; +import java.util.stream.Stream; + +/** + * OOXMLLiteAgent is the replacement for the former OOXMLLite, because in Java 12 + * it isn't possible to access the privates :) of the ClassLoader + */ +public class OOXMLLiteAgent { + + static class LoggingTransformer implements ClassFileTransformer { + final Path path; + final Pattern includes; + final Set fileHashes = new HashSet<>(); + + public LoggingTransformer(String agentArgs) { + String args[] = (agentArgs == null ? "" : agentArgs).split("\\|",2); + path = Paths.get(args.length >= 1 ? args[0] : "ooxml-lite.out"); + includes = Pattern.compile(args.length >= 2 ? args[1] : ".*/schemas/.*"); + + try { + if (Files.exists(path)) { + try (Stream stream = Files.lines(path)) { + stream.forEach((s) -> fileHashes.add(s.hashCode())); + } + } else { + Files.createFile(path); + } + } catch (IOException ignored) { + } + } + + public byte[] transform(ClassLoader loader, String className, Class redefiningClass, ProtectionDomain domain, byte[] bytes) { + if (path != null && className != null && !fileHashes.contains(className.hashCode()) && includes.matcher(className).find()) { + try { + // TODO: check if this is atomic ... as transform() is probably called synchronized, it doesn't matter anyway + Files.write(path, (className+"\n").getBytes(StandardCharsets.ISO_8859_1), StandardOpenOption.APPEND); + fileHashes.add(className.hashCode()); + } catch (IOException ignroed) { + } + } + return bytes; + } + } + + public static void premain(String agentArgs, Instrumentation inst) { + inst.addTransformer(new LoggingTransformer(agentArgs)); + } +} diff --git a/src/ooxml/testcases/org/apache/poi/ss/format/TestCellFormatPart.java b/src/ooxml/testcases/org/apache/poi/ss/format/TestCellFormatPart.java index 583fa8b851..fd1c8d8a10 100644 --- a/src/ooxml/testcases/org/apache/poi/ss/format/TestCellFormatPart.java +++ b/src/ooxml/testcases/org/apache/poi/ss/format/TestCellFormatPart.java @@ -41,7 +41,7 @@ public class TestCellFormatPart extends CellFormatTestBase { @BeforeClass public static void setLocale() { userLocale = LocaleUtil.getUserLocale(); - LocaleUtil.setUserLocale(Locale.ROOT); + LocaleUtil.setUserLocale(Locale.UK); } @AfterClass diff --git a/src/scratchpad/testcases/org/apache/poi/hmef/TestAttachments.java b/src/scratchpad/testcases/org/apache/poi/hmef/TestAttachments.java index 18f59725bb..87655cb3ae 100644 --- a/src/scratchpad/testcases/org/apache/poi/hmef/TestAttachments.java +++ b/src/scratchpad/testcases/org/apache/poi/hmef/TestAttachments.java @@ -18,6 +18,7 @@ package org.apache.poi.hmef; import java.text.DateFormat; +import java.text.SimpleDateFormat; import java.util.List; import java.util.Locale; @@ -83,9 +84,7 @@ public final class TestAttachments extends HMEFTest { List attachments = quick.getAttachments(); // Pick a predictable date format + timezone - DateFormat fmt = DateFormat.getDateTimeInstance( - DateFormat.MEDIUM, DateFormat.MEDIUM, Locale.UK - ); + DateFormat fmt = new SimpleDateFormat("dd-MMM-yyyy hh:mm:ss", Locale.UK); fmt.setTimeZone(LocaleUtil.TIMEZONE_UTC); // They should all have the same date on them diff --git a/src/scratchpad/testcases/org/apache/poi/hmef/attribute/TestMAPIAttributes.java b/src/scratchpad/testcases/org/apache/poi/hmef/attribute/TestMAPIAttributes.java index f854394816..7fcad02042 100644 --- a/src/scratchpad/testcases/org/apache/poi/hmef/attribute/TestMAPIAttributes.java +++ b/src/scratchpad/testcases/org/apache/poi/hmef/attribute/TestMAPIAttributes.java @@ -20,6 +20,7 @@ package org.apache.poi.hmef.attribute; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.text.DateFormat; +import java.text.SimpleDateFormat; import java.util.Locale; import org.apache.poi.POIDataSamples; @@ -159,9 +160,7 @@ protected void tearDown() throws Exception { assertEquals(MAPIDateAttribute.class, attr.getClass()); MAPIDateAttribute date = (MAPIDateAttribute)attr; - DateFormat fmt = DateFormat.getDateTimeInstance( - DateFormat.MEDIUM, DateFormat.MEDIUM, Locale.UK - ); + DateFormat fmt = new SimpleDateFormat("dd-MMM-yyyy HH:mm:ss", Locale.UK); fmt.setTimeZone(LocaleUtil.TIMEZONE_UTC); assertEquals("15-Dec-2010 14:46:31", fmt.format(date.getDate())); diff --git a/src/scratchpad/testcases/org/apache/poi/hmef/attribute/TestTNEFAttributes.java b/src/scratchpad/testcases/org/apache/poi/hmef/attribute/TestTNEFAttributes.java index cd13b94b39..04004fae23 100644 --- a/src/scratchpad/testcases/org/apache/poi/hmef/attribute/TestTNEFAttributes.java +++ b/src/scratchpad/testcases/org/apache/poi/hmef/attribute/TestTNEFAttributes.java @@ -19,6 +19,7 @@ package org.apache.poi.hmef.attribute; import java.io.ByteArrayInputStream; import java.text.DateFormat; +import java.text.SimpleDateFormat; import java.util.Locale; import org.apache.poi.POIDataSamples; @@ -159,9 +160,7 @@ public final class TestTNEFAttributes extends TestCase { // Ask for it as a Java date, and have it converted // Pick a predictable format + location + timezone TNEFDateAttribute date = (TNEFDateAttribute)attr; - DateFormat fmt = DateFormat.getDateTimeInstance( - DateFormat.MEDIUM, DateFormat.MEDIUM, Locale.UK - ); + DateFormat fmt = new SimpleDateFormat("dd-MMM-yyyy HH:mm:ss", Locale.UK); fmt.setTimeZone(LocaleUtil.TIMEZONE_UTC); assertEquals("28-Apr-2010 12:40:56", fmt.format(date.getDate())); } diff --git a/src/testcases/org/apache/poi/ss/usermodel/TestExcelStyleDateFormatter.java b/src/testcases/org/apache/poi/ss/usermodel/TestExcelStyleDateFormatter.java index f4e61801a5..9d64f3a8a0 100644 --- a/src/testcases/org/apache/poi/ss/usermodel/TestExcelStyleDateFormatter.java +++ b/src/testcases/org/apache/poi/ss/usermodel/TestExcelStyleDateFormatter.java @@ -23,119 +23,100 @@ import java.text.DateFormatSymbols; import java.text.FieldPosition; import java.text.ParseException; import java.text.SimpleDateFormat; -import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; import org.apache.poi.util.LocaleUtil; import org.junit.Test; public class TestExcelStyleDateFormatter { private static final String EXCEL_DATE_FORMAT = "MMMMM"; + private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd", Locale.ROOT); + private final int jreVersion; + + public TestExcelStyleDateFormatter() { + jreVersion = Integer.parseInt(System.getProperty("java.version") + .replace("1.8", "8").replaceAll("(\\d+).*", "$1")); + } /** * [Bug 60369] Month format 'MMMMM' issue with TEXT-formula and Java 8 */ @Test - public void test60369() throws ParseException { - Map> testMap = initializeLocales(); + public void test60369() { + Map testMap = initializeLocales(); // We have to set up dates as well. - SimpleDateFormat testDateFormat = new SimpleDateFormat("dd.MM.yyyy", Locale.ROOT); - List testDates = Arrays.asList( - testDateFormat.parse("12.01.1980"), - testDateFormat.parse("11.02.1995"), - testDateFormat.parse("10.03.2045"), - testDateFormat.parse("09.04.2016"), - testDateFormat.parse("08.05.2017"), - testDateFormat.parse("07.06.1945"), - testDateFormat.parse("06.07.1998"), - testDateFormat.parse("05.08.2099"), - testDateFormat.parse("04.09.1988"), - testDateFormat.parse("03.10.2023"), - testDateFormat.parse("02.11.1978"), - testDateFormat.parse("01.12.1890")); + List testDates = Stream.of("1980-01-12", "1995-02-11", "2045-03-10", "2016-04-09", "2017-05-08", + "1945-06-07", "1998-07-06", "2099-08-05", "1988-09-04", "2023-10-03", "1978-11-02", "1890-12-01") + .map(this::parseDate).collect(Collectors.toList()); // Let's iterate over the test setup. - for (Locale locale : testMap.keySet()) { - ExcelStyleDateFormatter formatter = new ExcelStyleDateFormatter(EXCEL_DATE_FORMAT, new DateFormatSymbols(locale)); - for (int i = 0; i < testDates.size(); i++) { - // Call the method to be tested! - String result = - formatter.format(testDates.get(i), - new StringBuffer(), - new FieldPosition(java.text.DateFormat.MONTH_FIELD)).toString(); - //System.err.println(result + " - " + getUnicode(result.charAt(0))); - assertEquals("Failed for locale " + locale + ", provider: " + System.getProperty("java.locale.providers") + - " and date " + testDates.get(i) + ", having: " + result, - getUnicode(testMap.get(locale).get(i).charAt(0)), getUnicode(result.charAt(0))); + final String provider = System.getProperty("java.locale.providers"); + final FieldPosition fp = new FieldPosition(java.text.DateFormat.MONTH_FIELD); + final ExcelStyleDateFormatter formatter = new ExcelStyleDateFormatter(EXCEL_DATE_FORMAT); + final StringBuffer sb = new StringBuffer(); + + for (Map.Entry me : testMap.entrySet()) { + final Locale locale = me.getKey(); + final String expected = me.getValue(); + formatter.setDateFormatSymbols(DateFormatSymbols.getInstance(locale)); + int month = 0; + for (Date d : testDates) { + sb.setLength(0); + String result = formatter.format(d, sb, fp).toString(); + String msg = "Failed testDates for locale " + locale + ", provider: " + provider + + " and date " + d + ", having: " + result; + + int actIdx = (Locale.CHINESE.equals(locale) && jreVersion >= 12) ? 1 : 0; + + assertEquals(msg, expected.charAt(month), result.charAt(actIdx)); + month++; } } } - private Map> initializeLocales() { - // Setting up the locale to be tested together with a list of asserted unicode-formatted results and put them in a map. - Locale germanLocale = Locale.GERMAN; - List germanResultList = Arrays.asList("\u004a", "\u0046", "\u004d", "\u0041", "\u004d", - "\u004a", "\u004a", "\u0041", "\u0053", "\u004f", "\u004e", "\u0044"); - - Locale russianLocale = new Locale("ru", "RU"); - List russianResultList = Arrays.asList("\u044f", "\u0444", "\u043c", "\u0430", "\u043c", - "\u0438", "\u0438", "\u0430", "\u0441", "\u043e", "\u043d", "\u0434"); - - Locale austrianLocale = new Locale("de", "AT"); - List austrianResultList = Arrays.asList("\u004a", "\u0046", "\u004d", "\u0041", "\u004d", - "\u004a", "\u004a", "\u0041", "\u0053", "\u004f", "\u004e", "\u0044"); - - Locale englishLocale = Locale.UK; - List englishResultList = Arrays.asList("\u004a", "\u0046", "\u004d", "\u0041", "\u004d", - "\u004a", "\u004a", "\u0041", "\u0053", "\u004f", "\u004e", "\u0044"); - - Locale frenchLocale = Locale.FRENCH; - List frenchResultList = Arrays.asList("\u006a", "\u0066", "\u006d", "\u0061", "\u006d", - "\u006a", "\u006a", "\u0061", "\u0073", "\u006f", "\u006e", "\u0064"); - - Locale chineseLocale = Locale.CHINESE; - List chineseResultList = Arrays.asList("\u4e00", "\u4e8c", "\u4e09", "\u56db", "\u4e94", - "\u516d", "\u4e03", "\u516b", "\u4e5d", "\u5341", "\u5341", "\u5341"); - - Locale turkishLocale = new Locale("tr", "TR"); - List turkishResultList = Arrays.asList("\u004f", "\u015e", "\u004d", "\u004e", "\u004d", - "\u0048", "\u0054", "\u0041", "\u0045", "\u0045", "\u004b", "\u0041"); - - Locale hungarianLocale = new Locale("hu", "HU"); - List hungarianResultList = Arrays.asList("\u006a", "\u0066", "\u006d", "\u00e1", "\u006d", - "\u006a", "\u006a", "\u0061", "\u0073", "\u006f", "\u006e", "\u0064"); - - Locale indianLocale = new Locale("en", "IN"); - List indianResultList = Arrays.asList("\u004a", "\u0046", "\u004d", "\u0041", "\u004d", - "\u004a", "\u004a", "\u0041", "\u0053", "\u004f", "\u004e", "\u0044"); - - Locale indonesianLocale = new Locale("in", "ID"); - List indonesianResultList = Arrays.asList("\u004a", "\u0046", "\u004d", "\u0041", "\u004d", - "\u004a", "\u004a", "\u0041", "\u0053", "\u004f", "\u004e", "\u0044"); - - - Map> testMap = new HashMap<>(); - testMap.put(germanLocale, germanResultList); - testMap.put(russianLocale, russianResultList); - testMap.put(austrianLocale, austrianResultList); - testMap.put(englishLocale, englishResultList); - testMap.put(frenchLocale, frenchResultList); - testMap.put(chineseLocale, chineseResultList); - testMap.put(turkishLocale, turkishResultList); - testMap.put(hungarianLocale, hungarianResultList); - testMap.put(indianLocale, indianResultList); - testMap.put(indonesianLocale, indonesianResultList); - - return testMap; + private Date parseDate(String dateStr) { + try { + return DATE_FORMAT.parse(dateStr); + } catch (ParseException e) { + return new Date(0); + } } - private String getUnicode(char c) { - return "\\u" + Integer.toHexString(c | 0x10000).substring(1); + /** + * Setting up the locale to be tested together with a list of asserted + * unicode-formatted results and put them in a map. + */ + private Map initializeLocales() { + Map testMap = new HashMap<>(); + + testMap.put(Locale.GERMAN, "JFMAMJJASOND"); + testMap.put(new Locale("de", "AT"), "JFMAMJJASOND"); + testMap.put(Locale.UK, "JFMAMJJASOND"); + testMap.put(new Locale("en", "IN"), "JFMAMJJASOND"); + testMap.put(new Locale("in", "ID"), "JFMAMJJASOND"); + testMap.put(Locale.FRENCH, "jfmamjjasond"); + + testMap.put(new Locale("ru", "RU"), + "\u044f\u0444\u043c\u0430\u043c\u0438\u0438\u0430\u0441\u043e\u043d\u0434"); + + testMap.put(Locale.CHINESE, jreVersion < 12 + ? "\u4e00\u4e8c\u4e09\u56db\u4e94\u516d\u4e03\u516b\u4e5d\u5341\u5341\u5341" + : "123456789111"); + + testMap.put(new Locale("tr", "TR"), + "\u004f\u015e\u004d\u004e\u004d\u0048\u0054\u0041\u0045\u0045\u004b\u0041"); + + testMap.put(new Locale("hu", "HU"), + "\u006a\u0066\u006d\u00e1\u006d\u006a\u006a\u0061\u0073\u006f\u006e\u0064"); + + return testMap; } @Test @@ -150,7 +131,7 @@ public class TestExcelStyleDateFormatter { try { LocaleUtil.setUserLocale(Locale.GERMAN); String dateStr = new ExcelStyleDateFormatter(EXCEL_DATE_FORMAT).format( - new SimpleDateFormat("yyyy-MM-dd", Locale.ROOT).parse("2016-03-26")); + DATE_FORMAT.parse("2016-03-26")); assertEquals("M", dateStr); } finally { LocaleUtil.setUserLocale(before); @@ -160,7 +141,7 @@ public class TestExcelStyleDateFormatter { @Test public void testWithPattern() throws ParseException { String dateStr = new ExcelStyleDateFormatter("yyyy|" + EXCEL_DATE_FORMAT + "|").format( - new SimpleDateFormat("yyyy-MM-dd", Locale.ROOT).parse("2016-03-26")); + DATE_FORMAT.parse("2016-03-26")); assertEquals("2016|M|", dateStr); } } From c7cf08b50a2caebfa9f8cb60494e01e228bf5088 Mon Sep 17 00:00:00 2001 From: Andreas Beeker Date: Sun, 18 Nov 2018 00:23:49 +0000 Subject: [PATCH 16/28] #62921 - Provide OOXMLLite alternative for Java 12+ git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1846810 13f79535-47bb-0310-9956-ffa450edef68 --- jenkins/create_jobs.groovy | 2 +- .../apache/poi/ss/usermodel/TestExcelStyleDateFormatter.java | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/jenkins/create_jobs.groovy b/jenkins/create_jobs.groovy index 5638a03407..60795db960 100644 --- a/jenkins/create_jobs.groovy +++ b/jenkins/create_jobs.groovy @@ -377,7 +377,7 @@ poijobs.each { poijob -> } } else if (poijob.noScratchpad) { ant { - targets(['clean', 'compile-all'] + (poijob.properties ?: [])) + targets(['clean', 'compile'] + (poijob.properties ?: [])) prop('coverage.enabled', true) antInstallation(antRT) } diff --git a/src/testcases/org/apache/poi/ss/usermodel/TestExcelStyleDateFormatter.java b/src/testcases/org/apache/poi/ss/usermodel/TestExcelStyleDateFormatter.java index 9d64f3a8a0..f055d4174b 100644 --- a/src/testcases/org/apache/poi/ss/usermodel/TestExcelStyleDateFormatter.java +++ b/src/testcases/org/apache/poi/ss/usermodel/TestExcelStyleDateFormatter.java @@ -18,6 +18,8 @@ package org.apache.poi.ss.usermodel; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; import java.text.DateFormatSymbols; import java.text.FieldPosition; @@ -75,6 +77,8 @@ public class TestExcelStyleDateFormatter { int actIdx = (Locale.CHINESE.equals(locale) && jreVersion >= 12) ? 1 : 0; + assertNotNull(msg, result); + assertTrue(msg, result.length() > actIdx); assertEquals(msg, expected.charAt(month), result.charAt(actIdx)); month++; } From 7239d7c5257dc7d8256f63234806615bdade0b78 Mon Sep 17 00:00:00 2001 From: Andreas Beeker Date: Sun, 18 Nov 2018 00:49:54 +0000 Subject: [PATCH 17/28] #62921 - Provide OOXMLLite alternative for Java 12+ git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1846811 13f79535-47bb-0310-9956-ffa450edef68 --- .../TestExcelStyleDateFormatter.java | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/testcases/org/apache/poi/ss/usermodel/TestExcelStyleDateFormatter.java b/src/testcases/org/apache/poi/ss/usermodel/TestExcelStyleDateFormatter.java index f055d4174b..b7fd43e367 100644 --- a/src/testcases/org/apache/poi/ss/usermodel/TestExcelStyleDateFormatter.java +++ b/src/testcases/org/apache/poi/ss/usermodel/TestExcelStyleDateFormatter.java @@ -75,7 +75,7 @@ public class TestExcelStyleDateFormatter { String msg = "Failed testDates for locale " + locale + ", provider: " + provider + " and date " + d + ", having: " + result; - int actIdx = (Locale.CHINESE.equals(locale) && jreVersion >= 12) ? 1 : 0; + int actIdx = localeIndex(locale); assertNotNull(msg, result); assertTrue(msg, result.length() > actIdx); @@ -85,6 +85,18 @@ public class TestExcelStyleDateFormatter { } } + /** + * Depending on the JRE version, the provider setting and the locale, a different result + * is expected and selected via an index + */ + private int localeIndex(Locale locale) { + final String provider = System.getProperty("java.locale.providers"); + return jreVersion < 12 || + !locale.equals (Locale.CHINESE) || + (provider != null && provider.startsWith("JRE")) + ? 0 : 1; + } + private Date parseDate(String dateStr) { try { return DATE_FORMAT.parse(dateStr); @@ -110,9 +122,10 @@ public class TestExcelStyleDateFormatter { testMap.put(new Locale("ru", "RU"), "\u044f\u0444\u043c\u0430\u043c\u0438\u0438\u0430\u0441\u043e\u043d\u0434"); - testMap.put(Locale.CHINESE, jreVersion < 12 - ? "\u4e00\u4e8c\u4e09\u56db\u4e94\u516d\u4e03\u516b\u4e5d\u5341\u5341\u5341" - : "123456789111"); + testMap.put(Locale.CHINESE, new String[]{ + "\u4e00\u4e8c\u4e09\u56db\u4e94\u516d\u4e03\u516b\u4e5d\u5341\u5341\u5341", + "123456789111" + }[localeIndex(Locale.CHINESE)]); testMap.put(new Locale("tr", "TR"), "\u004f\u015e\u004d\u004e\u004d\u0048\u0054\u0041\u0045\u0045\u004b\u0041"); From 4d2bd9d57e28614a7d849fdbbd4f4716298802eb Mon Sep 17 00:00:00 2001 From: Andreas Beeker Date: Sun, 18 Nov 2018 11:06:28 +0000 Subject: [PATCH 18/28] #62921 - Provide OOXMLLite alternative for Java 12+ git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1846824 13f79535-47bb-0310-9956-ffa450edef68 --- build.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.xml b/build.xml index 89f0423e78..cdb28bd055 100644 --- a/build.xml +++ b/build.xml @@ -1969,7 +1969,7 @@ under the License. - + From 4458a10d66dee397d1ef402cb5be2136955ed488 Mon Sep 17 00:00:00 2001 From: Andreas Beeker Date: Sun, 18 Nov 2018 16:03:20 +0000 Subject: [PATCH 19/28] #62921 - Provide OOXMLLite alternative for Java 12+ git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1846849 13f79535-47bb-0310-9956-ffa450edef68 --- build.xml | 2 +- src/testcases/org/apache/poi/POIDataSamples.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build.xml b/build.xml index cdb28bd055..a49aa53111 100644 --- a/build.xml +++ b/build.xml @@ -81,7 +81,7 @@ under the License. user.language and user.country are required as we have locale-sensitive formatters --> - + diff --git a/src/testcases/org/apache/poi/POIDataSamples.java b/src/testcases/org/apache/poi/POIDataSamples.java index c4a093fe41..92db8fe18a 100644 --- a/src/testcases/org/apache/poi/POIDataSamples.java +++ b/src/testcases/org/apache/poi/POIDataSamples.java @@ -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 '" + dataDir + "' does not exist"); } // convert to canonical file, to make any subsequent error messages // clearer. From 8c12df72704183acd77ad2e44e251c13dba3a731 Mon Sep 17 00:00:00 2001 From: Andreas Beeker Date: Sun, 18 Nov 2018 22:09:44 +0000 Subject: [PATCH 20/28] #62921 - Provide OOXMLLite alternative for Java 12+ git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1846870 13f79535-47bb-0310-9956-ffa450edef68 --- build.xml | 7 ++-- .../org/apache/poi/TestAllFiles.java | 33 ++++++++++++------- .../poi/stress/AbstractFileHandler.java | 18 ++++++---- 3 files changed, 38 insertions(+), 20 deletions(-) diff --git a/build.xml b/build.xml index a49aa53111..f78ad14f46 100644 --- a/build.xml +++ b/build.xml @@ -335,8 +335,11 @@ under the License. - - + + + + + diff --git a/src/integrationtest/org/apache/poi/TestAllFiles.java b/src/integrationtest/org/apache/poi/TestAllFiles.java index 7d4495d87c..61c47b9e88 100644 --- a/src/integrationtest/org/apache/poi/TestAllFiles.java +++ b/src/integrationtest/org/apache/poi/TestAllFiles.java @@ -90,6 +90,7 @@ import org.junit.runners.Parameterized.Parameters; @RunWith(Parameterized.class) public class TestAllFiles { private static final File ROOT_DIR = new File("test-data"); + private static final boolean IGNORE_SCRATCHPAD = Boolean.getBoolean("scratchpad.ignore"); public static final String[] SCAN_EXCLUDES = new String[] { "**/.svn/**", "lost+found", "**/.git/**" }; @@ -98,6 +99,7 @@ public class TestAllFiles { // map file extensions to the actual mappers public static final Map HANDLERS = new HashMap<>(); + static { // Excel HANDLERS.put(".xls", new HSSFFileHandler()); @@ -107,17 +109,17 @@ public class TestAllFiles { HANDLERS.put(".xlsb", new XSSFBFileHandler()); // Word - HANDLERS.put(".doc", new HWPFFileHandler()); + HANDLERS.put(".doc", IGNORE_SCRATCHPAD ? new HPSFFileHandler() : new HWPFFileHandler()); HANDLERS.put(".docx", new XWPFFileHandler()); HANDLERS.put(".dotx", new XWPFFileHandler()); HANDLERS.put(".docm", new XWPFFileHandler()); // OpenXML4J files - HANDLERS.put(".ooxml", new OPCFileHandler()); // OPCPackage - HANDLERS.put(".zip", new OPCFileHandler()); // OPCPackage + HANDLERS.put(".ooxml", new OPCFileHandler()); + HANDLERS.put(".zip", new OPCFileHandler()); // Powerpoint - HANDLERS.put(".ppt", new HSLFFileHandler()); + HANDLERS.put(".ppt", IGNORE_SCRATCHPAD ? new HPSFFileHandler() : new HSLFFileHandler()); HANDLERS.put(".pptx", new XSLFFileHandler()); HANDLERS.put(".pptm", new XSLFFileHandler()); HANDLERS.put(".ppsm", new XSLFFileHandler()); @@ -126,13 +128,13 @@ public class TestAllFiles { HANDLERS.put(".potx", new XSLFFileHandler()); // Outlook - HANDLERS.put(".msg", new HSMFFileHandler()); + HANDLERS.put(".msg", IGNORE_SCRATCHPAD ? new HPSFFileHandler() : new HSMFFileHandler()); // Publisher - HANDLERS.put(".pub", new HPBFFileHandler()); + HANDLERS.put(".pub", IGNORE_SCRATCHPAD ? new HPSFFileHandler() : new HPBFFileHandler()); // Visio - binary - HANDLERS.put(".vsd", new HDGFFileHandler()); + HANDLERS.put(".vsd", IGNORE_SCRATCHPAD ? new HPSFFileHandler() : new HDGFFileHandler()); // Visio - ooxml HANDLERS.put(".vsdm", new XDGFFileHandler()); @@ -153,7 +155,7 @@ public class TestAllFiles { HANDLERS.put(".adm", new HPSFFileHandler()); // Microsoft TNEF - HANDLERS.put(".dat", new HMEFFileHandler()); + HANDLERS.put(".dat", IGNORE_SCRATCHPAD ? new HPSFFileHandler() : new HMEFFileHandler()); // TODO: are these readable by some of the formats? HANDLERS.put(".wri", new NullFileHandler()); @@ -300,7 +302,7 @@ public class TestAllFiles { "spreadsheet/54764-2.xlsx", // see TestXSSFBugs.bug54764() "spreadsheet/54764.xlsx", // see TestXSSFBugs.bug54764() "poifs/unknown_properties.msg", // POIFS properties corrupted - "poifs/only-zero-byte-streams.ole2", // No actual contents + (IGNORE_SCRATCHPAD ? "" : "poifs/only-zero-byte-streams.ole2"), // No actual contents "spreadsheet/poc-xmlbomb.xlsx", // contains xml-entity-expansion "spreadsheet/poc-xmlbomb-empty.xlsx", // contains xml-entity-expansion "spreadsheet/poc-shared-strings.xlsx", // contains shared-string-entity-expansion @@ -438,8 +440,17 @@ public class TestAllFiles { } } - // let some file handlers do additional stuff - handler.handleAdditional(inputFile); + try { + // let some file handlers do additional stuff + handler.handleAdditional(inputFile); + } catch (AssumptionViolatedException e) { + // file handler ignored this file + } catch (Exception e) { + if(!EXPECTED_FAILURES.contains(file) && !AbstractFileHandler.EXPECTED_EXTRACTOR_FAILURES.contains(file)) { + System.out.println("Failed: " + file); + throw new Exception("While handling " + file, e); + } + } } public static String getExtension(String file) { diff --git a/src/integrationtest/org/apache/poi/stress/AbstractFileHandler.java b/src/integrationtest/org/apache/poi/stress/AbstractFileHandler.java index 480a7faf61..7f9c22ff41 100644 --- a/src/integrationtest/org/apache/poi/stress/AbstractFileHandler.java +++ b/src/integrationtest/org/apache/poi/stress/AbstractFileHandler.java @@ -79,26 +79,26 @@ public abstract class AbstractFileHandler implements FileHandler { long modified = file.lastModified(); POITextExtractor extractor = null; - try { + try { extractor = ExtractorFactory.createExtractor(file); assertNotNull("Should get a POITextExtractor but had none for file " + file, extractor); assertNotNull("Should get some text but had none for file " + file, extractor.getText()); - + // also try metadata @SuppressWarnings("resource") POITextExtractor metadataExtractor = extractor.getMetadataTextExtractor(); assertNotNull(metadataExtractor.getText()); - assertFalse("Expected Extraction to fail for file " + file + " and handler " + this + ", but did not fail!", + assertFalse("Expected Extraction to fail for file " + file + " and handler " + this + ", but did not fail!", EXPECTED_EXTRACTOR_FAILURES.contains(file.getParentFile().getName() + "/" + file.getName())); - + assertEquals("File should not be modified by extractor", length, file.length()); assertEquals("File should not be modified by extractor", modified, file.lastModified()); - + handleExtractingAsStream(file); - - if(extractor instanceof POIOLE2TextExtractor) { + + if (extractor instanceof POIOLE2TextExtractor) { try (HPSFPropertiesExtractor hpsfExtractor = new HPSFPropertiesExtractor((POIOLE2TextExtractor) extractor)) { assertNotNull(hpsfExtractor.getDocumentSummaryInformationText()); assertNotNull(hpsfExtractor.getSummaryInformationText()); @@ -115,6 +115,10 @@ public abstract class AbstractFileHandler implements FileHandler { String msg = "org.apache.poi.EncryptedDocumentException: Export Restrictions in place - please install JCE Unlimited Strength Jurisdiction Policy files"; assumeFalse(msg.equals(e.getMessage())); throw e; + } catch (IllegalStateException e) { + if (!e.getMessage().contains("POI Scratchpad jar missing") || !Boolean.getBoolean("scratchpad.ignore")) { + throw e; + } } finally { IOUtils.closeQuietly(extractor); } From 655c24dcb5ee809e30669efd92c11e28c50f0114 Mon Sep 17 00:00:00 2001 From: Andreas Beeker Date: Mon, 19 Nov 2018 18:00:42 +0000 Subject: [PATCH 21/28] Remove/Minimize references to Scratchpad module from other modules git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1846931 13f79535-47bb-0310-9956-ffa450edef68 --- build.xml | 2 + .../org/apache/poi/BaseIntegrationTest.java | 34 +++++---- .../poi/ooxml/extractor/ExtractorFactory.java | 47 +++--------- .../extractor/ooxml/TestExtractorFactory.java | 75 +++++++++---------- .../poi/poifs/crypt/TestHxxFEncryption.java | 43 ++++++----- .../org/apache/poi/sl/TestFonts.java | 5 +- .../org/apache/poi/sl/TestHeadersFooters.java | 34 --------- .../org/apache/poi/sl/TestOleShape.java | 20 +++-- .../org/apache/poi/sl/TestSlide.java | 5 +- .../org/apache/poi/sl/TestTable.java | 5 +- .../poi/ss/usermodel/TestEmbedOLEPackage.java | 16 ++-- .../poi/xslf/usermodel/TestXSLFTextShape.java | 10 +-- .../ole2/OLE2ScratchpadExtractorFactory.java | 17 ++++- .../poi/hslf/model/TestHeadersFooters.java | 47 ++++++++++++ 14 files changed, 187 insertions(+), 173 deletions(-) diff --git a/build.xml b/build.xml index f78ad14f46..f60ad87192 100644 --- a/build.xml +++ b/build.xml @@ -1133,6 +1133,7 @@ under the License. + @@ -1303,6 +1304,7 @@ under the License. + - + + + From fa5e01e3918a66e6fdbda804a48432d60d7765bd Mon Sep 17 00:00:00 2001 From: Andreas Beeker Date: Mon, 19 Nov 2018 20:48:10 +0000 Subject: [PATCH 23/28] Remove commented out System.out calls / Move DummyGraphics2d to testcase area, as it's not used by production code git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1846946 13f79535-47bb-0310-9956-ffa450edef68 --- .../MissingRecordAwareHSSFListener.java | 2 -- .../apache/poi/hssf/record/UnknownRecord.java | 11 ++++------ .../org/apache/poi/ss/formula/Formula.java | 22 ++++++++----------- .../apache/poi/ss/formula/FormulaParser.java | 1 - .../poi/ss/formula/eval/OperandResolver.java | 3 +-- .../poi/ss/usermodel/DataFormatter.java | 1 - .../src/org/apache/poi/hslf/record/Notes.java | 1 - .../poi/hssf/usermodel/DummyGraphics2d.java | 0 8 files changed, 14 insertions(+), 27 deletions(-) rename src/{java => testcases}/org/apache/poi/hssf/usermodel/DummyGraphics2d.java (100%) diff --git a/src/java/org/apache/poi/hssf/eventusermodel/MissingRecordAwareHSSFListener.java b/src/java/org/apache/poi/hssf/eventusermodel/MissingRecordAwareHSSFListener.java index ea9b70d88d..f154a1f86c 100644 --- a/src/java/org/apache/poi/hssf/eventusermodel/MissingRecordAwareHSSFListener.java +++ b/src/java/org/apache/poi/hssf/eventusermodel/MissingRecordAwareHSSFListener.java @@ -94,8 +94,6 @@ public final class MissingRecordAwareHSSFListener implements HSSFListener { break; case RowRecord.sid: RowRecord rowrec = (RowRecord) record; - //System.out.println("Row " + rowrec.getRowNumber() + " found, first column at " - // + rowrec.getFirstCol() + " last column at " + rowrec.getLastCol()); // If there's a jump in rows, fire off missing row records if (lastRowRow + 1 < rowrec.getRowNumber()) { diff --git a/src/java/org/apache/poi/hssf/record/UnknownRecord.java b/src/java/org/apache/poi/hssf/record/UnknownRecord.java index 189b582472..ef324a681f 100644 --- a/src/java/org/apache/poi/hssf/record/UnknownRecord.java +++ b/src/java/org/apache/poi/hssf/record/UnknownRecord.java @@ -80,13 +80,10 @@ public final class UnknownRecord extends StandardRecord { public UnknownRecord(RecordInputStream in) { _sid = in.getSid(); _rawData = in.readRemainder(); -// if (false && getBiffName(_sid) == null) { -// // unknown sids in the range 0x0004-0x0013 are probably 'sub-records' of ObjectRecord -// // those sids are in a different number space. -// // TODO - put unknown OBJ sub-records in a different class -// System.out.println("Unknown record 0x" + -// Integer.toHexString(_sid).toUpperCase(Locale.ROOT)); -// } + + // TODO - put unknown OBJ sub-records in a different class + // unknown sids in the range 0x0004-0x0013 are probably 'sub-records' of ObjectRecord + // those sids are in a different number space. } /** diff --git a/src/java/org/apache/poi/ss/formula/Formula.java b/src/java/org/apache/poi/ss/formula/Formula.java index b0a2842040..50ae3d2aea 100644 --- a/src/java/org/apache/poi/ss/formula/Formula.java +++ b/src/java/org/apache/poi/ss/formula/Formula.java @@ -48,19 +48,15 @@ public class Formula { private Formula(byte[] byteEncoding, int encodedTokenLen) { _byteEncoding = byteEncoding.clone(); _encodedTokenLen = encodedTokenLen; -// if (false) { // set to true to eagerly check Ptg decoding -// LittleEndianByteArrayInputStream in = new LittleEndianByteArrayInputStream(byteEncoding); -// Ptg.readTokens(encodedTokenLen, in); -// int nUnusedBytes = _byteEncoding.length - in.getReadIndex(); -// if (nUnusedBytes > 0) { -// // TODO - this seems to occur when IntersectionPtg is present -// // This example file "IntersectionPtg.xls" -// // used by test: TestIntersectionPtg.testReading() -// // has 10 bytes unused at the end of the formula -// // 10 extra bytes are just 0x01 and 0x00 -// System.out.println(nUnusedBytes + " unused bytes at end of formula"); -// } -// } + + // TODO - this seems to occur when IntersectionPtg is present + // This example file "IntersectionPtg.xls" + // used by test: TestIntersectionPtg.testReading() + // has 10 bytes unused at the end of the formula + // 10 extra bytes are just 0x01 and 0x00 + // LittleEndianByteArrayInputStream in = new LittleEndianByteArrayInputStream(byteEncoding); + // Ptg.readTokens(encodedTokenLen, in); + // int nUnusedBytes = _byteEncoding.length - in.getReadIndex(); } /** * Convenience method for {@link #read(int, LittleEndianInput, int)} diff --git a/src/java/org/apache/poi/ss/formula/FormulaParser.java b/src/java/org/apache/poi/ss/formula/FormulaParser.java index 3b82daad91..bd0c9995bf 100644 --- a/src/java/org/apache/poi/ss/formula/FormulaParser.java +++ b/src/java/org/apache/poi/ss/formula/FormulaParser.java @@ -234,7 +234,6 @@ public final class FormulaParser { _inIntersection = false; } _pointer += Character.charCount(look); - //System.out.println(new StringBuilder("Got char: ").appendCodePoint(look)).toString(); } private void resetPointer(int ptr) { _pointer = ptr; diff --git a/src/java/org/apache/poi/ss/formula/eval/OperandResolver.java b/src/java/org/apache/poi/ss/formula/eval/OperandResolver.java index 7258b98c25..26de08c534 100644 --- a/src/java/org/apache/poi/ss/formula/eval/OperandResolver.java +++ b/src/java/org/apache/poi/ss/formula/eval/OperandResolver.java @@ -88,8 +88,7 @@ public final class OperandResolver { CellRangeAddress range = cell.getArrayFormulaRange(); int relativeRowIndex = cell.getRowIndex() - range.getFirstRow(); int relativeColIndex = cell.getColumnIndex() - range.getFirstColumn(); - //System.out.println("Row: " + relativeRowIndex + " Col: " + relativeColIndex); - + if (ae.isColumn()) { if (ae.isRow()) { return ae.getRelativeValue(0, 0); diff --git a/src/java/org/apache/poi/ss/usermodel/DataFormatter.java b/src/java/org/apache/poi/ss/usermodel/DataFormatter.java index e1e5b7a2c1..b805d0cc85 100644 --- a/src/java/org/apache/poi/ss/usermodel/DataFormatter.java +++ b/src/java/org/apache/poi/ss/usermodel/DataFormatter.java @@ -450,7 +450,6 @@ public class DataFormatter implements Observer { // Strip custom text in quotes and escaped characters for now as it can cause performance problems in fractions. //String strippedFormatStr = formatStr.replaceAll("\\\\ ", " ").replaceAll("\\\\.", "").replaceAll("\"[^\"]*\"", " ").replaceAll("\\?", "#"); - //System.out.println("formatStr: "+strippedFormatStr); return new FractionFormat(defaultFractionWholePartFormat, defaultFractionFractionPartFormat); } diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/Notes.java b/src/scratchpad/src/org/apache/poi/hslf/record/Notes.java index 80ee6039f1..8695b25f0b 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/record/Notes.java +++ b/src/scratchpad/src/org/apache/poi/hslf/record/Notes.java @@ -63,7 +63,6 @@ public final class Notes extends SheetContainer for(int i=0; i<_children.length; i++) { if(_children[i] instanceof NotesAtom) { notesAtom = (NotesAtom)_children[i]; - //System.out.println("Found notes for sheet " + notesAtom.getSlideID()); } if(_children[i] instanceof PPDrawing) { ppDrawing = (PPDrawing)_children[i]; diff --git a/src/java/org/apache/poi/hssf/usermodel/DummyGraphics2d.java b/src/testcases/org/apache/poi/hssf/usermodel/DummyGraphics2d.java similarity index 100% rename from src/java/org/apache/poi/hssf/usermodel/DummyGraphics2d.java rename to src/testcases/org/apache/poi/hssf/usermodel/DummyGraphics2d.java From 6d9706b73505eeaf02091300afdf1d3dcc53bb3d Mon Sep 17 00:00:00 2001 From: Andreas Beeker Date: Mon, 19 Nov 2018 21:24:24 +0000 Subject: [PATCH 24/28] release prepare for 4.0.1 - updating build.xml and changes.xml git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1846949 13f79535-47bb-0310-9956-ffa450edef68 --- build.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.xml b/build.xml index f60ad87192..d7162c29cd 100644 --- a/build.xml +++ b/build.xml @@ -42,7 +42,7 @@ under the License. The Apache POI project Ant build. - + From 0377b57a5427d94bba4d220998f64a270628658a Mon Sep 17 00:00:00 2001 From: Andreas Beeker Date: Mon, 19 Nov 2018 21:25:14 +0000 Subject: [PATCH 25/28] prepare for 4.0.2 git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1846951 13f79535-47bb-0310-9956-ffa450edef68 --- build.xml | 2 +- sonar/examples/pom.xml | 2 +- sonar/excelant/pom.xml | 2 +- sonar/main/pom.xml | 2 +- sonar/ooxml-schema-encryption/pom.xml | 2 +- sonar/ooxml-schema-security/pom.xml | 2 +- sonar/ooxml-schema/pom.xml | 2 +- sonar/ooxml/pom.xml | 2 +- sonar/pom.xml | 2 +- sonar/scratchpad/pom.xml | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/build.xml b/build.xml index d7162c29cd..4743a00804 100644 --- a/build.xml +++ b/build.xml @@ -42,7 +42,7 @@ under the License. The Apache POI project Ant build. - + diff --git a/sonar/examples/pom.xml b/sonar/examples/pom.xml index 441dfad7a9..22c576a20d 100644 --- a/sonar/examples/pom.xml +++ b/sonar/examples/pom.xml @@ -6,7 +6,7 @@ org.apache.poi poi-parent - 4.0.1-SNAPSHOT + 4.0.2-SNAPSHOT poi-examples jar diff --git a/sonar/excelant/pom.xml b/sonar/excelant/pom.xml index b9814037f3..220d4eb1e9 100644 --- a/sonar/excelant/pom.xml +++ b/sonar/excelant/pom.xml @@ -6,7 +6,7 @@ org.apache.poi poi-parent - 4.0.1-SNAPSHOT + 4.0.2-SNAPSHOT poi-excelant jar diff --git a/sonar/main/pom.xml b/sonar/main/pom.xml index b4ed72f4a1..9bd0af96a2 100644 --- a/sonar/main/pom.xml +++ b/sonar/main/pom.xml @@ -6,7 +6,7 @@ org.apache.poi poi-parent - 4.0.1-SNAPSHOT + 4.0.2-SNAPSHOT poi-main jar diff --git a/sonar/ooxml-schema-encryption/pom.xml b/sonar/ooxml-schema-encryption/pom.xml index 5b2489a7be..d768a5f4b3 100644 --- a/sonar/ooxml-schema-encryption/pom.xml +++ b/sonar/ooxml-schema-encryption/pom.xml @@ -6,7 +6,7 @@ org.apache.poi poi-parent - 4.0.1-SNAPSHOT + 4.0.2-SNAPSHOT .. poi-ooxml-schema-encryption diff --git a/sonar/ooxml-schema-security/pom.xml b/sonar/ooxml-schema-security/pom.xml index d872d9b59a..06318b2be9 100644 --- a/sonar/ooxml-schema-security/pom.xml +++ b/sonar/ooxml-schema-security/pom.xml @@ -6,7 +6,7 @@ org.apache.poi poi-parent - 4.0.1-SNAPSHOT + 4.0.2-SNAPSHOT .. poi-ooxml-schema-security diff --git a/sonar/ooxml-schema/pom.xml b/sonar/ooxml-schema/pom.xml index 92c2e264af..7bb69433da 100644 --- a/sonar/ooxml-schema/pom.xml +++ b/sonar/ooxml-schema/pom.xml @@ -6,7 +6,7 @@ org.apache.poi poi-parent - 4.0.1-SNAPSHOT + 4.0.2-SNAPSHOT .. poi-ooxml-schema diff --git a/sonar/ooxml/pom.xml b/sonar/ooxml/pom.xml index fad8ac5642..dc4ffc8373 100644 --- a/sonar/ooxml/pom.xml +++ b/sonar/ooxml/pom.xml @@ -6,7 +6,7 @@ org.apache.poi poi-parent - 4.0.1-SNAPSHOT + 4.0.2-SNAPSHOT poi-ooxml jar diff --git a/sonar/pom.xml b/sonar/pom.xml index 87c2daf37c..3fcaf93e5d 100644 --- a/sonar/pom.xml +++ b/sonar/pom.xml @@ -4,7 +4,7 @@ org.apache.poi poi-parent pom - 4.0.1-SNAPSHOT + 4.0.2-SNAPSHOT Apache POI - the Java API for Microsoft Documents Maven build of Apache POI for Sonar checks http://poi.apache.org/ diff --git a/sonar/scratchpad/pom.xml b/sonar/scratchpad/pom.xml index e7ef7303a4..a980e15568 100644 --- a/sonar/scratchpad/pom.xml +++ b/sonar/scratchpad/pom.xml @@ -6,7 +6,7 @@ org.apache.poi poi-parent - 4.0.1-SNAPSHOT + 4.0.2-SNAPSHOT poi-scratchpad jar From 96308eb51259d9e5cb19ef6d5ea0af0f1ecadd84 Mon Sep 17 00:00:00 2001 From: PJ Fanning Date: Tue, 20 Nov 2018 14:15:14 +0000 Subject: [PATCH 26/28] [bug-62929] add null check for blip fill. Thanks to Mate Borcsok git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1847004 13f79535-47bb-0310-9956-ffa450edef68 --- .../poi/xslf/usermodel/XSLFPictureShape.java | 21 ++++++++++---- .../org/apache/poi/xslf/TestXSLFBugs.java | 26 ++++++++++++++---- test-data/slideshow/missing-blip-fill.pptx | Bin 0 -> 40732 bytes 3 files changed, 35 insertions(+), 12 deletions(-) create mode 100644 test-data/slideshow/missing-blip-fill.pptx diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureShape.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureShape.java index 97b4ab8cb0..95a8f0bc23 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureShape.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureShape.java @@ -170,16 +170,25 @@ public class XSLFPictureShape extends XSLFSimpleShape @SuppressWarnings("WeakerAccess") protected String getBlipLink(){ - String link = getBlip().getLink(); - if (link.isEmpty()) return null; - return link; + CTBlip blip = getBlip(); + if (blip != null) { + String link = blip.getLink(); + if (link.isEmpty()) return null; + return link;} else { + return null; + } } @SuppressWarnings("WeakerAccess") protected String getBlipId(){ - String id = getBlip().getEmbed(); - if (id.isEmpty()) return null; - return id; + CTBlip blip = getBlip(); + if (blip != null) { + String id = getBlip().getEmbed(); + if (id.isEmpty()) return null; + return id; + } else { + return null; + } } @Override diff --git a/src/ooxml/testcases/org/apache/poi/xslf/TestXSLFBugs.java b/src/ooxml/testcases/org/apache/poi/xslf/TestXSLFBugs.java index 48b0816993..8dbc8ca23e 100644 --- a/src/ooxml/testcases/org/apache/poi/xslf/TestXSLFBugs.java +++ b/src/ooxml/testcases/org/apache/poi/xslf/TestXSLFBugs.java @@ -17,12 +17,7 @@ package org.apache.poi.xslf; import static org.apache.poi.POITestCase.assertContains; -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; +import static org.junit.Assert.*; import java.awt.Color; import java.awt.Dimension; @@ -93,6 +88,25 @@ import org.openxmlformats.schemas.presentationml.x2006.main.CTShape; public class TestXSLFBugs { private static final POIDataSamples slTests = POIDataSamples.getSlideShowInstance(); + @Test + public void bug62929() throws Exception { + try(XMLSlideShow ss1 = XSLFTestDataSamples.openSampleDocument("missing-blip-fill.pptx")) { + assertEquals(1, ss1.getSlides().size()); + + XSLFSlide slide = ss1.getSlides().get(0); + + assertEquals(slide.getShapes().size(), 1); + + XSLFPictureShape picture = (XSLFPictureShape)slide.getShapes().get(0); + + assertEquals(picture.getShapeId(), 662); + assertFalse(picture.isExternalLinkedPicture()); + assertNull(picture.getPictureData()); + assertNull(picture.getPictureLink()); + assertNull(picture.getClipping()); + } + } + @Test public void bug62736() throws Exception { XMLSlideShow ss1 = XSLFTestDataSamples.openSampleDocument("bug62736.pptx"); diff --git a/test-data/slideshow/missing-blip-fill.pptx b/test-data/slideshow/missing-blip-fill.pptx new file mode 100644 index 0000000000000000000000000000000000000000..62e5f675d0cd4d4c26d0567454cf897ea2bb33e4 GIT binary patch literal 40732 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 Date: Tue, 20 Nov 2018 14:31:49 +0000 Subject: [PATCH 27/28] tidy up code formatting git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1847012 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/poi/xslf/usermodel/XSLFPictureShape.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureShape.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureShape.java index 95a8f0bc23..9f07b18bac 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureShape.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureShape.java @@ -173,8 +173,8 @@ public class XSLFPictureShape extends XSLFSimpleShape CTBlip blip = getBlip(); if (blip != null) { String link = blip.getLink(); - if (link.isEmpty()) return null; - return link;} else { + return (link.isEmpty()) ? null : link; + } else { return null; } } @@ -183,9 +183,8 @@ public class XSLFPictureShape extends XSLFSimpleShape protected String getBlipId(){ CTBlip blip = getBlip(); if (blip != null) { - String id = getBlip().getEmbed(); - if (id.isEmpty()) return null; - return id; + String id = blip.getEmbed(); + return (id.isEmpty()) ? null : id; } else { return null; } From 78aceb2106e83f584924306979502c877286a49e Mon Sep 17 00:00:00 2001 From: Andreas Beeker Date: Tue, 20 Nov 2018 22:11:58 +0000 Subject: [PATCH 28/28] Remove duplicated .jar extension when crafting the maven-jar name git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1847068 13f79535-47bb-0310-9956-ffa450edef68 --- build.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/build.xml b/build.xml index 4743a00804..207acc4c68 100644 --- a/build.xml +++ b/build.xml @@ -1950,6 +1950,7 @@ under the License. +