org.apache.rocketmq.shaded.ch.qos.logback.core.rolling.helper.RenameUtil Maven / Gradle / Ivy
/**
* Logback: the reliable, generic, fast and flexible logging framework.
* Copyright (C) 1999-2015, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
* the Eclipse Foundation
*
* or (per the licensee's choosing)
*
* under the terms of the GNU Lesser General Public License version 2.1
* as published by the Free Software Foundation.
*/
package org.apache.rocketmq.shaded.ch.qos.logback.core.rolling.helper;
import java.io.File;
import org.apache.rocketmq.shaded.ch.qos.logback.core.CoreConstants;
import org.apache.rocketmq.shaded.ch.qos.logback.core.rolling.RollingFileAppender;
import org.apache.rocketmq.shaded.ch.qos.logback.core.rolling.RolloverFailure;
import org.apache.rocketmq.shaded.ch.qos.logback.core.spi.ContextAwareBase;
import org.apache.rocketmq.shaded.ch.qos.logback.core.util.EnvUtil;
import org.apache.rocketmq.shaded.ch.qos.logback.core.util.FileUtil;
/**
* Utility class to help solving problems encountered while renaming files.
*
* @author Ceki Gulcu
*/
public class RenameUtil extends ContextAwareBase {
static String RENAMING_ERROR_URL = CoreConstants.CODES_URL + "#renamingError";
/**
* A relatively robust file renaming method which in case of failure due to
* src and target being on different volumes, falls back onto
* renaming by copying.
*
* @param src
* @param target
* @throws RolloverFailure
*/
public void rename(String src, String target) throws RolloverFailure {
if (src.equals(target)) {
addWarn("Source and target files are the same [" + src + "]. Skipping.");
return;
}
File srcFile = new File(src);
if (srcFile.exists()) {
File targetFile = new File(target);
createMissingTargetDirsIfNecessary(targetFile);
addInfo("Renaming file [" + srcFile + "] to [" + targetFile + "]");
boolean result = srcFile.renameTo(targetFile);
if (!result) {
addWarn("Failed to rename file [" + srcFile + "] as [" + targetFile + "].");
Boolean areOnDifferentVolumes = areOnDifferentVolumes(srcFile, targetFile);
if (Boolean.TRUE.equals(areOnDifferentVolumes)) {
addWarn("Detected different file systems for source [" + src + "] and target [" + target + "]. Attempting rename by copying.");
renameByCopying(src, target);
return;
} else {
addWarn("Please consider leaving the [file] option of " + RollingFileAppender.class.getSimpleName() + " empty.");
addWarn("See also " + RENAMING_ERROR_URL);
}
}
} else {
throw new RolloverFailure("File [" + src + "] does not exist.");
}
}
/**
* Attempts to determine whether both files are on different volumes. Returns true if we could determine that
* the files are on different volumes. Returns false otherwise or if an error occurred while doing the check.
*
* @param srcFile
* @param targetFile
* @return true if on different volumes, false otherwise or if an error occurred
*/
Boolean areOnDifferentVolumes(File srcFile, File targetFile) throws RolloverFailure {
if (!EnvUtil.isJDK7OrHigher())
return false;
// target file is not certain to exist but its parent has to exist given the call hierarchy of this method
File parentOfTarget = targetFile.getAbsoluteFile().getParentFile();
if(parentOfTarget == null) {
addWarn("Parent of target file ["+targetFile+"] is null");
return null;
}
if(!parentOfTarget.exists()) {
addWarn("Parent of target file ["+targetFile+"] does not exist");
return null;
}
try {
boolean onSameFileStore = FileStoreUtil.areOnSameFileStore(srcFile, parentOfTarget);
return !onSameFileStore;
} catch (RolloverFailure rf) {
addWarn("Error while checking file store equality", rf);
return null;
}
}
public void renameByCopying(String src, String target) throws RolloverFailure {
FileUtil fileUtil = new FileUtil(getContext());
fileUtil.copy(src, target);
File srcFile = new File(src);
if (!srcFile.delete()) {
addWarn("Could not delete " + src);
}
}
void createMissingTargetDirsIfNecessary(File toFile) throws RolloverFailure {
boolean result = FileUtil.createMissingParentDirectories(toFile);
if (!result) {
throw new RolloverFailure("Failed to create parent directories for [" + toFile.getAbsolutePath() + "]");
}
}
@Override
public String toString() {
return "c.q.l.co.rolling.helper.RenameUtil";
}
}