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
This commit is contained in:
Nick Burch 2014-07-24 18:58:27 +00:00
parent 9fcdec5719
commit 4c98f1db45
14 changed files with 149 additions and 73 deletions

View File

@ -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
* <code>poi.keep.tmp.files</code>.
* 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 <code>null</code>.
*/
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
* <code>poi.keep.tmp.files</code> (see {@link DefaultTempFileCreationStrategy}).
* <p>
* 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();
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 <code>poi.keep.tmp.files</code>.
*/
public static class DefaultTempFileCreationStrategy implements TempFileCreationStrategy {
/** The directory where the temporary files will be created (<code>null</code> 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);
}
/**
* Creates the strategy allowing to set the
*
* @param dir The directory where the temporary files will be created (<code>null</code> 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();
}
// Generate a unique new filename
File newFile = File.createTempFile(prefix, suffix, dir);
// Set the delete on exit flag, unless explicitly disabled
if (System.getProperty("poi.keep.tmp.files") == null)
dir.deleteOnExit();
newFile.deleteOnExit();
// All done
return newFile;
}
// 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);
}
// Set the delete on exit flag, unless explicitly disabled
if (System.getProperty("poi.keep.tmp.files") == null)
newFile.deleteOnExit();
// All done
return newFile;
}
}

View File

@ -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;
}

View File

@ -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");

View File

@ -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
*/

View File

@ -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");
}
/**

View File

@ -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);

View File

@ -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");
}
/**

View File

@ -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);
}

View File

@ -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);

View File

@ -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));

View File

@ -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));

View File

@ -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 &lt; amol at ap ache dot org &gt;
*/
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();

View File

@ -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);

View File

@ -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();