1
0

M3-AP-007: Startvalidierung für Quellordner testbar gemacht

This commit is contained in:
2026-04-01 22:41:10 +02:00
parent 1b974db321
commit 092e83340f
2 changed files with 223 additions and 6 deletions

View File

@@ -14,11 +14,57 @@ import java.util.List;
* Performs mandatory field checks, numeric range validation, URI scheme validation,
* and basic path existence checks. Throws {@link InvalidStartConfigurationException}
* if any validation rule fails.
* <p>
* M3/AP-007: Supports injected source folder validation for testability
* (allows mocking of platform-dependent filesystem checks).
*/
public class StartConfigurationValidator {
private static final Logger LOG = LogManager.getLogger(StartConfigurationValidator.class);
/**
* Abstraction for source folder existence, type, and readability checks.
* <p>
* Separates filesystem operations from validation logic to enable
* platform-independent unit testing (mocking) of readability edge cases.
* <p>
* Implementation note: The default implementation uses {@code java.nio.file.Files}
* static methods directly; tests can substitute alternative implementations.
*/
@FunctionalInterface
public interface SourceFolderChecker {
/**
* Checks source folder and returns validation error message, or null if valid.
* <p>
* Checks (in order):
* 1. Folder exists
* 2. Is a directory
* 3. Is readable
*
* @param path the source folder path
* @return error message string, or null if all checks pass
*/
String checkSourceFolder(Path path);
}
private final SourceFolderChecker sourceFolderChecker;
/**
* Creates a validator with the default source folder checker (NIO-based).
*/
public StartConfigurationValidator() {
this(new DefaultSourceFolderChecker());
}
/**
* Creates a validator with a custom source folder checker (primarily for testing).
*
* @param sourceFolderChecker the checker to use (must not be null)
*/
public StartConfigurationValidator(SourceFolderChecker sourceFolderChecker) {
this.sourceFolderChecker = sourceFolderChecker;
}
/**
* Validates the given configuration.
* <p>
@@ -66,12 +112,9 @@ public class StartConfigurationValidator {
errors.add("- source.folder: must not be null");
return;
}
if (!Files.exists(sourceFolder)) {
errors.add("- source.folder: path does not exist: " + sourceFolder);
} else if (!Files.isDirectory(sourceFolder)) {
errors.add("- source.folder: path is not a directory: " + sourceFolder);
} else if (!Files.isReadable(sourceFolder)) {
errors.add("- source.folder: directory is not readable: " + sourceFolder);
String checkError = sourceFolderChecker.checkSourceFolder(sourceFolder);
if (checkError != null) {
errors.add(checkError);
}
}
@@ -197,4 +240,29 @@ public class StartConfigurationValidator {
// If it doesn't exist yet, that's acceptable - we don't auto-create
}
}
/**
* Default NIO-based implementation of {@link SourceFolderChecker}.
* <p>
* Uses {@code java.nio.file.Files} static methods to check existence, type, and readability.
* <p>
* M3/AP-007: This separation allows unit tests to inject alternative implementations
* that control the outcome of readability checks without relying on actual filesystem
* permissions (which are platform-dependent).
*/
private static class DefaultSourceFolderChecker implements SourceFolderChecker {
@Override
public String checkSourceFolder(Path path) {
if (!Files.exists(path)) {
return "- source.folder: path does not exist: " + path;
}
if (!Files.isDirectory(path)) {
return "- source.folder: path is not a directory: " + path;
}
if (!Files.isReadable(path)) {
return "- source.folder: directory is not readable: " + path;
}
return null; // All checks passed
}
}
}