summaryrefslogtreecommitdiff
path: root/src/main/java/com/keuin/kbackupfabric/operation/backup
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/keuin/kbackupfabric/operation/backup')
-rw-r--r--src/main/java/com/keuin/kbackupfabric/operation/backup/BackupMethod.java44
-rw-r--r--src/main/java/com/keuin/kbackupfabric/operation/backup/IncrementalBackupMethod.java62
-rw-r--r--src/main/java/com/keuin/kbackupfabric/operation/backup/IncrementalBackupUtil.java90
-rw-r--r--src/main/java/com/keuin/kbackupfabric/operation/backup/PrimitiveBackupMethod.java99
-rw-r--r--src/main/java/com/keuin/kbackupfabric/operation/backup/feedback/BackupFeedback.java6
-rw-r--r--src/main/java/com/keuin/kbackupfabric/operation/backup/feedback/IncrementalBackupFeedback.java28
-rw-r--r--src/main/java/com/keuin/kbackupfabric/operation/backup/feedback/PrimitiveBackupFeedback.java30
-rw-r--r--src/main/java/com/keuin/kbackupfabric/operation/backup/method/ConfiguredBackupMethod.java37
-rw-r--r--src/main/java/com/keuin/kbackupfabric/operation/backup/method/ConfiguredIncrementalBackupMethod.java92
-rw-r--r--src/main/java/com/keuin/kbackupfabric/operation/backup/method/ConfiguredPrimitiveBackupMethod.java88
10 files changed, 281 insertions, 295 deletions
diff --git a/src/main/java/com/keuin/kbackupfabric/operation/backup/BackupMethod.java b/src/main/java/com/keuin/kbackupfabric/operation/backup/BackupMethod.java
deleted file mode 100644
index 4e9eb6c..0000000
--- a/src/main/java/com/keuin/kbackupfabric/operation/backup/BackupMethod.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package com.keuin.kbackupfabric.operation.backup;
-
-import com.keuin.kbackupfabric.util.backup.builder.BackupFileNameBuilder;
-import com.keuin.kbackupfabric.util.backup.formatter.BackupFileNameFormatter;
-
-import java.io.IOException;
-
-/**
- * Provide specific backup method, which is implemented statelessly.
- */
-public interface BackupMethod {
-
- /**
- * Perform a backup with given method. The backup will be saved as the given name.
- * Note: real file name depends on the backup type.
- * @param backupName the backup name.
- * @return if the backup operation succeed.
- */
- BackupResult backup(String backupName, String levelPath, String backupSaveDirectory) throws IOException;
-
- boolean restore(String backupName, String levelPath, String backupSaveDirectory) throws IOException;
-
- BackupFileNameBuilder getBackupFileNameBuilder();
-
- BackupFileNameFormatter getBackupFileNameFormatter();
-
- class BackupResult {
- private final boolean success;
- private final long backupSizeBytes;
-
- public BackupResult(boolean success, long backupSizeBytes) {
- this.success = success;
- this.backupSizeBytes = backupSizeBytes;
- }
-
- public boolean isSuccess() {
- return success;
- }
-
- public long getBackupSizeBytes() {
- return backupSizeBytes;
- }
- }
-}
diff --git a/src/main/java/com/keuin/kbackupfabric/operation/backup/IncrementalBackupMethod.java b/src/main/java/com/keuin/kbackupfabric/operation/backup/IncrementalBackupMethod.java
deleted file mode 100644
index 4a87bb3..0000000
--- a/src/main/java/com/keuin/kbackupfabric/operation/backup/IncrementalBackupMethod.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package com.keuin.kbackupfabric.operation.backup;
-
-import com.google.gson.JsonObject;
-import com.keuin.kbackupfabric.util.PrintUtil;
-import com.keuin.kbackupfabric.util.backup.builder.BackupFileNameBuilder;
-import com.keuin.kbackupfabric.util.backup.builder.ObjectTreeBackupFileNameBuilder;
-import com.keuin.kbackupfabric.util.backup.formatter.BackupFileNameFormatter;
-import com.keuin.kbackupfabric.util.backup.formatter.ObjectTreeBackupFileNameFormatter;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.file.Paths;
-import java.time.LocalDateTime;
-
-public class IncrementalBackupMethod implements BackupMethod {
-
- private static final IncrementalBackupMethod INSTANCE = new IncrementalBackupMethod();
-
- public static IncrementalBackupMethod getInstance() {
- return INSTANCE;
- }
-
- @Override
- public BackupResult backup(String backupName, String levelPath, String backupSaveDirectory) throws IOException {
- /*
- 1. Analyze the save directory, to get a json containing md5 values of all files.
- 2. Copy new files which we do not have in our backup repository.
- 3. Save the above json as a backup file. When restoring from this,
- what we have to do is just copy all files back from the repository,
- based on their md5 digests.
- */
-
- boolean success = true;
- // Generate JSON
- JsonObject hashJson = IncrementalBackupUtil.generateDirectoryJsonObject(levelPath);
- // Copy files
- long newFilesSizeBytes = IncrementalBackupUtil.saveNewFiles(backupSaveDirectory, levelPath, hashJson);
- if(newFilesSizeBytes < 0) {
- success = false;
- PrintUtil.error("Failed to copy new files to object tree.");
- }
- // Save JSON tree
- File jsonFile = new File(String.valueOf(Paths.get(backupSaveDirectory, BackupFileNameBuilder.objectTreeBackup().build(LocalDateTime.now(), backupName))));
- // TODO
- return new BackupResult(success, newFilesSizeBytes);
- }
-
- @Override
- public boolean restore(String backupName, String levelPath, String backupSaveDirectory) throws IOException {
- return false;
- }
-
- @Override
- public BackupFileNameBuilder getBackupFileNameBuilder() {
- return null;
- }
-
- @Override
- public BackupFileNameFormatter getBackupFileNameFormatter() {
- return null;
- }
-}
diff --git a/src/main/java/com/keuin/kbackupfabric/operation/backup/IncrementalBackupUtil.java b/src/main/java/com/keuin/kbackupfabric/operation/backup/IncrementalBackupUtil.java
deleted file mode 100644
index f90aef1..0000000
--- a/src/main/java/com/keuin/kbackupfabric/operation/backup/IncrementalBackupUtil.java
+++ /dev/null
@@ -1,90 +0,0 @@
-package com.keuin.kbackupfabric.operation.backup;
-
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
-import com.keuin.kbackupfabric.util.FilesystemUtil;
-import org.apache.commons.codec.digest.DigestUtils;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.file.*;
-import java.util.Map;
-
-public class IncrementalBackupUtil {
- /**
- * Generate a json object representing a directory and its all sub files and directories.
- * @param path path to the directory.
- * @return a json object.
- */
- public static JsonObject generateDirectoryJsonObject(String path) throws IOException {
- JsonObject json = new JsonObject();
- File directory = new File(path);
- if (!(directory.isDirectory() && directory.exists()))
- throw new IOException(String.format("Path %s is not a valid directory.", path));
-
- // Iterate all sub files using BFS.
- try (DirectoryStream<Path> directoryStream = Files.newDirectoryStream(Paths.get(path))) {
- for (Path sub : directoryStream) {
- if (sub.toFile().isFile()) {
- // A sub file
- // Just hash and add it as a string
- try (InputStream is = Files.newInputStream(sub)) {
- String md5 = org.apache.commons.codec.digest.DigestUtils.md5Hex(is);
- json.addProperty(sub.getFileName().toString(), md5);
- }
- } else {
- // A sub directory
- // Search into
- json.addProperty(String.valueOf(sub.getFileName()), sub.toString());
- }
- }
- }
-
- return json;
- }
-
- /**
- * Save new (or modified) files to target path, based on hash json.
- * @param targetSavePath where we should save new files.
- * @param sourcePath where new files come from. This path must be the base directory of given hash json.
- * @param hashJson the json object obtained by calling generateDirectoryJsonObject method.
- * @return total size of new files. If failed, will return -1.
- */
- public static long saveNewFiles(String targetSavePath, String sourcePath, JsonObject hashJson) throws IOException {
- long bytesCopied = 0;
- for (Map.Entry<String, JsonElement> entry : hashJson.entrySet()) {
- String key = entry.getKey();
- JsonElement value = entry.getValue();
- if (value.isJsonPrimitive() && value.getAsJsonPrimitive().isString()) {
- // A sub file
- // key is file name
- // value is file md5
- String md5 = value.getAsJsonPrimitive().getAsString();
- File saveTarget = new File(targetSavePath, md5);
- if (!saveTarget.exists()) {
- // Target file does not exist. We have to copy this to the target.
- File sourceFile = new File(sourcePath, key);
- Files.copy(sourceFile.toPath(), saveTarget.toPath(), StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES);
- try {
- bytesCopied += sourceFile.length();
- } catch (SecurityException ignored) {
- // failed to get the file size. Just ignore this.
- }
- }
- } else if (value.isJsonObject()) {
- // A sub directory
- // key is directory name
- // value is directory json object
- // Go into
- if(!value.isJsonObject())
- throw new IllegalArgumentException(String.format("Hash json contains illegal argument of a directory item: %s -> %s.", key, value));
- Path pathSource = Paths.get(sourcePath, key);
- bytesCopied += saveNewFiles(targetSavePath, pathSource.toString(), value.getAsJsonObject());
- } else {
- throw new IllegalArgumentException(String.format("Hash json contains illegal element: %s -> %s.", key, value));
- }
- }
- return bytesCopied;
- }
-}
diff --git a/src/main/java/com/keuin/kbackupfabric/operation/backup/PrimitiveBackupMethod.java b/src/main/java/com/keuin/kbackupfabric/operation/backup/PrimitiveBackupMethod.java
deleted file mode 100644
index 72e9cdb..0000000
--- a/src/main/java/com/keuin/kbackupfabric/operation/backup/PrimitiveBackupMethod.java
+++ /dev/null
@@ -1,99 +0,0 @@
-package com.keuin.kbackupfabric.operation.backup;
-
-import com.keuin.kbackupfabric.exception.ZipUtilException;
-import com.keuin.kbackupfabric.metadata.BackupMetadata;
-import com.keuin.kbackupfabric.util.FilesystemUtil;
-import com.keuin.kbackupfabric.util.PrintUtil;
-import com.keuin.kbackupfabric.util.ZipUtil;
-import com.keuin.kbackupfabric.util.backup.builder.BackupFileNameBuilder;
-import com.keuin.kbackupfabric.util.backup.formatter.BackupFileNameFormatter;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.file.Paths;
-import java.time.LocalDateTime;
-
-import static org.apache.commons.io.FileUtils.forceDelete;
-
-public class PrimitiveBackupMethod implements BackupMethod {
-
- private static final PrimitiveBackupMethod INSTANCE = new PrimitiveBackupMethod();
- private static int zipLevel = 9;
-
- public static PrimitiveBackupMethod getInstance() {
- return INSTANCE;
- }
-
- @Override
- public BackupResult backup(String backupName, String levelPath, String backupSaveDirectory) throws IOException {
- String backupFileName = BackupFileNameBuilder.primitiveZipBackup().build(LocalDateTime.now(),backupName);
- try {
- BackupMetadata backupMetadata = new BackupMetadata(System.currentTimeMillis(), backupName);
-
- PrintUtil.info(String.format("zip(srcPath=%s, destPath=%s)", levelPath, backupSaveDirectory));
- PrintUtil.info("Compressing level ...");
- ZipUtil.makeBackupZip(levelPath, backupSaveDirectory, backupFileName, backupMetadata, zipLevel);
-
- } catch (ZipUtilException exception) {
- PrintUtil.info("Infinite recursive of directory tree detected, backup was aborted.");
- return new BackupResult(false, 0);
- }
-
- // Get backup file size and return
- return new BackupResult(true, FilesystemUtil.getFileSizeBytes(backupSaveDirectory, backupFileName));
- }
-
- @Override
- public boolean restore(String backupName, String levelDirectory, String backupSaveDirectory) throws IOException {
- // Delete old level
- PrintUtil.info("Server stopped. Deleting old level ...");
- File levelDirFile = new File(levelDirectory);
- long startTime = System.currentTimeMillis();
-
- int failedCounter = 0;
- final int MAX_RETRY_TIMES = 20;
- while (failedCounter < MAX_RETRY_TIMES) {
- System.gc();
- if (!levelDirFile.delete() && levelDirFile.exists()) {
- System.gc();
- forceDelete(levelDirFile); // Try to force delete.
- }
- if (!levelDirFile.exists())
- break;
- ++failedCounter;
- try {
- Thread.sleep(500);
- } catch (InterruptedException ignored) {
- }
- }
- if (levelDirFile.exists()) {
- PrintUtil.error(String.format("Cannot restore: failed to delete old level %s .", levelDirFile.getName()));
- return false;
- }
-
- // TODO: Refactor this to the concrete BackupMethod.
- // Decompress archive
- PrintUtil.info("Decompressing archived level ...");
- ZipUtil.unzip(Paths.get(backupSaveDirectory, backupName).toString(), levelDirectory, false);
- long endTime = System.currentTimeMillis();
- PrintUtil.info(String.format("Restore complete! (%.2fs) Please restart the server manually.", (endTime - startTime) / 1000.0));
- PrintUtil.info("If you want to restart automatically after restoring, please visit the project manual at: https://github.com/keuin/KBackup-Fabric/blob/master/README.md");
-
-// try {
-// Thread.sleep(1000);
-// } catch (InterruptedException ignored) {
-// }
-
- return true;
- }
-
- @Override
- public BackupFileNameBuilder getBackupFileNameBuilder() {
- return BackupFileNameBuilder.primitiveZipBackup();
- }
-
- @Override
- public BackupFileNameFormatter getBackupFileNameFormatter() {
- return BackupFileNameFormatter.primitiveZipBackup();
- }
-}
diff --git a/src/main/java/com/keuin/kbackupfabric/operation/backup/feedback/BackupFeedback.java b/src/main/java/com/keuin/kbackupfabric/operation/backup/feedback/BackupFeedback.java
new file mode 100644
index 0000000..0fe0766
--- /dev/null
+++ b/src/main/java/com/keuin/kbackupfabric/operation/backup/feedback/BackupFeedback.java
@@ -0,0 +1,6 @@
+package com.keuin.kbackupfabric.operation.backup.feedback;
+
+public interface BackupFeedback {
+ String getFeedback();
+ boolean isSuccess();
+}
diff --git a/src/main/java/com/keuin/kbackupfabric/operation/backup/feedback/IncrementalBackupFeedback.java b/src/main/java/com/keuin/kbackupfabric/operation/backup/feedback/IncrementalBackupFeedback.java
new file mode 100644
index 0000000..f39fde6
--- /dev/null
+++ b/src/main/java/com/keuin/kbackupfabric/operation/backup/feedback/IncrementalBackupFeedback.java
@@ -0,0 +1,28 @@
+package com.keuin.kbackupfabric.operation.backup.feedback;
+
+public class IncrementalBackupFeedback implements BackupFeedback {
+ private final boolean success;
+ private final int newFilesAdded;
+
+ public IncrementalBackupFeedback(boolean success, int newFilesAdded) {
+ this.success = success;
+ this.newFilesAdded = newFilesAdded;
+ }
+
+ @Override
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public long getNewFilesAdded() {
+ return newFilesAdded;
+ }
+
+ @Override
+ public String getFeedback() {
+ if (success && newFilesAdded >= 0)
+ return String.format("File(s) added: %d.", newFilesAdded);
+ else
+ return "";
+ }
+}
diff --git a/src/main/java/com/keuin/kbackupfabric/operation/backup/feedback/PrimitiveBackupFeedback.java b/src/main/java/com/keuin/kbackupfabric/operation/backup/feedback/PrimitiveBackupFeedback.java
new file mode 100644
index 0000000..3bcd012
--- /dev/null
+++ b/src/main/java/com/keuin/kbackupfabric/operation/backup/feedback/PrimitiveBackupFeedback.java
@@ -0,0 +1,30 @@
+package com.keuin.kbackupfabric.operation.backup.feedback;
+
+import static com.keuin.kbackupfabric.util.backup.BackupFilesystemUtil.getFriendlyFileSizeString;
+
+public class PrimitiveBackupFeedback implements BackupFeedback {
+ private final boolean success;
+ private final long backupSizeBytes;
+
+ public PrimitiveBackupFeedback(boolean success, long backupSizeBytes) {
+ this.success = success;
+ this.backupSizeBytes = backupSizeBytes;
+ }
+
+ @Override
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public long getBackupSizeBytes() {
+ return backupSizeBytes;
+ }
+
+ @Override
+ public String getFeedback() {
+ if (success && backupSizeBytes >= 0)
+ return String.format("File size: %s.", getFriendlyFileSizeString(backupSizeBytes));
+ else
+ return "";
+ }
+}
diff --git a/src/main/java/com/keuin/kbackupfabric/operation/backup/method/ConfiguredBackupMethod.java b/src/main/java/com/keuin/kbackupfabric/operation/backup/method/ConfiguredBackupMethod.java
new file mode 100644
index 0000000..bb80c80
--- /dev/null
+++ b/src/main/java/com/keuin/kbackupfabric/operation/backup/method/ConfiguredBackupMethod.java
@@ -0,0 +1,37 @@
+package com.keuin.kbackupfabric.operation.backup.method;
+
+import com.keuin.kbackupfabric.operation.backup.feedback.BackupFeedback;
+
+import java.io.IOException;
+
+/**
+ * Provide specific backup method, which has been configured with proper settings,
+ * such as saving directory and level path.
+ */
+public interface ConfiguredBackupMethod {
+
+ /**
+ * Perform a backup with given method. The backup will be saved as the given name.
+ * Note: real file name depends on the backup type.
+ *
+ * @return backup result.
+ */
+ BackupFeedback backup() throws IOException;
+
+ boolean restore() throws IOException;
+
+ /**
+ * Create backup save directory and do some essential initialization before the backup process.
+ *
+ * @return false if failed, then the backup process won't proceed.
+ */
+ boolean touch();
+
+ /**
+ * Get the used backup file name.
+ *
+ * @return the file name.
+ */
+ String getBackupFileName();
+
+}
diff --git a/src/main/java/com/keuin/kbackupfabric/operation/backup/method/ConfiguredIncrementalBackupMethod.java b/src/main/java/com/keuin/kbackupfabric/operation/backup/method/ConfiguredIncrementalBackupMethod.java
new file mode 100644
index 0000000..b5d2463
--- /dev/null
+++ b/src/main/java/com/keuin/kbackupfabric/operation/backup/method/ConfiguredIncrementalBackupMethod.java
@@ -0,0 +1,92 @@
+package com.keuin.kbackupfabric.operation.backup.method;
+
+import com.keuin.kbackupfabric.operation.backup.feedback.IncrementalBackupFeedback;
+import com.keuin.kbackupfabric.util.FilesystemUtil;
+import com.keuin.kbackupfabric.util.PrintUtil;
+import com.keuin.kbackupfabric.util.backup.incremental.ObjectCollection;
+import com.keuin.kbackupfabric.util.backup.incremental.ObjectCollectionFactory;
+import com.keuin.kbackupfabric.util.backup.incremental.ObjectCollectionSerializer;
+import com.keuin.kbackupfabric.util.backup.incremental.identifier.Sha256Identifier;
+import com.keuin.kbackupfabric.util.backup.incremental.manager.IncrementalBackupStorageManager;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.HashSet;
+
+public class ConfiguredIncrementalBackupMethod implements ConfiguredBackupMethod {
+
+ private final String backupIndexFileName;
+ private final String levelPath;
+ private final String backupIndexFileSaveDirectory;
+ private final String backupBaseDirectory;
+
+ public ConfiguredIncrementalBackupMethod(String backupIndexFileName, String levelPath, String backupIndexFileSaveDirectory, String backupBaseDirectory) {
+ this.backupIndexFileName = backupIndexFileName;
+ this.levelPath = levelPath;
+ this.backupIndexFileSaveDirectory = backupIndexFileSaveDirectory;
+ this.backupBaseDirectory = backupBaseDirectory;
+ }
+
+ @Override
+ public IncrementalBackupFeedback backup() throws IOException {
+ File levelPathFile = new File(levelPath);
+
+ // construct incremental backup index
+ PrintUtil.info("Hashing files...");
+ ObjectCollection collection = new ObjectCollectionFactory<>(Sha256Identifier.getFactory())
+ .fromDirectory(levelPathFile, new HashSet<>(Arrays.asList("session.lock", "kbackup_metadata")));
+
+ // update storage
+ PrintUtil.info("Copying files...");
+ IncrementalBackupStorageManager storageManager = new IncrementalBackupStorageManager(Paths.get(backupBaseDirectory));
+ int filesAdded = storageManager.addObjectCollection(collection, levelPathFile);
+
+ // save index file
+ PrintUtil.info("Saving index file...");
+ ObjectCollectionSerializer.toFile(collection, new File(backupIndexFileSaveDirectory, backupIndexFileName));
+
+ // return result
+ PrintUtil.info("Incremental backup finished.");
+ return new IncrementalBackupFeedback(filesAdded >= 0, filesAdded);
+ }
+
+ @Override
+ public boolean restore() throws IOException {
+ // load collection
+ PrintUtil.info("Loading file list...");
+ ObjectCollection collection = ObjectCollectionSerializer.fromFile(
+ new File(backupIndexFileSaveDirectory, backupIndexFileName)
+ );
+
+ // delete old level
+ File levelPathFile = new File(levelPath);
+ PrintUtil.info("Deleting old level...");
+ if (!FilesystemUtil.forceDeleteDirectory(levelPathFile)) {
+ PrintUtil.info("Failed to delete old level!");
+ return false;
+ }
+
+ // restore file
+ PrintUtil.info("Copying files...");
+ IncrementalBackupStorageManager storageManager = new IncrementalBackupStorageManager(Paths.get(backupBaseDirectory));
+ int restoreObjectCount = storageManager.restoreObjectCollection(collection, levelPathFile);
+
+ PrintUtil.info(String.format("%d file(s) restored.", restoreObjectCount));
+ return true;
+ }
+
+ @Override
+ public boolean touch() {
+ File baseDirectoryFile = new File(backupBaseDirectory);
+ return baseDirectoryFile.isDirectory() || baseDirectoryFile.mkdir();
+ }
+
+ @Override
+ public String getBackupFileName() {
+ return backupIndexFileName;
+ }
+
+
+}
diff --git a/src/main/java/com/keuin/kbackupfabric/operation/backup/method/ConfiguredPrimitiveBackupMethod.java b/src/main/java/com/keuin/kbackupfabric/operation/backup/method/ConfiguredPrimitiveBackupMethod.java
new file mode 100644
index 0000000..1c3c9f6
--- /dev/null
+++ b/src/main/java/com/keuin/kbackupfabric/operation/backup/method/ConfiguredPrimitiveBackupMethod.java
@@ -0,0 +1,88 @@
+package com.keuin.kbackupfabric.operation.backup.method;
+
+import com.keuin.kbackupfabric.exception.ZipUtilException;
+import com.keuin.kbackupfabric.metadata.BackupMetadata;
+import com.keuin.kbackupfabric.operation.backup.feedback.PrimitiveBackupFeedback;
+import com.keuin.kbackupfabric.util.FilesystemUtil;
+import com.keuin.kbackupfabric.util.PrintUtil;
+import com.keuin.kbackupfabric.util.ZipUtil;
+import com.keuin.kbackupfabric.util.backup.BackupFilesystemUtil;
+import com.keuin.kbackupfabric.util.backup.BackupNameTimeFormatter;
+import com.keuin.kbackupfabric.util.backup.name.PrimitiveBackupFileNameEncoder;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Paths;
+import java.time.LocalDateTime;
+
+public class ConfiguredPrimitiveBackupMethod implements ConfiguredBackupMethod {
+
+ private final String backupFileName;
+ private final String levelPath;
+ private final String backupSavePath;
+
+ public ConfiguredPrimitiveBackupMethod(String backupFileName, String levelPath, String backupSavePath) {
+ this.backupFileName = backupFileName;
+ this.levelPath = levelPath;
+ this.backupSavePath = backupSavePath;
+ }
+
+ @Deprecated
+ private String getBackupFileName(LocalDateTime time, String backupName) {
+ String timeString = BackupNameTimeFormatter.localDateTimeToString(time);
+ return String.format("%s%s_%s%s", BackupFilesystemUtil.getBackupFileNamePrefix(), timeString, backupName, ".zip");
+ }
+
+ @Override
+ public PrimitiveBackupFeedback backup() throws IOException {
+ try {
+ String customBackupName = new PrimitiveBackupFileNameEncoder().decode(backupFileName).customName;
+ BackupMetadata backupMetadata = new BackupMetadata(System.currentTimeMillis(), customBackupName);
+ PrintUtil.info(String.format("zip(srcPath=%s, destPath=%s)", levelPath, backupSavePath));
+ PrintUtil.info("Compressing level ...");
+ ZipUtil.makeBackupZip(levelPath, backupSavePath, backupFileName, backupMetadata);
+ } catch (ZipUtilException exception) {
+ PrintUtil.info("Infinite recursive of directory tree detected, backup was aborted.");
+ return new PrimitiveBackupFeedback(false, 0);
+ }
+
+ // Get backup file size and return
+ return new PrimitiveBackupFeedback(true, FilesystemUtil.getFileSizeBytes(backupSavePath, backupFileName));
+ }
+
+ @Override
+ public boolean restore() throws IOException {
+ // Delete old level
+ PrintUtil.info("Server stopped. Deleting old level ...");
+ if (!FilesystemUtil.forceDeleteDirectory(new File(levelPath))) {
+ PrintUtil.info("Failed to delete old level!");
+ return false;
+ }
+
+
+ // TODO: Refactor this to the concrete BackupMethod.
+ // Decompress archive
+ PrintUtil.info("Decompressing archived level ...");
+ ZipUtil.unzip(Paths.get(backupSavePath, backupFileName).toString(), levelPath, false);
+
+
+// try {
+// Thread.sleep(1000);
+// } catch (InterruptedException ignored) {
+// }
+
+ return true;
+ }
+
+ @Override
+ public boolean touch() {
+ File backupSaveDirectoryFile = new File(backupSavePath);
+ return backupSaveDirectoryFile.isDirectory() || backupSaveDirectoryFile.mkdir();
+ }
+
+ @Override
+ public String getBackupFileName() {
+ return backupFileName;
+ }
+
+}