diff --git a/build.xml b/build.xml index d7162c29c..7cf2c3a43 100644 --- a/build.xml +++ b/build.xml @@ -1950,6 +1950,7 @@ under the License. + @@ -2112,6 +2113,7 @@ under the License. sonar/*/src/**, compile-lib/**, ooxml-lib/**, + ooxml-testlib/**, scripts/**, TEST*, *.ipr, @@ -2452,7 +2454,7 @@ under the License. - + diff --git a/sonar/examples/pom.xml b/sonar/examples/pom.xml index 441dfad7a..22c576a20 100644 --- a/sonar/examples/pom.xml +++ b/sonar/examples/pom.xml @@ -6,7 +6,7 @@ org.apache.poi poi-parent - 4.0.1-SNAPSHOT + 4.0.2-SNAPSHOT poi-examples jar diff --git a/sonar/excelant/pom.xml b/sonar/excelant/pom.xml index b9814037f..220d4eb1e 100644 --- a/sonar/excelant/pom.xml +++ b/sonar/excelant/pom.xml @@ -6,7 +6,7 @@ org.apache.poi poi-parent - 4.0.1-SNAPSHOT + 4.0.2-SNAPSHOT poi-excelant jar diff --git a/sonar/main/pom.xml b/sonar/main/pom.xml index b4ed72f4a..9bd0af96a 100644 --- a/sonar/main/pom.xml +++ b/sonar/main/pom.xml @@ -6,7 +6,7 @@ org.apache.poi poi-parent - 4.0.1-SNAPSHOT + 4.0.2-SNAPSHOT poi-main jar diff --git a/sonar/ooxml-schema-encryption/pom.xml b/sonar/ooxml-schema-encryption/pom.xml index 5b2489a7b..d768a5f4b 100644 --- a/sonar/ooxml-schema-encryption/pom.xml +++ b/sonar/ooxml-schema-encryption/pom.xml @@ -6,7 +6,7 @@ org.apache.poi poi-parent - 4.0.1-SNAPSHOT + 4.0.2-SNAPSHOT .. poi-ooxml-schema-encryption diff --git a/sonar/ooxml-schema-security/pom.xml b/sonar/ooxml-schema-security/pom.xml index d872d9b59..06318b2be 100644 --- a/sonar/ooxml-schema-security/pom.xml +++ b/sonar/ooxml-schema-security/pom.xml @@ -6,7 +6,7 @@ org.apache.poi poi-parent - 4.0.1-SNAPSHOT + 4.0.2-SNAPSHOT .. poi-ooxml-schema-security diff --git a/sonar/ooxml-schema/pom.xml b/sonar/ooxml-schema/pom.xml index 92c2e264a..7bb69433d 100644 --- a/sonar/ooxml-schema/pom.xml +++ b/sonar/ooxml-schema/pom.xml @@ -6,7 +6,7 @@ org.apache.poi poi-parent - 4.0.1-SNAPSHOT + 4.0.2-SNAPSHOT .. poi-ooxml-schema diff --git a/sonar/ooxml/pom.xml b/sonar/ooxml/pom.xml index fad8ac564..dc4ffc837 100644 --- a/sonar/ooxml/pom.xml +++ b/sonar/ooxml/pom.xml @@ -6,7 +6,7 @@ org.apache.poi poi-parent - 4.0.1-SNAPSHOT + 4.0.2-SNAPSHOT poi-ooxml jar diff --git a/sonar/pom.xml b/sonar/pom.xml index 87c2daf37..3fcaf93e5 100644 --- a/sonar/pom.xml +++ b/sonar/pom.xml @@ -4,7 +4,7 @@ org.apache.poi poi-parent pom - 4.0.1-SNAPSHOT + 4.0.2-SNAPSHOT Apache POI - the Java API for Microsoft Documents Maven build of Apache POI for Sonar checks http://poi.apache.org/ diff --git a/sonar/scratchpad/pom.xml b/sonar/scratchpad/pom.xml index e7ef7303a..a980e1556 100644 --- a/sonar/scratchpad/pom.xml +++ b/sonar/scratchpad/pom.xml @@ -6,7 +6,7 @@ org.apache.poi poi-parent - 4.0.1-SNAPSHOT + 4.0.2-SNAPSHOT poi-scratchpad jar diff --git a/src/integrationtest/org/apache/poi/TestAllFiles.java b/src/integrationtest/org/apache/poi/TestAllFiles.java index 61c47b9e8..40f19f9c8 100644 --- a/src/integrationtest/org/apache/poi/TestAllFiles.java +++ b/src/integrationtest/org/apache/poi/TestAllFiles.java @@ -289,6 +289,7 @@ public class TestAllFiles { "document/Bug50955.doc", "document/57843.doc", "slideshow/PPT95.ppt", + "slideshow/pp40only.ppt", "slideshow/Divino_Revelado.pptx", "openxml4j/OPCCompliance_CoreProperties_DCTermsNamespaceLimitedUseFAIL.docx", "openxml4j/OPCCompliance_CoreProperties_DoNotUseCompatibilityMarkupFAIL.docx", diff --git a/src/integrationtest/org/apache/poi/stress/XSSFFileHandler.java b/src/integrationtest/org/apache/poi/stress/XSSFFileHandler.java index 5c47d9af7..48a30a256 100644 --- a/src/integrationtest/org/apache/poi/stress/XSSFFileHandler.java +++ b/src/integrationtest/org/apache/poi/stress/XSSFFileHandler.java @@ -35,7 +35,6 @@ import java.util.Iterator; import java.util.Locale; import java.util.Set; -import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.TransformerException; import org.apache.poi.EncryptedDocumentException; @@ -148,7 +147,7 @@ public class XSSFFileHandler extends SpreadsheetHandler { } private void exportToXML(XSSFWorkbook wb) throws SAXException, - ParserConfigurationException, TransformerException { + TransformerException { for (XSSFMap map : wb.getCustomXMLMappings()) { XSSFExportToXml exporter = new XSSFExportToXml(map); @@ -165,7 +164,6 @@ public class XSSFFileHandler extends SpreadsheetHandler { // zip-bomb EXPECTED_ADDITIONAL_FAILURES.add("spreadsheet/54764.xlsx"); EXPECTED_ADDITIONAL_FAILURES.add("spreadsheet/54764-2.xlsx"); - EXPECTED_ADDITIONAL_FAILURES.add("spreadsheet/54764.xlsx"); EXPECTED_ADDITIONAL_FAILURES.add("spreadsheet/poc-xmlbomb.xlsx"); EXPECTED_ADDITIONAL_FAILURES.add("spreadsheet/poc-xmlbomb-empty.xlsx"); // strict OOXML @@ -185,18 +183,19 @@ public class XSSFFileHandler extends SpreadsheetHandler { public void handleAdditional(File file) throws Exception { // redirect stdout as the examples often write lots of text PrintStream oldOut = System.out; + String testFile = file.getParentFile().getName() + "/" + file.getName(); try { System.setOut(new NullPrintStream()); FromHowTo.main(new String[]{file.getAbsolutePath()}); XLSX2CSV.main(new String[]{file.getAbsolutePath()}); assertFalse("Expected Extraction to fail for file " + file + " and handler " + this + ", but did not fail!", - EXPECTED_ADDITIONAL_FAILURES.contains(file.getParentFile().getName() + "/" + file.getName())); + EXPECTED_ADDITIONAL_FAILURES.contains(testFile)); } catch (OLE2NotOfficeXmlFileException e) { // we have some files that are not actually OOXML and thus cannot be tested here } catch (IllegalArgumentException | InvalidFormatException | POIXMLException | IOException e) { - if(!EXPECTED_ADDITIONAL_FAILURES.contains(file.getParentFile().getName() + "/" + file.getName())) { + if(!EXPECTED_ADDITIONAL_FAILURES.contains(testFile)) { throw e; } } finally { diff --git a/src/java/org/apache/poi/hpsf/VariantSupport.java b/src/java/org/apache/poi/hpsf/VariantSupport.java index e60679027..0e8dc08c6 100644 --- a/src/java/org/apache/poi/hpsf/VariantSupport.java +++ b/src/java/org/apache/poi/hpsf/VariantSupport.java @@ -36,7 +36,7 @@ import org.apache.poi.util.POILogger; * Supports reading and writing of variant data.

* * FIXME (3): Reading and writing should be made more - * uniform than it is now. The following items should be resolved:

+ * uniform than it is now. The following items should be resolved: * *

    * diff --git a/src/java/org/apache/poi/hpsf/wellknown/PropertyIDMap.java b/src/java/org/apache/poi/hpsf/wellknown/PropertyIDMap.java index 130408e7b..c01ded7fe 100644 --- a/src/java/org/apache/poi/hpsf/wellknown/PropertyIDMap.java +++ b/src/java/org/apache/poi/hpsf/wellknown/PropertyIDMap.java @@ -33,8 +33,11 @@ import org.apache.poi.hpsf.SummaryInformation; * The methods {@link #getSummaryInformationProperties} and {@link * #getDocumentSummaryInformationProperties} return singleton {@link * PropertyIDMap}s. An application that wants to extend these maps - * should treat them as unmodifiable, copy them and modifiy the + * should treat them as unmodifiable, copy them and modify the * copies. + * + * Trying to modify the map directly will cause exceptions + * {@link UnsupportedOperationException} to be thrown. */ public class PropertyIDMap implements Map { @@ -490,11 +493,13 @@ public class PropertyIDMap implements Map { @Override public String put(Long key, String value) { + //noinspection ConstantConditions return idMap.put(key, value); } @Override public String remove(Object key) { + //noinspection ConstantConditions return idMap.remove(key); } diff --git a/src/java/org/apache/poi/hssf/model/InternalWorkbook.java b/src/java/org/apache/poi/hssf/model/InternalWorkbook.java index 46d867822..4ff370125 100644 --- a/src/java/org/apache/poi/hssf/model/InternalWorkbook.java +++ b/src/java/org/apache/poi/hssf/model/InternalWorkbook.java @@ -2276,6 +2276,8 @@ public final class InternalWorkbook { /** * Only for internal calls - code based on this is not supported ... + * + * @return The list of records. */ @Internal public WorkbookRecordList getWorkbookRecordList() { diff --git a/src/java/org/apache/poi/hssf/record/RecordInputStream.java b/src/java/org/apache/poi/hssf/record/RecordInputStream.java index 4f5f58903..8347655a8 100644 --- a/src/java/org/apache/poi/hssf/record/RecordInputStream.java +++ b/src/java/org/apache/poi/hssf/record/RecordInputStream.java @@ -33,8 +33,9 @@ import org.apache.poi.util.LittleEndianInputStream; import org.apache.poi.util.RecordFormatException; /** - * Title: Record Input Stream

    - * Description: Wraps a stream and provides helper methods for the construction of records.

    + * Title: Record Input Stream + * + * Description: Wraps a stream and provides helper methods for the construction of records. */ public final class RecordInputStream implements LittleEndianInput { @@ -194,11 +195,11 @@ public final class RecordInputStream implements LittleEndianInput { private int readNextSid() { int nAvailable = _bhi.available(); if (nAvailable < EOFRecord.ENCODED_SIZE) { - if (nAvailable > 0) { + /*if (nAvailable > 0) { // some scrap left over? // ex45582-22397.xls has one extra byte after the last record // Excel reads that file OK - } + }*/ return INVALID_SID_VALUE; } int result = _bhi.readRecordSID(); @@ -305,14 +306,13 @@ public final class RecordInputStream implements LittleEndianInput { @Override public double readDouble() { long valueLongBits = readLong(); - double result = Double.longBitsToDouble(valueLongBits); - if (Double.isNaN(result)) { + /*if (Double.isNaN(result)) { // YK: Excel doesn't write NaN but instead converts the cell type into {@link CellType#ERROR}. // HSSF prior to version 3.7 had a bug: it could write Double.NaN but could not read such a file back. // This behavior was fixed in POI-3.7. //throw new RuntimeException("Did not expect to read NaN"); // (Because Excel typically doesn't write NaN) - } - return result; + }*/ + return Double.longBitsToDouble(valueLongBits); } public void readPlain(byte[] buf, int off, int len) { diff --git a/src/java/org/apache/poi/hssf/record/SSTRecord.java b/src/java/org/apache/poi/hssf/record/SSTRecord.java index 20d99319d..1de2fe4fc 100644 --- a/src/java/org/apache/poi/hssf/record/SSTRecord.java +++ b/src/java/org/apache/poi/hssf/record/SSTRecord.java @@ -161,7 +161,7 @@ public final class SSTRecord extends ContinuableRecord { *

    * The data consists of sets of string data. This string data is * arranged as follows: - *

    + *

    *

          * short  string_length;   // length of string data
          * byte   string_flag;     // flag specifying special string
    @@ -176,9 +176,9 @@ public final class SSTRecord extends ContinuableRecord {
          * byte[] extension;       // optional extension (length of array
          *                         // is extend_length)
          * 
    - *

    + *

    * The string_flag is bit mapped as follows: - *

    + *

    * * * @@ -232,7 +232,7 @@ public final class SSTRecord extends ContinuableRecord { * associated data. The UnicodeString class can handle the byte[] * vs short[] nature of the actual string data * - * @param in the RecordInputstream to read the record from + * @param in the RecordInputStream to read the record from */ public SSTRecord(RecordInputStream in) { // this method is ALWAYS called after construction -- using diff --git a/src/java/org/apache/poi/hssf/record/SharedFormulaRecord.java b/src/java/org/apache/poi/hssf/record/SharedFormulaRecord.java index 770f740a0..328402db8 100644 --- a/src/java/org/apache/poi/hssf/record/SharedFormulaRecord.java +++ b/src/java/org/apache/poi/hssf/record/SharedFormulaRecord.java @@ -77,7 +77,7 @@ public final class SharedFormulaRecord extends SharedValueRecordBase { public String toString() { - StringBuffer buffer = new StringBuffer(); + StringBuilder buffer = new StringBuilder(); buffer.append("[SHARED FORMULA (").append(HexDump.intToHex(sid)).append("]\n"); buffer.append(" .range = ").append(getRange()).append("\n"); @@ -99,6 +99,10 @@ public final class SharedFormulaRecord extends SharedValueRecordBase { } /** + * Convert formula into an array of {@link Ptg} tokens. + * + * @param formula The record to break into tokens, cannot be null + * * @return the equivalent {@link Ptg} array that the formula would have, were it not shared. */ public Ptg[] getFormulaTokens(FormulaRecord formula) { diff --git a/src/java/org/apache/poi/hssf/record/SharedValueRecordBase.java b/src/java/org/apache/poi/hssf/record/SharedValueRecordBase.java index a5035303a..51fe09180 100644 --- a/src/java/org/apache/poi/hssf/record/SharedValueRecordBase.java +++ b/src/java/org/apache/poi/hssf/record/SharedValueRecordBase.java @@ -42,6 +42,8 @@ public abstract class SharedValueRecordBase extends StandardRecord { /** * reads only the range (1 {@link CellRangeAddress8Bit}) from the stream + * + * @param in The interface for reading the record data. */ public SharedValueRecordBase(LittleEndianInput in) { _range = new CellRangeAddress8Bit(in); @@ -99,14 +101,12 @@ public abstract class SharedValueRecordBase extends StandardRecord { && r.getLastColumn() >= colIx; } /** - * @return {@code true} if (rowIx, colIx) describes the first cell in this shared value - * object's range - * * @param rowIx the row index * @param colIx the column index - * - * @return {@code true} if its the first cell in this shared value object range - * + * + * @return {@code true} if (rowIx, colIx) describes the first cell in this shared value + * object's range + * * @see #getRange() */ public final boolean isFirstCell(int rowIx, int colIx) { diff --git a/src/java/org/apache/poi/poifs/filesystem/FileMagic.java b/src/java/org/apache/poi/poifs/filesystem/FileMagic.java index 4ac616082..bab62c643 100644 --- a/src/java/org/apache/poi/poifs/filesystem/FileMagic.java +++ b/src/java/org/apache/poi/poifs/filesystem/FileMagic.java @@ -78,7 +78,7 @@ public enum FileMagic { /** PDF document */ PDF("%PDF"), /** Some different HTML documents */ - HTML(" diff --git a/src/java/org/apache/poi/sl/draw/DrawPaint.java b/src/java/org/apache/poi/sl/draw/DrawPaint.java index d6986f302..a83060538 100644 --- a/src/java/org/apache/poi/sl/draw/DrawPaint.java +++ b/src/java/org/apache/poi/sl/draw/DrawPaint.java @@ -29,7 +29,10 @@ import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.io.IOException; import java.io.InputStream; +import java.util.Map; import java.util.Objects; +import java.util.TreeMap; +import java.util.function.BiFunction; import org.apache.poi.sl.usermodel.AbstractColorStyle; import org.apache.poi.sl.usermodel.ColorStyle; @@ -197,28 +200,17 @@ public class DrawPaint { @Override public int getShade() { - int shade = orig.getShade(); - switch (modifier) { - case DARKEN: - return Math.min(100000, Math.max(0,shade)+40000); - case DARKEN_LESS: - return Math.min(100000, Math.max(0,shade)+20000); - default: - return shade; - } + return scale(orig.getShade(), PaintModifier.DARKEN_LESS, PaintModifier.DARKEN); } @Override public int getTint() { - int tint = orig.getTint(); - switch (modifier) { - case LIGHTEN: - return Math.min(100000, Math.max(0,tint)+40000); - case LIGHTEN_LESS: - return Math.min(100000, Math.max(0,tint)+20000); - default: - return tint; - } + return scale(orig.getTint(), PaintModifier.LIGHTEN_LESS, PaintModifier.LIGHTEN); + } + + private int scale(int value, PaintModifier lessModifier, PaintModifier moreModifier) { + int delta = (modifier == lessModifier ? 20000 : (modifier == moreModifier ? 40000 : 0)); + return Math.min(100000, Math.max(0,value)+delta); } }; @@ -300,7 +292,7 @@ public class DrawPaint { Color result = color.getColor(); double alpha = getAlpha(result, color); - double hsl[] = RGB2HSL(result); // values are in the range [0..100] (usually ...) + double[] hsl = RGB2HSL(result); // values are in the range [0..100] (usually ...) applyHslModOff(hsl, 0, color.getHueMod(), color.getHueOff()); applyHslModOff(hsl, 1, color.getSatMod(), color.getSatOff()); applyHslModOff(hsl, 2, color.getLumMod(), color.getLumOff()); @@ -344,7 +336,7 @@ public class DrawPaint { * @param mod the modulation adjustment * @param off the offset adjustment */ - private static void applyHslModOff(double hsl[], int hslPart, int mod, int off) { + private static void applyHslModOff(double[] hsl, int hslPart, int mod, int off) { if (mod == -1) { mod = 100000; } @@ -363,7 +355,7 @@ public class DrawPaint { * * For a shade, the equation is luminance * %tint. */ - private static void applyShade(double hsl[], ColorStyle fc) { + private static void applyShade(double[] hsl, ColorStyle fc) { int shade = fc.getShade(); if (shade == -1) { return; @@ -380,7 +372,7 @@ public class DrawPaint { * For a tint, the equation is luminance * %tint + (1-%tint). * (Note that 1-%tint is equal to the lumOff value in DrawingML.) */ - private static void applyTint(double hsl[], ColorStyle fc) { + private static void applyTint(double[] hsl, ColorStyle fc) { int tint = fc.getTint(); if (tint == -1) { return; @@ -403,70 +395,63 @@ public class DrawPaint { } Rectangle2D anchor = DrawShape.getAnchor(graphics, shape); - final double h = anchor.getHeight(), w = anchor.getWidth(), x = anchor.getX(), y = anchor.getY(); AffineTransform at = AffineTransform.getRotateInstance(Math.toRadians(angle), anchor.getCenterX(), anchor.getCenterY()); - double diagonal = Math.sqrt(h * h + w * w); - Point2D p1 = new Point2D.Double(x + w / 2 - diagonal / 2, y + h / 2); - p1 = at.transform(p1, null); - - Point2D p2 = new Point2D.Double(x + w, y + h / 2); - p2 = at.transform(p2, null); + double diagonal = Math.sqrt(Math.pow(anchor.getWidth(),2) + Math.pow(anchor.getHeight(),2)); + final Point2D p1 = at.transform(new Point2D.Double(anchor.getCenterX() - diagonal / 2, anchor.getCenterY()), null); + final Point2D p2 = at.transform(new Point2D.Double(anchor.getMaxX(), anchor.getCenterY()), null); // snapToAnchor(p1, anchor); // snapToAnchor(p2, anchor); - if (p1.equals(p2)) { - // gradient paint on the same point throws an exception ... and doesn't make sense - return null; - } - - float[] fractions = fill.getGradientFractions(); - Color[] colors = new Color[fractions.length]; - - int i = 0; - for (ColorStyle fc : fill.getGradientColors()) { - // if fc is null, use transparent color to get color of background - colors[i++] = (fc == null) ? TRANSPARENT : applyColorTransform(fc); - } - - return new LinearGradientPaint(p1, p2, fractions, colors); + // gradient paint on the same point throws an exception ... and doesn't make sense + return (p1.equals(p2)) ? null : safeFractions((f,c)->new LinearGradientPaint(p1,p2,f,c), fill); } + @SuppressWarnings("WeakerAccess") protected Paint createRadialGradientPaint(GradientPaint fill, Graphics2D graphics) { Rectangle2D anchor = DrawShape.getAnchor(graphics, shape); - Point2D pCenter = new Point2D.Double(anchor.getX() + anchor.getWidth()/2, - anchor.getY() + anchor.getHeight()/2); + final Point2D pCenter = new Point2D.Double(anchor.getCenterX(), anchor.getCenterY()); - float radius = (float)Math.max(anchor.getWidth(), anchor.getHeight()); + final float radius = (float)Math.max(anchor.getWidth(), anchor.getHeight()); - float[] fractions = fill.getGradientFractions(); - Color[] colors = new Color[fractions.length]; - - int i=0; - for (ColorStyle fc : fill.getGradientColors()) { - colors[i++] = applyColorTransform(fc); - } - - return new RadialGradientPaint(pCenter, radius, fractions, colors); + return safeFractions((f,c)->new RadialGradientPaint(pCenter,radius,f,c), fill); } @SuppressWarnings({"WeakerAccess", "unused"}) protected Paint createPathGradientPaint(GradientPaint fill, Graphics2D graphics) { // currently we ignore an eventually center setting - float[] fractions = fill.getGradientFractions(); - Color[] colors = new Color[fractions.length]; + return safeFractions(PathGradientPaint::new, fill); + } - int i=0; - for (ColorStyle fc : fill.getGradientColors()) { - colors[i++] = applyColorTransform(fc); + private Paint safeFractions(BiFunction init, GradientPaint fill) { + float[] fractions = fill.getGradientFractions(); + final ColorStyle[] styles = fill.getGradientColors(); + + // need to remap the fractions, because Java doesn't like repeating fraction values + Map m = new TreeMap<>(); + for (int i = 0; i me : m.entrySet()) { + fractions[i] = me.getKey(); + colors[i] = me.getValue(); + i++; + } + + return init.apply(fractions, colors); } /** diff --git a/src/java/org/apache/poi/sl/draw/PathGradientPaint.java b/src/java/org/apache/poi/sl/draw/PathGradientPaint.java index d4a2a5fa5..2281bbff8 100644 --- a/src/java/org/apache/poi/sl/draw/PathGradientPaint.java +++ b/src/java/org/apache/poi/sl/draw/PathGradientPaint.java @@ -23,21 +23,24 @@ import java.awt.MultipleGradientPaint.CycleMethod; import java.awt.geom.*; import java.awt.image.*; +import org.apache.poi.util.Internal; + +@Internal class PathGradientPaint implements Paint { // http://asserttrue.blogspot.de/2010/01/how-to-iimplement-custom-paint-in-50.html - protected final Color colors[]; - protected final float fractions[]; - protected final int capStyle; - protected final int joinStyle; - protected final int transparency; + private final Color[] colors; + private final float[] fractions; + private final int capStyle; + private final int joinStyle; + private final int transparency; - public PathGradientPaint(Color colors[], float fractions[]) { - this(colors,fractions,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND); + PathGradientPaint(float[] fractions, Color[] colors) { + this(fractions,colors,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND); } - public PathGradientPaint(Color colors[], float fractions[], int capStyle, int joinStyle) { + private PathGradientPaint(float[] fractions, Color[] colors, int capStyle, int joinStyle) { this.colors = colors.clone(); this.fractions = fractions.clone(); this.capStyle = capStyle; @@ -66,26 +69,26 @@ class PathGradientPaint implements Paint { } class PathGradientContext implements PaintContext { - protected final Rectangle deviceBounds; - protected final Rectangle2D userBounds; + final Rectangle deviceBounds; + final Rectangle2D userBounds; protected final AffineTransform xform; - protected final RenderingHints hints; + final RenderingHints hints; /** * for POI: the shape will be only known when the subclasses determines the concrete implementation * in the draw/-content method, so we need to postpone the setting/creation as long as possible **/ protected final Shape shape; - protected final PaintContext pCtx; - protected final int gradientSteps; + final PaintContext pCtx; + final int gradientSteps; WritableRaster raster; - public PathGradientContext( - ColorModel cm - , Rectangle deviceBounds - , Rectangle2D userBounds - , AffineTransform xform - , RenderingHints hints + PathGradientContext( + ColorModel cm + , Rectangle deviceBounds + , Rectangle2D userBounds + , AffineTransform xform + , RenderingHints hints ) { shape = (Shape)hints.get(Drawable.GRADIENT_SHAPE); if (shape == null) { @@ -139,7 +142,7 @@ class PathGradientPaint implements Paint { return childRaster; } - protected int getGradientSteps(Shape gradientShape) { + int getGradientSteps(Shape gradientShape) { Rectangle rect = gradientShape.getBounds(); int lower = 1; int upper = (int)(Math.max(rect.getWidth(),rect.getHeight())/2.0); @@ -158,7 +161,7 @@ class PathGradientPaint implements Paint { - protected void createRaster() { + void createRaster() { ColorModel cm = getColorModel(); raster = cm.createCompatibleWritableRaster((int)deviceBounds.getWidth(), (int)deviceBounds.getHeight()); BufferedImage img = new BufferedImage(cm, raster, false, null); @@ -168,7 +171,7 @@ class PathGradientPaint implements Paint { graphics.transform(xform); Raster img2 = pCtx.getRaster(0, 0, gradientSteps, 1); - int rgb[] = new int[cm.getNumComponents()]; + int[] rgb = new int[cm.getNumComponents()]; for (int i = gradientSteps-1; i>=0; i--) { img2.getPixel(i, 0, rgb); diff --git a/src/java/org/apache/poi/ss/formula/SheetNameFormatter.java b/src/java/org/apache/poi/ss/formula/SheetNameFormatter.java index c6e13c311..6e10e67c5 100644 --- a/src/java/org/apache/poi/ss/formula/SheetNameFormatter.java +++ b/src/java/org/apache/poi/ss/formula/SheetNameFormatter.java @@ -59,6 +59,7 @@ public final class SheetNameFormatter { * @param rawSheetName - sheet name * @deprecated use appendFormat(StringBuilder out, String rawSheetName) instead */ + @Deprecated public static void appendFormat(StringBuffer out, String rawSheetName) { boolean needsQuotes = needsDelimiting(rawSheetName); if(needsQuotes) { @@ -73,6 +74,7 @@ public final class SheetNameFormatter { /** * @deprecated use appendFormat(StringBuilder out, String workbookName, String rawSheetName) instead */ + @Deprecated public static void appendFormat(StringBuffer out, String workbookName, String rawSheetName) { boolean needsQuotes = needsDelimiting(workbookName) || needsDelimiting(rawSheetName); if(needsQuotes) { @@ -123,7 +125,7 @@ public final class SheetNameFormatter { } } - private static void appendAndEscape(Appendable sb, String rawSheetName) { + static void appendAndEscape(Appendable sb, String rawSheetName) { int len = rawSheetName.length(); for(int i=0; i= 0) { + sb.append('['); + sb.append(workbookIndex); + sb.append(']'); + } + + SheetNameFormatter.appendAndEscape(sb, firstSheetName); + + if (lastSheetName != null) { + sb.append(':'); + SheetNameFormatter.appendAndEscape(sb, lastSheetName); + } + + sb.append('\''); + return sb.toString(); + } + + private static String formatWithoutDelimiting(StringBuilder sb, int workbookIndex, String firstSheetName, String lastSheetName) { + if (workbookIndex >= 0) { + sb.append('['); + sb.append(workbookIndex); + sb.append(']'); + } + + sb.append(firstSheetName); + + if (lastSheetName != null) { + sb.append(':'); + sb.append(lastSheetName); + } + + return sb.toString(); + } + + private static boolean anySheetNameNeedsEscaping(String firstSheetName, String lastSheetName) { + boolean anySheetNameNeedsDelimiting = firstSheetName != null && SheetNameFormatter.needsDelimiting(firstSheetName); + anySheetNameNeedsDelimiting |= lastSheetName != null && SheetNameFormatter.needsDelimiting(lastSheetName); + return anySheetNameNeedsDelimiting; + } +} diff --git a/src/java/org/apache/poi/ss/formula/ptg/Area3DPxg.java b/src/java/org/apache/poi/ss/formula/ptg/Area3DPxg.java index 65f59e83e..41bea0c95 100644 --- a/src/java/org/apache/poi/ss/formula/ptg/Area3DPxg.java +++ b/src/java/org/apache/poi/ss/formula/ptg/Area3DPxg.java @@ -20,6 +20,7 @@ package org.apache.poi.ss.formula.ptg; import org.apache.poi.ss.SpreadsheetVersion; import org.apache.poi.ss.formula.SheetIdentifier; import org.apache.poi.ss.formula.SheetNameFormatter; +import org.apache.poi.ss.formula.SheetRangeAndWorkbookIndexFormatter; import org.apache.poi.ss.formula.SheetRangeIdentifier; import org.apache.poi.ss.util.AreaReference; import org.apache.poi.util.LittleEndianOutput; @@ -102,16 +103,8 @@ public final class Area3DPxg extends AreaPtgBase implements Pxg3D { public String toFormulaString() { StringBuilder sb = new StringBuilder(64); - if (externalWorkbookNumber >= 0) { - sb.append('['); - sb.append(externalWorkbookNumber); - sb.append(']'); - } - SheetNameFormatter.appendFormat(sb, firstSheetName); - if (lastSheetName != null) { - sb.append(':'); - SheetNameFormatter.appendFormat(sb, lastSheetName); - } + + SheetRangeAndWorkbookIndexFormatter.format(sb, externalWorkbookNumber, firstSheetName, lastSheetName); sb.append('!'); sb.append(formatReferenceAsString()); return sb.toString(); diff --git a/src/java/org/apache/poi/ss/formula/ptg/Ref3DPxg.java b/src/java/org/apache/poi/ss/formula/ptg/Ref3DPxg.java index 67f73b360..12e7e54ed 100644 --- a/src/java/org/apache/poi/ss/formula/ptg/Ref3DPxg.java +++ b/src/java/org/apache/poi/ss/formula/ptg/Ref3DPxg.java @@ -18,7 +18,7 @@ package org.apache.poi.ss.formula.ptg; import org.apache.poi.ss.formula.SheetIdentifier; -import org.apache.poi.ss.formula.SheetNameFormatter; +import org.apache.poi.ss.formula.SheetRangeAndWorkbookIndexFormatter; import org.apache.poi.ss.formula.SheetRangeIdentifier; import org.apache.poi.ss.util.CellReference; import org.apache.poi.util.LittleEndianOutput; @@ -101,18 +101,8 @@ public final class Ref3DPxg extends RefPtgBase implements Pxg3D { public String toFormulaString() { StringBuilder sb = new StringBuilder(64); - if (externalWorkbookNumber >= 0) { - sb.append('['); - sb.append(externalWorkbookNumber); - sb.append(']'); - } - if (firstSheetName != null) { - SheetNameFormatter.appendFormat(sb, firstSheetName); - } - if (lastSheetName != null) { - sb.append(':'); - SheetNameFormatter.appendFormat(sb, lastSheetName); - } + + SheetRangeAndWorkbookIndexFormatter.format(sb, externalWorkbookNumber, firstSheetName, lastSheetName); sb.append('!'); sb.append(formatReferenceAsString()); return sb.toString(); diff --git a/src/java/org/apache/poi/util/RecordFormatException.java b/src/java/org/apache/poi/util/RecordFormatException.java index 2bc4ba3bc..65bea581e 100644 --- a/src/java/org/apache/poi/util/RecordFormatException.java +++ b/src/java/org/apache/poi/util/RecordFormatException.java @@ -45,8 +45,8 @@ public class RecordFormatException * be thrown. If assertTrue is false, this will throw this * exception with the message. * - * @param assertTrue - * @param message + * @param assertTrue If false, the exception is thrown, if true, no action is performed + * @param message The message to include in the thrown exception */ public static void check(boolean assertTrue, String message) { if (! assertTrue) { diff --git a/src/ooxml/java/org/apache/poi/ooxml/POIXMLDocumentPart.java b/src/ooxml/java/org/apache/poi/ooxml/POIXMLDocumentPart.java index 54fa790ec..c8e1a277a 100644 --- a/src/ooxml/java/org/apache/poi/ooxml/POIXMLDocumentPart.java +++ b/src/ooxml/java/org/apache/poi/ooxml/POIXMLDocumentPart.java @@ -615,7 +615,7 @@ public class POIXMLDocumentPart { protected void read(POIXMLFactory factory, Map context) throws OpenXML4JException { PackagePart pp = getPackagePart(); - if (pp.getContentType().equals(XWPFRelation.TEMPLATE.getContentType())) { + if (pp.getContentType().equals(XWPFRelation.GLOSSARY_DOCUMENT.getContentType())) { logger.log(POILogger.WARN, "POI does not currently support template.main+xml (glossary) parts. " + "Skipping this part for now."); diff --git a/src/ooxml/java/org/apache/poi/ooxml/extractor/CommandLineTextExtractor.java b/src/ooxml/java/org/apache/poi/ooxml/extractor/CommandLineTextExtractor.java index 999abd46e..c3d429b3c 100644 --- a/src/ooxml/java/org/apache/poi/ooxml/extractor/CommandLineTextExtractor.java +++ b/src/ooxml/java/org/apache/poi/ooxml/extractor/CommandLineTextExtractor.java @@ -22,41 +22,37 @@ import org.apache.poi.extractor.POITextExtractor; /** * A command line wrapper around {@link ExtractorFactory}, useful - * for when debugging. + * for when debugging. */ public class CommandLineTextExtractor { - public static final String DIVIDER = "======================="; - - public static void main(String[] args) throws Exception { - if(args.length < 1) { - System.err.println("Use:"); - System.err.println(" CommandLineTextExtractor [filename] [filename]"); - System.exit(1); - } + public static final String DIVIDER = "======================="; - for (String arg : args) { - System.out.println(DIVIDER); + public static void main(String[] args) throws Exception { + if (args.length < 1) { + System.err.println("Use:"); + System.err.println(" CommandLineTextExtractor [filename] [filename]"); + System.exit(1); + } - File f = new File(arg); - System.out.println(f); + for (String arg : args) { + System.out.println(DIVIDER); - POITextExtractor extractor = - ExtractorFactory.createExtractor(f); - try { - POITextExtractor metadataExtractor = - extractor.getMetadataTextExtractor(); + File f = new File(arg); + System.out.println(f); - System.out.println(" " + DIVIDER); - String metaData = metadataExtractor.getText(); - System.out.println(metaData); - System.out.println(" " + DIVIDER); - String text = extractor.getText(); - System.out.println(text); - System.out.println(DIVIDER); - System.out.println("Had " + metaData.length() + " characters of metadata and " + text.length() + " characters of text"); - } finally { - extractor.close(); - } - } - } + try (POITextExtractor extractor = ExtractorFactory.createExtractor(f)) { + POITextExtractor metadataExtractor = + extractor.getMetadataTextExtractor(); + + System.out.println(" " + DIVIDER); + String metaData = metadataExtractor.getText(); + System.out.println(metaData); + System.out.println(" " + DIVIDER); + String text = extractor.getText(); + System.out.println(text); + System.out.println(DIVIDER); + System.out.println("Had " + metaData.length() + " characters of metadata and " + text.length() + " characters of text"); + } + } + } } diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ZipHelper.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ZipHelper.java index 094e89c6d..0169909c9 100644 --- a/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ZipHelper.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ZipHelper.java @@ -154,8 +154,6 @@ public final class ZipHelper { "The supplied data appears to be a raw XML file. " + "Formats such as Office 2003 XML are not supported"); default: - case OOXML: - case UNKNOWN: // Don't check for a Zip header, as to maintain backwards // compatibility we need to let them seek over junk at the // start before beginning processing. diff --git a/src/ooxml/java/org/apache/poi/openxml4j/util/ZipInputStreamZipEntrySource.java b/src/ooxml/java/org/apache/poi/openxml4j/util/ZipInputStreamZipEntrySource.java index e185239ff..0a56966d4 100644 --- a/src/ooxml/java/org/apache/poi/openxml4j/util/ZipInputStreamZipEntrySource.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/util/ZipInputStreamZipEntrySource.java @@ -38,7 +38,7 @@ public class ZipInputStreamZipEntrySource implements ZipEntrySource { /** * Reads all the entries from the ZipInputStream - * into memory, and closes the source stream. + * into memory, and don't close (since POI 4.0.1) the source stream. * We'll then eat lots of memory, but be able to * work with the entries at-will. */ @@ -50,7 +50,6 @@ public class ZipInputStreamZipEntrySource implements ZipEntrySource { } zipEntries.put(zipEntry.getName(), new ZipArchiveFakeEntry(zipEntry, inp)); } - inp.close(); } @Override 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 97b4ab8cb..9f07b18ba 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/testcases/org/apache/poi/ooxml/TestPOIXMLProperties.java b/src/ooxml/testcases/org/apache/poi/ooxml/TestPOIXMLProperties.java index d91b8191e..1ad2a633f 100644 --- a/src/ooxml/testcases/org/apache/poi/ooxml/TestPOIXMLProperties.java +++ b/src/ooxml/testcases/org/apache/poi/ooxml/TestPOIXMLProperties.java @@ -19,6 +19,7 @@ package org.apache.poi.ooxml; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -89,7 +90,7 @@ public final class TestPOIXMLProperties { XSSFWorkbook newWorkbook = XSSFTestDataSamples.writeOutAndReadBack(workbook); workbook.close(); - assertTrue(workbook != newWorkbook); + assertNotSame(workbook, newWorkbook); POIXMLProperties newProps = newWorkbook.getProperties(); @@ -158,7 +159,7 @@ public final class TestPOIXMLProperties { p = ctProps.getPropertyArray(3); assertEquals("{D5CDD505-2E9C-101B-9397-08002B2CF9AE}", p.getFmtid()); assertEquals("test-4", p.getName()); - assertEquals(true, p.getBool()); + assertTrue(p.getBool()); assertEquals(5, p.getPid()); wb2.close(); diff --git a/src/ooxml/testcases/org/apache/poi/xddf/usermodel/TestNecessaryOOXMLClasses.java b/src/ooxml/testcases/org/apache/poi/xddf/usermodel/TestNecessaryOOXMLClasses.java index 74ec1bb6c..6cbf24ab6 100644 --- a/src/ooxml/testcases/org/apache/poi/xddf/usermodel/TestNecessaryOOXMLClasses.java +++ b/src/ooxml/testcases/org/apache/poi/xddf/usermodel/TestNecessaryOOXMLClasses.java @@ -87,6 +87,10 @@ public class TestNecessaryOOXMLClasses { Assert.assertNotNull(ctLblAlgn); CTDashStopList ctDashStopList = CTDashStopList.Factory.newInstance(); Assert.assertNotNull(ctDashStopList); + STDispBlanksAs stDashBlanksAs = STDispBlanksAs.Factory.newInstance(); + Assert.assertNotNull(stDashBlanksAs); + CTDispBlanksAs ctDashBlanksAs = CTDispBlanksAs.Factory.newInstance(); + Assert.assertNotNull(ctDashBlanksAs); STLblAlgn.Enum e1 = STLblAlgn.Enum.forString("ctr"); Assert.assertNotNull(e1); @@ -100,6 +104,8 @@ public class TestNecessaryOOXMLClasses { Assert.assertNotNull(e5); STMarkerStyle.Enum e6 = STMarkerStyle.Enum.forString("circle"); Assert.assertNotNull(e6); + STDispBlanksAs.Enum e7 = STDispBlanksAs.Enum.forString("span"); + Assert.assertNotNull(e7); CTTextBulletTypefaceFollowText ctTextBulletTypefaceFollowText = CTTextBulletTypefaceFollowText.Factory.newInstance(); Assert.assertNotNull(ctTextBulletTypefaceFollowText); diff --git a/src/ooxml/testcases/org/apache/poi/xdgf/extractor/TestXDGFVisioExtractor.java b/src/ooxml/testcases/org/apache/poi/xdgf/extractor/TestXDGFVisioExtractor.java index 6a3369ed9..c261e2c91 100644 --- a/src/ooxml/testcases/org/apache/poi/xdgf/extractor/TestXDGFVisioExtractor.java +++ b/src/ooxml/testcases/org/apache/poi/xdgf/extractor/TestXDGFVisioExtractor.java @@ -42,7 +42,7 @@ public class TestXDGFVisioExtractor { } @After - public void closeResoures() throws IOException { + public void closeResources() throws IOException { if(xml != null) { xml.close(); } diff --git a/src/ooxml/testcases/org/apache/poi/xslf/TestXSLFBugs.java b/src/ooxml/testcases/org/apache/poi/xslf/TestXSLFBugs.java index 48b081699..8dbc8ca23 100644 --- a/src/ooxml/testcases/org/apache/poi/xslf/TestXSLFBugs.java +++ b/src/ooxml/testcases/org/apache/poi/xslf/TestXSLFBugs.java @@ -17,12 +17,7 @@ package org.apache.poi.xslf; import static org.apache.poi.POITestCase.assertContains; -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; +import static org.junit.Assert.*; import java.awt.Color; import java.awt.Dimension; @@ -93,6 +88,25 @@ import org.openxmlformats.schemas.presentationml.x2006.main.CTShape; public class TestXSLFBugs { private static final POIDataSamples slTests = POIDataSamples.getSlideShowInstance(); + @Test + public void bug62929() throws Exception { + try(XMLSlideShow ss1 = XSLFTestDataSamples.openSampleDocument("missing-blip-fill.pptx")) { + assertEquals(1, ss1.getSlides().size()); + + XSLFSlide slide = ss1.getSlides().get(0); + + assertEquals(slide.getShapes().size(), 1); + + XSLFPictureShape picture = (XSLFPictureShape)slide.getShapes().get(0); + + assertEquals(picture.getShapeId(), 662); + assertFalse(picture.isExternalLinkedPicture()); + assertNull(picture.getPictureData()); + assertNull(picture.getPictureLink()); + assertNull(picture.getClipping()); + } + } + @Test public void bug62736() throws Exception { XMLSlideShow ss1 = XSLFTestDataSamples.openSampleDocument("bug62736.pptx"); diff --git a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestPPTX2PNG.java b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestPPTX2PNG.java index 94205da14..199a9f628 100644 --- a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestPPTX2PNG.java +++ b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestPPTX2PNG.java @@ -47,7 +47,7 @@ public class TestPPTX2PNG { private static final POIDataSamples samples = POIDataSamples.getSlideShowInstance(); private static final File basedir = null; private static final String files = - "53446.ppt, alterman_security.ppt, alterman_security.pptx, KEY02.pptx, themes.pptx, backgrounds.pptx, layouts.pptx, sample.pptx, shapes.pptx, 54880_chinese.ppt"; + "53446.ppt, alterman_security.ppt, alterman_security.pptx, KEY02.pptx, themes.pptx, backgrounds.pptx, layouts.pptx, sample.pptx, shapes.pptx, 54880_chinese.ppt, keyframes.pptx"; diff --git a/src/ooxml/testcases/org/apache/poi/xssf/XSSFTestDataSamples.java b/src/ooxml/testcases/org/apache/poi/xssf/XSSFTestDataSamples.java index 0f03af745..b981b9994 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/XSSFTestDataSamples.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/XSSFTestDataSamples.java @@ -70,7 +70,7 @@ public class XSSFTestDataSamples { * @param wb the workbook to write * @param testName a fragment of the filename * @return the location where the workbook was saved - * @throws IOException + * @throws IOException If writing the file fails */ public static File writeOut(R wb, String testName) throws IOException { final File file = getOutputFile(testName); @@ -104,7 +104,9 @@ public class XSSFTestDataSamples { file = TempFile.createTempFile(testName, ".xlsx"); } if (file.exists()) { - file.delete(); + if(!file.delete()) { + throw new IOException("Could not delete file " + file); + } } return file; } @@ -114,7 +116,7 @@ public class XSSFTestDataSamples { * * @param wb the workbook to write * @return the memory buffer - * @throws IOException + * @throws IOException If writing the file fails */ public static ByteArrayOutputStream writeOut(R wb) throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(8192); @@ -137,7 +139,7 @@ public class XSSFTestDataSamples { * to avoid creating a temporary file. However, this may complicate the calling * code to avoid having the workbook, BAOS, and BAIS open at the same time. * - * @param wb + * @param wb The workbook to write out, it is closed after the call. * @param testName file name to be used to write to a file. This file will be cleaned up by a call to readBack(String) * @return workbook location * @throws RuntimeException if {@link #TEST_OUTPUT_DIR} System property is not set @@ -161,18 +163,13 @@ public class XSSFTestDataSamples { * * @param wb the workbook to write * @return the memory buffer - * @throws IOException + * @throws RuntimeException If writing the file fails */ - public static ByteArrayOutputStream writeOutAndClose(R wb) { - try { - ByteArrayOutputStream out = writeOut(wb); - // Do not close the workbook if there was a problem writing the workbook - wb.close(); - return out; - } - catch (final IOException e) { - throw new RuntimeException(e); - } + public static ByteArrayOutputStream writeOutAndClose(R wb) throws IOException { + ByteArrayOutputStream out = writeOut(wb); + // Do not close the workbook if there was a problem writing the workbook + wb.close(); + return out; } /** @@ -183,12 +180,14 @@ public class XSSFTestDataSamples { * * @param file the workbook file to read and delete * @return the read back workbook - * @throws IOException + * @throws IOException If reading or deleting the file fails */ public static XSSFWorkbook readBackAndDelete(File file) throws IOException { XSSFWorkbook wb = readBack(file); // do not delete the file if there's an error--might be helpful for debugging - file.delete(); + if(!file.delete()) { + throw new IOException("Could not delete file " + file + " after reading"); + } return wb; } @@ -198,16 +197,12 @@ public class XSSFTestDataSamples { * * @param file the workbook file to read * @return the read back workbook - * @throws IOException + * @throws IOException If reading the file fails */ public static XSSFWorkbook readBack(File file) throws IOException { - InputStream in = new FileInputStream(file); - try { + try (InputStream in = new FileInputStream(file)) { return new XSSFWorkbook(in); } - finally { - in.close(); - } } /** @@ -216,17 +211,13 @@ public class XSSFTestDataSamples { * * @param out the output stream to read back from * @return the read back workbook - * @throws IOException + * @throws IOException If reading the file fails */ public static XSSFWorkbook readBack(ByteArrayOutputStream out) throws IOException { - InputStream is = new ByteArrayInputStream(out.toByteArray()); - out.close(); - try { + try (InputStream is = new ByteArrayInputStream(out.toByteArray())) { + out.close(); return new XSSFWorkbook(is); } - finally { - is.close(); - } } /** diff --git a/src/ooxml/testcases/org/apache/poi/xwpf/extractor/TestXWPFWordExtractor.java b/src/ooxml/testcases/org/apache/poi/xwpf/extractor/TestXWPFWordExtractor.java index 0fcccd183..30d943051 100644 --- a/src/ooxml/testcases/org/apache/poi/xwpf/extractor/TestXWPFWordExtractor.java +++ b/src/ooxml/testcases/org/apache/poi/xwpf/extractor/TestXWPFWordExtractor.java @@ -452,4 +452,12 @@ public class TestXWPFWordExtractor extends TestCase { //once we add processing for this, we can change this to contains assertNotContained(txt, "table rows"); } + + public void testPartsInTemplate() throws IOException { + XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("60316b.dotx"); + XWPFWordExtractor extractor = new XWPFWordExtractor(doc); + String txt = extractor.getText(); + assertContains(txt, "header 2"); + assertContains(txt, "footer 1"); + } } diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/CurrentUserAtom.java b/src/scratchpad/src/org/apache/poi/hslf/record/CurrentUserAtom.java index cedfbb047..26ba59d2c 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/record/CurrentUserAtom.java +++ b/src/scratchpad/src/org/apache/poi/hslf/record/CurrentUserAtom.java @@ -20,6 +20,8 @@ package org.apache.poi.hslf.record; +import static org.apache.poi.hslf.usermodel.HSLFSlideShow.PP95_DOCUMENT; + import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -143,7 +145,7 @@ public class CurrentUserAtom // See how long it is. If it's under 28 bytes long, we can't // read it if(_contents.length < 28) { - boolean isPP95 = dir.hasEntry("PP40"); + boolean isPP95 = dir.hasEntry(PP95_DOCUMENT); // PPT95 has 4 byte size, then data if (!isPP95 && _contents.length >= 4) { int size = LittleEndian.getInt(_contents); diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShow.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShow.java index ecc360e13..2f0a116d6 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShow.java +++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShow.java @@ -71,6 +71,7 @@ public final class HSLFSlideShow implements SlideShow
    Bit number