/* ==================================================================== 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 static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.fail; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import org.apache.poi.POIDataSamples; import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; public class BaseTestSlideShowFactory { private static final POIDataSamples _slTests = POIDataSamples.getSlideShowInstance(); @SuppressWarnings("resource") protected static void testFactoryFromFile(String file) throws Exception { SlideShow<?,?> ss; // from file ss = SlideShowFactory.create(fromFile(file)); assertNotNull(ss); assertCloseDoesNotModifyFile(file, ss); } @SuppressWarnings("resource") protected static void testFactoryFromStream(String file) throws Exception { SlideShow<?,?> ss; // from stream ss = SlideShowFactory.create(fromStream(file)); assertNotNull(ss); assertCloseDoesNotModifyFile(file, ss); } @SuppressWarnings("resource") protected static void testFactoryFromNative(String file) throws Exception { SlideShow<?,?> ss; // from NPOIFS if (file.endsWith(".ppt")) { NPOIFSFileSystem npoifs = new NPOIFSFileSystem(fromFile(file)); ss = SlideShowFactory.create(npoifs); assertNotNull(ss); npoifs.close(); assertCloseDoesNotModifyFile(file, ss); } // from OPCPackage else if (file.endsWith(".pptx")) { // not implemented throw new UnsupportedOperationException("Test not implemented"); } else { fail("Unexpected file extension: " + file); } } @SuppressWarnings("resource") protected static void testFactoryFromProtectedFile(String protectedFile, String password) throws Exception { SlideShow<?,?> ss; // from protected file ss = SlideShowFactory.create(fromFile(protectedFile), password); assertNotNull(ss); assertCloseDoesNotModifyFile(protectedFile, ss); } @SuppressWarnings("resource") protected static void testFactoryFromProtectedStream(String protectedFile, String password) throws Exception { SlideShow<?,?> ss; // from protected stream ss = SlideShowFactory.create(fromStream(protectedFile), password); assertNotNull(ss); assertCloseDoesNotModifyFile(protectedFile, ss); } @SuppressWarnings("resource") protected static void testFactoryFromProtectedNative(String protectedFile, String password) throws Exception { SlideShow<?,?> ss; // Encryption layer is a BIFF8 binary format that can be read by NPOIFSFileSystem, // used for both HSLF and XSLF // from protected NPOIFS if (protectedFile.endsWith(".ppt") || protectedFile.endsWith(".pptx")) { NPOIFSFileSystem npoifs = new NPOIFSFileSystem(fromFile(protectedFile)); ss = SlideShowFactory.create(npoifs, password); assertNotNull(ss); npoifs.close(); assertCloseDoesNotModifyFile(protectedFile, ss); } else { fail("Unrecognized file extension: " + protectedFile); } } public static void testFactory(String file, String protectedFile, String password) throws Exception { testFactoryFromFile(file); testFactoryFromStream(file); testFactoryFromNative(file); testFactoryFromProtectedFile(protectedFile, password); testFactoryFromProtectedStream(protectedFile, password); testFactoryFromProtectedNative(protectedFile, password); } /** * reads either a test-data file (filename) or a file outside the test-data folder (full path) */ private static byte[] readFile(String filename) { byte[] bytes; try { bytes = _slTests.readFile(filename); } catch (final RuntimeException e) { if (!e.getMessage().startsWith("Sample file '" + filename + "' not found in data dir")) { throw e; } bytes = readExternalFile(filename); } return bytes; } private static byte[] readExternalFile(String path) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); try { InputStream fis = new FileInputStream(path); byte[] buf = new byte[512]; while (true) { int bytesRead = fis.read(buf); if (bytesRead < 1) { break; } baos.write(buf, 0, bytesRead); } fis.close(); } catch (final IOException e) { throw new RuntimeException(e); } final byte[] bytes = baos.toByteArray(); return bytes; } /** * FIXME: * bug 58779: Closing an XMLSlideShow that was created with {@link SlideShowFactory#create(File)} modifies the file * * @param filename the sample filename or full path of the slideshow to check before and after closing * @param ss the slideshow to close or revert * @throws IOException */ private static void assertCloseDoesNotModifyFile(String filename, SlideShow<?,?> ss) throws IOException { final byte[] before = readFile(filename); ss.close(); final byte[] after = readFile(filename); try { 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 // working tree when running this test FileOutputStream str = new FileOutputStream(_slTests.getFile(filename)); try { str.write(before); } finally { str.close(); } throw e; } } private static File fromFile(String file) { return (file.contains("/") || file.contains("\\")) ? new File(file) : _slTests.getFile(file); } private static InputStream fromStream(String file) throws IOException { return (file.contains("/") || file.contains("\\")) ? new FileInputStream(file) : _slTests.openResourceAsStream(file); } }