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 /** Default Constructor */ 042 ForceFileDeleteStrategy() { 043 super("Force"); 044 } 045 046 /** 047 * Deletes the file object. 048 * <p> 049 * This implementation uses <code>FileUtils.forceDelete()</code> 050 * if the file exists. 051 * </p> 052 * 053 * @param fileToDelete the file to delete, not null 054 * @return Always returns {@code true} 055 * @throws NullPointerException if the file is null 056 * @throws IOException if an error occurs during file deletion 057 */ 058 @Override 059 protected boolean doDelete(final File fileToDelete) throws IOException { 060 FileUtils.forceDelete(fileToDelete); 061 return true; 062 } 063 } 064 065 /** 066 * The singleton instance for normal file deletion, which does not permit 067 * the deletion of directories that are not empty. 068 */ 069 public static final FileDeleteStrategy NORMAL = new FileDeleteStrategy("Normal"); 070 071 /** 072 * The singleton instance for forced file deletion, which always deletes, 073 * even if the file represents a non-empty directory. 074 */ 075 public static final FileDeleteStrategy FORCE = new ForceFileDeleteStrategy(); 076 077 /** The name of the strategy. */ 078 private final String name; 079 080 /** 081 * Restricted constructor. 082 * 083 * @param name the name by which the strategy is known 084 */ 085 protected FileDeleteStrategy(final String name) { 086 this.name = name; 087 } 088 089 /** 090 * Deletes the file object, which may be a file or a directory. 091 * If the file does not exist, the method just returns. 092 * <p> 093 * Subclass writers should override {@link #doDelete(File)}, not this method. 094 * </p> 095 * 096 * @param fileToDelete the file to delete, not null 097 * @throws NullPointerException if the file is null 098 * @throws IOException if an error occurs during file deletion 099 */ 100 public void delete(final File fileToDelete) throws IOException { 101 if (fileToDelete.exists() && doDelete(fileToDelete) == false) { 102 throw new IOException("Deletion failed: " + fileToDelete); 103 } 104 } 105 106 /** 107 * Deletes the file object, which may be a file or a directory. 108 * All <code>IOException</code>s are caught and false returned instead. 109 * If the file does not exist or is null, true is returned. 110 * <p> 111 * Subclass writers should override {@link #doDelete(File)}, not this method. 112 * </p> 113 * 114 * @param fileToDelete the file to delete, null returns true 115 * @return true if the file was deleted, or there was no such file 116 */ 117 public boolean deleteQuietly(final File fileToDelete) { 118 if (fileToDelete == null || fileToDelete.exists() == false) { 119 return true; 120 } 121 try { 122 return doDelete(fileToDelete); 123 } catch (final IOException ex) { 124 return false; 125 } 126 } 127 128 /** 129 * Actually deletes the file object, which may be a file or a directory. 130 * <p> 131 * This method is designed for subclasses to override. 132 * The implementation may return either false or an <code>IOException</code> 133 * when deletion fails. The {@link #delete(File)} and {@link #deleteQuietly(File)} 134 * methods will handle either response appropriately. 135 * A check has been made to ensure that the file will exist. 136 * </p> 137 * <p> 138 * This implementation uses {@link File#delete()}. 139 * </p> 140 * 141 * @param fileToDelete the file to delete, exists, not null 142 * @return true if the file was deleted 143 * @throws NullPointerException if the file is null 144 * @throws IOException if an error occurs during file deletion 145 */ 146 protected boolean doDelete(final File fileToDelete) throws IOException { 147 return fileToDelete.delete(); 148 } 149 150 /** 151 * Gets a string describing the delete strategy. 152 * 153 * @return a string describing the delete strategy 154 */ 155 @Override 156 public String toString() { 157 return "FileDeleteStrategy[" + name + "]"; 158 } 159 160}