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