aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/java/org/apache/poi/sl/usermodel/SlideShowFactory.java237
-rw-r--r--src/java/org/apache/poi/sl/usermodel/SlideShowProvider.java42
-rw-r--r--src/java/org/apache/poi/ss/usermodel/WorkbookFactory.java2
-rw-r--r--src/multimodule/ooxml/java9/module-info.classbin2715 -> 2828 bytes
-rw-r--r--src/multimodule/ooxml/java9/module-info.java5
-rw-r--r--src/multimodule/ooxml/test9/module-info.classbin3584 -> 3697 bytes
-rw-r--r--src/multimodule/ooxml/test9/module-info.java3
-rw-r--r--src/multimodule/poi/java9/module-info.classbin3169 -> 3222 bytes
-rw-r--r--src/multimodule/poi/java9/module-info.java3
-rw-r--r--src/multimodule/poi/test9/module-info.classbin3296 -> 3349 bytes
-rw-r--r--src/multimodule/poi/test9/module-info.java3
-rw-r--r--src/multimodule/scratchpad/java9/module-info.classbin2219 -> 2332 bytes
-rw-r--r--src/multimodule/scratchpad/java9/module-info.java1
-rw-r--r--src/multimodule/scratchpad/test9/module-info.classbin2393 -> 2506 bytes
-rw-r--r--src/multimodule/scratchpad/test9/module-info.java1
-rw-r--r--src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideShowFactory.java118
-rw-r--r--src/resources/ooxml/META-INF/services/org.apache.poi.sl.usermodel.SlideShowProvider18
-rw-r--r--src/resources/scratchpad/META-INF/services/org.apache.poi.sl.usermodel.SlideShowProvider18
-rw-r--r--src/scratchpad/src/org/apache/poi/extractor/ole2/OLE2ScratchpadExtractorFactory.java4
-rw-r--r--src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShowFactory.java64
-rw-r--r--src/testcases/org/apache/poi/sl/usermodel/BaseTestSlideShow.java3
-rw-r--r--src/testcases/org/apache/poi/sl/usermodel/BaseTestSlideShowFactory.java8
22 files changed, 331 insertions, 199 deletions
diff --git a/src/java/org/apache/poi/sl/usermodel/SlideShowFactory.java b/src/java/org/apache/poi/sl/usermodel/SlideShowFactory.java
index 84d98e70ac..1424a70608 100644
--- a/src/java/org/apache/poi/sl/usermodel/SlideShowFactory.java
+++ b/src/java/org/apache/poi/sl/usermodel/SlideShowFactory.java
@@ -16,46 +16,59 @@
==================================================================== */
package org.apache.poi.sl.usermodel;
+import static org.apache.poi.poifs.crypt.EncryptionInfo.ENCRYPTION_INFO_ENTRY;
+
+import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.ServiceLoader;
+import org.apache.poi.EmptyFileException;
import org.apache.poi.EncryptedDocumentException;
-import org.apache.poi.hssf.record.crypto.Biff8EncryptionKey;
import org.apache.poi.poifs.crypt.Decryptor;
import org.apache.poi.poifs.filesystem.DirectoryNode;
-import org.apache.poi.poifs.filesystem.DocumentFactoryHelper;
import org.apache.poi.poifs.filesystem.FileMagic;
-import org.apache.poi.poifs.filesystem.OfficeXmlFileException;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
-import org.apache.poi.util.IOUtils;
-@SuppressWarnings("unchecked")
-public abstract class SlideShowFactory {
+public final class SlideShowFactory {
- protected interface CreateSlideShow1<T> {
- SlideShow<?, ?> apply(T t) throws IOException;
+ private static class Singleton {
+ private static final SlideShowFactory INSTANCE = new SlideShowFactory();
}
- protected interface CreateSlideShow2<T, U> {
- SlideShow<?, ?> apply(T t, U u) throws IOException;
+ private interface ProviderMethod {
+ SlideShow<?,?> create(SlideShowProvider<?,?> prov) throws IOException;
}
- // XMLSlideShow createSlideShow(InputStream stream)
- protected static CreateSlideShow1<InputStream> createXslfByStream;
-
- // XMLSlideShow createSlideShow(File file, boolean readOnly)
- protected static CreateSlideShow2<File, Boolean> createXslfByFile;
+ private final List<SlideShowProvider<?,?>> provider = new ArrayList<>();
- // HSLFSlideShow createSlideShow(final POIFSFileSystem fs)
- protected static CreateSlideShow1<POIFSFileSystem> createHslfByPoifs;
+ private SlideShowFactory() {
+ ServiceLoader.load(SlideShowProvider.class).forEach(provider::add);
+ }
- // HSLFSlideShow createSlideShow(final DirectoryNode root)
- protected static CreateSlideShow1<DirectoryNode> createHslfByNode;
+ /**
+ * Create a new empty SlideShow, either XSLF or HSLF depending
+ * on the parameter
+ *
+ * @param XSLF If an XSLFSlideShow or a HSLFSlideShow should be created
+ *
+ * @return The created SlideShow
+ *
+ * @throws IOException if an error occurs while creating the objects
+ */
+ public static SlideShow<?,?> create(boolean XSLF) throws IOException {
+ return wp(XSLF ? FileMagic.OOXML : FileMagic.OLE2, SlideShowProvider::create);
+ }
/**
- * Creates a SlideShow from the given POIFSFileSystem.
+ * Creates a HSLFSlideShow from the given POIFSFileSystem<p>
+ *
+ * Note that in order to properly release resources the
+ * SlideShow should be closed after use.
*
* @param fs The {@link POIFSFileSystem} to read the document from
*
@@ -63,31 +76,26 @@ public abstract class SlideShowFactory {
*
* @throws IOException if an error occurs while reading the data
*/
- public static <
- S extends Shape<S,P>,
- P extends TextParagraph<S,P,? extends TextRun>
- > SlideShow<S,P> create(POIFSFileSystem fs) throws IOException {
+ public static SlideShow<?,?> create(POIFSFileSystem fs) throws IOException {
return create(fs, null);
}
/**
* Creates a SlideShow from the given POIFSFileSystem, which may
- * be password protected
+ * be password protected
*
- * @param fs The {@link POIFSFileSystem} to read the document from
- * @param password The password that should be used or null if no password is necessary.
+ * @param fs The {@link POIFSFileSystem} to read the document from
+ * @param password The password that should be used or null if no password is necessary.
*
- * @return The created SlideShow
+ * @return The created SlideShow
*
- * @throws IOException if an error occurs while reading the data
+ * @throws IOException if an error occurs while reading the data
*/
- public static <
- S extends Shape<S,P>,
- P extends TextParagraph<S,P,? extends TextRun>
- > SlideShow<S,P> create(final POIFSFileSystem fs, String password) throws IOException {
+ private static SlideShow<?,?> create(final POIFSFileSystem fs, String password) throws IOException {
return create(fs.getRoot(), password);
}
+
/**
* Creates a SlideShow from the given DirectoryNode.
*
@@ -97,10 +105,7 @@ public abstract class SlideShowFactory {
*
* @throws IOException if an error occurs while reading the data
*/
- public static <
- S extends Shape<S,P>,
- P extends TextParagraph<S,P,? extends TextRun>
- > SlideShow<S,P> create(final DirectoryNode root) throws IOException {
+ public static SlideShow<?,?> create(final DirectoryNode root) throws IOException {
return create(root, null);
}
@@ -116,48 +121,22 @@ public abstract class SlideShowFactory {
*
* @throws IOException if an error occurs while reading the data
*/
- public static <
- S extends Shape<S,P>,
- P extends TextParagraph<S,P,? extends TextRun>
- > SlideShow<S,P> create(final DirectoryNode root, String password) throws IOException {
+ public static SlideShow<?,?> create(final DirectoryNode root, String password) throws IOException {
// Encrypted OOXML files go inside OLE2 containers, is this one?
if (root.hasEntry(Decryptor.DEFAULT_POIFS_ENTRY)) {
- InputStream stream = null;
- try {
- stream = DocumentFactoryHelper.getDecryptedStream(root, password);
- initXslf();
- return (SlideShow<S, P>) createXslfByStream.apply(stream);
- } finally {
- IOUtils.closeQuietly(stream);
-
- // as we processed the full stream already, we can close the filesystem here
- // otherwise file handles are leaked
- root.getFileSystem().close();
- }
- }
-
- // If we get here, it isn't an encrypted PPTX file
- // So, treat it as a regular HSLF PPT one
- boolean passwordSet = false;
- if (password != null) {
- Biff8EncryptionKey.setCurrentUserPassword(password);
- passwordSet = true;
- }
- try {
- initHslf();
- return (SlideShow<S, P>) createHslfByNode.apply(root);
- } finally {
- if (passwordSet) {
- Biff8EncryptionKey.setCurrentUserPassword(null);
- }
+ return wp(FileMagic.OOXML, w -> w.create(root, password));
+ } else {
+ return wp(FileMagic.OLE2, w -> w.create(root, password));
}
}
/**
- * Creates the appropriate HSLFSlideShow / XMLSlideShow from
+ * Creates the appropriate HSLFSlideShow / XSLFSlideShow from
* the given InputStream.
*
- * <p>Note that using an {@link InputStream} has a higher memory footprint
+ * <p>Your input stream MUST either support mark/reset, or
+ * be wrapped as a {@link BufferedInputStream}!
+ * Note that using an {@link InputStream} has a higher memory footprint
* than using a {@link File}.</p>
*
* <p>Note that in order to properly release resources the
@@ -170,20 +149,19 @@ public abstract class SlideShowFactory {
* @return The created SlideShow
*
* @throws IOException if an error occurs while reading the data
- * @throws EncryptedDocumentException If the SlideShow given is password protected
+ * @throws EncryptedDocumentException If the SlideShow<?,?> given is password protected
*/
- public static <
- S extends Shape<S,P>,
- P extends TextParagraph<S,P,? extends TextRun>
- > SlideShow<S,P> create(InputStream inp) throws IOException, EncryptedDocumentException {
+ public static SlideShow<?,?> create(InputStream inp) throws IOException, EncryptedDocumentException {
return create(inp, null);
}
/**
- * Creates the appropriate HSLFSlideShow / XMLSlideShow from
+ * Creates the appropriate HSLFSlideShow / XSLFSlideShow from
* the given InputStream, which may be password protected.
*
- * <p>Note that using an {@link InputStream} has a higher memory footprint
+ * <p>Your input stream MUST either support mark/reset, or
+ * be wrapped as a {@link BufferedInputStream}!
+ * Note that using an {@link InputStream} has a higher memory footprint
* than using a {@link File}.</p>
*
* <p>Note that in order to properly release resources the
@@ -199,27 +177,32 @@ public abstract class SlideShowFactory {
* @throws IOException if an error occurs while reading the data
* @throws EncryptedDocumentException If the wrong password is given for a protected file
*/
- public static <
- S extends Shape<S,P>,
- P extends TextParagraph<S,P,? extends TextRun>
- > SlideShow<S,P> create(InputStream inp, String password) throws IOException, EncryptedDocumentException {
+ public static SlideShow<?,?> create(InputStream inp, String password) throws IOException, EncryptedDocumentException {
InputStream is = FileMagic.prepareToCheckMagic(inp);
- FileMagic fm = FileMagic.valueOf(is);
-
- switch (fm) {
- case OLE2:
- POIFSFileSystem fs = new POIFSFileSystem(is);
- return create(fs, password);
- case OOXML:
- initXslf();
- return (SlideShow<S, P>) createXslfByStream.apply(is);
- default:
- throw new IOException("Your InputStream was neither an OLE2 stream, nor an OOXML stream");
+ byte[] emptyFileCheck = new byte[1];
+ is.mark(emptyFileCheck.length);
+ if (is.read(emptyFileCheck) < emptyFileCheck.length) {
+ throw new EmptyFileException();
+ }
+ is.reset();
+
+ final FileMagic fm = FileMagic.valueOf(is);
+ if (FileMagic.OOXML == fm) {
+ return wp(fm, w -> w.create(is));
+ }
+
+ if (FileMagic.OLE2 != fm) {
+ throw new IOException("Can't open SlideShow - unsupported file type: "+fm);
}
+
+ POIFSFileSystem poifs = new POIFSFileSystem(is);
+ boolean isOOXML = poifs.getRoot().hasEntry(ENCRYPTION_INFO_ENTRY);
+
+ return wp(isOOXML ? FileMagic.OOXML : fm, w -> w.create(poifs.getRoot(), password));
}
/**
- * Creates the appropriate HSLFSlideShow / XMLSlideShow from
+ * Creates the appropriate HSLFSlideShow / XSLFSlideShow from
* the given File, which must exist and be readable.
* <p>Note that in order to properly release resources the
* SlideShow should be closed after use.
@@ -231,15 +214,12 @@ public abstract class SlideShowFactory {
* @throws IOException if an error occurs while reading the data
* @throws EncryptedDocumentException If the SlideShow given is password protected
*/
- public static <
- S extends Shape<S,P>,
- P extends TextParagraph<S,P,? extends TextRun>
- > SlideShow<S,P> create(File file) throws IOException, EncryptedDocumentException {
+ public static SlideShow<?,?> create(File file) throws IOException, EncryptedDocumentException {
return create(file, null);
}
/**
- * Creates the appropriate HSLFSlideShow / XMLSlideShow from
+ * Creates the appropriate HSLFSlideShow / XSLFSlideShow from
* the given File, which must exist and be readable, and
* may be password protected
* <p>Note that in order to properly release resources the
@@ -253,15 +233,12 @@ public abstract class SlideShowFactory {
* @throws IOException if an error occurs while reading the data
* @throws EncryptedDocumentException If the wrong password is given for a protected file
*/
- public static <
- S extends Shape<S,P>,
- P extends TextParagraph<S,P,? extends TextRun>
- > SlideShow<S,P> create(File file, String password) throws IOException, EncryptedDocumentException {
+ public static SlideShow<?,?> create(File file, String password) throws IOException, EncryptedDocumentException {
return create(file, password, false);
}
/**
- * Creates the appropriate HSLFSlideShow / XMLSlideShow from
+ * Creates the appropriate HSLFSlideShow / XSLFSlideShow from
* the given File, which must exist and be readable, and
* may be password protected
* <p>Note that in order to properly release resources the
@@ -277,45 +254,39 @@ public abstract class SlideShowFactory {
* @throws IOException if an error occurs while reading the data
* @throws EncryptedDocumentException If the wrong password is given for a protected file
*/
- public static <
- S extends Shape<S,P>,
- P extends TextParagraph<S,P,? extends TextRun>
- > SlideShow<S,P> create(File file, String password, boolean readOnly) throws IOException, EncryptedDocumentException {
+ public static SlideShow<?,?> create(File file, String password, boolean readOnly) throws IOException, EncryptedDocumentException {
if (!file.exists()) {
throw new FileNotFoundException(file.toString());
}
- POIFSFileSystem fs = null;
- try {
- fs = new POIFSFileSystem(file, readOnly);
- return create(fs, password);
- } catch(OfficeXmlFileException e) {
- IOUtils.closeQuietly(fs);
- initXslf();
- return (SlideShow<S, P>) createXslfByFile.apply(file, readOnly);
- } catch(RuntimeException e) {
- IOUtils.closeQuietly(fs);
- throw e;
+ if (file.length() == 0) {
+ throw new EmptyFileException();
}
- }
- private static void initXslf() throws IOException {
- if (createXslfByFile == null) {
- initFactory("org.apache.poi.xslf.usermodel.XSLFSlideShowFactory", "poi-ooxml-*.jar");
+ FileMagic fm = FileMagic.valueOf(file);
+ if (fm == FileMagic.OOXML) {
+ return wp(fm, w -> w.create(file, password, readOnly));
+ } else if (fm == FileMagic.OLE2) {
+ final boolean ooxmlEnc;
+ try (POIFSFileSystem fs = new POIFSFileSystem(file, true)) {
+ ooxmlEnc = fs.getRoot().hasEntry(Decryptor.DEFAULT_POIFS_ENTRY);
+ }
+ return wp(ooxmlEnc ? FileMagic.OOXML : fm, w -> w.create(file, password, readOnly));
}
- }
- private static void initHslf() throws IOException {
- if (createHslfByPoifs == null) {
- initFactory("org.apache.poi.hslf.usermodel.HSLFSlideShowFactory", "poi-scratchpad-*.jar");
- }
+ return null;
}
- private static void initFactory(String factoryClass, String jar) throws IOException {
- try {
- Class.forName(factoryClass, true, SlideShowFactory.class.getClassLoader());
- } catch (ClassNotFoundException e) {
- throw new IOException(factoryClass+" not found - check if " + jar + " is on the classpath.");
+
+
+ private static SlideShow<?,?> wp(FileMagic fm, SlideShowFactory.ProviderMethod fun) throws IOException {
+
+ for (SlideShowProvider<?,?> prov : SlideShowFactory.Singleton.INSTANCE.provider) {
+ if (prov.accepts(fm)) {
+ return fun.create(prov);
+ }
}
+ throw new IOException("Your InputStream was neither an OLE2 stream, nor an OOXML stream " +
+ "or you haven't provide the poi-ooxml*.jar in the classpath/modulepath - FileMagic: "+fm);
}
}
diff --git a/src/java/org/apache/poi/sl/usermodel/SlideShowProvider.java b/src/java/org/apache/poi/sl/usermodel/SlideShowProvider.java
new file mode 100644
index 0000000000..3dbde3cde5
--- /dev/null
+++ b/src/java/org/apache/poi/sl/usermodel/SlideShowProvider.java
@@ -0,0 +1,42 @@
+/* ====================================================================
+ 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.sl.usermodel;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.poi.poifs.filesystem.DirectoryNode;
+import org.apache.poi.poifs.filesystem.FileMagic;
+
+public interface SlideShowProvider<
+ S extends Shape<S,P>,
+ P extends TextParagraph<S,P,? extends TextRun>
+> {
+ boolean accepts(FileMagic fm);
+
+ SlideShow<S,P> create();
+
+ SlideShow<S,P> create(InputStream inp) throws IOException;
+
+ SlideShow<S,P> create(InputStream inp, String password) throws IOException;
+
+ SlideShow<S,P> create(DirectoryNode root, String password) throws IOException;
+
+ SlideShow<S,P> create(File file, String password, boolean readOnly) throws IOException;
+}
diff --git a/src/java/org/apache/poi/ss/usermodel/WorkbookFactory.java b/src/java/org/apache/poi/ss/usermodel/WorkbookFactory.java
index 25f5cde753..d9504fe63a 100644
--- a/src/java/org/apache/poi/ss/usermodel/WorkbookFactory.java
+++ b/src/java/org/apache/poi/ss/usermodel/WorkbookFactory.java
@@ -274,7 +274,7 @@ public final class WorkbookFactory {
if (fm == FileMagic.OOXML) {
return wp(fm, w -> w.create(file, password, readOnly));
} else if (fm == FileMagic.OLE2) {
- boolean ooxmlEnc = false;
+ final boolean ooxmlEnc;
try (POIFSFileSystem fs = new POIFSFileSystem(file, true)) {
ooxmlEnc = fs.getRoot().hasEntry(Decryptor.DEFAULT_POIFS_ENTRY);
}
diff --git a/src/multimodule/ooxml/java9/module-info.class b/src/multimodule/ooxml/java9/module-info.class
index 0895d4b496..517b8bbe2c 100644
--- a/src/multimodule/ooxml/java9/module-info.class
+++ b/src/multimodule/ooxml/java9/module-info.class
Binary files differ
diff --git a/src/multimodule/ooxml/java9/module-info.java b/src/multimodule/ooxml/java9/module-info.java
index 876e6a3b1d..66928ffa24 100644
--- a/src/multimodule/ooxml/java9/module-info.java
+++ b/src/multimodule/ooxml/java9/module-info.java
@@ -28,8 +28,9 @@ module org.apache.poi.ooxml {
requires java.desktop;
requires java.security.jgss;
- provides org.apache.poi.ss.usermodel.WorkbookProvider with org.apache.poi.xssf.usermodel.XSSFWorkbookFactory;
provides org.apache.poi.extractor.ExtractorProvider with org.apache.poi.ooxml.extractor.POIXMLExtractorFactory;
+ provides org.apache.poi.ss.usermodel.WorkbookProvider with org.apache.poi.xssf.usermodel.XSSFWorkbookFactory;
+ provides org.apache.poi.sl.usermodel.SlideShowProvider with org.apache.poi.xslf.usermodel.XSLFSlideShowFactory;
exports org.apache.poi.xwpf.extractor;
exports org.apache.poi.xwpf.usermodel;
@@ -79,7 +80,7 @@ module org.apache.poi.ooxml {
opens org.apache.poi.openxml4j.opc to org.apache.poi.poi;
- /* optional dependencies for xml signatures - you need to add a require entry your module-info
+ /* optional dependencies for xml signatures - you need to add a require entry to your module-info
* or add them via the --add-modules JVM argument */
requires java.xml.crypto;
requires static org.apache.santuario.xmlsec;
diff --git a/src/multimodule/ooxml/test9/module-info.class b/src/multimodule/ooxml/test9/module-info.class
index 7777b5f681..be87166834 100644
--- a/src/multimodule/ooxml/test9/module-info.class
+++ b/src/multimodule/ooxml/test9/module-info.class
Binary files differ
diff --git a/src/multimodule/ooxml/test9/module-info.java b/src/multimodule/ooxml/test9/module-info.java
index bd8a23a725..b41ae2b9b6 100644
--- a/src/multimodule/ooxml/test9/module-info.java
+++ b/src/multimodule/ooxml/test9/module-info.java
@@ -28,8 +28,9 @@ module org.apache.poi.ooxml {
requires java.desktop;
requires java.security.jgss;
- provides org.apache.poi.ss.usermodel.WorkbookProvider with org.apache.poi.xssf.usermodel.XSSFWorkbookFactory;
provides org.apache.poi.extractor.ExtractorProvider with org.apache.poi.ooxml.extractor.POIXMLExtractorFactory;
+ provides org.apache.poi.ss.usermodel.WorkbookProvider with org.apache.poi.xssf.usermodel.XSSFWorkbookFactory;
+ provides org.apache.poi.sl.usermodel.SlideShowProvider with org.apache.poi.xslf.usermodel.XSLFSlideShowFactory;
exports org.apache.poi.xwpf.extractor;
exports org.apache.poi.xwpf.usermodel;
diff --git a/src/multimodule/poi/java9/module-info.class b/src/multimodule/poi/java9/module-info.class
index ba2f2330ed..ab0e08c358 100644
--- a/src/multimodule/poi/java9/module-info.class
+++ b/src/multimodule/poi/java9/module-info.class
Binary files differ
diff --git a/src/multimodule/poi/java9/module-info.java b/src/multimodule/poi/java9/module-info.java
index 2995a21864..ea3f394035 100644
--- a/src/multimodule/poi/java9/module-info.java
+++ b/src/multimodule/poi/java9/module-info.java
@@ -27,8 +27,9 @@ module org.apache.poi.poi {
/* needed for CleanerUtil */
requires jdk.unsupported;
- uses org.apache.poi.ss.usermodel.WorkbookProvider;
uses org.apache.poi.extractor.ExtractorProvider;
+ uses org.apache.poi.ss.usermodel.WorkbookProvider;
+ uses org.apache.poi.sl.usermodel.SlideShowProvider;
provides org.apache.poi.ss.usermodel.WorkbookProvider with org.apache.poi.hssf.usermodel.HSSFWorkbookFactory;
diff --git a/src/multimodule/poi/test9/module-info.class b/src/multimodule/poi/test9/module-info.class
index 9010295aa0..2b43c43fa8 100644
--- a/src/multimodule/poi/test9/module-info.class
+++ b/src/multimodule/poi/test9/module-info.class
Binary files differ
diff --git a/src/multimodule/poi/test9/module-info.java b/src/multimodule/poi/test9/module-info.java
index add8071309..9e5bc0a110 100644
--- a/src/multimodule/poi/test9/module-info.java
+++ b/src/multimodule/poi/test9/module-info.java
@@ -27,8 +27,9 @@ module org.apache.poi.poi {
/* needed for CleanerUtil */
requires jdk.unsupported;
- uses org.apache.poi.ss.usermodel.WorkbookProvider;
uses org.apache.poi.extractor.ExtractorProvider;
+ uses org.apache.poi.ss.usermodel.WorkbookProvider;
+ uses org.apache.poi.sl.usermodel.SlideShowProvider;
provides org.apache.poi.ss.usermodel.WorkbookProvider with org.apache.poi.hssf.usermodel.HSSFWorkbookFactory;
provides org.apache.poi.extractor.ExtractorProvider with org.apache.poi.extractor.MainExtractorFactory;
diff --git a/src/multimodule/scratchpad/java9/module-info.class b/src/multimodule/scratchpad/java9/module-info.class
index 5e04b3dec9..8697888d28 100644
--- a/src/multimodule/scratchpad/java9/module-info.class
+++ b/src/multimodule/scratchpad/java9/module-info.class
Binary files differ
diff --git a/src/multimodule/scratchpad/java9/module-info.java b/src/multimodule/scratchpad/java9/module-info.java
index 717730fdd4..b936858c70 100644
--- a/src/multimodule/scratchpad/java9/module-info.java
+++ b/src/multimodule/scratchpad/java9/module-info.java
@@ -21,6 +21,7 @@ module org.apache.poi.scratchpad {
requires commons.math3;
provides org.apache.poi.extractor.ExtractorProvider with org.apache.poi.extractor.ole2.OLE2ScratchpadExtractorFactory;
+ provides org.apache.poi.sl.usermodel.SlideShowProvider with org.apache.poi.hslf.usermodel.HSLFSlideShowFactory;
exports org.apache.poi.hmef;
exports org.apache.poi.hmef.dev;
diff --git a/src/multimodule/scratchpad/test9/module-info.class b/src/multimodule/scratchpad/test9/module-info.class
index 489d1d1ab9..4ee1e56a65 100644
--- a/src/multimodule/scratchpad/test9/module-info.class
+++ b/src/multimodule/scratchpad/test9/module-info.class
Binary files differ
diff --git a/src/multimodule/scratchpad/test9/module-info.java b/src/multimodule/scratchpad/test9/module-info.java
index db69fd4e8f..cb0691b9a1 100644
--- a/src/multimodule/scratchpad/test9/module-info.java
+++ b/src/multimodule/scratchpad/test9/module-info.java
@@ -21,6 +21,7 @@ module org.apache.poi.scratchpad {
requires commons.math3;
provides org.apache.poi.extractor.ExtractorProvider with org.apache.poi.extractor.ole2.OLE2ScratchpadExtractorFactory;
+ provides org.apache.poi.sl.usermodel.SlideShowProvider with org.apache.poi.hslf.usermodel.HSLFSlideShowFactory;
exports org.apache.poi.hmef;
exports org.apache.poi.hmef.dev;
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideShowFactory.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideShowFactory.java
index 548cdc7a08..929b000bbb 100644
--- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideShowFactory.java
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideShowFactory.java
@@ -25,40 +25,81 @@ import org.apache.poi.EncryptedDocumentException;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackageAccess;
-import org.apache.poi.sl.usermodel.SlideShowFactory;
+import org.apache.poi.poifs.filesystem.DirectoryNode;
+import org.apache.poi.poifs.filesystem.DocumentFactoryHelper;
+import org.apache.poi.poifs.filesystem.FileMagic;
+import org.apache.poi.poifs.filesystem.POIFSFileSystem;
+import org.apache.poi.sl.usermodel.SlideShowProvider;
import org.apache.poi.util.Internal;
@Internal
-public class XSLFSlideShowFactory extends SlideShowFactory {
+public class XSLFSlideShowFactory implements SlideShowProvider<XSLFShape,XSLFTextParagraph> {
- static {
- SlideShowFactory.createXslfByFile = XSLFSlideShowFactory::createSlideShow;
- SlideShowFactory.createXslfByStream = XSLFSlideShowFactory::createSlideShow;
+ @Override
+ public boolean accepts(FileMagic fm) {
+ return fm == FileMagic.OOXML;
}
/**
- * Creates a XMLSlideShow from the given OOXML Package.
- * This is a convenience method to go along the create-methods of the super class.
+ * Create a new empty SlideShow
+ *
+ * @return The created SlideShow
+ */
+ @Override
+ public XMLSlideShow create() {
+ return new XMLSlideShow();
+ }
+
+ @Override
+ public XMLSlideShow create(DirectoryNode root, String password) throws IOException {
+ try (InputStream stream = DocumentFactoryHelper.getDecryptedStream(root, password)) {
+ return create(stream);
+ } finally {
+ // as we processed the full stream already, we can close the filesystem here
+ // otherwise file handles are leaked
+ root.getFileSystem().close();
+ }
+ }
+
+ @Override
+ public XMLSlideShow create(InputStream inp, String password) throws IOException {
+ InputStream bufInp = FileMagic.prepareToCheckMagic(inp);
+ FileMagic fm = FileMagic.valueOf(bufInp);
+
+ if (fm == FileMagic.OLE2) {
+ try (POIFSFileSystem poifs = new POIFSFileSystem(bufInp);
+ InputStream stream = DocumentFactoryHelper.getDecryptedStream(poifs.getRoot(), password)) {
+ return create(stream);
+ }
+ }
+
+ if (fm == FileMagic.OOXML) {
+ return create(bufInp);
+ }
+
+ return null;
+ }
+
+ /**
+ * Creates a XMLSlideShow from the given InputStream
*
* <p>Note that in order to properly release resources the
- * SlideShow should be closed after use.</p>
+ * SlideShow should be closed after use.</p>
*
- * @param pkg The {@link OPCPackage} opened for reading data.
+ * @param stream The {@link InputStream} to read data from.
*
- * @return The created SlideShow
+ * @return The created SlideShow
*
- * @throws IOException if an error occurs while reading the data
+ * @throws IOException if an error occurs while reading the data
*/
- public static XMLSlideShow create(OPCPackage pkg) throws IOException {
+ @SuppressWarnings("resource")
+ @Override
+ public XMLSlideShow create(InputStream stream) throws IOException {
try {
- return new XMLSlideShow(pkg);
- } catch (IllegalArgumentException ioe) {
- // ensure that file handles are closed (use revert() to not re-write the file)
- pkg.revert();
- //pkg.close();
-
- // rethrow exception
- throw ioe;
+ OPCPackage pkg = OPCPackage.open(stream);
+ return createSlideShow(pkg);
+ } catch (InvalidFormatException e) {
+ throw new IOException(e);
}
}
@@ -77,7 +118,7 @@ public class XSLFSlideShowFactory extends SlideShowFactory {
public static XMLSlideShow createSlideShow(OPCPackage pkg) throws IOException {
try {
return new XMLSlideShow(pkg);
- } catch (IllegalArgumentException ioe) {
+ } catch (RuntimeException ioe) {
// ensure that file handles are closed (use revert() to not re-write the file)
pkg.revert();
//pkg.close();
@@ -89,7 +130,7 @@ public class XSLFSlideShowFactory extends SlideShowFactory {
/**
* Creates the XMLSlideShow from the given File, which must exist and be readable.
- * <p>Note that in order to properly release resources theSlideShow should be closed after use.
+ * <p>Note that in order to properly release resources the SlideShow should be closed after use.
*
* @param file The file to read data from.
* @param readOnly If the SlideShow should be opened in read-only mode to avoid writing back
@@ -101,36 +142,21 @@ public class XSLFSlideShowFactory extends SlideShowFactory {
* @throws EncryptedDocumentException If the wrong password is given for a protected file
*/
@SuppressWarnings("resource")
- public static XMLSlideShow createSlideShow(File file, boolean readOnly)
- throws IOException {
- try {
- OPCPackage pkg = OPCPackage.open(file, readOnly ? PackageAccess.READ : PackageAccess.READ_WRITE);
- return createSlideShow(pkg);
- } catch (InvalidFormatException e) {
- throw new IOException(e);
+ public XMLSlideShow create(File file, String password, boolean readOnly) throws IOException {
+ FileMagic fm = FileMagic.valueOf(file);
+
+ if (fm == FileMagic.OLE2) {
+ try (POIFSFileSystem poifs = new POIFSFileSystem(file, true);
+ InputStream stream = DocumentFactoryHelper.getDecryptedStream(poifs.getRoot(), password)) {
+ return create(stream);
+ }
}
- }
- /**
- * Creates a XMLSlideShow from the given InputStream
- *
- * <p>Note that in order to properly release resources the
- * SlideShow should be closed after use.</p>
- *
- * @param stream The {@link InputStream} to read data from.
- *
- * @return The created SlideShow
- *
- * @throws IOException if an error occurs while reading the data
- */
- @SuppressWarnings("resource")
- public static XMLSlideShow createSlideShow(InputStream stream) throws IOException {
try {
- OPCPackage pkg = OPCPackage.open(stream);
+ OPCPackage pkg = OPCPackage.open(file, readOnly ? PackageAccess.READ : PackageAccess.READ_WRITE);
return createSlideShow(pkg);
} catch (InvalidFormatException e) {
throw new IOException(e);
}
}
-
}
diff --git a/src/resources/ooxml/META-INF/services/org.apache.poi.sl.usermodel.SlideShowProvider b/src/resources/ooxml/META-INF/services/org.apache.poi.sl.usermodel.SlideShowProvider
new file mode 100644
index 0000000000..f4251abe27
--- /dev/null
+++ b/src/resources/ooxml/META-INF/services/org.apache.poi.sl.usermodel.SlideShowProvider
@@ -0,0 +1,18 @@
+# ====================================================================
+# 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.
+# ====================================================================
+
+org.apache.poi.xslf.usermodel.XSLFSlideShowFactory \ No newline at end of file
diff --git a/src/resources/scratchpad/META-INF/services/org.apache.poi.sl.usermodel.SlideShowProvider b/src/resources/scratchpad/META-INF/services/org.apache.poi.sl.usermodel.SlideShowProvider
new file mode 100644
index 0000000000..1fcb1ec7c7
--- /dev/null
+++ b/src/resources/scratchpad/META-INF/services/org.apache.poi.sl.usermodel.SlideShowProvider
@@ -0,0 +1,18 @@
+# ====================================================================
+# 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.
+# ====================================================================
+
+org.apache.poi.hslf.usermodel.HSLFSlideShowFactory \ No newline at end of file
diff --git a/src/scratchpad/src/org/apache/poi/extractor/ole2/OLE2ScratchpadExtractorFactory.java b/src/scratchpad/src/org/apache/poi/extractor/ole2/OLE2ScratchpadExtractorFactory.java
index 16711d0b11..d0e0f88e81 100644
--- a/src/scratchpad/src/org/apache/poi/extractor/ole2/OLE2ScratchpadExtractorFactory.java
+++ b/src/scratchpad/src/org/apache/poi/extractor/ole2/OLE2ScratchpadExtractorFactory.java
@@ -30,9 +30,7 @@ import org.apache.poi.extractor.POIOLE2TextExtractor;
import org.apache.poi.extractor.POITextExtractor;
import org.apache.poi.hdgf.extractor.VisioTextExtractor;
import org.apache.poi.hpbf.extractor.PublisherTextExtractor;
-import org.apache.poi.hslf.usermodel.HSLFShape;
import org.apache.poi.hslf.usermodel.HSLFSlideShow;
-import org.apache.poi.hslf.usermodel.HSLFTextParagraph;
import org.apache.poi.hsmf.MAPIMessage;
import org.apache.poi.hsmf.datatypes.AttachmentChunks;
import org.apache.poi.hsmf.extractor.OutlookTextExtractor;
@@ -102,7 +100,7 @@ public class OLE2ScratchpadExtractorFactory implements ExtractorProvider {
}
if (poifsDir.hasEntry(HSLFSlideShow.POWERPOINT_DOCUMENT)) {
- return new SlideShowExtractor<HSLFShape, HSLFTextParagraph>(SlideShowFactory.create(poifsDir));
+ return new SlideShowExtractor<>((HSLFSlideShow)SlideShowFactory.create(poifsDir));
}
if (poifsDir.hasEntry("VisioDocument")) {
diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShowFactory.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShowFactory.java
index 42db16482e..936eae064e 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShowFactory.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShowFactory.java
@@ -17,11 +17,16 @@
package org.apache.poi.hslf.usermodel;
+import java.io.File;
import java.io.IOException;
+import java.io.InputStream;
+import org.apache.poi.hssf.record.crypto.Biff8EncryptionKey;
import org.apache.poi.poifs.filesystem.DirectoryNode;
+import org.apache.poi.poifs.filesystem.FileMagic;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.sl.usermodel.SlideShowFactory;
+import org.apache.poi.sl.usermodel.SlideShowProvider;
import org.apache.poi.util.Internal;
/**
@@ -30,11 +35,20 @@ import org.apache.poi.util.Internal;
*/
@SuppressWarnings("unused")
@Internal
-public class HSLFSlideShowFactory extends SlideShowFactory {
+public class HSLFSlideShowFactory implements SlideShowProvider<HSLFShape,HSLFTextParagraph> {
- static {
- SlideShowFactory.createHslfByNode = HSLFSlideShowFactory::createSlideShow;
- SlideShowFactory.createHslfByPoifs = HSLFSlideShowFactory::createSlideShow;
+ @Override
+ public boolean accepts(FileMagic fm) {
+ return FileMagic.OLE2 == fm;
+ }
+
+ /**
+ * Create a new empty SlideShow
+ *
+ * @return The created SlideShow
+ */
+ public HSLFSlideShow create() {
+ return new HSLFSlideShow();
}
/**
@@ -51,7 +65,45 @@ public class HSLFSlideShowFactory extends SlideShowFactory {
* Note that in order to properly release resources the
* SlideShow should be closed after use.
*/
- public static HSLFSlideShow createSlideShow(final DirectoryNode root) throws IOException {
- return new HSLFSlideShow(root);
+ public HSLFSlideShow create(final DirectoryNode root, String password) throws IOException {
+ boolean passwordSet = false;
+ if (password != null) {
+ Biff8EncryptionKey.setCurrentUserPassword(password);
+ passwordSet = true;
+ }
+ try {
+ return new HSLFSlideShow(root);
+ } finally {
+ if (passwordSet) {
+ Biff8EncryptionKey.setCurrentUserPassword(null);
+ }
+ }
+ }
+
+ @Override
+ public HSLFSlideShow create(InputStream inp) throws IOException {
+ return create(inp, null);
+ }
+
+ @Override
+ public HSLFSlideShow create(InputStream inp, String password) throws IOException {
+ POIFSFileSystem fs = new POIFSFileSystem(inp);
+ return create(fs.getRoot(), password);
+ }
+
+ @Override
+ public HSLFSlideShow create(File file, String password, boolean readOnly) throws IOException {
+ boolean passwordSet = false;
+ if (password != null) {
+ Biff8EncryptionKey.setCurrentUserPassword(password);
+ passwordSet = true;
+ }
+ try {
+ return new HSLFSlideShow(new POIFSFileSystem(file, readOnly));
+ } finally {
+ if (passwordSet) {
+ Biff8EncryptionKey.setCurrentUserPassword(null);
+ }
+ }
}
}
diff --git a/src/testcases/org/apache/poi/sl/usermodel/BaseTestSlideShow.java b/src/testcases/org/apache/poi/sl/usermodel/BaseTestSlideShow.java
index 5d53b4bd62..6158c9de63 100644
--- a/src/testcases/org/apache/poi/sl/usermodel/BaseTestSlideShow.java
+++ b/src/testcases/org/apache/poi/sl/usermodel/BaseTestSlideShow.java
@@ -160,8 +160,9 @@ public abstract class BaseTestSlideShow<
@Test
public void shapeAndSlideName() throws IOException {
final String file = "SampleShow.ppt"+(getClass().getSimpleName().contains("XML")?"x":"");
+ //noinspection unchecked
try (final InputStream is = slTests.openResourceAsStream(file);
- final SlideShow<S,P> ppt = SlideShowFactory.create(is)) {
+ final SlideShow<S,P> ppt = (SlideShow<S,P>)SlideShowFactory.create(is)) {
final List<S> shapes1 = ppt.getSlides().get(0).getShapes();
assertEquals("The Title", shapes1.get(0).getShapeName());
assertEquals("Another Subtitle", shapes1.get(1).getShapeName());
diff --git a/src/testcases/org/apache/poi/sl/usermodel/BaseTestSlideShowFactory.java b/src/testcases/org/apache/poi/sl/usermodel/BaseTestSlideShowFactory.java
index d62d787d94..345bb7906e 100644
--- a/src/testcases/org/apache/poi/sl/usermodel/BaseTestSlideShowFactory.java
+++ b/src/testcases/org/apache/poi/sl/usermodel/BaseTestSlideShowFactory.java
@@ -98,7 +98,7 @@ public abstract class BaseTestSlideShowFactory {
// from protected POIFS
if (protectedFile.endsWith(".ppt") || protectedFile.endsWith(".pptx")) {
POIFSFileSystem poifs = new POIFSFileSystem(fromFile(protectedFile));
- ss = SlideShowFactory.create(poifs, password);
+ ss = SlideShowFactory.create(poifs.getRoot(), password);
assertNotNull(ss);
poifs.close();
assertCloseDoesNotModifyFile(protectedFile, ss);
@@ -172,13 +172,13 @@ public abstract class BaseTestSlideShowFactory {
assertArrayEquals(filename + " sample file was modified as a result of closing the slideshow",
before, after);
} catch (AssertionError e) {
- // if the file after closing is different, then re-set
- // the file to the state before in order to not have a dirty SCM
+ // if the file after closing is different, then re-set
+ // the file to the state before in order to not have a dirty SCM
// working tree when running this test
try (FileOutputStream str = new FileOutputStream(_slTests.getFile(filename))) {
str.write(before);
}
-
+
throw e;
}
}