package net.sourceforge.tuned; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; public final class TemporaryFolder { private static final String tmpdir = System.getProperty("java.io.tmpdir"); private static final Map folders = new HashMap(); /** * Get a {@link TemporaryFolder} instance for a given name. The actual directory will be * created lazily (e.g. when a file is created). The name of the directory will start with * the given name (lower-case) and contain a unique id, so multiple application instances * may run at the same time without the risk of interference. * * @param name case-insensitive name of a temporary folder (e.g. application name) * @return temporary folder for this name */ public static TemporaryFolder getFolder(String name) { // make name case-insensitive name = name.toLowerCase(); synchronized (folders) { TemporaryFolder folder = folders.get(name); if (folder == null) { folder = new TemporaryFolder(new File(tmpdir, String.format("%s [%s]", name, UUID.randomUUID()))); folders.put(name, folder); } return folder; } } /** * Delete all temporary folders on shutdown */ static { Runtime.getRuntime().addShutdownHook(new Thread("TemporaryFolder Cleanup") { @Override public void run() { synchronized (folders) { for (TemporaryFolder folder : folders.values()) { folder.delete(); } } } }); } private final File root; private TemporaryFolder(File root) { this.root = root; } /** * Create an empty file in this temporary folder. * * @param name name of the file * @return newly created file * @throws IOException if an I/O error occurred */ public File createFile(String name) throws IOException { // if the directory does not exist it will be created File file = new File(getFolder(), name); file.createNewFile(); return file; } /** * Creates an empty file in this temporary folder, using the given prefix and suffix to * generate its name. * * @param prefix The prefix string to be used in generating the file's name; must be at * least three characters long * @param suffix The suffix string to be used in generating the file's name; may be null, * in which case the suffix ".tmp" will be used * @return An abstract pathname denoting a newly-created empty file * @throws IOException If a file could not be created * @see File#createTempFile(String, String) */ public File createFile(String prefix, String suffix) throws IOException { return File.createTempFile(prefix, suffix, getFolder()); } public boolean deleteFile(String name) { return new File(getFolder(), name).delete(); } /** * Retrieve the {@link File} object for this {@link TemporaryFolder}. The actual directory * for the {@link TemporaryFolder} instance will be created by this method. * * @return the {@link File} object for this {@link TemporaryFolder} */ public File getFolder() { if (!root.exists()) { root.mkdirs(); } return root; } public TemporaryFolder subFolder(String name) { return new TemporaryFolder(new File(getFolder(), name)); } public List list(boolean recursive) { List list = new ArrayList(); list(root, list, recursive); return list; } private void list(File file, List list, boolean recursive) { if (file.isDirectory()) { for (File entry : file.listFiles()) { if (entry.isDirectory()) { if (recursive) { list(entry, list, recursive); } } else { list.add(entry); } } } } public void delete() { delete(root); } /** * Delete files/folders recursively * * @param file file/folder that will be deleted */ private void delete(File file) { if (file.isDirectory()) { for (File entry : file.listFiles()) { delete(entry); } } file.delete(); } }