From: Nick Burch Date: Thu, 24 Jul 2014 18:58:27 +0000 (+0000) Subject: Patch from Raúl Wegmann from bug #56735 / GitHub Pull #10 - Rationalise POI temp... X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=4c98f1db45e13984e4e5eca126ba6994466cfb01;p=poi.git Patch from Raúl Wegmann from bug #56735 / GitHub Pull #10 - Rationalise POI temp file creation to the TempFile util class, and allow a system wide setting of where Temp files (eg for SXSSF) go, via TempFile / TempFileCreationStrategy git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1613246 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/src/java/org/apache/poi/util/TempFile.java b/src/java/org/apache/poi/util/TempFile.java index 82578886bf..a20341ee12 100644 --- a/src/java/org/apache/poi/util/TempFile.java +++ b/src/java/org/apache/poi/util/TempFile.java @@ -18,47 +18,99 @@ package org.apache.poi.util; import java.io.File; -import java.util.Random; +import java.io.IOException; /** - * Interface for creating temporary files. Collects them all into one directory. - * - * @author Glen Stampoultzis + * Interface for creating temporary files. Collects them all into one directory by default. */ public final class TempFile { - private static File dir; - private static final Random rnd = new Random(); - + + /** The strategy used by {@link #createTempFile(String, String)} to create the temporary files. */ + private static TempFileCreationStrategy strategy = new DefaultTempFileCreationStrategy(); + /** - * Creates a temporary file. Files are collected into one directory and by default are - * deleted on exit from the VM. Files can be kept by defining the system property - * poi.keep.tmp.files. + * Configures the strategy used by {@link #createTempFile(String, String)} to create the temporary files. + * + * @param strategy The new strategy to be used to create the temporary files. + * + * @throws IllegalArgumentException When the given strategy is null. + */ + public static void setTempFileCreationStrategy(TempFileCreationStrategy strategy) { + if (strategy == null) { + throw new IllegalArgumentException("strategy == null"); + } + TempFile.strategy = strategy; + } + + /** + * Creates a new and empty temporary file. By default, files are collected into one directory and are + * deleted on exit from the VM, although they can be kept by defining the system property + * poi.keep.tmp.files (see {@link DefaultTempFileCreationStrategy}). *

* Don't forget to close all files or it might not be possible to delete them. + * + * @param prefix The prefix to be used to generate the name of the temporary file. + * @param suffix The suffix to be used to generate the name of the temporary file. + * + * @return The path to the newly created and empty temporary file. + * + * @throws IOException If no temporary file could be created. */ - public static File createTempFile(String prefix, String suffix) { - // Identify and create our temp dir, if needed - if (dir == null) - { - dir = new File(System.getProperty("java.io.tmpdir"), "poifiles"); - dir.mkdir(); - if (System.getProperty("poi.keep.tmp.files") == null) - dir.deleteOnExit(); + public static File createTempFile(String prefix, String suffix) throws IOException { + return strategy.createTempFile(prefix, suffix); + } + + /** + * Default implementation of the {@link TempFileCreationStrategy} used by {@link TempFile}: + * Files are collected into one directory and by default are deleted on exit from the VM. + * Files can be kept by defining the system property poi.keep.tmp.files. + */ + public static class DefaultTempFileCreationStrategy implements TempFileCreationStrategy { + + /** The directory where the temporary files will be created (null to use the default directory). */ + private File dir; + + /** + * Creates the strategy so that it creates the temporary files in the default directory. + * + * @see File#createTempFile(String, String) + */ + public DefaultTempFileCreationStrategy() { + this(null); } - - // Generate a unique new filename - File newFile = new File(dir, prefix + rnd.nextInt() + suffix); - if (newFile.exists()) - { - // That name is already taken, try another - newFile = createTempFile(prefix, suffix); + + /** + * Creates the strategy allowing to set the + * + * @param dir The directory where the temporary files will be created (null to use the default directory). + * + * @see File#createTempFile(String, String, File) + */ + public DefaultTempFileCreationStrategy(File dir) { + this.dir = dir; } + + @Override + public File createTempFile(String prefix, String suffix) throws IOException { + // Identify and create our temp dir, if needed + if (dir == null) + { + dir = new File(System.getProperty("java.io.tmpdir"), "poifiles"); + dir.mkdir(); + if (System.getProperty("poi.keep.tmp.files") == null) + dir.deleteOnExit(); + } - // Set the delete on exit flag, unless explicitly disabled - if (System.getProperty("poi.keep.tmp.files") == null) - newFile.deleteOnExit(); + // Generate a unique new filename + File newFile = File.createTempFile(prefix, suffix, dir); - // All done - return newFile; + // Set the delete on exit flag, unless explicitly disabled + if (System.getProperty("poi.keep.tmp.files") == null) + newFile.deleteOnExit(); + + // All done + return newFile; + } + } } diff --git a/src/java/org/apache/poi/util/TempFileCreationStrategy.java b/src/java/org/apache/poi/util/TempFileCreationStrategy.java new file mode 100644 index 0000000000..1e9ae9cdbb --- /dev/null +++ b/src/java/org/apache/poi/util/TempFileCreationStrategy.java @@ -0,0 +1,38 @@ +/* ==================================================================== + 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.util; + +import java.io.File; +import java.io.IOException; + +/** + * Interface used by the {@link TempFile} utility class to create temporary files. + */ +public interface TempFileCreationStrategy { + /** + * Creates a new and empty temporary file. + * + * @param prefix The prefix to be used to generate the name of the temporary file. + * @param suffix The suffix to be used to generate the name of the temporary file. + * + * @return The path to the newly created and empty temporary file. + * + * @throws IOException If no temporary file could be created. + */ + public File createTempFile(String prefix, String suffix) throws IOException; +} diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackage.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackage.java index a352a8d1f6..62f26b7546 100644 --- a/src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackage.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackage.java @@ -43,6 +43,7 @@ import org.apache.poi.openxml4j.util.ZipFileZipEntrySource; import org.apache.poi.openxml4j.util.ZipInputStreamZipEntrySource; import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogger; +import org.apache.poi.util.TempFile; /** * Physical zip package. @@ -343,7 +344,7 @@ public final class ZipPackage extends Package { if (targetFile.exists()) { // Case of a package previously open - File tempFile = File.createTempFile( + File tempFile = TempFile.createTempFile( generateTempFileName(FileHelper .getDirectory(targetFile)), ".tmp"); diff --git a/src/ooxml/java/org/apache/poi/util/PackageHelper.java b/src/ooxml/java/org/apache/poi/util/PackageHelper.java index f4ab052055..884868f1be 100644 --- a/src/ooxml/java/org/apache/poi/util/PackageHelper.java +++ b/src/ooxml/java/org/apache/poi/util/PackageHelper.java @@ -29,8 +29,6 @@ import java.net.URI; /** * Provides handy methods to work with OOXML packages - * - * @author Yegor Kozlov */ public final class PackageHelper { @@ -80,18 +78,6 @@ public final class PackageHelper { return OPCPackage.open(path); } - /** - * Creates an empty file in the default temporary-file directory, - */ - public static File createTempFile() { - File file = TempFile.createTempFile("poi-ooxml-", ".tmp"); - //there is no way to pass an existing file to Package.create(file), - //delete first, the file will be re-created in Packe.create(file) - file.delete(); - return file; - - } - /** * Recursively copy package parts to the destination package */ diff --git a/src/ooxml/java/org/apache/poi/xssf/streaming/GZIPSheetDataWriter.java b/src/ooxml/java/org/apache/poi/xssf/streaming/GZIPSheetDataWriter.java index dbe7c12a31..d194f4fb16 100644 --- a/src/ooxml/java/org/apache/poi/xssf/streaming/GZIPSheetDataWriter.java +++ b/src/ooxml/java/org/apache/poi/xssf/streaming/GZIPSheetDataWriter.java @@ -29,6 +29,7 @@ import java.io.Writer; import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; +import org.apache.poi.util.TempFile; import org.apache.poi.xssf.model.SharedStringsTable; /** @@ -51,8 +52,8 @@ public class GZIPSheetDataWriter extends SheetDataWriter { * @return temp file to write sheet data */ @Override - public File createTempFile()throws IOException { - return File.createTempFile("poi-sxssf-sheet-xml", ".gz"); + public File createTempFile() throws IOException { + return TempFile.createTempFile("poi-sxssf-sheet-xml", ".gz"); } /** diff --git a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java index 2f1d55947b..576e0b8f81 100644 --- a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java +++ b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java @@ -43,6 +43,7 @@ import org.apache.poi.ss.usermodel.Row.MissingCellPolicy; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.util.TempFile; import org.apache.poi.xssf.model.SharedStringsTable; import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook; @@ -820,7 +821,7 @@ public class SXSSFWorkbook implements Workbook } //Save the template - File tmplFile = File.createTempFile("poi-sxssf-template", ".xlsx"); + File tmplFile = TempFile.createTempFile("poi-sxssf-template", ".xlsx"); try { FileOutputStream os = new FileOutputStream(tmplFile); diff --git a/src/ooxml/java/org/apache/poi/xssf/streaming/SheetDataWriter.java b/src/ooxml/java/org/apache/poi/xssf/streaming/SheetDataWriter.java index fbdda65436..95b3a0bcb9 100644 --- a/src/ooxml/java/org/apache/poi/xssf/streaming/SheetDataWriter.java +++ b/src/ooxml/java/org/apache/poi/xssf/streaming/SheetDataWriter.java @@ -33,6 +33,7 @@ import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.FormulaError; import org.apache.poi.ss.util.CellReference; +import org.apache.poi.util.TempFile; import org.apache.poi.xssf.model.SharedStringsTable; import org.apache.poi.xssf.usermodel.XSSFRichTextString; import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCellType; @@ -75,8 +76,8 @@ public class SheetDataWriter { * * @return temp file to write sheet data */ - public File createTempFile()throws IOException { - return File.createTempFile("poi-sxssf-sheet", ".xml"); + public File createTempFile() throws IOException { + return TempFile.createTempFile("poi-sxssf-sheet", ".xml"); } /** diff --git a/src/ooxml/testcases/org/apache/poi/openxml4j/OpenXML4JTestDataSamples.java b/src/ooxml/testcases/org/apache/poi/openxml4j/OpenXML4JTestDataSamples.java index bf93681a4b..1c6b942a58 100644 --- a/src/ooxml/testcases/org/apache/poi/openxml4j/OpenXML4JTestDataSamples.java +++ b/src/ooxml/testcases/org/apache/poi/openxml4j/OpenXML4JTestDataSamples.java @@ -22,11 +22,10 @@ import org.apache.poi.util.TempFile; import java.io.File; import java.io.InputStream; +import java.io.IOException; /** * Centralises logic for finding/opening sample files for ooxml4j unit tests - * - * @author jmicich */ public final class OpenXML4JTestDataSamples { private static final POIDataSamples _samples = POIDataSamples.getOpenXML4JInstance(); @@ -46,7 +45,7 @@ public final class OpenXML4JTestDataSamples { return _samples.getFile(sampleFileName); } - public static File getOutputFile(String outputFileName) { + public static File getOutputFile(String outputFileName) throws IOException { String suffix = outputFileName.substring(outputFileName.lastIndexOf('.')); return TempFile.createTempFile(outputFileName, suffix); } diff --git a/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackage.java b/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackage.java index 01116abcf9..fe5bb21d46 100644 --- a/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackage.java +++ b/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackage.java @@ -454,7 +454,7 @@ public final class TestPackage extends TestCase { * write changes to it. */ public void testOpenFileThenOverwrite() throws Exception { - File tempFile = File.createTempFile("poiTesting","tmp"); + File tempFile = TempFile.createTempFile("poiTesting","tmp"); File origFile = OpenXML4JTestDataSamples.getSampleFile("TestPackageCommon.docx"); FileHelper.copyFile(origFile, tempFile); @@ -491,8 +491,8 @@ public final class TestPackage extends TestCase { * to another file, then delete both */ public void testOpenFileThenSaveDelete() throws Exception { - File tempFile = File.createTempFile("poiTesting","tmp"); - File tempFile2 = File.createTempFile("poiTesting","tmp"); + File tempFile = TempFile.createTempFile("poiTesting","tmp"); + File tempFile2 = TempFile.createTempFile("poiTesting","tmp"); File origFile = OpenXML4JTestDataSamples.getSampleFile("TestPackageCommon.docx"); FileHelper.copyFile(origFile, tempFile); diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFTable.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFTable.java index 78e5d80a0f..de7eff6be7 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFTable.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFTable.java @@ -20,6 +20,7 @@ package org.apache.poi.xssf.usermodel; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.xssf.XSSFTestDataSamples; import org.apache.poi.xssf.streaming.SXSSFWorkbook; +import org.apache.poi.util.TempFile; import org.junit.Test; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTable; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableColumn; @@ -52,7 +53,7 @@ public final class TestXSSFTable { } // save the worksheet as-is using SXSSF - File outputFile = File.createTempFile("poi-56274", ".xlsx"); + File outputFile = TempFile.createTempFile("poi-56274", ".xlsx"); SXSSFWorkbook outputWorkbook = new org.apache.poi.xssf.streaming.SXSSFWorkbook(inputWorkbook); outputWorkbook.write(new FileOutputStream(outputFile)); diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestFontRendering.java b/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestFontRendering.java index 5f981f5405..a6fa770059 100644 --- a/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestFontRendering.java +++ b/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestFontRendering.java @@ -41,6 +41,7 @@ import javax.imageio.ImageIO; import org.apache.poi.POIDataSamples; import org.apache.poi.hslf.model.Slide; import org.apache.poi.hslf.model.TextPainter; +import org.apache.poi.util.TempFile; import org.junit.Ignore; import org.junit.Test; @@ -114,7 +115,7 @@ public class TestFontRendering { // allow to find out what the actual difference is in CI where this fails currently if(!Arrays.equals(expectedData, actualData)) { - ImageIO.write(imgActual, "PNG", File.createTempFile("TestFontRendering", ".png")); + ImageIO.write(imgActual, "PNG", TempFile.createTempFile("TestFontRendering", ".png")); } assertTrue("Expected to have matching raster-arrays, but found differences, size " + expectedData.length + " and " + actualData.length, Arrays.equals(expectedData, actualData)); diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFName.java b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFName.java index 3a61f3cd3f..2903e9b059 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFName.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFName.java @@ -30,14 +30,10 @@ import org.apache.poi.ss.formula.ptg.Ptg; import org.apache.poi.ss.formula.FormulaType; import org.apache.poi.ss.usermodel.BaseTestNamedRange; import org.apache.poi.ss.util.AreaReference; +import org.apache.poi.util.TempFile; /** * Tests various functionality having to do with {@link org.apache.poi.ss.usermodel.Name}. - * - * @author Andrew C. Oliver (acoliver at apache dot org) - * @author ROMANL - * @author Danny Mui (danny at muibros.com) - * @author Amol S. Deshmukh < amol at ap ache dot org > */ public final class TestHSSFName extends BaseTestNamedRange { @@ -115,7 +111,7 @@ public final class TestHSSFName extends BaseTestNamedRange { // In case you fancy checking in excel, to ensure it // won't complain about the file now try { - File tempFile = File.createTempFile("POI-45126-", ".xls"); + File tempFile = TempFile.createTempFile("POI-45126-", ".xls"); FileOutputStream fout = new FileOutputStream(tempFile); nwb.write(fout); fout.close(); diff --git a/src/testcases/org/apache/poi/ss/formula/function/ExcelFileFormatDocFunctionExtractor.java b/src/testcases/org/apache/poi/ss/formula/function/ExcelFileFormatDocFunctionExtractor.java index e6646ae826..a4849a782b 100644 --- a/src/testcases/org/apache/poi/ss/formula/function/ExcelFileFormatDocFunctionExtractor.java +++ b/src/testcases/org/apache/poi/ss/formula/function/ExcelFileFormatDocFunctionExtractor.java @@ -17,6 +17,8 @@ package org.apache.poi.ss.formula.function; +import org.apache.poi.util.TempFile; + import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; @@ -57,8 +59,6 @@ import org.xml.sax.helpers.XMLReaderFactory; * the file 'functionMetadata.txt'. There are more than 300 built-in functions in Excel and the * intention of this class is to make it easier to maintain the metadata, by extracting it from * a reliable source. - * - * @author Josh Micich */ public final class ExcelFileFormatDocFunctionExtractor { @@ -577,7 +577,7 @@ public final class ExcelFileFormatDocFunctionExtractor { URLConnection conn = url.openConnection(); InputStream is = conn.getInputStream(); System.out.println("downloading " + url.toExternalForm()); - result = File.createTempFile("excelfileformat", ".odt"); + result = TempFile.createTempFile("excelfileformat", ".odt"); OutputStream os = new FileOutputStream(result); while(true) { int bytesRead = is.read(buf); diff --git a/src/testcases/org/apache/poi/ss/formula/ptg/TestExternalFunctionFormulas.java b/src/testcases/org/apache/poi/ss/formula/ptg/TestExternalFunctionFormulas.java index f1edbe21d0..968d926eef 100644 --- a/src/testcases/org/apache/poi/ss/formula/ptg/TestExternalFunctionFormulas.java +++ b/src/testcases/org/apache/poi/ss/formula/ptg/TestExternalFunctionFormulas.java @@ -17,6 +17,8 @@ package org.apache.poi.ss.formula.ptg; +import org.apache.poi.util.TempFile; + import java.io.File; import java.io.FileOutputStream; import java.io.IOException; @@ -32,9 +34,6 @@ import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.usermodel.CellValue; /** * Tests for functions from external workbooks (e.g. YEARFRAC). - * - * - * @author Josh Micich */ public final class TestExternalFunctionFormulas extends TestCase { @@ -60,7 +59,7 @@ public final class TestExternalFunctionFormulas extends TestCase { if (false) { // In case you fancy checking in excel try { - File tempFile = File.createTempFile("testExtFunc", ".xls"); + File tempFile = TempFile.createTempFile("testExtFunc", ".xls"); FileOutputStream fout = new FileOutputStream(tempFile); wb.write(fout); fout.close();