From 0c0db9047644962b4faa23fb2b6406824a2db9c2 Mon Sep 17 00:00:00 2001 From: Nitin Suresh Date: Mon, 5 Jun 2023 08:19:52 -0700 Subject: [PATCH] Add ability to use DOI directly in Web Search (#9969) * add ability to use doi in web search * add changelog entry * update variable initialization * update variable declaration for clarity --- CHANGELOG.md | 1 + .../fetcher/WebSearchPaneViewModel.java | 32 ++++++++++++++++--- .../fetcher/WebSearchPaneViewModelTest.java | 18 +++++++++++ 3 files changed, 47 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a1976aafae2..a0e849d73ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,7 @@ Note that this project **does not** adhere to [Semantic Versioning](http://semve - We added the link icon for ISBNs in linked identifiers column. [#9819](https://github.com/JabRef/jabref/issues/9819) - We added drag and drop events for field 'Groups' in entry editor panel. [#569](https://github.com/koppor/jabref/issues/569) - We added support for parsing MathML in the Medline importer. [#4273](https://github.com/JabRef/jabref/issues/4273) +- We added the ability to search for a DOI directly from 'Web Search'. [#9674](https://github.com/JabRef/jabref/issues/9674) ### Changed diff --git a/src/main/java/org/jabref/gui/importer/fetcher/WebSearchPaneViewModel.java b/src/main/java/org/jabref/gui/importer/fetcher/WebSearchPaneViewModel.java index 6aa6e7177d5..b038a406f5c 100644 --- a/src/main/java/org/jabref/gui/importer/fetcher/WebSearchPaneViewModel.java +++ b/src/main/java/org/jabref/gui/importer/fetcher/WebSearchPaneViewModel.java @@ -1,7 +1,9 @@ package org.jabref.gui.importer.fetcher; import java.util.Map; +import java.util.Optional; import java.util.SortedSet; +import java.util.concurrent.Callable; import javafx.beans.property.ListProperty; import javafx.beans.property.ObjectProperty; @@ -20,8 +22,11 @@ import org.jabref.logic.importer.ParserResult; import org.jabref.logic.importer.SearchBasedFetcher; import org.jabref.logic.importer.WebFetchers; +import org.jabref.logic.importer.fetcher.DoiFetcher; import org.jabref.logic.l10n.Localization; +import org.jabref.model.entry.identifier.DOI; import org.jabref.model.strings.StringUtil; +import org.jabref.model.util.OptionalUtil; import org.jabref.preferences.PreferencesService; import org.jabref.preferences.SidePanePreferences; @@ -43,6 +48,7 @@ public class WebSearchPaneViewModel { private final ListProperty fetchers = new SimpleListProperty<>(FXCollections.observableArrayList()); private final StringProperty query = new SimpleStringProperty(); private final DialogService dialogService; + private final PreferencesService preferencesService; private final StateManager stateManager; private final Validator searchQueryValidator; @@ -51,6 +57,7 @@ public class WebSearchPaneViewModel { public WebSearchPaneViewModel(PreferencesService preferencesService, DialogService dialogService, StateManager stateManager) { this.dialogService = dialogService; this.stateManager = stateManager; + this.preferencesService = preferencesService; SortedSet allFetchers = WebFetchers.getSearchBasedFetchers( preferencesService.getImportFormatPreferences(), @@ -77,6 +84,13 @@ public WebSearchPaneViewModel(PreferencesService preferencesService, DialogServi // in case user did not enter something, it is treated as valid (to avoid UI WTFs) return null; } + + Optional doi = DOI.findInText(queryText); + if (doi.isPresent()) { + // in case the query contains a DOI, it is treated as valid + return null; + } + try { parser.parse(queryText, NO_EXPLICIT_FIELD); return null; @@ -130,16 +144,26 @@ public void search() { } SearchBasedFetcher activeFetcher = getSelectedFetcher(); + Callable parserResultCallable = () -> new ParserResult(activeFetcher.performSearch(query)); + String fetcherName = activeFetcher.getName(); + + Optional doi = DOI.findInText(query); + if (doi.isPresent()) { + DoiFetcher doiFetcher = new DoiFetcher(preferencesService.getImportFormatPreferences()); + parserResultCallable = () -> new ParserResult(OptionalUtil.toList(doiFetcher.performSearchById(doi.get().getDOI()))); + fetcherName = doiFetcher.getName(); + } + + final String finalFetcherName = fetcherName; Globals.getTelemetryClient().ifPresent(client -> - client.trackEvent("search", Map.of("fetcher", activeFetcher.getName()), Map.of())); + client.trackEvent("search", Map.of("fetcher", finalFetcherName), Map.of())); - BackgroundTask task; - task = BackgroundTask.wrap(() -> new ParserResult(activeFetcher.performSearch(query))) + BackgroundTask task = BackgroundTask.wrap(parserResultCallable) .withInitialMessage(Localization.lang("Processing %0", query)); task.onFailure(dialogService::showErrorDialogAndWait); ImportEntriesDialog dialog = new ImportEntriesDialog(stateManager.getActiveDatabase().get(), task); - dialog.setTitle(activeFetcher.getName()); + dialog.setTitle(finalFetcherName); dialogService.showCustomDialogAndWait(dialog); } diff --git a/src/test/java/org/jabref/gui/importer/fetcher/WebSearchPaneViewModelTest.java b/src/test/java/org/jabref/gui/importer/fetcher/WebSearchPaneViewModelTest.java index 6903ce89cae..a1f4a724e16 100644 --- a/src/test/java/org/jabref/gui/importer/fetcher/WebSearchPaneViewModelTest.java +++ b/src/test/java/org/jabref/gui/importer/fetcher/WebSearchPaneViewModelTest.java @@ -57,4 +57,22 @@ void notCorrectQueryValidationStatus() { viewModel.queryProperty().setValue("Miami AND Beach OR Houston AND Texas"); assertFalse(viewModel.queryValidationStatus().validProperty().not().getValue()); } + + @Test + void queryConsistingOfDOIIsValid() { + viewModel.queryProperty().setValue("10.1007/JHEP02(2023)082"); + assertTrue(viewModel.queryValidationStatus().validProperty().getValue()); + } + + @Test + void canExtractDOIFromQueryText() { + viewModel.queryProperty().setValue("this is the DOI: 10.1007/JHEP02(2023)082, other text"); + assertTrue(viewModel.queryValidationStatus().validProperty().getValue()); + } + + @Test + void queryConsistingOfInvalidDOIIsInvalid() { + viewModel.queryProperty().setValue("101.1007/JHEP02(2023)082"); + assertFalse(viewModel.queryValidationStatus().validProperty().getValue()); + } }