Browse Source

Switched ArbitraryDataFile.filePath from String to Path

qdn
CalDescent 3 years ago
parent
commit
51b12567e8
  1. 78
      src/main/java/org/qortal/arbitrary/ArbitraryDataFile.java
  2. 3
      src/main/java/org/qortal/arbitrary/ArbitraryDataFileChunk.java
  3. 4
      src/main/java/org/qortal/arbitrary/ArbitraryDataReader.java
  4. 2
      src/main/java/org/qortal/arbitrary/ArbitraryDataWriter.java

78
src/main/java/org/qortal/arbitrary/ArbitraryDataFile.java

@ -48,7 +48,7 @@ public class ArbitraryDataFile {
FILE_HASH,
TRANSACTION_DATA,
NAME
};
}
private static final Logger LOGGER = LogManager.getLogger(ArbitraryDataFile.class);
@ -56,7 +56,7 @@ public class ArbitraryDataFile {
public static final int CHUNK_SIZE = 1 * 1024 * 1024; // 1MiB
public static int SHORT_DIGEST_LENGTH = 8;
protected String filePath;
protected Path filePath;
protected String hash58;
private ArrayList<ArbitraryDataFileChunk> chunks;
private byte[] secret;
@ -80,8 +80,8 @@ public class ArbitraryDataFile {
this.hash58 = Base58.encode(Crypto.digest(fileContent));
LOGGER.trace(String.format("File digest: %s, size: %d bytes", this.hash58, fileContent.length));
String outputFilePath = getOutputFilePath(this.hash58, true);
File outputFile = new File(outputFilePath);
Path outputFilePath = getOutputFilePath(this.hash58, true);
File outputFile = outputFilePath.toFile();
try (FileOutputStream outputStream = new FileOutputStream(outputFile)) {
outputStream.write(fileContent);
this.filePath = outputFilePath;
@ -104,8 +104,11 @@ public class ArbitraryDataFile {
return ArbitraryDataFile.fromHash58(Base58.encode(hash));
}
public static ArbitraryDataFile fromPath(String path) {
File file = new File(path);
public static ArbitraryDataFile fromPath(Path path) {
if (path == null) {
return null;
}
File file = path.toFile();
if (file.exists()) {
try {
byte[] fileContent = Files.readAllBytes(file.toPath());
@ -113,15 +116,14 @@ public class ArbitraryDataFile {
ArbitraryDataFile arbitraryDataFile = ArbitraryDataFile.fromHash(digest);
// Copy file to data directory if needed
Path filePath = Paths.get(path);
if (Files.exists(filePath) && !arbitraryDataFile.isInBaseDirectory(path)) {
arbitraryDataFile.copyToDataDirectory(filePath);
if (Files.exists(path) && !arbitraryDataFile.isInBaseDirectory(path)) {
arbitraryDataFile.copyToDataDirectory(path);
}
// Or, if it's already in the data directory, we may need to move it
else if (!filePath.equals(arbitraryDataFile.getFilePath())) {
else if (!path.equals(arbitraryDataFile.getFilePath())) {
// Wrong path, so relocate
Path dest = Paths.get(arbitraryDataFile.getFilePath());
FilesystemUtils.moveFile(filePath, dest, true);
Path dest = arbitraryDataFile.getFilePath();
FilesystemUtils.moveFile(path, dest, true);
}
return arbitraryDataFile;
@ -133,7 +135,7 @@ public class ArbitraryDataFile {
}
public static ArbitraryDataFile fromFile(File file) {
return ArbitraryDataFile.fromPath(file.getPath());
return ArbitraryDataFile.fromPath(Paths.get(file.getPath()));
}
private boolean createDataDirectory() {
@ -149,21 +151,21 @@ public class ArbitraryDataFile {
return true;
}
private String copyToDataDirectory(Path sourcePath) {
private Path copyToDataDirectory(Path sourcePath) {
if (this.hash58 == null || this.filePath == null) {
return null;
}
String outputFilePath = getOutputFilePath(this.hash58, true);
Path outputFilePath = getOutputFilePath(this.hash58, true);
sourcePath = sourcePath.toAbsolutePath();
Path destPath = Paths.get(outputFilePath).toAbsolutePath();
Path destPath = outputFilePath.toAbsolutePath();
try {
return Files.copy(sourcePath, destPath, StandardCopyOption.REPLACE_EXISTING).toString();
return Files.copy(sourcePath, destPath, StandardCopyOption.REPLACE_EXISTING);
} catch (IOException e) {
throw new IllegalStateException("Unable to copy file to data directory");
}
}
public static String getOutputFilePath(String hash58, boolean createDirectories) {
public static Path getOutputFilePath(String hash58, boolean createDirectories) {
if (hash58 == null) {
return null;
}
@ -179,20 +181,19 @@ public class ArbitraryDataFile {
throw new IllegalStateException("Unable to create data subdirectory");
}
}
return outputDirectory + File.separator + hash58;
return Paths.get(outputDirectory, hash58);
}
public ValidationResult isValid() {
try {
// Ensure the file exists on disk
Path path = Paths.get(this.filePath);
if (!Files.exists(path)) {
if (!Files.exists(this.filePath)) {
LOGGER.error("File doesn't exist at path {}", this.filePath);
return ValidationResult.FILE_NOT_FOUND;
}
// Validate the file size
long fileSize = Files.size(path);
long fileSize = Files.size(this.filePath);
if (fileSize > MAX_FILE_SIZE) {
LOGGER.error(String.format("ArbitraryDataFile is too large: %d bytes (max size: %d bytes)", fileSize, MAX_FILE_SIZE));
return ArbitraryDataFile.ValidationResult.FILE_TOO_LARGE;
@ -276,7 +277,7 @@ public class ArbitraryDataFile {
File outputFile = new File(outputPath.toString());
try (BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(outputFile))) {
for (ArbitraryDataFileChunk chunk : this.chunks) {
File sourceFile = new File(chunk.filePath);
File sourceFile = chunk.filePath.toFile();
BufferedInputStream in = new BufferedInputStream(new FileInputStream(sourceFile));
byte[] buffer = new byte[2048];
int inSize;
@ -306,13 +307,12 @@ public class ArbitraryDataFile {
public boolean delete() {
// Delete the complete file
// ... but only if it's inside the Qortal data or temp directory
Path path = Paths.get(this.filePath);
if (FilesystemUtils.pathInsideDataOrTempPath(path)) {
if (Files.exists(path)) {
if (FilesystemUtils.pathInsideDataOrTempPath(this.filePath)) {
if (Files.exists(this.filePath)) {
try {
Files.delete(path);
Files.delete(this.filePath);
this.cleanupFilesystem();
LOGGER.debug("Deleted file {}", path.toString());
LOGGER.debug("Deleted file {}", this.filePath);
return true;
} catch (IOException e) {
LOGGER.warn("Couldn't delete DataFileChunk at path {}", this.filePath);
@ -340,11 +340,9 @@ public class ArbitraryDataFile {
}
protected void cleanupFilesystem() {
String path = this.filePath;
// Iterate through two levels of parent directories, and delete if empty
for (int i=0; i<2; i++) {
Path directory = Paths.get(path).getParent().toAbsolutePath();
Path directory = this.filePath.getParent().toAbsolutePath();
try (Stream<Path> files = Files.list(directory)) {
final long count = files.count();
if (count == 0) {
@ -355,14 +353,13 @@ public class ArbitraryDataFile {
} catch (IOException e) {
LOGGER.warn("Unable to count files in directory", e);
}
path = directory.toString();
this.filePath = directory;
}
}
public byte[] getBytes() {
Path path = Paths.get(this.filePath);
try {
return Files.readAllBytes(path);
return Files.readAllBytes(this.filePath);
} catch (IOException e) {
LOGGER.error("Unable to read bytes for file");
return null;
@ -372,15 +369,15 @@ public class ArbitraryDataFile {
/* Helper methods */
private boolean isInBaseDirectory(String filePath) {
Path path = Paths.get(filePath).toAbsolutePath();
private boolean isInBaseDirectory(Path filePath) {
Path path = filePath.toAbsolutePath();
String dataPath = Settings.getInstance().getDataPath();
String basePath = Paths.get(dataPath).toAbsolutePath().toString();
return path.startsWith(basePath);
}
public boolean exists() {
File file = new File(this.filePath);
File file = this.filePath.toFile();
return file.exists();
}
@ -422,9 +419,8 @@ public class ArbitraryDataFile {
}
public long size() {
Path path = Paths.get(this.filePath);
try {
return Files.size(path);
return Files.size(this.filePath);
} catch (IOException e) {
return 0;
}
@ -464,14 +460,14 @@ public class ArbitraryDataFile {
}
private File getFile() {
File file = new File(this.filePath);
File file = this.filePath.toFile();
if (file.exists()) {
return file;
}
return null;
}
public String getFilePath() {
public Path getFilePath() {
return this.filePath;
}

3
src/main/java/org/qortal/arbitrary/ArbitraryDataFileChunk.java

@ -38,10 +38,9 @@ public class ArbitraryDataFileChunk extends ArbitraryDataFile {
return superclassValidationResult;
}
Path path = Paths.get(this.filePath);
try {
// Validate the file size (chunks have stricter limits)
long fileSize = Files.size(path);
long fileSize = Files.size(this.filePath);
if (fileSize > CHUNK_SIZE) {
LOGGER.error(String.format("DataFileChunk is too large: %d bytes (max chunk size: %d bytes)", fileSize, CHUNK_SIZE));
return ValidationResult.FILE_TOO_LARGE;

4
src/main/java/org/qortal/arbitrary/ArbitraryDataReader.java

@ -218,7 +218,7 @@ public class ArbitraryDataReader {
// Load data file directly from the hash
ArbitraryDataFile arbitraryDataFile = ArbitraryDataFile.fromHash58(resourceId);
// Set filePath to the location of the ArbitraryDataFile
this.filePath = Paths.get(arbitraryDataFile.getFilePath());
this.filePath = arbitraryDataFile.getFilePath();
}
private void fetchFromName() throws IllegalStateException, IOException, DataException {
@ -294,7 +294,7 @@ public class ArbitraryDataReader {
throw new IllegalStateException("Unable to validate complete file hash");
}
// Set filePath to the location of the ArbitraryDataFile
this.filePath = Paths.get(arbitraryDataFile.getFilePath());
this.filePath = arbitraryDataFile.getFilePath();
}
private void decrypt() {

2
src/main/java/org/qortal/arbitrary/ArbitraryDataWriter.java

@ -233,7 +233,7 @@ public class ArbitraryDataWriter {
}
private void split() throws IOException {
this.arbitraryDataFile = ArbitraryDataFile.fromPath(this.filePath.toString());
this.arbitraryDataFile = ArbitraryDataFile.fromPath(this.filePath);
if (this.arbitraryDataFile == null) {
throw new IOException("No file available when trying to split");
}

Loading…
Cancel
Save