aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPJ Fanning <fanningpj@apache.org>2021-12-23 10:33:59 +0000
committerPJ Fanning <fanningpj@apache.org>2021-12-23 10:33:59 +0000
commitd6ab8e844442607965eb749d42c67d7c9f0f5495 (patch)
tree2570ca0e76f930df691a1c1080df6f723cfa2dc9
parentd41e05068855187d1e08d50e16f1428b1e1f30a1 (diff)
downloadpoi-d6ab8e844442607965eb749d42c67d7c9f0f5495.tar.gz
poi-d6ab8e844442607965eb749d42c67d7c9f0f5495.zip
[github-290] Customize Spliterator implementations for better parallelism. Thanks to Daniel Shuy. This closes #290
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1896305 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--poi-ooxml-lite-agent/src/main/java9/module-info.classbin278 -> 278 bytes
-rw-r--r--poi-ooxml/src/main/java/org/apache/poi/openxml4j/opc/PackageRelationshipCollection.java10
-rw-r--r--poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/text/XDDFTextParagraph.java12
-rw-r--r--poi-ooxml/src/main/java/org/apache/poi/xslf/usermodel/XSLFTextShape.java9
-rw-r--r--poi-ooxml/src/main/java/org/apache/poi/xssf/streaming/SXSSFDrawing.java11
-rw-r--r--poi-ooxml/src/main/java/org/apache/poi/xssf/streaming/SXSSFRow.java34
-rw-r--r--poi-ooxml/src/main/java/org/apache/poi/xssf/streaming/SXSSFSheet.java20
-rw-r--r--poi-ooxml/src/main/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java23
-rw-r--r--poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFDrawing.java9
-rw-r--r--poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFRow.java17
-rw-r--r--poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFShapeGroup.java9
-rw-r--r--poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFSheet.java12
-rw-r--r--poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFSimpleShape.java9
-rw-r--r--poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java15
-rw-r--r--poi-ooxml/src/main/java/org/apache/poi/xwpf/usermodel/XWPFAbstractFootnoteEndnote.java12
-rw-r--r--poi-ooxml/src/main/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java24
-rw-r--r--poi-ooxml/src/test/java/org/apache/poi/xssf/streaming/TestSXSSFSheet.java4
-rw-r--r--poi-scratchpad/src/main/java/org/apache/poi/hslf/record/PPDrawing.java9
-rw-r--r--poi-scratchpad/src/main/java/org/apache/poi/hslf/usermodel/HSLFGroupShape.java9
-rw-r--r--poi-scratchpad/src/main/java/org/apache/poi/hslf/usermodel/HSLFSheet.java8
-rw-r--r--poi-scratchpad/src/main/java/org/apache/poi/hslf/usermodel/HSLFTextParagraph.java9
-rw-r--r--poi-scratchpad/src/main/java/org/apache/poi/hslf/usermodel/HSLFTextShape.java9
-rw-r--r--poi/src/main/java/org/apache/poi/ddf/EscherArrayProperty.java10
-rw-r--r--poi/src/main/java/org/apache/poi/ddf/EscherContainerRecord.java10
-rw-r--r--poi/src/main/java/org/apache/poi/hssf/record/PageBreakRecord.java8
-rw-r--r--poi/src/main/java/org/apache/poi/hssf/record/aggregates/RowRecordsAggregate.java17
-rw-r--r--poi/src/main/java/org/apache/poi/hssf/record/aggregates/ValueRecordsAggregate.java12
-rw-r--r--poi/src/main/java/org/apache/poi/hssf/record/common/UnicodeString.java11
-rw-r--r--poi/src/main/java/org/apache/poi/hssf/usermodel/HSSFPatriarch.java9
-rw-r--r--poi/src/main/java/org/apache/poi/hssf/usermodel/HSSFRow.java8
-rw-r--r--poi/src/main/java/org/apache/poi/hssf/usermodel/HSSFShapeGroup.java9
-rw-r--r--poi/src/main/java/org/apache/poi/hssf/usermodel/HSSFSheet.java14
-rw-r--r--poi/src/main/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java14
-rw-r--r--poi/src/main/java/org/apache/poi/poifs/filesystem/DirectoryNode.java11
-rw-r--r--poi/src/main/java/org/apache/poi/poifs/filesystem/FilteringDirectoryNode.java10
-rw-r--r--poi/src/main/java/org/apache/poi/poifs/property/DirectoryProperty.java13
-rw-r--r--poi/src/main/java/org/apache/poi/sl/draw/geom/CustomGeometry.java9
-rw-r--r--poi/src/main/java/org/apache/poi/ss/formula/functions/LookupUtils.java14
-rw-r--r--poi/src/main/java/org/apache/poi/ss/usermodel/Row.java28
-rw-r--r--poi/src/main/java/org/apache/poi/ss/usermodel/Sheet.java23
-rw-r--r--poi/src/main/java/org/apache/poi/ss/usermodel/Workbook.java23
-rw-r--r--poi/src/main/java/org/apache/poi/ss/util/CellRangeAddressBase.java11
-rw-r--r--poi/src/main/java/org/apache/poi/ss/util/SSCellRange.java9
-rw-r--r--poi/src/main/java/org/apache/poi/util/IntMapper.java10
-rw-r--r--poi/src/main/java9/module-info.classbin3386 -> 3386 bytes
-rw-r--r--poi/src/test/java/org/apache/poi/hssf/model/TestDrawingShapes.java7
-rw-r--r--poi/src/test/java/org/apache/poi/poifs/filesystem/TestDirectoryNode.java6
-rw-r--r--poi/src/test/java/org/apache/poi/poifs/filesystem/TestFilteringDirectoryNode.java20
-rw-r--r--poi/src/test/java/org/apache/poi/poifs/property/TestDirectoryProperty.java1
-rw-r--r--poi/src/test/java/org/apache/poi/sl/draw/geom/TestPresetGeometries.java5
-rw-r--r--poi/src/test/java/org/apache/poi/ss/usermodel/BaseTestRow.java50
-rw-r--r--poi/src/test/java/org/apache/poi/ss/usermodel/BaseTestSheet.java10
-rw-r--r--poi/src/test/java/org/apache/poi/ss/usermodel/BaseTestWorkbook.java10
-rw-r--r--poi/src/test/java/org/apache/poi/ss/util/TestCellRangeAddress.java26
54 files changed, 634 insertions, 58 deletions
diff --git a/poi-ooxml-lite-agent/src/main/java9/module-info.class b/poi-ooxml-lite-agent/src/main/java9/module-info.class
index 13840f12cc..e5bdb0c1d9 100644
--- a/poi-ooxml-lite-agent/src/main/java9/module-info.class
+++ b/poi-ooxml-lite-agent/src/main/java9/module-info.class
Binary files differ
diff --git a/poi-ooxml/src/main/java/org/apache/poi/openxml4j/opc/PackageRelationshipCollection.java b/poi-ooxml/src/main/java/org/apache/poi/openxml4j/opc/PackageRelationshipCollection.java
index ba507c617f..4ac65c7eaa 100644
--- a/poi-ooxml/src/main/java/org/apache/poi/openxml4j/opc/PackageRelationshipCollection.java
+++ b/poi-ooxml/src/main/java/org/apache/poi/openxml4j/opc/PackageRelationshipCollection.java
@@ -374,6 +374,16 @@ public final class PackageRelationshipCollection implements Iterable<PackageRela
}
/**
+ * Get this collection's spliterator.
+ *
+ * @since POI 5.2.0
+ */
+ @Override
+ public Spliterator<PackageRelationship> spliterator() {
+ return relationshipsByID.values().spliterator();
+ }
+
+ /**
* Get an iterator of a collection with all relationship with the specified
* type.
*
diff --git a/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/text/XDDFTextParagraph.java b/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/text/XDDFTextParagraph.java
index 7fa888b05f..4f52d26a7a 100644
--- a/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/text/XDDFTextParagraph.java
+++ b/poi-ooxml/src/main/java/org/apache/poi/xddf/usermodel/text/XDDFTextParagraph.java
@@ -22,6 +22,7 @@ import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;
+import java.util.Spliterator;
import java.util.function.Function;
import java.util.function.Predicate;
@@ -48,7 +49,7 @@ import org.openxmlformats.schemas.drawingml.x2006.main.CTTextSpacing;
* is the highest level text separation mechanism.
*/
@Beta
-public class XDDFTextParagraph {
+public class XDDFTextParagraph implements Iterable<XDDFTextRun> {
private XDDFTextBody _parent;
private XDDFParagraphProperties _properties;
private final CTTextParagraph _p;
@@ -115,11 +116,20 @@ public class XDDFTextParagraph {
return _runs;
}
+ @Override
public Iterator<XDDFTextRun> iterator() {
return _runs.iterator();
}
/**
+ * @since POI 5.2.0
+ */
+ @Override
+ public Spliterator<XDDFTextRun> spliterator() {
+ return _runs.spliterator();
+ }
+
+ /**
* Append a line break.
*
* @return text run representing this line break ('\n').
diff --git a/poi-ooxml/src/main/java/org/apache/poi/xslf/usermodel/XSLFTextShape.java b/poi-ooxml/src/main/java/org/apache/poi/xslf/usermodel/XSLFTextShape.java
index a147758403..2a0e6aded7 100644
--- a/poi-ooxml/src/main/java/org/apache/poi/xslf/usermodel/XSLFTextShape.java
+++ b/poi-ooxml/src/main/java/org/apache/poi/xslf/usermodel/XSLFTextShape.java
@@ -25,6 +25,7 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;
+import java.util.Spliterator;
import java.util.function.Function;
import java.util.function.Predicate;
@@ -87,6 +88,14 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
return getTextParagraphs().iterator();
}
+ /**
+ * @since POI 5.2.0
+ */
+ @Override
+ public Spliterator<XSLFTextParagraph> spliterator() {
+ return getTextParagraphs().spliterator();
+ }
+
@Override
public String getText() {
StringBuilder out = new StringBuilder();
diff --git a/poi-ooxml/src/main/java/org/apache/poi/xssf/streaming/SXSSFDrawing.java b/poi-ooxml/src/main/java/org/apache/poi/xssf/streaming/SXSSFDrawing.java
index dbaf370e30..c75265a4db 100644
--- a/poi-ooxml/src/main/java/org/apache/poi/xssf/streaming/SXSSFDrawing.java
+++ b/poi-ooxml/src/main/java/org/apache/poi/xssf/streaming/SXSSFDrawing.java
@@ -18,6 +18,7 @@
package org.apache.poi.xssf.streaming;
import java.util.Iterator;
+import java.util.Spliterator;
import org.apache.poi.ss.usermodel.ClientAnchor;
import org.apache.poi.ss.usermodel.Comment;
@@ -66,6 +67,14 @@ public class SXSSFDrawing implements Drawing<XSSFShape> {
public Iterator<XSSFShape> iterator() {
return _drawing.getShapes().iterator();
}
-
+
+ /**
+ * @since POI 5.2.0
+ */
+ @Override
+ public Spliterator<XSSFShape> spliterator() {
+ return _drawing.getShapes().spliterator();
+ }
+
}
diff --git a/poi-ooxml/src/main/java/org/apache/poi/xssf/streaming/SXSSFRow.java b/poi-ooxml/src/main/java/org/apache/poi/xssf/streaming/SXSSFRow.java
index 531261e056..ff86b1ef30 100644
--- a/poi-ooxml/src/main/java/org/apache/poi/xssf/streaming/SXSSFRow.java
+++ b/poi-ooxml/src/main/java/org/apache/poi/xssf/streaming/SXSSFRow.java
@@ -21,6 +21,8 @@ import java.util.Iterator;
import java.util.Map.Entry;
import java.util.NoSuchElementException;
import java.util.SortedMap;
+import java.util.Spliterator;
+import java.util.Spliterators;
import java.util.TreeMap;
import org.apache.poi.ss.SpreadsheetVersion;
@@ -61,6 +63,11 @@ public class SXSSFRow implements Row, Comparable<SXSSFRow>
return new CellIterator();
}
+ public Spliterator<Cell> allCellsSpliterator()
+ {
+ return Spliterators.spliterator(allCellsIterator(), getLastCellNum(), 0);
+ }
+
public boolean hasCustomHeight()
{
return _height!=-1;
@@ -101,15 +108,6 @@ public class SXSSFRow implements Row, Comparable<SXSSFRow>
}
//begin of interface implementation
/**
- * {@inheritDoc}
- */
- @Override
- public Iterator<Cell> iterator()
- {
- return new FilledCellIterator();
- }
-
- /**
* Use this to create new cells within the row and return it.
* <p>
* The cell that is returned is a {@link CellType#BLANK}. The type can be changed
@@ -427,7 +425,23 @@ public class SXSSFRow implements Row, Comparable<SXSSFRow>
@Override
public Iterator<Cell> cellIterator()
{
- return iterator();
+ return new FilledCellIterator();
+ }
+
+ /**
+ * Create a spliterator over the cells from [0, getLastCellNum()).
+ * Includes blank cells, excludes empty cells
+ *
+ * Returns a spliterator over all filled cells (created via Row.createCell())
+ * Throws ConcurrentModificationException if cells are added, moved, or
+ * removed after the spliterator is created.
+ *
+ * @since POI 5.2.0
+ */
+ @Override
+ @SuppressWarnings("unchecked")
+ public Spliterator<Cell> spliterator() {
+ return (Spliterator<Cell>)(Spliterator<? extends Cell>) _cells.values().spliterator();
}
/**
diff --git a/poi-ooxml/src/main/java/org/apache/poi/xssf/streaming/SXSSFSheet.java b/poi-ooxml/src/main/java/org/apache/poi/xssf/streaming/SXSSFSheet.java
index a29ce60499..d4e22810b2 100644
--- a/poi-ooxml/src/main/java/org/apache/poi/xssf/streaming/SXSSFSheet.java
+++ b/poi-ooxml/src/main/java/org/apache/poi/xssf/streaming/SXSSFSheet.java
@@ -24,6 +24,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.Spliterator;
import java.util.TreeMap;
import org.apache.poi.ss.SpreadsheetVersion;
@@ -100,11 +101,6 @@ public class SXSSFSheet implements Sheet, OoxmlSheetExtensions {
}
//start of interface implementation
- @Override
- public Iterator<Row> iterator() {
- return rowIterator();
- }
-
/**
* Create a new row within the sheet and return the high level representation
*
@@ -509,6 +505,20 @@ public class SXSSFSheet implements Sheet, OoxmlSheetExtensions {
}
/**
+ * Returns a spliterator of the physical rows
+ *
+ * @return a spliterator of the PHYSICAL rows. Meaning the 3rd element may not
+ * be the third row if say for instance the second row is undefined.
+ *
+ * @since POI 5.2.0
+ */
+ @Override
+ @SuppressWarnings("unchecked")
+ public Spliterator<Row> spliterator() {
+ return (Spliterator<Row>)(Spliterator<? extends Row>) _rows.values().spliterator();
+ }
+
+ /**
* Flag indicating whether the sheet displays Automatic Page Breaks.
*
* @param value <code>true</code> if the sheet displays Automatic Page Breaks.
diff --git a/poi-ooxml/src/main/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java b/poi-ooxml/src/main/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java
index fc499ad70e..189787f96b 100644
--- a/poi-ooxml/src/main/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java
+++ b/poi-ooxml/src/main/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java
@@ -31,6 +31,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
+import java.util.Spliterator;
import org.apache.commons.compress.archivers.ArchiveOutputStream;
import org.apache.commons.compress.archivers.zip.Zip64Mode;
@@ -758,6 +759,19 @@ public class SXSSFWorkbook implements Workbook {
return new SheetIterator<>();
}
+ /**
+ * Returns a spliterator of the sheets in the workbook
+ * in sheet order. Includes hidden and very hidden sheets.
+ *
+ * @return a spliterator of the sheets.
+ *
+ * @since POI 5.2.0
+ */
+ @Override
+ public Spliterator<Sheet> spliterator() {
+ return _wb.spliterator();
+ }
+
protected final class SheetIterator<T extends Sheet> implements Iterator<T> {
final private Iterator<XSSFSheet> it;
@SuppressWarnings("unchecked")
@@ -787,15 +801,6 @@ public class SXSSFWorkbook implements Workbook {
}
/**
- * Alias for {@link #sheetIterator()} to allow
- * foreach loops
- */
- @Override
- public Iterator<Sheet> iterator() {
- return sheetIterator();
- }
-
- /**
* Get the Sheet object at the given index.
*
* @param index of the sheet number (0-based physical and logical)
diff --git a/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFDrawing.java b/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFDrawing.java
index 46fef0784b..6bf672db6d 100644
--- a/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFDrawing.java
+++ b/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFDrawing.java
@@ -25,6 +25,7 @@ import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
+import java.util.Spliterator;
import javax.xml.namespace.QName;
@@ -725,6 +726,14 @@ public final class XSSFDrawing extends POIXMLDocumentPart implements Drawing<XSS
}
/**
+ * @since POI 5.2.0
+ */
+ @Override
+ public Spliterator<XSSFShape> spliterator() {
+ return getShapes().spliterator();
+ }
+
+ /**
* @return the sheet associated with the drawing
*/
public XSSFSheet getSheet() {
diff --git a/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFRow.java b/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFRow.java
index b35c71e858..85543d5ff0 100644
--- a/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFRow.java
+++ b/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFRow.java
@@ -22,6 +22,7 @@ import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.Objects;
import java.util.Set;
+import java.util.Spliterator;
import java.util.TreeMap;
import org.apache.poi.ss.SpreadsheetVersion;
@@ -120,18 +121,16 @@ public class XSSFRow implements Row, Comparable<XSSFRow> {
}
/**
- * Alias for {@link #cellIterator()} to allow foreach loops:
- * <blockquote><pre>
- * for(Cell cell : row){
- * ...
- * }
- * </pre></blockquote>
+ * Cell spliterator over the physically defined cells
*
- * @return an iterator over cells in this row.
+ * @return a spliterator over cells in this row.
+ *
+ * @since POI 5.2.0
*/
@Override
- public Iterator<Cell> iterator() {
- return cellIterator();
+ @SuppressWarnings("unchecked")
+ public Spliterator<Cell> spliterator() {
+ return (Spliterator<Cell>)(Spliterator<? extends Cell>)_cells.values().spliterator();
}
/**
diff --git a/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFShapeGroup.java b/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFShapeGroup.java
index 96c7c9bcd3..b9c92ddd7a 100644
--- a/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFShapeGroup.java
+++ b/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFShapeGroup.java
@@ -18,6 +18,7 @@
package org.apache.poi.xssf.usermodel;
import java.util.Iterator;
+import java.util.Spliterator;
import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.ss.usermodel.ShapeContainer;
@@ -230,6 +231,14 @@ public final class XSSFShapeGroup extends XSSFShape implements ShapeContainer<XS
return getDrawing().getShapes(this).iterator();
}
+ /**
+ * @since POI 5.2.0
+ */
+ @Override
+ public Spliterator<XSSFShape> spliterator() {
+ return getDrawing().getShapes(this).spliterator();
+ }
+
@Override
public String getShapeName() {
return ctGroup.getNvGrpSpPr().getCNvPr().getName();
diff --git a/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFSheet.java b/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFSheet.java
index 886d25b563..e90c7a5c97 100644
--- a/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFSheet.java
+++ b/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFSheet.java
@@ -2058,12 +2058,16 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet, OoxmlSheetEx
}
/**
- * Alias for {@link #rowIterator()} to
- * allow foreach loops
+ * @return a spliterator of the PHYSICAL rows. Meaning the 3rd element may not
+ * be the third row if say for instance the second row is undefined.
+ * Call getRowNum() on each row if you care which one it is.
+ *
+ * @since POI 5.2.0
*/
@Override
- public Iterator<Row> iterator() {
- return rowIterator();
+ @SuppressWarnings("unchecked")
+ public Spliterator<Row> spliterator() {
+ return (Spliterator<Row>)(Spliterator<? extends Row>) _rows.values().spliterator();
}
/**
diff --git a/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFSimpleShape.java b/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFSimpleShape.java
index dfc7a69466..9cab106a14 100644
--- a/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFSimpleShape.java
+++ b/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFSimpleShape.java
@@ -22,6 +22,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Optional;
+import java.util.Spliterator;
import java.util.function.Function;
import java.util.function.Predicate;
@@ -168,6 +169,14 @@ public class XSSFSimpleShape extends XSSFShape implements Iterable<XSSFTextParag
}
/**
+ * @since POI 5.2.0
+ */
+ @Override
+ public Spliterator<XSSFTextParagraph> spliterator() {
+ return _paragraphs.spliterator();
+ }
+
+ /**
* Returns the text from all paragraphs in the shape. Paragraphs are
* separated by new lines.
*
diff --git a/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java b/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java
index 39cf9c7080..efe4893c5a 100644
--- a/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java
+++ b/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java
@@ -35,6 +35,7 @@ import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.NoSuchElementException;
+import java.util.Spliterator;
import java.util.regex.Pattern;
import javax.xml.namespace.QName;
@@ -1269,6 +1270,20 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, Date1904Su
return sheetIterator();
}
+ /**
+ * Returns a spliterator of the sheets in the workbook
+ * in sheet order. Includes hidden and very hidden sheets.
+ *
+ * @return a spliterator of the sheets.
+ *
+ * @since POI 5.2.0
+ */
+ @Override
+ @SuppressWarnings("unchecked")
+ public Spliterator<Sheet> spliterator() {
+ return (Spliterator<Sheet>)(Spliterator<? extends Sheet>) sheets.spliterator();
+ }
+
private final class SheetIterator<T extends Sheet> implements Iterator<T> {
final private Iterator<T> it;
@SuppressWarnings("unchecked")
diff --git a/poi-ooxml/src/main/java/org/apache/poi/xwpf/usermodel/XWPFAbstractFootnoteEndnote.java b/poi-ooxml/src/main/java/org/apache/poi/xwpf/usermodel/XWPFAbstractFootnoteEndnote.java
index d1a86f2945..8c1cc90784 100644
--- a/poi-ooxml/src/main/java/org/apache/poi/xwpf/usermodel/XWPFAbstractFootnoteEndnote.java
+++ b/poi-ooxml/src/main/java/org/apache/poi/xwpf/usermodel/XWPFAbstractFootnoteEndnote.java
@@ -20,6 +20,7 @@ import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
+import java.util.Spliterator;
import org.apache.poi.ooxml.POIXMLDocumentPart;
import org.apache.poi.util.Internal;
@@ -113,6 +114,17 @@ public abstract class XWPFAbstractFootnoteEndnote implements Iterable<XWPFParag
}
/**
+ * Get a spliterator over the {@link XWPFParagraph}s in the footnote.
+ * @return Spliterator over the paragraph list.
+ *
+ * @since POI 5.2.0
+ */
+ @Override
+ public Spliterator<XWPFParagraph> spliterator() {
+ return paragraphs.spliterator();
+ }
+
+ /**
* Get the list of {@link XWPFTable}s in the footnote.
* @return List of tables
*/
diff --git a/poi-ooxml/src/main/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java b/poi-ooxml/src/main/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java
index 012a09a3a6..3530c7c5fe 100644
--- a/poi-ooxml/src/main/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java
+++ b/poi-ooxml/src/main/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java
@@ -32,6 +32,7 @@ import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import java.util.Spliterator;
import javax.xml.namespace.QName;
@@ -348,6 +349,15 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
return bodyElements.iterator();
}
+ /**
+ * returns a Spliterator with paragraphs and tables
+ *
+ * @since POI 5.2.0
+ */
+ public Spliterator<IBodyElement> getBodyElementsSpliterator() {
+ return bodyElements.spliterator();
+ }
+
@Override
public List<XWPFParagraph> getParagraphs() {
return Collections.unmodifiableList(paragraphs);
@@ -1582,11 +1592,25 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
return tables.iterator();
}
+ /**
+ * @since POI 5.2.0
+ */
+ public Spliterator<XWPFTable> getTablesSpliterator() {
+ return tables.spliterator();
+ }
+
public Iterator<XWPFParagraph> getParagraphsIterator() {
return paragraphs.iterator();
}
/**
+ * @since POI 5.2.0
+ */
+ public Spliterator<XWPFParagraph> getParagraphsSpliterator() {
+ return paragraphs.spliterator();
+ }
+
+ /**
* Returns the paragraph that of position pos
*/
@Override
diff --git a/poi-ooxml/src/test/java/org/apache/poi/xssf/streaming/TestSXSSFSheet.java b/poi-ooxml/src/test/java/org/apache/poi/xssf/streaming/TestSXSSFSheet.java
index 7d92af51a6..dac5bbc746 100644
--- a/poi-ooxml/src/test/java/org/apache/poi/xssf/streaming/TestSXSSFSheet.java
+++ b/poi-ooxml/src/test/java/org/apache/poi/xssf/streaming/TestSXSSFSheet.java
@@ -179,7 +179,9 @@ public final class TestSXSSFSheet extends BaseTestXSheet {
assertEquals(2, row0.getRowNum(), "Row 2 knows its row number");
assertEquals(1, sheet.getRowNum(row1), "Sheet knows Row 1's row number");
assertEquals(2, sheet.getRowNum(row0), "Sheet knows Row 2's row number");
- assertEquals(row1, sheet.iterator().next(), "Sheet row iteratation order should be ascending");
+ assertEquals(row1, sheet.iterator().next(), "Sheet row iteration order should be ascending");
+ sheet.spliterator().tryAdvance(row ->
+ assertEquals(row1, row, "Sheet row iteration order should be ascending"));
wb.close();
}
diff --git a/poi-scratchpad/src/main/java/org/apache/poi/hslf/record/PPDrawing.java b/poi-scratchpad/src/main/java/org/apache/poi/hslf/record/PPDrawing.java
index 2140678d26..1267da2eeb 100644
--- a/poi-scratchpad/src/main/java/org/apache/poi/hslf/record/PPDrawing.java
+++ b/poi-scratchpad/src/main/java/org/apache/poi/hslf/record/PPDrawing.java
@@ -25,6 +25,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
+import java.util.Spliterator;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
@@ -86,6 +87,14 @@ public final class PPDrawing extends RecordAtom implements Iterable<EscherRecord
}
/**
+ * @since POI 5.2.0
+ */
+ @Override
+ public Spliterator<EscherRecord> spliterator() {
+ return getEscherRecords().spliterator();
+ }
+
+ /**
* Get access to the atoms inside Textboxes
*/
public EscherTextboxWrapper[] getTextboxWrappers() { return textboxWrappers; }
diff --git a/poi-scratchpad/src/main/java/org/apache/poi/hslf/usermodel/HSLFGroupShape.java b/poi-scratchpad/src/main/java/org/apache/poi/hslf/usermodel/HSLFGroupShape.java
index cfa09db8a4..a82390e97f 100644
--- a/poi-scratchpad/src/main/java/org/apache/poi/hslf/usermodel/HSLFGroupShape.java
+++ b/poi-scratchpad/src/main/java/org/apache/poi/hslf/usermodel/HSLFGroupShape.java
@@ -21,6 +21,7 @@ import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
+import java.util.Spliterator;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -261,6 +262,14 @@ implements HSLFShapeContainer, GroupShape<HSLFShape,HSLFTextParagraph> {
return getShapes().iterator();
}
+ /**
+ * @since POI 5.2.0
+ */
+ @Override
+ public Spliterator<HSLFShape> spliterator() {
+ return getShapes().spliterator();
+ }
+
@Override
public boolean removeShape(HSLFShape shape) {
// TODO: implement!
diff --git a/poi-scratchpad/src/main/java/org/apache/poi/hslf/usermodel/HSLFSheet.java b/poi-scratchpad/src/main/java/org/apache/poi/hslf/usermodel/HSLFSheet.java
index 6ceafed5b4..effe54e372 100644
--- a/poi-scratchpad/src/main/java/org/apache/poi/hslf/usermodel/HSLFSheet.java
+++ b/poi-scratchpad/src/main/java/org/apache/poi/hslf/usermodel/HSLFSheet.java
@@ -22,6 +22,7 @@ import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
+import java.util.Spliterator;
import org.apache.poi.ddf.EscherContainerRecord;
import org.apache.poi.ddf.EscherDgRecord;
@@ -360,6 +361,13 @@ public abstract class HSLFSheet implements HSLFShapeContainer, Sheet<HSLFShape,H
return getShapes().iterator();
}
+ /**
+ * @since POI 5.2.0
+ */
+ @Override
+ public Spliterator<HSLFShape> spliterator() {
+ return getShapes().spliterator();
+ }
/**
* @return whether shapes on the master sheet should be shown. By default master graphics is turned off.
diff --git a/poi-scratchpad/src/main/java/org/apache/poi/hslf/usermodel/HSLFTextParagraph.java b/poi-scratchpad/src/main/java/org/apache/poi/hslf/usermodel/HSLFTextParagraph.java
index 129c61c0f3..2612b17692 100644
--- a/poi-scratchpad/src/main/java/org/apache/poi/hslf/usermodel/HSLFTextParagraph.java
+++ b/poi-scratchpad/src/main/java/org/apache/poi/hslf/usermodel/HSLFTextParagraph.java
@@ -26,6 +26,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
+import java.util.Spliterator;
import java.util.function.Consumer;
import java.util.stream.Collectors;
@@ -341,6 +342,14 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
return _runs.iterator();
}
+ /**
+ * @since POI 5.2.0
+ */
+ @Override
+ public Spliterator<HSLFTextRun> spliterator() {
+ return _runs.spliterator();
+ }
+
@Override
public Double getLeftMargin() {
Integer val = null;
diff --git a/poi-scratchpad/src/main/java/org/apache/poi/hslf/usermodel/HSLFTextShape.java b/poi-scratchpad/src/main/java/org/apache/poi/hslf/usermodel/HSLFTextShape.java
index 8efa7cadb1..8d99617e7b 100644
--- a/poi-scratchpad/src/main/java/org/apache/poi/hslf/usermodel/HSLFTextShape.java
+++ b/poi-scratchpad/src/main/java/org/apache/poi/hslf/usermodel/HSLFTextShape.java
@@ -28,6 +28,7 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
+import java.util.Spliterator;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -704,6 +705,14 @@ implements TextShape<HSLFShape,HSLFTextParagraph> {
return _paragraphs.iterator();
}
+ /**
+ * @since POI 5.2.0
+ */
+ @Override
+ public Spliterator<HSLFTextParagraph> spliterator() {
+ return _paragraphs.spliterator();
+ }
+
@Override
public Insets2D getInsets() {
return new Insets2D(getTopInset(), getLeftInset(), getBottomInset(), getRightInset());
diff --git a/poi/src/main/java/org/apache/poi/ddf/EscherArrayProperty.java b/poi/src/main/java/org/apache/poi/ddf/EscherArrayProperty.java
index 07731c97bb..e135623c4b 100644
--- a/poi/src/main/java/org/apache/poi/ddf/EscherArrayProperty.java
+++ b/poi/src/main/java/org/apache/poi/ddf/EscherArrayProperty.java
@@ -20,6 +20,8 @@ package org.apache.poi.ddf;
import java.util.Iterator;
import java.util.Map;
import java.util.NoSuchElementException;
+import java.util.Spliterator;
+import java.util.Spliterators;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
@@ -263,6 +265,14 @@ public final class EscherArrayProperty extends EscherComplexProperty implements
};
}
+ /**
+ * @since POI 5.2.0
+ */
+ @Override
+ public Spliterator<byte[]> spliterator() {
+ return Spliterators.spliterator(iterator(), getNumberOfElementsInArray(), 0);
+ }
+
@Override
public Map<String, Supplier<?>> getGenericProperties() {
return GenericRecordUtil.getGenericProperties(
diff --git a/poi/src/main/java/org/apache/poi/ddf/EscherContainerRecord.java b/poi/src/main/java/org/apache/poi/ddf/EscherContainerRecord.java
index e525d50333..74df2761a6 100644
--- a/poi/src/main/java/org/apache/poi/ddf/EscherContainerRecord.java
+++ b/poi/src/main/java/org/apache/poi/ddf/EscherContainerRecord.java
@@ -23,6 +23,7 @@ import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Spliterator;
import java.util.function.Supplier;
import org.apache.logging.log4j.LogManager;
@@ -170,6 +171,15 @@ public final class EscherContainerRecord extends EscherRecord implements Iterabl
return Collections.unmodifiableList(_childRecords).iterator();
}
+ /**
+ * @return a spliterator over the child records
+ *
+ * @since POI 5.2.0
+ */
+ @Override
+ public Spliterator<EscherRecord> spliterator() {
+ return _childRecords.spliterator();
+ }
/**
* replaces the internal child list with the contents of the supplied {@code childRecords}
diff --git a/poi/src/main/java/org/apache/poi/hssf/record/PageBreakRecord.java b/poi/src/main/java/org/apache/poi/hssf/record/PageBreakRecord.java
index eda43c94e2..1df6e28c8e 100644
--- a/poi/src/main/java/org/apache/poi/hssf/record/PageBreakRecord.java
+++ b/poi/src/main/java/org/apache/poi/hssf/record/PageBreakRecord.java
@@ -21,6 +21,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
+import java.util.Spliterator;
import java.util.function.Supplier;
import org.apache.poi.common.usermodel.GenericRecord;
@@ -146,6 +147,13 @@ public abstract class PageBreakRecord extends StandardRecord {
return _breaks.iterator();
}
+ /**
+ * @since POI 5.2.0
+ */
+ public final Spliterator<Break> getBreaksSpliterator() {
+ return _breaks.spliterator();
+ }
+
/**
* Adds the page break at the specified parameters
* @param main Depending on sid, will determine row or column to put page break (zero-based)
diff --git a/poi/src/main/java/org/apache/poi/hssf/record/aggregates/RowRecordsAggregate.java b/poi/src/main/java/org/apache/poi/hssf/record/aggregates/RowRecordsAggregate.java
index 172ce0e7ea..2a5789c7cb 100644
--- a/poi/src/main/java/org/apache/poi/hssf/record/aggregates/RowRecordsAggregate.java
+++ b/poi/src/main/java/org/apache/poi/hssf/record/aggregates/RowRecordsAggregate.java
@@ -21,6 +21,7 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Spliterator;
import java.util.TreeMap;
import org.apache.poi.hssf.model.RecordStream;
@@ -307,6 +308,13 @@ public final class RowRecordsAggregate extends RecordAggregate {
return _rowRecords.values().iterator();
}
+ /**
+ * @since POI 5.2.0
+ */
+ public Spliterator<RowRecord> getSpliterator() {
+ return _rowRecords.values().spliterator();
+ }
+
public int findStartOfRowOutlineGroup(int row) {
// Find the start of the group.
RowRecord rowRecord = this.getRow( row );
@@ -461,6 +469,15 @@ public final class RowRecordsAggregate extends RecordAggregate {
return _valuesAgg.iterator();
}
+ /**
+ * Returns a spliterator for the cell values
+ *
+ * @since POI 5.2.0
+ */
+ public Spliterator<CellValueRecordInterface> getCellValueSpliterator() {
+ return _valuesAgg.spliterator();
+ }
+
public IndexRecord createIndexRecord(int indexRecordOffset, int sizeOfInitialSheetRecords) {
IndexRecord result = new IndexRecord();
result.setFirstRow(_firstrow);
diff --git a/poi/src/main/java/org/apache/poi/hssf/record/aggregates/ValueRecordsAggregate.java b/poi/src/main/java/org/apache/poi/hssf/record/aggregates/ValueRecordsAggregate.java
index 7b53847741..d5a9ba5478 100644
--- a/poi/src/main/java/org/apache/poi/hssf/record/aggregates/ValueRecordsAggregate.java
+++ b/poi/src/main/java/org/apache/poi/hssf/record/aggregates/ValueRecordsAggregate.java
@@ -19,6 +19,8 @@ package org.apache.poi.hssf.record.aggregates;
import java.util.Iterator;
import java.util.NoSuchElementException;
+import java.util.Spliterator;
+import java.util.Spliterators;
import org.apache.poi.hssf.model.RecordStream;
import org.apache.poi.hssf.record.BlankRecord;
@@ -354,4 +356,14 @@ public final class ValueRecordsAggregate implements Iterable<CellValueRecordInte
public Iterator<CellValueRecordInterface> iterator() {
return new ValueIterator();
}
+
+ /**
+ * value spliterator
+ *
+ * @since POI 5.2.0
+ */
+ @Override
+ public Spliterator<CellValueRecordInterface> spliterator() {
+ return Spliterators.spliterator(iterator(), getPhysicalNumberOfCells(), 0);
+ }
}
diff --git a/poi/src/main/java/org/apache/poi/hssf/record/common/UnicodeString.java b/poi/src/main/java/org/apache/poi/hssf/record/common/UnicodeString.java
index 63c405aeca..37fd7e0ec5 100644
--- a/poi/src/main/java/org/apache/poi/hssf/record/common/UnicodeString.java
+++ b/poi/src/main/java/org/apache/poi/hssf/record/common/UnicodeString.java
@@ -23,6 +23,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
+import java.util.Spliterator;
import java.util.function.Supplier;
import java.util.stream.Collectors;
@@ -324,6 +325,16 @@ public class UnicodeString implements Comparable<UnicodeString>, Duplicatable, G
return null;
}
+ /**
+ * @since POI 5.2.0
+ */
+ public Spliterator<FormatRun> formatSpliterator() {
+ if (field_4_format_runs != null) {
+ return field_4_format_runs.spliterator();
+ }
+ return null;
+ }
+
public void removeFormatRun(FormatRun r) {
field_4_format_runs.remove(r);
if (field_4_format_runs.size() == 0) {
diff --git a/poi/src/main/java/org/apache/poi/hssf/usermodel/HSSFPatriarch.java b/poi/src/main/java/org/apache/poi/hssf/usermodel/HSSFPatriarch.java
index bf68edf821..45ac29a9eb 100644
--- a/poi/src/main/java/org/apache/poi/hssf/usermodel/HSSFPatriarch.java
+++ b/poi/src/main/java/org/apache/poi/hssf/usermodel/HSSFPatriarch.java
@@ -25,6 +25,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.Spliterator;
import org.apache.poi.ddf.EscherComplexProperty;
import org.apache.poi.ddf.EscherContainerRecord;
@@ -554,6 +555,14 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing<HSSFShap
return _shapes.iterator();
}
+ /**
+ * @since POI 5.2.0
+ */
+ @Override
+ public Spliterator<HSSFShape> spliterator() {
+ return _shapes.spliterator();
+ }
+
protected HSSFSheet getSheet() {
return _sheet;
}
diff --git a/poi/src/main/java/org/apache/poi/hssf/usermodel/HSSFRow.java b/poi/src/main/java/org/apache/poi/hssf/usermodel/HSSFRow.java
index 4a28ca4668..83d6213b32 100644
--- a/poi/src/main/java/org/apache/poi/hssf/usermodel/HSSFRow.java
+++ b/poi/src/main/java/org/apache/poi/hssf/usermodel/HSSFRow.java
@@ -630,14 +630,6 @@ public final class HSSFRow implements Row, Comparable<HSSFRow> {
{
return new CellIterator();
}
- /**
- * Alias for {@link #cellIterator} to allow
- * foreach loops
- */
- @Override
- public Iterator<Cell> iterator() {
- return cellIterator();
- }
/**
* An iterator over the (physical) cells in the row.
diff --git a/poi/src/main/java/org/apache/poi/hssf/usermodel/HSSFShapeGroup.java b/poi/src/main/java/org/apache/poi/hssf/usermodel/HSSFShapeGroup.java
index 623409d684..ab7df1d733 100644
--- a/poi/src/main/java/org/apache/poi/hssf/usermodel/HSSFShapeGroup.java
+++ b/poi/src/main/java/org/apache/poi/hssf/usermodel/HSSFShapeGroup.java
@@ -21,6 +21,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
+import java.util.Spliterator;
import org.apache.poi.ddf.DefaultEscherRecordFactory;
import org.apache.poi.ddf.EscherBoolProperty;
@@ -410,4 +411,12 @@ public class HSSFShapeGroup extends HSSFShape implements HSSFShapeContainer {
public Iterator<HSSFShape> iterator() {
return shapes.iterator();
}
+
+ /**
+ * @since POI 5.2.0
+ */
+ @Override
+ public Spliterator<HSSFShape> spliterator() {
+ return shapes.spliterator();
+ }
}
diff --git a/poi/src/main/java/org/apache/poi/hssf/usermodel/HSSFSheet.java b/poi/src/main/java/org/apache/poi/hssf/usermodel/HSSFSheet.java
index b37f54605a..f77cc16205 100644
--- a/poi/src/main/java/org/apache/poi/hssf/usermodel/HSSFSheet.java
+++ b/poi/src/main/java/org/apache/poi/hssf/usermodel/HSSFSheet.java
@@ -23,6 +23,7 @@ import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Spliterator;
import java.util.TreeMap;
import java.util.TreeSet;
@@ -963,15 +964,18 @@ public final class HSSFSheet implements Sheet {
}
/**
- * Alias for {@link #rowIterator()} to allow
- * foreach loops
+ * @return a spliterator of the PHYSICAL rows. Meaning the 3rd element may not
+ * be the third row if say for instance the second row is undefined.
+ * Call getRowNum() on each row if you care which one it is.
+ *
+ * @since POI 5.2.0
*/
@Override
- public Iterator<Row> iterator() {
- return rowIterator();
+ @SuppressWarnings("unchecked") // can this clumsy generic syntax be improved?
+ public Spliterator<Row> spliterator() {
+ return (Spliterator<Row>)(Spliterator<? extends Row>) _rows.values().spliterator();
}
-
/**
* used internally in the API to get the low level Sheet record represented by this
* Object.
diff --git a/poi/src/main/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java b/poi/src/main/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java
index e2504d2712..e369488d10 100644
--- a/poi/src/main/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java
+++ b/poi/src/main/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java
@@ -42,6 +42,7 @@ import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
+import java.util.Spliterator;
import java.util.regex.Pattern;
import org.apache.commons.codec.digest.DigestUtils;
@@ -988,12 +989,17 @@ public final class HSSFWorkbook extends POIDocument implements Workbook {
}
/**
- * Alias for {@link #sheetIterator()} to allow
- * foreach loops
+ * Returns a spliterator of the sheets in the workbook
+ * in sheet order. Includes hidden and very hidden sheets.
+ *
+ * @return a spliterator of the sheets.
+ *
+ * @since POI 5.2.0
*/
@Override
- public Iterator<Sheet> iterator() {
- return sheetIterator();
+ @SuppressWarnings("unchecked")
+ public Spliterator<Sheet> spliterator() {
+ return (Spliterator<Sheet>)(Spliterator<? extends Sheet>) _sheets.spliterator();
}
private final class SheetIterator<T extends Sheet> implements Iterator<T> {
diff --git a/poi/src/main/java/org/apache/poi/poifs/filesystem/DirectoryNode.java b/poi/src/main/java/org/apache/poi/poifs/filesystem/DirectoryNode.java
index 3b233ab81d..cd3a1bc134 100644
--- a/poi/src/main/java/org/apache/poi/poifs/filesystem/DirectoryNode.java
+++ b/poi/src/main/java/org/apache/poi/poifs/filesystem/DirectoryNode.java
@@ -28,6 +28,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.Spliterator;
import org.apache.poi.hpsf.ClassID;
import org.apache.poi.poifs.dev.POIFSViewable;
@@ -553,6 +554,16 @@ public class DirectoryNode
return getEntries();
}
+ /**
+ * Returns a Spliterator over all the entries
+ *
+ * @since POI 5.2.0
+ */
+ @Override
+ public Spliterator<Entry> spliterator() {
+ return _entries.spliterator();
+ }
+
/* ********** END begin implementation of POIFSViewable ********** */
} // end public class DirectoryNode
diff --git a/poi/src/main/java/org/apache/poi/poifs/filesystem/FilteringDirectoryNode.java b/poi/src/main/java/org/apache/poi/poifs/filesystem/FilteringDirectoryNode.java
index 609578aaa9..9b3c0150b0 100644
--- a/poi/src/main/java/org/apache/poi/poifs/filesystem/FilteringDirectoryNode.java
+++ b/poi/src/main/java/org/apache/poi/poifs/filesystem/FilteringDirectoryNode.java
@@ -31,6 +31,8 @@ import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
+import java.util.Spliterator;
+import java.util.Spliterators;
import org.apache.poi.hpsf.ClassID;
@@ -115,6 +117,14 @@ public class FilteringDirectoryNode implements DirectoryEntry
return getEntries();
}
+ /**
+ * @since POI 5.2.0
+ */
+ @Override
+ public Spliterator<Entry> spliterator() {
+ return Spliterators.spliterator(iterator(), getEntryCount(), 0);
+ }
+
@Override
public int getEntryCount() {
int size = directory.getEntryCount();
diff --git a/poi/src/main/java/org/apache/poi/poifs/property/DirectoryProperty.java b/poi/src/main/java/org/apache/poi/poifs/property/DirectoryProperty.java
index 0e72e089cd..b7e6356b38 100644
--- a/poi/src/main/java/org/apache/poi/poifs/property/DirectoryProperty.java
+++ b/poi/src/main/java/org/apache/poi/poifs/property/DirectoryProperty.java
@@ -26,6 +26,7 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
+import java.util.Spliterator;
/**
* Directory property
@@ -243,6 +244,18 @@ public class DirectoryProperty extends Property implements Parent, Iterable<Prop
public Iterator<Property> iterator() {
return getChildren();
}
+ /**
+ * Get a spliterator over the children of this Parent; all elements
+ * are instances of Property.
+ *
+ * @return Spliterator of children; may refer to an empty collection
+ *
+ * @since POI 5.2.0
+ */
+ @Override
+ public Spliterator<Property> spliterator() {
+ return _children.spliterator();
+ }
/**
* Add a new child to the collection of children
diff --git a/poi/src/main/java/org/apache/poi/sl/draw/geom/CustomGeometry.java b/poi/src/main/java/org/apache/poi/sl/draw/geom/CustomGeometry.java
index 84ef46357f..a5157c23d9 100644
--- a/poi/src/main/java/org/apache/poi/sl/draw/geom/CustomGeometry.java
+++ b/poi/src/main/java/org/apache/poi/sl/draw/geom/CustomGeometry.java
@@ -23,6 +23,7 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
+import java.util.Spliterator;
/**
* Definition of a custom geometric shape
@@ -110,6 +111,14 @@ public final class CustomGeometry implements Iterable<PathIf>{
return paths.iterator();
}
+ /**
+ * @since POI 5.2.0
+ */
+ @Override
+ public Spliterator<PathIf> spliterator() {
+ return paths.spliterator();
+ }
+
public Path getTextBounds(){
return textBounds;
}
diff --git a/poi/src/main/java/org/apache/poi/ss/formula/functions/LookupUtils.java b/poi/src/main/java/org/apache/poi/ss/formula/functions/LookupUtils.java
index 09528ae95a..a393e13b65 100644
--- a/poi/src/main/java/org/apache/poi/ss/formula/functions/LookupUtils.java
+++ b/poi/src/main/java/org/apache/poi/ss/formula/functions/LookupUtils.java
@@ -21,6 +21,8 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
+import java.util.Spliterator;
+import java.util.Spliterators;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -123,6 +125,12 @@ public final class LookupUtils {
}
};
}
+ /**
+ * @since POI 5.2.0
+ */
+ default Spliterator<Integer> indexSpliterator() {
+ return Spliterators.spliterator(indexIterator(), getSize(), 0);
+ }
default Iterator<Integer> reverseIndexIterator() {
return new Iterator<Integer>() {
int pos = getSize() - 1;
@@ -138,6 +146,12 @@ public final class LookupUtils {
}
};
}
+ /**
+ * @since POI 5.2.0
+ */
+ default Spliterator<Integer> reverseIndexSpliterator() {
+ return Spliterators.spliterator(reverseIndexIterator(), getSize(), 0);
+ }
}
private static final class RowVector implements ValueVector {
diff --git a/poi/src/main/java/org/apache/poi/ss/usermodel/Row.java b/poi/src/main/java/org/apache/poi/ss/usermodel/Row.java
index ff27f4e826..2ddb957274 100644
--- a/poi/src/main/java/org/apache/poi/ss/usermodel/Row.java
+++ b/poi/src/main/java/org/apache/poi/ss/usermodel/Row.java
@@ -18,6 +18,8 @@
package org.apache.poi.ss.usermodel;
import java.util.Iterator;
+import java.util.Spliterator;
+import java.util.Spliterators;
/**
* High level representation of a row of a spreadsheet.
@@ -212,6 +214,32 @@ public interface Row extends Iterable<Cell> {
Iterator<Cell> cellIterator();
/**
+ * Alias for {@link #cellIterator()} to allow foreach loops:
+ * <blockquote><pre>
+ * for(Cell cell : row){
+ * ...
+ * }
+ * </pre></blockquote>
+ *
+ * @return an iterator over cells in this row.
+ */
+ @Override
+ default Iterator<Cell> iterator() {
+ return cellIterator();
+ }
+
+ /**
+ * @return Cell spliterator of the physically defined cells. Note element 4 may
+ * actually be row cell depending on how many are defined!
+ *
+ * @since POI 5.2.0
+ */
+ @Override
+ default Spliterator<Cell> spliterator() {
+ return Spliterators.spliterator(cellIterator(), getPhysicalNumberOfCells(), 0);
+ }
+
+ /**
* Returns the Sheet this row belongs to
*
* @return the Sheet that owns this row
diff --git a/poi/src/main/java/org/apache/poi/ss/usermodel/Sheet.java b/poi/src/main/java/org/apache/poi/ss/usermodel/Sheet.java
index fadbb6f48b..ee03e35ea7 100644
--- a/poi/src/main/java/org/apache/poi/ss/usermodel/Sheet.java
+++ b/poi/src/main/java/org/apache/poi/ss/usermodel/Sheet.java
@@ -21,6 +21,8 @@ import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Spliterator;
+import java.util.Spliterators;
import org.apache.poi.ss.util.CellAddress;
import org.apache.poi.ss.util.CellRangeAddress;
@@ -376,6 +378,27 @@ public interface Sheet extends Iterable<Row> {
Iterator<Row> rowIterator();
/**
+ * Alias for {@link #rowIterator()} to allow foreach loops
+ */
+ @Override
+ default Iterator<Row> iterator() {
+ return rowIterator();
+ }
+
+ /**
+ * Returns a spliterator of the physical rows
+ *
+ * @return a spliterator of the PHYSICAL rows. Meaning the 3rd element may not
+ * be the third row if say for instance the second row is undefined.
+ *
+ * @since POI 5.2.0
+ */
+ @Override
+ default Spliterator<Row> spliterator() {
+ return Spliterators.spliterator(rowIterator(), getPhysicalNumberOfRows(), 0);
+ }
+
+ /**
* Control if Excel should be asked to recalculate all formulas on this sheet
* when the workbook is opened.
*
diff --git a/poi/src/main/java/org/apache/poi/ss/usermodel/Workbook.java b/poi/src/main/java/org/apache/poi/ss/usermodel/Workbook.java
index 26a81725c0..e76637f5fd 100644
--- a/poi/src/main/java/org/apache/poi/ss/usermodel/Workbook.java
+++ b/poi/src/main/java/org/apache/poi/ss/usermodel/Workbook.java
@@ -22,6 +22,8 @@ import java.io.IOException;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.List;
+import java.util.Spliterator;
+import java.util.Spliterators;
import org.apache.poi.ss.SpreadsheetVersion;
import org.apache.poi.ss.formula.EvaluationWorkbook;
@@ -221,6 +223,27 @@ public interface Workbook extends Closeable, Iterable<Sheet> {
Iterator<Sheet> sheetIterator();
/**
+ * Alias for {@link #sheetIterator()} to allow foreach loops
+ */
+ @Override
+ default Iterator<Sheet> iterator() {
+ return sheetIterator();
+ }
+
+ /**
+ * Returns a spliterator of the sheets in the workbook
+ * in sheet order. Includes hidden and very hidden sheets.
+ *
+ * @return a spliterator of the sheets.
+ *
+ * @since POI 5.2.0
+ */
+ @Override
+ default Spliterator<Sheet> spliterator() {
+ return Spliterators.spliterator(sheetIterator(), getNumberOfSheets(), 0);
+ }
+
+ /**
* Get the number of spreadsheets in the workbook
*
* @return the number of sheets
diff --git a/poi/src/main/java/org/apache/poi/ss/util/CellRangeAddressBase.java b/poi/src/main/java/org/apache/poi/ss/util/CellRangeAddressBase.java
index 482bc70f02..d8852221c4 100644
--- a/poi/src/main/java/org/apache/poi/ss/util/CellRangeAddressBase.java
+++ b/poi/src/main/java/org/apache/poi/ss/util/CellRangeAddressBase.java
@@ -22,6 +22,8 @@ import java.util.Iterator;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
+import java.util.Spliterator;
+import java.util.Spliterators;
import java.util.function.Supplier;
import org.apache.poi.common.Duplicatable;
@@ -290,6 +292,15 @@ public abstract class CellRangeAddressBase implements Iterable<CellAddress>, Dup
}
/**
+ * Returns a spliterator over the CellAddresses in this cell range in row-major order.
+ * @since POI 5.2.0
+ */
+ @Override
+ public Spliterator<CellAddress> spliterator() {
+ return Spliterators.spliterator(iterator(), getNumberOfCells(), 0);
+ }
+
+ /**
* Iterates over the cell addresses in a cell range in row major order
*
* The iterator is unaffected by changes to the CellRangeAddressBase instance
diff --git a/poi/src/main/java/org/apache/poi/ss/util/SSCellRange.java b/poi/src/main/java/org/apache/poi/ss/util/SSCellRange.java
index c9cb954bf2..20757c092f 100644
--- a/poi/src/main/java/org/apache/poi/ss/util/SSCellRange.java
+++ b/poi/src/main/java/org/apache/poi/ss/util/SSCellRange.java
@@ -20,6 +20,7 @@ package org.apache.poi.ss.util;
import java.lang.reflect.Array;
import java.util.Iterator;
import java.util.List;
+import java.util.Spliterator;
import java.util.stream.Stream;
import org.apache.poi.ss.usermodel.Cell;
@@ -119,4 +120,12 @@ public final class SSCellRange<K extends Cell> implements CellRange<K> {
public Iterator<K> iterator() {
return Stream.of(_flattenedArray).iterator();
}
+
+ /**
+ * @since POI 5.2.0
+ */
+ @Override
+ public Spliterator<K> spliterator() {
+ return Stream.of(_flattenedArray).spliterator();
+ }
}
diff --git a/poi/src/main/java/org/apache/poi/util/IntMapper.java b/poi/src/main/java/org/apache/poi/util/IntMapper.java
index 86d5b599ae..3a2c4f2ecd 100644
--- a/poi/src/main/java/org/apache/poi/util/IntMapper.java
+++ b/poi/src/main/java/org/apache/poi/util/IntMapper.java
@@ -24,6 +24,7 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Spliterator;
import org.apache.poi.common.Duplicatable;
@@ -37,7 +38,7 @@ import org.apache.poi.common.Duplicatable;
* update
*/
-public class IntMapper<T> implements Duplicatable {
+public class IntMapper<T> implements Duplicatable, Iterable<T> {
private final List<T> elements;
private final Map<T, Integer> valueKeyMap;
@@ -90,6 +91,13 @@ public class IntMapper<T> implements Duplicatable {
return elements.iterator();
}
+ /**
+ * @since POI 5.2.0
+ */
+ public Spliterator<T> spliterator() {
+ return elements.spliterator();
+ }
+
@Override
public IntMapper<T> copy() {
return new IntMapper<>(this);
diff --git a/poi/src/main/java9/module-info.class b/poi/src/main/java9/module-info.class
index e6ce06b6d3..6274a9f771 100644
--- a/poi/src/main/java9/module-info.class
+++ b/poi/src/main/java9/module-info.class
Binary files differ
diff --git a/poi/src/test/java/org/apache/poi/hssf/model/TestDrawingShapes.java b/poi/src/test/java/org/apache/poi/hssf/model/TestDrawingShapes.java
index 81673da773..1ca797067f 100644
--- a/poi/src/test/java/org/apache/poi/hssf/model/TestDrawingShapes.java
+++ b/poi/src/test/java/org/apache/poi/hssf/model/TestDrawingShapes.java
@@ -25,10 +25,12 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
+import java.util.Spliterator;
import org.apache.poi.ddf.EscherBoolProperty;
import org.apache.poi.ddf.EscherContainerRecord;
@@ -700,6 +702,11 @@ class TestDrawingShapes {
assertEquals(s1, iter.next());
assertEquals(s2, iter.next());
assertFalse(iter.hasNext());
+
+ Spliterator<HSSFShape> spliter = patriarch.spliterator();
+ spliter.tryAdvance(s -> assertEquals(s1, s));
+ spliter.tryAdvance(s -> assertEquals(s2, s));
+ assertFalse(spliter.tryAdvance(s -> fail()));
}
}
diff --git a/poi/src/test/java/org/apache/poi/poifs/filesystem/TestDirectoryNode.java b/poi/src/test/java/org/apache/poi/poifs/filesystem/TestDirectoryNode.java
index 9212aa6c8f..1a81dc5a58 100644
--- a/poi/src/test/java/org/apache/poi/poifs/filesystem/TestDirectoryNode.java
+++ b/poi/src/test/java/org/apache/poi/poifs/filesystem/TestDirectoryNode.java
@@ -63,6 +63,9 @@ final class TestDirectoryNode {
}
assertEquals(0, count);
+ // verify that spliterator behaves correctly
+ assertEquals(0, node.spliterator().getExactSizeIfKnown());
+
// verify behavior of isEmpty
assertTrue(node.isEmpty());
@@ -111,6 +114,9 @@ final class TestDirectoryNode {
}
assertEquals(2, count);
+ // verify that spliterator behaves correctly
+ assertEquals(2, node.spliterator().getExactSizeIfKnown());
+
// verify behavior of isEmpty
assertFalse(node.isEmpty());
diff --git a/poi/src/test/java/org/apache/poi/poifs/filesystem/TestFilteringDirectoryNode.java b/poi/src/test/java/org/apache/poi/poifs/filesystem/TestFilteringDirectoryNode.java
index aa9c8883af..ae28e00d36 100644
--- a/poi/src/test/java/org/apache/poi/poifs/filesystem/TestFilteringDirectoryNode.java
+++ b/poi/src/test/java/org/apache/poi/poifs/filesystem/TestFilteringDirectoryNode.java
@@ -22,6 +22,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
import java.io.ByteArrayInputStream;
import java.io.FileNotFoundException;
@@ -30,6 +31,7 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
+import java.util.Spliterator;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -77,6 +79,12 @@ final class TestFilteringDirectoryNode {
assertEquals(dirB, i.next());
assertEquals(eRoot, i.next());
assertThrows(NoSuchElementException.class, i::next, "Should throw NoSuchElementException when depleted");
+
+ Spliterator<Entry> s = d.spliterator();
+ s.tryAdvance(entry -> assertEquals(dirA, entry));
+ s.tryAdvance(entry -> assertEquals(dirB, entry));
+ s.tryAdvance(entry -> assertEquals(eRoot, entry));
+ assertFalse(s.tryAdvance(entry -> fail("Should be depleted")), "Should return false when depleted");
}
@Test
@@ -98,6 +106,11 @@ final class TestFilteringDirectoryNode {
assertEquals(dirB, i.next());
assertThrows(NoSuchElementException.class, i::next, "Should throw NoSuchElementException when depleted");
+ Spliterator<Entry> s1 = d1.spliterator();
+ s1.tryAdvance(entry -> assertEquals(dirA, entry));
+ s1.tryAdvance(entry -> assertEquals(dirB, entry));
+ assertFalse(s1.tryAdvance(entry -> fail("Should be depleted")), "Should return false when depleted");
+
// Filter more
excl = Arrays.asList("NotThere", "AlsoNotThere", eRoot.getName(), dirA.getName());
@@ -115,6 +128,10 @@ final class TestFilteringDirectoryNode {
assertEquals(dirB, i.next());
assertThrows(NoSuchElementException.class, i::next, "Should throw NoSuchElementException when depleted");
+ Spliterator<Entry> s2 = d2.spliterator();
+ s2.tryAdvance(entry -> assertEquals(dirB, entry));
+ assertFalse(s2.tryAdvance(entry -> fail("Should be depleted")), "Should return false when depleted");
+
// Filter everything
excl = Arrays.asList("NotThere", eRoot.getName(), dirA.getName(), dirB.getName());
FilteringDirectoryNode d3 = new FilteringDirectoryNode(fs.getRoot(), excl);
@@ -129,6 +146,9 @@ final class TestFilteringDirectoryNode {
i = d3.getEntries();
assertThrows(NoSuchElementException.class, i::next, "Should throw NoSuchElementException when depleted");
+
+ Spliterator<Entry> s3 = d3.spliterator();
+ assertFalse(s3.tryAdvance(entry -> fail("Should be depleted")), "Should return false when depleted");
}
@Test
diff --git a/poi/src/test/java/org/apache/poi/poifs/property/TestDirectoryProperty.java b/poi/src/test/java/org/apache/poi/poifs/property/TestDirectoryProperty.java
index f3f855fd8d..c200bbdee0 100644
--- a/poi/src/test/java/org/apache/poi/poifs/property/TestDirectoryProperty.java
+++ b/poi/src/test/java/org/apache/poi/poifs/property/TestDirectoryProperty.java
@@ -110,6 +110,7 @@ final class TestDirectoryProperty {
children.add(iter.next());
}
assertEquals(count, children.size());
+ assertEquals(count, _property.spliterator().getExactSizeIfKnown());
if (count != 0)
{
boolean[] found = new boolean[ count ];
diff --git a/poi/src/test/java/org/apache/poi/sl/draw/geom/TestPresetGeometries.java b/poi/src/test/java/org/apache/poi/sl/draw/geom/TestPresetGeometries.java
index 6cb3360b68..ddf6aaf1d2 100644
--- a/poi/src/test/java/org/apache/poi/sl/draw/geom/TestPresetGeometries.java
+++ b/poi/src/test/java/org/apache/poi/sl/draw/geom/TestPresetGeometries.java
@@ -24,7 +24,9 @@ import static org.junit.jupiter.api.Assertions.assertSame;
import java.awt.geom.Path2D;
import java.awt.geom.Rectangle2D;
+import java.util.stream.StreamSupport;
+import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
class TestPresetGeometries {
@@ -41,6 +43,9 @@ class TestPresetGeometries {
Path2D path = p.getPath(ctx);
assertNotNull(path);
}
+ StreamSupport.stream(geom.spliterator(), true)
+ .map(p -> p.getPath(ctx))
+ .forEach(Assertions::assertNotNull);
}
// we get the same instance on further calls
diff --git a/poi/src/test/java/org/apache/poi/ss/usermodel/BaseTestRow.java b/poi/src/test/java/org/apache/poi/ss/usermodel/BaseTestRow.java
index c2205d240c..878b5ab9e4 100644
--- a/poi/src/test/java/org/apache/poi/ss/usermodel/BaseTestRow.java
+++ b/poi/src/test/java/org/apache/poi/ss/usermodel/BaseTestRow.java
@@ -25,9 +25,11 @@ import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
import java.io.IOException;
import java.util.Iterator;
+import java.util.Spliterator;
import org.apache.poi.ss.ITestDataProvider;
import org.apache.poi.ss.usermodel.Row.MissingCellPolicy;
@@ -408,6 +410,54 @@ public abstract class BaseTestRow {
wb.close();
}
+ /**
+ * Test adding cells to a row in various places and see if we can find them again.
+ */
+ @Test
+ void testSpliterator() throws IOException {
+ Workbook wb = _testDataProvider.createWorkbook();
+ Sheet sheet = wb.createSheet();
+ Row row = sheet.createRow(0);
+
+ // One cell at the beginning
+ Cell cell1 = row.createCell(1);
+ Spliterator<Cell> split = row.spliterator();
+ assertTrue(split.tryAdvance(cell -> assertSame(cell1, cell)));
+ assertFalse(split.tryAdvance(cell -> fail()));
+
+ // Add another cell at the end
+ Cell cell2 = row.createCell(99);
+ split = row.spliterator();
+ assertTrue(split.tryAdvance(cell -> assertSame(cell1, cell)));
+ assertTrue(split.tryAdvance(cell -> assertSame(cell2, cell)));
+
+ // Add another cell at the beginning
+ Cell cell3 = row.createCell(0);
+ split = row.spliterator();
+ assertTrue(split.tryAdvance(cell -> assertSame(cell3, cell)));
+ assertTrue(split.tryAdvance(cell -> assertSame(cell1, cell)));
+ assertTrue(split.tryAdvance(cell -> assertSame(cell2, cell)));
+
+ // Replace cell1
+ Cell cell4 = row.createCell(1);
+ split = row.spliterator();
+ assertTrue(split.tryAdvance(cell -> assertSame(cell3, cell)));
+ assertTrue(split.tryAdvance(cell -> assertSame(cell4, cell)));
+ assertTrue(split.tryAdvance(cell -> assertSame(cell2, cell)));
+ assertFalse(split.tryAdvance(cell -> fail()));
+
+ // Add another cell, specifying the cellType
+ Cell cell5 = row.createCell(2, CellType.STRING);
+ split = row.spliterator();
+ assertNotNull(cell5);
+ assertTrue(split.tryAdvance(cell -> assertSame(cell3, cell)));
+ assertTrue(split.tryAdvance(cell -> assertSame(cell4, cell)));
+ assertTrue(split.tryAdvance(cell -> assertSame(cell5, cell)));
+ assertTrue(split.tryAdvance(cell -> assertSame(cell2, cell)));
+ assertEquals(CellType.STRING, cell5.getCellType());
+ wb.close();
+ }
+
@Test
void testRowStyle() throws IOException {
Workbook wb1 = _testDataProvider.createWorkbook();
diff --git a/poi/src/test/java/org/apache/poi/ss/usermodel/BaseTestSheet.java b/poi/src/test/java/org/apache/poi/ss/usermodel/BaseTestSheet.java
index 2b4a8697a4..6c069f0539 100644
--- a/poi/src/test/java/org/apache/poi/ss/usermodel/BaseTestSheet.java
+++ b/poi/src/test/java/org/apache/poi/ss/usermodel/BaseTestSheet.java
@@ -37,6 +37,7 @@ import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
+import java.util.Spliterator;
import org.apache.poi.common.usermodel.HyperlinkType;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
@@ -83,6 +84,9 @@ public abstract class BaseTestSheet {
assertSame(row1, it.next());
assertTrue(it.hasNext());
assertSame(row2, it.next());
+ Spliterator<Row> split = sheet.spliterator();
+ assertTrue(split.tryAdvance(row -> assertSame(row1, row)));
+ assertTrue(split.tryAdvance(row -> assertSame(row2, row)));
assertEquals(1, sheet.getLastRowNum());
// Test row creation with non consecutive index
@@ -102,6 +106,12 @@ public abstract class BaseTestSheet {
Row row2_ovrewritten_ref = it2.next();
assertSame(row2_ovrewritten, row2_ovrewritten_ref);
assertEquals(100.0, row2_ovrewritten_ref.getCell(0).getNumericCellValue(), 0.0);
+ Spliterator<Row> split2 = sheet.spliterator();
+ assertTrue(split2.tryAdvance(row -> assertSame(row1, row)));
+ assertTrue(split2.tryAdvance(row -> {
+ assertSame(row2_ovrewritten, row);
+ assertEquals(100.0, row.getCell(0).getNumericCellValue(), 0.0);
+ }));
}
}
diff --git a/poi/src/test/java/org/apache/poi/ss/usermodel/BaseTestWorkbook.java b/poi/src/test/java/org/apache/poi/ss/usermodel/BaseTestWorkbook.java
index d41a9a9aa3..1f600cf0f2 100644
--- a/poi/src/test/java/org/apache/poi/ss/usermodel/BaseTestWorkbook.java
+++ b/poi/src/test/java/org/apache/poi/ss/usermodel/BaseTestWorkbook.java
@@ -31,6 +31,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.IOException;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
+import java.util.Spliterator;
import org.apache.poi.hssf.HSSFTestDataSamples;
import org.apache.poi.ss.ITestDataProvider;
@@ -74,11 +75,15 @@ public abstract class BaseTestWorkbook {
wb.createSheet("Sheet2");
Iterator<Sheet> it = wb.sheetIterator();
+ Spliterator<Sheet> split = wb.spliterator();
it.next();
+ split.tryAdvance(sheet -> {});
wb.setSheetOrder("Sheet2", 1);
// Iterator order should be fixed when iterator is created
assertThrows(ConcurrentModificationException.class, it::next);
+ // Spliterator order should be fixed when spliterator is created
+ assertThrows(ConcurrentModificationException.class, () -> split.tryAdvance(sheet -> {}));
}
}
@@ -95,10 +100,15 @@ public abstract class BaseTestWorkbook {
wb.createSheet("Sheet2");
Iterator<Sheet> it = wb.sheetIterator();
+ Spliterator<Sheet> split = wb.spliterator();
+ it.next();
+ split.tryAdvance(sheet -> {});
wb.removeSheetAt(1);
// Iterator order should be fixed when iterator is created
assertThrows(ConcurrentModificationException.class, it::next);
+ // Spliterator order should be fixed when spliterator is created
+ assertThrows(ConcurrentModificationException.class, () -> split.tryAdvance(sheet -> {}));
}
}
diff --git a/poi/src/test/java/org/apache/poi/ss/util/TestCellRangeAddress.java b/poi/src/test/java/org/apache/poi/ss/util/TestCellRangeAddress.java
index 033fb5f179..4d729d6006 100644
--- a/poi/src/test/java/org/apache/poi/ss/util/TestCellRangeAddress.java
+++ b/poi/src/test/java/org/apache/poi/ss/util/TestCellRangeAddress.java
@@ -28,10 +28,13 @@ import static org.junit.jupiter.api.Assertions.fail;
import java.io.IOException;
import java.util.Iterator;
import java.util.NoSuchElementException;
+import java.util.Spliterator;
+import java.util.stream.StreamSupport;
import org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream;
import org.apache.poi.hssf.record.TestcaseRecordInputStream;
import org.apache.poi.util.LittleEndianOutputStream;
+import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
final class TestCellRangeAddress {
@@ -275,6 +278,29 @@ final class TestCellRangeAddress {
assertEquals(4, count);
}
+ @Test
+ void spliterator() {
+ final CellRangeAddress A1_B2 = new CellRangeAddress(0, 1, 0, 1);
+
+ // the cell address iterator iterates in row major order
+ final Spliterator<CellAddress> spliter = A1_B2.spliterator();
+ spliter.tryAdvance(addr ->
+ assertEquals(new CellAddress(0, 0), addr, "A1"));
+ spliter.tryAdvance(addr ->
+ assertEquals(new CellAddress(0, 1), addr, "B1"));
+ spliter.tryAdvance(addr ->
+ assertEquals(new CellAddress(1, 0), addr, "A2"));
+ spliter.tryAdvance(addr ->
+ assertEquals(new CellAddress(1, 1), addr, "B2"));
+ assertFalse(spliter.tryAdvance(addr -> fail()));
+
+ // stream
+ long count = StreamSupport.stream(A1_B2.spliterator(), false)
+ .peek(Assertions::assertNotNull)
+ .count();
+ assertEquals(4, count);
+ }
+
private static void assertIntersects(CellRangeAddress regionA, CellRangeAddress regionB) {
if (!(regionA.intersects(regionB) && regionB.intersects(regionA))) {
final String A = regionA.formatAsString();