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", " - ", ""));
+ }
+
+}