diff --git a/build.xml b/build.xml
index 207acc4c68..ce3c83c860 100644
--- a/build.xml
+++ b/build.xml
@@ -60,6 +60,10 @@ under the License.
+
+
+
+
-
-
-
-
-
-
-
-
-
-
@@ -1180,6 +1173,59 @@ under the License.
+
+
+
+
+
+
+
+
+
+
+ sun/java2d/pipe/AAShapePipe.renderTiles(Lsun/java2d/SunGraphics2D;Ljava/awt/Shape;Lsun/java2d/pipe/AATileGenerator;[I)V
+ sun/java2d/pipe/AlphaPaintPipe.renderPathTile(Ljava/lang/Object;[BIIIIII)V
+ java/awt/TexturePaintContext.getRaster(IIII)Ljava/awt/image/Raster;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -1219,39 +1265,23 @@ under the License.
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
-
+
@@ -1306,6 +1336,7 @@ under the License.
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -1500,45 +1514,23 @@ under the License.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -1559,72 +1551,35 @@ under the License.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -1650,34 +1605,16 @@ under the License.
unless="integration.test.notRequired" xmlns:jacoco="antlib:org.jacoco.ant">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
@@ -1739,33 +1676,16 @@ under the License.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
@@ -1791,6 +1711,9 @@ under the License.
+
+
+
@@ -1828,7 +1751,7 @@ under the License.
-
+ POI API Documentation]]>
@@ -2113,6 +2036,7 @@ under the License.
sonar/*/src/**,
compile-lib/**,
ooxml-lib/**,
+ ooxml-testlib/**,
scripts/**,
TEST*,
*.ipr,
@@ -2303,7 +2227,10 @@ under the License.
-
+
+
@@ -2453,7 +2380,7 @@ under the License.
-
+
diff --git a/doap_POI.rdf b/doap_POI.rdf
index f1d21a8cee..88ba48f04d 100644
--- a/doap_POI.rdf
+++ b/doap_POI.rdf
@@ -35,6 +35,13 @@
Java
+
+
+ Apache POI 4.0.1
+ 2018-12-03
+ 4.0.1
+
+ Apache POI 4.0.0
diff --git a/src/examples/src/org/apache/poi/xslf/usermodel/ChartFromScratch.java b/src/examples/src/org/apache/poi/xslf/usermodel/ChartFromScratch.java
new file mode 100644
index 0000000000..12f96fa6fd
--- /dev/null
+++ b/src/examples/src/org/apache/poi/xslf/usermodel/ChartFromScratch.java
@@ -0,0 +1,145 @@
+/*
+ * ====================================================================
+ * 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.xslf.usermodel;
+
+import java.awt.geom.Rectangle2D;
+import java.io.BufferedReader;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.xddf.usermodel.chart.AxisCrosses;
+import org.apache.poi.xddf.usermodel.chart.AxisPosition;
+import org.apache.poi.xddf.usermodel.chart.BarDirection;
+import org.apache.poi.xddf.usermodel.chart.ChartTypes;
+import org.apache.poi.xddf.usermodel.chart.LegendPosition;
+import org.apache.poi.xddf.usermodel.chart.XDDFBarChartData;
+import org.apache.poi.xddf.usermodel.chart.XDDFChart;
+import org.apache.poi.xddf.usermodel.chart.XDDFChartAxis;
+import org.apache.poi.xddf.usermodel.chart.XDDFChartLegend;
+import org.apache.poi.xddf.usermodel.chart.XDDFDataSource;
+import org.apache.poi.xddf.usermodel.chart.XDDFDataSourcesFactory;
+import org.apache.poi.xddf.usermodel.chart.XDDFNumericalDataSource;
+import org.apache.poi.xddf.usermodel.chart.XDDFValueAxis;
+
+/**
+ * Build a chart without reading template file
+ */
+public class ChartFromScratch {
+ private static void usage(){
+ System.out.println("Usage: BarChartExample ");
+ System.out.println(" bar-chart-data.txt the model to set. First line is chart title, " +
+ "then go pairs {axis-label value}");
+ }
+
+ public static void main(String[] args) throws Exception {
+ if(args.length < 1) {
+ usage();
+ return;
+ }
+
+ try (BufferedReader modelReader = new BufferedReader(new FileReader(args[0]))) {
+
+ String chartTitle = modelReader.readLine(); // first line is chart title
+ String[] series = modelReader.readLine().split(",");
+
+ // Category Axis Data
+ List listLanguages = new ArrayList<>(10);
+
+ // Values
+ List listCountries = new ArrayList<>(10);
+ List listSpeakers = new ArrayList<>(10);
+
+ // set model
+ String ln;
+ while((ln = modelReader.readLine()) != null) {
+ String[] vals = ln.split(",");
+ listCountries.add(Double.valueOf(vals[0]));
+ listSpeakers.add(Double.valueOf(vals[1]));
+ listLanguages.add(vals[2]);
+ }
+
+ String[] categories = listLanguages.toArray(new String[listLanguages.size()]);
+ Double[] values1 = listCountries.toArray(new Double[listCountries.size()]);
+ Double[] values2 = listSpeakers.toArray(new Double[listSpeakers.size()]);
+
+ try {
+
+ XMLSlideShow ppt = new XMLSlideShow();
+ XSLFSlide slide = ppt.createSlide();
+ XSLFChart chart = ppt.createChart();
+ Rectangle2D rect2D = new java.awt.Rectangle(XDDFChart.DEFAULT_X, XDDFChart.DEFAULT_Y,
+ XDDFChart.DEFAULT_WIDTH, XDDFChart.DEFAULT_HEIGHT);
+ slide.addChart(chart, rect2D);
+ setBarData(chart, chartTitle, series, categories, values1, values2);
+ // save the result
+ try (OutputStream out = new FileOutputStream("bar-chart-demo-output.pptx")) {
+ ppt.write(out);
+ }
+ }
+ catch(Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+ System.out.println("Done");
+ }
+
+ private static void setBarData(XSLFChart chart, String chartTitle, String[] series, String[] categories, Double[] values1, Double[] values2) {
+ // Use a category axis for the bottom axis.
+ XDDFChartAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
+ bottomAxis.setTitle(series[2]);
+ XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT);
+ leftAxis.setTitle(series[0]+","+series[1]);
+ leftAxis.setCrosses(AxisCrosses.AUTO_ZERO);
+
+ final int numOfPoints = categories.length;
+ final String categoryDataRange = chart.formatRange(new CellRangeAddress(1, numOfPoints, 0, 0));
+ final String valuesDataRange = chart.formatRange(new CellRangeAddress(1, numOfPoints, 1, 1));
+ final String valuesDataRange2 = chart.formatRange(new CellRangeAddress(1, numOfPoints, 2, 2));
+ final XDDFDataSource> categoriesData = XDDFDataSourcesFactory.fromArray(categories, categoryDataRange, 0);
+ final XDDFNumericalDataSource extends Number> valuesData = XDDFDataSourcesFactory.fromArray(values1, valuesDataRange, 1);
+ values1[6] = 16.0; // if you ever want to change the underlying data
+ final XDDFNumericalDataSource extends Number> valuesData2 = XDDFDataSourcesFactory.fromArray(values2, valuesDataRange2, 2);
+
+
+ XDDFBarChartData bar = (XDDFBarChartData) chart.createData(ChartTypes.BAR, bottomAxis, leftAxis);
+ XDDFBarChartData.Series series1 = (XDDFBarChartData.Series) bar.addSeries(categoriesData, valuesData);
+ series1.setTitle(series[0], chart.setSheetTitle(series[0], 1));
+
+ XDDFBarChartData.Series series2 = (XDDFBarChartData.Series) bar.addSeries(categoriesData, valuesData2);
+ series2.setTitle(series[1], chart.setSheetTitle(series[1], 2));
+
+ bar.setVaryColors(true);
+ bar.setBarDirection(BarDirection.COL);
+ chart.plot(bar);
+
+ XDDFChartLegend legend = chart.getOrAddLegend();
+ legend.setPosition(LegendPosition.LEFT);
+ legend.setOverlay(false);
+
+ chart.setTitleText(chartTitle);
+ chart.setTitleOverlay(false);
+ }
+}
+
diff --git a/src/examples/src/org/apache/poi/xwpf/usermodel/examples/ChartFromScratch.java b/src/examples/src/org/apache/poi/xwpf/usermodel/examples/ChartFromScratch.java
new file mode 100644
index 0000000000..4a1a78150f
--- /dev/null
+++ b/src/examples/src/org/apache/poi/xwpf/usermodel/examples/ChartFromScratch.java
@@ -0,0 +1,140 @@
+/*
+ * ====================================================================
+ * 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.xwpf.usermodel.examples;
+
+import java.io.BufferedReader;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.xddf.usermodel.chart.AxisCrosses;
+import org.apache.poi.xddf.usermodel.chart.AxisPosition;
+import org.apache.poi.xddf.usermodel.chart.BarDirection;
+import org.apache.poi.xddf.usermodel.chart.ChartTypes;
+import org.apache.poi.xddf.usermodel.chart.LegendPosition;
+import org.apache.poi.xddf.usermodel.chart.XDDFBarChartData;
+import org.apache.poi.xddf.usermodel.chart.XDDFChart;
+import org.apache.poi.xddf.usermodel.chart.XDDFChartAxis;
+import org.apache.poi.xddf.usermodel.chart.XDDFChartLegend;
+import org.apache.poi.xddf.usermodel.chart.XDDFDataSource;
+import org.apache.poi.xddf.usermodel.chart.XDDFDataSourcesFactory;
+import org.apache.poi.xddf.usermodel.chart.XDDFNumericalDataSource;
+import org.apache.poi.xddf.usermodel.chart.XDDFValueAxis;
+import org.apache.poi.xwpf.usermodel.XWPFChart;
+import org.apache.poi.xwpf.usermodel.XWPFDocument;
+
+/**
+ * Build a chart without reading template file
+ */
+public class ChartFromScratch {
+ private static void usage(){
+ System.out.println("Usage: BarChartExample ");
+ System.out.println(" bar-chart-data.txt the model to set. First line is chart title, " +
+ "then go pairs {axis-label value}");
+ }
+
+ public static void main(String[] args) throws Exception {
+ if(args.length < 1) {
+ usage();
+ return;
+ }
+
+ try (BufferedReader modelReader = new BufferedReader(new FileReader(args[0]))) {
+
+ String chartTitle = modelReader.readLine(); // first line is chart title
+ String[] series = modelReader.readLine().split(",");
+
+ // Category Axis Data
+ List listLanguages = new ArrayList<>(10);
+
+ // Values
+ List listCountries = new ArrayList<>(10);
+ List listSpeakers = new ArrayList<>(10);
+
+ // set model
+ String ln;
+ while((ln = modelReader.readLine()) != null) {
+ String[] vals = ln.split(",");
+ listCountries.add(Double.valueOf(vals[0]));
+ listSpeakers.add(Double.valueOf(vals[1]));
+ listLanguages.add(vals[2]);
+ }
+
+ String[] categories = listLanguages.toArray(new String[listLanguages.size()]);
+ Double[] values1 = listCountries.toArray(new Double[listCountries.size()]);
+ Double[] values2 = listSpeakers.toArray(new Double[listSpeakers.size()]);
+
+ try (XWPFDocument doc = new XWPFDocument()) {
+ XWPFChart chart = doc.createChart(XDDFChart.DEFAULT_WIDTH, XDDFChart.DEFAULT_HEIGHT);
+ setBarData(chart, chartTitle, series, categories, values1, values2);
+ // save the result
+ try (OutputStream out = new FileOutputStream("bar-chart-demo-output.docx")) {
+ doc.write(out);
+ }
+ }
+ catch(Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+ System.out.println("Done");
+ }
+
+ private static void setBarData(XWPFChart chart, String chartTitle, String[] series, String[] categories, Double[] values1, Double[] values2) {
+ // Use a category axis for the bottom axis.
+ XDDFChartAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
+ bottomAxis.setTitle(series[2]);
+ XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT);
+ leftAxis.setTitle(series[0]+","+series[1]);
+ leftAxis.setCrosses(AxisCrosses.AUTO_ZERO);
+
+ final int numOfPoints = categories.length;
+ final String categoryDataRange = chart.formatRange(new CellRangeAddress(1, numOfPoints, 0, 0));
+ final String valuesDataRange = chart.formatRange(new CellRangeAddress(1, numOfPoints, 1, 1));
+ final String valuesDataRange2 = chart.formatRange(new CellRangeAddress(1, numOfPoints, 2, 2));
+ final XDDFDataSource> categoriesData = XDDFDataSourcesFactory.fromArray(categories, categoryDataRange, 0);
+ final XDDFNumericalDataSource extends Number> valuesData = XDDFDataSourcesFactory.fromArray(values1, valuesDataRange, 1);
+ values1[6] = 16.0; // if you ever want to change the underlying data
+ final XDDFNumericalDataSource extends Number> valuesData2 = XDDFDataSourcesFactory.fromArray(values2, valuesDataRange2, 2);
+
+
+ XDDFBarChartData bar = (XDDFBarChartData) chart.createData(ChartTypes.BAR, bottomAxis, leftAxis);
+ XDDFBarChartData.Series series1 = (XDDFBarChartData.Series) bar.addSeries(categoriesData, valuesData);
+ series1.setTitle(series[0], chart.setSheetTitle(series[0], 1));
+
+ XDDFBarChartData.Series series2 = (XDDFBarChartData.Series) bar.addSeries(categoriesData, valuesData2);
+ series2.setTitle(series[1], chart.setSheetTitle(series[1], 2));
+
+ bar.setVaryColors(true);
+ bar.setBarDirection(BarDirection.COL);
+ chart.plot(bar);
+
+ XDDFChartLegend legend = chart.getOrAddLegend();
+ legend.setPosition(LegendPosition.LEFT);
+ legend.setOverlay(false);
+
+ chart.setTitleText(chartTitle);
+ chart.setTitleOverlay(false);
+ }
+}
+
diff --git a/src/integrationtest/org/apache/poi/TestAllFiles.java b/src/integrationtest/org/apache/poi/TestAllFiles.java
index 61c47b9e88..40f19f9c85 100644
--- a/src/integrationtest/org/apache/poi/TestAllFiles.java
+++ b/src/integrationtest/org/apache/poi/TestAllFiles.java
@@ -289,6 +289,7 @@ public class TestAllFiles {
"document/Bug50955.doc",
"document/57843.doc",
"slideshow/PPT95.ppt",
+ "slideshow/pp40only.ppt",
"slideshow/Divino_Revelado.pptx",
"openxml4j/OPCCompliance_CoreProperties_DCTermsNamespaceLimitedUseFAIL.docx",
"openxml4j/OPCCompliance_CoreProperties_DoNotUseCompatibilityMarkupFAIL.docx",
diff --git a/src/integrationtest/org/apache/poi/stress/XSSFFileHandler.java b/src/integrationtest/org/apache/poi/stress/XSSFFileHandler.java
index 5c47d9af7e..48a30a2569 100644
--- a/src/integrationtest/org/apache/poi/stress/XSSFFileHandler.java
+++ b/src/integrationtest/org/apache/poi/stress/XSSFFileHandler.java
@@ -35,7 +35,6 @@ import java.util.Iterator;
import java.util.Locale;
import java.util.Set;
-import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
import org.apache.poi.EncryptedDocumentException;
@@ -148,7 +147,7 @@ public class XSSFFileHandler extends SpreadsheetHandler {
}
private void exportToXML(XSSFWorkbook wb) throws SAXException,
- ParserConfigurationException, TransformerException {
+ TransformerException {
for (XSSFMap map : wb.getCustomXMLMappings()) {
XSSFExportToXml exporter = new XSSFExportToXml(map);
@@ -165,7 +164,6 @@ public class XSSFFileHandler extends SpreadsheetHandler {
// zip-bomb
EXPECTED_ADDITIONAL_FAILURES.add("spreadsheet/54764.xlsx");
EXPECTED_ADDITIONAL_FAILURES.add("spreadsheet/54764-2.xlsx");
- EXPECTED_ADDITIONAL_FAILURES.add("spreadsheet/54764.xlsx");
EXPECTED_ADDITIONAL_FAILURES.add("spreadsheet/poc-xmlbomb.xlsx");
EXPECTED_ADDITIONAL_FAILURES.add("spreadsheet/poc-xmlbomb-empty.xlsx");
// strict OOXML
@@ -185,18 +183,19 @@ public class XSSFFileHandler extends SpreadsheetHandler {
public void handleAdditional(File file) throws Exception {
// redirect stdout as the examples often write lots of text
PrintStream oldOut = System.out;
+ String testFile = file.getParentFile().getName() + "/" + file.getName();
try {
System.setOut(new NullPrintStream());
FromHowTo.main(new String[]{file.getAbsolutePath()});
XLSX2CSV.main(new String[]{file.getAbsolutePath()});
assertFalse("Expected Extraction to fail for file " + file + " and handler " + this + ", but did not fail!",
- EXPECTED_ADDITIONAL_FAILURES.contains(file.getParentFile().getName() + "/" + file.getName()));
+ EXPECTED_ADDITIONAL_FAILURES.contains(testFile));
} catch (OLE2NotOfficeXmlFileException e) {
// we have some files that are not actually OOXML and thus cannot be tested here
} catch (IllegalArgumentException | InvalidFormatException | POIXMLException | IOException e) {
- if(!EXPECTED_ADDITIONAL_FAILURES.contains(file.getParentFile().getName() + "/" + file.getName())) {
+ if(!EXPECTED_ADDITIONAL_FAILURES.contains(testFile)) {
throw e;
}
} finally {
diff --git a/src/java/org/apache/poi/ddf/EscherProperties.java b/src/java/org/apache/poi/ddf/EscherProperties.java
index acff6241c2..482bce95c5 100644
--- a/src/java/org/apache/poi/ddf/EscherProperties.java
+++ b/src/java/org/apache/poi/ddf/EscherProperties.java
@@ -26,6 +26,7 @@ import java.util.Map;
*
* @author Glen Stampoultzis (glens at apache.org)
*/
+@SuppressWarnings("WeakerAccess")
public final class EscherProperties {
// Property constants
@@ -117,6 +118,15 @@ public final class EscherProperties {
public static final short GEOMETRY__ADJUST8VALUE = 334;
public static final short GEOMETRY__ADJUST9VALUE = 335;
public static final short GEOMETRY__ADJUST10VALUE = 336;
+ public static final short GEOMETRY__PCONNECTIONSITES = 337;
+ public static final short GEOMETRY__PCONNECTIONSITESDIR = 338;
+ public static final short GEOMETRY__XLIMO = 339;
+ public static final short GEOMETRY__YLIMO = 340;
+ public static final short GEOMETRY__PADJUSTHANDLES = 341;
+ public static final short GEOMETRY__PGUIDES = 342;
+ public static final short GEOMETRY__PINSCRIBE = 343;
+ public static final short GEOMETRY__CXK = 344;
+ public static final short GEOMETRY__PFRAGMENTS = 345;
public static final short GEOMETRY__SHADOWok = 378;
public static final short GEOMETRY__3DOK = 379;
public static final short GEOMETRY__LINEOK = 380;
@@ -333,6 +343,9 @@ public final class EscherProperties {
private static final Map properties = initProps();
+ private EscherProperties() {
+ }
+
private static Map initProps() {
Map m = new HashMap<>();
addProp(m, TRANSFORM__ROTATION, "transform.rotation");
@@ -423,6 +436,15 @@ public final class EscherProperties {
addProp(m, GEOMETRY__ADJUST8VALUE, "geometry.adjust8value");
addProp(m, GEOMETRY__ADJUST9VALUE, "geometry.adjust9value");
addProp(m, GEOMETRY__ADJUST10VALUE, "geometry.adjust10value");
+ addProp(m, GEOMETRY__PCONNECTIONSITES, "geometry.pConnectionSites");
+ addProp(m, GEOMETRY__PCONNECTIONSITESDIR, "geometry.pConnectionSitesDir");
+ addProp(m, GEOMETRY__XLIMO, "geometry.xLimo");
+ addProp(m, GEOMETRY__YLIMO, "geometry.yLimo");
+ addProp(m, GEOMETRY__PADJUSTHANDLES, "geometry.pAdjustHandles");
+ addProp(m, GEOMETRY__PGUIDES, "geometry.pGuides");
+ addProp(m, GEOMETRY__PINSCRIBE, "geometry.pInscribe");
+ addProp(m, GEOMETRY__CXK, "geometry.cxk");
+ addProp(m, GEOMETRY__PFRAGMENTS, "geometry.pFragments");
addProp(m, GEOMETRY__SHADOWok, "geometry.shadowOK");
addProp(m, GEOMETRY__3DOK, "geometry.3dok");
addProp(m, GEOMETRY__LINEOK, "geometry.lineok");
@@ -641,20 +663,20 @@ public final class EscherProperties {
}
private static void addProp(Map m, int s, String propName) {
- m.put(Short.valueOf((short) s), new EscherPropertyMetaData(propName));
+ m.put((short) s, new EscherPropertyMetaData(propName));
}
private static void addProp(Map m, int s, String propName, byte type) {
- m.put(Short.valueOf((short) s), new EscherPropertyMetaData(propName, type));
+ m.put((short) s, new EscherPropertyMetaData(propName, type));
}
public static String getPropertyName(short propertyId) {
- EscherPropertyMetaData o = properties.get(Short.valueOf(propertyId));
+ EscherPropertyMetaData o = properties.get(propertyId);
return o == null ? "unknown" : o.getDescription();
}
public static byte getPropertyType(short propertyId) {
- EscherPropertyMetaData escherPropertyMetaData = properties.get(Short.valueOf(propertyId));
+ EscherPropertyMetaData escherPropertyMetaData = properties.get(propertyId);
return escherPropertyMetaData == null ? 0 : escherPropertyMetaData.getType();
}
}
diff --git a/src/java/org/apache/poi/hpsf/VariantSupport.java b/src/java/org/apache/poi/hpsf/VariantSupport.java
index e60679027d..0e8dc08c6e 100644
--- a/src/java/org/apache/poi/hpsf/VariantSupport.java
+++ b/src/java/org/apache/poi/hpsf/VariantSupport.java
@@ -36,7 +36,7 @@ import org.apache.poi.util.POILogger;
* Supports reading and writing of variant data.
*
* FIXME (3): Reading and writing should be made more
- * uniform than it is now. The following items should be resolved:
+ * uniform than it is now. The following items should be resolved:
*
*
*
diff --git a/src/java/org/apache/poi/hpsf/wellknown/PropertyIDMap.java b/src/java/org/apache/poi/hpsf/wellknown/PropertyIDMap.java
index 130408e7b5..c01ded7fe8 100644
--- a/src/java/org/apache/poi/hpsf/wellknown/PropertyIDMap.java
+++ b/src/java/org/apache/poi/hpsf/wellknown/PropertyIDMap.java
@@ -33,8 +33,11 @@ import org.apache.poi.hpsf.SummaryInformation;
* The methods {@link #getSummaryInformationProperties} and {@link
* #getDocumentSummaryInformationProperties} return singleton {@link
* PropertyIDMap}s. An application that wants to extend these maps
- * should treat them as unmodifiable, copy them and modifiy the
+ * should treat them as unmodifiable, copy them and modify the
* copies.
+ *
+ * Trying to modify the map directly will cause exceptions
+ * {@link UnsupportedOperationException} to be thrown.
*/
public class PropertyIDMap implements Map {
@@ -490,11 +493,13 @@ public class PropertyIDMap implements Map {
@Override
public String put(Long key, String value) {
+ //noinspection ConstantConditions
return idMap.put(key, value);
}
@Override
public String remove(Object key) {
+ //noinspection ConstantConditions
return idMap.remove(key);
}
diff --git a/src/java/org/apache/poi/hssf/model/InternalWorkbook.java b/src/java/org/apache/poi/hssf/model/InternalWorkbook.java
index 46d8678229..4ff370125c 100644
--- a/src/java/org/apache/poi/hssf/model/InternalWorkbook.java
+++ b/src/java/org/apache/poi/hssf/model/InternalWorkbook.java
@@ -2276,6 +2276,8 @@ public final class InternalWorkbook {
/**
* Only for internal calls - code based on this is not supported ...
+ *
+ * @return The list of records.
*/
@Internal
public WorkbookRecordList getWorkbookRecordList() {
diff --git a/src/java/org/apache/poi/hssf/record/RecordInputStream.java b/src/java/org/apache/poi/hssf/record/RecordInputStream.java
index 3c9b977c79..400553721e 100644
--- a/src/java/org/apache/poi/hssf/record/RecordInputStream.java
+++ b/src/java/org/apache/poi/hssf/record/RecordInputStream.java
@@ -33,8 +33,9 @@ import org.apache.poi.util.LittleEndianInputStream;
import org.apache.poi.util.RecordFormatException;
/**
- * Title: Record Input Stream
- * Description: Wraps a stream and provides helper methods for the construction of records.
+ * Title: Record Input Stream
+ *
+ * Description: Wraps a stream and provides helper methods for the construction of records.
*/
public final class RecordInputStream implements LittleEndianInput {
@@ -142,6 +143,15 @@ public final class RecordInputStream implements LittleEndianInput {
_nextSid = readNextSid();
}
+ static LittleEndianInput getLEI(InputStream is) {
+ if (is instanceof LittleEndianInput) {
+ // accessing directly is an optimisation
+ return (LittleEndianInput) is;
+ }
+ // less optimal, but should work OK just the same. Often occurs in junit tests.
+ return new LittleEndianInputStream(is);
+ }
+
/**
* @return the number of bytes available in the current BIFF record
* @see #remaining()
@@ -295,12 +305,9 @@ public final class RecordInputStream implements LittleEndianInput {
return _dataInput.readUShort();
}
- /**
- *
- * @return a double - might return NaN
- */
@Override
public double readDouble() {
+ // YK: Excel doesn't write NaN but instead converts the cell type into {@link CellType#ERROR}.
return Double.longBitsToDouble(readLong());
}
diff --git a/src/java/org/apache/poi/hssf/record/SSTRecord.java b/src/java/org/apache/poi/hssf/record/SSTRecord.java
index 20d99319d6..1de2fe4fc2 100644
--- a/src/java/org/apache/poi/hssf/record/SSTRecord.java
+++ b/src/java/org/apache/poi/hssf/record/SSTRecord.java
@@ -161,7 +161,7 @@ public final class SSTRecord extends ContinuableRecord {
*
* The data consists of sets of string data. This string data is
* arranged as follows:
- *
+ *
*
* short string_length; // length of string data
* byte string_flag; // flag specifying special string
@@ -176,9 +176,9 @@ public final class SSTRecord extends ContinuableRecord {
* byte[] extension; // optional extension (length of array
* // is extend_length)
*
- *
+ *
* The string_flag is bit mapped as follows:
- *
+ *
*
*
*
Bit number
@@ -232,7 +232,7 @@ public final class SSTRecord extends ContinuableRecord {
* associated data. The UnicodeString class can handle the byte[]
* vs short[] nature of the actual string data
*
- * @param in the RecordInputstream to read the record from
+ * @param in the RecordInputStream to read the record from
*/
public SSTRecord(RecordInputStream in) {
// this method is ALWAYS called after construction -- using
diff --git a/src/java/org/apache/poi/hssf/record/SharedFormulaRecord.java b/src/java/org/apache/poi/hssf/record/SharedFormulaRecord.java
index 770f740a09..328402db80 100644
--- a/src/java/org/apache/poi/hssf/record/SharedFormulaRecord.java
+++ b/src/java/org/apache/poi/hssf/record/SharedFormulaRecord.java
@@ -77,7 +77,7 @@ public final class SharedFormulaRecord extends SharedValueRecordBase {
public String toString()
{
- StringBuffer buffer = new StringBuffer();
+ StringBuilder buffer = new StringBuilder();
buffer.append("[SHARED FORMULA (").append(HexDump.intToHex(sid)).append("]\n");
buffer.append(" .range = ").append(getRange()).append("\n");
@@ -99,6 +99,10 @@ public final class SharedFormulaRecord extends SharedValueRecordBase {
}
/**
+ * Convert formula into an array of {@link Ptg} tokens.
+ *
+ * @param formula The record to break into tokens, cannot be null
+ *
* @return the equivalent {@link Ptg} array that the formula would have, were it not shared.
*/
public Ptg[] getFormulaTokens(FormulaRecord formula) {
diff --git a/src/java/org/apache/poi/hssf/record/SharedValueRecordBase.java b/src/java/org/apache/poi/hssf/record/SharedValueRecordBase.java
index a5035303a3..51fe091808 100644
--- a/src/java/org/apache/poi/hssf/record/SharedValueRecordBase.java
+++ b/src/java/org/apache/poi/hssf/record/SharedValueRecordBase.java
@@ -42,6 +42,8 @@ public abstract class SharedValueRecordBase extends StandardRecord {
/**
* reads only the range (1 {@link CellRangeAddress8Bit}) from the stream
+ *
+ * @param in The interface for reading the record data.
*/
public SharedValueRecordBase(LittleEndianInput in) {
_range = new CellRangeAddress8Bit(in);
@@ -99,14 +101,12 @@ public abstract class SharedValueRecordBase extends StandardRecord {
&& r.getLastColumn() >= colIx;
}
/**
- * @return {@code true} if (rowIx, colIx) describes the first cell in this shared value
- * object's range
- *
* @param rowIx the row index
* @param colIx the column index
- *
- * @return {@code true} if its the first cell in this shared value object range
- *
+ *
+ * @return {@code true} if (rowIx, colIx) describes the first cell in this shared value
+ * object's range
+ *
* @see #getRange()
*/
public final boolean isFirstCell(int rowIx, int colIx) {
diff --git a/src/java/org/apache/poi/poifs/crypt/ChunkedCipherOutputStream.java b/src/java/org/apache/poi/poifs/crypt/ChunkedCipherOutputStream.java
index 9da03cf2e2..0aa73fd670 100644
--- a/src/java/org/apache/poi/poifs/crypt/ChunkedCipherOutputStream.java
+++ b/src/java/org/apache/poi/poifs/crypt/ChunkedCipherOutputStream.java
@@ -99,6 +99,13 @@ public abstract class ChunkedCipherOutputStream extends FilterOutputStream {
return initCipherForBlock(cipher, block, lastChunk);
}
+ // helper method to break a recursion loop introduced because of an IBMJCE bug, i.e. not resetting on Cipher.doFinal()
+ @Internal
+ protected Cipher initCipherForBlockNoFlush(Cipher existing, int block, boolean lastChunk)
+ throws IOException, GeneralSecurityException {
+ return initCipherForBlock(cipher, block, lastChunk);
+ }
+
protected abstract Cipher initCipherForBlock(Cipher existing, int block, boolean lastChunk)
throws IOException, GeneralSecurityException;
@@ -212,13 +219,30 @@ public abstract class ChunkedCipherOutputStream extends FilterOutputStream {
* @throws IllegalBlockSizeException
* @throws ShortBufferException
*/
- protected int invokeCipher(int posInChunk, boolean doFinal) throws GeneralSecurityException {
+ protected int invokeCipher(int posInChunk, boolean doFinal) throws GeneralSecurityException, IOException {
byte plain[] = (plainByteFlags.isEmpty()) ? null : chunk.clone();
int ciLen = (doFinal)
? cipher.doFinal(chunk, 0, posInChunk, chunk)
: cipher.update(chunk, 0, posInChunk, chunk);
+ if (doFinal && "IBMJCE".equals(cipher.getProvider().getName()) && "RC4".equals(cipher.getAlgorithm())) {
+ // workaround for IBMs cipher not resetting on doFinal
+
+ int index = (int)(pos >> chunkBits);
+ boolean lastChunk;
+ if (posInChunk==0) {
+ index--;
+ posInChunk = chunk.length;
+ lastChunk = false;
+ } else {
+ // pad the last chunk
+ lastChunk = true;
+ }
+
+ cipher = initCipherForBlockNoFlush(cipher, index, lastChunk);
+ }
+
if (plain != null) {
int i = plainByteFlags.nextSetBit(0);
while (i >= 0 && i < posInChunk) {
diff --git a/src/java/org/apache/poi/poifs/crypt/cryptoapi/CryptoAPIEncryptor.java b/src/java/org/apache/poi/poifs/crypt/cryptoapi/CryptoAPIEncryptor.java
index b412585261..9221d4a390 100644
--- a/src/java/org/apache/poi/poifs/crypt/cryptoapi/CryptoAPIEncryptor.java
+++ b/src/java/org/apache/poi/poifs/crypt/cryptoapi/CryptoAPIEncryptor.java
@@ -207,9 +207,15 @@ public class CryptoAPIEncryptor extends Encryptor implements Cloneable {
protected Cipher initCipherForBlock(Cipher cipher, int block, boolean lastChunk)
throws IOException, GeneralSecurityException {
flush();
+ return initCipherForBlockNoFlush(cipher, block, lastChunk);
+ }
+
+ @Override
+ protected Cipher initCipherForBlockNoFlush(Cipher existing, int block, boolean lastChunk)
+ throws GeneralSecurityException {
EncryptionInfo ei = getEncryptionInfo();
SecretKey sk = getSecretKey();
- return CryptoAPIDecryptor.initCipherForBlock(cipher, block, ei, sk, Cipher.ENCRYPT_MODE);
+ return CryptoAPIDecryptor.initCipherForBlock(existing, block, ei, sk, Cipher.ENCRYPT_MODE);
}
@Override
diff --git a/src/java/org/apache/poi/poifs/filesystem/FileMagic.java b/src/java/org/apache/poi/poifs/filesystem/FileMagic.java
index 4ac616082e..bab62c6437 100644
--- a/src/java/org/apache/poi/poifs/filesystem/FileMagic.java
+++ b/src/java/org/apache/poi/poifs/filesystem/FileMagic.java
@@ -78,7 +78,7 @@ public enum FileMagic {
/** PDF document */
PDF("%PDF"),
/** Some different HTML documents */
- HTML("
diff --git a/src/java/org/apache/poi/sl/draw/DrawBackground.java b/src/java/org/apache/poi/sl/draw/DrawBackground.java
index 1e9d5945b3..c61f6dbb79 100644
--- a/src/java/org/apache/poi/sl/draw/DrawBackground.java
+++ b/src/java/org/apache/poi/sl/draw/DrawBackground.java
@@ -17,6 +17,8 @@
package org.apache.poi.sl.draw;
+import static org.apache.poi.sl.draw.DrawPaint.fillPaintWorkaround;
+
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Paint;
@@ -59,10 +61,10 @@ public class DrawBackground extends DrawShape {
if(fill != null) {
graphics.setRenderingHint(Drawable.GRADIENT_SHAPE, anchor);
graphics.setPaint(fill);
- graphics.fill(anchor2);
+ fillPaintWorkaround(graphics, anchor2);
}
}
-
+
protected Background,?> getShape() {
return (Background,?>)shape;
}
diff --git a/src/java/org/apache/poi/sl/draw/DrawFreeformShape.java b/src/java/org/apache/poi/sl/draw/DrawFreeformShape.java
index 6eb60dfb52..be18f037ab 100644
--- a/src/java/org/apache/poi/sl/draw/DrawFreeformShape.java
+++ b/src/java/org/apache/poi/sl/draw/DrawFreeformShape.java
@@ -17,43 +17,11 @@
package org.apache.poi.sl.draw;
-import java.awt.Graphics2D;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Path2D;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-import org.apache.poi.sl.draw.geom.Outline;
-import org.apache.poi.sl.draw.geom.Path;
-import org.apache.poi.sl.usermodel.*;
+import org.apache.poi.sl.usermodel.FreeformShape;
+@SuppressWarnings("WeakerAccess")
public class DrawFreeformShape extends DrawAutoShape {
public DrawFreeformShape(FreeformShape,?> shape) {
super(shape);
}
-
- protected Collection computeOutlines(Graphics2D graphics) {
- List lst = new ArrayList<>();
- FreeformShape,?> fsh = (FreeformShape, ?>) getShape();
- Path2D sh = fsh.getPath();
-
- AffineTransform tx = (AffineTransform)graphics.getRenderingHint(Drawable.GROUP_TRANSFORM);
- if (tx == null) {
- tx = new AffineTransform();
- }
-
- java.awt.Shape canvasShape = tx.createTransformedShape(sh);
-
- FillStyle fs = fsh.getFillStyle();
- StrokeStyle ss = fsh.getStrokeStyle();
- Path path = new Path(fs != null, ss != null);
- lst.add(new Outline(canvasShape, path));
- return lst;
- }
-
- @Override
- protected TextShape,? extends TextParagraph,?,? extends TextRun>> getShape() {
- return (TextShape,? extends TextParagraph,?,? extends TextRun>>)shape;
- }
}
diff --git a/src/java/org/apache/poi/sl/draw/DrawPaint.java b/src/java/org/apache/poi/sl/draw/DrawPaint.java
index d6986f3023..80c5bcb00b 100644
--- a/src/java/org/apache/poi/sl/draw/DrawPaint.java
+++ b/src/java/org/apache/poi/sl/draw/DrawPaint.java
@@ -23,13 +23,17 @@ import java.awt.Graphics2D;
import java.awt.LinearGradientPaint;
import java.awt.Paint;
import java.awt.RadialGradientPaint;
+import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
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 +201,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 +293,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 +337,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 +356,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 +373,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 +396,63 @@ public class DrawPaint {
}
Rectangle2D anchor = DrawShape.getAnchor(graphics, shape);
- final double h = anchor.getHeight(), w = anchor.getWidth(), x = anchor.getX(), y = anchor.getY();
AffineTransform at = AffineTransform.getRotateInstance(Math.toRadians(angle), anchor.getCenterX(), anchor.getCenterY());
- double diagonal = Math.sqrt(h * h + w * w);
- Point2D p1 = new Point2D.Double(x + w / 2 - diagonal / 2, y + h / 2);
- p1 = at.transform(p1, null);
-
- Point2D p2 = new Point2D.Double(x + w, y + h / 2);
- p2 = at.transform(p2, null);
+ double diagonal = Math.sqrt(Math.pow(anchor.getWidth(),2) + Math.pow(anchor.getHeight(),2));
+ final Point2D p1 = at.transform(new Point2D.Double(anchor.getCenterX() - diagonal / 2, anchor.getCenterY()), null);
+ final Point2D p2 = at.transform(new Point2D.Double(anchor.getMaxX(), anchor.getCenterY()), null);
// snapToAnchor(p1, anchor);
// snapToAnchor(p2, anchor);
- if (p1.equals(p2)) {
- // gradient paint on the same point throws an exception ... and doesn't make sense
- return null;
- }
-
- float[] fractions = fill.getGradientFractions();
- Color[] colors = new Color[fractions.length];
-
- int i = 0;
- for (ColorStyle fc : fill.getGradientColors()) {
- // if fc is null, use transparent color to get color of background
- colors[i++] = (fc == null) ? TRANSPARENT : applyColorTransform(fc);
- }
-
- return new LinearGradientPaint(p1, p2, fractions, colors);
+ // gradient paint on the same point throws an exception ... and doesn't make sense
+ return (p1.equals(p2)) ? null : safeFractions((f,c)->new LinearGradientPaint(p1,p2,f,c), fill);
}
+
@SuppressWarnings("WeakerAccess")
protected Paint createRadialGradientPaint(GradientPaint fill, Graphics2D graphics) {
Rectangle2D anchor = DrawShape.getAnchor(graphics, shape);
- Point2D pCenter = new Point2D.Double(anchor.getX() + anchor.getWidth()/2,
- anchor.getY() + anchor.getHeight()/2);
+ final Point2D pCenter = new Point2D.Double(anchor.getCenterX(), anchor.getCenterY());
- float radius = (float)Math.max(anchor.getWidth(), anchor.getHeight());
+ final float radius = (float)Math.max(anchor.getWidth(), anchor.getHeight());
- float[] fractions = fill.getGradientFractions();
- Color[] colors = new Color[fractions.length];
-
- int i=0;
- for (ColorStyle fc : fill.getGradientColors()) {
- colors[i++] = applyColorTransform(fc);
- }
-
- return new RadialGradientPaint(pCenter, radius, fractions, colors);
+ return safeFractions((f,c)->new RadialGradientPaint(pCenter,radius,f,c), fill);
}
@SuppressWarnings({"WeakerAccess", "unused"})
protected Paint createPathGradientPaint(GradientPaint fill, Graphics2D graphics) {
// currently we ignore an eventually center setting
- float[] fractions = fill.getGradientFractions();
- Color[] colors = new Color[fractions.length];
+ return safeFractions(PathGradientPaint::new, fill);
+ }
- int i=0;
- for (ColorStyle fc : fill.getGradientColors()) {
- colors[i++] = applyColorTransform(fc);
+ private Paint safeFractions(BiFunction init, GradientPaint fill) {
+ float[] fractions = fill.getGradientFractions();
+ final ColorStyle[] styles = fill.getGradientColors();
+
+ // need to remap the fractions, because Java doesn't like repeating fraction values
+ Map m = new TreeMap<>();
+ for (int i = 0; i me : m.entrySet()) {
+ fractions[i] = me.getKey();
+ colors[i] = me.getValue();
+ i++;
+ }
+
+ return init.apply(fractions, colors);
}
/**
@@ -620,4 +606,19 @@ public class DrawPaint {
return (float)(1.055d * Math.pow(linRGB / 100000d, 1.0d/2.4d) - 0.055d);
}
}
+
+
+ static void fillPaintWorkaround(Graphics2D graphics, Shape shape) {
+ // the ibm jdk has a rendering/JIT bug, which throws an AIOOBE in
+ // TexturePaintContext$Int.setRaster(TexturePaintContext.java:476)
+ // this usually doesn't happen while debugging, because JIT doesn't jump in then.
+ try {
+ graphics.fill(shape);
+ } catch (ArrayIndexOutOfBoundsException e) {
+ LOG.log(POILogger.WARN, "IBM JDK failed with TexturePaintContext AIOOBE - try adding the following to the VM parameter:\n" +
+ "-Xjit:exclude={sun/java2d/pipe/AlphaPaintPipe.renderPathTile(Ljava/lang/Object;[BIIIIII)V} and " +
+ "search for 'JIT Problem Determination for IBM SDK using -Xjit' (http://www-01.ibm.com/support/docview.wss?uid=swg21294023) " +
+ "for how to add/determine further excludes", e);
+ }
+ }
}
diff --git a/src/java/org/apache/poi/sl/draw/DrawSimpleShape.java b/src/java/org/apache/poi/sl/draw/DrawSimpleShape.java
index 7ed1d35da2..a8d6fb534e 100644
--- a/src/java/org/apache/poi/sl/draw/DrawSimpleShape.java
+++ b/src/java/org/apache/poi/sl/draw/DrawSimpleShape.java
@@ -17,6 +17,8 @@
package org.apache.poi.sl.draw;
+import static org.apache.poi.sl.draw.DrawPaint.fillPaintWorkaround;
+
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
@@ -87,7 +89,7 @@ public class DrawSimpleShape extends DrawShape {
graphics.setPaint(fillMod);
java.awt.Shape s = o.getOutline();
graphics.setRenderingHint(Drawable.GRADIENT_SHAPE, s);
- graphics.fill(s);
+ fillPaintWorkaround(graphics, s);
}
}
}
@@ -327,7 +329,7 @@ public class DrawSimpleShape extends DrawShape {
graphics.setPaint(shadowColor);
if(fill != null && p.isFilled()){
- graphics.fill(s);
+ fillPaintWorkaround(graphics, s);
} else if (line != null && p.isStroked()) {
graphics.draw(s);
}
@@ -410,14 +412,20 @@ public class DrawSimpleShape extends DrawShape {
}
for (Path p : geom) {
- double w = p.getW(), h = p.getH(), scaleX = Units.toPoints(1), scaleY = scaleX;
+ double w = p.getW(), h = p.getH(), scaleX, scaleY;
if (w == -1) {
w = Units.toEMU(anchor.getWidth());
+ scaleX = Units.toPoints(1);
+ } else if (anchor.getWidth() == 0) {
+ scaleX = 1;
} else {
scaleX = anchor.getWidth() / w;
}
if (h == -1) {
h = Units.toEMU(anchor.getHeight());
+ scaleY = Units.toPoints(1);
+ } else if (anchor.getHeight() == 0) {
+ scaleY = 1;
} else {
scaleY = anchor.getHeight() / h;
}
diff --git a/src/java/org/apache/poi/sl/draw/DrawTableShape.java b/src/java/org/apache/poi/sl/draw/DrawTableShape.java
index 905196fc90..703fb04d82 100644
--- a/src/java/org/apache/poi/sl/draw/DrawTableShape.java
+++ b/src/java/org/apache/poi/sl/draw/DrawTableShape.java
@@ -17,6 +17,8 @@
package org.apache.poi.sl.draw;
+import static org.apache.poi.sl.draw.DrawPaint.fillPaintWorkaround;
+
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Paint;
@@ -83,8 +85,8 @@ public class DrawTableShape extends DrawShape {
Paint fillPaint = drawPaint.getPaint(graphics, tc.getFillStyle().getPaint());
graphics.setPaint(fillPaint);
Rectangle2D cellAnc = tc.getAnchor();
- graphics.fill(cellAnc);
-
+ fillPaintWorkaround(graphics, cellAnc);
+
for (BorderEdge edge : BorderEdge.values()) {
StrokeStyle stroke = tc.getBorderStyle(edge);
if (stroke == null) {
diff --git a/src/java/org/apache/poi/sl/draw/PathGradientPaint.java b/src/java/org/apache/poi/sl/draw/PathGradientPaint.java
index d4a2a5fa5f..2281bbff83 100644
--- a/src/java/org/apache/poi/sl/draw/PathGradientPaint.java
+++ b/src/java/org/apache/poi/sl/draw/PathGradientPaint.java
@@ -23,21 +23,24 @@ import java.awt.MultipleGradientPaint.CycleMethod;
import java.awt.geom.*;
import java.awt.image.*;
+import org.apache.poi.util.Internal;
+
+@Internal
class PathGradientPaint implements Paint {
// http://asserttrue.blogspot.de/2010/01/how-to-iimplement-custom-paint-in-50.html
- protected final Color colors[];
- protected final float fractions[];
- protected final int capStyle;
- protected final int joinStyle;
- protected final int transparency;
+ private final Color[] colors;
+ private final float[] fractions;
+ private final int capStyle;
+ private final int joinStyle;
+ private final int transparency;
- public PathGradientPaint(Color colors[], float fractions[]) {
- this(colors,fractions,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND);
+ PathGradientPaint(float[] fractions, Color[] colors) {
+ this(fractions,colors,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND);
}
- public PathGradientPaint(Color colors[], float fractions[], int capStyle, int joinStyle) {
+ private PathGradientPaint(float[] fractions, Color[] colors, int capStyle, int joinStyle) {
this.colors = colors.clone();
this.fractions = fractions.clone();
this.capStyle = capStyle;
@@ -66,26 +69,26 @@ class PathGradientPaint implements Paint {
}
class PathGradientContext implements PaintContext {
- protected final Rectangle deviceBounds;
- protected final Rectangle2D userBounds;
+ final Rectangle deviceBounds;
+ final Rectangle2D userBounds;
protected final AffineTransform xform;
- protected final RenderingHints hints;
+ final RenderingHints hints;
/**
* for POI: the shape will be only known when the subclasses determines the concrete implementation
* in the draw/-content method, so we need to postpone the setting/creation as long as possible
**/
protected final Shape shape;
- protected final PaintContext pCtx;
- protected final int gradientSteps;
+ final PaintContext pCtx;
+ final int gradientSteps;
WritableRaster raster;
- public PathGradientContext(
- ColorModel cm
- , Rectangle deviceBounds
- , Rectangle2D userBounds
- , AffineTransform xform
- , RenderingHints hints
+ PathGradientContext(
+ ColorModel cm
+ , Rectangle deviceBounds
+ , Rectangle2D userBounds
+ , AffineTransform xform
+ , RenderingHints hints
) {
shape = (Shape)hints.get(Drawable.GRADIENT_SHAPE);
if (shape == null) {
@@ -139,7 +142,7 @@ class PathGradientPaint implements Paint {
return childRaster;
}
- protected int getGradientSteps(Shape gradientShape) {
+ int getGradientSteps(Shape gradientShape) {
Rectangle rect = gradientShape.getBounds();
int lower = 1;
int upper = (int)(Math.max(rect.getWidth(),rect.getHeight())/2.0);
@@ -158,7 +161,7 @@ class PathGradientPaint implements Paint {
- protected void createRaster() {
+ void createRaster() {
ColorModel cm = getColorModel();
raster = cm.createCompatibleWritableRaster((int)deviceBounds.getWidth(), (int)deviceBounds.getHeight());
BufferedImage img = new BufferedImage(cm, raster, false, null);
@@ -168,7 +171,7 @@ class PathGradientPaint implements Paint {
graphics.transform(xform);
Raster img2 = pCtx.getRaster(0, 0, gradientSteps, 1);
- int rgb[] = new int[cm.getNumComponents()];
+ int[] rgb = new int[cm.getNumComponents()];
for (int i = gradientSteps-1; i>=0; i--) {
img2.getPixel(i, 0, rgb);
diff --git a/src/java/org/apache/poi/sl/draw/geom/Context.java b/src/java/org/apache/poi/sl/draw/geom/Context.java
index 31847ceeff..3ed84b3d18 100644
--- a/src/java/org/apache/poi/sl/draw/geom/Context.java
+++ b/src/java/org/apache/poi/sl/draw/geom/Context.java
@@ -22,11 +22,18 @@ package org.apache.poi.sl.draw.geom;
import java.awt.geom.Rectangle2D;
import java.util.HashMap;
import java.util.Map;
+import java.util.regex.Pattern;
public class Context {
- final Map _ctx = new HashMap<>();
- final IAdjustableShape _props;
- final Rectangle2D _anchor;
+ private static final Pattern DOUBLE_PATTERN = Pattern.compile(
+ "[\\x00-\\x20]*[+-]?(NaN|Infinity|((((\\p{Digit}+)(\\.)?((\\p{Digit}+)?)" +
+ "([eE][+-]?(\\p{Digit}+))?)|(\\.(\\p{Digit}+)([eE][+-]?(\\p{Digit}+))?)|" +
+ "(((0[xX](\\p{XDigit}+)(\\.)?)|(0[xX](\\p{XDigit}+)?(\\.)(\\p{XDigit}+)))" +
+ "[pP][+-]?(\\p{Digit}+)))[fFdD]?))[\\x00-\\x20]*");
+
+ private final Map _ctx = new HashMap<>();
+ private final IAdjustableShape _props;
+ private final Rectangle2D _anchor;
public Context(CustomGeometry geom, Rectangle2D anchor, IAdjustableShape props){
_props = props;
@@ -39,23 +46,22 @@ public class Context {
}
}
- public Rectangle2D getShapeAnchor(){
+ Rectangle2D getShapeAnchor(){
return _anchor;
}
- public Guide getAdjustValue(String name){
+ Guide getAdjustValue(String name){
// ignore HSLF props for now ... the results with default value are usually better - see #59004
return (_props.getClass().getName().contains("hslf")) ? null : _props.getAdjustValue(name);
}
public double getValue(String key){
- if(key.matches("(\\+|-)?\\d+")){
+ if(DOUBLE_PATTERN.matcher(key).matches()){
return Double.parseDouble(key);
}
- Double val = _ctx.get(key);
// BuiltInGuide throws IllegalArgumentException if key is not defined
- return (val != null) ? val : evaluate(BuiltInGuide.valueOf("_"+key));
+ return _ctx.containsKey(key) ? _ctx.get(key) : evaluate(BuiltInGuide.valueOf("_"+key));
}
public double evaluate(Formula fmla){
diff --git a/src/java/org/apache/poi/sl/draw/geom/PresetGeometries.java b/src/java/org/apache/poi/sl/draw/geom/PresetGeometries.java
index a188e6e255..f8b461f929 100644
--- a/src/java/org/apache/poi/sl/draw/geom/PresetGeometries.java
+++ b/src/java/org/apache/poi/sl/draw/geom/PresetGeometries.java
@@ -27,12 +27,12 @@ import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.stream.EventFilter;
-import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
-import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;
+import javax.xml.transform.stream.StreamSource;
import org.apache.poi.sl.draw.binding.CTCustomGeometry2D;
import org.apache.poi.util.POILogFactory;
@@ -61,27 +61,30 @@ public class PresetGeometries extends LinkedHashMap {
};
XMLInputFactory staxFactory = StaxHelper.newXMLInputFactory();
- XMLEventReader staxReader = staxFactory.createXMLEventReader(is);
- XMLEventReader staxFiltRd = staxFactory.createFilteredReader(staxReader, startElementFilter);
- // ignore StartElement:
- /* XMLEvent evDoc = */ staxFiltRd.nextEvent();
- // JAXB:
- JAXBContext jaxbContext = JAXBContext.newInstance(BINDING_PACKAGE);
- Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
+ XMLStreamReader streamReader = staxFactory.createXMLStreamReader(new StreamSource(is));
+ try {
+ // ignore StartElement:
+ streamReader.nextTag();
- long cntElem = 0;
- while (staxFiltRd.peek() != null) {
- StartElement evRoot = (StartElement)staxFiltRd.peek();
- String name = evRoot.getName().getLocalPart();
- JAXBElement el = unmarshaller.unmarshal(staxReader, CTCustomGeometry2D.class);
- CTCustomGeometry2D cus = el.getValue();
- cntElem++;
-
- if(containsKey(name)) {
- LOG.log(POILogger.WARN, "Duplicate definition of " + name);
+ // JAXB:
+ JAXBContext jaxbContext = JAXBContext.newInstance(BINDING_PACKAGE);
+ Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
+
+ long cntElem = 0;
+ while (streamReader.hasNext() && streamReader.nextTag() == XMLStreamConstants.START_ELEMENT) {
+ String name = streamReader.getLocalName();
+ JAXBElement el = unmarshaller.unmarshal(streamReader, CTCustomGeometry2D.class);
+ CTCustomGeometry2D cus = el.getValue();
+ cntElem++;
+
+ if (containsKey(name)) {
+ LOG.log(POILogger.WARN, "Duplicate definition of " + name);
+ }
+ put(name, new CustomGeometry(cus));
}
- put(name, new CustomGeometry(cus));
- }
+ } finally {
+ streamReader.close();
+ }
}
/**
diff --git a/src/java/org/apache/poi/sl/usermodel/FreeformShape.java b/src/java/org/apache/poi/sl/usermodel/FreeformShape.java
index 2a1580a7da..42ae10ae9a 100644
--- a/src/java/org/apache/poi/sl/usermodel/FreeformShape.java
+++ b/src/java/org/apache/poi/sl/usermodel/FreeformShape.java
@@ -24,16 +24,15 @@ public interface FreeformShape<
P extends TextParagraph
> extends AutoShape {
/**
- * Gets the shape path.
- *
- * The path is translated in the shape's coordinate system, i.e.
- * freeform.getPath().getBounds2D() equals to freeform.getAnchor()
- * (small discrepancies are possible due to rounding errors)
- *
+ * Gets the shape path.
+ *
+ * The path is translated in the shape's coordinate system, i.e.
+ * freeform.getPath2D().getBounds2D() equals to freeform.getAnchor()
+ * (small discrepancies are possible due to rounding errors)
*
* @return the path
*/
- Path2D.Double getPath();
+ Path2D getPath();
/**
* Set the shape path
@@ -41,5 +40,5 @@ public interface FreeformShape<
* @param path shape outline
* @return the number of points written
*/
- int setPath(Path2D.Double path);
+ int setPath(Path2D path);
}
diff --git a/src/java/org/apache/poi/ss/formula/SheetNameFormatter.java b/src/java/org/apache/poi/ss/formula/SheetNameFormatter.java
index c6e13c3110..6e10e67c58 100644
--- a/src/java/org/apache/poi/ss/formula/SheetNameFormatter.java
+++ b/src/java/org/apache/poi/ss/formula/SheetNameFormatter.java
@@ -59,6 +59,7 @@ public final class SheetNameFormatter {
* @param rawSheetName - sheet name
* @deprecated use appendFormat(StringBuilder out, String rawSheetName) instead
*/
+ @Deprecated
public static void appendFormat(StringBuffer out, String rawSheetName) {
boolean needsQuotes = needsDelimiting(rawSheetName);
if(needsQuotes) {
@@ -73,6 +74,7 @@ public final class SheetNameFormatter {
/**
* @deprecated use appendFormat(StringBuilder out, String workbookName, String rawSheetName) instead
*/
+ @Deprecated
public static void appendFormat(StringBuffer out, String workbookName, String rawSheetName) {
boolean needsQuotes = needsDelimiting(workbookName) || needsDelimiting(rawSheetName);
if(needsQuotes) {
@@ -123,7 +125,7 @@ public final class SheetNameFormatter {
}
}
- private static void appendAndEscape(Appendable sb, String rawSheetName) {
+ static void appendAndEscape(Appendable sb, String rawSheetName) {
int len = rawSheetName.length();
for(int i=0; i= 0) {
+ sb.append('[');
+ sb.append(workbookIndex);
+ sb.append(']');
+ }
+
+ SheetNameFormatter.appendAndEscape(sb, firstSheetName);
+
+ if (lastSheetName != null) {
+ sb.append(':');
+ SheetNameFormatter.appendAndEscape(sb, lastSheetName);
+ }
+
+ sb.append('\'');
+ return sb.toString();
+ }
+
+ private static String formatWithoutDelimiting(StringBuilder sb, int workbookIndex, String firstSheetName, String lastSheetName) {
+ if (workbookIndex >= 0) {
+ sb.append('[');
+ sb.append(workbookIndex);
+ sb.append(']');
+ }
+
+ sb.append(firstSheetName);
+
+ if (lastSheetName != null) {
+ sb.append(':');
+ sb.append(lastSheetName);
+ }
+
+ return sb.toString();
+ }
+
+ private static boolean anySheetNameNeedsEscaping(String firstSheetName, String lastSheetName) {
+ boolean anySheetNameNeedsDelimiting = firstSheetName != null && SheetNameFormatter.needsDelimiting(firstSheetName);
+ anySheetNameNeedsDelimiting |= lastSheetName != null && SheetNameFormatter.needsDelimiting(lastSheetName);
+ return anySheetNameNeedsDelimiting;
+ }
+}
diff --git a/src/java/org/apache/poi/ss/formula/functions/MatrixFunction.java b/src/java/org/apache/poi/ss/formula/functions/MatrixFunction.java
index 6b111cfc1a..04e7f4cd77 100644
--- a/src/java/org/apache/poi/ss/formula/functions/MatrixFunction.java
+++ b/src/java/org/apache/poi/ss/formula/functions/MatrixFunction.java
@@ -63,7 +63,7 @@ public abstract class MatrixFunction implements Function{
i = 0;
j++;
}
- matrix[j][i++] = aVector;
+ if (j < matrix.length) matrix[j][i++] = aVector;
}
}
diff --git a/src/java/org/apache/poi/ss/formula/ptg/Area3DPxg.java b/src/java/org/apache/poi/ss/formula/ptg/Area3DPxg.java
index 65f59e83e1..41bea0c950 100644
--- a/src/java/org/apache/poi/ss/formula/ptg/Area3DPxg.java
+++ b/src/java/org/apache/poi/ss/formula/ptg/Area3DPxg.java
@@ -20,6 +20,7 @@ package org.apache.poi.ss.formula.ptg;
import org.apache.poi.ss.SpreadsheetVersion;
import org.apache.poi.ss.formula.SheetIdentifier;
import org.apache.poi.ss.formula.SheetNameFormatter;
+import org.apache.poi.ss.formula.SheetRangeAndWorkbookIndexFormatter;
import org.apache.poi.ss.formula.SheetRangeIdentifier;
import org.apache.poi.ss.util.AreaReference;
import org.apache.poi.util.LittleEndianOutput;
@@ -102,16 +103,8 @@ public final class Area3DPxg extends AreaPtgBase implements Pxg3D {
public String toFormulaString() {
StringBuilder sb = new StringBuilder(64);
- if (externalWorkbookNumber >= 0) {
- sb.append('[');
- sb.append(externalWorkbookNumber);
- sb.append(']');
- }
- SheetNameFormatter.appendFormat(sb, firstSheetName);
- if (lastSheetName != null) {
- sb.append(':');
- SheetNameFormatter.appendFormat(sb, lastSheetName);
- }
+
+ SheetRangeAndWorkbookIndexFormatter.format(sb, externalWorkbookNumber, firstSheetName, lastSheetName);
sb.append('!');
sb.append(formatReferenceAsString());
return sb.toString();
diff --git a/src/java/org/apache/poi/ss/formula/ptg/Ref3DPxg.java b/src/java/org/apache/poi/ss/formula/ptg/Ref3DPxg.java
index 67f73b360d..12e7e54eda 100644
--- a/src/java/org/apache/poi/ss/formula/ptg/Ref3DPxg.java
+++ b/src/java/org/apache/poi/ss/formula/ptg/Ref3DPxg.java
@@ -18,7 +18,7 @@
package org.apache.poi.ss.formula.ptg;
import org.apache.poi.ss.formula.SheetIdentifier;
-import org.apache.poi.ss.formula.SheetNameFormatter;
+import org.apache.poi.ss.formula.SheetRangeAndWorkbookIndexFormatter;
import org.apache.poi.ss.formula.SheetRangeIdentifier;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.util.LittleEndianOutput;
@@ -101,18 +101,8 @@ public final class Ref3DPxg extends RefPtgBase implements Pxg3D {
public String toFormulaString() {
StringBuilder sb = new StringBuilder(64);
- if (externalWorkbookNumber >= 0) {
- sb.append('[');
- sb.append(externalWorkbookNumber);
- sb.append(']');
- }
- if (firstSheetName != null) {
- SheetNameFormatter.appendFormat(sb, firstSheetName);
- }
- if (lastSheetName != null) {
- sb.append(':');
- SheetNameFormatter.appendFormat(sb, lastSheetName);
- }
+
+ SheetRangeAndWorkbookIndexFormatter.format(sb, externalWorkbookNumber, firstSheetName, lastSheetName);
sb.append('!');
sb.append(formatReferenceAsString());
return sb.toString();
diff --git a/src/java/org/apache/poi/util/RecordFormatException.java b/src/java/org/apache/poi/util/RecordFormatException.java
index 2bc4ba3bcb..65bea581ee 100644
--- a/src/java/org/apache/poi/util/RecordFormatException.java
+++ b/src/java/org/apache/poi/util/RecordFormatException.java
@@ -45,8 +45,8 @@ public class RecordFormatException
* be thrown. If assertTrue is false, this will throw this
* exception with the message.
*
- * @param assertTrue
- * @param message
+ * @param assertTrue If false, the exception is thrown, if true, no action is performed
+ * @param message The message to include in the thrown exception
*/
public static void check(boolean assertTrue, String message) {
if (! assertTrue) {
diff --git a/src/java/org/apache/poi/util/StringUtil.java b/src/java/org/apache/poi/util/StringUtil.java
index 302e532570..2017abf125 100644
--- a/src/java/org/apache/poi/util/StringUtil.java
+++ b/src/java/org/apache/poi/util/StringUtil.java
@@ -698,7 +698,7 @@ public class StringUtil {
final String prefix;
// #61881 - for now we only check the first char
- if (len > 0 && string[offset] == 0 && string[offset+1] == 0) {
+ if (len > 0 && offset < (string.length - 1) && string[offset] == 0 && string[offset+1] == 0) {
newOffset = offset+2;
prefix = "?";
diff --git a/src/java/org/apache/poi/util/Units.java b/src/java/org/apache/poi/util/Units.java
index da0a877cf4..709e3f10cc 100644
--- a/src/java/org/apache/poi/util/Units.java
+++ b/src/java/org/apache/poi/util/Units.java
@@ -127,7 +127,7 @@ public class Units {
points /= MASTER_DPI;
return points;
}
-
+
public static int pointsToMaster(double points) {
points *= MASTER_DPI;
points /= POINT_DPI;
diff --git a/src/ooxml/java/org/apache/poi/ooxml/POIXMLDocumentPart.java b/src/ooxml/java/org/apache/poi/ooxml/POIXMLDocumentPart.java
index 54fa790eca..c8e1a277a4 100644
--- a/src/ooxml/java/org/apache/poi/ooxml/POIXMLDocumentPart.java
+++ b/src/ooxml/java/org/apache/poi/ooxml/POIXMLDocumentPart.java
@@ -615,7 +615,7 @@ public class POIXMLDocumentPart {
protected void read(POIXMLFactory factory, Map context) throws OpenXML4JException {
PackagePart pp = getPackagePart();
- if (pp.getContentType().equals(XWPFRelation.TEMPLATE.getContentType())) {
+ if (pp.getContentType().equals(XWPFRelation.GLOSSARY_DOCUMENT.getContentType())) {
logger.log(POILogger.WARN,
"POI does not currently support template.main+xml (glossary) parts. " +
"Skipping this part for now.");
diff --git a/src/ooxml/java/org/apache/poi/ooxml/extractor/CommandLineTextExtractor.java b/src/ooxml/java/org/apache/poi/ooxml/extractor/CommandLineTextExtractor.java
index 999abd46ee..c3d429b3c7 100644
--- a/src/ooxml/java/org/apache/poi/ooxml/extractor/CommandLineTextExtractor.java
+++ b/src/ooxml/java/org/apache/poi/ooxml/extractor/CommandLineTextExtractor.java
@@ -22,41 +22,37 @@ import org.apache.poi.extractor.POITextExtractor;
/**
* A command line wrapper around {@link ExtractorFactory}, useful
- * for when debugging.
+ * for when debugging.
*/
public class CommandLineTextExtractor {
- public static final String DIVIDER = "=======================";
-
- public static void main(String[] args) throws Exception {
- if(args.length < 1) {
- System.err.println("Use:");
- System.err.println(" CommandLineTextExtractor [filename] [filename]");
- System.exit(1);
- }
+ public static final String DIVIDER = "=======================";
- for (String arg : args) {
- System.out.println(DIVIDER);
+ public static void main(String[] args) throws Exception {
+ if (args.length < 1) {
+ System.err.println("Use:");
+ System.err.println(" CommandLineTextExtractor [filename] [filename]");
+ System.exit(1);
+ }
- File f = new File(arg);
- System.out.println(f);
+ for (String arg : args) {
+ System.out.println(DIVIDER);
- POITextExtractor extractor =
- ExtractorFactory.createExtractor(f);
- try {
- POITextExtractor metadataExtractor =
- extractor.getMetadataTextExtractor();
+ File f = new File(arg);
+ System.out.println(f);
- System.out.println(" " + DIVIDER);
- String metaData = metadataExtractor.getText();
- System.out.println(metaData);
- System.out.println(" " + DIVIDER);
- String text = extractor.getText();
- System.out.println(text);
- System.out.println(DIVIDER);
- System.out.println("Had " + metaData.length() + " characters of metadata and " + text.length() + " characters of text");
- } finally {
- extractor.close();
- }
- }
- }
+ try (POITextExtractor extractor = ExtractorFactory.createExtractor(f)) {
+ POITextExtractor metadataExtractor =
+ extractor.getMetadataTextExtractor();
+
+ System.out.println(" " + DIVIDER);
+ String metaData = metadataExtractor.getText();
+ System.out.println(metaData);
+ System.out.println(" " + DIVIDER);
+ String text = extractor.getText();
+ System.out.println(text);
+ System.out.println(DIVIDER);
+ System.out.println("Had " + metaData.length() + " characters of metadata and " + text.length() + " characters of text");
+ }
+ }
+ }
}
diff --git a/src/ooxml/java/org/apache/poi/ooxml/util/POIXMLConstants.java b/src/ooxml/java/org/apache/poi/ooxml/util/POIXMLConstants.java
index ab58e35833..c6d7935fda 100644
--- a/src/ooxml/java/org/apache/poi/ooxml/util/POIXMLConstants.java
+++ b/src/ooxml/java/org/apache/poi/ooxml/util/POIXMLConstants.java
@@ -20,6 +20,7 @@ package org.apache.poi.ooxml.util;
public class POIXMLConstants {
public static final String FEATURE_LOAD_DTD_GRAMMAR = "http://apache.org/xml/features/nonvalidating/load-dtd-grammar";
public static final String FEATURE_LOAD_EXTERNAL_DTD = "http://apache.org/xml/features/nonvalidating/load-external-dtd";
+ public static final String FEATURE_DISALLOW_DOCTYPE_DECL = "http://apache.org/xml/features/disallow-doctype-decl";
public static final String PROPERTY_ENTITY_EXPANSION_LIMIT = "http://www.oracle.com/xml/jaxp/properties/entityExpansionLimit";
public static final String PROPERTY_SECURITY_MANAGER = "http://apache.org/xml/properties/security-manager";
}
diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ZipHelper.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ZipHelper.java
index 094e89c6d7..0169909c9b 100644
--- a/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ZipHelper.java
+++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ZipHelper.java
@@ -154,8 +154,6 @@ public final class ZipHelper {
"The supplied data appears to be a raw XML file. " +
"Formats such as Office 2003 XML are not supported");
default:
- case OOXML:
- case UNKNOWN:
// Don't check for a Zip header, as to maintain backwards
// compatibility we need to let them seek over junk at the
// start before beginning processing.
diff --git a/src/ooxml/java/org/apache/poi/openxml4j/util/ZipInputStreamZipEntrySource.java b/src/ooxml/java/org/apache/poi/openxml4j/util/ZipInputStreamZipEntrySource.java
index 048b34e251..0a56966d4f 100644
--- a/src/ooxml/java/org/apache/poi/openxml4j/util/ZipInputStreamZipEntrySource.java
+++ b/src/ooxml/java/org/apache/poi/openxml4j/util/ZipInputStreamZipEntrySource.java
@@ -38,7 +38,7 @@ public class ZipInputStreamZipEntrySource implements ZipEntrySource {
/**
* Reads all the entries from the ZipInputStream
- * into memory, and closes the source stream.
+ * into memory, and don't close (since POI 4.0.1) the source stream.
* We'll then eat lots of memory, but be able to
* work with the entries at-will.
*/
diff --git a/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureOutputStream.java b/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureOutputStream.java
index 0a00e29f1a..0ba11fbd34 100644
--- a/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureOutputStream.java
+++ b/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureOutputStream.java
@@ -20,6 +20,7 @@ package org.apache.poi.poifs.crypt.dsig;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.PrivateKey;
+import java.security.Security;
import java.security.Signature;
import java.security.SignatureException;
@@ -35,7 +36,12 @@ import org.apache.poi.poifs.crypt.HashAlgorithm;
@Override
public void init() throws GeneralSecurityException {
final String provider = isMSCapi(key) ? "SunMSCAPI" : "SunRsaSign";
- signature = Signature.getInstance(algo.ecmaString+"withRSA", provider);
+ if (Security.getProvider(provider) != null) {
+ signature = Signature.getInstance(algo.ecmaString + "withRSA", provider);
+ } else {
+ signature = Signature.getInstance(algo.ecmaString + "withRSA");
+ }
+
signature.initSign(key);
}
diff --git a/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFChart.java b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFChart.java
index 321626d71f..4267898309 100644
--- a/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFChart.java
+++ b/src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFChart.java
@@ -53,6 +53,7 @@ import org.apache.poi.xddf.usermodel.text.XDDFTextBody;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
+import org.apache.poi.xssf.usermodel.XSSFTable;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlOptions;
@@ -81,6 +82,27 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableColumns;
@Beta
public abstract class XDDFChart extends POIXMLDocumentPart implements TextContainer {
+
+ /**
+ * default width of chart in emu
+ */
+ public static final int DEFAULT_WIDTH = 500000;
+
+ /**
+ * default height of chart in emu
+ */
+ public static final int DEFAULT_HEIGHT = 500000;
+
+ /**
+ * default x-coordinate of chart in emu
+ */
+ public static final int DEFAULT_X = 10;
+
+ /**
+ * default y-coordinate value of chart in emu
+ */
+ public static final int DEFAULT_Y = 10;
+
/**
* Underlying workbook
*/
@@ -712,10 +734,29 @@ public abstract class XDDFChart extends POIXMLDocumentPart implements TextContai
XSSFRow row = this.getRow(sheet, 0);
XSSFCell cell = this.getCell(row, column);
cell.setCellValue(title);
- this.updateSheetTable(sheet.getTables().get(0).getCTTable(), title, column);
+
+ CTTable ctTable = this.getSheetTable(sheet);
+
+ this.updateSheetTable(ctTable, title, column);
return new CellReference(sheet.getSheetName(), 0, column, true, true);
}
+ /**
+ * this method will check whether sheet have table
+ * in case table size zero then create new table and add table columns element
+ * @param sheet
+ * @return table object
+ */
+ private CTTable getSheetTable(XSSFSheet sheet) {
+ if(sheet.getTables().size() == 0)
+ {
+ XSSFTable newTable = sheet.createTable(null);
+ newTable.getCTTable().addNewTableColumns();
+ sheet.getTables().add(newTable);
+ }
+ return sheet.getTables().get(0).getCTTable();
+ }
+
/**
* this method update column header of sheet into table
*
@@ -729,7 +770,8 @@ public abstract class XDDFChart extends POIXMLDocumentPart implements TextContai
private void updateSheetTable(CTTable ctTable, String title, int index) {
CTTableColumns tableColumnList = ctTable.getTableColumns();
CTTableColumn column = null;
- for( int i = 0; tableColumnList.getCount() < index; i++) {
+ int columnCount = tableColumnList.getTableColumnList().size()-1;
+ for( int i = columnCount; i < index; i++) {
column = tableColumnList.addNewTableColumn();
column.setId(i);
}
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XMLSlideShow.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XMLSlideShow.java
index 687ddc5f5b..b0cbc59dd1 100644
--- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XMLSlideShow.java
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XMLSlideShow.java
@@ -302,14 +302,23 @@ public class XMLSlideShow extends POIXMLDocument
* Create a blank chart on the given slide.
*/
public XSLFChart createChart(XSLFSlide slide) {
+ XSLFChart chart = createChart();
+ slide.addRelation(null, XSLFRelation.CHART, chart);
+ return chart;
+ }
+
+ /**
+ * This method is used to create template for chart XML.
+ * @return Xslf chart object
+ * @since POI 4.0.2
+ */
+ public XSLFChart createChart() {
int chartIdx = findNextAvailableFileNameIndex(XSLFRelation.CHART, _charts.size() + 1);
XSLFChart chart = (XSLFChart) createRelationship(XSLFRelation.CHART, XSLFFactory.getInstance(), chartIdx, true).getDocumentPart();
- slide.addRelation(null, XSLFRelation.CHART, chart);
chart.setChartIndex(chartIdx);
_charts.add(chart);
return chart;
}
-
/**
* Return notes slide for the specified slide or create new if it does not exist yet.
*/
@@ -416,7 +425,7 @@ public class XMLSlideShow extends POIXMLDocument
* Return all the charts in the slideshow
*/
public List getCharts() {
- return _charts;
+ return Collections.unmodifiableList(_charts);
}
/**
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFChart.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFChart.java
index 8e6612f875..5e8d73cd06 100644
--- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFChart.java
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFChart.java
@@ -19,16 +19,28 @@
package org.apache.poi.xslf.usermodel;
+import java.awt.geom.Rectangle2D;
import java.io.IOException;
+import javax.xml.namespace.QName;
+
import org.apache.poi.ooxml.POIXMLFactory;
import org.apache.poi.ooxml.POIXMLRelation;
import org.apache.poi.openxml4j.opc.PackagePart;
+import org.apache.poi.openxml4j.opc.PackageRelationshipTypes;
import org.apache.poi.util.Beta;
import org.apache.poi.xddf.usermodel.chart.XDDFChart;
+import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlException;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTTitle;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTGraphicalObjectData;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBody;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTransform2D;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTGraphicalObjectFrame;
+import org.openxmlformats.schemas.presentationml.x2006.main.CTGraphicalObjectFrameNonVisual;
/**
* Represents a Chart in a .pptx presentation
@@ -36,6 +48,8 @@ import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBody;
@Beta
public final class XSLFChart extends XDDFChart {
+ private static String CHART_URI = "http://schemas.openxmlformats.org/drawingml/2006/chart";
+
/**
* Construct a PresentationML chart.
*/
@@ -90,4 +104,47 @@ public final class XSLFChart extends XDDFChart {
};
}
}
+
+ /**
+ * method to add graphic frame for XSLF chart
+ *
+ * @param shapeId shape id
+ * @param rID relation id
+ * @param anchor size and location of chart
+ * @return graphic frame object
+ * @since POI 4.0.2
+ */
+ static CTGraphicalObjectFrame prototype(int shapeId, String rID, Rectangle2D anchor) {
+ CTGraphicalObjectFrame frame = CTGraphicalObjectFrame.Factory.newInstance();
+ CTGraphicalObjectFrameNonVisual nvGr = frame.addNewNvGraphicFramePr();
+
+ CTNonVisualDrawingProps cnv = nvGr.addNewCNvPr();
+ cnv.setName("Chart " + shapeId);
+ cnv.setId(shapeId);
+ nvGr.addNewCNvGraphicFramePr().addNewGraphicFrameLocks().setNoGrp(true);
+ nvGr.addNewNvPr();
+
+ CTTransform2D xfrm = frame.addNewXfrm();
+
+ CTPoint2D off = xfrm.addNewOff();
+ off.setX((int)anchor.getX());
+ off.setY((int)anchor.getY());
+
+ CTPositiveSize2D ext = xfrm.addNewExt();
+ ext.setCx((int)anchor.getWidth());
+ ext.setCy((int)anchor.getHeight());
+
+ xfrm.setExt(ext);
+ xfrm.setOff(off);
+
+ CTGraphicalObjectData gr = frame.addNewGraphic().addNewGraphicData();
+ XmlCursor grCur = gr.newCursor();
+ grCur.toNextToken();
+ grCur.beginElement(new QName(CHART_URI, "chart"));
+ grCur.insertAttributeWithValue("id", PackageRelationshipTypes.CORE_PROPERTIES_ECMA376_NS, rID);
+ grCur.dispose();
+
+ gr.setUri(CHART_URI);
+ return frame;
+ }
}
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFDrawing.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFDrawing.java
index f4cd0d8e1c..ba93988d0b 100644
--- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFDrawing.java
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFDrawing.java
@@ -107,6 +107,19 @@ public class XSLFDrawing {
return shape;
}
+ /**
+ * This method will add chart into slide's graphic frame
+ *
+ * @param rID relation id of chart
+ * @param rect2D Chart Bounding values
+ * @since POI 4.0.2
+ */
+ public void addChart(String rID, Rectangle2D rect2D) {
+ CTGraphicalObjectFrame sp = _spTree.addNewGraphicFrame();
+ sp.set(XSLFChart.prototype(_sheet.allocateShapeId(), rID, rect2D));
+ }
+
+
public XSLFObjectShape createOleShape(String pictureRel) {
CTGraphicalObjectFrame sp = _spTree.addNewGraphicFrame();
sp.set(XSLFObjectShape.prototype(_sheet.allocateShapeId(), pictureRel));
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFFreeformShape.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFFreeformShape.java
index 54acd2b7ba..8c41fe1b93 100644
--- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFFreeformShape.java
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFFreeformShape.java
@@ -24,6 +24,12 @@ import java.awt.geom.Path2D;
import java.awt.geom.PathIterator;
import java.awt.geom.Rectangle2D;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.poi.ooxml.POIXMLTypeLoader;
+import org.apache.poi.sl.draw.geom.CustomGeometry;
+import org.apache.poi.sl.draw.geom.PresetGeometries;
import org.apache.poi.sl.usermodel.FreeformShape;
import org.apache.poi.util.Beta;
import org.apache.poi.util.POILogFactory;
@@ -31,6 +37,7 @@ import org.apache.poi.util.POILogger;
import org.apache.poi.util.Units;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlObject;
+import org.apache.xmlbeans.XmlOptions;
import org.openxmlformats.schemas.drawingml.x2006.main.CTAdjPoint2D;
import org.openxmlformats.schemas.drawingml.x2006.main.CTCustomGeometry2D;
import org.openxmlformats.schemas.drawingml.x2006.main.CTGeomRect;
@@ -61,7 +68,7 @@ public class XSLFFreeformShape extends XSLFAutoShape
}
@Override
- public int setPath(final Path2D.Double path) {
+ public int setPath(final Path2D path) {
final CTPath2D ctPath = CTPath2D.Factory.newInstance();
final Rectangle2D bounds = path.getBounds2D();
@@ -117,6 +124,30 @@ public class XSLFFreeformShape extends XSLFAutoShape
return numPoints;
}
+ /**
+ * @return definition of the shape geometry
+ */
+ @Override
+ public CustomGeometry getGeometry() {
+ final XmlObject xo = getShapeProperties();
+ if (!(xo instanceof CTShapeProperties)) {
+ return null;
+ }
+
+ XmlOptions xop = new XmlOptions(POIXMLTypeLoader.DEFAULT_XML_OPTIONS);
+ xop.setSaveOuter();
+
+ XMLStreamReader staxReader = ((CTShapeProperties)xo).getCustGeom().newXMLStreamReader(xop);
+ CustomGeometry custGeo = PresetGeometries.convertCustomGeometry(staxReader);
+ try {
+ staxReader.close();
+ } catch (XMLStreamException e) {
+ LOG.log(POILogger.WARN,
+ "An error occurred while closing a Custom Geometry XML Stream Reader: " + e.getMessage());
+ }
+
+ return custGeo;
+ }
@Override
public Path2D.Double getPath() {
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSheet.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSheet.java
index b67264ba0f..2bcf063990 100644
--- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSheet.java
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSheet.java
@@ -20,6 +20,7 @@ import static org.apache.poi.ooxml.POIXMLTypeLoader.DEFAULT_XML_OPTIONS;
import java.awt.Dimension;
import java.awt.Graphics2D;
+import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@@ -52,6 +53,7 @@ import org.apache.poi.util.IOUtils;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import org.apache.poi.util.Units;
+import org.apache.poi.xddf.usermodel.chart.XDDFChart;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlObject;
@@ -306,14 +308,13 @@ implements XSLFShapeContainer, Sheet {
throw new IllegalArgumentException("pictureData needs to be of type XSLFPictureData");
}
RelationPart rp = addRelation(null, XSLFRelation.IMAGES, (XSLFPictureData)pictureData);
-
+
XSLFObjectShape sh = getDrawing().createOleShape(rp.getRelationship().getId());
CTOleObject oleObj = sh.getCTOleObject();
Dimension dim = pictureData.getImageDimension();
oleObj.setImgW(Units.toEMU(dim.getWidth()));
oleObj.setImgH(Units.toEMU(dim.getHeight()));
-
-
+
getShapes().add(sh);
sh.setParent(this);
return sh;
@@ -719,4 +720,28 @@ implements XSLFShapeContainer, Sheet {
return (ph == null) ? null : new XSLFPlaceholderDetails(ph);
}
+ /**
+ * this method will add chart into slide
+ * with default height, width, x and y
+ * @param chart xslf chart object
+ * @since POI 4.0.2
+ */
+ public void addChart(XSLFChart chart) {
+ Rectangle2D rect2D = new java.awt.Rectangle(XDDFChart.DEFAULT_X, XDDFChart.DEFAULT_Y,
+ XDDFChart.DEFAULT_WIDTH, XDDFChart.DEFAULT_HEIGHT);
+
+ this.addChart(chart, rect2D);
+ }
+
+ /**
+ * this method will add chart into slide
+ * with given height, width, x and y
+ * @param chart xslf chart object
+ * @since POI 4.0.2
+ */
+ public void addChart(XSLFChart chart, Rectangle2D rect2D) {
+ RelationPart rp = addRelation(null, XSLFRelation.CHART, chart);
+ getDrawing().addChart(rp.getRelationship().getId(), rect2D);
+ }
+
}
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSimpleShape.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSimpleShape.java
index 4e54712a77..89f312327b 100644
--- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSimpleShape.java
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSimpleShape.java
@@ -716,7 +716,6 @@ public abstract class XSLFSimpleShape extends XSLFShape
}
/**
- *
* @return definition of the shape geometry
*/
@Override
diff --git a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java
index ed52e0e16b..16d7903a37 100644
--- a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java
+++ b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java
@@ -32,6 +32,7 @@ import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
+import org.apache.commons.compress.archivers.zip.Zip64Mode;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import org.apache.poi.openxml4j.opc.OPCPackage;
@@ -51,13 +52,7 @@ import org.apache.poi.ss.usermodel.Row.MissingCellPolicy;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.SheetVisibility;
import org.apache.poi.ss.usermodel.Workbook;
-import org.apache.poi.util.IOUtils;
-import org.apache.poi.util.Internal;
-import org.apache.poi.util.NotImplemented;
-import org.apache.poi.util.POILogFactory;
-import org.apache.poi.util.POILogger;
-import org.apache.poi.util.Removal;
-import org.apache.poi.util.TempFile;
+import org.apache.poi.util.*;
import org.apache.poi.xssf.model.SharedStringsTable;
import org.apache.poi.xssf.usermodel.XSSFChartSheet;
import org.apache.poi.xssf.usermodel.XSSFSheet;
@@ -117,6 +112,8 @@ public class SXSSFWorkbook implements Workbook {
*/
private final SharedStringsTable _sharedStringSource;
+ private Zip64Mode zip64Mode = Zip64Mode.AsNeeded;
+
/**
* Construct a new workbook with default row window size
*/
@@ -250,6 +247,7 @@ public class SXSSFWorkbook implements Workbook {
}
}
}
+
/**
* Construct an empty workbook and specify the window for row access.
*
@@ -290,6 +288,16 @@ public class SXSSFWorkbook implements Workbook {
_randomAccessWindowSize = rowAccessWindowSize;
}
+ /**
+ * @param zip64Mode {@link Zip64Mode}
+ *
+ * @since 4.0.3
+ */
+ @Beta
+ public void setZip64Mode(Zip64Mode zip64Mode) {
+ this.zip64Mode = zip64Mode;
+ }
+
/**
* Get whether temp files should be compressed.
*
@@ -298,6 +306,7 @@ public class SXSSFWorkbook implements Workbook {
public boolean isCompressTempFiles() {
return _compressTmpFiles;
}
+
/**
* Set whether temp files should be compressed.
*
@@ -377,6 +386,7 @@ public class SXSSFWorkbook implements Workbook {
protected void injectData(ZipEntrySource zipEntrySource, OutputStream out) throws IOException {
ZipArchiveOutputStream zos = new ZipArchiveOutputStream(out);
+ zos.setUseZip64(zip64Mode);
try {
Enumeration extends ZipArchiveEntry> en = zipEntrySource.getEntries();
while (en.hasMoreElements()) {
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFChart.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFChart.java
index 44820a5871..495cde1bf9 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFChart.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFChart.java
@@ -39,12 +39,12 @@ public class XWPFChart extends XDDFChart {
/**
* default width of chart in emu
*/
- public static final int DEFAULT_WIDTH = 500000;
+ public static final int DEFAULT_WIDTH = XDDFChart.DEFAULT_WIDTH;
/**
* default height of chart in emu
*/
- public static final int DEFAULT_HEIGHT = 500000;
+ public static final int DEFAULT_HEIGHT = XDDFChart.DEFAULT_HEIGHT;
// lazy initialization
private Long checksum;
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java
index e3cc314a4a..8e7e383d45 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java
@@ -58,6 +58,7 @@ import org.apache.poi.util.Internal;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import org.apache.poi.wp.usermodel.HeaderFooterType;
+import org.apache.poi.xddf.usermodel.chart.XDDFChart;
import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlException;
@@ -1672,7 +1673,7 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
* @since POI 4.0.0
*/
public XWPFChart createChart() throws InvalidFormatException, IOException {
- return createChart(XWPFChart.DEFAULT_WIDTH, XWPFChart.DEFAULT_HEIGHT);
+ return createChart(XDDFChart.DEFAULT_WIDTH, XDDFChart.DEFAULT_HEIGHT);
}
/**
diff --git a/src/ooxml/testcases/org/apache/poi/ooxml/TestPOIXMLProperties.java b/src/ooxml/testcases/org/apache/poi/ooxml/TestPOIXMLProperties.java
index d91b8191eb..1ad2a633f9 100644
--- a/src/ooxml/testcases/org/apache/poi/ooxml/TestPOIXMLProperties.java
+++ b/src/ooxml/testcases/org/apache/poi/ooxml/TestPOIXMLProperties.java
@@ -19,6 +19,7 @@ package org.apache.poi.ooxml;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -89,7 +90,7 @@ public final class TestPOIXMLProperties {
XSSFWorkbook newWorkbook =
XSSFTestDataSamples.writeOutAndReadBack(workbook);
workbook.close();
- assertTrue(workbook != newWorkbook);
+ assertNotSame(workbook, newWorkbook);
POIXMLProperties newProps = newWorkbook.getProperties();
@@ -158,7 +159,7 @@ public final class TestPOIXMLProperties {
p = ctProps.getPropertyArray(3);
assertEquals("{D5CDD505-2E9C-101B-9397-08002B2CF9AE}", p.getFmtid());
assertEquals("test-4", p.getName());
- assertEquals(true, p.getBool());
+ assertTrue(p.getBool());
assertEquals(5, p.getPid());
wb2.close();
diff --git a/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestSignatureInfo.java b/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestSignatureInfo.java
index dd2bc1705f..4b9cff9b3c 100644
--- a/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestSignatureInfo.java
+++ b/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestSignatureInfo.java
@@ -60,6 +60,7 @@ import javax.xml.crypto.dsig.CanonicalizationMethod;
import javax.xml.crypto.dsig.dom.DOMSignContext;
import org.apache.jcp.xml.dsig.internal.dom.DOMSignedInfo;
+import org.apache.poi.EncryptedDocumentException;
import org.apache.poi.POIDataSamples;
import org.apache.poi.POITestCase;
import org.apache.poi.ooxml.util.DocumentHelper;
@@ -682,6 +683,8 @@ public class TestSignatureInfo {
si.confirmSignature();
boolean b = si.verifySignature();
assertTrue("Signature not correctly calculated for " + ha, b);
+ } catch (EncryptedDocumentException e) {
+ Assume.assumeTrue(e.getMessage().startsWith("Export Restrictions"));
} finally {
if (pkg != null) {
pkg.close();
diff --git a/src/ooxml/testcases/org/apache/poi/xddf/usermodel/TestNecessaryOOXMLClasses.java b/src/ooxml/testcases/org/apache/poi/xddf/usermodel/TestNecessaryOOXMLClasses.java
index 74ec1bb6cf..6cbf24ab6f 100644
--- a/src/ooxml/testcases/org/apache/poi/xddf/usermodel/TestNecessaryOOXMLClasses.java
+++ b/src/ooxml/testcases/org/apache/poi/xddf/usermodel/TestNecessaryOOXMLClasses.java
@@ -87,6 +87,10 @@ public class TestNecessaryOOXMLClasses {
Assert.assertNotNull(ctLblAlgn);
CTDashStopList ctDashStopList = CTDashStopList.Factory.newInstance();
Assert.assertNotNull(ctDashStopList);
+ STDispBlanksAs stDashBlanksAs = STDispBlanksAs.Factory.newInstance();
+ Assert.assertNotNull(stDashBlanksAs);
+ CTDispBlanksAs ctDashBlanksAs = CTDispBlanksAs.Factory.newInstance();
+ Assert.assertNotNull(ctDashBlanksAs);
STLblAlgn.Enum e1 = STLblAlgn.Enum.forString("ctr");
Assert.assertNotNull(e1);
@@ -100,6 +104,8 @@ public class TestNecessaryOOXMLClasses {
Assert.assertNotNull(e5);
STMarkerStyle.Enum e6 = STMarkerStyle.Enum.forString("circle");
Assert.assertNotNull(e6);
+ STDispBlanksAs.Enum e7 = STDispBlanksAs.Enum.forString("span");
+ Assert.assertNotNull(e7);
CTTextBulletTypefaceFollowText ctTextBulletTypefaceFollowText = CTTextBulletTypefaceFollowText.Factory.newInstance();
Assert.assertNotNull(ctTextBulletTypefaceFollowText);
diff --git a/src/ooxml/testcases/org/apache/poi/xdgf/extractor/TestXDGFVisioExtractor.java b/src/ooxml/testcases/org/apache/poi/xdgf/extractor/TestXDGFVisioExtractor.java
index 6a3369ed90..c261e2c91b 100644
--- a/src/ooxml/testcases/org/apache/poi/xdgf/extractor/TestXDGFVisioExtractor.java
+++ b/src/ooxml/testcases/org/apache/poi/xdgf/extractor/TestXDGFVisioExtractor.java
@@ -42,7 +42,7 @@ public class TestXDGFVisioExtractor {
}
@After
- public void closeResoures() throws IOException {
+ public void closeResources() throws IOException {
if(xml != null) {
xml.close();
}
diff --git a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestPPTX2PNG.java b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestPPTX2PNG.java
index 94205da144..9a206a48ca 100644
--- a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestPPTX2PNG.java
+++ b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestPPTX2PNG.java
@@ -47,7 +47,9 @@ 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," +
+ "customGeo.pptx, customGeo.ppt";
diff --git a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSlide.java b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSlide.java
index fbf4589765..b9cda3fd21 100644
--- a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSlide.java
+++ b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSlide.java
@@ -20,6 +20,7 @@ import static org.apache.poi.sl.TestCommonSL.sameColor;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
@@ -34,7 +35,7 @@ import org.junit.Test;
* @author Yegor Kozlov
*/
public class TestXSLFSlide {
-
+
@Test
public void testReadShapes() throws IOException {
XMLSlideShow ppt = XSLFTestDataSamples.openSampleDocument("shapes.pptx");
@@ -101,7 +102,7 @@ public class TestXSLFSlide {
XSLFTable tbl = (XSLFTable)shapes4.get(0);
assertEquals(3, tbl.getNumberOfColumns());
assertEquals(6, tbl.getNumberOfRows());
-
+
ppt.close();
}
@@ -116,7 +117,7 @@ public class TestXSLFSlide {
assertFalse(slide.getFollowMasterGraphics());
slide.setFollowMasterGraphics(true);
assertTrue(slide.getFollowMasterGraphics());
-
+
ppt.close();
}
@@ -174,7 +175,7 @@ public class TestXSLFSlide {
XSLFPictureShape sh4 = (XSLFPictureShape)shapes2.get(1);
XSLFPictureShape srcPic = (XSLFPictureShape)src.getSlides().get(4).getShapes().get(1);
assertArrayEquals(sh4.getPictureData().getData(), srcPic.getPictureData().getData());
-
+
ppt.close();
}
@@ -191,7 +192,23 @@ public class TestXSLFSlide {
}
}
assertEquals(30, ppt.getSlides().size());
-
+
ppt.close();
- }
-}
\ No newline at end of file
+ }
+
+ @Test
+ public void testCreateChart() throws IOException {
+ XMLSlideShow ppt = new XMLSlideShow();
+ XSLFSlide slide = ppt.createSlide();
+ XSLFChart chart = ppt.createChart();
+ assertNotNull(chart);
+
+ slide.addChart(chart);
+ assertEquals(XSLFRelation.CHART.getContentType(), chart.getPackagePart().getContentType());
+
+ String partName = slide.getRelationPartById("rId2").getDocumentPart().getPackagePart().getPartName().getName();
+ assertEquals(partName, chart.getPackagePart().getPartName().getName());
+
+ ppt.close();
+ }
+}
diff --git a/src/ooxml/testcases/org/apache/poi/xssf/XSSFTestDataSamples.java b/src/ooxml/testcases/org/apache/poi/xssf/XSSFTestDataSamples.java
index 0f03af7453..b981b9994e 100644
--- a/src/ooxml/testcases/org/apache/poi/xssf/XSSFTestDataSamples.java
+++ b/src/ooxml/testcases/org/apache/poi/xssf/XSSFTestDataSamples.java
@@ -70,7 +70,7 @@ public class XSSFTestDataSamples {
* @param wb the workbook to write
* @param testName a fragment of the filename
* @return the location where the workbook was saved
- * @throws IOException
+ * @throws IOException If writing the file fails
*/
public static File writeOut(R wb, String testName) throws IOException {
final File file = getOutputFile(testName);
@@ -104,7 +104,9 @@ public class XSSFTestDataSamples {
file = TempFile.createTempFile(testName, ".xlsx");
}
if (file.exists()) {
- file.delete();
+ if(!file.delete()) {
+ throw new IOException("Could not delete file " + file);
+ }
}
return file;
}
@@ -114,7 +116,7 @@ public class XSSFTestDataSamples {
*
* @param wb the workbook to write
* @return the memory buffer
- * @throws IOException
+ * @throws IOException If writing the file fails
*/
public static ByteArrayOutputStream writeOut(R wb) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream(8192);
@@ -137,7 +139,7 @@ public class XSSFTestDataSamples {
* to avoid creating a temporary file. However, this may complicate the calling
* code to avoid having the workbook, BAOS, and BAIS open at the same time.
*
- * @param wb
+ * @param wb The workbook to write out, it is closed after the call.
* @param testName file name to be used to write to a file. This file will be cleaned up by a call to readBack(String)
* @return workbook location
* @throws RuntimeException if {@link #TEST_OUTPUT_DIR} System property is not set
@@ -161,18 +163,13 @@ public class XSSFTestDataSamples {
*
* @param wb the workbook to write
* @return the memory buffer
- * @throws IOException
+ * @throws RuntimeException If writing the file fails
*/
- public static ByteArrayOutputStream writeOutAndClose(R wb) {
- try {
- ByteArrayOutputStream out = writeOut(wb);
- // Do not close the workbook if there was a problem writing the workbook
- wb.close();
- return out;
- }
- catch (final IOException e) {
- throw new RuntimeException(e);
- }
+ public static ByteArrayOutputStream writeOutAndClose(R wb) throws IOException {
+ ByteArrayOutputStream out = writeOut(wb);
+ // Do not close the workbook if there was a problem writing the workbook
+ wb.close();
+ return out;
}
/**
@@ -183,12 +180,14 @@ public class XSSFTestDataSamples {
*
* @param file the workbook file to read and delete
* @return the read back workbook
- * @throws IOException
+ * @throws IOException If reading or deleting the file fails
*/
public static XSSFWorkbook readBackAndDelete(File file) throws IOException {
XSSFWorkbook wb = readBack(file);
// do not delete the file if there's an error--might be helpful for debugging
- file.delete();
+ if(!file.delete()) {
+ throw new IOException("Could not delete file " + file + " after reading");
+ }
return wb;
}
@@ -198,16 +197,12 @@ public class XSSFTestDataSamples {
*
* @param file the workbook file to read
* @return the read back workbook
- * @throws IOException
+ * @throws IOException If reading the file fails
*/
public static XSSFWorkbook readBack(File file) throws IOException {
- InputStream in = new FileInputStream(file);
- try {
+ try (InputStream in = new FileInputStream(file)) {
return new XSSFWorkbook(in);
}
- finally {
- in.close();
- }
}
/**
@@ -216,17 +211,13 @@ public class XSSFTestDataSamples {
*
* @param out the output stream to read back from
* @return the read back workbook
- * @throws IOException
+ * @throws IOException If reading the file fails
*/
public static XSSFWorkbook readBack(ByteArrayOutputStream out) throws IOException {
- InputStream is = new ByteArrayInputStream(out.toByteArray());
- out.close();
- try {
+ try (InputStream is = new ByteArrayInputStream(out.toByteArray())) {
+ out.close();
return new XSSFWorkbook(is);
}
- finally {
- is.close();
- }
}
/**
diff --git a/src/ooxml/testcases/org/apache/poi/xwpf/extractor/TestXWPFWordExtractor.java b/src/ooxml/testcases/org/apache/poi/xwpf/extractor/TestXWPFWordExtractor.java
index 0fcccd1838..30d943051f 100644
--- a/src/ooxml/testcases/org/apache/poi/xwpf/extractor/TestXWPFWordExtractor.java
+++ b/src/ooxml/testcases/org/apache/poi/xwpf/extractor/TestXWPFWordExtractor.java
@@ -452,4 +452,12 @@ public class TestXWPFWordExtractor extends TestCase {
//once we add processing for this, we can change this to contains
assertNotContained(txt, "table rows");
}
+
+ public void testPartsInTemplate() throws IOException {
+ XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("60316b.dotx");
+ XWPFWordExtractor extractor = new XWPFWordExtractor(doc);
+ String txt = extractor.getText();
+ assertContains(txt, "header 2");
+ assertContains(txt, "footer 1");
+ }
}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/CurrentUserAtom.java b/src/scratchpad/src/org/apache/poi/hslf/record/CurrentUserAtom.java
index cedfbb0470..26ba59d2c6 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/record/CurrentUserAtom.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/record/CurrentUserAtom.java
@@ -20,6 +20,8 @@
package org.apache.poi.hslf.record;
+import static org.apache.poi.hslf.usermodel.HSLFSlideShow.PP95_DOCUMENT;
+
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@@ -143,7 +145,7 @@ public class CurrentUserAtom
// See how long it is. If it's under 28 bytes long, we can't
// read it
if(_contents.length < 28) {
- boolean isPP95 = dir.hasEntry("PP40");
+ boolean isPP95 = dir.hasEntry(PP95_DOCUMENT);
// PPT95 has 4 byte size, then data
if (!isPP95 && _contents.length >= 4) {
int size = LittleEndian.getInt(_contents);
diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFAutoShape.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFAutoShape.java
index 910c8a0adc..3a3fa7afb3 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFAutoShape.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFAutoShape.java
@@ -17,21 +17,122 @@
package org.apache.poi.hslf.usermodel;
+import java.awt.geom.Arc2D;
+import java.awt.geom.Path2D;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.poi.ddf.AbstractEscherOptRecord;
+import org.apache.poi.ddf.EscherArrayProperty;
import org.apache.poi.ddf.EscherContainerRecord;
import org.apache.poi.ddf.EscherProperties;
-import org.apache.poi.sl.usermodel.*;
+import org.apache.poi.ddf.EscherProperty;
+import org.apache.poi.ddf.EscherSimpleProperty;
+import org.apache.poi.sl.draw.binding.CTAdjPoint2D;
+import org.apache.poi.sl.draw.binding.CTCustomGeometry2D;
+import org.apache.poi.sl.draw.binding.CTPath2D;
+import org.apache.poi.sl.draw.binding.CTPath2DArcTo;
+import org.apache.poi.sl.draw.binding.CTPath2DCubicBezierTo;
+import org.apache.poi.sl.draw.binding.CTPath2DLineTo;
+import org.apache.poi.sl.draw.binding.CTPath2DList;
+import org.apache.poi.sl.draw.binding.CTPath2DMoveTo;
+import org.apache.poi.sl.draw.binding.ObjectFactory;
+import org.apache.poi.sl.draw.geom.CustomGeometry;
+import org.apache.poi.sl.usermodel.AutoShape;
+import org.apache.poi.sl.usermodel.ShapeContainer;
+import org.apache.poi.sl.usermodel.ShapeType;
+import org.apache.poi.sl.usermodel.VerticalAlignment;
import org.apache.poi.ss.usermodel.ShapeTypes;
+import org.apache.poi.util.BitField;
+import org.apache.poi.util.BitFieldFactory;
+import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.POILogFactory;
+import org.apache.poi.util.POILogger;
/**
- * Represents an AutoShape.
- *
+ * Represents an AutoShape.
+ *
* AutoShapes are drawing objects with a particular shape that may be customized through smart resizing and adjustments.
* See {@link ShapeTypes}
- *
- *
- * @author Yegor Kozlov
*/
public class HSLFAutoShape extends HSLFTextShape implements AutoShape {
+ private static final POILogger LOG = POILogFactory.getLogger(HSLFAutoShape.class);
+
+ static final byte[] SEGMENTINFO_MOVETO = new byte[]{0x00, 0x40};
+ static final byte[] SEGMENTINFO_LINETO = new byte[]{0x00, (byte)0xAC};
+ static final byte[] SEGMENTINFO_ESCAPE = new byte[]{0x01, 0x00};
+ static final byte[] SEGMENTINFO_ESCAPE2 = new byte[]{0x01, 0x20};
+ static final byte[] SEGMENTINFO_CUBICTO = new byte[]{0x00, (byte)0xAD};
+ // OpenOffice inserts 0xB3 instead of 0xAD.
+ // protected static final byte[] SEGMENTINFO_CUBICTO2 = new byte[]{0x00, (byte)0xB3};
+ static final byte[] SEGMENTINFO_CLOSE = new byte[]{0x01, (byte)0x60};
+ static final byte[] SEGMENTINFO_END = new byte[]{0x00, (byte)0x80};
+
+ private static final BitField PATH_INFO = BitFieldFactory.getInstance(0xE000);
+ private static final BitField ESCAPE_INFO = BitFieldFactory.getInstance(0x1F00);
+
+ enum PathInfo {
+ lineTo(0),curveTo(1),moveTo(2),close(3),end(4),escape(5),clientEscape(6);
+ private final int flag;
+ PathInfo(int flag) {
+ this.flag = flag;
+ }
+ public int getFlag() {
+ return flag;
+ }
+ static PathInfo valueOf(int flag) {
+ for (PathInfo v : values()) {
+ if (v.flag == flag) {
+ return v;
+ }
+ }
+ return null;
+ }
+ }
+
+ enum EscapeInfo {
+ EXTENSION(0x0000),
+ ANGLE_ELLIPSE_TO(0x0001),
+ ANGLE_ELLIPSE(0x0002),
+ ARC_TO(0x0003),
+ ARC(0x0004),
+ CLOCKWISE_ARC_TO(0x0005),
+ CLOCKWISE_ARC(0x0006),
+ ELLIPTICAL_QUADRANT_X(0x0007),
+ ELLIPTICAL_QUADRANT_Y(0x0008),
+ QUADRATIC_BEZIER(0x0009),
+ NO_FILL(0X000A),
+ NO_LINE(0X000B),
+ AUTO_LINE(0X000C),
+ AUTO_CURVE(0X000D),
+ CORNER_LINE(0X000E),
+ CORNER_CURVE(0X000F),
+ SMOOTH_LINE(0X0010),
+ SMOOTH_CURVE(0X0011),
+ SYMMETRIC_LINE(0X0012),
+ SYMMETRIC_CURVE(0X0013),
+ FREEFORM(0X0014),
+ FILL_COLOR(0X0015),
+ LINE_COLOR(0X0016);
+
+ private final int flag;
+ EscapeInfo(int flag) {
+ this.flag = flag;
+ }
+ public int getFlag() {
+ return flag;
+ }
+ static EscapeInfo valueOf(int flag) {
+ for (EscapeInfo v : values()) {
+ if (v.flag == flag) {
+ return v;
+ }
+ }
+ return null;
+ }
+ }
protected HSLFAutoShape(EscherContainerRecord escherRecord, ShapeContainer parent){
super(escherRecord, parent);
@@ -72,13 +173,11 @@ public class HSLFAutoShape extends HSLFTextShape implements AutoShape
*
- *
* The adjustment values are given in shape coordinates:
* the origin is at the top-left, positive-x is to the right, positive-y is down.
* The region from (0,0) to (S,S) maps to the geometry box of the shape (S=21600 is a constant).
- *
*
* @param idx the adjust index in the [0, 9] range
* @return the adjustment value
@@ -90,13 +189,11 @@ public class HSLFAutoShape extends HSLFTextShape implements AutoShape
*
- *
* The adjustment values are given in shape coordinates:
* the origin is at the top-left, positive-x is to the right, positive-y is down.
* The region from (0,0) to (S,S) maps to the geometry box of the shape (S=21600 is a constant).
- *
*
* @param idx the adjust index in the [0, 9] range
* @param val the adjustment value
@@ -106,4 +203,278 @@ public class HSLFAutoShape extends HSLFTextShape implements AutoShape vertIter = verticesProp.iterator();
+ final Iterator segIter = segmentsProp.iterator();
+ final int[] xyPoints = new int[2];
+ boolean isClosed = false;
+
+ final CTPath2DList pathLst = of.createCTPath2DList();
+ final CTPath2D pathCT = of.createCTPath2D();
+ final List