==================================================================== */
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
*
*
* @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.
*
*
* @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);
}
*
* @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
* @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
* @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.
* @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
* @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
* @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);
}
}
--- /dev/null
+/* ====================================================================
+ 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;
+}
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);
}
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;
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;
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;
/* 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;
/* 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;
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;
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;
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);
}
}
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();
/**
* 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
* @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);
}
}
-
}
--- /dev/null
+# ====================================================================
+# 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
--- /dev/null
+# ====================================================================
+# 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
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;
}
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")) {
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;
/**
*/
@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();
}
/**
* 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);
+ }
+ }
}
}
@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());
// 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);
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;
}
}