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:
commit
3ad99da86e
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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",
|
||||
|
@ -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 {
|
||||
|
@ -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>
|
||||
*
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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() {
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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>
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
|
@ -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");
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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) {
|
||||
|
@ -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.");
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -42,7 +42,7 @@ public class TestXDGFVisioExtractor {
|
||||
}
|
||||
|
||||
@After
|
||||
public void closeResoures() throws IOException {
|
||||
public void closeResources() throws IOException {
|
||||
if(xml != null) {
|
||||
xml.close();
|
||||
}
|
||||
|
@ -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");
|
||||
|
@ -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";
|
||||
|
||||
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
@ -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)));
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
BIN
test-data/document/60316.docx
Normal file
BIN
test-data/document/60316.docx
Normal file
Binary file not shown.
BIN
test-data/document/60316b.dotx
Normal file
BIN
test-data/document/60316b.dotx
Normal file
Binary file not shown.
BIN
test-data/slideshow/keyframes.pptx
Normal file
BIN
test-data/slideshow/keyframes.pptx
Normal file
Binary file not shown.
BIN
test-data/slideshow/missing-blip-fill.pptx
Normal file
BIN
test-data/slideshow/missing-blip-fill.pptx
Normal file
Binary file not shown.
BIN
test-data/slideshow/pp40only.ppt
Normal file
BIN
test-data/slideshow/pp40only.ppt
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user