1 package org.junit.rules; 2 3 import java.io.File; 4 import java.io.IOException; 5 6 import org.junit.Rule; 7 8 /** 9 * The TemporaryFolder Rule allows creation of files and folders that should 10 * be deleted when the test method finishes (whether it passes or 11 * fails). Whether the deletion is successful or not is not checked by this rule. 12 * No exception will be thrown in case the deletion fails. 13 * 14 * <p>Example of usage: 15 * <pre> 16 * public static class HasTempFolder { 17 * @Rule 18 * public TemporaryFolder folder= new TemporaryFolder(); 19 * 20 * @Test 21 * public void testUsingTempFolder() throws IOException { 22 * File createdFile= folder.newFile("myfile.txt"); 23 * File createdFolder= folder.newFolder("subfolder"); 24 * // ... 25 * } 26 * } 27 * </pre> 28 * 29 * @since 4.7 30 */ 31 public class TemporaryFolder extends ExternalResource { 32 private final File parentFolder; 33 private File folder; 34 TemporaryFolder()35 public TemporaryFolder() { 36 this(null); 37 } 38 TemporaryFolder(File parentFolder)39 public TemporaryFolder(File parentFolder) { 40 this.parentFolder = parentFolder; 41 } 42 43 @Override before()44 protected void before() throws Throwable { 45 create(); 46 } 47 48 @Override after()49 protected void after() { 50 delete(); 51 } 52 53 // testing purposes only 54 55 /** 56 * for testing purposes only. Do not use. 57 */ create()58 public void create() throws IOException { 59 folder = createTemporaryFolderIn(parentFolder); 60 } 61 62 /** 63 * Returns a new fresh file with the given name under the temporary folder. 64 */ newFile(String fileName)65 public File newFile(String fileName) throws IOException { 66 File file = new File(getRoot(), fileName); 67 if (!file.createNewFile()) { 68 throw new IOException( 69 "a file with the name \'" + fileName + "\' already exists in the test folder"); 70 } 71 return file; 72 } 73 74 /** 75 * Returns a new fresh file with a random name under the temporary folder. 76 */ newFile()77 public File newFile() throws IOException { 78 return File.createTempFile("junit", null, getRoot()); 79 } 80 81 /** 82 * Returns a new fresh folder with the given name under the temporary 83 * folder. 84 */ newFolder(String folder)85 public File newFolder(String folder) throws IOException { 86 return newFolder(new String[]{folder}); 87 } 88 89 /** 90 * Returns a new fresh folder with the given name(s) under the temporary 91 * folder. 92 */ newFolder(String... folderNames)93 public File newFolder(String... folderNames) throws IOException { 94 File file = getRoot(); 95 for (int i = 0; i < folderNames.length; i++) { 96 String folderName = folderNames[i]; 97 validateFolderName(folderName); 98 file = new File(file, folderName); 99 if (!file.mkdir() && isLastElementInArray(i, folderNames)) { 100 throw new IOException( 101 "a folder with the name \'" + folderName + "\' already exists"); 102 } 103 } 104 return file; 105 } 106 107 /** 108 * Validates if multiple path components were used while creating a folder. 109 * 110 * @param folderName 111 * Name of the folder being created 112 */ validateFolderName(String folderName)113 private void validateFolderName(String folderName) throws IOException { 114 File tempFile = new File(folderName); 115 if (tempFile.getParent() != null) { 116 String errorMsg = "Folder name cannot consist of multiple path components separated by a file separator." 117 + " Please use newFolder('MyParentFolder','MyFolder') to create hierarchies of folders"; 118 throw new IOException(errorMsg); 119 } 120 } 121 isLastElementInArray(int index, String[] array)122 private boolean isLastElementInArray(int index, String[] array) { 123 return index == array.length - 1; 124 } 125 126 /** 127 * Returns a new fresh folder with a random name under the temporary folder. 128 */ newFolder()129 public File newFolder() throws IOException { 130 return createTemporaryFolderIn(getRoot()); 131 } 132 createTemporaryFolderIn(File parentFolder)133 private File createTemporaryFolderIn(File parentFolder) throws IOException { 134 File createdFolder = File.createTempFile("junit", "", parentFolder); 135 createdFolder.delete(); 136 createdFolder.mkdir(); 137 return createdFolder; 138 } 139 140 /** 141 * @return the location of this temporary folder. 142 */ getRoot()143 public File getRoot() { 144 if (folder == null) { 145 throw new IllegalStateException( 146 "the temporary folder has not yet been created"); 147 } 148 return folder; 149 } 150 151 /** 152 * Delete all files and folders under the temporary folder. Usually not 153 * called directly, since it is automatically applied by the {@link Rule} 154 */ delete()155 public void delete() { 156 if (folder != null) { 157 recursiveDelete(folder); 158 } 159 } 160 recursiveDelete(File file)161 private void recursiveDelete(File file) { 162 File[] files = file.listFiles(); 163 if (files != null) { 164 for (File each : files) { 165 recursiveDelete(each); 166 } 167 } 168 file.delete(); 169 } 170 } 171