001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.io; 018 019import java.io.File; 020import java.io.IOException; 021 022/** 023 * Strategy for deleting files. 024 * <p> 025 * There is more than one way to delete a file. 026 * You may want to limit access to certain directories, to only delete 027 * directories if they are empty, or maybe to force deletion. 028 * </p> 029 * <p> 030 * This class captures the strategy to use and is designed for user subclassing. 031 * </p> 032 * 033 * @since 1.3 034 */ 035public class FileDeleteStrategy { 036 037 /** 038 * Force file deletion strategy. 039 */ 040 static class ForceFileDeleteStrategy extends FileDeleteStrategy { 041 042 /** Default Constructor */ 043 ForceFileDeleteStrategy() { 044 super("Force"); 045 } 046 047 /** 048 * Deletes the file object. 049 * <p> 050 * This implementation uses {@code FileUtils.forceDelete()} 051 * if the file exists. 052 * </p> 053 * 054 * @param fileToDelete the file to delete, not null 055 * @return Always returns {@code true} 056 * @throws NullPointerException if the file is null 057 * @throws IOException if an error occurs during file deletion 058 */ 059 @Override 060 protected boolean doDelete(final File fileToDelete) throws IOException { 061 FileUtils.forceDelete(fileToDelete); 062 return true; 063 } 064 } 065 066 /** 067 * The singleton instance for normal file deletion, which does not permit 068 * the deletion of directories that are not empty. 069 */ 070 public static final FileDeleteStrategy NORMAL = new FileDeleteStrategy("Normal"); 071 072 /** 073 * The singleton instance for forced file deletion, which always deletes, 074 * even if the file represents a non-empty directory. 075 */ 076 public static final FileDeleteStrategy FORCE = new ForceFileDeleteStrategy(); 077 078 /** The name of the strategy. */ 079 private final String name; 080 081 /** 082 * Restricted constructor. 083 * 084 * @param name the name by which the strategy is known 085 */ 086 protected FileDeleteStrategy(final String name) { 087 this.name = name; 088 } 089 090 /** 091 * Deletes the file object, which may be a file or a directory. 092 * If the file does not exist, the method just returns. 093 * <p> 094 * Subclass writers should override {@link #doDelete(File)}, not this method. 095 * </p> 096 * 097 * @param fileToDelete the file to delete, not null 098 * @throws NullPointerException if the file is null 099 * @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}