summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeuin <[email protected]>2020-04-24 12:21:47 +0800
committerkeuin <[email protected]>2020-04-24 12:21:47 +0800
commit5749fc65909f0ee934d0410406265387157575a1 (patch)
tree111efa8934bae8761372bb7a13227abb75e3dc5a
parentb692a73e039fbdb404ef1219785660dc9eb60e60 (diff)
Refactored pending task using OCP design pattern.
-rw-r--r--README.md3
-rw-r--r--src/main/java/com/keuin/kbackupfabric/KBCommands.java74
-rw-r--r--src/main/java/com/keuin/kbackupfabric/operation/Confirmable.java20
-rw-r--r--src/main/java/com/keuin/kbackupfabric/operation/DeleteOperation.java59
-rw-r--r--src/main/java/com/keuin/kbackupfabric/operation/RestoreOperation.java55
5 files changed, 144 insertions, 67 deletions
diff --git a/README.md b/README.md
index 006d014..e3daa47 100644
--- a/README.md
+++ b/README.md
@@ -19,8 +19,7 @@ commands:
To-Do List:
-- Add /kb prev command for easily select previous backup.
-- Use OCP to refactor pending task.
+- Restoration of player data may not be correct.
- Optimize log output, normal output and op broadcast output.
- More thorough test.
- Enhance ZipUtil for hashing sub-files and generating incremental diff-table. (A:Add, M:Modification, D:Deletion)
diff --git a/src/main/java/com/keuin/kbackupfabric/KBCommands.java b/src/main/java/com/keuin/kbackupfabric/KBCommands.java
index 5302150..8bade76 100644
--- a/src/main/java/com/keuin/kbackupfabric/KBCommands.java
+++ b/src/main/java/com/keuin/kbackupfabric/KBCommands.java
@@ -1,12 +1,11 @@
package com.keuin.kbackupfabric;
import com.keuin.kbackupfabric.data.BackupMetadata;
-import com.keuin.kbackupfabric.data.PendingOperation;
+import com.keuin.kbackupfabric.operation.Confirmable;
import com.keuin.kbackupfabric.util.BackupFilesystemUtil;
import com.keuin.kbackupfabric.util.BackupNameTimeFormatter;
import com.keuin.kbackupfabric.util.PrintUtil;
import com.keuin.kbackupfabric.worker.BackupWorker;
-import com.keuin.kbackupfabric.worker.RestoreWorker;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.context.CommandContext;
import net.minecraft.server.MinecraftServer;
@@ -15,7 +14,6 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.File;
-import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -23,7 +21,6 @@ import java.util.Objects;
import static com.keuin.kbackupfabric.util.BackupFilesystemUtil.*;
import static com.keuin.kbackupfabric.util.PrintUtil.*;
-import static org.apache.commons.io.FileUtils.forceDelete;
public final class KBCommands {
@@ -34,7 +31,7 @@ public final class KBCommands {
private static final Logger LOGGER = LogManager.getLogger();
private static final List<String> backupNameList = new ArrayList<>(); // index -> backupName
- private static PendingOperation pendingOperation = null;
+ private static Confirmable pendingOperation = null;
/**
* Print the help menu.
@@ -112,9 +109,9 @@ public final class KBCommands {
}
// Update pending task
- pendingOperation = PendingOperation.deleteOperation(backupName);
+ pendingOperation = Confirmable.createDeleteOperation(context, backupName);
- msgWarn(context, String.format("DELETION WARNING: The deletion is irreversible! You will lose the backup %s permanently. Use /kb confirm to start or /kb cancel to abort.", pendingOperation.getBackupName()), true);
+ msgWarn(context, String.format("DELETION WARNING: The deletion is irreversible! You will lose the backup %s permanently. Use /kb confirm to start or /kb cancel to abort.", backupName), true);
return SUCCESS;
}
@@ -143,9 +140,9 @@ public final class KBCommands {
}
// Update pending task
- pendingOperation = PendingOperation.restoreOperation(backupName);
+ pendingOperation = Confirmable.createRestoreOperation(context, backupName);
- msgWarn(context, String.format("RESET WARNING: You will LOSE YOUR CURRENT WORLD PERMANENTLY! The worlds will be replaced with backup %s . Use /kb confirm to start or /kb cancel to abort.", pendingOperation.getBackupName()), true);
+ msgWarn(context, String.format("RESET WARNING: You will LOSE YOUR CURRENT WORLD PERMANENTLY! The worlds will be replaced with backup %s . Use /kb confirm to start or /kb cancel to abort.", backupName), true);
return SUCCESS;
}
@@ -192,61 +189,9 @@ public final class KBCommands {
msgWarn(context, "Nothing to be confirmed. Please execute /kb restore <backup_name> first.");
return FAILED;
}
-
- MinecraftServer server = context.getSource().getMinecraftServer();
-
- // Restore
- if (pendingOperation.isRestore()) {
- // do restore to backupName
- String backupName = pendingOperation.getBackupName();
- PrintUtil.msgInfo(context, String.format("Restoring to previous world %s ...", backupName), true);
-
- String backupFileName = getBackupFileName(backupName);
- LOGGER.debug("Backup file name: " + backupFileName);
- File backupFile = new File(getBackupSaveDirectory(server), backupFileName);
-
- PrintUtil.msgInfo(context, "Server will shutdown in a few seconds, depended on your world size and the disk speed, the restore progress may take seconds or minutes.", true);
- PrintUtil.msgInfo(context, "Please do not force the server stop, or the level would be broken.", true);
- PrintUtil.msgInfo(context, "After it shuts down, please restart the server manually.", true);
- final int WAIT_SECONDS = 10;
- for (int i = 0; i < WAIT_SECONDS; ++i) {
- try {
- Thread.sleep(1000);
- } catch (InterruptedException ignored) {
- }
- }
- PrintUtil.msgInfo(context, "Shutting down ...", true);
- RestoreWorker.invoke(server, backupFile.getPath(), getLevelPath(server));
- return SUCCESS;
- }
-
- // Delete
- if (pendingOperation.isDelete()) {
- String backupName = pendingOperation.getBackupName();
- String backupFileName = getBackupFileName(backupName);
- LOGGER.info("Deleting backup " + backupName);
- File backupFile = new File(getBackupSaveDirectory(server), backupFileName);
- int tryCounter = 0;
- do {
- if (tryCounter == 5) {
- String msg = "Failed to delete file " + backupFileName;
- LOGGER.error(msg);
- msgErr(context, msg);
- return FAILED;
- }
- try {
- if (!backupFile.delete())
- forceDelete(backupFile);
- } catch (SecurityException | NullPointerException | IOException ignored) {
- }
- ++tryCounter;
- } while (backupFile.exists());
- LOGGER.info("Deleted backup " + backupName);
- msgInfo(context, "Deleted backup " + backupName);
- return SUCCESS;
- }
-
- return SUCCESS; // block compiler's complain.
+ Confirmable confirmable = pendingOperation;
+ pendingOperation = null;
+ return confirmable.confirm() ? SUCCESS : FAILED; // block compiler's complain.
}
/**
@@ -302,7 +247,6 @@ public final class KBCommands {
private static String parseBackupName(CommandContext<ServerCommandSource> context, String userInput) {
try {
- MinecraftServer server = context.getSource().getMinecraftServer();
String backupName = StringArgumentType.getString(context, "backupName");
if (backupName.matches("[0-9]*")) {
diff --git a/src/main/java/com/keuin/kbackupfabric/operation/Confirmable.java b/src/main/java/com/keuin/kbackupfabric/operation/Confirmable.java
new file mode 100644
index 0000000..c8fdd71
--- /dev/null
+++ b/src/main/java/com/keuin/kbackupfabric/operation/Confirmable.java
@@ -0,0 +1,20 @@
+package com.keuin.kbackupfabric.operation;
+
+import com.mojang.brigadier.context.CommandContext;
+import net.minecraft.server.command.ServerCommandSource;
+
+public abstract class Confirmable {
+
+ public static Confirmable createRestoreOperation(CommandContext<ServerCommandSource> context, String backupName) {
+ return new RestoreOperation(context, backupName);
+ }
+
+ public static Confirmable createDeleteOperation(CommandContext<ServerCommandSource> context, String backupName) {
+ return new DeleteOperation(context, backupName);
+ }
+
+ public abstract boolean confirm();
+
+ @Override
+ public abstract String toString();
+}
diff --git a/src/main/java/com/keuin/kbackupfabric/operation/DeleteOperation.java b/src/main/java/com/keuin/kbackupfabric/operation/DeleteOperation.java
new file mode 100644
index 0000000..1e28324
--- /dev/null
+++ b/src/main/java/com/keuin/kbackupfabric/operation/DeleteOperation.java
@@ -0,0 +1,59 @@
+package com.keuin.kbackupfabric.operation;
+
+import com.mojang.brigadier.context.CommandContext;
+import net.minecraft.server.MinecraftServer;
+import net.minecraft.server.command.ServerCommandSource;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.io.File;
+import java.io.IOException;
+
+import static com.keuin.kbackupfabric.util.BackupFilesystemUtil.getBackupFileName;
+import static com.keuin.kbackupfabric.util.BackupFilesystemUtil.getBackupSaveDirectory;
+import static com.keuin.kbackupfabric.util.PrintUtil.msgErr;
+import static com.keuin.kbackupfabric.util.PrintUtil.msgInfo;
+import static org.apache.commons.io.FileUtils.forceDelete;
+
+class DeleteOperation extends Confirmable {
+
+ private static final Logger LOGGER = LogManager.getLogger();
+ private final String backupName;
+ private final CommandContext<ServerCommandSource> context;
+
+ DeleteOperation(CommandContext<ServerCommandSource> context, String backupName) {
+ this.backupName = backupName;
+ this.context = context;
+ }
+
+ @Override
+ public boolean confirm() {
+ MinecraftServer server = context.getSource().getMinecraftServer();
+ String backupFileName = getBackupFileName(backupName);
+ LOGGER.info("Deleting backup " + backupName);
+ File backupFile = new File(getBackupSaveDirectory(server), backupFileName);
+ int tryCounter = 0;
+ do {
+ if (tryCounter == 5) {
+ String msg = "Failed to delete file " + backupFileName;
+ LOGGER.error(msg);
+ msgErr(context, msg);
+ return false;
+ }
+ try {
+ if (!backupFile.delete())
+ forceDelete(backupFile);
+ } catch (SecurityException | NullPointerException | IOException ignored) {
+ }
+ ++tryCounter;
+ } while (backupFile.exists());
+ LOGGER.info("Deleted backup " + backupName);
+ msgInfo(context, "Deleted backup " + backupName);
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("deletion of %s", backupName);
+ }
+}
diff --git a/src/main/java/com/keuin/kbackupfabric/operation/RestoreOperation.java b/src/main/java/com/keuin/kbackupfabric/operation/RestoreOperation.java
new file mode 100644
index 0000000..48dd413
--- /dev/null
+++ b/src/main/java/com/keuin/kbackupfabric/operation/RestoreOperation.java
@@ -0,0 +1,55 @@
+package com.keuin.kbackupfabric.operation;
+
+import com.keuin.kbackupfabric.util.PrintUtil;
+import com.keuin.kbackupfabric.worker.RestoreWorker;
+import com.mojang.brigadier.context.CommandContext;
+import net.minecraft.server.MinecraftServer;
+import net.minecraft.server.command.ServerCommandSource;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.io.File;
+
+import static com.keuin.kbackupfabric.util.BackupFilesystemUtil.*;
+
+class RestoreOperation extends Confirmable {
+
+ private static final Logger LOGGER = LogManager.getLogger();
+ private final String backupName;
+ private final CommandContext<ServerCommandSource> context;
+
+ RestoreOperation(CommandContext<ServerCommandSource> context, String backupName) {
+ this.backupName = backupName;
+ this.context = context;
+ }
+
+ @Override
+ public boolean confirm() {
+ // do restore to backupName
+ MinecraftServer server = context.getSource().getMinecraftServer();
+ PrintUtil.msgInfo(context, String.format("Restoring to previous world %s ...", backupName), true);
+
+ String backupFileName = getBackupFileName(backupName);
+ LOGGER.debug("Backup file name: " + backupFileName);
+ File backupFile = new File(getBackupSaveDirectory(server), backupFileName);
+
+ PrintUtil.msgInfo(context, "Server will shutdown in a few seconds, depended on your world size and the disk speed, the restore progress may take seconds or minutes.", true);
+ PrintUtil.msgInfo(context, "Please do not force the server stop, or the level would be broken.", true);
+ PrintUtil.msgInfo(context, "After it shuts down, please restart the server manually.", true);
+ final int WAIT_SECONDS = 10;
+ for (int i = 0; i < WAIT_SECONDS; ++i) {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException ignored) {
+ }
+ }
+ PrintUtil.msgInfo(context, "Shutting down ...", true);
+ RestoreWorker.invoke(server, backupFile.getPath(), getLevelPath(server));
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("restoration from %s", backupName);
+ }
+}