1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 package org.apache.commons.io; 18 19 import java.io.File; 20 import java.io.IOException; 21 22 /** 23 * Strategy for deleting files. 24 * <p> 25 * There is more than one way to delete a file. 26 * You may want to limit access to certain directories, to only delete 27 * directories if they are empty, or maybe to force deletion. 28 * </p> 29 * <p> 30 * This class captures the strategy to use and is designed for user subclassing. 31 * </p> 32 * 33 * @since 1.3 34 */ 35 public class FileDeleteStrategy { 36 37 /** 38 * Force file deletion strategy. 39 */ 40 static class ForceFileDeleteStrategy extends FileDeleteStrategy { 41 42 /** Default Constructor */ 43 ForceFileDeleteStrategy() { 44 super("Force"); 45 } 46 47 /** 48 * Deletes the file object. 49 * <p> 50 * This implementation uses {@code FileUtils.forceDelete()} 51 * if the file exists. 52 * </p> 53 * 54 * @param fileToDelete the file to delete, not null 55 * @return Always returns {@code true} 56 * @throws NullPointerException if the file is null 57 * @throws IOException if an error occurs during file deletion 58 */ 59 @Override 60 protected boolean doDelete(final File fileToDelete) throws IOException { 61 FileUtils.forceDelete(fileToDelete); 62 return true; 63 } 64 } 65 66 /** 67 * The singleton instance for normal file deletion, which does not permit 68 * the deletion of directories that are not empty. 69 */ 70 public static final FileDeleteStrategy NORMAL = new FileDeleteStrategy("Normal"); 71 72 /** 73 * The singleton instance for forced file deletion, which always deletes, 74 * even if the file represents a non-empty directory. 75 */ 76 public static final FileDeleteStrategy FORCE = new ForceFileDeleteStrategy(); 77 78 /** The name of the strategy. */ 79 private final String name; 80 81 /** 82 * Restricted constructor. 83 * 84 * @param name the name by which the strategy is known 85 */ 86 protected FileDeleteStrategy(final String name) { 87 this.name = name; 88 } 89 90 /** 91 * Deletes the file object, which may be a file or a directory. 92 * If the file does not exist, the method just returns. 93 * <p> 94 * Subclass writers should override {@link #doDelete(File)}, not this method. 95 * </p> 96 * 97 * @param fileToDelete the file to delete, not null 98 * @throws NullPointerException if the file is null 99 * @throws IOException if an error occurs during file deletion 100 */ 101 public void delete(final File fileToDelete) throws IOException { 102 if (fileToDelete.exists() && !doDelete(fileToDelete)) { 103 throw new IOException("Deletion failed: " + fileToDelete); 104 } 105 } 106 107 /** 108 * Deletes the file object, which may be a file or a directory. 109 * All {@link IOException}s are caught and false returned instead. 110 * If the file does not exist or is null, true is returned. 111 * <p> 112 * Subclass writers should override {@link #doDelete(File)}, not this method. 113 * </p> 114 * 115 * @param fileToDelete the file to delete, null returns true 116 * @return true if the file was deleted, or there was no such file 117 */ 118 public boolean deleteQuietly(final File fileToDelete) { 119 if (fileToDelete == null || !fileToDelete.exists()) { 120 return true; 121 } 122 try { 123 return doDelete(fileToDelete); 124 } catch (final IOException ex) { 125 return false; 126 } 127 } 128 129 /** 130 * Actually deletes the file object, which may be a file or a directory. 131 * <p> 132 * This method is designed for subclasses to override. 133 * The implementation may return either false or an {@link IOException} 134 * when deletion fails. The {@link #delete(File)} and {@link #deleteQuietly(File)} 135 * methods will handle either response appropriately. 136 * A check has been made to ensure that the file will exist. 137 * </p> 138 * <p> 139 * This implementation uses {@link FileUtils#delete(File)}. 140 * </p> 141 * 142 * @param file the file to delete, exists, not null 143 * @return true if the file was deleted 144 * @throws NullPointerException if the file is null 145 * @throws IOException if an error occurs during file deletion 146 */ 147 protected boolean doDelete(final File file) throws IOException { 148 FileUtils.delete(file); 149 return true; 150 } 151 152 /** 153 * Gets a string describing the delete strategy. 154 * 155 * @return a string describing the delete strategy 156 */ 157 @Override 158 public String toString() { 159 return "FileDeleteStrategy[" + name + "]"; 160 } 161 162 }