tag r1847494 as 4.0.1

git-svn-id: https://svn.apache.org/repos/asf/poi/tags/REL_4_0_1@1847495 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Andreas Beeker 2018-11-26 21:27:30 +00:00
commit 3ad99da86e
50 changed files with 507 additions and 246 deletions

View File

@ -1950,6 +1950,7 @@ under the License.
<mapper>
<chainedmapper>
<filtermapper>
<replaceregex pattern=".jar" replace="" flags="g"/>
<replaceregex pattern="ooxml-lite" replace="ooxml-schemas" flags="g"/>
<replaceregex pattern="(.java|.src)$$" replace="-sources"/>
<replaceregex pattern=".*(?:build|src).?(.*)?" replace="\1"/>
@ -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.
<copy todir="${repo}">
<mappedresources>
<!-- add sha-512 when nexus rules are updated (1/2) -->
<fileset dir="build/dist/maven" includes="@{artifactId}/**" excludes="**/*.sha512"/>
<fileset dir="build/dist/maven" includes="@{artifactId}/**" excludes="**/*.sha512,**/*.sha256"/>
<regexpmapper from="^([^/]+)/(.*)$$" to="org/apache/poi/\1/${version.id}/\2" handledirsep="true"/>
</mappedresources>
</copy>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>org.apache.poi</groupId>
<artifactId>poi-parent</artifactId>
<version>4.0.1-SNAPSHOT</version>
<version>4.0.2-SNAPSHOT</version>
</parent>
<artifactId>poi-examples</artifactId>
<packaging>jar</packaging>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>org.apache.poi</groupId>
<artifactId>poi-parent</artifactId>
<version>4.0.1-SNAPSHOT</version>
<version>4.0.2-SNAPSHOT</version>
</parent>
<artifactId>poi-excelant</artifactId>
<packaging>jar</packaging>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>org.apache.poi</groupId>
<artifactId>poi-parent</artifactId>
<version>4.0.1-SNAPSHOT</version>
<version>4.0.2-SNAPSHOT</version>
</parent>
<artifactId>poi-main</artifactId>
<packaging>jar</packaging>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>org.apache.poi</groupId>
<artifactId>poi-parent</artifactId>
<version>4.0.1-SNAPSHOT</version>
<version>4.0.2-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<artifactId>poi-ooxml-schema-encryption</artifactId>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>org.apache.poi</groupId>
<artifactId>poi-parent</artifactId>
<version>4.0.1-SNAPSHOT</version>
<version>4.0.2-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<artifactId>poi-ooxml-schema-security</artifactId>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>org.apache.poi</groupId>
<artifactId>poi-parent</artifactId>
<version>4.0.1-SNAPSHOT</version>
<version>4.0.2-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<artifactId>poi-ooxml-schema</artifactId>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>org.apache.poi</groupId>
<artifactId>poi-parent</artifactId>
<version>4.0.1-SNAPSHOT</version>
<version>4.0.2-SNAPSHOT</version>
</parent>
<artifactId>poi-ooxml</artifactId>
<packaging>jar</packaging>

View File

@ -4,7 +4,7 @@
<groupId>org.apache.poi</groupId>
<artifactId>poi-parent</artifactId>
<packaging>pom</packaging>
<version>4.0.1-SNAPSHOT</version>
<version>4.0.2-SNAPSHOT</version>
<name>Apache POI - the Java API for Microsoft Documents</name>
<description>Maven build of Apache POI for Sonar checks</description>
<url>http://poi.apache.org/</url>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>org.apache.poi</groupId>
<artifactId>poi-parent</artifactId>
<version>4.0.1-SNAPSHOT</version>
<version>4.0.2-SNAPSHOT</version>
</parent>
<artifactId>poi-scratchpad</artifactId>
<packaging>jar</packaging>

View File

@ -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",

View File

@ -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 {

View File

@ -36,7 +36,7 @@ import org.apache.poi.util.POILogger;
* Supports reading and writing of variant data.<p>
*
* <strong>FIXME (3):</strong> Reading and writing should be made more
* uniform than it is now. The following items should be resolved:<p>
* uniform than it is now. The following items should be resolved:
*
* <ul>
*

View File

@ -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<Long,String> {
@ -490,11 +493,13 @@ public class PropertyIDMap implements Map<Long,String> {
@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);
}

View File

@ -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() {

View File

@ -33,8 +33,9 @@ import org.apache.poi.util.LittleEndianInputStream;
import org.apache.poi.util.RecordFormatException;
/**
* Title: Record Input Stream<P>
* Description: Wraps a stream and provides helper methods for the construction of records.<P>
* 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) {

View File

@ -161,7 +161,7 @@ public final class SSTRecord extends ContinuableRecord {
* <P>
* The data consists of sets of string data. This string data is
* arranged as follows:
* <P>
* </P><P>
* <pre>
* 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)
* </pre>
* <P>
* </P><P>
* The string_flag is bit mapped as follows:
* <P>
* </P><P>
* <TABLE summary="string_flag mapping">
* <TR>
* <TH>Bit number</TH>
@ -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

View File

@ -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) {

View File

@ -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) {

View File

@ -78,7 +78,7 @@ public enum FileMagic {
/** PDF document */
PDF("%PDF"),
/** Some different HTML documents */
HTML("<!DOCTYP".getBytes(UTF_8), "<html".getBytes(UTF_8)),
HTML("<!DOCTYP".getBytes(UTF_8), "<html".getBytes(UTF_8), "<HTML".getBytes(UTF_8)),
WORD2(new byte[]{ (byte)0xdb, (byte)0xa5, 0x2d, 0x00}),
// keep UNKNOWN always as last enum!
/** UNKNOWN magic */
@ -101,17 +101,8 @@ public enum FileMagic {
public static FileMagic valueOf(byte[] magic) {
for (FileMagic fm : values()) {
int i=0;
boolean found = true;
for (byte[] ma : fm.magic) {
for (byte m : ma) {
byte d = magic[i++];
if (!(d == m || (m == 0x70 && (d == 0x10 || d == 0x20 || d == 0x40)))) {
found = false;
break;
}
}
if (found) {
if (findMagic(ma, magic)) {
return fm;
}
}
@ -119,6 +110,17 @@ public enum FileMagic {
return UNKNOWN;
}
private static boolean findMagic(byte[] cmp, byte[] actual) {
int i=0;
for (byte m : cmp) {
byte d = actual[i++];
if (!(d == m || (m == 0x70 && (d == 0x10 || d == 0x20 || d == 0x40)))) {
return false;
}
}
return true;
}
/**
* Get the file magic of the supplied {@link File}<p>

View File

@ -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<float[],Color[],Paint> 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<Float,Color> m = new TreeMap<>();
for (int i = 0; i<fractions.length; i++) {
// if fc is null, use transparent color to get color of background
m.put(fractions[i], (styles[i] == null ? TRANSPARENT : applyColorTransform(styles[i])));
}
return new PathGradientPaint(colors, fractions);
final Color[] colors = new Color[m.size()];
if (fractions.length != m.size()) {
fractions = new float[m.size()];
}
int i=0;
for (Map.Entry<Float,Color> me : m.entrySet()) {
fractions[i] = me.getKey();
colors[i] = me.getValue();
i++;
}
return init.apply(fractions, colors);
}
/**

View File

@ -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);

View File

@ -59,6 +59,7 @@ public final class SheetNameFormatter {
* @param rawSheetName - sheet name
* @deprecated use <code>appendFormat(StringBuilder out, String rawSheetName)</code> 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 <code>appendFormat(StringBuilder out, String workbookName, String rawSheetName)</code> 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<len; i++) {
char ch = rawSheetName.charAt(i);
@ -139,7 +141,12 @@ public final class SheetNameFormatter {
}
}
private static boolean needsDelimiting(String rawSheetName) {
/**
* Tell if the given raw sheet name needs screening/delimiting.
* @param rawSheetName the sheet name.
* @return true if the given raw sheet name needs screening/delimiting, false otherwise.
*/
static boolean needsDelimiting(String rawSheetName) {
int len = rawSheetName.length();
if(len < 1) {
throw new RuntimeException("Zero length string is an invalid sheet name");

View File

@ -0,0 +1,73 @@
/* ====================================================================
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.ss.formula;
public class SheetRangeAndWorkbookIndexFormatter {
private SheetRangeAndWorkbookIndexFormatter() {
}
public static String format(StringBuilder sb, int workbookIndex, String firstSheetName, String lastSheetName) {
if (anySheetNameNeedsEscaping(firstSheetName, lastSheetName)) {
return formatWithDelimiting(sb, workbookIndex, firstSheetName, lastSheetName);
} else {
return formatWithoutDelimiting(sb, workbookIndex, firstSheetName, lastSheetName);
}
}
private static String formatWithDelimiting(StringBuilder sb, int workbookIndex, String firstSheetName, String lastSheetName) {
sb.append('\'');
if (workbookIndex >= 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;
}
}

View File

@ -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();

View File

@ -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();

View File

@ -45,8 +45,8 @@ public class RecordFormatException
* be thrown. If assertTrue is <code>false</code>, 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) {

View File

@ -615,7 +615,7 @@ public class POIXMLDocumentPart {
protected void read(POIXMLFactory factory, Map<PackagePart, POIXMLDocumentPart> 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.");

View File

@ -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] [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] [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");
}
}
}
}

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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();

View File

@ -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);

View File

@ -42,7 +42,7 @@ public class TestXDGFVisioExtractor {
}
@After
public void closeResoures() throws IOException {
public void closeResources() throws IOException {
if(xml != null) {
xml.close();
}

View File

@ -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");

View File

@ -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";

View File

@ -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 <R extends Workbook> 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 <R extends Workbook> 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 <R extends Workbook> 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 <R extends Workbook> 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();
}
}
/**

View File

@ -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");
}
}

View File

@ -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);

View File

@ -71,6 +71,7 @@ public final class HSLFSlideShow implements SlideShow<HSLFShape,HSLFTextParagrap
/** Powerpoint document entry/stream name */
public static final String POWERPOINT_DOCUMENT = "PowerPoint Document";
public static final String PP95_DOCUMENT = "PP40";
enum LoadSavePhase {
INIT, LOADED

View File

@ -17,6 +17,9 @@
package org.apache.poi.hslf.usermodel;
import static org.apache.poi.hslf.usermodel.HSLFSlideShow.POWERPOINT_DOCUMENT;
import static org.apache.poi.hslf.usermodel.HSLFSlideShow.PP95_DOCUMENT;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
@ -35,6 +38,7 @@ import java.util.TreeMap;
import org.apache.poi.POIDocument;
import org.apache.poi.hslf.exceptions.CorruptPowerPointFileException;
import org.apache.poi.hslf.exceptions.HSLFException;
import org.apache.poi.hslf.exceptions.OldPowerPointFormatException;
import org.apache.poi.hslf.record.CurrentUserAtom;
import org.apache.poi.hslf.record.DocumentEncryptionAtom;
import org.apache.poi.hslf.record.ExOleObjStg;
@ -183,13 +187,18 @@ public final class HSLFSlideShowImpl extends POIDocument implements Closeable {
* @throws IOException when the powerpoint can't be read
*/
private void readPowerPointStream() throws IOException {
final DirectoryNode dir = getDirectory();
if (!dir.hasEntry(POWERPOINT_DOCUMENT) && dir.hasEntry(PP95_DOCUMENT)) {
throw new OldPowerPointFormatException("You seem to have supplied a PowerPoint95 file, which isn't supported");
}
// Get the main document stream
DocumentEntry docProps =
(DocumentEntry) getDirectory().getEntry(HSLFSlideShow.POWERPOINT_DOCUMENT);
DocumentEntry docProps = (DocumentEntry)dir.getEntry(POWERPOINT_DOCUMENT);
// Grab the document stream
int len = docProps.getSize();
try (InputStream is = getDirectory().createDocumentInputStream(HSLFSlideShow.POWERPOINT_DOCUMENT)) {
try (InputStream is = dir.createDocumentInputStream(docProps)) {
_docstream = IOUtils.toByteArray(is, len);
}
}
@ -665,8 +674,8 @@ public final class HSLFSlideShowImpl extends POIDocument implements Closeable {
// Write the PPT stream into the POIFS layer
ByteArrayInputStream bais = new ByteArrayInputStream(_docstream);
outFS.createOrUpdateDocument(bais, HSLFSlideShow.POWERPOINT_DOCUMENT);
writtenEntries.add(HSLFSlideShow.POWERPOINT_DOCUMENT);
outFS.createOrUpdateDocument(bais, POWERPOINT_DOCUMENT);
writtenEntries.add(POWERPOINT_DOCUMENT);
currentUser.setEncrypted(encryptedSS.getDocumentEncryptionAtom() != null);
currentUser.writeToFS(outFS);

View File

@ -0,0 +1,81 @@
/* ====================================================================
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.poifs.filesystem;
import org.apache.commons.codec.Charsets;
import org.apache.poi.POIDataSamples;
import org.junit.Test;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import static org.junit.Assert.*;
public class TestFileMagic {
@Test
public void testFileMagic() {
assertEquals(FileMagic.XML, FileMagic.valueOf("XML"));
assertEquals(FileMagic.XML, FileMagic.valueOf("<?xml".getBytes(Charsets.UTF_8)));
assertEquals(FileMagic.HTML, FileMagic.valueOf("HTML"));
assertEquals(FileMagic.HTML, FileMagic.valueOf("<!DOCTYP".getBytes(Charsets.UTF_8)));
assertEquals(FileMagic.HTML, FileMagic.valueOf("<!DOCTYPE".getBytes(Charsets.UTF_8)));
assertEquals(FileMagic.HTML, FileMagic.valueOf("<html".getBytes(Charsets.UTF_8)));
try {
FileMagic.valueOf("some string");
fail("Should catch exception here");
} catch (IllegalArgumentException e) {
// expected here
}
}
@Test
public void testFileMagicFile() throws IOException {
assertEquals(FileMagic.OLE2, FileMagic.valueOf(POIDataSamples.getSpreadSheetInstance().getFile("SampleSS.xls")));
assertEquals(FileMagic.OOXML, FileMagic.valueOf(POIDataSamples.getSpreadSheetInstance().getFile("SampleSS.xlsx")));
}
@Test
public void testFileMagicStream() throws IOException {
try (InputStream stream = new BufferedInputStream(new FileInputStream(POIDataSamples.getSpreadSheetInstance().getFile("SampleSS.xls")))) {
assertEquals(FileMagic.OLE2, FileMagic.valueOf(stream));
}
try (InputStream stream = new BufferedInputStream(new FileInputStream(POIDataSamples.getSpreadSheetInstance().getFile("SampleSS.xlsx")))) {
assertEquals(FileMagic.OOXML, FileMagic.valueOf(stream));
}
}
@Test
public void testPrepare() throws IOException {
try (InputStream stream = new BufferedInputStream(new FileInputStream(POIDataSamples.getSpreadSheetInstance().getFile("SampleSS.xlsx")))) {
assertSame(stream, FileMagic.prepareToCheckMagic(stream));
}
try (InputStream stream = new InputStream() {
@Override
public int read() {
return 0;
}
}) {
assertNotSame(stream, FileMagic.prepareToCheckMagic(stream));
}
}
}

View File

@ -17,6 +17,7 @@
package org.apache.poi.poifs.filesystem;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@ -278,4 +279,18 @@ public final class TestPOIFSFileSystem {
private static InputStream openSampleStream(String sampleFileName) {
return HSSFTestDataSamples.openSampleFileStream(sampleFileName);
}
@Test
public void fileMagics() {
for (FileMagic fm : FileMagic.values()) {
if (fm == FileMagic.UNKNOWN) {
continue;
}
for (byte[] b : fm.magic) {
assertEquals(fm, FileMagic.valueOf(b));
}
}
assertEquals(FileMagic.UNKNOWN, FileMagic.valueOf("foobaa".getBytes(UTF_8)));
}
}

View File

@ -0,0 +1,66 @@
/* ====================================================================
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.ss.formula;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class SheetRangeAndWorkbookIndexFormatterTest {
@Test
public void noDelimiting_ifASingleSheetNameDoesntNeedDelimiting() {
StringBuilder sb = new StringBuilder();
String result = SheetRangeAndWorkbookIndexFormatter.format(sb, 0, "noDelimiting", null);
assertEquals("[0]noDelimiting", result);
}
@Test
public void everythingIsScreened_ifASingleSheetNameNeedsDelimiting() {
StringBuilder sb = new StringBuilder();
String result = SheetRangeAndWorkbookIndexFormatter.format(sb, 0, "1delimiting", null);
assertEquals("'[0]1delimiting'", result);
}
@Test
public void noDelimiting_ifBothSheetNamesDontNeedDelimiting() {
StringBuilder sb = new StringBuilder();
String result = SheetRangeAndWorkbookIndexFormatter.format(sb, 0, "noDelimiting1", "noDelimiting2");
assertEquals("[0]noDelimiting1:noDelimiting2", result);
}
@Test
public void everythingIsScreened_ifFirstSheetNamesNeedsDelimiting() {
StringBuilder sb = new StringBuilder();
String result = SheetRangeAndWorkbookIndexFormatter.format(sb, 0, "1delimiting", "noDelimiting");
assertEquals("'[0]1delimiting:noDelimiting'", result);
}
@Test
public void everythingIsScreened_ifLastSheetNamesNeedsDelimiting() {
StringBuilder sb = new StringBuilder();
String result = SheetRangeAndWorkbookIndexFormatter.format(sb, 0, "noDelimiting", "1delimiting");
assertEquals("'[0]noDelimiting:1delimiting'", result);
}
@Test
public void everythingIsScreened_ifBothSheetNamesNeedDelimiting() {
StringBuilder sb = new StringBuilder();
String result = SheetRangeAndWorkbookIndexFormatter.format(sb, 0, "1delimiting", "2delimiting");
assertEquals("'[0]1delimiting:2delimiting'", result);
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.