From: Javen O'Neal Date: Sun, 3 Jul 2016 22:58:06 +0000 (+0000) Subject: bug 59788: create temporary directories X-Git-Tag: REL_3_15_BETA3~222 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=e3f4061bc89ccc6480764dabeac258b602fc4c2d;p=poi.git bug 59788: create temporary directories git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1751177 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 44f461379c..b2b9c56bd4 100644 --- a/src/java/org/apache/poi/util/TempFile.java +++ b/src/java/org/apache/poi/util/TempFile.java @@ -19,6 +19,7 @@ package org.apache.poi.util; import java.io.File; import java.io.IOException; +import java.security.SecureRandom; /** * Interface for creating temporary files. Collects them all into one directory by default. @@ -29,6 +30,10 @@ public final class TempFile { /** Define a constant for this property as it is sometimes mistypes as "tempdir" otherwise */ public static final String JAVA_IO_TMPDIR = "java.io.tmpdir"; + + private TempFile() { + // no instances of this class + } /** * Configures the strategy used by {@link #createTempFile(String, String)} to create the temporary files. @@ -62,6 +67,10 @@ public final class TempFile { return strategy.createTempFile(prefix, suffix); } + public static File createTempDirectory(String name) throws IOException { + return strategy.createTempDirectory(name); + } + /** * 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. @@ -92,9 +101,9 @@ public final class TempFile { this.dir = dir; } - @Override - public File createTempFile(String prefix, String suffix) throws IOException { + private void createPOIFilesDirectory() throws IOException { // Identify and create our temp dir, if needed + // The directory is not deleted, even if it was created by this TempFleCreationStrategy if (dir == null) { String tmpDir = System.getProperty(JAVA_IO_TMPDIR); if (tmpDir == null) { @@ -102,10 +111,20 @@ public final class TempFile { } dir = new File(tmpDir, "poifiles"); } - - if (!(dir.exists() || dir.mkdirs()) || !dir.isDirectory()) { - throw new IOException("Could not create temporary directory '" + dir + "'"); + + createTempDirectory(dir); + } + + private void createTempDirectory(File directory) throws IOException { + if (!(directory.exists() || directory.mkdirs()) || !directory.isDirectory()) { + throw new IOException("Could not create temporary directory '" + directory + "'"); } + } + + @Override + public File createTempFile(String prefix, String suffix) throws IOException { + // Identify and create our temp dir, if needed + createPOIFilesDirectory(); // Generate a unique new filename File newFile = File.createTempFile(prefix, suffix, dir); @@ -118,5 +137,26 @@ public final class TempFile { // All done return newFile; } + + private static final SecureRandom random = new SecureRandom(); + @Override + public File createTempDirectory(String prefix) throws IOException { + // Identify and create our temp dir, if needed + createPOIFilesDirectory(); + + // Generate a unique new filename + // FIXME: Java 7+: use java.nio.Files#createTempDirectory + final long n = random.nextLong(); + File newDirectory = new File(dir, prefix + Long.toString(n)); + createTempDirectory(newDirectory); + + // Set the delete on exit flag, unless explicitly disabled + if (System.getProperty("poi.keep.tmp.files") == null) { + newDirectory.deleteOnExit(); + } + + // All done + return newDirectory; + } } } diff --git a/src/java/org/apache/poi/util/TempFileCreationStrategy.java b/src/java/org/apache/poi/util/TempFileCreationStrategy.java index d7752e766f..28feca0c1d 100644 --- a/src/java/org/apache/poi/util/TempFileCreationStrategy.java +++ b/src/java/org/apache/poi/util/TempFileCreationStrategy.java @@ -35,4 +35,15 @@ public interface TempFileCreationStrategy { * @throws IOException If no temporary file could be created. */ File createTempFile(String prefix, String suffix) throws IOException; + + /** + * Creates a new and empty temporary directory. + * + * @param prefix The directory name to be used to generate the name of the temporary directory. + * + * @return The path to the newly created and empty temporary directory. + * + * @throws IOException If no temporary directory could be created. + */ + File createTempDirectory(String prefix) throws IOException; } diff --git a/src/testcases/org/apache/poi/util/TestTempFile.java b/src/testcases/org/apache/poi/util/TestTempFile.java index fbae6577bc..aff7e2d6db 100644 --- a/src/testcases/org/apache/poi/util/TestTempFile.java +++ b/src/testcases/org/apache/poi/util/TestTempFile.java @@ -20,6 +20,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import java.io.File; import java.io.FileOutputStream; @@ -29,12 +30,16 @@ import java.util.Arrays; import org.apache.poi.poifs.dev.TestPOIFSDump; import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; public class TestTempFile { private String previousTempDir; - private File tempDir; + + @Rule + public ExpectedException thrown = ExpectedException.none(); @Before public void setUp() throws IOException { @@ -78,29 +83,54 @@ public class TestTempFile { } @Test - public void testCreateTempFile() throws Exception + public void testCreateTempFile() throws IOException { File tempFile = TempFile.createTempFile("test", ".txt"); FileOutputStream fos = new FileOutputStream(tempFile); - fos.write(1); + fos.write(1); //file can be written to fos.close(); - assertTrue(tempFile.exists()); - assertEquals("poifiles", tempFile.getParentFile().getName()); + assertTrue("temp file exists", tempFile.exists()); + assertTrue("temp file is a file", tempFile.isFile()); + assertTrue("temp file's name should start with test", + tempFile.getName().startsWith("test")); + assertTrue("temp file's name should end with .txt", + tempFile.getName().endsWith(".txt")); + assertEquals("temp file is saved in poifiles directory", + "poifiles", tempFile.getParentFile().getName()); // Can't think of a good way to check whether a file is actually deleted since it would require the VM to stop. - assertTrue(tempFile.delete()); + // Solution: set TempFileCreationStrategy to something that the unit test can trigger a deletion" + assertTrue("Unable to delete temp file", tempFile.delete()); } @Test - public void testConstructor() { - // can currently be constructed... - new TempFile(); + public void createTempFileWithDefaultSuffix() throws IOException { + File tempFile = TempFile.createTempFile("test", null); + assertTrue("temp file's name should end with .tmp", + tempFile.getName().endsWith(".tmp")); } - @Test(expected=IllegalArgumentException.class) + @Test + public void testCreateTempDirectory() throws IOException + { + File tempDir = TempFile.createTempDirectory("testDir"); + assertTrue("testDir exists", tempDir.exists()); + assertTrue("testDir is a directory", tempDir.isDirectory()); + assertTrue("testDir's name starts with testDir", + tempDir.getName().startsWith("testDir")); + assertEquals("tempDir is saved in poifiles directory", + "poifiles", tempDir.getParentFile().getName()); + + // Can't think of a good way to check whether a directory is actually deleted since it would require the VM to stop. + // Solution: set TempFileCreationStrategy to something that the unit test can trigger a deletion" + assertTrue("Unable to delete tempDir", tempDir.delete()); + } + + @Test public void testSetTempFileCreationStrategy() throws IOException { TempFile.setTempFileCreationStrategy(new TempFile.DefaultTempFileCreationStrategy()); + // Should be able to create two tempfiles with same prefix and suffix File file1 = TempFile.createTempFile("TestTempFile", ".tst"); File file2 = TempFile.createTempFile("TestTempFile", ".tst"); assertFalse(file1.equals(file2)); @@ -109,6 +139,7 @@ public class TestTempFile { assertNotNull(file1); assertTrue(file1.delete()); + thrown.expect(IllegalArgumentException.class); TempFile.setTempFileCreationStrategy(null); } }