From 37cedecea75d809bdca2ac745a8fee5580be3e50 Mon Sep 17 00:00:00 2001 From: RatzzFatzz Date: Thu, 11 Dec 2025 01:47:55 +0100 Subject: [PATCH] Make InputConfig no longer be a singleton --- .../mkvaudiosubtitlechanger/Main.java | 12 ++++--- .../impl/FileFilter.java | 32 +++++++++++-------- .../impl/kernel/AttributeUpdaterKernel.java | 9 +++--- .../CoherentAttributeUpdaterKernel.java | 4 +-- .../processors/CachedMkvFileProcessor.java | 5 +++ .../impl/processors/MkvFileProcessor.java | 19 ++++++----- .../model/InputConfig.java | 19 ----------- .../impl/FileFilterTest.java | 5 ++- .../impl/MkvFileProcessorTest.java | 6 +--- .../model/InputConfigTest.java | 29 ++++++++--------- 10 files changed, 63 insertions(+), 77 deletions(-) diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/Main.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/Main.java index b5c7a9c..54b20ee 100644 --- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/Main.java +++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/Main.java @@ -1,5 +1,7 @@ package at.pcgamingfreaks.mkvaudiosubtitlechanger; +import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.FileFilter; +import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.processors.MkvFileProcessor; import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.InputConfig; import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.validation.ValidationExecutionStrategy; import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.processors.CachedMkvFileProcessor; @@ -50,10 +52,12 @@ public class Main implements Runnable { Configurator.setRootLevel(Level.DEBUG); } - InputConfig.setInstance(config); - AttributeUpdaterKernel kernel = InputConfig.getInstance().getCoherent() != null - ? new CoherentAttributeUpdaterKernel(config, new CachedMkvFileProcessor()) - : new DefaultAttributeUpdaterKernel(config, new CachedMkvFileProcessor()); + FileFilter fileFilter = new FileFilter(config.getExcluded(), config.getIncludePattern(), config.getFilterDate()); + MkvFileProcessor fileProcessor = new CachedMkvFileProcessor(config.getMkvToolNix(), fileFilter); + + AttributeUpdaterKernel kernel = config.getCoherent() != null + ? new CoherentAttributeUpdaterKernel(config, fileProcessor) + : new DefaultAttributeUpdaterKernel(config, fileProcessor); kernel.execute(); } } diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/FileFilter.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/FileFilter.java index 68d39a2..f059ef3 100644 --- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/FileFilter.java +++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/FileFilter.java @@ -1,8 +1,8 @@ package at.pcgamingfreaks.mkvaudiosubtitlechanger.impl; -import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.InputConfig; import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.ResultStatistic; import at.pcgamingfreaks.mkvaudiosubtitlechanger.util.DateUtils; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import java.io.File; @@ -16,11 +16,16 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; @Slf4j +@RequiredArgsConstructor public class FileFilter { - private static final String EXTENSION_GROUP = "extension"; - private static final Pattern extensionPattern = Pattern.compile(String.format(".*(?<%s>\\..*)", EXTENSION_GROUP)); + private final Set excluded; + private final Pattern includePattern; + private final Date filterDate; - public static boolean accept(File pathName, Set fileExtensions) { + private final String EXTENSION_GROUP = "extension"; + private final Pattern extensionPattern = Pattern.compile(String.format(".*(?<%s>\\..*)", EXTENSION_GROUP)); + + public boolean accept(File pathName, Set fileExtensions) { // Ignore files irrelevant for statistics if (!hasProperFileExtension(pathName, new HashSet<>(fileExtensions))) { return false; @@ -29,7 +34,7 @@ public class FileFilter { ResultStatistic.getInstance().total(); if (!hasMatchingPattern(pathName) || !isNewer(pathName) - || isExcluded(pathName, new HashSet<>(InputConfig.getInstance().getExcluded()))) { + || isExcluded(pathName, new HashSet<>(excluded))) { ResultStatistic.getInstance().excluded(); return false; } @@ -37,18 +42,17 @@ public class FileFilter { return true; } - private static boolean hasProperFileExtension(File pathName, Set fileExtensions) { + private boolean hasProperFileExtension(File pathName, Set fileExtensions) { Matcher matcher = extensionPattern.matcher(pathName.getName()); return matcher.find() && fileExtensions.contains(matcher.group(EXTENSION_GROUP)); } - private static boolean hasMatchingPattern(File pathName) { - return InputConfig.getInstance().getIncludePattern().matcher(pathName.getName()).matches(); + private boolean hasMatchingPattern(File pathName) { + return includePattern.matcher(pathName.getName()).matches(); } - private static boolean isNewer(File pathName) { - InputConfig config = InputConfig.getInstance(); - if (config.getFilterDate() == null) return true; + private boolean isNewer(File pathName) { + if (filterDate == null) return true; try { BasicFileAttributes attributes = Files.readAttributes(pathName.toPath(), BasicFileAttributes.class); return isNewer(DateUtils.convert(attributes.creationTime().toMillis())); @@ -58,11 +62,11 @@ public class FileFilter { return true; } - private static boolean isNewer(Date creationDate) { - return creationDate.toInstant().isAfter(InputConfig.getInstance().getFilterDate().toInstant()); + private boolean isNewer(Date creationDate) { + return creationDate.toInstant().isAfter(filterDate.toInstant()); } - private static boolean isExcluded(File pathName, Set excludedDirs) { + private boolean isExcluded(File pathName, Set excludedDirs) { if (excludedDirs.contains(pathName.getPath())) return true; // TODO improve partial matches and wildcard? diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/kernel/AttributeUpdaterKernel.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/kernel/AttributeUpdaterKernel.java index d55484b..aaf75ee 100644 --- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/kernel/AttributeUpdaterKernel.java +++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/kernel/AttributeUpdaterKernel.java @@ -8,7 +8,6 @@ import at.pcgamingfreaks.mkvaudiosubtitlechanger.util.DateUtils; import at.pcgamingfreaks.mkvaudiosubtitlechanger.util.ProjectUtil; import at.pcgamingfreaks.yaml.YAML; import at.pcgamingfreaks.yaml.YamlInvalidContentException; -import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import me.tongfei.progressbar.ProgressBar; @@ -54,7 +53,7 @@ public abstract class AttributeUpdaterKernel { statistic.startTimer(); try (ProgressBar progressBar = pbBuilder().build()) { - List files = processor.loadFiles(InputConfig.getInstance().getLibraryPath().getAbsolutePath()); + List files = processor.loadFiles(config.getLibraryPath().getAbsolutePath()); progressBar.maxHint(files.size()); progressBar.refresh(); @@ -122,7 +121,7 @@ public abstract class AttributeUpdaterKernel { } private void commitChange(FileInfo fileInfo) { - if (InputConfig.getInstance().isSafeMode()) return; + if (config.isSafeMode()) return; try { processor.update(fileInfo); @@ -136,7 +135,7 @@ public abstract class AttributeUpdaterKernel { // should this be here? protected void writeLastExecutionDate() { - if (InputConfig.getInstance().isSafeMode()) { + if (config.isSafeMode()) { return; } @@ -150,7 +149,7 @@ public abstract class AttributeUpdaterKernel { if (!lastExecutionFile.exists()) lastExecutionFile.createNewFile(); YAML yaml = new YAML(lastExecutionFile); - yaml.set(InputConfig.getInstance().getNormalizedLibraryPath(), DateUtils.convert(new Date())); + yaml.set(config.getNormalizedLibraryPath(), DateUtils.convert(new Date())); yaml.save(lastExecutionFile); } catch (IOException | YamlInvalidContentException e) { log.error("last-execution.yml could not be created or read.", e); diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/kernel/CoherentAttributeUpdaterKernel.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/kernel/CoherentAttributeUpdaterKernel.java index 76c1ae3..bf7cd95 100644 --- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/kernel/CoherentAttributeUpdaterKernel.java +++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/kernel/CoherentAttributeUpdaterKernel.java @@ -50,7 +50,7 @@ public class CoherentAttributeUpdaterKernel extends AttributeUpdaterKernel { */ @Override void process(File file) { - process(file, InputConfig.getInstance().getCoherent()); + process(file, config.getCoherent()); } void process(File file, int depth) { @@ -60,7 +60,7 @@ public class CoherentAttributeUpdaterKernel extends AttributeUpdaterKernel { // .map(FileInfoOld::new) // .collect(Collectors.toList()); - for (AttributeConfig config : InputConfig.getInstance().getAttributeConfig()) { + for (AttributeConfig config : config.getAttributeConfig()) { // for (FileInfoOld fileInfoOld : fileInfoOlds) { // List attributes = processor.readAttributes(fileInfoOld.getFile()); diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/processors/CachedMkvFileProcessor.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/processors/CachedMkvFileProcessor.java index 2f16c01..4809aee 100644 --- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/processors/CachedMkvFileProcessor.java +++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/processors/CachedMkvFileProcessor.java @@ -1,6 +1,7 @@ package at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.processors; import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.Cache; +import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.FileFilter; import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.FileInfo; import java.io.File; @@ -8,6 +9,10 @@ import java.io.File; public class CachedMkvFileProcessor extends MkvFileProcessor { Cache cache = new Cache<>(); + public CachedMkvFileProcessor(File mkvToolNixInstallation, FileFilter fileFilter) { + super(mkvToolNixInstallation, fileFilter); + } + @Override public FileInfo readAttributes(File file) { return cache.retrieve(file, super::readAttributes); diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/processors/MkvFileProcessor.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/processors/MkvFileProcessor.java index d851135..5d66ad3 100644 --- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/processors/MkvFileProcessor.java +++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/processors/MkvFileProcessor.java @@ -1,14 +1,11 @@ package at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.processors; import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.FileFilter; -import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.SubtitleTrackComparator; -import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.InputConfig; import at.pcgamingfreaks.mkvaudiosubtitlechanger.exceptions.MkvToolNixException; import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.*; -import at.pcgamingfreaks.mkvaudiosubtitlechanger.util.SetUtils; import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.core.util.IOUtils; import java.io.File; @@ -22,12 +19,14 @@ import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; -import static at.pcgamingfreaks.mkvaudiosubtitlechanger.model.TrackType.AUDIO; -import static at.pcgamingfreaks.mkvaudiosubtitlechanger.model.TrackType.SUBTITLES; -import static java.lang.String.format; +import static at.pcgamingfreaks.mkvaudiosubtitlechanger.util.FileUtils.getPathFor; @Slf4j +@RequiredArgsConstructor public class MkvFileProcessor implements FileProcessor { + protected final File mkvToolNixInstallation; + protected final FileFilter fileFilter; + private final ObjectMapper mapper = new ObjectMapper(); private static final Set fileExtensions = new HashSet<>(Set.of(".mkv", ".mka", ".mks", ".mk3d")); @@ -46,7 +45,7 @@ public class MkvFileProcessor implements FileProcessor { return paths .filter(Files::isRegularFile) .map(Path::toFile) - .filter(file -> FileFilter.accept(file, fileExtensions)) + .filter(file -> fileFilter.accept(file, fileExtensions)) .collect(Collectors.toList()); } catch (IOException e) { log.error("Couldn't find file or directory!", e); @@ -76,7 +75,7 @@ public class MkvFileProcessor implements FileProcessor { FileInfo fileInfo = new FileInfo(file); try { String[] command = new String[]{ - InputConfig.getInstance().getPathFor(MkvToolNix.MKV_MERGE), + getPathFor(mkvToolNixInstallation, MkvToolNix.MKV_MERGE).getAbsolutePath(), "--identify", "--identification-format", "json", @@ -121,7 +120,7 @@ public class MkvFileProcessor implements FileProcessor { @Override public void update(FileInfo fileInfo) throws IOException, MkvToolNixException { List command = new ArrayList<>(); - command.add(InputConfig.getInstance().getPathFor(MkvToolNix.MKV_PROP_EDIT)); + command.add(getPathFor(mkvToolNixInstallation, MkvToolNix.MKV_PROP_EDIT).getAbsolutePath()); command.add(String.format(fileInfo.getFile().getAbsolutePath())); PlannedChange changes = fileInfo.getChanges(); diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/InputConfig.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/InputConfig.java index eb8be2a..8148e0f 100644 --- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/InputConfig.java +++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/InputConfig.java @@ -5,7 +5,6 @@ import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.validation.ValidFile; import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.validation.ValidMkvToolNix; import at.pcgamingfreaks.mkvaudiosubtitlechanger.util.FileUtils; import jakarta.validation.constraints.Min; -import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @@ -24,9 +23,6 @@ import picocli.CommandLine.Option; @NoArgsConstructor @CommandLine.Command public class InputConfig { - @Getter(AccessLevel.NONE) - @Setter(AccessLevel.NONE) - private static InputConfig config = null; private File configPath; @@ -89,21 +85,6 @@ public class InputConfig { System.setProperty("DEFAULT_MKV_TOOL_NIX", SystemUtils.IS_OS_WINDOWS ? "C:\\Program Files\\MKVToolNix" : "/usr/bin/"); } - public static InputConfig getInstance() { - return getInstance(false); - } - - public static InputConfig getInstance(boolean reset) { - if (config == null || reset) { - config = new InputConfig(); - } - return config; - } - - public static void setInstance(InputConfig c) { - config = c; - } - /** * Get path to specific mkvtoolnix application. * @return absolute path to desired application. diff --git a/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/FileFilterTest.java b/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/FileFilterTest.java index be83a65..0e4c545 100644 --- a/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/FileFilterTest.java +++ b/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/FileFilterTest.java @@ -63,16 +63,15 @@ class FileFilterTest { when(file.getName()).thenReturn(List.of(path.split("/")).get(1)); when(file.toPath()).thenReturn(Path.of(TEST_FILE)); - InputConfig.getInstance(true).setIncludePattern(Pattern.compile(pattern)); long currentTime = System.currentTimeMillis(); - InputConfig.getInstance().setFilterDate(new Date(currentTime + filterDateOffset)); + FileFilter fileFilter = new FileFilter(Set.of(), Pattern.compile(pattern), new Date(currentTime + filterDateOffset)); try (MockedStatic mockedFiles = Mockito.mockStatic(DateUtils.class)) { mockedFiles .when(() -> DateUtils.convert(anyLong())) .thenReturn(new Date(currentTime)); - assertEquals(expectedHit, FileFilter.accept(file, new HashSet<>(args)), "File is accepted"); + assertEquals(expectedHit, fileFilter.accept(file, new HashSet<>(args)), "File is accepted"); assertEquals(total, ResultStatistic.getInstance().getTotal(), "Total files"); assertEquals(excluded, ResultStatistic.getInstance().getExcluded(), "Excluded files"); } diff --git a/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/MkvFileProcessorTest.java b/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/MkvFileProcessorTest.java index c92acac..cfcb65f 100644 --- a/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/MkvFileProcessorTest.java +++ b/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/MkvFileProcessorTest.java @@ -1,8 +1,6 @@ package at.pcgamingfreaks.mkvaudiosubtitlechanger.impl; -import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.processors.MkvFileProcessor; import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.FileInfo; -import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.InputConfig; import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.AttributeConfig; import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.TrackAttributes; import org.junit.jupiter.api.Disabled; @@ -11,7 +9,6 @@ import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; import java.util.List; -import java.util.Set; import java.util.stream.Stream; import static at.pcgamingfreaks.mkvaudiosubtitlechanger.util.FileInfoTestUtil.*; @@ -33,9 +30,8 @@ class MkvFileProcessorTest { @MethodSource @Disabled void detectDesiredTracks(AttributeConfig expectedMatch, List tracks, AttributeConfig... configs) { - InputConfig.getInstance().setPreferredSubtitles(Set.of()); FileInfo info = new FileInfo(null); - MkvFileProcessor processor = new MkvFileProcessor(); +// MkvFileProcessor processor = new MkvFileProcessor(null, new FileFilter()); // processor.detectDesiredTracks(info, tracks, tracks, configs); assertEquals(expectedMatch.getAudioLanguage(), info.getMatchedConfig().getAudioLanguage()); assertEquals(expectedMatch.getSubtitleLanguage(), info.getMatchedConfig().getSubtitleLanguage()); diff --git a/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/InputConfigTest.java b/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/InputConfigTest.java index bdc0652..61d5170 100644 --- a/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/InputConfigTest.java +++ b/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/InputConfigTest.java @@ -31,25 +31,25 @@ class InputConfigTest { "--commentary-keywords", "testCommentary", "--preferred-subtitles", "testPreferred" }; - CommandLine.populateCommand(InputConfig.getInstance(true), sut); + InputConfig config = CommandLine.populateCommand(new InputConfig(), sut); - assertTrue(InputConfig.getInstance().getLibraryPath().exists()); + assertTrue(config.getLibraryPath().exists()); assertEquals(List.of(new AttributeConfig("ger", "ger"), new AttributeConfig("eng", "eng")), - InputConfig.getInstance().getAttributeConfig()); + config.getAttributeConfig()); - assertTrue(InputConfig.getInstance().isSafeMode()); - assertTrue(InputConfig.getInstance().isForceCoherent()); - assertTrue(InputConfig.getInstance().isOnlyNewFiles()); - assertNull(InputConfig.getInstance().getFilterDate()); + assertTrue(config.isSafeMode()); + assertTrue(config.isForceCoherent()); + assertTrue(config.isOnlyNewFiles()); + assertNull(config.getFilterDate()); - assertEquals(2, InputConfig.getInstance().getCoherent()); - assertEquals(4, InputConfig.getInstance().getThreads()); - assertEquals(".*[abc].*", InputConfig.getInstance().getIncludePattern().pattern()); - assertTrue(InputConfig.getInstance().getForcedKeywords().contains("testForced")); - assertTrue(InputConfig.getInstance().getCommentaryKeywords().contains("testCommentary")); - assertTrue(InputConfig.getInstance().getPreferredSubtitles().contains("testPreferred")); + assertEquals(2, config.getCoherent()); + assertEquals(4, config.getThreads()); + assertEquals(".*[abc].*", config.getIncludePattern().pattern()); + assertTrue(config.getForcedKeywords().contains("testForced")); + assertTrue(config.getCommentaryKeywords().contains("testCommentary")); + assertTrue(config.getPreferredSubtitles().contains("testPreferred")); - assertNull(InputConfig.getInstance().getConfigPath()); + assertNull(config.getConfigPath()); } @@ -66,7 +66,6 @@ class InputConfigTest { @ParameterizedTest @MethodSource("jakartaValidationData") void testJakartaValidation(String[] args, String expectedMessage) { - InputConfig.getInstance(true); StringWriter writer = new StringWriter(); PrintWriter printWriter = new PrintWriter(writer);