From b5030f940165b46f76a4b760148cd540e71a22af Mon Sep 17 00:00:00 2001 From: RatzzFatzz Date: Sat, 3 Sep 2022 21:14:07 +0200 Subject: [PATCH] Add config validators --- pom.xml | 14 +- .../AttributeUpdaterKernel.java | 4 +- .../mkvaudiosubtitlechanger/Main.java | 8 +- .../config/Config.java | 145 ++++-------------- .../config/ConfigLoader.java | 103 +++++++++++++ .../config/ValidationResult.java | 11 ++ .../config/validator/BooleanValidator.java | 53 +++++++ .../config/validator/ConfigValidator.java | 84 ++++++++++ .../validator/MkvToolNixPathValidator.java | 23 +++ .../validator/OperatingSystemValidator.java | 28 ++++ .../config/validator/PathValidator.java | 24 +++ .../config/validator/PatternValidator.java | 26 ++++ .../config/validator/SetValidator.java | 90 +++++++++++ .../config/validator/ThreadValidator.java | 20 +++ .../model/ConfigProperty.java | 7 +- .../model/MkvToolNix.java | 4 +- .../validator/BooleanValidatorTest.java | 58 +++++++ .../util/TestUtil.java | 16 ++ 18 files changed, 592 insertions(+), 126 deletions(-) create mode 100644 src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/ConfigLoader.java create mode 100644 src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/ValidationResult.java create mode 100644 src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validator/BooleanValidator.java create mode 100644 src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validator/ConfigValidator.java create mode 100644 src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validator/MkvToolNixPathValidator.java create mode 100644 src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validator/OperatingSystemValidator.java create mode 100644 src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validator/PathValidator.java create mode 100644 src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validator/PatternValidator.java create mode 100644 src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validator/SetValidator.java create mode 100644 src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validator/ThreadValidator.java create mode 100644 src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validator/BooleanValidatorTest.java create mode 100644 src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/util/TestUtil.java diff --git a/pom.xml b/pom.xml index 5ffcf59..8c4c83f 100644 --- a/pom.xml +++ b/pom.xml @@ -117,7 +117,7 @@ org.projectlombok lombok - 1.18.8 + 1.18.24 provided @@ -182,20 +182,26 @@ org.junit.jupiter junit-jupiter-api - 5.4.2 + 5.9.0 test org.junit.jupiter junit-jupiter-engine - 5.4.2 + 5.9.0 test org.mockito mockito-all - 1.9.5 + 1.10.19 + test + + + org.junit.jupiter + junit-jupiter-params + 5.9.0 test diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/AttributeUpdaterKernel.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/AttributeUpdaterKernel.java index 99a7681..a967778 100644 --- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/AttributeUpdaterKernel.java +++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/AttributeUpdaterKernel.java @@ -24,7 +24,7 @@ import java.util.stream.Collectors; @Log4j2 public class AttributeUpdaterKernel { - private final ExecutorService executor = Executors.newFixedThreadPool(Config.getInstance().getThreadCount()); + private final ExecutorService executor = Executors.newFixedThreadPool(Config.getInstance().getThreads()); private final FileCollector collector; private final FileProcessor processor; private final ResultStatistic statistic = new ResultStatistic(); @@ -43,7 +43,7 @@ public class AttributeUpdaterKernel { .map(collector::loadFiles) .flatMap(Collection::stream) .collect(Collectors.toList()); - List files = collector.loadFiles(Config.getInstance().getLibraryPath()).stream() + List files = collector.loadFiles(Config.getInstance().getLibraryPath().getAbsolutePath()).stream() .filter(file -> !excludedFiles.contains(file)) .collect(Collectors.toList()); progressBar.maxHint(files.size()); diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/Main.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/Main.java index 6e26216..eb46bb5 100644 --- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/Main.java +++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/Main.java @@ -1,6 +1,7 @@ package at.pcgamingfreaks.mkvaudiosubtitlechanger; import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.Config; +import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.ConfigLoader; import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.MkvFileCollector; import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.MkvFileProcessor; import lombok.extern.log4j.Log4j2; @@ -8,8 +9,9 @@ import lombok.extern.log4j.Log4j2; @Log4j2 public class Main { public static void main(String[] args) { - Config.getInstance().initConfig(args); - AttributeUpdaterKernel kernel = new AttributeUpdaterKernel(new MkvFileCollector(), new MkvFileProcessor()); - kernel.execute(); + ConfigLoader.initConfig(args); +// Config.getInstance().initConfig(args); +// AttributeUpdaterKernel kernel = new AttributeUpdaterKernel(new MkvFileCollector(), new MkvFileProcessor()); +// kernel.execute(); } } diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/Config.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/Config.java index 5e66832..97f4647 100644 --- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/Config.java +++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/Config.java @@ -5,18 +5,13 @@ import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.MkvToolNix; import at.pcgamingfreaks.mkvaudiosubtitlechanger.util.VersionUtil; import at.pcgamingfreaks.yaml.YAML; import at.pcgamingfreaks.yaml.YamlInvalidContentException; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.SneakyThrows; +import lombok.*; import lombok.extern.log4j.Log4j2; import org.apache.commons.cli.*; import java.io.File; import java.io.IOException; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +import java.util.*; import java.util.function.Function; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; @@ -28,6 +23,8 @@ import static at.pcgamingfreaks.mkvaudiosubtitlechanger.util.LanguageValidatorUt @Log4j2 @Getter +@Setter +@NoArgsConstructor(access = AccessLevel.PRIVATE) public class Config { @Getter(AccessLevel.NONE) CommandLineParser parser = new DefaultParser(); @@ -35,18 +32,18 @@ public class Config { HelpFormatter formatter = new HelpFormatter(); @Getter(AccessLevel.NONE) + @Setter(AccessLevel.NONE) private static Config config = null; private File configPath; - private String libraryPath; - private boolean isSafeMode; - - private int threadCount; - private Pattern includePattern; + private File libraryPath; @Getter(AccessLevel.NONE) - private String mkvToolNixPath; + private File mkvToolNix; - private boolean isWindows; + private int threads; + private Pattern includePattern; + private boolean windows; + private boolean safeMode; private final Set forcedKeywords = new HashSet<>(Arrays.asList("forced", "signs")); private final Set commentaryKeywords = new HashSet<>(Arrays.asList("commentary", "director")); @@ -61,104 +58,6 @@ public class Config { return config; } - public void initConfig(String[] args) throws InvalidConfigException { - ConfigErrors errors = new ConfigErrors(); - CommandLine cmd = null; - Options options = initOptions(); - - try { - cmd = parser.parse(options, args); - if (cmd == null) throw new NullPointerException(); - } catch (ParseException | NullPointerException e) { - formatter.printHelp(106, "java -jar MKVAudioSubtitlesChanger.jar -l ", - "\nParameters:", options, - "\nFeature requests and bug reports: https://github.com/RatzzFatzz/MKVAudioSubtitleChanger/issues"); - System.exit(1); - } - - exitIfHelp(cmd, options); - exitIfVersion(cmd); - - configPath = loadConfigPath(cmd, errors); - libraryPath = loadLibraryPath(cmd, errors); - isSafeMode = cmd.hasOption(SAFE_MODE.prop()); - - try (YAML config = new YAML(configPath)) { - threadCount = loadThreadCount(cmd, config); - includePattern = loadIncludePattern(cmd, config, errors); - mkvToolNixPath = loadMkvToolNixPath(cmd, config, errors); - - isWindows = loadOperatingSystem(); - - loadForcedKeywords(cmd, config); - loadExcludedDirectories(cmd, config); - - attributeConfig = loadAttributeConfig(config, errors); - } catch (IOException | YamlInvalidContentException ignored) {} - - if (errors.hasErrors()) { - throw new InvalidConfigException(errors); - } - } - - private static Options initOptions() { - Options options = new Options(); - options.addOption(optionOf(HELP, "h", false)); - options.addOption(optionOf(VERSION, "v", false)); - options.addOption(optionOf(LIBRARY, "l", true)); - options.addOption(optionOf(MKV_TOOL_NIX, "m", true)); - options.addOption(optionOf(CONFIG_PATH, "c", true)); - options.addOption(optionOf(THREADS, "t", true)); - options.addOption(optionOf(SAFE_MODE, "s", false)); - options.addOption(optionOf(FORCED_KEYWORDS, "k", Option.UNLIMITED_VALUES, false)); - options.addOption(optionOf(EXCLUDE_DIRECTORY, "e", Option.UNLIMITED_VALUES, false)); - options.addOption(optionOf(INCLUDE_PATTERN, "i", true)); - return options; - } - - private void exitIfHelp(CommandLine cmd, Options options) { - if (cmd.hasOption("help")) { - formatter.printHelp(106, "java -jar MKVAudioSubtitlesChanger.jar -l ", - "\nParameters:", options, - "\nFeature requests and bug reports: https://github.com/RatzzFatzz/MKVAudioSubtitleChanger/issues"); - System.exit(0); - } - } - - private void exitIfVersion(CommandLine cmd) { - if (cmd.hasOption(VERSION.prop())) { - System.out.printf("MKV Audio Subtitle Changer Version %s%n", VersionUtil.getVersion()); - System.exit(0); - } - } - - private File loadConfigPath(CommandLine cmd, ConfigErrors errors) { - File configPath = new File(cmd.getOptionValue(CONFIG_PATH.prop(), "config.yaml")); - if (configPath.isFile()) return configPath; - - errors.add("invalid config path"); - return null; - } - - private String loadLibraryPath(CommandLine cmd, ConfigErrors errors) { - if (cmd.hasOption(LIBRARY.prop())) { - File libraryPath = new File(cmd.getOptionValue(LIBRARY.prop())); - if (libraryPath.isFile() || libraryPath.isDirectory()) { - return libraryPath.getAbsolutePath(); - } else { - errors.add("invalid library path"); - } - } else { - errors.add("missing library path"); - } - return null; - } - - private int loadThreadCount(CommandLine cmd, YAML config) { - return cmd.hasOption(THREADS.prop()) - ? Integer.parseInt(cmd.getOptionValue(THREADS.prop())) - : config.getInt(THREADS.prop(), 2); - } private Pattern loadIncludePattern(CommandLine cmd, YAML config, ConfigErrors errors) { try { @@ -218,7 +117,27 @@ public class Config { } public String getPathFor(MkvToolNix exe) { - return mkvToolNixPath.endsWith("/") ? mkvToolNixPath + exe : mkvToolNixPath + "/" + exe; + return mkvToolNix.getAbsolutePath().endsWith("/") ? mkvToolNix.getAbsolutePath() + exe + ".exe" : + mkvToolNix.getAbsolutePath() + "/" + exe + ".exe"; + } + + @Override + public String toString() { + return new StringJoiner(", ", Config.class.getSimpleName() + "[", "]") + .add("parser=" + parser).add("\n") + .add("formatter=" + formatter).add("\n") + .add("configPath=" + configPath).add("\n") + .add("libraryPath=" + libraryPath).add("\n") + .add("isWindows=" + windows).add("\n") + .add("isSafeMode=" + safeMode).add("\n") + .add("forcedKeywords=" + forcedKeywords).add("\n") + .add("commentaryKeywords=" + commentaryKeywords).add("\n") + .add("excludedDirectories=" + excludedDirectories).add("\n") + .add("threadCount=" + threads).add("\n") + .add("includePattern=" + includePattern).add("\n") + .add("mkvToolNixPath='" + mkvToolNix + "'").add("\n") + .add("attributeConfig=" + attributeConfig) + .toString(); } } diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/ConfigLoader.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/ConfigLoader.java new file mode 100644 index 0000000..c7884fc --- /dev/null +++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/ConfigLoader.java @@ -0,0 +1,103 @@ +package at.pcgamingfreaks.mkvaudiosubtitlechanger.config; + +import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.validator.*; +import at.pcgamingfreaks.mkvaudiosubtitlechanger.util.VersionUtil; +import at.pcgamingfreaks.yaml.YAML; +import at.pcgamingfreaks.yaml.YamlInvalidContentException; +import org.apache.commons.cli.*; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Path; +import java.util.List; +import java.util.regex.Pattern; + +import static at.pcgamingfreaks.mkvaudiosubtitlechanger.model.ConfigProperty.*; +import static at.pcgamingfreaks.mkvaudiosubtitlechanger.util.CommandLineOptionsUtil.optionOf; + +public class ConfigLoader { + private static final List> VALIDATORS = List.of( + new PathValidator(CONFIG_PATH, false, Path.of("./").toFile()), + new PathValidator(LIBRARY, true, null), + new ThreadValidator(THREADS, false, 2), + new MkvToolNixPathValidator(MKV_TOOL_NIX, true, Path.of("C:\\Program Files\\MKVToolNix").toFile()), + new BooleanValidator(SAFE_MODE, false), + new OperatingSystemValidator(WINDOWS), + new PatternValidator(INCLUDE_PATTERN, false, Pattern.compile(".*")), + new SetValidator(FORCED_KEYWORDS, false, true), + new SetValidator(COMMENTARY_KEYWORDS, false, true), + new SetValidator(EXCLUDE_DIRECTORY, false, true) + ); + + public static void initConfig(String[] args) throws InvalidConfigException { + CommandLineParser parser = new DefaultParser(); + HelpFormatter formatter = new HelpFormatter(); + ConfigErrors errors = new ConfigErrors(); + CommandLine cmd = null; + Options options = initOptions(); + + try { + cmd = parser.parse(options, args); + if (cmd == null) throw new NullPointerException(); + } catch (ParseException | NullPointerException e) { + formatter.printHelp(106, "java -jar MKVAudioSubtitlesChanger.jar -l ", + "\nParameters:", options, + "\nFeature requests and bug reports: https://github.com/RatzzFatzz/MKVAudioSubtitleChanger/issues"); + System.exit(1); + } + + exitIfHelp(cmd, options, formatter); + exitIfVersion(cmd); + + File configPath = loadConfigPath(cmd, errors); + + try (YAML config = new YAML(configPath)) { + for (ConfigValidator validator : VALIDATORS) { + if (validator.validate(config, cmd).equals(ValidationResult.INVALID)) { + throw new InvalidConfigException(new ConfigErrors()); + } + } + } catch (IOException | YamlInvalidContentException ignored) {} + + System.out.println(Config.getInstance()); + } + + private static Options initOptions() { + Options options = new Options(); + options.addOption(optionOf(HELP, "h", false)); + options.addOption(optionOf(VERSION, "v", false)); + options.addOption(optionOf(LIBRARY, "l", true)); + options.addOption(optionOf(MKV_TOOL_NIX, "m", true)); + options.addOption(optionOf(CONFIG_PATH, "c", true)); + options.addOption(optionOf(THREADS, "t", true)); + options.addOption(optionOf(SAFE_MODE, "s", false)); + options.addOption(optionOf(FORCED_KEYWORDS, "k", Option.UNLIMITED_VALUES, false)); + options.addOption(optionOf(EXCLUDE_DIRECTORY, "e", Option.UNLIMITED_VALUES, false)); + options.addOption(optionOf(INCLUDE_PATTERN, "i", true)); + return options; + } + + private static void exitIfHelp(CommandLine cmd, Options options, HelpFormatter formatter) { + if (cmd.hasOption("help")) { + formatter.printHelp(106, "java -jar MKVAudioSubtitlesChanger.jar -l ", + "\nParameters:", options, + "\nFeature requests and bug reports: https://github.com/RatzzFatzz/MKVAudioSubtitleChanger/issues"); + System.exit(0); + } + } + + private static void exitIfVersion(CommandLine cmd) { + if (cmd.hasOption(VERSION.prop())) { + System.out.printf("MKV Audio Subtitle Changer Version %s%n", VersionUtil.getVersion()); + System.exit(0); + } + } + + private static File loadConfigPath(CommandLine cmd, ConfigErrors errors) { + File configPath = new File(cmd.getOptionValue(CONFIG_PATH.prop(), "config.yaml")); + if (configPath.isFile()) return configPath; + + errors.add("invalid config path"); + return null; + } +} diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/ValidationResult.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/ValidationResult.java new file mode 100644 index 0000000..8f63726 --- /dev/null +++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/ValidationResult.java @@ -0,0 +1,11 @@ +package at.pcgamingfreaks.mkvaudiosubtitlechanger.config; + +import lombok.Getter; +import lombok.Setter; + +public enum ValidationResult { + VALID, + NOT_PRESENT, + MISSING, + INVALID; +} diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validator/BooleanValidator.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validator/BooleanValidator.java new file mode 100644 index 0000000..8f4a67e --- /dev/null +++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validator/BooleanValidator.java @@ -0,0 +1,53 @@ +package at.pcgamingfreaks.mkvaudiosubtitlechanger.config.validator; + +import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.ValidationResult; +import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.ConfigProperty; +import at.pcgamingfreaks.yaml.YAML; +import org.apache.commons.cli.CommandLine; + +import java.util.List; + +import static at.pcgamingfreaks.mkvaudiosubtitlechanger.model.ConfigProperty.ARGUMENTS; + +public class BooleanValidator extends ConfigValidator { + + public BooleanValidator(ConfigProperty property, boolean required) { + super(property, required, null); + } + + public ValidationResult validate(YAML yaml, CommandLine cmd) { + System.out.printf("Checking %s... ", property.prop()); + boolean result; + + if (cmd.hasOption(property.prop())) { + result = true; + } else if (yaml.isSet(ARGUMENTS.prop()) + && yaml.getStringList(ARGUMENTS.prop(), List.of()).contains(property.prop())) { + result = true; + } else if (required) { + System.out.println("missing"); + return ValidationResult.MISSING; + } else { + System.out.println("ok"); + return ValidationResult.NOT_PRESENT; + } + + if (!isValid(result) || !setValue(result)) { + System.out.println("invalid"); + return ValidationResult.INVALID; + } + + System.out.println("ok"); + return ValidationResult.VALID; + } + + @Override + Boolean parse(String value) { + throw new RuntimeException("This should not be called"); + } + + @Override + boolean isValid(Boolean result) { + return true; // skip + } +} diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validator/ConfigValidator.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validator/ConfigValidator.java new file mode 100644 index 0000000..f04cf2a --- /dev/null +++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validator/ConfigValidator.java @@ -0,0 +1,84 @@ +package at.pcgamingfreaks.mkvaudiosubtitlechanger.config.validator; + +import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.Config; +import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.ValidationResult; +import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.ConfigProperty; +import at.pcgamingfreaks.yaml.YAML; +import at.pcgamingfreaks.yaml.YamlKeyNotFoundException; +import lombok.RequiredArgsConstructor; +import org.apache.commons.cli.CommandLine; +import org.apache.commons.lang3.StringUtils; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.List; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +@RequiredArgsConstructor +public abstract class ConfigValidator { + protected final ConfigProperty property; + protected final boolean required; + protected final FieldType defaultValue; + + public ValidationResult validate(YAML yaml, CommandLine cmd) { + System.out.printf("Checking %s... ", property.prop()); + String resultString = null; + + if (cmd.hasOption(property.prop())) { + resultString = cmd.getOptionValue(property.prop()); + } else if (yaml.isSet(property.prop())) { + try { + resultString = yaml.getString(property.prop()); + } catch (YamlKeyNotFoundException ignored) {} + } else if (required) { + System.out.println("missing"); + return ValidationResult.MISSING; + } else { + System.out.println("ok"); + return ValidationResult.NOT_PRESENT; + } + + FieldType result = parse(resultString); + + if (!isValid(result) || !setValue(result)) { + System.out.println("invalid"); + return ValidationResult.INVALID; + } + + System.out.println("ok"); + return ValidationResult.VALID; + } + + abstract FieldType parse(String value); + + abstract boolean isValid(FieldType result); + + protected boolean setValue(FieldType result) { + List methods = Arrays.stream(Config.getInstance().getClass().getDeclaredMethods()) + .filter(containsSetterOf(property)) + .collect(Collectors.toList()); + if (methods.size() != 1) { + return false; + } + try { + methods.get(0).invoke(Config.getInstance(), result); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new RuntimeException(e); + } + return true; + } + + protected Predicate containsSetterOf(ConfigProperty property) { + return method -> StringUtils.containsIgnoreCase(method.getName(), "set") + && StringUtils.containsIgnoreCase(method.getName(), property.prop().replace("-", "")); + } + + protected Predicate containsGetterOf(ConfigProperty property) { + return method -> StringUtils.containsIgnoreCase(method.getName(), "get") + && StringUtils.containsIgnoreCase(method.getName(), property.prop().replace("-", "")); + } + + +} diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validator/MkvToolNixPathValidator.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validator/MkvToolNixPathValidator.java new file mode 100644 index 0000000..9508049 --- /dev/null +++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validator/MkvToolNixPathValidator.java @@ -0,0 +1,23 @@ +package at.pcgamingfreaks.mkvaudiosubtitlechanger.config.validator; + +import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.ConfigProperty; + +import java.io.File; +import java.nio.file.Path; + +import static at.pcgamingfreaks.mkvaudiosubtitlechanger.model.MkvToolNix.MKV_MERGER; +import static at.pcgamingfreaks.mkvaudiosubtitlechanger.model.MkvToolNix.MKV_PROP_EDIT; + +public class MkvToolNixPathValidator extends PathValidator { + public MkvToolNixPathValidator(ConfigProperty property, boolean required, File defaultValue) { + super(property, required, defaultValue); + } + + @Override + protected boolean isValid(File result) { + return result.isDirectory() + && Path.of(result.getAbsolutePath() + "/" + MKV_MERGER + ".exe").toFile().isFile() + && Path.of(result.getAbsolutePath() + "/" + MKV_PROP_EDIT+ ".exe").toFile().isFile(); + // TODO: make linux compatible + } +} diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validator/OperatingSystemValidator.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validator/OperatingSystemValidator.java new file mode 100644 index 0000000..a1bc5ed --- /dev/null +++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validator/OperatingSystemValidator.java @@ -0,0 +1,28 @@ +package at.pcgamingfreaks.mkvaudiosubtitlechanger.config.validator; + +import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.ValidationResult; +import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.ConfigProperty; +import at.pcgamingfreaks.yaml.YAML; +import org.apache.commons.cli.CommandLine; +import org.apache.commons.lang3.StringUtils; + +public class OperatingSystemValidator extends BooleanValidator { + + public OperatingSystemValidator(ConfigProperty property) { + super(property, false); + } + + @Override + public ValidationResult validate(YAML yaml, CommandLine cmd) { + System.out.printf("Checking %s... ", property.prop()); + Boolean result = StringUtils.containsIgnoreCase(System.getProperty("os.name"), "windows"); + + if (!isValid(result) || !setValue(result)) { + System.out.println("invalid"); + return ValidationResult.INVALID; + } + + System.out.println("ok"); + return ValidationResult.VALID; + } +} diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validator/PathValidator.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validator/PathValidator.java new file mode 100644 index 0000000..4557202 --- /dev/null +++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validator/PathValidator.java @@ -0,0 +1,24 @@ +package at.pcgamingfreaks.mkvaudiosubtitlechanger.config.validator; + +import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.ConfigProperty; + +import java.io.File; +import java.nio.file.Path; + +public class PathValidator extends ConfigValidator { + + public PathValidator(ConfigProperty property, boolean required, File defaultValue) { + super(property, required, defaultValue); + } + + @Override + protected File parse(String value) { + return value != null ? Path.of(value).toFile() : defaultValue; + } + + @Override + protected boolean isValid(File result) { + return result.isDirectory() || result.isFile(); + } + +} diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validator/PatternValidator.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validator/PatternValidator.java new file mode 100644 index 0000000..60668d1 --- /dev/null +++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validator/PatternValidator.java @@ -0,0 +1,26 @@ +package at.pcgamingfreaks.mkvaudiosubtitlechanger.config.validator; + +import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.ConfigProperty; + +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; + +public class PatternValidator extends ConfigValidator { + public PatternValidator(ConfigProperty property, boolean required, Pattern defaultValue) { + super(property, required, defaultValue); + } + + @Override + Pattern parse(String value) { + try { + return Pattern.compile(value); + } catch (PatternSyntaxException e) { + return null; + } + } + + @Override + boolean isValid(Pattern result) { + return result != null; + } +} diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validator/SetValidator.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validator/SetValidator.java new file mode 100644 index 0000000..fdaa4d7 --- /dev/null +++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validator/SetValidator.java @@ -0,0 +1,90 @@ +package at.pcgamingfreaks.mkvaudiosubtitlechanger.config.validator; + +import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.Config; +import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.ValidationResult; +import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.ConfigProperty; +import at.pcgamingfreaks.yaml.YAML; +import at.pcgamingfreaks.yaml.YamlKeyNotFoundException; +import org.apache.commons.cli.CommandLine; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +public class SetValidator extends ConfigValidator> { + private final boolean append; + + public SetValidator(ConfigProperty property, boolean required, boolean append) { + super(property, required, null); + this.append = append; + } + + public ValidationResult validate(YAML yaml, CommandLine cmd) { + System.out.printf("Checking %s... ", property.prop()); + List resultList = null; + + if (cmd.hasOption(property.prop())) { + resultList = List.of(cmd.getOptionValues(property.prop())); + } else if (yaml.isSet(property.prop())) { + try { + resultList = yaml.getStringList(property.prop()); + } catch (YamlKeyNotFoundException ignored) {} + } else if (required) { + System.out.println("missing"); + return ValidationResult.MISSING; + } else { + System.out.println("not present"); + return ValidationResult.NOT_PRESENT; + } + + Set result = parse(resultList); + + if (!isValid(result) || !setValue(result)) { + System.out.println("invalid"); + return ValidationResult.INVALID; + } + + System.out.println("ok"); + return ValidationResult.VALID; + } + @Override + Set parse(String value) { + throw new RuntimeException("This should not be called"); + } + + protected Set parse(List value) { + return new HashSet<>(value); + } + + @Override + boolean isValid(Set result) { + return true; + } + + protected boolean setValue(Set result) { + List methods = append + ? Arrays.stream(Config.getInstance().getClass().getDeclaredMethods()) + .filter(containsGetterOf(property)) + .collect(Collectors.toList()) + : Arrays.stream(Config.getInstance().getClass().getDeclaredMethods()) + .filter(containsSetterOf(property)) + .collect(Collectors.toList()); + if (methods.size() != 1) { + return false; + } + try { + if (append) { + ((Set) methods.get(0).invoke(Config.getInstance())).addAll(result); + } else { + methods.get(0).invoke(Config.getInstance(), result); + } + } catch (IllegalAccessException | InvocationTargetException e) { + throw new RuntimeException(e); + } + return true; + } +} diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validator/ThreadValidator.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validator/ThreadValidator.java new file mode 100644 index 0000000..f2adc12 --- /dev/null +++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validator/ThreadValidator.java @@ -0,0 +1,20 @@ +package at.pcgamingfreaks.mkvaudiosubtitlechanger.config.validator; + +import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.ConfigProperty; +import org.apache.commons.lang3.StringUtils; + +public class ThreadValidator extends ConfigValidator{ + public ThreadValidator(ConfigProperty property, boolean required, Integer defaultValue) { + super(property, required, defaultValue); + } + + @Override + Integer parse(String value) { + return StringUtils.isNumeric(value) ? Integer.parseInt(value) : defaultValue; + } + + @Override + boolean isValid(Integer result) { + return result > 0; + } +} diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/ConfigProperty.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/ConfigProperty.java index 203b4b2..6624749 100644 --- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/ConfigProperty.java +++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/ConfigProperty.java @@ -7,13 +7,16 @@ public enum ConfigProperty { CONFIG_PATH("config", "Path to config file"), LIBRARY("library", "Path to library"), SAFE_MODE("safe-mode", "Test run (no files will be changes)"), + WINDOWS("windows", "Is operating system windows"), THREADS("threads", "thread count (default: 2)"), INCLUDE_PATTERN("include-pattern", "Include files matching pattern"), MKV_TOOL_NIX("mkvtoolnix", "Path to mkv tool nix installation"), - FORCED_KEYWORDS("forcedKeywords", "Additional keywords to identify forced tracks, combines with config file"), + FORCED_KEYWORDS("forcedKeywords", "Additional keywords to identify forced tracks"), + COMMENTARY_KEYWORDS("excludedKeywords", "Additional keywords to identify commentary tracks"), EXCLUDE_DIRECTORY("exclude-directories", "Directories to be excluded, combines with config file"), HELP("help", "\"for help this is\" - Yoda"), - VERSION("version", "Display version"); + VERSION("version", "Display version"), + ARGUMENTS("arguments", "List of arguments"); private final String property; private final String description; diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/MkvToolNix.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/MkvToolNix.java index 5bf698b..0e6e853 100644 --- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/MkvToolNix.java +++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/MkvToolNix.java @@ -4,8 +4,8 @@ import lombok.AllArgsConstructor; @AllArgsConstructor public enum MkvToolNix { - MKV_MERGER("mkvmerge.exe"), - MKV_PROP_EDIT("mkvpropedit.exe"); + MKV_MERGER("mkvmerge"), + MKV_PROP_EDIT("mkvpropedit"); private final String file; diff --git a/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validator/BooleanValidatorTest.java b/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validator/BooleanValidatorTest.java new file mode 100644 index 0000000..c91afe1 --- /dev/null +++ b/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validator/BooleanValidatorTest.java @@ -0,0 +1,58 @@ +package at.pcgamingfreaks.mkvaudiosubtitlechanger.config.validator; + +import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.ValidationResult; +import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.ConfigProperty; +import at.pcgamingfreaks.yaml.YAML; +import at.pcgamingfreaks.yaml.YamlInvalidContentException; +import org.apache.commons.cli.CommandLineParser; +import org.apache.commons.cli.DefaultParser; +import org.apache.commons.cli.Options; +import org.apache.commons.cli.ParseException; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.util.stream.Stream; + +import static at.pcgamingfreaks.mkvaudiosubtitlechanger.config.ValidationResult.*; +import static at.pcgamingfreaks.mkvaudiosubtitlechanger.model.ConfigProperty.*; +import static at.pcgamingfreaks.mkvaudiosubtitlechanger.util.CommandLineOptionsUtil.optionOf; +import static at.pcgamingfreaks.mkvaudiosubtitlechanger.util.TestUtil.yamlList; +import static org.junit.jupiter.api.Assertions.assertEquals; + +class BooleanValidatorTest { + private static CommandLineParser parser; + private static Options options; + + @BeforeAll + static void before() { + parser = new DefaultParser(); + options = new Options(); + options.addOption(optionOf(SAFE_MODE, "s", false)); + } + + private static Stream provideTestCases() { + return Stream.of( + Arguments.of(SAFE_MODE, false, "", new String[]{"-safe-mode"}, VALID), + Arguments.of(SAFE_MODE, true, "", new String[]{"-safe-mode"}, VALID), + Arguments.of(SAFE_MODE, false, "", new String[]{""}, NOT_PRESENT), + Arguments.of(SAFE_MODE, true, "", new String[]{""}, MISSING), + Arguments.of(SAFE_MODE, false, yamlList(ARGUMENTS, SAFE_MODE), new String[]{""}, VALID), + Arguments.of(SAFE_MODE, true, yamlList(ARGUMENTS, SAFE_MODE), new String[]{""}, VALID), + Arguments.of(SAFE_MODE, false, yamlList(ARGUMENTS, WINDOWS), new String[]{""}, NOT_PRESENT), + Arguments.of(SAFE_MODE, true, yamlList(ARGUMENTS, WINDOWS), new String[]{""}, MISSING) + ); + } + + @ParameterizedTest + @MethodSource("provideTestCases") + void validate(ConfigProperty property, boolean required, String yamlArgs, String[] cmdArgs, + ValidationResult expectedResult) throws ParseException, YamlInvalidContentException { + BooleanValidator underTest = new BooleanValidator(property, required); + + ValidationResult result = underTest.validate(new YAML(yamlArgs), parser.parse(options, cmdArgs)); + + assertEquals(expectedResult, result); + } +} \ No newline at end of file diff --git a/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/util/TestUtil.java b/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/util/TestUtil.java new file mode 100644 index 0000000..8b617a5 --- /dev/null +++ b/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/util/TestUtil.java @@ -0,0 +1,16 @@ +package at.pcgamingfreaks.mkvaudiosubtitlechanger.util; + +import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.ConfigProperty; + +import java.util.Arrays; + +import static java.util.stream.Collectors.joining; + +public class TestUtil { + public static String yamlList(ConfigProperty main, ConfigProperty... child) { + return main.prop() + ":\n" + Arrays.stream(child) + .map(ConfigProperty::prop) + .collect(joining("\n", " - ", "")); + } + +}