diff --git a/src/main/java/org/qortal/arbitrary/ArbitraryDataCreatePatch.java b/src/main/java/org/qortal/arbitrary/ArbitraryDataCreatePatch.java index 6d28c455..2e2233fe 100644 --- a/src/main/java/org/qortal/arbitrary/ArbitraryDataCreatePatch.java +++ b/src/main/java/org/qortal/arbitrary/ArbitraryDataCreatePatch.java @@ -3,11 +3,14 @@ package org.qortal.arbitrary; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.qortal.repository.DataException; +import org.qortal.settings.Settings; import org.qortal.utils.FilesystemUtils; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.UUID; public class ArbitraryDataCreatePatch { @@ -18,6 +21,9 @@ public class ArbitraryDataCreatePatch { private byte[] previousSignature; private Path finalPath; + private Path workingPath; + private String identifier; + public ArbitraryDataCreatePatch(Path pathBefore, Path pathAfter, byte[] previousSignature) { this.pathBefore = pathBefore; this.pathAfter = pathAfter; @@ -27,6 +33,7 @@ public class ArbitraryDataCreatePatch { public void create() throws DataException, IOException { try { this.preExecute(); + this.copyFiles(); this.process(); } catch (Exception e) { @@ -45,10 +52,21 @@ public class ArbitraryDataCreatePatch { if (!Files.exists(this.pathBefore) || !Files.exists(this.pathAfter)) { throw new IllegalStateException(String.format("Unable to create patch because at least one path doesn't exist")); } + + this.createRandomIdentifier(); + this.createWorkingDirectory(); } private void postExecute() { + this.cleanupWorkingPath(); + } + private void cleanupWorkingPath() { + try { + FilesystemUtils.safeDeleteDirectory(this.workingPath, true); + } catch (IOException e) { + LOGGER.info("Unable to cleanup working directory"); + } } private void cleanupOnFailure() { @@ -59,6 +77,40 @@ public class ArbitraryDataCreatePatch { } } + private void createRandomIdentifier() { + this.identifier = UUID.randomUUID().toString(); + } + + private void createWorkingDirectory() { + // Use the user-specified temp dir, as it is deterministic, and is more likely to be located on reusable storage hardware + String baseDir = Settings.getInstance().getTempDataPath(); + Path tempDir = Paths.get(baseDir, "patch", this.identifier); + try { + Files.createDirectories(tempDir); + } catch (IOException e) { + throw new IllegalStateException("Unable to create temp directory"); + } + this.workingPath = tempDir; + } + + private void copyFiles() throws IOException { + // When dealing with single files, we need to copy them to a container directory + // in order for the structure to align with the previous revision and therefore + // make comparisons possible. + + if (this.pathAfter.toFile().isFile()) { + // Create a "data" directory within the working directory + Path workingDataPath = Paths.get(this.workingPath.toString(), "data"); + Files.createDirectories(workingDataPath); + // Copy to temp directory + // Filename is currently hardcoded to "data" + String filename = "data"; //this.pathAfter.getFileName().toString(); + Files.copy(this.pathAfter, Paths.get(workingDataPath.toString(), filename)); + // Update pathAfter to point to the new path + this.pathAfter = workingDataPath; + } + } + private void process() throws IOException { ArbitraryDataDiff diff = new ArbitraryDataDiff(this.pathBefore, this.pathAfter, this.previousSignature);