diff --git a/src/main/java/org/apache/maven/plugins/clean/CleanMojo.java b/src/main/java/org/apache/maven/plugins/clean/CleanMojo.java index afc0df4..4f77c00 100644 --- a/src/main/java/org/apache/maven/plugins/clean/CleanMojo.java +++ b/src/main/java/org/apache/maven/plugins/clean/CleanMojo.java @@ -186,8 +186,8 @@ public class CleanMojo extends AbstractMojo { * should usually reside on the same volume. The exact conditions are system dependant though, but if an atomic * move is not supported, the standard deletion mechanism will be used. * - * @since 3.2 * @see #fast + * @since 3.2 */ @Parameter(property = "maven.clean.fastDir") private File fastDir; @@ -199,8 +199,8 @@ public class CleanMojo extends AbstractMojo { * the actual file deletion should be started in the background when the session ends (this should only be used * when maven is embedded in a long running process). * - * @since 3.2 * @see #fast + * @since 3.2 */ @Parameter(property = "maven.clean.fastMode", defaultValue = FAST_MODE_BACKGROUND) private String fastMode; diff --git a/src/main/java/org/apache/maven/plugins/clean/Cleaner.java b/src/main/java/org/apache/maven/plugins/clean/Cleaner.java index 97ef594..f5c25d2 100644 --- a/src/main/java/org/apache/maven/plugins/clean/Cleaner.java +++ b/src/main/java/org/apache/maven/plugins/clean/Cleaner.java @@ -56,48 +56,43 @@ class Cleaner { */ private final MavenSession session; - private final Logger logDebug; - - private final Logger logInfo; - - private final Logger logVerbose; - - private final Logger logWarn; - private final File fastDir; private final String fastMode; + private final boolean verbose; + + private Log log; + /** * Creates a new cleaner. - * @param log The logger to use, may be null to disable logging. - * @param verbose Whether to perform verbose logging. - * @param fastMode The fast deletion mode + * + * @param session The Maven session to be used. + * @param log The logger to use. + * @param verbose Whether to perform verbose logging. + * @param fastDir The explicit configured directory or to be deleted in fast mode. + * @param fastMode The fast deletion mode. */ Cleaner(MavenSession session, final Log log, boolean verbose, File fastDir, String fastMode) { - logDebug = (log == null || !log.isDebugEnabled()) ? null : log::debug; - - logInfo = (log == null || !log.isInfoEnabled()) ? null : log::info; - - logWarn = (log == null || !log.isWarnEnabled()) ? null : log::warn; - - logVerbose = verbose ? logInfo : logDebug; - this.session = session; + // This can't be null as the Cleaner gets it from the CleanMojo which gets it from AbstractMojo class, where it + // is never null. + this.log = log; this.fastDir = fastDir; this.fastMode = fastMode; + this.verbose = verbose; } /** * Deletes the specified directories and its contents. * - * @param basedir The directory to delete, must not be null. Non-existing directories will be silently - * ignored. - * @param selector The selector used to determine what contents to delete, may be null to delete - * everything. + * @param basedir The directory to delete, must not be null. Non-existing directories will be silently + * ignored. + * @param selector The selector used to determine what contents to delete, may be null to delete + * everything. * @param followSymlinks Whether to follow symlinks. - * @param failOnError Whether to abort with an exception in case a selected file/directory could not be deleted. - * @param retryOnError Whether to undertake additional delete attempts in case the first attempt failed. + * @param failOnError Whether to abort with an exception in case a selected file/directory could not be deleted. + * @param retryOnError Whether to undertake additional delete attempts in case the first attempt failed. * @throws IOException If a file/directory could not be deleted and failOnError is true. */ public void delete( @@ -105,16 +100,16 @@ public void delete( throws IOException { if (!basedir.isDirectory()) { if (!basedir.exists()) { - if (logDebug != null) { - logDebug.log("Skipping non-existing directory " + basedir); + if (log.isDebugEnabled()) { + log.debug("Skipping non-existing directory " + basedir); } return; } throw new IOException("Invalid base directory " + basedir); } - if (logInfo != null) { - logInfo.log("Deleting " + basedir + (selector != null ? " (" + selector + ")" : "")); + if (log.isInfoEnabled()) { + log.info("Deleting " + basedir + (selector != null ? " (" + selector + ")" : "")); } File file = followSymlinks ? basedir : basedir.getCanonicalFile(); @@ -148,9 +143,8 @@ private boolean fastDelete(File baseDirFile) { throw e; } } catch (IOException e) { - if (logDebug != null) { - // TODO: this Logger interface cannot log exceptions and needs refactoring - logDebug.log("Unable to fast delete directory: " + e); + if (log.isDebugEnabled()) { + log.debug("Unable to fast delete directory: ", e); } return false; } @@ -161,10 +155,11 @@ private boolean fastDelete(File baseDirFile) { Files.createDirectories(fastDir); } } catch (IOException e) { - if (logDebug != null) { - // TODO: this Logger interface cannot log exceptions and needs refactoring - logDebug.log("Unable to fast delete directory as the path " + fastDir - + " does not point to a directory or cannot be created: " + e); + if (log.isDebugEnabled()) { + log.debug( + "Unable to fast delete directory as the path " + fastDir + + " does not point to a directory or cannot be created: ", + e); } return false; } @@ -180,9 +175,8 @@ private boolean fastDelete(File baseDirFile) { BackgroundCleaner.delete(this, tmpDir.toFile(), fastMode); return true; } catch (IOException e) { - if (logDebug != null) { - // TODO: this Logger interface cannot log exceptions and needs refactoring - logDebug.log("Unable to fast delete directory: " + e); + if (log.isDebugEnabled()) { + log.debug("Unable to fast delete directory: ", e); } return false; } @@ -191,15 +185,15 @@ private boolean fastDelete(File baseDirFile) { /** * Deletes the specified file or directory. * - * @param file The file/directory to delete, must not be null. If followSymlinks is - * false, it is assumed that the parent file is canonical. - * @param pathname The relative pathname of the file, using {@link File#separatorChar}, must not be - * null. - * @param selector The selector used to determine what contents to delete, may be null to delete - * everything. + * @param file The file/directory to delete, must not be null. If followSymlinks is + * false, it is assumed that the parent file is canonical. + * @param pathname The relative pathname of the file, using {@link File#separatorChar}, must not be + * null. + * @param selector The selector used to determine what contents to delete, may be null to delete + * everything. * @param followSymlinks Whether to follow symlinks. - * @param failOnError Whether to abort with an exception in case a selected file/directory could not be deleted. - * @param retryOnError Whether to undertake additional delete attempts in case the first attempt failed. + * @param failOnError Whether to abort with an exception in case a selected file/directory could not be deleted. + * @param retryOnError Whether to undertake additional delete attempts in case the first attempt failed. * @return The result of the cleaning, never null. * @throws IOException If a file/directory could not be deleted and failOnError is true. */ @@ -229,24 +223,30 @@ private Result delete( child, prefix + filename, selector, followSymlinks, failOnError, retryOnError)); } } - } else if (logDebug != null) { - logDebug.log("Not recursing into symlink " + file); + } else if (log.isDebugEnabled()) { + log.debug("Not recursing into symlink " + file); } - } else if (logDebug != null) { - logDebug.log("Not recursing into directory without included files " + file); + } else if (log.isDebugEnabled()) { + log.debug("Not recursing into directory without included files " + file); } } if (!result.excluded && (selector == null || selector.isSelected(pathname))) { - if (logVerbose != null) { - if (isDirectory) { - logVerbose.log("Deleting directory " + file); - } else if (file.exists()) { - logVerbose.log("Deleting file " + file); - } else { - logVerbose.log("Deleting dangling symlink " + file); - } + String logmessage; + if (isDirectory) { + logmessage = "Deleting directory " + file; + } else if (file.exists()) { + logmessage = "Deleting file " + file; + } else { + logmessage = "Deleting dangling symlink " + file; + } + + if (verbose && log.isInfoEnabled()) { + log.info(logmessage); + } else if (log.isDebugEnabled()) { + log.debug(logmessage); } + result.failures += delete(file, failOnError, retryOnError); } else { result.excluded = true; @@ -266,8 +266,8 @@ private boolean isSymbolicLink(Path path) throws IOException { * Deletes the specified file, directory. If the path denotes a symlink, only the link is removed, its target is * left untouched. * - * @param file The file/directory to delete, must not be null. - * @param failOnError Whether to abort with an exception in case the file/directory could not be deleted. + * @param file The file/directory to delete, must not be null. + * @param failOnError Whether to abort with an exception in case the file/directory could not be deleted. * @param retryOnError Whether to undertake additional delete attempts in case the first attempt failed. * @return 0 if the file was deleted, 1 otherwise. * @throws IOException If a file/directory could not be deleted and failOnError is true. @@ -299,8 +299,8 @@ private int delete(File file, boolean failOnError, boolean retryOnError) throws if (failOnError) { throw new IOException("Failed to delete " + file); } else { - if (logWarn != null) { - logWarn.log("Failed to delete " + file); + if (log.isWarnEnabled()) { + log.warn("Failed to delete " + file); } return 1; } @@ -322,27 +322,24 @@ public void update(Result result) { } } - private interface Logger { - - void log(CharSequence message); - } - private static class BackgroundCleaner extends Thread { + private static final int NEW = 0; + private static final int RUNNING = 1; + private static final int STOPPED = 2; private static BackgroundCleaner instance; - private final Deque filesToDelete = new ArrayDeque<>(); - private final Cleaner cleaner; - private final String fastMode; - - private static final int NEW = 0; - private static final int RUNNING = 1; - private static final int STOPPED = 2; - private int status = NEW; + private BackgroundCleaner(Cleaner cleaner, File dir, String fastMode) { + super("mvn-background-cleaner"); + this.cleaner = cleaner; + this.fastMode = fastMode; + init(cleaner.fastDir, dir); + } + public static void delete(Cleaner cleaner, File dir, String fastMode) { synchronized (BackgroundCleaner.class) { if (instance == null || !instance.doDelete(dir)) { @@ -359,13 +356,6 @@ static void sessionEnd() { } } - private BackgroundCleaner(Cleaner cleaner, File dir, String fastMode) { - super("mvn-background-cleaner"); - this.cleaner = cleaner; - this.fastMode = fastMode; - init(cleaner.fastDir, dir); - } - public void run() { while (true) { File basedir = pollNext(); @@ -450,8 +440,8 @@ synchronized void doSessionEnd() { } if (!FAST_MODE_DEFER.equals(fastMode)) { try { - if (cleaner.logInfo != null) { - cleaner.logInfo.log("Waiting for background file deletion"); + if (cleaner.log.isInfoEnabled()) { + cleaner.log.info("Waiting for background file deletion"); } while (status != STOPPED) { wait();