Author: fanningpj
Date: Thu Oct 26 18:09:38 2023
New Revision: 1913359
URL: http://svn.apache.org/viewvc?rev=1913359&view=rev
Log:
[bug-67579] add new XSSFWorkbook constructor
Added:
poi/trunk/poi-ooxml/src/main/java/org/apache/poi/openxml4j/opc/internal/NoCloseInputStream.java
(with props)
Modified:
poi/trunk/poi-ooxml/src/main/java/org/apache/poi/ooxml/util/PackageHelper.java
poi/trunk/poi-ooxml/src/main/java/org/apache/poi/openxml4j/opc/OPCPackage.java
poi/trunk/poi-ooxml/src/main/java/org/apache/poi/openxml4j/opc/ZipPackage.java
poi/trunk/poi-ooxml/src/main/java/org/apache/poi/openxml4j/opc/internal/ZipHelper.java
poi/trunk/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java
poi/trunk/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFWorkbook.java
Modified:
poi/trunk/poi-ooxml/src/main/java/org/apache/poi/ooxml/util/PackageHelper.java
URL:
http://svn.apache.org/viewvc/poi/trunk/poi-ooxml/src/main/java/org/apache/poi/ooxml/util/PackageHelper.java?rev=1913359&r1=1913358&r2=1913359&view=diff
==============================================================================
---
poi/trunk/poi-ooxml/src/main/java/org/apache/poi/ooxml/util/PackageHelper.java
(original)
+++
poi/trunk/poi-ooxml/src/main/java/org/apache/poi/ooxml/util/PackageHelper.java
Thu Oct 26 18:09:38 2023
@@ -43,20 +43,25 @@ import org.apache.poi.util.Removal;
*/
public final class PackageHelper {
- public static OPCPackage open(InputStream is) throws IOException {
- return open(is, false);
+ /**
+ * @param stream The InputStream to read from - which is closed when it is
read
+ * @return OPCPackage
+ * @throws IOException If reading data from the stream fails
+ */
+ public static OPCPackage open(InputStream stream) throws IOException {
+ return open(stream, false);
}
/**
* @param stream The InputStream to read from
- * @param closeStream whether to close the stream (default is false)
- * @since POI 5.2.0
+ * @param closeStream whether to close the stream
* @return OPCPackage
* @throws IOException If reading data from the stream fails
+ * @since POI 5.2.0
*/
public static OPCPackage open(InputStream stream, boolean closeStream)
throws IOException {
try {
- return OPCPackage.open(stream);
+ return OPCPackage.open(stream, closeStream);
} catch (InvalidFormatException e){
throw new POIXMLException(e);
} finally {
Modified:
poi/trunk/poi-ooxml/src/main/java/org/apache/poi/openxml4j/opc/OPCPackage.java
URL:
http://svn.apache.org/viewvc/poi/trunk/poi-ooxml/src/main/java/org/apache/poi/openxml4j/opc/OPCPackage.java?rev=1913359&r1=1913358&r2=1913359&view=diff
==============================================================================
---
poi/trunk/poi-ooxml/src/main/java/org/apache/poi/openxml4j/opc/OPCPackage.java
(original)
+++
poi/trunk/poi-ooxml/src/main/java/org/apache/poi/openxml4j/opc/OPCPackage.java
Thu Oct 26 18:09:38 2023
@@ -329,6 +329,38 @@ public abstract class OPCPackage impleme
}
/**
+ * Open a package.
+ *
+ * Note - uses quite a bit more memory than {@link #open(String)}, which
+ * doesn't need to hold the whole zip file in memory, and can take
advantage
+ * of native methods
+ *
+ * @param in
+ * The InputStream to read the package from.
+ * @param closeStream
+ * Whether to close the input stream.
+ * @return A PackageBase object
+ *
+ * @throws InvalidFormatException
+ * Throws if the specified file exist and is not valid.
+ * @throws IOException If reading the stream fails
+ * @since POI 5.2.5
+ */
+ public static OPCPackage open(InputStream in, boolean closeStream) throws
InvalidFormatException,
+ IOException {
+ OPCPackage pack = new ZipPackage(in, PackageAccess.READ_WRITE,
closeStream);
+ try {
+ if (pack.partList == null) {
+ pack.getParts();
+ }
+ } catch (InvalidFormatException | RuntimeException e) {
+ IOUtils.closeQuietly(pack);
+ throw e;
+ }
+ return pack;
+ }
+
+ /**
* Opens a package if it exists, else it creates one.
*
* @param file
Modified:
poi/trunk/poi-ooxml/src/main/java/org/apache/poi/openxml4j/opc/ZipPackage.java
URL:
http://svn.apache.org/viewvc/poi/trunk/poi-ooxml/src/main/java/org/apache/poi/openxml4j/opc/ZipPackage.java?rev=1913359&r1=1913358&r2=1913359&view=diff
==============================================================================
---
poi/trunk/poi-ooxml/src/main/java/org/apache/poi/openxml4j/opc/ZipPackage.java
(original)
+++
poi/trunk/poi-ooxml/src/main/java/org/apache/poi/openxml4j/opc/ZipPackage.java
Thu Oct 26 18:09:38 2023
@@ -115,7 +115,7 @@ public final class ZipPackage extends OP
/**
* Constructor. Opens a Zip based Open XML document from
- * an InputStream.
+ * an InputStream. The InputStream is closed.
*
* @param in
* Zip input stream to load.
@@ -133,6 +133,30 @@ public final class ZipPackage extends OP
this.zipArchive = new ZipInputStreamZipEntrySource(zis);
}
}
+
+ /**
+ * Constructor. Opens a Zip based Open XML document from
+ * an InputStream. The InputStream is closed.
+ *
+ * @param in
+ * Zip input stream to load.
+ * @param access
+ * The package access mode.
+ * @param closeStream
+ * Whether to close the input stream.
+ * @throws IllegalArgumentException
+ * If the specified input stream is not an instance of
+ * ZipInputStream.
+ * @throws IOException
+ * if input stream cannot be opened, read, or closed
+ * @since POI 5.2.5
+ */
+ ZipPackage(InputStream in, PackageAccess access, boolean closeStream)
throws IOException {
+ super(access);
+ try (ZipArchiveThresholdInputStream zis = ZipHelper.openZipStream(in,
closeStream)) {
+ this.zipArchive = new ZipInputStreamZipEntrySource(zis);
+ }
+ }
/**
* Constructor. Opens a Zip based Open XML document from a file.
Added:
poi/trunk/poi-ooxml/src/main/java/org/apache/poi/openxml4j/opc/internal/NoCloseInputStream.java
URL:
http://svn.apache.org/viewvc/poi/trunk/poi-ooxml/src/main/java/org/apache/poi/openxml4j/opc/internal/NoCloseInputStream.java?rev=1913359&view=auto
==============================================================================
---
poi/trunk/poi-ooxml/src/main/java/org/apache/poi/openxml4j/opc/internal/NoCloseInputStream.java
(added)
+++
poi/trunk/poi-ooxml/src/main/java/org/apache/poi/openxml4j/opc/internal/NoCloseInputStream.java
Thu Oct 26 18:09:38 2023
@@ -0,0 +1,33 @@
+/* ====================================================================
+ 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.openxml4j.opc.internal;
+
+import org.apache.poi.util.Internal;
+
+import java.io.FilterInputStream;
+import java.io.InputStream;
+
+@Internal
+final class NoCloseInputStream extends FilterInputStream {
+ NoCloseInputStream(InputStream stream) {
+ super(stream);
+ }
+
+ @Override
+ public void close() {}
+}
Propchange:
poi/trunk/poi-ooxml/src/main/java/org/apache/poi/openxml4j/opc/internal/NoCloseInputStream.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified:
poi/trunk/poi-ooxml/src/main/java/org/apache/poi/openxml4j/opc/internal/ZipHelper.java
URL:
http://svn.apache.org/viewvc/poi/trunk/poi-ooxml/src/main/java/org/apache/poi/openxml4j/opc/internal/ZipHelper.java?rev=1913359&r1=1913358&r2=1913359&view=diff
==============================================================================
---
poi/trunk/poi-ooxml/src/main/java/org/apache/poi/openxml4j/opc/internal/ZipHelper.java
(original)
+++
poi/trunk/poi-ooxml/src/main/java/org/apache/poi/openxml4j/opc/internal/ZipHelper.java
Thu Oct 26 18:09:38 2023
@@ -163,20 +163,33 @@ public final class ZipHelper {
}
/**
- * Opens the specified stream as a secure zip
+ * Opens the specified stream as a secure zip. Closes the Input Stream.
*
- * @param stream
- * The stream to open.
+ * @param stream The stream to open.
* @return The zip stream freshly open.
*/
@SuppressWarnings("resource")
public static ZipArchiveThresholdInputStream openZipStream(InputStream
stream) throws IOException {
+ return openZipStream(stream, true);
+ }
+
+ /**
+ * Opens the specified stream as a secure zip. Closes the Input Stream.
+ *
+ * @param stream The stream to open.
+ * @param closeStream whether to close the stream
+ * @return The zip stream freshly open.
+ */
+ @SuppressWarnings("resource")
+ public static ZipArchiveThresholdInputStream openZipStream(
+ final InputStream stream, final boolean closeStream) throws
IOException {
// Peek at the first few bytes to sanity check
InputStream checkedStream = FileMagic.prepareToCheckMagic(stream);
verifyZipHeader(checkedStream);
-
+
+ final InputStream processStream = closeStream ? checkedStream : new
NoCloseInputStream(checkedStream);
// Open as a proper zip stream
- return new ZipArchiveThresholdInputStream(new
ZipArchiveInputStream(checkedStream));
+ return new ZipArchiveThresholdInputStream(new
ZipArchiveInputStream(processStream));
}
/**
Modified:
poi/trunk/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java
URL:
http://svn.apache.org/viewvc/poi/trunk/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java?rev=1913359&r1=1913358&r2=1913359&view=diff
==============================================================================
---
poi/trunk/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java
(original)
+++
poi/trunk/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java
Thu Oct 26 18:09:38 2023
@@ -277,17 +277,40 @@ public class XSSFWorkbook extends POIXML
* pkg.close(); // gracefully closes the underlying zip file
* }</pre>
*
+ * @param stream The InputStream, which is closed when it is read.
* @throws IOException If reading data from the stream fails
* @throws POIXMLException a RuntimeException that can be caused by
invalid OOXML data
* @throws IllegalStateException a number of other runtime exceptions can
be thrown, especially if there are problems with the
* input format
*/
- public XSSFWorkbook(InputStream is) throws IOException {
- this(is, false);
+ public XSSFWorkbook(InputStream stream) throws IOException {
+ this(stream, true);
}
- private XSSFWorkbook(InputStream is, boolean closeStream) throws
IOException {
- this(PackageHelper.open(is, closeStream));
+ /**
+ * Constructs a XSSFWorkbook object, by buffering the whole stream into
memory
+ * and then opening an {@link OPCPackage} object for it.
+ *
+ * <p>Using an {@link InputStream} requires more memory than using a File,
so
+ * if a {@link File} is available then you should instead do something
like
+ * <pre>{@code
+ * OPCPackage pkg = OPCPackage.open(path);
+ * XSSFWorkbook wb = new XSSFWorkbook(pkg);
+ * // work with the wb object
+ * ......
+ * pkg.close(); // gracefully closes the underlying zip file
+ * }</pre>
+ *
+ * @param stream The InputStream.
+ * @param closeStream Whether to close the stream.
+ * @throws IOException If reading data from the stream fails
+ * @throws POIXMLException a RuntimeException that can be caused by
invalid OOXML data
+ * @throws IllegalStateException a number of other runtime exceptions can
be thrown, especially if there are problems with the
+ * input format
+ * @since POI 5.2.5
+ */
+ public XSSFWorkbook(InputStream stream, boolean closeStream) throws
IOException {
+ this(PackageHelper.open(stream, closeStream));
}
/**
Modified:
poi/trunk/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFWorkbook.java
URL:
http://svn.apache.org/viewvc/poi/trunk/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFWorkbook.java?rev=1913359&r1=1913358&r2=1913359&view=diff
==============================================================================
---
poi/trunk/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFWorkbook.java
(original)
+++
poi/trunk/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFWorkbook.java
Thu Oct 26 18:09:38 2023
@@ -1460,13 +1460,17 @@ public final class TestXSSFWorkbook exte
}
}
- static class NoCloseInputStream extends FilterInputStream {
- NoCloseInputStream(InputStream stream) {
- super(stream);
+ @Test
+ void testWorkbookCloseCanBeStoppedFromClosingInputStream() throws
Exception {
+ try (WrappedStream stream = new WrappedStream(
+ HSSFTestDataSamples.openSampleFileStream("github-321.xlsx"))) {
+ // uses new constructor, available since POI 5.2.5
+ try (XSSFWorkbook wb = new XSSFWorkbook(stream, false)) {
+ XSSFSheet xssfSheet = wb.getSheetAt(0);
+ assertNotNull(xssfSheet);
+ }
+ assertFalse(stream.isClosed(), "stream should not be closed by
XSSFWorkbook");
}
-
- @Override
- public void close() {}
}
@Test
@@ -1494,9 +1498,8 @@ public final class TestXSSFWorkbook exte
try (ZipArchiveInputStream zis = new
ZipArchiveInputStream(Files.newInputStream(tempFile.toPath()))) {
ZipArchiveEntry entry;
while ((entry = zis.getNextZipEntry()) != null) {
- // NoCloseInputStream is needed to stop XSSFWorkbook
closing the underlying InputStream
- // this might not sound great but POI has worked like this
for years and we can't just change it
- XSSFWorkbook wb = new XSSFWorkbook(new
NoCloseInputStream(zis));
+ // Since POI 5.2.5, you can stop XSSFWorkbook closing the
InputStream by using this new constructor
+ XSSFWorkbook wb = new XSSFWorkbook(zis, false);
assertNotNull(wb);
count++;
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]