From b1ce28ece1af54b6ff2924c91b06a908980cdc15 Mon Sep 17 00:00:00 2001 From: Pasqual Koschmieder Date: Sat, 15 Apr 2023 23:45:12 +0200 Subject: [PATCH] fix: return empty document for non-existent file when parsing from path (#1197) ### Motivation The document api rewrite introduced a breaking change (which affects internals as well) as the `DocumentFactory#read(Path)` (prior `Document#read(Path)`) now throws an exception in case the file does not exist rather than returing a new, empty document. ### Modification Let `DocumentFactory#read(Path)` return a new, empty document in case the file does not exist or is not a file and change the specification of the method to reflect the change. ### Result The `DocumentFactory#read(Path)` method now returns an empty document in case the file does either not exist or is not a regular file. --- .../driver/document/DocumentFactory.java | 5 ++++- .../driver/document/gson/GsonDocumentFactory.java | 13 +++++++++---- .../driver/document/DocumentSerialisationTest.java | 12 ++++++++++++ 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/driver/src/main/java/eu/cloudnetservice/driver/document/DocumentFactory.java b/driver/src/main/java/eu/cloudnetservice/driver/document/DocumentFactory.java index 6ffcedab22..7238a7b34b 100644 --- a/driver/src/main/java/eu/cloudnetservice/driver/document/DocumentFactory.java +++ b/driver/src/main/java/eu/cloudnetservice/driver/document/DocumentFactory.java @@ -62,7 +62,10 @@ public interface DocumentFactory { /** * Parses a document of the factory supported document type from the file at the given path. The given data must be - * the root object of a document in order to work. + * the root object of a document in order to work. Note: if the file at the given does not exist or the given path is + * a directory, this method returns a new, empty document from this factory (as specified by {@link #newDocument()}). + * However, this method invocation will fail in case the current jvm does not have the appropriate privileges that + * would allow it open the file for reading. * * @param path the path to the file to parse. * @return a parsed document from the file at the given path. diff --git a/driver/src/main/java/eu/cloudnetservice/driver/document/gson/GsonDocumentFactory.java b/driver/src/main/java/eu/cloudnetservice/driver/document/gson/GsonDocumentFactory.java index 1e2eb78ce9..5673b4e8ad 100644 --- a/driver/src/main/java/eu/cloudnetservice/driver/document/gson/GsonDocumentFactory.java +++ b/driver/src/main/java/eu/cloudnetservice/driver/document/gson/GsonDocumentFactory.java @@ -80,11 +80,16 @@ private GsonDocumentFactory() { */ @Override public @NonNull Document.Mutable parse(@NonNull Path path) { - try (var stream = Files.newInputStream(path)) { - return this.parse(stream); - } catch (IOException exception) { - throw new DocumentParseException("Unable to parse document from path " + path, exception); + if (Files.exists(path) && Files.isRegularFile(path)) { + try (var stream = Files.newInputStream(path)) { + return this.parse(stream); + } catch (IOException exception) { + throw new DocumentParseException("Unable to parse document from path " + path, exception); + } } + + // in case that the file does not exist just return an empty document + return this.newDocument(); } /** diff --git a/driver/src/test/java/eu/cloudnetservice/driver/document/DocumentSerialisationTest.java b/driver/src/test/java/eu/cloudnetservice/driver/document/DocumentSerialisationTest.java index 1f13e55426..3e93b21721 100644 --- a/driver/src/test/java/eu/cloudnetservice/driver/document/DocumentSerialisationTest.java +++ b/driver/src/test/java/eu/cloudnetservice/driver/document/DocumentSerialisationTest.java @@ -23,8 +23,10 @@ import java.nio.file.Path; import java.util.List; import java.util.Map; +import java.util.UUID; import java.util.stream.Stream; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.CleanupMode; import org.junit.jupiter.api.io.TempDir; import org.junit.jupiter.params.ParameterizedTest; @@ -67,6 +69,16 @@ static Stream serialisationInputSource() { StandardSerialisationStyle.COMPACT)); } + @Test + void testFileReadReturnsNewDocumentIfMissing() { + var targetFile = Path.of("random_test_file_data_" + UUID.randomUUID()); + Assertions.assertFalse(Files.exists(targetFile)); + Assertions.assertFalse(Files.isRegularFile(targetFile)); + + var deserialized = Assertions.assertDoesNotThrow(() -> DocumentFactory.json().parse(targetFile)); + Assertions.assertTrue(deserialized.empty()); + } + @ParameterizedTest @MethodSource("serialisationInputSource") void testFileSerialisation(Document input, SerialisationStyle style) {