filebot/source/net/filebot/StandardRenameAction.java

213 lines
4.7 KiB
Java
Raw Permalink Normal View History

2014-04-19 02:30:29 -04:00
package net.filebot;
2017-02-17 09:02:20 -05:00
import static java.util.Arrays.*;
import static java.util.stream.Collectors.*;
2019-03-15 03:33:16 -04:00
import static net.filebot.Execute.*;
import static net.filebot.Logging.*;
2016-08-16 15:11:56 -04:00
import static net.filebot.UserFiles.*;
import static net.filebot.util.FileUtilities.*;
2016-07-31 01:36:07 -04:00
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
2016-03-10 11:23:45 -05:00
import java.nio.file.LinkOption;
import java.nio.file.attribute.BasicFileAttributes;
2017-02-17 09:02:20 -05:00
import java.util.List;
import com.sun.jna.Platform;
public enum StandardRenameAction implements RenameAction {
MOVE {
@Override
public File rename(File from, File to) throws Exception {
return moveRename(from, to);
}
},
COPY {
@Override
public File rename(File from, File to) throws Exception {
return copyAs(from, to);
}
},
KEEPLINK {
@Override
public File rename(File from, File to) throws Exception {
2019-02-20 07:48:21 -05:00
// move file
File dest = MOVE.rename(from, to);
2019-02-20 07:48:21 -05:00
// symlink file back into the original location
SYMLINK.rename(dest, from);
2016-08-01 02:02:26 -04:00
return dest;
}
},
SYMLINK {
@Override
public File rename(File from, File to) throws Exception {
2019-02-20 07:48:21 -05:00
return createRelativeSymlink(resolveDestination(from, to), from, true);
}
},
HARDLINK {
@Override
public File rename(File from, File to) throws Exception {
2019-02-20 07:48:21 -05:00
return createHardLinkStructure(resolveDestination(from, to), from);
}
},
CLONE {
2014-08-10 03:11:09 -04:00
@Override
public File rename(File from, File to) throws Exception {
File dest = resolveDestination(from, to);
2014-08-10 03:11:09 -04:00
// clonefile or reflink requires filesystem that supports copy-on-write (e.g. apfs or btrfs)
if (Platform.isMac()) {
// -c copy files using clonefile
2019-03-15 03:33:16 -04:00
system("cp", "-c", "-f", from.getPath(), dest.getPath());
} else {
// --reflink copy files using reflink
system("cp", "--reflink=auto", "--force", from.isDirectory() ? "--recursive" : "--no-target-directory", from.getPath(), dest.getPath());
2016-08-01 02:02:26 -04:00
}
return dest;
}
},
DUPLICATE {
@Override
public File rename(File from, File to) throws Exception {
// try to hardlink
try {
return HARDLINK.rename(from, to);
} catch (Exception e) {
2019-02-20 07:48:21 -05:00
debug.finest(cause(HARDLINK, e));
}
// copy if necessary
return COPY.rename(from, to);
}
},
TEST {
@Override
public File rename(File from, File to) throws IOException {
return resolve(from, to);
}
@Override
public boolean canRevert() {
return false;
}
};
public String getDisplayName() {
switch (this) {
case MOVE:
return "Rename";
case COPY:
return "Copy";
case KEEPLINK:
return "Keeplink";
case SYMLINK:
return "Symlink";
case HARDLINK:
return "Hardlink";
case CLONE:
return "Clone";
2016-11-25 06:37:20 -05:00
case DUPLICATE:
return "Hardlink or Copy";
default:
2016-11-25 06:37:20 -05:00
return "Test";
}
}
public String getDisplayVerb() {
switch (this) {
case MOVE:
return "Moving";
case COPY:
return "Copying";
case KEEPLINK:
return "Moving and symlinking";
case SYMLINK:
return "Symlinking";
case HARDLINK:
return "Hardlinking";
case CLONE:
return "Cloning";
case DUPLICATE:
return "Duplicating";
default:
return "Testing";
}
}
2017-02-17 09:02:20 -05:00
public static List<String> names() {
return stream(values()).map(Enum::name).collect(toList());
}
public static StandardRenameAction forName(String name) {
for (StandardRenameAction action : values()) {
if (action.name().equalsIgnoreCase(name)) {
return action;
}
}
2017-02-17 09:02:20 -05:00
throw new IllegalArgumentException(String.format("%s not in %s", name, names()));
}
2016-03-10 11:23:45 -05:00
public static File revert(File current, File original) throws IOException {
// do nothing if current and original path is exactly the same
if (current.equals(original)) {
return original;
}
2016-03-10 11:23:45 -05:00
// reverse move
if (current.exists() && !original.exists()) {
return moveRename(current, original);
2016-03-10 11:23:45 -05:00
}
BasicFileAttributes currentAttr = Files.readAttributes(current.toPath(), BasicFileAttributes.class, LinkOption.NOFOLLOW_LINKS);
BasicFileAttributes originalAttr = Files.readAttributes(original.toPath(), BasicFileAttributes.class, LinkOption.NOFOLLOW_LINKS);
// reverse symlink
if (currentAttr.isSymbolicLink() && !originalAttr.isSymbolicLink()) {
2016-07-31 01:36:07 -04:00
trash(current);
2016-03-10 11:23:45 -05:00
return original;
}
// reverse keeplink
if (!currentAttr.isSymbolicLink() && originalAttr.isSymbolicLink()) {
2016-07-31 01:36:07 -04:00
trash(original);
return moveRename(current, original);
2016-03-10 11:23:45 -05:00
}
// reverse copy / hardlink
if (currentAttr.isRegularFile() && originalAttr.isRegularFile()) {
2016-07-31 01:36:07 -04:00
trash(current);
2016-03-10 11:23:45 -05:00
return original;
}
// reverse folder copy
if (currentAttr.isDirectory() && originalAttr.isDirectory()) {
2016-07-31 01:36:07 -04:00
trash(original);
return moveRename(current, original);
2016-03-10 11:23:45 -05:00
}
2016-05-15 15:09:30 -04:00
throw new IllegalArgumentException(String.format("Cannot revert file: %s => %s", current, original));
2016-03-10 11:23:45 -05:00
}
}