externalLists = abbreviationsPreferences.getExternalJournalLists();
+
+ // Remove files that are no longer in the external lists
+ journalFiles.removeIf(file -> !externalLists.contains(file.getAbsolutePath().map(Path::toString).orElse("")));
+ // Add new files
+ for (String filePath : externalLists) {
+ if (journalFiles.stream().noneMatch(file -> file.getAbsolutePath().map(Path::toString).orElse("").equals(filePath))) {
+ Path path = Path.of(filePath);
+ if (filePath.endsWith(".mv")) {
+ openMvFile(path);
+ }
+ }
+ }
+ }
+
public void addAbbreviation(Abbreviation abbreviationObject) {
AbbreviationViewModel abbreviationViewModel = new AbbreviationViewModel(abbreviationObject);
if (abbreviations.contains(abbreviationViewModel)) {
@@ -335,6 +398,7 @@ public void storeSettings() {
abbreviationsPreferences.setExternalJournalLists(journalStringList);
abbreviationsPreferences.setUseFJournalField(useFJournal.get());
+ abbreviationsPreferences.setJournalAbbreviationDir(directoryPath.get());
if (shouldWriteLists) {
saveJournalAbbreviationFiles();
@@ -387,4 +451,8 @@ public SimpleBooleanProperty isFileRemovableProperty() {
public SimpleBooleanProperty useFJournalProperty() {
return useFJournal;
}
+
+ public StringProperty directoryPathProperty() {
+ return directoryPath;
+ }
}
diff --git a/src/main/java/org/jabref/logic/journals/JournalAbbreviationLoader.java b/src/main/java/org/jabref/logic/journals/JournalAbbreviationLoader.java
index 264a727ff13..37a981844a0 100644
--- a/src/main/java/org/jabref/logic/journals/JournalAbbreviationLoader.java
+++ b/src/main/java/org/jabref/logic/journals/JournalAbbreviationLoader.java
@@ -3,15 +3,20 @@
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
-import java.nio.file.InvalidPathException;
import java.nio.file.Path;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
+import javafx.beans.property.SimpleStringProperty;
+
+import org.jabref.logic.util.Directories;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import static org.jabref.logic.journals.JournalAbbreviationMvGenerator.loadAbbreviationsFromMv;
+
/**
*
* This class loads abbreviations from a CSV file and stores them into a MV file ({@link #readAbbreviationsFromCsvFile(Path)}
@@ -34,7 +39,6 @@ public static Collection readAbbreviationsFromCsvFile(Path file) t
public static JournalAbbreviationRepository loadRepository(JournalAbbreviationPreferences journalAbbreviationPreferences) {
JournalAbbreviationRepository repository;
-
// Initialize with built-in list
try (InputStream resourceAsStream = JournalAbbreviationRepository.class.getResourceAsStream("/journals/journal-list.mv")) {
if (resourceAsStream == null) {
@@ -53,6 +57,8 @@ public static JournalAbbreviationRepository loadRepository(JournalAbbreviationPr
return null;
}
+ journalAbbreviationPreferences.updateJournalsDir(journalAbbreviationPreferences.getJournalAbbreviationDir());
+
// Read external lists
List lists = journalAbbreviationPreferences.getExternalJournalLists();
// might produce NPE in tests
@@ -61,9 +67,13 @@ public static JournalAbbreviationRepository loadRepository(JournalAbbreviationPr
Collections.reverse(lists);
for (String filename : lists) {
try {
- repository.addCustomAbbreviations(readAbbreviationsFromCsvFile(Path.of(filename)));
- } catch (IOException | InvalidPathException e) {
- // invalid path might come from unix/windows mixup of prefs
+ Path filePath = Path.of(filename);
+ if (filename.endsWith(".mv")) {
+ repository.addCustomAbbreviations(loadAbbreviationsFromMv(filePath));
+ } else if (filename.endsWith(".csv")) {
+ repository.addCustomAbbreviations(readAbbreviationsFromCsvFile(filePath));
+ }
+ } catch (IOException e) {
LOGGER.error("Cannot read external journal list file {}", filename, e);
}
}
@@ -72,6 +82,6 @@ public static JournalAbbreviationRepository loadRepository(JournalAbbreviationPr
}
public static JournalAbbreviationRepository loadBuiltInRepository() {
- return loadRepository(new JournalAbbreviationPreferences(Collections.emptyList(), true));
+ return loadRepository(new JournalAbbreviationPreferences(Collections.emptyList(), true, new SimpleStringProperty(Directories.getJournalAbbreviationsDirectory().toString())));
}
}
diff --git a/src/main/java/org/jabref/logic/journals/JournalAbbreviationMvGenerator.java b/src/main/java/org/jabref/logic/journals/JournalAbbreviationMvGenerator.java
new file mode 100644
index 00000000000..d13a8e38ff3
--- /dev/null
+++ b/src/main/java/org/jabref/logic/journals/JournalAbbreviationMvGenerator.java
@@ -0,0 +1,149 @@
+package org.jabref.logic.journals;
+
+import java.io.IOException;
+import java.nio.file.DirectoryStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import org.h2.mvstore.MVMap;
+import org.h2.mvstore.MVStore;
+import org.h2.mvstore.MVStoreException;
+import org.jooq.lambda.Unchecked;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This class converts each CSV abbreviation file in a given directory into an MV file.
+ * For each CSV file, an MV file is created in the same directory with the same base name.
+ */
+public class JournalAbbreviationMvGenerator {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(JournalAbbreviationMvGenerator.class);
+
+ /**
+ * Scans the given directory for CSV files and converts each
+ * CSV file into a corresponding MV file in the same directory.
+ *
+ * @param abbreviationsDirectory the directory containing journal abbreviation CSV files.
+ */
+ public static void convertAllCsvToMv(Path abbreviationsDirectory) {
+ // A set of filenames to ignore
+ Set ignoredNames = Set.of(
+ "journal_abbreviations_entrez.csv",
+ "journal_abbreviations_medicus.csv",
+ "journal_abbreviations_webofscience-dotless.csv",
+ "journal_abbreviations_ieee_strings.csv"
+ );
+
+ // Open or create a persistent MVStore file for storing CSV file timestamps.
+ Path timestampFile = abbreviationsDirectory.resolve("timestamps.mv");
+ try (MVStore store = new MVStore.Builder()
+ .fileName(timestampFile.toString())
+ .compressHigh()
+ .open()) {
+ MVMap timestampMap = store.openMap("fileTimestamps");
+
+ // Iterate through all CSV files in the directory.
+ try (DirectoryStream stream = Files.newDirectoryStream(abbreviationsDirectory, "*.csv")) {
+ stream.forEach(Unchecked.consumer(csvFile -> {
+ String fileName = csvFile.getFileName().toString();
+ if (ignoredNames.contains(fileName)) {
+ LOGGER.info("{} ignored", fileName);
+ } else {
+ long currentTimestamp = Files.getLastModifiedTime(csvFile).toMillis();
+ Long storedTimestamp = timestampMap.get(fileName);
+
+ // Compute the MV file path by replacing the .csv extension with .mv
+ Path mvFile = csvFile.resolveSibling(fileName.replaceFirst("\\.csv$", ".mv"));
+
+ // If MV file is missing OR the CSV file has been updated, process it
+ if (!Files.exists(mvFile) || storedTimestamp == null || storedTimestamp != currentTimestamp) {
+ convertCsvToMv(csvFile, mvFile);
+ LOGGER.info("Processing {} -> Creating MV file: {}", fileName, mvFile.getFileName());
+ // Update the timestamp in the persistent map
+ timestampMap.put(fileName, currentTimestamp);
+ } else {
+ LOGGER.info("File {} is up-to-date, skipping conversion.", fileName);
+ }
+ }
+ }));
+ }
+ // Commit changes to the timestamp map
+ store.commit();
+ } catch (IOException e) {
+ LOGGER.error("Error while processing abbreviation files in directory: {}", abbreviationsDirectory, e);
+ }
+ }
+ /**
+ * Converts a CSV file into an MV file.
+ * Reads the CSV file and stores its abbreviations into an MVMap inside the MV file.
+ *
+ * @param csvFile the source CSV file.
+ * @param mvFile the target MV file.
+ */
+
+ public static void convertCsvToMv(Path csvFile, Path mvFile) throws IOException {
+
+ try (MVStore store = new MVStore.Builder()
+ .fileName(mvFile.toString())
+ .compressHigh()
+ .open()) {
+ MVMap fullToAbbreviation = store.openMap("FullToAbbreviation");
+
+ // Clear the existing map to remove outdated entries
+ fullToAbbreviation.clear();
+
+ // Read abbreviations from the CSV file using existing logic
+ Collection abbreviations = JournalAbbreviationLoader.readAbbreviationsFromCsvFile(csvFile);
+
+ // Convert the collection into a map using the full journal name as the key
+ Map abbreviationMap = abbreviations
+ .stream()
+ .collect(Collectors.toMap(
+ Abbreviation::getName,
+ abbr -> abbr,
+ (abbr1, abbr2) -> {
+ LOGGER.info("Duplicate entry found: {}", abbr1.getName());
+ return abbr2;
+ }));
+
+ fullToAbbreviation.putAll(abbreviationMap);
+ store.commit();
+ LOGGER.info("Saved MV file: {}", mvFile.getFileName());
+ } catch (IOException e) {
+ LOGGER.error("Failed to convert CSV file: {}", csvFile, e);
+ }
+ }
+
+ public static Collection loadAbbreviationsFromMv(Path path) throws IOException {
+ Collection abbreviations = new ArrayList<>();
+
+ try (MVStore store = new MVStore.Builder()
+ .fileName(path.toString())
+ .readOnly()
+ .open()) {
+ MVMap abbreviationMap = store.openMap("FullToAbbreviation");
+
+ abbreviationMap.forEach((key, value) -> {
+ Abbreviation fixedAbbreviation = new Abbreviation(
+ key,
+ value.getAbbreviation(),
+ value.getShortestUniqueAbbreviation()
+ );
+ abbreviations.add(fixedAbbreviation);
+ });
+ store.commit();
+ } catch (MVStoreException e) {
+ LOGGER.error("MVStoreException: {} , Error message: {}", path, e.getMessage(), e);
+ } catch (Exception e) {
+ LOGGER.error("Unexpected error while reading MV file: {}", path, e);
+ }
+
+ return abbreviations;
+ }
+}
diff --git a/src/main/java/org/jabref/logic/journals/JournalAbbreviationPreferences.java b/src/main/java/org/jabref/logic/journals/JournalAbbreviationPreferences.java
index fb256bbe8ab..684abd29781 100644
--- a/src/main/java/org/jabref/logic/journals/JournalAbbreviationPreferences.java
+++ b/src/main/java/org/jabref/logic/journals/JournalAbbreviationPreferences.java
@@ -1,23 +1,96 @@
package org.jabref.logic.journals;
+import java.io.IOException;
+import java.nio.file.DirectoryStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
import java.util.List;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
+import javafx.beans.property.SimpleStringProperty;
+import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
+import org.jabref.logic.util.Directories;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
public class JournalAbbreviationPreferences {
+ private static final Logger LOGGER = LoggerFactory.getLogger(JournalAbbreviationPreferences.class);
+ private static final String CUSTOM_CSV_FILE = "custom.csv";
+ private static final String MV_FILE_PATTERN = "*.mv";
+ private static final String TIMESTAMPS_FILE = "timestamps.mv";
private final ObservableList externalJournalLists;
private final BooleanProperty useFJournalField;
+ private StringProperty journalsDir;
public JournalAbbreviationPreferences(List externalJournalLists,
- boolean useFJournalField) {
+ boolean useFJournalField,
+ StringProperty journalsDir) {
+
+ if (journalsDir == null || journalsDir.get() == null) {
+ this.journalsDir = new SimpleStringProperty(Directories.getJournalAbbreviationsDirectory().toString()); // default directory
+ } else {
+ this.journalsDir = journalsDir;
+ }
+
+ this.journalsDir.addListener((observable, oldValue, newValue) -> {
+ updateJournalsDir(newValue);
+ });
+
this.externalJournalLists = FXCollections.observableArrayList(externalJournalLists);
this.useFJournalField = new SimpleBooleanProperty(useFJournalField);
}
+ public void updateJournalsDir(String directory) {
+ // Remove old .mv paths if exist
+ externalJournalLists.removeIf(path -> path.endsWith(".mv"));
+
+ Path dirPath = Path.of(directory);
+ try {
+ initializeDirectory(dirPath);
+ } catch (IOException e) {
+ LOGGER.error("Error initializing the journal directory", e);
+ }
+ setJournalAbbreviationDir(directory);
+ }
+
+ /**
+ * Ensures the journal abbreviation directory exists and initializes necessary files.
+ *
+ * This method performs the following steps:
+ * - Creates the journal abbreviation directory if it does not already exist.
+ * - Ensures the existence of the "CUSTOM_CSV_FILE" file, creating an empty one if missing.
+ * - Converts all `.csv` files in the directory to `.mv` format using {@link JournalAbbreviationMvGenerator#convertAllCsvToMv}.
+ * - Scans the directory for `.mv` files (excluding TIMESTAMPS_FILE) and adds them to {@code externalJournalLists}.
+ *
+ * If any I/O errors occur during these operations, they are logged.
+ *
+ * @param journalsDir The path to the journal abbreviation directory.
+ */
+ private void initializeDirectory(Path journalsDir) throws IOException {
+ Files.createDirectories(journalsDir);
+ Path customCsv = journalsDir.resolve(CUSTOM_CSV_FILE);
+ if (!Files.exists(customCsv)) {
+ Files.createFile(customCsv);
+ }
+
+ JournalAbbreviationMvGenerator.convertAllCsvToMv(journalsDir);
+
+ // Iterate through the directory and add all .mv files to externalJournalLists
+ try (DirectoryStream stream = Files.newDirectoryStream(journalsDir, MV_FILE_PATTERN)) {
+ for (Path mvFile : stream) {
+ if (!TIMESTAMPS_FILE.equals(mvFile.getFileName().toString())) { // Exclude TIMESTAMPS_FILE
+ externalJournalLists.add(mvFile.toString());
+ }
+ }
+ }
+ }
+
public ObservableList getExternalJournalLists() {
return externalJournalLists;
}
@@ -38,4 +111,21 @@ public BooleanProperty useFJournalFieldProperty() {
public void setUseFJournalField(boolean useFJournalField) {
this.useFJournalField.set(useFJournalField);
}
+
+ public String getJournalAbbreviationDir() {
+ if (journalsDir == null) {
+ String defaultDir = Directories.getJournalAbbreviationsDirectory().toString();
+ setJournalAbbreviationDir(defaultDir);
+ return defaultDir;
+ }
+ return journalsDir.get();
+ }
+
+ public StringProperty journalAbbreviationDirectoryProperty() {
+ return journalsDir;
+ }
+
+ public void setJournalAbbreviationDir(String journalsDir) {
+ this.journalsDir.set(journalsDir);
+ }
}
diff --git a/src/main/java/org/jabref/logic/journals/JournalAbbreviationRepository.java b/src/main/java/org/jabref/logic/journals/JournalAbbreviationRepository.java
index 4191be45857..70c8ae2ce2c 100644
--- a/src/main/java/org/jabref/logic/journals/JournalAbbreviationRepository.java
+++ b/src/main/java/org/jabref/logic/journals/JournalAbbreviationRepository.java
@@ -39,15 +39,15 @@ public JournalAbbreviationRepository(Path journalList) {
try (MVStore store = new MVStore.Builder().readOnly().fileName(journalList.toAbsolutePath().toString()).open()) {
mvFullToAbbreviationObject = store.openMap("FullToAbbreviation");
mvFullToAbbreviationObject.forEach((name, abbreviation) -> {
- String abbrevationString = abbreviation.getAbbreviation();
+ String abbreviationString = abbreviation.getAbbreviation();
String shortestUniqueAbbreviation = abbreviation.getShortestUniqueAbbreviation();
Abbreviation newAbbreviation = new Abbreviation(
name,
- abbrevationString,
+ abbreviationString,
shortestUniqueAbbreviation
);
fullToAbbreviationObject.put(name, newAbbreviation);
- abbreviationToAbbreviationObject.put(abbrevationString, newAbbreviation);
+ abbreviationToAbbreviationObject.put(abbreviationString, newAbbreviation);
dotlessToAbbreviationObject.put(newAbbreviation.getDotlessAbbreviation(), newAbbreviation);
shortestUniqueToAbbreviationObject.put(shortestUniqueAbbreviation, newAbbreviation);
});
diff --git a/src/main/java/org/jabref/logic/preferences/JabRefCliPreferences.java b/src/main/java/org/jabref/logic/preferences/JabRefCliPreferences.java
index dd9832448bb..6bc92c8ec94 100644
--- a/src/main/java/org/jabref/logic/preferences/JabRefCliPreferences.java
+++ b/src/main/java/org/jabref/logic/preferences/JabRefCliPreferences.java
@@ -28,6 +28,7 @@
import java.util.stream.Stream;
import javafx.beans.InvalidationListener;
+import javafx.beans.property.SimpleStringProperty;
import javafx.collections.ListChangeListener;
import javafx.collections.SetChangeListener;
@@ -328,6 +329,8 @@ public class JabRefCliPreferences implements CliPreferences {
private static final String EXTERNAL_JOURNAL_LISTS = "externalJournalLists";
private static final String USE_AMS_FJOURNAL = "useAMSFJournal";
+ private static final String JOURNAL_ABBREVIATION_DIRECTORY = "journalAbbreviationDirectory";
+
// Protected terms
private static final String PROTECTED_TERMS_ENABLED_EXTERNAL = "protectedTermsEnabledExternal";
private static final String PROTECTED_TERMS_DISABLED_EXTERNAL = "protectedTermsDisabledExternal";
@@ -577,7 +580,7 @@ protected JabRefCliPreferences() {
defaults.put(CONFIRM_LINKED_FILE_DELETE, Boolean.TRUE);
defaults.put(KEEP_DOWNLOAD_URL, Boolean.TRUE);
defaults.put(DEFAULT_CITATION_KEY_PATTERN, "[auth][year]");
- defaults.put(UNWANTED_CITATION_KEY_CHARACTERS, "-`ʹ:!;?^$");
+ defaults.put(UNWANTED_CITATION_KEY_CHARACTERS, "-`ʹ:!;?^");
defaults.put(RESOLVE_STRINGS_FOR_FIELDS, "author;booktitle;editor;editora;editorb;editorc;institution;issuetitle;journal;journalsubtitle;journaltitle;mainsubtitle;month;publisher;shortauthor;shorteditor;subtitle;titleaddon");
defaults.put(DO_NOT_RESOLVE_STRINGS, Boolean.FALSE);
defaults.put(NON_WRAPPABLE_FIELDS, "pdf;ps;url;doi;file;isbn;issn");
@@ -673,6 +676,9 @@ protected JabRefCliPreferences() {
// endregion
// endregion
+
+ // Journal abbreviations directory
+ defaults.put(JOURNAL_ABBREVIATION_DIRECTORY, Directories.getJournalAbbreviationsDirectory().toString());
}
public void setLanguageDependentDefaultValues() {
@@ -1012,13 +1018,19 @@ public JournalAbbreviationPreferences getJournalAbbreviationPreferences() {
journalAbbreviationPreferences = new JournalAbbreviationPreferences(
getStringList(EXTERNAL_JOURNAL_LISTS),
- getBoolean(USE_AMS_FJOURNAL));
+ getBoolean(USE_AMS_FJOURNAL),
+ new SimpleStringProperty(get(JOURNAL_ABBREVIATION_DIRECTORY)));
journalAbbreviationPreferences.getExternalJournalLists().addListener((InvalidationListener) change ->
putStringList(EXTERNAL_JOURNAL_LISTS, journalAbbreviationPreferences.getExternalJournalLists()));
EasyBind.listen(journalAbbreviationPreferences.useFJournalFieldProperty(),
(obs, oldValue, newValue) -> putBoolean(USE_AMS_FJOURNAL, newValue));
+ EasyBind.listen(journalAbbreviationPreferences.journalAbbreviationDirectoryProperty(),
+ (obs, oldValue, newValue) -> {
+ put(JOURNAL_ABBREVIATION_DIRECTORY, newValue);
+ });
+
return journalAbbreviationPreferences;
}
diff --git a/src/main/java/org/jabref/logic/util/Directories.java b/src/main/java/org/jabref/logic/util/Directories.java
index e87666d749a..7d7e2c4cb67 100644
--- a/src/main/java/org/jabref/logic/util/Directories.java
+++ b/src/main/java/org/jabref/logic/util/Directories.java
@@ -62,4 +62,11 @@ public static Path getSslDirectory() {
"ssl",
OS.APP_DIR_APP_AUTHOR));
}
+
+ public static Path getJournalAbbreviationsDirectory() {
+ return Path.of(AppDirsFactory.getInstance()
+ .getUserDataDir(OS.APP_DIR_APP_NAME,
+ "journal-abbreviations",
+ OS.APP_DIR_APP_AUTHOR));
+ }
}
diff --git a/src/test/java/org/jabref/logic/journals/JournalAbbreviationMvGeneratorTest.java b/src/test/java/org/jabref/logic/journals/JournalAbbreviationMvGeneratorTest.java
new file mode 100644
index 00000000000..916bc4b7fc3
--- /dev/null
+++ b/src/test/java/org/jabref/logic/journals/JournalAbbreviationMvGeneratorTest.java
@@ -0,0 +1,81 @@
+package org.jabref.logic.journals;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Collection;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class JournalAbbreviationMvGeneratorTest {
+
+ @TempDir
+ Path tempDir;
+
+ private Path csvFile;
+ private Path mvFile;
+
+ @BeforeEach
+ void setUp() throws IOException {
+ // Create a sample CSV file with two entries.
+ csvFile = tempDir.resolve("testJournal.csv");
+ String csvContent = "\"Test Journal\",\"T. J.\"\n" +
+ "\"Another Journal\",\"A. J.\"";
+ Files.writeString(csvFile, csvContent);
+
+ // The expected MV file has the same base name with extension .mv.
+ mvFile = tempDir.resolve("testJournal.mv");
+ }
+
+ @Test
+ void convertCsvToMvCreatesMvFileAndLoadsCorrectly() throws IOException, InterruptedException {
+ // Convert CSV to MV
+ JournalAbbreviationMvGenerator.convertCsvToMv(csvFile, mvFile);
+
+ // Verify the MV file is created
+ assertTrue(Files.exists(mvFile));
+
+ // Load abbreviations from the MV file
+ Collection abbreviations = JournalAbbreviationMvGenerator.loadAbbreviationsFromMv(mvFile);
+ // Expecting 2 abbreviations as in the CSV file
+ assertEquals(2, abbreviations.size());
+
+ // Check that the abbreviations match expected values
+ boolean foundTestJournal = abbreviations.stream()
+ .anyMatch(abbr -> "Test Journal".equalsIgnoreCase(abbr.getName()) &&
+ "T. J.".equals(abbr.getAbbreviation()));
+ boolean foundAnotherJournal = abbreviations.stream()
+ .anyMatch(abbr -> "Another Journal".equalsIgnoreCase(abbr.getName()) &&
+ "A. J.".equals(abbr.getAbbreviation()));
+ assertTrue(foundTestJournal);
+ assertTrue(foundAnotherJournal);
+ }
+
+ @Test
+ void convertAllCsvToMvIgnoresSpecifiedFiles(@TempDir Path testDir) throws IOException {
+ // Create an ignored CSV file.
+ Path ignoredCsv = testDir.resolve("journal_abbreviations_entrez.csv");
+ Files.writeString(ignoredCsv, "\"Ignored Journal\",\"I. J.\"");
+
+ // Create a valid CSV file.
+ Path validCsv = testDir.resolve("validJournal.csv");
+ Files.writeString(validCsv, "\"Valid Journal\",\"V. J.\"");
+
+ // Run convertAllCsvToMv on the test directory.
+ JournalAbbreviationMvGenerator.convertAllCsvToMv(testDir);
+
+ // The ignored CSV file should not produce an MV file.
+ Path ignoredMv = testDir.resolve("journal_abbreviations_entrez.mv");
+ assertFalse(Files.exists(ignoredMv));
+
+ // The valid CSV file should produce an MV file.
+ Path validMv = testDir.resolve("validJournal.mv");
+ assertTrue(Files.exists(validMv));
+ }
+}