From 724d499845b21bfe9f86fa3d8daabc27bb038317 Mon Sep 17 00:00:00 2001 From: NikodemKch Date: Thu, 13 Feb 2020 02:25:56 +0100 Subject: [PATCH 1/7] GROBID integration using new fetcher Add the possibility to extract references from plain text using the GROBID service. GROBID is called over a custom server. See also pull request #5614 Co-Authored-By: joeyzgraggen Co-Authored-By: guenesaydin Co-Authored-By: obsluk00 Co-Authored-By: nikodemkch --- src/main/java/org/jabref/gui/JabRefFrame.java | 3 +- .../jabref/gui/actions/StandardActions.java | 3 +- .../BibtexExtractorViewModel.java | 52 +++++--- .../bibtexextractor/ExtractBibtexDialog.fxml | 10 +- .../bibtexextractor/ExtractBibtexDialog.java | 32 +++-- .../java/org/jabref/gui/icon/IconTheme.java | 3 +- .../org/jabref/gui/keyboard/KeyBinding.java | 2 +- .../jabref/logic/importer/WebFetchers.java | 2 + .../fetcher/GrobidCitationFetcher.java | 77 ++++++++++++ .../logic/importer/util/GrobidService.java | 53 +++++++++ src/main/resources/l10n/JabRef_en.properties | 14 ++- .../fetcher/GrobidCitationFetcherTest.java | 112 ++++++++++++++++++ .../importer/util/GrobidServiceTest.java | 54 +++++++++ 13 files changed, 376 insertions(+), 41 deletions(-) create mode 100644 src/main/java/org/jabref/logic/importer/fetcher/GrobidCitationFetcher.java create mode 100644 src/main/java/org/jabref/logic/importer/util/GrobidService.java create mode 100644 src/test/java/org/jabref/logic/importer/fetcher/GrobidCitationFetcherTest.java create mode 100644 src/test/java/org/jabref/logic/importer/util/GrobidServiceTest.java diff --git a/src/main/java/org/jabref/gui/JabRefFrame.java b/src/main/java/org/jabref/gui/JabRefFrame.java index 7fd1df234f9..935e36edbb2 100644 --- a/src/main/java/org/jabref/gui/JabRefFrame.java +++ b/src/main/java/org/jabref/gui/JabRefFrame.java @@ -480,6 +480,7 @@ private Node createToolbar() { HBox rightSide = new HBox( factory.createIconButton(StandardActions.NEW_ARTICLE, new NewEntryAction(this, StandardEntryType.Article, dialogService, Globals.prefs, stateManager)), factory.createIconButton(StandardActions.NEW_ENTRY, new NewEntryAction(this, dialogService, Globals.prefs, stateManager)), + factory.createIconButton(StandardActions.NEW_ENTRY_FROM_PLAIN_TEXT, new ExtractBibtexAction(stateManager)), factory.createIconButton(StandardActions.DELETE_ENTRY, new OldDatabaseCommandWrapper(Actions.DELETE, this, stateManager)), new Separator(Orientation.VERTICAL), factory.createIconButton(StandardActions.UNDO, new OldDatabaseCommandWrapper(Actions.UNDO, this, stateManager)), @@ -728,6 +729,7 @@ private MenuBar createMenu() { //@formatter:off library.getItems().addAll( factory.createMenuItem(StandardActions.NEW_ENTRY, new NewEntryAction(this, dialogService, Globals.prefs, stateManager)), + factory.createMenuItem(StandardActions.NEW_ENTRY_FROM_PLAIN_TEXT, new ExtractBibtexAction(stateManager)), factory.createMenuItem(StandardActions.DELETE_ENTRY, new OldDatabaseCommandWrapper(Actions.DELETE, this, stateManager)), new SeparatorMenuItem(), @@ -767,7 +769,6 @@ private MenuBar createMenu() { factory.createMenuItem(StandardActions.FIND_UNLINKED_FILES, new FindUnlinkedFilesAction(this, stateManager)), factory.createMenuItem(StandardActions.WRITE_XMP, new OldDatabaseCommandWrapper(Actions.WRITE_XMP, this, stateManager)), factory.createMenuItem(StandardActions.COPY_LINKED_FILES, new CopyFilesAction(stateManager, this.getDialogService())), - factory.createMenuItem(StandardActions.EXTRACT_BIBTEX, new ExtractBibtexAction(stateManager)), new SeparatorMenuItem(), diff --git a/src/main/java/org/jabref/gui/actions/StandardActions.java b/src/main/java/org/jabref/gui/actions/StandardActions.java index 87f48f1b4a5..245c20e30d5 100644 --- a/src/main/java/org/jabref/gui/actions/StandardActions.java +++ b/src/main/java/org/jabref/gui/actions/StandardActions.java @@ -120,7 +120,7 @@ public enum StandardActions implements Action { NEW_ENTRY(Localization.lang("New entry"), IconTheme.JabRefIcons.ADD_ENTRY, KeyBinding.NEW_ENTRY), NEW_ARTICLE(Localization.lang("New article"), IconTheme.JabRefIcons.ADD_ARTICLE), - NEW_ENTRY_FROM_PLAINTEX(Localization.lang("New entry from plain text"), KeyBinding.NEW_FROM_PLAIN_TEXT), + NEW_ENTRY_FROM_PLAIN_TEXT(Localization.lang("New entry from plain text"), IconTheme.JabRefIcons.NEW_ENTRY_FROM_PLAIN_TEXT, KeyBinding.NEW_ENTRY_FROM_PLAIN_TEXT), LIBRARY_PROPERTIES(Localization.lang("Library properties")), EDIT_PREAMBLE(Localization.lang("Edit preamble")), EDIT_STRINGS(Localization.lang("Edit string constants"), IconTheme.JabRefIcons.EDIT_STRINGS, KeyBinding.EDIT_STRINGS), @@ -138,7 +138,6 @@ public enum StandardActions implements Action { DOWNLOAD_FULL_TEXT(Localization.lang("Search full text documents online"), IconTheme.JabRefIcons.FILE_SEARCH, KeyBinding.DOWNLOAD_FULL_TEXT), CLEANUP_ENTRIES(Localization.lang("Cleanup entries"), IconTheme.JabRefIcons.CLEANUP_ENTRIES, KeyBinding.CLEANUP), SET_FILE_LINKS(Localization.lang("Automatically set file links"), KeyBinding.AUTOMATICALLY_LINK_FILES), - EXTRACT_BIBTEX(Localization.lang("Extract BibTeX from plain text")), HELP(Localization.lang("Online help"), IconTheme.JabRefIcons.HELP, KeyBinding.HELP), HELP_KEY_PATTERNS(Localization.lang("Help on key patterns"), IconTheme.JabRefIcons.HELP, KeyBinding.HELP), diff --git a/src/main/java/org/jabref/gui/bibtexextractor/BibtexExtractorViewModel.java b/src/main/java/org/jabref/gui/bibtexextractor/BibtexExtractorViewModel.java index 8eb694bd692..8f376810ca8 100644 --- a/src/main/java/org/jabref/gui/bibtexextractor/BibtexExtractorViewModel.java +++ b/src/main/java/org/jabref/gui/bibtexextractor/BibtexExtractorViewModel.java @@ -3,40 +3,60 @@ import java.util.HashMap; import java.util.Map; +import javax.swing.undo.UndoManager; + import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.StringProperty; import org.jabref.Globals; +import org.jabref.gui.DialogService; +import org.jabref.gui.StateManager; +import org.jabref.gui.externalfiles.ImportHandler; +import org.jabref.gui.externalfiletype.ExternalFileTypes; +import org.jabref.gui.util.BackgroundTask; +import org.jabref.gui.util.TaskExecutor; +import org.jabref.logic.importer.fetcher.GrobidCitationFetcher; +import org.jabref.logic.l10n.Localization; import org.jabref.model.database.BibDatabaseContext; import org.jabref.model.entry.BibEntry; -import org.jabref.model.entry.types.EntryType; -import org.jabref.model.entry.types.StandardEntryType; +import org.jabref.model.util.FileUpdateMonitor; +import org.jabref.preferences.JabRefPreferences; public class BibtexExtractorViewModel { private final StringProperty inputTextProperty = new SimpleStringProperty(""); - private final BibDatabaseContext bibdatabaseContext; - - public BibtexExtractorViewModel(BibDatabaseContext bibdatabaseContext) { - this.bibdatabaseContext = bibdatabaseContext; + private DialogService dialogService; + private GrobidCitationFetcher currentCitationfetcher; + private TaskExecutor taskExecutor; + private ImportHandler importHandler; + + public BibtexExtractorViewModel(BibDatabaseContext bibdatabaseContext, DialogService dialogService, + JabRefPreferences jabRefPreferences, FileUpdateMonitor fileUpdateMonitor, TaskExecutor taskExecutor, UndoManager undoManager, StateManager stateManager) { + this.dialogService = dialogService; + currentCitationfetcher = new GrobidCitationFetcher(jabRefPreferences.getImportFormatPreferences()); + this.taskExecutor = taskExecutor; + this.importHandler = new ImportHandler(dialogService, bibdatabaseContext, ExternalFileTypes.getInstance(), jabRefPreferences.getFilePreferences(), jabRefPreferences.getImportFormatPreferences(), jabRefPreferences.getUpdateFieldPreferences(), fileUpdateMonitor, undoManager, stateManager); } public StringProperty inputTextProperty() { return this.inputTextProperty; } - public void startExtraction() { - - BibtexExtractor extractor = new BibtexExtractor(); - BibEntry entity = extractor.extract(inputTextProperty.getValue()); - this.bibdatabaseContext.getDatabase().insertEntry(entity); - trackNewEntry(StandardEntryType.Article); + public void startParsing() { + BackgroundTask.wrap(() -> currentCitationfetcher.performSearch(inputTextProperty.getValue())) + .onRunning(() -> dialogService.notify(Localization.lang("Your text is being parsed..."))) + .onSuccess(parsedEntries -> { + dialogService.notify(Localization.lang("GROBID could parse %0 Entries from your query.", String.valueOf(parsedEntries.size()))); + importHandler.importEntries(parsedEntries); + for (BibEntry bibEntry : parsedEntries) { + trackNewEntry(bibEntry); + } + }).executeWith(taskExecutor); } - private void trackNewEntry(EntryType type) { + private void trackNewEntry(BibEntry bibEntry) { Map properties = new HashMap<>(); - properties.put("EntryType", type.getName()); - - Globals.getTelemetryClient().ifPresent(client -> client.trackEvent("NewEntry", properties, new HashMap<>())); + properties.put("EntryType", bibEntry.typeProperty().getValue().getName()); + Globals.getTelemetryClient().ifPresent(client -> client.trackEvent("ParseWithGrobid", properties, new HashMap<>())); } } diff --git a/src/main/java/org/jabref/gui/bibtexextractor/ExtractBibtexDialog.fxml b/src/main/java/org/jabref/gui/bibtexextractor/ExtractBibtexDialog.fxml index 053024c2a6a..b024323565b 100644 --- a/src/main/java/org/jabref/gui/bibtexextractor/ExtractBibtexDialog.fxml +++ b/src/main/java/org/jabref/gui/bibtexextractor/ExtractBibtexDialog.fxml @@ -4,11 +4,17 @@ + + -