diff --git a/CHANGELOG.md b/CHANGELOG.md index 89da1b9b7a0..525ee9d3ead 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -75,6 +75,8 @@ Note that this project **does not** adhere to [Semantic Versioning](https://semv ### Removed +- We removed the predatory journal checks due to a high rate of false positives. [#11066](https://github.com/JabRef/jabref/pull/11066) + ## [5.12] – 2023-12-24 ### Added diff --git a/build.gradle b/build.gradle index 1c11c083be6..8946387263c 100644 --- a/build.gradle +++ b/build.gradle @@ -346,18 +346,8 @@ tasks.register("generateJournalListMV", JavaExec) { } } -tasks.register("generatePredatoryJournalListMV", JavaExec) { - group = "JabRef" - description = "Load predatory journal information from online sources to a H2 MVStore" - classpath = sourceSets.main.runtimeClasspath - mainClass = "org.jabref.cli.PredatoryJournalsMvGenerator" - onlyIf { - !file("build/resources/main/journals/predatory-journals.mv").exists() - } -} - -jar.dependsOn("generateJournalListMV", "generatePredatoryJournalListMV") -compileTestJava.dependsOn("generateJournalListMV","generatePredatoryJournalListMV") +jar.dependsOn("generateJournalListMV") +compileTestJava.dependsOn("generateJournalListMV") tasks.register('generateCitaviSource', XjcTask) { group = 'JabRef' diff --git a/src/main/java/org/jabref/Launcher.java b/src/main/java/org/jabref/Launcher.java index 8f1ea3229c7..6f8fd7ec121 100644 --- a/src/main/java/org/jabref/Launcher.java +++ b/src/main/java/org/jabref/Launcher.java @@ -17,7 +17,6 @@ import org.jabref.gui.JabRefGUI; import org.jabref.logic.UiCommand; import org.jabref.logic.journals.JournalAbbreviationLoader; -import org.jabref.logic.journals.predatory.PredatoryJournalListLoader; import org.jabref.logic.net.ProxyAuthenticator; import org.jabref.logic.net.ProxyPreferences; import org.jabref.logic.net.ProxyRegisterer; @@ -188,9 +187,6 @@ private static void initGlobals(PreferencesService preferences) { // Read list(s) of journal names and abbreviations Globals.journalAbbreviationRepository = JournalAbbreviationLoader .loadRepository(preferences.getJournalAbbreviationPreferences()); - Globals.predatoryJournalRepository = PredatoryJournalListLoader - .loadRepository(); - Globals.entryTypesManager = preferences.getCustomEntryTypesRepository(); Globals.protectedTermsLoader = new ProtectedTermsLoader(preferences.getProtectedTermsPreferences()); } diff --git a/src/main/java/org/jabref/cli/PredatoryJournalsMvGenerator.java b/src/main/java/org/jabref/cli/PredatoryJournalsMvGenerator.java deleted file mode 100644 index 574e287abf8..00000000000 --- a/src/main/java/org/jabref/cli/PredatoryJournalsMvGenerator.java +++ /dev/null @@ -1,47 +0,0 @@ -package org.jabref.cli; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Set; -import java.util.function.Function; -import java.util.stream.Collectors; - -import org.jabref.logic.journals.predatory.PredatoryJournalInformation; -import org.jabref.logic.journals.predatory.PredatoryJournalListCrawler; - -import org.h2.mvstore.MVMap; -import org.h2.mvstore.MVStore; - -public class PredatoryJournalsMvGenerator { - public static void main(String[] args) throws IOException { - boolean verbose = (args.length == 1) && ("--verbose".equals(args[0])); - - Path predatoryJournalsMvFile = Path.of("build", "resources", "main", "journals", "predatory-journals.mv"); - Files.createDirectories(predatoryJournalsMvFile.getParent()); - - try (MVStore store = new MVStore.Builder() - .fileName(predatoryJournalsMvFile.toString()) - .compressHigh() - .backgroundExceptionHandler((t, e) -> { - System.err.println("Exception occurred in Thread " + t + "with exception " + e); - e.printStackTrace(); - }) - .open()) { - MVMap predatoryJournalsMap = store.openMap("PredatoryJournals"); - - PredatoryJournalListCrawler loader = new PredatoryJournalListCrawler(); - Set predatoryJournals = loader.loadFromOnlineSources(); - - var resultMap = predatoryJournals.stream().collect(Collectors.toMap(PredatoryJournalInformation::name, Function.identity(), - (predatoryJournalInformation, predatoryJournalInformation2) -> { - if (verbose) { - System.out.println("Double entry " + predatoryJournalInformation.name()); - } - return predatoryJournalInformation2; - })); - - predatoryJournalsMap.putAll(resultMap); - } - } -} diff --git a/src/main/java/org/jabref/gui/Globals.java b/src/main/java/org/jabref/gui/Globals.java index 26d56c302c6..c95ceed3153 100644 --- a/src/main/java/org/jabref/gui/Globals.java +++ b/src/main/java/org/jabref/gui/Globals.java @@ -8,7 +8,6 @@ import org.jabref.gui.util.DefaultTaskExecutor; import org.jabref.gui.util.TaskExecutor; import org.jabref.logic.journals.JournalAbbreviationRepository; -import org.jabref.logic.journals.predatory.PredatoryJournalRepository; import org.jabref.logic.protectedterms.ProtectedTermsLoader; import org.jabref.logic.remote.RemotePreferences; import org.jabref.logic.remote.server.RemoteListenerServerManager; @@ -51,8 +50,6 @@ public class Globals { * Only GUI code is allowed to access it, logic code should use dependency injection. */ public static JournalAbbreviationRepository journalAbbreviationRepository; - public static PredatoryJournalRepository predatoryJournalRepository; - /** * This field is initialized upon startup. *

diff --git a/src/main/java/org/jabref/gui/JabRefFrame.java b/src/main/java/org/jabref/gui/JabRefFrame.java index 714a6c92e01..02d76834a35 100644 --- a/src/main/java/org/jabref/gui/JabRefFrame.java +++ b/src/main/java/org/jabref/gui/JabRefFrame.java @@ -455,7 +455,6 @@ private void initLayout() { taskExecutor, dialogService, Globals.journalAbbreviationRepository, - Globals.predatoryJournalRepository, entryTypesManager, undoManager, Globals.getClipboardManager()); diff --git a/src/main/java/org/jabref/gui/JabRefGUI.java b/src/main/java/org/jabref/gui/JabRefGUI.java index df0ea784494..6ef229f9cb0 100644 --- a/src/main/java/org/jabref/gui/JabRefGUI.java +++ b/src/main/java/org/jabref/gui/JabRefGUI.java @@ -102,11 +102,6 @@ public void stop() { OOBibBaseConnect.closeOfficeConnection(); Globals.stopBackgroundTasks(); Globals.shutdownThreadPools(); - try { - Globals.predatoryJournalRepository.close(); - } catch (Exception e) { - LOGGER.warn("Cloud not shut down predatoryJournalRepository", e); - } } private void setupProxy() { diff --git a/src/main/java/org/jabref/gui/MainMenu.java b/src/main/java/org/jabref/gui/MainMenu.java index 566290dd4e3..b145c678dfe 100644 --- a/src/main/java/org/jabref/gui/MainMenu.java +++ b/src/main/java/org/jabref/gui/MainMenu.java @@ -66,7 +66,6 @@ import org.jabref.logic.importer.IdFetcher; import org.jabref.logic.importer.WebFetchers; import org.jabref.logic.journals.JournalAbbreviationRepository; -import org.jabref.logic.journals.predatory.PredatoryJournalRepository; import org.jabref.logic.l10n.Localization; import org.jabref.logic.util.OS; import org.jabref.model.entry.BibEntryTypesManager; @@ -84,7 +83,6 @@ public class MainMenu extends MenuBar { private final TaskExecutor taskExecutor; private final DialogService dialogService; private final JournalAbbreviationRepository abbreviationRepository; - private final PredatoryJournalRepository predatoryJournalRepository; private final BibEntryTypesManager entryTypesManager; private final UndoManager undoManager; private final ClipBoardManager clipBoardManager; @@ -98,7 +96,6 @@ public MainMenu(JabRefFrame frame, TaskExecutor taskExecutor, DialogService dialogService, JournalAbbreviationRepository abbreviationRepository, - PredatoryJournalRepository predatoryJournalRepository, BibEntryTypesManager entryTypesManager, UndoManager undoManager, ClipBoardManager clipBoardManager) { @@ -111,7 +108,6 @@ public MainMenu(JabRefFrame frame, this.taskExecutor = taskExecutor; this.dialogService = dialogService; this.abbreviationRepository = abbreviationRepository; - this.predatoryJournalRepository = predatoryJournalRepository; this.entryTypesManager = entryTypesManager; this.undoManager = undoManager; this.clipBoardManager = clipBoardManager; @@ -229,7 +225,7 @@ private void createMenu() { quality.getItems().addAll( factory.createMenuItem(StandardActions.FIND_DUPLICATES, new DuplicateSearch(frame::getCurrentLibraryTab, dialogService, stateManager, preferencesService, entryTypesManager, taskExecutor)), factory.createMenuItem(StandardActions.MERGE_ENTRIES, new MergeEntriesAction(dialogService, stateManager, preferencesService)), - factory.createMenuItem(StandardActions.CHECK_INTEGRITY, new IntegrityCheckAction(frame::getCurrentLibraryTab, preferencesService, dialogService, stateManager, taskExecutor, abbreviationRepository, predatoryJournalRepository)), + factory.createMenuItem(StandardActions.CHECK_INTEGRITY, new IntegrityCheckAction(frame::getCurrentLibraryTab, preferencesService, dialogService, stateManager, taskExecutor, abbreviationRepository)), factory.createMenuItem(StandardActions.CLEANUP_ENTRIES, new CleanupAction(frame::getCurrentLibraryTab, preferencesService, dialogService, stateManager, taskExecutor, undoManager)), new SeparatorMenuItem(), diff --git a/src/main/java/org/jabref/gui/integrity/IntegrityCheckAction.java b/src/main/java/org/jabref/gui/integrity/IntegrityCheckAction.java index 472efce865e..aaa34b0fe69 100644 --- a/src/main/java/org/jabref/gui/integrity/IntegrityCheckAction.java +++ b/src/main/java/org/jabref/gui/integrity/IntegrityCheckAction.java @@ -15,7 +15,6 @@ import org.jabref.logic.integrity.IntegrityCheck; import org.jabref.logic.integrity.IntegrityMessage; import org.jabref.logic.journals.JournalAbbreviationRepository; -import org.jabref.logic.journals.predatory.PredatoryJournalRepository; import org.jabref.logic.l10n.Localization; import org.jabref.model.database.BibDatabaseContext; import org.jabref.model.entry.BibEntry; @@ -31,23 +30,19 @@ public class IntegrityCheckAction extends SimpleCommand { private final PreferencesService preferencesService; private final StateManager stateManager; private final JournalAbbreviationRepository abbreviationRepository; - private final PredatoryJournalRepository predatoryJournalRepository; public IntegrityCheckAction(Supplier tabSupplier, PreferencesService preferencesService, DialogService dialogService, StateManager stateManager, TaskExecutor taskExecutor, - JournalAbbreviationRepository abbreviationRepository, - PredatoryJournalRepository predatoryJournalRepository) { + JournalAbbreviationRepository abbreviationRepository) { this.tabSupplier = tabSupplier; this.stateManager = stateManager; this.taskExecutor = taskExecutor; this.preferencesService = preferencesService; this.dialogService = dialogService; this.abbreviationRepository = abbreviationRepository; - this.predatoryJournalRepository = predatoryJournalRepository; - this.executable.bind(needsDatabase(this.stateManager)); } @@ -58,7 +53,6 @@ public void execute() { preferencesService.getFilePreferences(), preferencesService.getCitationKeyPatternPreferences(), abbreviationRepository, - predatoryJournalRepository, preferencesService.getEntryEditorPreferences().shouldAllowIntegerEditionBibtex()); Task> task = new Task<>() { diff --git a/src/main/java/org/jabref/logic/integrity/IntegrityCheck.java b/src/main/java/org/jabref/logic/integrity/IntegrityCheck.java index bcf87382a55..9015da2efd1 100644 --- a/src/main/java/org/jabref/logic/integrity/IntegrityCheck.java +++ b/src/main/java/org/jabref/logic/integrity/IntegrityCheck.java @@ -6,7 +6,6 @@ import org.jabref.logic.citationkeypattern.CitationKeyPatternPreferences; import org.jabref.logic.journals.JournalAbbreviationRepository; -import org.jabref.logic.journals.predatory.PredatoryJournalRepository; import org.jabref.model.database.BibDatabase; import org.jabref.model.database.BibDatabaseContext; import org.jabref.model.entry.BibEntry; @@ -23,7 +22,6 @@ public IntegrityCheck(BibDatabaseContext bibDatabaseContext, FilePreferences filePreferences, CitationKeyPatternPreferences citationKeyPatternPreferences, JournalAbbreviationRepository journalAbbreviationRepository, - PredatoryJournalRepository predatoryJournalRepository, boolean allowIntegerEdition) { this.bibDatabaseContext = bibDatabaseContext; @@ -42,10 +40,8 @@ public IntegrityCheck(BibDatabaseContext bibDatabaseContext, new CitationKeyDuplicationChecker(bibDatabaseContext.getDatabase()), new AmpersandChecker(), new LatexIntegrityChecker(), - new JournalInAbbreviationListChecker(StandardField.JOURNAL, journalAbbreviationRepository), - new PredatoryJournalChecker(predatoryJournalRepository, - List.of(StandardField.JOURNAL, StandardField.PUBLISHER, StandardField.BOOKTITLE)) - )); + new JournalInAbbreviationListChecker(StandardField.JOURNAL, journalAbbreviationRepository))); + if (bibDatabaseContext.isBiblatexMode()) { entryCheckers.add(new UTF8Checker(bibDatabaseContext.getMetaData().getEncoding().orElse(StandardCharsets.UTF_8))); } else { diff --git a/src/main/java/org/jabref/logic/integrity/PredatoryJournalChecker.java b/src/main/java/org/jabref/logic/integrity/PredatoryJournalChecker.java deleted file mode 100644 index eb4f7030ced..00000000000 --- a/src/main/java/org/jabref/logic/integrity/PredatoryJournalChecker.java +++ /dev/null @@ -1,29 +0,0 @@ -package org.jabref.logic.integrity; - -import java.util.List; -import java.util.Objects; - -import org.jabref.logic.journals.predatory.PredatoryJournalRepository; -import org.jabref.logic.l10n.Localization; -import org.jabref.model.entry.BibEntry; -import org.jabref.model.entry.field.Field; - -public class PredatoryJournalChecker implements EntryChecker { - - private final PredatoryJournalRepository predatoryJournalRepository; - private final List fieldNames; - - public PredatoryJournalChecker(PredatoryJournalRepository predatoryJournalRepository, List fieldsToCheck) { - this.predatoryJournalRepository = Objects.requireNonNull(predatoryJournalRepository); - this.fieldNames = fieldsToCheck; - } - - @Override - public List check(BibEntry entry) { - return entry.getFieldMap().entrySet().stream() - .filter(field -> fieldNames.contains(field.getKey())) - .filter(field -> predatoryJournalRepository.isKnownName(field.getValue())) - .map(field -> new IntegrityMessage(Localization.lang("Predatory journal %0 found", field.getValue()), entry, field.getKey())) - .toList(); - } -} diff --git a/src/main/java/org/jabref/logic/journals/predatory/PredatoryJournalInformation.java b/src/main/java/org/jabref/logic/journals/predatory/PredatoryJournalInformation.java deleted file mode 100644 index 83c936f8748..00000000000 --- a/src/main/java/org/jabref/logic/journals/predatory/PredatoryJournalInformation.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.jabref.logic.journals.predatory; - -import java.io.Serializable; - -/** - * Represents predatory journal information - * - * @param name The full journal name - * @param abbr Abbreviation, if any - * @param url Url of the journal - */ -public record PredatoryJournalInformation( - String name, - String abbr, - String url) implements Serializable { // must implement @Serializable otherwise MVStore fails -} diff --git a/src/main/java/org/jabref/logic/journals/predatory/PredatoryJournalListCrawler.java b/src/main/java/org/jabref/logic/journals/predatory/PredatoryJournalListCrawler.java deleted file mode 100644 index dfedda4eec5..00000000000 --- a/src/main/java/org/jabref/logic/journals/predatory/PredatoryJournalListCrawler.java +++ /dev/null @@ -1,160 +0,0 @@ -package org.jabref.logic.journals.predatory; - -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.Reader; -import java.net.MalformedURLException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Optional; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.jabref.logic.net.URLDownload; -import org.jabref.model.strings.StringUtil; - -import org.apache.commons.csv.CSVFormat; -import org.apache.commons.csv.CSVParser; -import org.apache.commons.csv.CSVRecord; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Converts (hard-coded) online resources to a set. {@link #loadFromOnlineSources} is the method containing the result. - */ -public class PredatoryJournalListCrawler { - - private record PJSource(URL url, Optional elementPattern) { - PJSource(String url, String regex) { - this(createURL(url), Optional.of(Pattern.compile(regex))); - } - - PJSource(String url) { - this(createURL(url), Optional.empty()); - } - - private static URL createURL(String urlString) { - try { - return new URI(urlString).toURL(); - } catch (MalformedURLException | URISyntaxException ex) { - throw new IllegalArgumentException("Malformed URL has occurred in PJSource", ex); - } - } - } - - private static final Logger LOGGER = LoggerFactory.getLogger(PredatoryJournalListCrawler.class); - private static final Pattern PATTERN_NAME = Pattern.compile("(?<=\">).*?(?=<)"); - private static final Pattern PATTERN_URL = Pattern.compile("http.*?(?=\")"); - private static final Pattern PATTERN_ABBR = Pattern.compile("(?<=\\()[^ ]*(?=\\))"); - private final List predatorySources = List.of( - new PJSource("https://raw.githubusercontent.com/stop-predatory-journals/stop-predatory-journals.github.io/master/_data/journals.csv"), - new PJSource("https://raw.githubusercontent.com/stop-predatory-journals/stop-predatory-journals.github.io/master/_data/publishers.csv"), - new PJSource("https://beallslist.net/", - "

  • .*?
  • "), - new PJSource("https://beallslist.net/standalone-journals/", - "
  • .*?
  • "), - new PJSource("https://beallslist.net/hijacked-journals/", - ".*?") - ); - - private final List linkElements = new ArrayList<>(); - - private final List predatoryJournalInformation = new ArrayList<>(); - - /** - * Loads predatory journal information from online resources - * This method should be only called once when building JabRef - * - * @return the set of journal information - */ - public HashSet loadFromOnlineSources() { - predatorySources.forEach(this::crawl); - linkElements.forEach(this::clean); - return new HashSet<>(predatoryJournalInformation); - } - - private void crawl(PJSource source) { - try { - URLDownload download = new URLDownload(source.url); - - if (!download.canBeReached()) { - LOGGER.warn("Url {} is unreachable", source.url); - } else if (source.url.getPath().contains(".csv")) { - handleCSV(new InputStreamReader(download.asInputStream())); - } else { - if (source.elementPattern.isPresent()) { - handleHTML(source.elementPattern.get(), download.asString()); - } - } - } catch (IOException ex) { - LOGGER.error("Could not crawl source for predatory journals {}", source.url, ex); - } - } - - private void handleCSV(Reader reader) throws IOException { - CSVFormat format = CSVFormat.EXCEL.builder().setSkipHeaderRecord(true).build(); - CSVParser csvParser = new CSVParser(reader, format); - - for (CSVRecord csvRecord : csvParser) { - String name = csvRecord.get(1); - String abbr = csvRecord.get(2); - String url = csvRecord.get(0); - - if (StringUtil.isNullOrEmpty(name)) { - if (!abbr.isEmpty()) { - name = abbr; - } else { - continue; - } - } - // changes column order from CSV (source: url, name, abbr) - predatoryJournalInformation.add(new PredatoryJournalInformation(decode(name), decode(abbr), url)); - } - } - - private void handleHTML(Pattern pattern, String body) { - Matcher matcher = pattern.matcher(body); - while (matcher.find()) { - linkElements.add(matcher.group()); - } - } - - private void clean(String item) { - Matcher m_name = PATTERN_NAME.matcher(item); - Matcher m_url = PATTERN_URL.matcher(item); - Matcher m_abbr = PATTERN_ABBR.matcher(item); - - // using `if` gets only first link in element, `while` gets all, but this may not be desirable - // e.g. this way only the hijacked journals are recorded and not the authentic originals - if (m_name.find() && m_url.find()) { - String name = m_name.group(); - if (name != null) { - name = name.replace("\u200B", ""); // zero width space - } - String abbr = m_abbr.find() ? m_abbr.group() : ""; - String url = m_url.group(); - - if (StringUtil.isNullOrEmpty(name)) { - if (!abbr.isEmpty()) { - name = abbr; - } else { - return; - } - } - predatoryJournalInformation.add(new PredatoryJournalInformation(decode(name), decode(abbr), url)); - } - } - - private String decode(String s) { - return Optional.ofNullable(s) - .orElse("") - .replace(",", "") - .replace("&", "&") - .replace("’", "'") - .replace("–", "-"); - } -} diff --git a/src/main/java/org/jabref/logic/journals/predatory/PredatoryJournalListLoader.java b/src/main/java/org/jabref/logic/journals/predatory/PredatoryJournalListLoader.java deleted file mode 100644 index 011f6e38fd8..00000000000 --- a/src/main/java/org/jabref/logic/journals/predatory/PredatoryJournalListLoader.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.jabref.logic.journals.predatory; - -import java.io.IOException; -import java.io.InputStream; -import java.nio.file.Files; -import java.nio.file.Path; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class PredatoryJournalListLoader { - - private static final Logger LOGGER = LoggerFactory.getLogger(PredatoryJournalListLoader.class); - - public static PredatoryJournalRepository loadRepository() { - PredatoryJournalRepository repository = new PredatoryJournalRepository(); - // Initialize with built-in list - // We cannot use PredatoryJournalRepository.class.getResource, because this is null in JPackage, thus we need "getResourceAsStream" - try (InputStream resourceAsStream = PredatoryJournalListLoader.class.getResourceAsStream("/journals/predatory-journals.mv")) { - if (resourceAsStream == null) { - LOGGER.warn("There is no predatory-journal.mv. We use a default predatory dummy list"); - repository = new PredatoryJournalRepository(); - } else { - // MVStore does not support loading from stream. Thus, we need to have a file copy of the stream. - Path tempDir = Files.createTempDirectory("jabref-journal"); - Path tempJournalList = tempDir.resolve("predatory-journals.mv"); - Files.copy(resourceAsStream, tempJournalList); - repository = new PredatoryJournalRepository(tempJournalList); - tempDir.toFile().deleteOnExit(); - tempJournalList.toFile().deleteOnExit(); - } - } catch (IOException e) { - LOGGER.error("Error while copying journal list", e); - } - return repository; - } -} diff --git a/src/main/java/org/jabref/logic/journals/predatory/PredatoryJournalRepository.java b/src/main/java/org/jabref/logic/journals/predatory/PredatoryJournalRepository.java deleted file mode 100644 index 2c73530daff..00000000000 --- a/src/main/java/org/jabref/logic/journals/predatory/PredatoryJournalRepository.java +++ /dev/null @@ -1,67 +0,0 @@ -package org.jabref.logic.journals.predatory; - -import java.nio.file.Path; -import java.util.Locale; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.stream.Collectors; - -import org.jabref.logic.util.strings.StringSimilarity; - -import org.h2.mvstore.MVMap; -import org.h2.mvstore.MVStore; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * A repository for all predatory journals and publishers, including add and find methods. - */ -public class PredatoryJournalRepository implements AutoCloseable { - private final Logger LOGGER = LoggerFactory.getLogger(PredatoryJournalRepository.class); - private final Map predatoryJournals; - private final StringSimilarity match = new StringSimilarity(); - private final MVStore store; - - /** - * Initializes the internal data based on the predatory journals found in the given MV file - */ - public PredatoryJournalRepository(Path mvStore) { - MVMap predatoryJournalsMap; - store = new MVStore.Builder().readOnly().fileName(mvStore.toAbsolutePath().toString()).open(); - predatoryJournals = store.openMap("PredatoryJournals"); - } - - /** - * Initializes the repository with demonstration data. Used if no abbreviation file is found. - */ - public PredatoryJournalRepository() { - store = null; - predatoryJournals = Map.of("Demo", new PredatoryJournalInformation("Demo", "Demo", "")); - } - - /** - * Returns true if the given journal name is contained in the list in its full form - */ - public boolean isKnownName(String journalName) { - String journal = journalName.trim().replaceAll(Matcher.quoteReplacement("\\&"), "&"); - - if (predatoryJournals.containsKey(journal)) { - LOGGER.debug("Found predatory journal {}", journal); - return true; - } - - var matches = predatoryJournals.keySet().stream() - .filter(key -> match.isSimilar(journal.toLowerCase(Locale.ROOT), key.toLowerCase(Locale.ROOT))) - .collect(Collectors.toList()); - - LOGGER.info("Found multiple possible predatory journals {}", String.join(", ", matches)); - return !matches.isEmpty(); - } - - @Override - public void close() throws Exception { - if (store != null) { - store.close(); - } - } -} diff --git a/src/main/resources/l10n/JabRef_en.properties b/src/main/resources/l10n/JabRef_en.properties index d72fceb0f63..f80fbcbef55 100644 --- a/src/main/resources/l10n/JabRef_en.properties +++ b/src/main/resources/l10n/JabRef_en.properties @@ -2623,8 +2623,6 @@ Would\ you\ like\ to\ enable\ fetching\ of\ journal\ information?\ This\ can\ be Enable=Enable Keep\ disabled=Keep disabled -Predatory\ journal\ %0\ found=Predatory journal %0 found - Hide\ user\ comments=Hide user comments Show\ user\ comments\ field=Show user comments field diff --git a/src/test/java/org/jabref/logic/integrity/IntegrityCheckTest.java b/src/test/java/org/jabref/logic/integrity/IntegrityCheckTest.java index d7229ac2062..4273ce59ccf 100644 --- a/src/test/java/org/jabref/logic/integrity/IntegrityCheckTest.java +++ b/src/test/java/org/jabref/logic/integrity/IntegrityCheckTest.java @@ -12,8 +12,6 @@ import org.jabref.logic.citationkeypattern.CitationKeyPatternPreferences; import org.jabref.logic.citationkeypattern.GlobalCitationKeyPattern; import org.jabref.logic.journals.JournalAbbreviationLoader; -import org.jabref.logic.journals.predatory.PredatoryJournalListLoader; -import org.jabref.logic.journals.predatory.PredatoryJournalRepository; import org.jabref.model.database.BibDatabase; import org.jabref.model.database.BibDatabaseContext; import org.jabref.model.database.BibDatabaseMode; @@ -137,14 +135,12 @@ void entryIsUnchangedAfterChecks() throws Exception { bibDatabase.insertEntry(entry); BibDatabaseContext context = new BibDatabaseContext(bibDatabase); - try (PredatoryJournalRepository predatoryJournalRepository = PredatoryJournalListLoader.loadRepository()) { - new IntegrityCheck(context, - mock(FilePreferences.class), - createCitationKeyPatternPreferences(), - JournalAbbreviationLoader.loadBuiltInRepository(), - predatoryJournalRepository, false) - .check(); - } + new IntegrityCheck(context, + mock(FilePreferences.class), + createCitationKeyPatternPreferences(), + JournalAbbreviationLoader.loadBuiltInRepository(), + false) + .check(); assertEquals(clonedEntry, entry); } @@ -173,14 +169,14 @@ private BibDatabaseContext createContext(Field field, String value) { private void assertWrong(BibDatabaseContext context) throws Exception { List messages; - try (PredatoryJournalRepository predatoryJournalRepository = PredatoryJournalListLoader.loadRepository()) { - messages = new IntegrityCheck(context, - mock(FilePreferences.class), - createCitationKeyPatternPreferences(), - JournalAbbreviationLoader.loadBuiltInRepository(), - predatoryJournalRepository, false) - .check(); - } + + messages = new IntegrityCheck(context, + mock(FilePreferences.class), + createCitationKeyPatternPreferences(), + JournalAbbreviationLoader.loadBuiltInRepository(), + false) + .check(); + assertNotEquals(Collections.emptyList(), messages); } @@ -188,14 +184,14 @@ private void assertCorrect(BibDatabaseContext context) throws Exception { FilePreferences filePreferencesMock = mock(FilePreferences.class); when(filePreferencesMock.shouldStoreFilesRelativeToBibFile()).thenReturn(true); List messages; - try (PredatoryJournalRepository predatoryJournalRepository = PredatoryJournalListLoader.loadRepository()) { - messages = new IntegrityCheck(context, - filePreferencesMock, - createCitationKeyPatternPreferences(), - JournalAbbreviationLoader.loadBuiltInRepository(), - predatoryJournalRepository, false) - .check(); - } + + messages = new IntegrityCheck(context, + filePreferencesMock, + createCitationKeyPatternPreferences(), + JournalAbbreviationLoader.loadBuiltInRepository(), + false) + .check(); + assertEquals(Collections.emptyList(), messages); } diff --git a/src/test/java/org/jabref/logic/integrity/PredatoryJournalCheckerTest.java b/src/test/java/org/jabref/logic/integrity/PredatoryJournalCheckerTest.java deleted file mode 100644 index 74f9caa093f..00000000000 --- a/src/test/java/org/jabref/logic/integrity/PredatoryJournalCheckerTest.java +++ /dev/null @@ -1,78 +0,0 @@ -package org.jabref.logic.integrity; - -import java.util.Collections; -import java.util.List; - -import org.jabref.logic.journals.predatory.PredatoryJournalListLoader; -import org.jabref.logic.journals.predatory.PredatoryJournalRepository; -import org.jabref.model.entry.BibEntry; -import org.jabref.model.entry.field.StandardField; - -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -class PredatoryJournalCheckerTest { - - static PredatoryJournalChecker checker; - static PredatoryJournalRepository predatoryJournalRepository = PredatoryJournalListLoader.loadRepository(); - - @BeforeAll - static void initChecker() { - checker = new PredatoryJournalChecker(predatoryJournalRepository, - List.of(StandardField.JOURNAL, StandardField.PUBLISHER, StandardField.BOOKTITLE)); - } - - @AfterAll - static void close() throws Exception { - predatoryJournalRepository.close(); - } - - @Test - void journalIsNotPredatory() { - BibEntry entry = new BibEntry().withField(StandardField.JOURNAL, "IEEE Software"); - assertEquals(Collections.emptyList(), checker.check(entry)); - } - - @Test - void journalIsPredatory() { - String journalName = "European International Journal of Science and Technology"; - BibEntry entry = new BibEntry().withField(StandardField.JOURNAL, journalName); - assertEquals(List.of(new IntegrityMessage("Predatory journal %s found".formatted(journalName), - entry, StandardField.JOURNAL)), checker.check(entry)); - } - - @Test - void journalIsPredatoryCaseInsensitive() { - String journalName = "european international journal of science and technology"; - BibEntry entry = new BibEntry().withField(StandardField.JOURNAL, journalName); - assertEquals(List.of(new IntegrityMessage("Predatory journal %s found".formatted(journalName), - entry, StandardField.JOURNAL)), checker.check(entry)); - } - - @Test - void journalIsPredatoryExtraCharacters() { - String journalName = "European International Journal, of Science and Technology"; - BibEntry entry = new BibEntry().withField(StandardField.JOURNAL, journalName); - assertEquals(List.of(new IntegrityMessage("Predatory journal %s found".formatted(journalName), - entry, StandardField.JOURNAL)), checker.check(entry)); - } - - @Test - void publisherIsPredatory() { - String publisherName = "Academia Scholarly Journals"; - BibEntry entry = new BibEntry().withField(StandardField.PUBLISHER, publisherName); - assertEquals(List.of(new IntegrityMessage("Predatory journal %s found".formatted(publisherName), - entry, StandardField.PUBLISHER)), checker.check(entry)); - } - - @Test - void bookTitleIsPredatory() { - String bookTitle = "Biosciences International"; - BibEntry entry = new BibEntry().withField(StandardField.BOOKTITLE, bookTitle); - assertEquals(List.of(new IntegrityMessage("Predatory journal %s found".formatted(bookTitle), - entry, StandardField.BOOKTITLE)), checker.check(entry)); - } -}