From 3ed02ee3b60edf1f3f507e96e4e0655da1d0ced9 Mon Sep 17 00:00:00 2001 From: Robin Date: Thu, 18 Apr 2019 20:48:52 +0200 Subject: [PATCH 1/8] Improve full text search for several files (#4855) * changed BackgroundTask to Task in FindFullTextAction * separated download in LinkedFileViewModel to use in FindFulltextAction * changed progress dialog title --- .../gui/externalfiles/FindFullTextAction.java | 66 +++++++++++++------ .../gui/fieldeditors/LinkedFileViewModel.java | 39 ++++++----- 2 files changed, 67 insertions(+), 38 deletions(-) diff --git a/src/main/java/org/jabref/gui/externalfiles/FindFullTextAction.java b/src/main/java/org/jabref/gui/externalfiles/FindFullTextAction.java index adb6affcc4c..098175d865e 100644 --- a/src/main/java/org/jabref/gui/externalfiles/FindFullTextAction.java +++ b/src/main/java/org/jabref/gui/externalfiles/FindFullTextAction.java @@ -1,19 +1,24 @@ package org.jabref.gui.externalfiles; +import java.net.MalformedURLException; import java.net.URL; import java.nio.file.Path; import java.util.Map; import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; +import javafx.concurrent.Task; + import org.jabref.Globals; import org.jabref.gui.BasePanel; import org.jabref.gui.DialogService; import org.jabref.gui.actions.SimpleCommand; import org.jabref.gui.fieldeditors.LinkedFileViewModel; +import org.jabref.gui.fieldeditors.LinkedFilesEditorViewModel; import org.jabref.gui.util.BackgroundTask; import org.jabref.logic.importer.FulltextFetchers; import org.jabref.logic.l10n.Localization; +import org.jabref.logic.net.URLDownload; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.LinkedFile; import org.jabref.preferences.JabRefPreferences; @@ -63,18 +68,29 @@ public void execute() { return; } } - BackgroundTask.wrap(this::findFullTexts) - .onSuccess(this::downloadFullTexts) - .executeWith(Globals.TASK_EXECUTOR); - } - private Map, BibEntry> findFullTexts() { - Map, BibEntry> downloads = new ConcurrentHashMap<>(); - for (BibEntry entry : basePanel.getSelectedEntries()) { - FulltextFetchers fetchers = new FulltextFetchers(Globals.prefs.getImportFormatPreferences()); - downloads.put(fetchers.findFullTextPDF(entry), entry); - } - return downloads; + Task, BibEntry>> findFullTextsTask = new Task, BibEntry>>() { + @Override + protected Map, BibEntry> call() { + Map, BibEntry> downloads = new ConcurrentHashMap<>(); + int count = 0; + for (BibEntry entry : basePanel.getSelectedEntries()) { + FulltextFetchers fetchers = new FulltextFetchers(Globals.prefs.getImportFormatPreferences()); + downloads.put(fetchers.findFullTextPDF(entry), entry); + updateProgress(++count, basePanel.getSelectedEntries().size()); + } + return downloads; + } + }; + + findFullTextsTask.setOnSucceeded(value -> downloadFullTexts(findFullTextsTask.getValue())); + + dialogService.showProgressDialogAndWait( + Localization.lang("Look up full text documents"), + Localization.lang("Looking for full text document..."), + findFullTextsTask); + + Globals.TASK_EXECUTOR.execute(findFullTextsTask); } private void downloadFullTexts(Map, BibEntry> downloads) { @@ -92,7 +108,7 @@ private void downloadFullTexts(Map, BibEntry> downloads) { return; } //Download and link full text - addLinkedFileFromURL(result.get(), entry); + addLinkedFileFromURL(result.get(), entry, dir.get()); } else { dialogService.notify(Localization.lang("No full text document found for entry %0.", @@ -103,12 +119,13 @@ private void downloadFullTexts(Map, BibEntry> downloads) { /** * This method attaches a linked file from a URL (if not already linked) to an entry using the key and value pair - * from the findFullTexts map + * from the findFullTexts map and then downloads the file into the given targetDirectory * * @param url the url "key" * @param entry the entry "value" + * @param targetDirectory the target directory for the downloaded file */ - private void addLinkedFileFromURL(URL url, BibEntry entry) { + private void addLinkedFileFromURL(URL url, BibEntry entry, Path targetDirectory) { LinkedFile newLinkedFile = new LinkedFile(url, ""); if (!entry.getFiles().contains(newLinkedFile)) { @@ -121,12 +138,21 @@ private void addLinkedFileFromURL(URL url, BibEntry entry) { dialogService, JabRefPreferences.getInstance()); - onlineFile.download(); - - entry.addFile(onlineFile.getFile()); - - dialogService.notify(Localization.lang("Finished downloading full text document for entry %0.", - entry.getCiteKeyOptional().orElse(Localization.lang("undefined")))); + try { + URLDownload urlDownload = new URLDownload(newLinkedFile.getLink()); + BackgroundTask downloadTask = onlineFile.prepareDownloadTask(targetDirectory, urlDownload); + downloadTask.onSuccess(destination -> { + LinkedFile downloadedFile = LinkedFilesEditorViewModel.fromFile( + destination, + basePanel.getBibDatabaseContext().getFileDirectoriesAsPaths(JabRefPreferences.getInstance().getFilePreferences())); + entry.addFile(downloadedFile); + dialogService.notify(Localization.lang("Finished downloading full text document for entry %0.", + entry.getCiteKeyOptional().orElse(Localization.lang("undefined")))); + }); + Globals.TASK_EXECUTOR.execute(downloadTask); + } catch (MalformedURLException exception) { + dialogService.showErrorDialogAndWait(Localization.lang("Invalid URL"), exception); + } } else { dialogService.notify(Localization.lang("Full text document for entry %0 already linked.", entry.getCiteKeyOptional().orElse(Localization.lang("undefined")))); diff --git a/src/main/java/org/jabref/gui/fieldeditors/LinkedFileViewModel.java b/src/main/java/org/jabref/gui/fieldeditors/LinkedFileViewModel.java index f4088320e38..7d843d2188a 100644 --- a/src/main/java/org/jabref/gui/fieldeditors/LinkedFileViewModel.java +++ b/src/main/java/org/jabref/gui/fieldeditors/LinkedFileViewModel.java @@ -394,7 +394,6 @@ public void download() { if (!linkedFile.isOnlineLink()) { throw new UnsupportedOperationException("In order to download the file it has to be an online link"); } - try { Optional targetDirectory = databaseContext.getFirstExistingFileDir(filePreferences); if (!targetDirectory.isPresent()) { @@ -403,23 +402,12 @@ public void download() { } URLDownload urlDownload = new URLDownload(linkedFile.getLink()); - BackgroundTask downloadTask = BackgroundTask - .wrap(() -> { - Optional suggestedType = inferFileType(urlDownload); - String suggestedTypeName = suggestedType.map(ExternalFileType::getName).orElse(""); - linkedFile.setFileType(suggestedTypeName); - - String suggestedName = linkedFileHandler.getSuggestedFileName(); - return targetDirectory.get().resolve(suggestedName); - }) - .then(destination -> new FileDownloadTask(urlDownload.getSource(), destination)) - .onSuccess(destination -> { - LinkedFile newLinkedFile = LinkedFilesEditorViewModel.fromFile(destination, databaseContext.getFileDirectoriesAsPaths(filePreferences)); - linkedFile.setLink(newLinkedFile.getLink()); - linkedFile.setFileType(newLinkedFile.getFileType()); - }) - .onFailure(exception -> dialogService.showErrorDialogAndWait("Download failed", exception)); - + BackgroundTask downloadTask = prepareDownloadTask(targetDirectory.get(), urlDownload); + downloadTask.onSuccess(destination -> { + LinkedFile newLinkedFile = LinkedFilesEditorViewModel.fromFile(destination, databaseContext.getFileDirectoriesAsPaths(filePreferences)); + linkedFile.setLink(newLinkedFile.getLink()); + linkedFile.setFileType(newLinkedFile.getFileType()); + }); downloadProgress.bind(downloadTask.workDonePercentageProperty()); taskExecutor.execute(downloadTask); } catch (MalformedURLException exception) { @@ -427,6 +415,21 @@ public void download() { } } + public BackgroundTask prepareDownloadTask(Path targetDirectory, URLDownload urlDownload) { + BackgroundTask downloadTask = BackgroundTask + .wrap(() -> { + Optional suggestedType = inferFileType(urlDownload); + String suggestedTypeName = suggestedType.map(ExternalFileType::getName).orElse(""); + linkedFile.setFileType(suggestedTypeName); + + String suggestedName = linkedFileHandler.getSuggestedFileName(); + return targetDirectory.resolve(suggestedName); + }) + .then(destination -> new FileDownloadTask(urlDownload.getSource(), destination)) + .onFailure(exception -> dialogService.showErrorDialogAndWait("Download failed", exception)); + return downloadTask; + } + private Optional inferFileType(URLDownload urlDownload) { Optional suggestedType = inferFileTypeFromMimeType(urlDownload); From d93ed17410ca4f54fde021dcc1f5f4737a8a585a Mon Sep 17 00:00:00 2001 From: Christoph Date: Thu, 18 Apr 2019 22:52:17 +0200 Subject: [PATCH 2/8] Store column widths as integer (#4896) Fixes #4579 --- .../maintable/PersistenceVisualStateTable.java | 6 +++--- .../jabref/gui/preferences/TableColumnsTab.java | 16 ++++++++-------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/jabref/gui/maintable/PersistenceVisualStateTable.java b/src/main/java/org/jabref/gui/maintable/PersistenceVisualStateTable.java index 8ee6bd949d1..0b7d7b1dbb4 100644 --- a/src/main/java/org/jabref/gui/maintable/PersistenceVisualStateTable.java +++ b/src/main/java/org/jabref/gui/maintable/PersistenceVisualStateTable.java @@ -61,12 +61,12 @@ private void updateColumnPreferences() { NormalTableColumn normalColumn = (NormalTableColumn) column; columnNames.add(normalColumn.getColumnName()); - columnsWidths.add(String.valueOf(normalColumn.getWidth())); + columnsWidths.add(String.valueOf(Double.valueOf(normalColumn.getWidth()).intValue())); } } - if (columnNames.size() == columnsWidths.size() && - columnNames.size() == preferences.getStringList(JabRefPreferences.COLUMN_NAMES).size()) { + if ((columnNames.size() == columnsWidths.size()) && + (columnNames.size() == preferences.getStringList(JabRefPreferences.COLUMN_NAMES).size())) { preferences.putStringList(JabRefPreferences.COLUMN_NAMES, columnNames); preferences.putStringList(JabRefPreferences.COLUMN_WIDTHS, columnsWidths); } diff --git a/src/main/java/org/jabref/gui/preferences/TableColumnsTab.java b/src/main/java/org/jabref/gui/preferences/TableColumnsTab.java index 38c252b642c..18049b23385 100644 --- a/src/main/java/org/jabref/gui/preferences/TableColumnsTab.java +++ b/src/main/java/org/jabref/gui/preferences/TableColumnsTab.java @@ -502,7 +502,7 @@ public void storeSettings() { for (TableRow tr : data) { names.add(tr.getName().toLowerCase(Locale.ROOT)); - widths.add(String.valueOf(tr.getLength())); + widths.add(String.valueOf(Double.valueOf(tr.getLength()).intValue())); } // Finally, we store the new preferences. @@ -522,14 +522,14 @@ private void updateOrderAction() { final HashMap map = new HashMap<>(); // first element (#) not inside data - /* - for (TableColumn column : panel.getMainTable().getColumns()) { - String name = column.getText(); - if ((name != null) && !name.isEmpty()) { - map.put(name.toLowerCase(Locale.ROOT), i); - } + /* + for (TableColumn column : panel.getMainTable().getColumns()) { + String name = column.getText(); + if ((name != null) && !name.isEmpty()) { + map.put(name.toLowerCase(Locale.ROOT), i); } - */ + } + */ data.sort((o1, o2) -> { Integer n1 = map.get(o1.getName()); Integer n2 = map.get(o2.getName()); From 548e031dd9b51c4d91eb8810bd0d67ac3fae9ca7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Fri, 19 Apr 2019 14:20:06 +0200 Subject: [PATCH 3/8] Bump richtextfx from 0.9.3 to 0.10.0 (#4899) --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 994a1f66e64..e87584415b5 100644 --- a/build.gradle +++ b/build.gradle @@ -130,7 +130,7 @@ dependencies { compile 'de.saxsys:mvvmfx:1.8.0' compile 'org.fxmisc.easybind:easybind:1.0.3' compile 'org.fxmisc.flowless:flowless:0.6.1' - compile 'org.fxmisc.richtext:richtextfx:0.9.3' + compile 'org.fxmisc.richtext:richtextfx:0.10.0' compile 'com.sibvisions.external.jvxfx:dndtabpane:0.1' compile 'javax.inject:javax.inject:1' compile 'com.jfoenix:jfoenix:8.0.8' From 744b327faf4a16b461bb2403096ef853447d877c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Fri, 19 Apr 2019 14:20:30 +0200 Subject: [PATCH 4/8] Bump unoil from 6.2.2 to 6.2.3 (#4900) --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index e87584415b5..d176a3fe3ec 100644 --- a/build.gradle +++ b/build.gradle @@ -104,7 +104,7 @@ dependencies { compile "org.libreoffice:juh:6.2.2" compile "org.libreoffice:jurt:6.2.2" compile "org.libreoffice:ridl:6.2.2" - compile "org.libreoffice:unoil:6.2.2" + compile "org.libreoffice:unoil:6.2.3" compile 'io.github.java-diff-utils:java-diff-utils:4.0' compile 'info.debatty:java-string-similarity:1.2.1' From c6d62d9de6d78228e38e7c7e623366603fd60aa2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Fri, 19 Apr 2019 14:20:44 +0200 Subject: [PATCH 5/8] Bump jurt from 6.2.2 to 6.2.3 (#4901) --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index d176a3fe3ec..c4400ed776d 100644 --- a/build.gradle +++ b/build.gradle @@ -102,7 +102,7 @@ dependencies { compile 'commons-cli:commons-cli:1.4' compile "org.libreoffice:juh:6.2.2" - compile "org.libreoffice:jurt:6.2.2" + compile "org.libreoffice:jurt:6.2.3" compile "org.libreoffice:ridl:6.2.2" compile "org.libreoffice:unoil:6.2.3" From afdaa1aa036ed8a3d55a2cd041e79a0df54027b0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Fri, 19 Apr 2019 14:22:20 +0200 Subject: [PATCH 6/8] Bump juh from 6.2.2 to 6.2.3 (#4902) --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index c4400ed776d..835781a1868 100644 --- a/build.gradle +++ b/build.gradle @@ -101,7 +101,7 @@ dependencies { compile 'commons-cli:commons-cli:1.4' - compile "org.libreoffice:juh:6.2.2" + compile "org.libreoffice:juh:6.2.3" compile "org.libreoffice:jurt:6.2.3" compile "org.libreoffice:ridl:6.2.2" compile "org.libreoffice:unoil:6.2.3" From e669e55ab99b699f327971eaa069eba451d95fb3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Fri, 19 Apr 2019 14:22:35 +0200 Subject: [PATCH 7/8] Bump ridl from 6.2.2 to 6.2.3 (#4903) --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 835781a1868..64a94e143d6 100644 --- a/build.gradle +++ b/build.gradle @@ -103,7 +103,7 @@ dependencies { compile "org.libreoffice:juh:6.2.3" compile "org.libreoffice:jurt:6.2.3" - compile "org.libreoffice:ridl:6.2.2" + compile "org.libreoffice:ridl:6.2.3" compile "org.libreoffice:unoil:6.2.3" compile 'io.github.java-diff-utils:java-diff-utils:4.0' From 1c11575898e8ffb3c1c768262c4531b1b6f269ba Mon Sep 17 00:00:00 2001 From: Linus Dietz Date: Fri, 19 Apr 2019 16:00:41 +0200 Subject: [PATCH 8/8] Fix Some Codacy Code Convention Issues (#4904) * Method names should not start with capital letters * Avoid empty if statements --- .../LibraryPropertiesDialogView.java | 6 ++-- .../LibraryPropertiesDialogViewModel.java | 4 +-- .../logic/auxparser/DefaultAuxParser.java | 30 ++++++++----------- 3 files changed, 18 insertions(+), 22 deletions(-) diff --git a/src/main/java/org/jabref/gui/libraryproperties/LibraryPropertiesDialogView.java b/src/main/java/org/jabref/gui/libraryproperties/LibraryPropertiesDialogView.java index 58002962d84..b4c2a0a4694 100644 --- a/src/main/java/org/jabref/gui/libraryproperties/LibraryPropertiesDialogView.java +++ b/src/main/java/org/jabref/gui/libraryproperties/LibraryPropertiesDialogView.java @@ -72,7 +72,7 @@ private void initialize() { generalFileDirectory.textProperty().bindBidirectional(viewModel.generalFileDirectoryPropertyProperty()); userSpecificFileDirectory.textProperty().bindBidirectional(viewModel.userSpecificFileDirectoryProperty()); - laTexFileDirectory.textProperty().bindBidirectional(viewModel.LaTexFileDirectoryProperty()); + laTexFileDirectory.textProperty().bindBidirectional(viewModel.laTexFileDirectoryProperty()); encoding.itemsProperty().bind(viewModel.encodingsProperty()); encoding.valueProperty().bindBidirectional(viewModel.selectedEncodingProperty()); @@ -142,7 +142,7 @@ private void storeSettings() { metaData.setUserFileDirectory(preferencesService.getUser(), text); } - text = viewModel.LaTexFileDirectoryProperty().getValue(); + text = viewModel.laTexFileDirectoryProperty().getValue(); if (text.isEmpty()) { metaData.clearLaTexFileDirectory(preferencesService.getUser()); } else { @@ -180,7 +180,7 @@ private void storeSettings() { boolean changed = saveOrderConfigChanged || encodingChanged || viewModel.generalFileDirChanged() || viewModel.userFileDirChanged() - || viewModel.protectedValueChanged() || saveActionsChanged || viewModel.LaTexFileDirChanged(); + || viewModel.protectedValueChanged() || saveActionsChanged || viewModel.laTexFileDirChanged(); // ... if so, mark base changed. Prevent the Undo button from removing // change marking: if (changed) { diff --git a/src/main/java/org/jabref/gui/libraryproperties/LibraryPropertiesDialogViewModel.java b/src/main/java/org/jabref/gui/libraryproperties/LibraryPropertiesDialogViewModel.java index e7791d7a534..3206b98be9c 100644 --- a/src/main/java/org/jabref/gui/libraryproperties/LibraryPropertiesDialogViewModel.java +++ b/src/main/java/org/jabref/gui/libraryproperties/LibraryPropertiesDialogViewModel.java @@ -80,7 +80,7 @@ public StringProperty userSpecificFileDirectoryProperty() { return this.userSpecificFileDirectoryProperty; } - public StringProperty LaTexFileDirectoryProperty() { + public StringProperty laTexFileDirectoryProperty() { return this.laTexFileDirectoryProperty; } @@ -116,7 +116,7 @@ public boolean userFileDirChanged() { return !oldUserSpecificFileDir.equals(userSpecificFileDirectoryProperty.getValue()); } - public boolean LaTexFileDirChanged() { + public boolean laTexFileDirChanged() { return !oldLaTexFileDir.equals(laTexFileDirectoryProperty.getValue()); } diff --git a/src/main/java/org/jabref/logic/auxparser/DefaultAuxParser.java b/src/main/java/org/jabref/logic/auxparser/DefaultAuxParser.java index 054230c730b..8c4ea858ad7 100644 --- a/src/main/java/org/jabref/logic/auxparser/DefaultAuxParser.java +++ b/src/main/java/org/jabref/logic/auxparser/DefaultAuxParser.java @@ -24,16 +24,13 @@ /** * LaTeX Aux to BibTeX Parser *

- * Extracts a subset of BibTeX entries from a BibDatabase that are included in an AUX file. - * Also supports nested AUX files (latex \\include). + * Extracts a subset of BibTeX entries from a BibDatabase that are included in an AUX file. Also supports nested AUX + * files (latex \\include). * - * There exists no specification of the AUX file. - * Every package, class or document can write to the AUX file. - * The AUX file consists of LaTeX macros and is read at the \begin{document} and again at the \end{document}. + * There exists no specification of the AUX file. Every package, class or document can write to the AUX file. The AUX + * file consists of LaTeX macros and is read at the \begin{document} and again at the \end{document}. * - * BibTeX citation: \citation{x,y,z} - * Biblatex citation: \abx@aux@cite{x,y,z} - * Nested AUX files: \@input{x} + * BibTeX citation: \citation{x,y,z} Biblatex citation: \abx@aux@cite{x,y,z} Nested AUX files: \@input{x} */ public class DefaultAuxParser implements AuxParser { private static final Logger LOGGER = LoggerFactory.getLogger(DefaultAuxParser.class); @@ -128,15 +125,14 @@ private void matchCitation(AuxParserResult result, String line) { */ private void resolveTags(AuxParserResult result) { for (String key : result.getUniqueKeys()) { - Optional entry = masterDatabase.getEntryByKey(key); - - if (result.getGeneratedBibDatabase().getEntryByKey(key).isPresent()) { - // do nothing, key has already been processed - } else if (entry.isPresent()) { - insertEntry(entry.get(), result); - resolveCrossReferences(entry.get(), result); - } else { - result.getUnresolvedKeys().add(key); + if (!result.getGeneratedBibDatabase().getEntryByKey(key).isPresent()) { + Optional entry = masterDatabase.getEntryByKey(key); + if (entry.isPresent()) { + insertEntry(entry.get(), result); + resolveCrossReferences(entry.get(), result); + } else { + result.getUnresolvedKeys().add(key); + } } }