diff options
author | Andreas Beeker <kiwiwings@apache.org> | 2018-11-20 22:24:26 +0000 |
---|---|---|
committer | Andreas Beeker <kiwiwings@apache.org> | 2018-11-20 22:24:26 +0000 |
commit | 30d4934edcf8bb238049d733bcaf9ee4e4d4f45b (patch) | |
tree | 078b8ef39ea25a4204f99189f6ffaf6f45dfeb87 /src | |
parent | 940daf0d923f84a5ea8cc02397060c84d4f90ae7 (diff) | |
parent | 78aceb2106e83f584924306979502c877286a49e (diff) | |
download | poi-30d4934edcf8bb238049d733bcaf9ee4e4d4f45b.tar.gz poi-30d4934edcf8bb238049d733bcaf9ee4e4d4f45b.zip |
merge trunk
git-svn-id: https://svn.apache.org/repos/asf/poi/branches/hemf@1847069 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src')
43 files changed, 629 insertions, 786 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..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 @@ -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; @@ -36,8 +35,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( @@ -78,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")) { diff --git a/src/integrationtest/build.xml b/src/integrationtest/build.xml index 26bd57e108..a228a22374 100644 --- a/src/integrationtest/build.xml +++ b/src/integrationtest/build.xml @@ -82,7 +82,9 @@ Before running this, you should execute the "assemble" target in the main build. <target name="runCompileTest" depends="init" description="Verify that we can compile most examples without including excelant or scratchpad jars"> <!-- clean out old stuff in build-dir --> - <delete dir="${build}"/> + <delete dir="${build}" quiet="true" failonerror="false"/> + <!-- ... try again - on Windows, the JaCoCo ant task seems to keep files open and hence the lib directory can't be removed --> + <delete dir="${build}" quiet="true" failonerror="false"/> <mkdir dir="${build}"/> <!-- select latest built jar files without scratchpad.jar --> diff --git a/src/integrationtest/org/apache/poi/BaseIntegrationTest.java b/src/integrationtest/org/apache/poi/BaseIntegrationTest.java index 291618f680..304794b231 100644 --- a/src/integrationtest/org/apache/poi/BaseIntegrationTest.java +++ b/src/integrationtest/org/apache/poi/BaseIntegrationTest.java @@ -16,17 +16,24 @@ ==================================================================== */ package org.apache.poi; -import org.apache.poi.hslf.exceptions.OldPowerPointFormatException; -import org.apache.poi.hssf.OldExcelFormatException; -import org.apache.poi.hwpf.OldWordFileFormatException; -import org.apache.poi.poifs.filesystem.OfficeXmlFileException; -import org.apache.poi.stress.*; -import org.junit.Assume; +import static org.junit.Assert.assertNotNull; -import java.io.*; +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; import java.util.zip.ZipException; -import static org.junit.Assert.assertNotNull; +import org.apache.poi.poifs.filesystem.OfficeXmlFileException; +import org.apache.poi.stress.FileHandler; +import org.apache.poi.stress.HSLFFileHandler; +import org.apache.poi.stress.HSSFFileHandler; +import org.apache.poi.stress.HWPFFileHandler; +import org.apache.poi.stress.XSLFFileHandler; +import org.apache.poi.stress.XSSFFileHandler; +import org.apache.poi.stress.XWPFFileHandler; +import org.junit.Assume; public class BaseIntegrationTest { private final File rootDir; @@ -53,12 +60,13 @@ public class BaseIntegrationTest { // use XWPF instead of HWPF and XSSF instead of HSSF as the file seems to have the wrong extension handleWrongExtension(inputFile, e); - } catch (OldWordFileFormatException | OldExcelFormatException | OldPowerPointFormatException e) { - // at least perform extracting tests on these old files } catch (OldFileFormatException e) { - // Not even text extraction is supported for these: handler.handleExtracting(inputFile); - //noinspection ConstantConditions - Assume.assumeFalse("File " + file + " excluded because it is unsupported old Excel format", true); + if (e.getClass().equals(OldFileFormatException.class)) { + // Not even text extraction is supported for these: handler.handleExtracting(inputFile); + //noinspection ConstantConditions + Assume.assumeFalse("File " + file + " excluded because it is unsupported old Excel format", true); + } + // otherwise try at least to perform extracting tests on these old files } catch (EncryptedDocumentException e) { // Do not try to read encrypted files //noinspection ConstantConditions 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<String, FileHandler> 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); } 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/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<String, Color> NAMED_COLORS; + static final Map<String, Color> NAMED_COLORS; static { NAMED_COLORS = new TreeMap<>( String.CASE_INSENSITIVE_ORDER); - Map<Integer,HSSFColor> colors = HSSFColor.getIndexHash(); - for (HSSFColor color : colors.values()) { - Class<? extends HSSFColor> 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/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/ooxml/java/org/apache/poi/ooxml/extractor/ExtractorFactory.java b/src/ooxml/java/org/apache/poi/ooxml/extractor/ExtractorFactory.java index f49929e212..412cacfeac 100644 --- a/src/ooxml/java/org/apache/poi/ooxml/extractor/ExtractorFactory.java +++ b/src/ooxml/java/org/apache/poi/ooxml/extractor/ExtractorFactory.java @@ -16,24 +16,20 @@ ==================================================================== */ package org.apache.poi.ooxml.extractor; -import java.io.ByteArrayInputStream; import java.io.File; -import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; +import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Iterator; +import java.util.List; import org.apache.poi.EncryptedDocumentException; +import org.apache.poi.extractor.OLE2ExtractorFactory; import org.apache.poi.extractor.POIOLE2TextExtractor; import org.apache.poi.extractor.POITextExtractor; -import org.apache.poi.extractor.OLE2ExtractorFactory; -import org.apache.poi.hsmf.MAPIMessage; -import org.apache.poi.hsmf.datatypes.AttachmentChunks; -import org.apache.poi.hsmf.extractor.OutlookTextExtactor; import org.apache.poi.hssf.extractor.ExcelExtractor; import org.apache.poi.hssf.record.crypto.Biff8EncryptionKey; -import org.apache.poi.hwpf.extractor.WordExtractor; import org.apache.poi.openxml4j.exceptions.OpenXML4JException; import org.apache.poi.openxml4j.opc.OPCPackage; import org.apache.poi.openxml4j.opc.PackageAccess; @@ -46,9 +42,9 @@ import org.apache.poi.poifs.filesystem.DirectoryEntry; import org.apache.poi.poifs.filesystem.DirectoryNode; import org.apache.poi.poifs.filesystem.Entry; import org.apache.poi.poifs.filesystem.FileMagic; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; import org.apache.poi.poifs.filesystem.NotOLE2FileException; import org.apache.poi.poifs.filesystem.OfficeXmlFileException; +import org.apache.poi.poifs.filesystem.POIFSFileSystem; import org.apache.poi.sl.extractor.SlideShowExtractor; import org.apache.poi.util.IOUtils; import org.apache.poi.util.NotImplemented; @@ -311,6 +307,7 @@ public final class ExtractorFactory { throw new IllegalStateException("The extractor didn't know which POIFS it came from!"); } + // provide ExcelExtractor also in OOXML module, because scratchpad is not necessary for it if (ext instanceof ExcelExtractor) { // These are in MBD... under the root Iterator<Entry> it = root.getEntries(); @@ -320,34 +317,14 @@ public final class ExtractorFactory { dirs.add(entry); } } - } else if (ext instanceof WordExtractor) { - // These are in ObjectPool -> _... under the root + } else { try { - DirectoryEntry op = (DirectoryEntry) root.getEntry("ObjectPool"); - Iterator<Entry> it = op.getEntries(); - while (it.hasNext()) { - Entry entry = it.next(); - if (entry.getName().startsWith("_")) { - dirs.add(entry); - } - } - } catch (FileNotFoundException e) { - logger.log(POILogger.INFO, "Ignoring FileNotFoundException while extracting Word document", e.getLocalizedMessage()); - // ignored here - } - //} else if(ext instanceof PowerPointExtractor) { - // Tricky, not stored directly in poifs - // TODO - } else if (ext instanceof OutlookTextExtactor) { - // Stored in the Attachment blocks - MAPIMessage msg = ((OutlookTextExtactor)ext).getMAPIMessage(); - for (AttachmentChunks attachment : msg.getAttachmentFiles()) { - if (attachment.getAttachData() != null) { - byte[] data = attachment.getAttachData().getValue(); - nonPOIFS.add( new ByteArrayInputStream(data) ); - } else if (attachment.getAttachmentDirectory() != null) { - dirs.add(attachment.getAttachmentDirectory().getDirectory()); - } + Class<?> clazz = Class.forName("org.apache.poi.extractor.ole2.OLE2ScratchpadExtractorFactory"); + Method m = clazz.getDeclaredMethod("identifyEmbeddedResources", POIOLE2TextExtractor.class, List.class, List.class); + m.invoke(null, ext, dirs, nonPOIFS); + } catch (ReflectiveOperationException e) { + logger.log(POILogger.WARN, "POI Scratchpad jar not included ", e.getLocalizedMessage()); + return new POITextExtractor[0]; } } 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..9f07b18bac 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,24 @@ 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(); + return (link.isEmpty()) ? null : 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 = blip.getEmbed(); + return (id.isEmpty()) ? null : id; + } else { + return null; + } } @Override 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<? extends ZipArchiveEntry> 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/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 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/extractor/ooxml/TestExtractorFactory.java b/src/ooxml/testcases/org/apache/poi/extractor/ooxml/TestExtractorFactory.java index 46681f71e1..196499efdc 100644 --- a/src/ooxml/testcases/org/apache/poi/extractor/ooxml/TestExtractorFactory.java +++ b/src/ooxml/testcases/org/apache/poi/extractor/ooxml/TestExtractorFactory.java @@ -33,27 +33,18 @@ import org.apache.poi.POIDataSamples; import org.apache.poi.UnsupportedFileFormatException; import org.apache.poi.extractor.POIOLE2TextExtractor; import org.apache.poi.extractor.POITextExtractor; -import org.apache.poi.hdgf.extractor.VisioTextExtractor; -import org.apache.poi.hpbf.extractor.PublisherTextExtractor; -import org.apache.poi.hsmf.extractor.OutlookTextExtactor; import org.apache.poi.hssf.HSSFTestDataSamples; import org.apache.poi.hssf.OldExcelFormatException; import org.apache.poi.hssf.extractor.EventBasedExcelExtractor; import org.apache.poi.hssf.extractor.ExcelExtractor; -import org.apache.poi.hwpf.extractor.Word6Extractor; -import org.apache.poi.hwpf.extractor.WordExtractor; import org.apache.poi.ooxml.extractor.ExtractorFactory; import org.apache.poi.ooxml.extractor.POIXMLTextExtractor; import org.apache.poi.openxml4j.exceptions.OpenXML4JException; import org.apache.poi.openxml4j.opc.OPCPackage; import org.apache.poi.openxml4j.opc.PackageAccess; import org.apache.poi.poifs.filesystem.POIFSFileSystem; -import org.apache.poi.sl.extractor.SlideShowExtractor; -import org.apache.poi.xdgf.extractor.XDGFVisioExtractor; -import org.apache.poi.xssf.extractor.XSSFBEventBasedExcelExtractor; import org.apache.poi.xssf.extractor.XSSFEventBasedExcelExtractor; import org.apache.poi.xssf.extractor.XSSFExcelExtractor; -import org.apache.poi.xwpf.extractor.XWPFWordExtractor; import org.apache.xmlbeans.XmlException; import org.junit.Test; @@ -108,21 +99,21 @@ public class TestExtractorFactory { } private static final Object[] TEST_SET = { - "Excel", xls, ExcelExtractor.class, 200, - "Excel - xlsx", xlsx, XSSFExcelExtractor.class, 200, - "Excel - xltx", xltx, XSSFExcelExtractor.class, -1, - "Excel - xlsb", xlsb, XSSFBEventBasedExcelExtractor.class, -1, - "Word", doc, WordExtractor.class, 120, - "Word - docx", docx, XWPFWordExtractor.class, 120, - "Word - dotx", dotx, XWPFWordExtractor.class, -1, - "Word 6", doc6, Word6Extractor.class, 20, - "Word 95", doc95, Word6Extractor.class, 120, - "PowerPoint", ppt, SlideShowExtractor.class, 120, - "PowerPoint - pptx", pptx, SlideShowExtractor.class, 120, - "Visio", vsd, VisioTextExtractor.class, 50, - "Visio - vsdx", vsdx, XDGFVisioExtractor.class, 20, - "Publisher", pub, PublisherTextExtractor.class, 50, - "Outlook msg", msg, OutlookTextExtactor.class, 50, + "Excel", xls, "ExcelExtractor", 200, + "Excel - xlsx", xlsx, "XSSFExcelExtractor", 200, + "Excel - xltx", xltx, "XSSFExcelExtractor", -1, + "Excel - xlsb", xlsb, "XSSFBEventBasedExcelExtractor", -1, + "Word", doc, "WordExtractor", 120, + "Word - docx", docx, "XWPFWordExtractor", 120, + "Word - dotx", dotx, "XWPFWordExtractor", -1, + "Word 6", doc6, "Word6Extractor", 20, + "Word 95", doc95, "Word6Extractor", 120, + "PowerPoint", ppt, "SlideShowExtractor", 120, + "PowerPoint - pptx", pptx, "SlideShowExtractor", 120, + "Visio", vsd, "VisioTextExtractor", 50, + "Visio - vsdx", vsdx, "XDGFVisioExtractor", 20, + "Publisher", pub, "PublisherTextExtractor", 50, + "Outlook msg", msg, "OutlookTextExtactor", 50, // TODO Support OOXML-Strict, see bug #57699 // xlsxStrict @@ -138,7 +129,7 @@ public class TestExtractorFactory { public void testFile() throws Exception { for (int i = 0; i < TEST_SET.length; i += 4) { try (POITextExtractor ext = ExtractorFactory.createExtractor((File) TEST_SET[i + 1])) { - testExtractor(ext, (String) TEST_SET[i], (Class) TEST_SET[i + 2], (Integer) TEST_SET[i + 3]); + testExtractor(ext, (String) TEST_SET[i], (String) TEST_SET[i + 2], (Integer) TEST_SET[i + 3]); } } } @@ -180,15 +171,15 @@ public class TestExtractorFactory { } try (FileInputStream fis = new FileInputStream(testFile); POITextExtractor ext = poifsIS.apply(fis)) { - testExtractor(ext, (String) TEST_SET[i], (Class) TEST_SET[i + 2], (Integer) TEST_SET[i + 3]); + testExtractor(ext, (String) TEST_SET[i], (String) TEST_SET[i + 2], (Integer) TEST_SET[i + 3]); } catch (IllegalArgumentException e) { fail("failed to process "+testFile); } } } - private void testExtractor(final POITextExtractor ext, final String testcase, final Class extrClass, final Integer minLength) { - assertTrue("invalid extractor for " + testcase, extrClass.isInstance(ext)); + private void testExtractor(final POITextExtractor ext, final String testcase, final String extrClass, final Integer minLength) { + assertEquals("invalid extractor for " + testcase, extrClass, ext.getClass().getSimpleName()); final String actual = ext.getText(); if (minLength == -1) { assertContains(actual.toLowerCase(Locale.ROOT), "test"); @@ -215,7 +206,7 @@ public class TestExtractorFactory { try (final OPCPackage pkg = OPCPackage.open(testFile, PackageAccess.READ); final POITextExtractor ext = ExtractorFactory.createExtractor(pkg)) { - testExtractor(ext, (String) TEST_SET[i], (Class) TEST_SET[i + 2], (Integer) TEST_SET[i + 3]); + testExtractor(ext, (String) TEST_SET[i], (String) TEST_SET[i + 2], (Integer) TEST_SET[i + 3]); pkg.revert(); } } @@ -334,16 +325,22 @@ public class TestExtractorFactory { int numWord = 0, numXls = 0, numPpt = 0, numMsg = 0, numWordX = 0; for (POITextExtractor embed : embeds) { assertTrue(embed.getText().length() > 20); - if (embed instanceof SlideShowExtractor) { - numPpt++; - } else if (embed instanceof ExcelExtractor) { - numXls++; - } else if (embed instanceof WordExtractor) { - numWord++; - } else if (embed instanceof OutlookTextExtactor) { - numMsg++; - } else if (embed instanceof XWPFWordExtractor) { - numWordX++; + switch (embed.getClass().getSimpleName()) { + case "SlideShowExtractor": + numPpt++; + break; + case "ExcelExtractor": + numXls++; + break; + case "WordExtractor": + numWord++; + break; + case "OutlookTextExtactor": + numMsg++; + break; + case "XWPFWordExtractor": + numWordX++; + break; } } 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<Class<?>> 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<String> 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<Class<?>> classes = getLoadedClasses(_ooxmlJar.getName()); - Set<String> 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<Class<? extends List>> 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<Class<? extends StringEnumAbstractBase>> 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<JarEntry> 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<Class<?>> 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<Class<?>> 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<Field>() { - @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<Class<?>> classes = (Vector<Class<?>>) _classes.get(appLoader); - Set<Class<?>> 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<Integer> 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<String> 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/poifs/crypt/TestHxxFEncryption.java b/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestHxxFEncryption.java index 16d5a52a67..25443d786f 100644 --- a/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestHxxFEncryption.java +++ b/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestHxxFEncryption.java @@ -23,6 +23,7 @@ import static org.apache.poi.POIDataSamples.getSpreadSheetInstance; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -35,9 +36,8 @@ import java.util.Collection; import org.apache.poi.POIDataSamples; import org.apache.poi.POIDocument; import org.apache.poi.extractor.POITextExtractor; -import org.apache.poi.ooxml.extractor.ExtractorFactory; -import org.apache.poi.hslf.usermodel.HSLFSlideShowImpl; import org.apache.poi.hssf.record.crypto.Biff8EncryptionKey; +import org.apache.poi.ooxml.extractor.ExtractorFactory; import org.apache.poi.openxml4j.exceptions.OpenXML4JException; import org.apache.poi.poifs.crypt.cryptoapi.CryptoAPIEncryptionHeader; import org.apache.poi.poifs.storage.RawDataUtil; @@ -64,21 +64,24 @@ public class TestHxxFEncryption { @Parameters(name="{1}") public static Collection<Object[]> data() throws IOException { + final String base64 = + "H4sIAAAAAAAAAF1Uu24bMRDs/RULVwkgCUhSpHaZwkDgpHJH8fZ0G/Nx4ZI6y13yG/mRfIb9R5mlZFlIpdPtcnZmdnjPf57/vvx6+f3h6obuv3"+ + "ylbY5bEiVHe1fEpUp5pOgkrK0iabehm7FyoZi1ks8xcvHiQu8h5bLnorTlnUvkJ/YPOHKsLVInAqCs91KakuaxLq4w3g00SgCo9Xou1UnCmSBe"+ + "MhpRY6qHmXVFteQfQJ5yUaaOw4qXwgPVjPGAqhNH5bBHAfTmwqqoSkLdFT/J3nC0eZBRk7yiu5s7yoU+r+9l3tDtm5A3jgt6AQxNOY2ya+U4sK"+ + "XZ+YczbpfSVVuzFOuunKraqIVD2ND3yVXauT3TNthR/O3IJAM7gzTOGeIcXZvj14ahotW8wSognlMu0Yyp/Fi7O6s+CK6haUUjtPCji7MVcgqH"+ + "jh+42tqeqPDMroJ/lBAE4AZbJbJu6Fu35ej42Tw9mYeTwVXoBKJiPeFV94q2rZJAyNEPo/qOdWYLBpq3B2JX8GDZeJ14mZf3tOQWBmpd9yQ7kI"+ + "DCY/jmkj1oGOicFy62r9vutC5uJsVEMFgmAXXfYcC6BRBKNHCybALFJolnrDcPXNLl+K60Vctt09YZT7YgbeOICGJ/ZgC2JztOnm1JhX3eJXni"+ + "U5Bqhezzlu334vD/Ajr3yDGXw5G9IZ6aLmLfQafY42N3J7cjj1LaXOHihSrcC5ThmuYIB5FX5AU8tKlnNG9Dn1EnsdD4KcnPhsSNPRiXtz461b"+ + "VZw8Pm6vn0afh4fvr0D5P/+cMuBAAA"; + final String x = new String(RawDataUtil.decompress(base64), StandardCharsets.UTF_8); + return Arrays.asList( // binary rc4 new Object[]{ getDocumentInstance(), "password_tika_binaryrc4.doc", "tika", "This is an encrypted Word 2007 File." }, // cryptoapi new Object[]{ getDocumentInstance(), "password_password_cryptoapi.doc", "password", "This is a test" }, // binary rc4 - new Object[]{ getSpreadSheetInstance(), "password.xls", "password", - x("H4sIAAAAAAAAAF1Uu24bMRDs/RULVwkgCUhSpHaZwkDgpHJH8fZ0G/Nx4ZI6y13yG/mRfIb9R5mlZFlIpdPtcnZmdnjPf57/vvx6+f3h6obuv3"+ - "ylbY5bEiVHe1fEpUp5pOgkrK0iabehm7FyoZi1ks8xcvHiQu8h5bLnorTlnUvkJ/YPOHKsLVInAqCs91KakuaxLq4w3g00SgCo9Xou1UnCmSBe"+ - "MhpRY6qHmXVFteQfQJ5yUaaOw4qXwgPVjPGAqhNH5bBHAfTmwqqoSkLdFT/J3nC0eZBRk7yiu5s7yoU+r+9l3tDtm5A3jgt6AQxNOY2ya+U4sK"+ - "XZ+YczbpfSVVuzFOuunKraqIVD2ND3yVXauT3TNthR/O3IJAM7gzTOGeIcXZvj14ahotW8wSognlMu0Yyp/Fi7O6s+CK6haUUjtPCji7MVcgqH"+ - "jh+42tqeqPDMroJ/lBAE4AZbJbJu6Fu35ej42Tw9mYeTwVXoBKJiPeFV94q2rZJAyNEPo/qOdWYLBpq3B2JX8GDZeJ14mZf3tOQWBmpd9yQ7kI"+ - "DCY/jmkj1oGOicFy62r9vutC5uJsVEMFgmAXXfYcC6BRBKNHCybALFJolnrDcPXNLl+K60Vctt09YZT7YgbeOICGJ/ZgC2JztOnm1JhX3eJXni"+ - "U5Bqhezzlu334vD/Ajr3yDGXw5G9IZ6aLmLfQafY42N3J7cjj1LaXOHihSrcC5ThmuYIB5FX5AU8tKlnNG9Dn1EnsdD4KcnPhsSNPRiXtz461b"+ - "VZw8Pm6vn0afh4fvr0D5P/+cMuBAAA") }, + new Object[]{ getSpreadSheetInstance(), "password.xls", "password", x }, // cryptoapi new Object[]{ getSpreadSheetInstance(), "35897-type4.xls", "freedom", "Sheet1\nhello there!" }, // cryptoapi (PPT only supports cryptoapi...) @@ -86,10 +89,6 @@ public class TestHxxFEncryption { ); } - private static String x(String base64) throws IOException { - return new String(RawDataUtil.decompress(base64), StandardCharsets.UTF_8); - } - @Test public void extract() throws IOException, OpenXML4JException, XmlException { File f = sampleDir.getFile(file); @@ -112,7 +111,7 @@ public class TestHxxFEncryption { newPassword(null); } - public void newPassword(String newPass) throws IOException, OpenXML4JException, XmlException { + private void newPassword(String newPass) throws IOException, OpenXML4JException, XmlException { File f = sampleDir.getFile(file); Biff8EncryptionKey.setCurrentUserPassword(password); try (POITextExtractor te1 = ExtractorFactory.createExtractor(f)) { @@ -156,10 +155,14 @@ public class TestHxxFEncryption { try (POITextExtractor te3 = ExtractorFactory.createExtractor(new ByteArrayInputStream(bos.toByteArray())); POIDocument doc = (POIDocument) te3.getDocument()) { // need to cache data (i.e. read all data) before changing the key size - if (doc instanceof HSLFSlideShowImpl) { - HSLFSlideShowImpl hss = (HSLFSlideShowImpl) doc; - hss.getPictureData(); - hss.getDocumentSummaryInformation(); + Class<?> clazz = doc.getClass(); + if ("HSLFSlideShowImpl".equals(clazz.getSimpleName())) { + try { + clazz.getDeclaredMethod("getPictureData").invoke(doc); + } catch (ReflectiveOperationException e) { + fail("either scratchpad jar is included and this should work or the clazz should be != HSLFSlideShowImpl"); + } + doc.getDocumentSummaryInformation(); } EncryptionInfo ei = doc.getEncryptionInfo(); assertNotNull(ei); diff --git a/src/ooxml/testcases/org/apache/poi/sl/TestFonts.java b/src/ooxml/testcases/org/apache/poi/sl/TestFonts.java index fe76115b28..39de26a073 100644 --- a/src/ooxml/testcases/org/apache/poi/sl/TestFonts.java +++ b/src/ooxml/testcases/org/apache/poi/sl/TestFonts.java @@ -38,7 +38,6 @@ import java.util.Map; import org.apache.poi.POIDataSamples; import org.apache.poi.common.usermodel.fonts.FontGroup; -import org.apache.poi.hslf.usermodel.HSLFSlideShow; import org.apache.poi.sl.draw.DrawFactory; import org.apache.poi.sl.draw.Drawable; import org.apache.poi.sl.usermodel.Slide; @@ -93,9 +92,9 @@ public class TestFonts { } @Test - public void resizeToFitTextHSLF() throws IOException { + public void resizeToFitTextHSLF() throws IOException, ReflectiveOperationException { assumeFalse(xslfOnly()); - SlideShow<?,?> ppt = new HSLFSlideShow(); + SlideShow<?,?> ppt = (SlideShow<?,?>)Class.forName("org.apache.poi.hslf.usermodel.HSLFSlideShow").newInstance(); resizeToFitText(ppt); ppt.close(); } diff --git a/src/ooxml/testcases/org/apache/poi/sl/TestHeadersFooters.java b/src/ooxml/testcases/org/apache/poi/sl/TestHeadersFooters.java index 910e153e45..a4b50bf082 100644 --- a/src/ooxml/testcases/org/apache/poi/sl/TestHeadersFooters.java +++ b/src/ooxml/testcases/org/apache/poi/sl/TestHeadersFooters.java @@ -20,19 +20,12 @@ package org.apache.poi.sl; import static org.apache.poi.sl.SLCommonUtils.openSampleSlideshow; -import static org.apache.poi.sl.SLCommonUtils.xslfOnly; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; -import static org.junit.Assume.assumeFalse; import java.io.IOException; import java.util.List; -import org.apache.poi.hslf.model.HeadersFooters; -import org.apache.poi.hslf.usermodel.HSLFSlide; -import org.apache.poi.hslf.usermodel.HSLFTextParagraph; import org.apache.poi.sl.usermodel.Shape; import org.apache.poi.sl.usermodel.Slide; import org.apache.poi.sl.usermodel.SlideShow; @@ -42,33 +35,6 @@ import org.junit.Test; public class TestHeadersFooters { @Test - public void bug58144a() throws IOException { - assumeFalse(xslfOnly()); - SlideShow<?,?> ppt = openSampleSlideshow("bug58144-headers-footers-2003.ppt"); - HSLFSlide sl = (HSLFSlide)ppt.getSlides().get(0); - HeadersFooters hfs = sl.getHeadersFooters(); - assertNull(hfs.getHeaderText()); - assertEquals("Confidential", hfs.getFooterText()); - List<List<HSLFTextParagraph>> llp = sl.getTextParagraphs(); - assertEquals("Test", HSLFTextParagraph.getText(llp.get(0))); - assertFalse(llp.get(0).get(0).isHeaderOrFooter()); - ppt.close(); - } - - @Test - public void bug58144b() throws IOException { - assumeFalse(xslfOnly()); - SlideShow<?,?> ppt = openSampleSlideshow("bug58144-headers-footers-2007.ppt"); - Slide<?,?> sl = ppt.getSlides().get(0); - HeadersFooters hfs2 = ((HSLFSlide)sl).getHeadersFooters(); - assertNull(hfs2.getHeaderText()); - assertEquals("Slide footer", hfs2.getFooterText()); - - testSlideShow(ppt); - ppt.close(); - } - - @Test public void bug58144c() throws IOException { SlideShow<?,?> ppt = openSampleSlideshow("bug58144-headers-footers-2007.pptx"); testSlideShow(ppt); diff --git a/src/ooxml/testcases/org/apache/poi/sl/TestOleShape.java b/src/ooxml/testcases/org/apache/poi/sl/TestOleShape.java index 5f61a654bb..00614e2102 100644 --- a/src/ooxml/testcases/org/apache/poi/sl/TestOleShape.java +++ b/src/ooxml/testcases/org/apache/poi/sl/TestOleShape.java @@ -35,13 +35,14 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; import java.util.Arrays; import java.util.Collection; import org.apache.poi.POIDataSamples; -import org.apache.poi.hslf.usermodel.HSLFSlideShow; +import org.apache.poi.POIDocument; import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.hwpf.HWPFDocument; import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.poifs.storage.RawDataUtil; import org.apache.poi.sl.usermodel.ObjectMetaData; @@ -124,7 +125,7 @@ public class TestOleShape { } @Test - public void embedData() throws IOException, InvalidFormatException { + public void embedData() throws IOException, InvalidFormatException, ReflectiveOperationException { final ByteArrayInputStream pptBytes; try (SlideShow<?,?> ppt = createSlideShow()) { final PictureData picData = ppt.addPicture(pictureFile, PictureType.EMF); @@ -146,12 +147,12 @@ public class TestOleShape { } } - private SlideShow<?,?> createSlideShow() { + private SlideShow<?,?> createSlideShow() throws ReflectiveOperationException { if (api == Api.XSLF) { return new XMLSlideShow(); } else { assumeFalse(xslfOnly()); - return new HSLFSlideShow(); + return (SlideShow<?,?>)Class.forName("org.apache.poi.hslf.usermodel.HSLFSlideShow").newInstance(); } } @@ -186,7 +187,7 @@ public class TestOleShape { } } - private void validateOleData(final InputStream in) throws IOException, InvalidFormatException { + private void validateOleData(final InputStream in) throws IOException, InvalidFormatException, ReflectiveOperationException { switch (app) { case EXCEL_V8: case EXCEL_V12: @@ -195,8 +196,11 @@ public class TestOleShape { } break; case WORD_V8: - try (HWPFDocument doc = new HWPFDocument(in)) { - assertEquals("This is a simple file created with Word 97-SR2.\r", doc.getDocumentText()); + Class<? extends POIDocument> clazz = (Class<? extends POIDocument>)Class.forName("org.apache.poi.hwpf.HWPFDocument"); + Constructor<? extends POIDocument> con = clazz.getDeclaredConstructor(InputStream.class); + Method m = clazz.getMethod("getDocumentText"); + try (POIDocument doc = con.newInstance(in)) { + assertEquals("This is a simple file created with Word 97-SR2.\r", m.invoke(doc)); } break; case WORD_V12: diff --git a/src/ooxml/testcases/org/apache/poi/sl/TestSlide.java b/src/ooxml/testcases/org/apache/poi/sl/TestSlide.java index 6c4c49e63f..60a8a3691d 100644 --- a/src/ooxml/testcases/org/apache/poi/sl/TestSlide.java +++ b/src/ooxml/testcases/org/apache/poi/sl/TestSlide.java @@ -29,7 +29,6 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; -import org.apache.poi.hslf.usermodel.HSLFSlideShow; import org.apache.poi.sl.usermodel.SlideShow; import org.apache.poi.sl.usermodel.SlideShowFactory; import org.apache.poi.xslf.usermodel.XMLSlideShow; @@ -38,9 +37,9 @@ import org.junit.Test; public class TestSlide { @Test - public void hideHSLF() throws IOException { + public void hideHSLF() throws IOException, ReflectiveOperationException { assumeFalse(xslfOnly()); - SlideShow<?,?> ppt1 = new HSLFSlideShow(); + SlideShow<?,?> ppt1 = (SlideShow<?,?>)Class.forName("org.apache.poi.hslf.usermodel.HSLFSlideShow").newInstance(); hideSlide(ppt1); ppt1.close(); } diff --git a/src/ooxml/testcases/org/apache/poi/sl/TestTable.java b/src/ooxml/testcases/org/apache/poi/sl/TestTable.java index f55a8a7cbc..4b2a1b191e 100644 --- a/src/ooxml/testcases/org/apache/poi/sl/TestTable.java +++ b/src/ooxml/testcases/org/apache/poi/sl/TestTable.java @@ -34,7 +34,6 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; -import org.apache.poi.hslf.usermodel.HSLFSlideShow; import org.apache.poi.sl.usermodel.Slide; import org.apache.poi.sl.usermodel.SlideShow; import org.apache.poi.sl.usermodel.SlideShowFactory; @@ -96,9 +95,9 @@ public class TestTable { } @Test - public void directionHSLF() throws IOException { + public void directionHSLF() throws IOException, ReflectiveOperationException { assumeFalse(xslfOnly()); - SlideShow<?,?> ppt1 = new HSLFSlideShow(); + SlideShow<?,?> ppt1 = (SlideShow<?,?>)Class.forName("org.apache.poi.hslf.usermodel.HSLFSlideShow").newInstance(); testTextDirection(ppt1); ppt1.close(); } 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..fd1c8d8a10 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; @@ -38,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 @@ -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()) diff --git a/src/ooxml/testcases/org/apache/poi/ss/usermodel/TestEmbedOLEPackage.java b/src/ooxml/testcases/org/apache/poi/ss/usermodel/TestEmbedOLEPackage.java index f287d52fe9..16d0b0b8c4 100644 --- a/src/ooxml/testcases/org/apache/poi/ss/usermodel/TestEmbedOLEPackage.java +++ b/src/ooxml/testcases/org/apache/poi/ss/usermodel/TestEmbedOLEPackage.java @@ -17,10 +17,11 @@ package org.apache.poi.ss.usermodel; +import static org.apache.poi.sl.SLCommonUtils.xslfOnly; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -import static org.junit.Assume.assumeTrue; +import static org.junit.Assume.assumeFalse; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -48,7 +49,7 @@ public class TestEmbedOLEPackage { private static byte[] samplePPT, samplePPTX, samplePNG; @BeforeClass - public static void init() throws IOException { + public static void init() throws IOException, ReflectiveOperationException { samplePPT = getSamplePPT(false); samplePPTX = getSamplePPT(true); samplePNG = POIDataSamples.getSpreadSheetInstance().readFile("logoKarmokar4.png"); @@ -68,11 +69,7 @@ public class TestEmbedOLEPackage { @Test public void embedHSSF() throws IOException { - try { - Class.forName("org.apache.poi.hslf.usermodel.HSLFSlideShow"); - } catch (Exception e) { - assumeTrue(false); - } + assumeFalse(xslfOnly()); Workbook wb1 = new HSSFWorkbook(); addEmbeddedObjects(wb1); @@ -124,8 +121,9 @@ public class TestEmbedOLEPackage { pat2.createObjectData(anchor2, oleIdx2, picIdx); } - static byte[] getSamplePPT(boolean ooxml) throws IOException { - SlideShow<?,?> ppt = (ooxml) ? new XMLSlideShow() : new org.apache.poi.hslf.usermodel.HSLFSlideShow(); + static byte[] getSamplePPT(boolean ooxml) throws IOException, ReflectiveOperationException { + SlideShow<?,?> ppt = (ooxml) ? new XMLSlideShow() + : (SlideShow<?,?>)Class.forName("org.apache.poi.hslf.usermodel.HSLFSlideShow").newInstance(); Slide<?,?> slide = ppt.createSlide(); AutoShape<?,?> sh1 = slide.createAutoShape(); 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; @@ -94,6 +89,25 @@ 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/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextShape.java b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextShape.java index a67d4bef93..0d2c94999b 100644 --- a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextShape.java +++ b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextShape.java @@ -17,6 +17,7 @@ package org.apache.poi.xslf.usermodel; import static org.apache.poi.sl.TestCommonSL.sameColor; +import static org.apache.poi.xslf.usermodel.TestXSLFSimpleShape.getSpPr; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; @@ -24,7 +25,6 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import static org.junit.Assume.assumeFalse; -import static org.apache.poi.xslf.usermodel.TestXSLFSimpleShape.getSpPr; import java.awt.Color; import java.io.File; @@ -33,8 +33,8 @@ import java.util.List; import java.util.stream.Collectors; import org.apache.poi.POIDataSamples; -import org.apache.poi.hslf.usermodel.HSLFTextShape; import org.apache.poi.sl.usermodel.Placeholder; +import org.apache.poi.sl.usermodel.Shape; import org.apache.poi.sl.usermodel.SlideShow; import org.apache.poi.sl.usermodel.SlideShowFactory; import org.apache.poi.sl.usermodel.TextParagraph.TextAlign; @@ -950,12 +950,12 @@ public class TestXSLFTextShape { } @Test - public void metroBlob() throws IOException { + public void metroBlob() throws IOException, ReflectiveOperationException { assumeFalse(xslfOnly); File f = POIDataSamples.getSlideShowInstance().getFile("bug52297.ppt"); SlideShow<?,?> ppt = SlideShowFactory.create(f); - HSLFTextShape sh = (HSLFTextShape)ppt.getSlides().get(1).getShapes().get(3); - XSLFAutoShape xsh = (XSLFAutoShape)sh.getMetroShape(); + Shape<?, ?> sh = ppt.getSlides().get(1).getShapes().get(3); + XSLFAutoShape xsh = (XSLFAutoShape)sh.getClass().getMethod("getMetroShape").invoke(sh); String textExp = " ___ ___ ___ ________ __ _______ ___ ___________ __________ __ _____ ___ ___ ___ _______ ____ ______ ___________ _____________ ___ _______ ______ ____ ______ __ ___________ __________ ___ _________ _____ ________ __________ ___ _______ __________ "; String textAct = xsh.getText(); ppt.close(); 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!"); + } } 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(); - - XSSFHeaderFooterProperties hfProp = sh.getHeaderFooterProperties(); - assertNotNull(hfProp); + try (XSSFWorkbook wb = new XSSFWorkbook()) { + XSSFSheet sh = wb.createSheet(); - 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..b004319426 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,47 @@ 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("A1:C3", table1.getCTTable().getRef()); + + 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); + assertEquals("K11:M13", table2.getCTTable().getRef()); + + // 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()); + + 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 +398,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 +412,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) diff --git a/src/scratchpad/src/org/apache/poi/extractor/ole2/OLE2ScratchpadExtractorFactory.java b/src/scratchpad/src/org/apache/poi/extractor/ole2/OLE2ScratchpadExtractorFactory.java index 3201f633e6..3764c59664 100644 --- a/src/scratchpad/src/org/apache/poi/extractor/ole2/OLE2ScratchpadExtractorFactory.java +++ b/src/scratchpad/src/org/apache/poi/extractor/ole2/OLE2ScratchpadExtractorFactory.java @@ -32,6 +32,7 @@ import org.apache.poi.hslf.usermodel.HSLFSlideShow; import org.apache.poi.hsmf.MAPIMessage; import org.apache.poi.hsmf.datatypes.AttachmentChunks; import org.apache.poi.hsmf.extractor.OutlookTextExtactor; +import org.apache.poi.hssf.extractor.ExcelExtractor; import org.apache.poi.hwpf.OldWordFileFormatException; import org.apache.poi.hwpf.extractor.Word6Extractor; import org.apache.poi.hwpf.extractor.WordExtractor; @@ -40,6 +41,8 @@ import org.apache.poi.poifs.filesystem.DirectoryNode; import org.apache.poi.poifs.filesystem.Entry; import org.apache.poi.sl.extractor.SlideShowExtractor; import org.apache.poi.sl.usermodel.SlideShowFactory; +import org.apache.poi.util.POILogFactory; +import org.apache.poi.util.POILogger; /** * Scratchpad-specific logic for {@link OLE2ExtractorFactory} and @@ -50,6 +53,8 @@ import org.apache.poi.sl.usermodel.SlideShowFactory; */ @SuppressWarnings("WeakerAccess") public class OLE2ScratchpadExtractorFactory { + private static final POILogger logger = POILogFactory.getLogger(OLE2ScratchpadExtractorFactory.class); + /** * Look for certain entries in the stream, to figure it * out what format is desired @@ -125,7 +130,16 @@ public class OLE2ScratchpadExtractorFactory { throw new IllegalStateException("The extractor didn't know which POIFS it came from!"); } - if (ext instanceof WordExtractor) { + if (ext instanceof ExcelExtractor) { + // These are in MBD... under the root + Iterator<Entry> it = root.getEntries(); + while (it.hasNext()) { + Entry entry = it.next(); + if (entry.getName().startsWith("MBD")) { + dirs.add(entry); + } + } + } else if (ext instanceof WordExtractor) { // These are in ObjectPool -> _... under the root try { DirectoryEntry op = (DirectoryEntry) @@ -138,6 +152,7 @@ public class OLE2ScratchpadExtractorFactory { } } } catch(FileNotFoundException e) { + logger.log(POILogger.INFO, "Ignoring FileNotFoundException while extracting Word document", e.getLocalizedMessage()); // ignored here } //} else if(ext instanceof PowerPointExtractor) { 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/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<Attachment> 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/scratchpad/testcases/org/apache/poi/hslf/model/TestHeadersFooters.java b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestHeadersFooters.java index 333b7a829f..66795b5f1a 100644 --- a/src/scratchpad/testcases/org/apache/poi/hslf/model/TestHeadersFooters.java +++ b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestHeadersFooters.java @@ -30,6 +30,12 @@ import org.apache.poi.POIDataSamples; import org.apache.poi.hslf.HSLFTestDataSamples; import org.apache.poi.hslf.usermodel.HSLFSlide; import org.apache.poi.hslf.usermodel.HSLFSlideShow; +import org.apache.poi.hslf.usermodel.HSLFTextParagraph; +import org.apache.poi.sl.usermodel.Shape; +import org.apache.poi.sl.usermodel.Slide; +import org.apache.poi.sl.usermodel.SlideShow; +import org.apache.poi.sl.usermodel.TextParagraph; +import org.apache.poi.sl.usermodel.TextShape; import org.junit.Test; /** @@ -228,4 +234,45 @@ public final class TestHeadersFooters ppt2.close(); ppt1.close(); } + @Test + public void bug58144a() throws IOException { + try (InputStream is = _slTests.openResourceAsStream("bug58144-headers-footers-2003.ppt"); + SlideShow<?,?> ppt = new HSLFSlideShow(is)) { + HSLFSlide sl = (HSLFSlide) ppt.getSlides().get(0); + HeadersFooters hfs = sl.getHeadersFooters(); + assertNull(hfs.getHeaderText()); + assertEquals("Confidential", hfs.getFooterText()); + List<List<HSLFTextParagraph>> llp = sl.getTextParagraphs(); + assertEquals("Test", HSLFTextParagraph.getText(llp.get(0))); + assertFalse(llp.get(0).get(0).isHeaderOrFooter()); + } + } + + @Test + public void bug58144b() throws IOException { + try (InputStream is = _slTests.openResourceAsStream("bug58144-headers-footers-2007.ppt"); + SlideShow<?,?> ppt = new HSLFSlideShow(is)) { + Slide<?, ?> sl = ppt.getSlides().get(0); + HeadersFooters hfs2 = ((HSLFSlide) sl).getHeadersFooters(); + assertNull(hfs2.getHeaderText()); + assertEquals("Slide footer", hfs2.getFooterText()); + + testSlideShow(ppt); + } + } + + // copied from org.apache.poi.sl.TestHeadersFooters because of scratchpad.ignore option + private void testSlideShow(SlideShow<?,?> ppt) { + Slide<?,?> sl = ppt.getSlides().get(0); + + List<? extends Shape<?,?>> shapes = sl.getShapes(); + TextShape<?,?> ts0 = (TextShape<?,?>)shapes.get(0); + assertEquals("Test file", ts0.getText()); + TextShape<?,?> ts1 = (TextShape<?,?>)shapes.get(1); + assertEquals("Has some text in the headers and footers", ts1.getText()); + TextShape<?,?> ts2 = (TextShape<?,?>)shapes.get(2); + assertEquals("Slide footer", ts2.getText()); + List<? extends TextParagraph<?,?,?>> ltp = ts2.getTextParagraphs(); + assertTrue(ltp.get(0).isHeaderOrFooter()); + } } 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. diff --git a/src/java/org/apache/poi/hssf/usermodel/DummyGraphics2d.java b/src/testcases/org/apache/poi/hssf/usermodel/DummyGraphics2d.java index 093d2083a8..093d2083a8 100644 --- a/src/java/org/apache/poi/hssf/usermodel/DummyGraphics2d.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/DummyGraphics2d.java diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFPictureData.java b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFPictureData.java index 5326e759d9..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,6 +28,7 @@ import javax.imageio.ImageIO; import junit.framework.TestCase; import org.apache.poi.hssf.HSSFTestDataSamples; +import org.junit.BeforeClass; /** * Test <code>HSSFPictureData</code>. @@ -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() { + 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 { 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); } } - } diff --git a/src/testcases/org/apache/poi/ss/usermodel/TestExcelStyleDateFormatter.java b/src/testcases/org/apache/poi/ss/usermodel/TestExcelStyleDateFormatter.java index f4e61801a5..b7fd43e367 100644 --- a/src/testcases/org/apache/poi/ss/usermodel/TestExcelStyleDateFormatter.java +++ b/src/testcases/org/apache/poi/ss/usermodel/TestExcelStyleDateFormatter.java @@ -18,124 +18,122 @@ 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; 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<Locale, List<String>> testMap = initializeLocales(); + public void test60369() { + Map<Locale, String> testMap = initializeLocales(); // We have to set up dates as well. - SimpleDateFormat testDateFormat = new SimpleDateFormat("dd.MM.yyyy", Locale.ROOT); - List<Date> 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<Date> 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<Locale,String> 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 = localeIndex(locale); + + assertNotNull(msg, result); + assertTrue(msg, result.length() > actIdx); + assertEquals(msg, expected.charAt(month), result.charAt(actIdx)); + month++; } } } - private Map<Locale, List<String>> 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<String> germanResultList = Arrays.asList("\u004a", "\u0046", "\u004d", "\u0041", "\u004d", - "\u004a", "\u004a", "\u0041", "\u0053", "\u004f", "\u004e", "\u0044"); - - Locale russianLocale = new Locale("ru", "RU"); - List<String> russianResultList = Arrays.asList("\u044f", "\u0444", "\u043c", "\u0430", "\u043c", - "\u0438", "\u0438", "\u0430", "\u0441", "\u043e", "\u043d", "\u0434"); - - Locale austrianLocale = new Locale("de", "AT"); - List<String> austrianResultList = Arrays.asList("\u004a", "\u0046", "\u004d", "\u0041", "\u004d", - "\u004a", "\u004a", "\u0041", "\u0053", "\u004f", "\u004e", "\u0044"); - - Locale englishLocale = Locale.UK; - List<String> englishResultList = Arrays.asList("\u004a", "\u0046", "\u004d", "\u0041", "\u004d", - "\u004a", "\u004a", "\u0041", "\u0053", "\u004f", "\u004e", "\u0044"); - - Locale frenchLocale = Locale.FRENCH; - List<String> frenchResultList = Arrays.asList("\u006a", "\u0066", "\u006d", "\u0061", "\u006d", - "\u006a", "\u006a", "\u0061", "\u0073", "\u006f", "\u006e", "\u0064"); - - Locale chineseLocale = Locale.CHINESE; - List<String> chineseResultList = Arrays.asList("\u4e00", "\u4e8c", "\u4e09", "\u56db", "\u4e94", - "\u516d", "\u4e03", "\u516b", "\u4e5d", "\u5341", "\u5341", "\u5341"); - - Locale turkishLocale = new Locale("tr", "TR"); - List<String> turkishResultList = Arrays.asList("\u004f", "\u015e", "\u004d", "\u004e", "\u004d", - "\u0048", "\u0054", "\u0041", "\u0045", "\u0045", "\u004b", "\u0041"); - - Locale hungarianLocale = new Locale("hu", "HU"); - List<String> hungarianResultList = Arrays.asList("\u006a", "\u0066", "\u006d", "\u00e1", "\u006d", - "\u006a", "\u006a", "\u0061", "\u0073", "\u006f", "\u006e", "\u0064"); - - Locale indianLocale = new Locale("en", "IN"); - List<String> indianResultList = Arrays.asList("\u004a", "\u0046", "\u004d", "\u0041", "\u004d", - "\u004a", "\u004a", "\u0041", "\u0053", "\u004f", "\u004e", "\u0044"); - - Locale indonesianLocale = new Locale("in", "ID"); - List<String> indonesianResultList = Arrays.asList("\u004a", "\u0046", "\u004d", "\u0041", "\u004d", - "\u004a", "\u004a", "\u0041", "\u0053", "\u004f", "\u004e", "\u0044"); - - - Map<Locale, List<String>> 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); + /** + * 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; + } - 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<Locale, String> initializeLocales() { + Map<Locale, String> 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, 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"); + + testMap.put(new Locale("hu", "HU"), + "\u006a\u0066\u006d\u00e1\u006d\u006a\u006a\u0061\u0073\u006f\u006e\u0064"); + + return testMap; } @Test @@ -150,7 +148,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 +158,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); } } |