diff --git a/src/main/java/org/jabref/gui/externalfiles/FileDownloadTask.java b/src/main/java/org/jabref/gui/externalfiles/FileDownloadTask.java index 890cd232f16..6880d8b7c0a 100644 --- a/src/main/java/org/jabref/gui/externalfiles/FileDownloadTask.java +++ b/src/main/java/org/jabref/gui/externalfiles/FileDownloadTask.java @@ -11,7 +11,7 @@ import org.fxmisc.easybind.EasyBind; -public class FileDownloadTask extends BackgroundTask { +public class FileDownloadTask extends BackgroundTask { private final URL source; private final Path destination; @@ -22,7 +22,7 @@ public FileDownloadTask(URL source, Path destination) { } @Override - protected Void call() throws Exception { + protected Path call() throws Exception { URLDownload download = new URLDownload(source); try (ProgressInputStream inputStream = download.asInputStream()) { EasyBind.subscribe( @@ -35,6 +35,6 @@ protected Void call() throws Exception { Files.copy(inputStream, destination, StandardCopyOption.REPLACE_EXISTING); } - return null; + return destination; } } diff --git a/src/main/java/org/jabref/gui/fieldeditors/LinkedFileViewModel.java b/src/main/java/org/jabref/gui/fieldeditors/LinkedFileViewModel.java index 2307caf04d1..e1480c08688 100644 --- a/src/main/java/org/jabref/gui/fieldeditors/LinkedFileViewModel.java +++ b/src/main/java/org/jabref/gui/fieldeditors/LinkedFileViewModel.java @@ -356,26 +356,30 @@ public void download() { } try { - URLDownload urlDownload = new URLDownload(linkedFile.getLink()); - Optional suggestedType = inferFileType(urlDownload); - String suggestedTypeName = suggestedType.map(ExternalFileType::getName).orElse(""); - linkedFile.setFileType(suggestedTypeName); - Optional targetDirectory = databaseContext.getFirstExistingFileDir(fileDirectoryPreferences); if (!targetDirectory.isPresent()) { dialogService.showErrorDialogAndWait(Localization.lang("Download file"), Localization.lang("File directory is not set or does not exist!")); return; } - String suffix = suggestedType.map(ExternalFileType::getExtension).orElse(""); - String suggestedName = getSuggestedFileName(suffix); - Path destination = targetDirectory.get().resolve(suggestedName); - BackgroundTask downloadTask = new FileDownloadTask(urlDownload.getSource(), destination) - .onSuccess(event -> { - LinkedFile newLinkedFile = LinkedFilesEditorViewModel.fromFile(destination, databaseContext.getFileDirectoriesAsPaths(fileDirectoryPreferences)); - linkedFile.setLink(newLinkedFile.getLink()); - linkedFile.setFileType(newLinkedFile.getFileType()); - }).onFailure(ex -> dialogService.showErrorDialogAndWait("Download failed", ex)); + 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 suffix = suggestedType.map(ExternalFileType::getExtension).orElse(""); + String suggestedName = getSuggestedFileName(suffix); + return targetDirectory.get().resolve(suggestedName); + }) + .then(destination -> new FileDownloadTask(urlDownload.getSource(), destination)) + .onSuccess(destination -> { + LinkedFile newLinkedFile = LinkedFilesEditorViewModel.fromFile(destination, databaseContext.getFileDirectoriesAsPaths(fileDirectoryPreferences)); + linkedFile.setLink(newLinkedFile.getLink()); + linkedFile.setFileType(newLinkedFile.getFileType()); + }) + .onFailure(exception -> dialogService.showErrorDialogAndWait("Download failed", exception)); downloadProgress.bind(downloadTask.workDonePercentageProperty()); taskExecutor.execute(downloadTask); @@ -395,7 +399,6 @@ private Optional inferFileType(URLDownload urlDownload) { } private Optional inferFileTypeFromMimeType(URLDownload urlDownload) { - // TODO: what if this takes long time? String mimeType = urlDownload.getMimeType(); if (mimeType != null) { diff --git a/src/main/java/org/jabref/gui/util/BackgroundTask.java b/src/main/java/org/jabref/gui/util/BackgroundTask.java index a0ba66966b4..d420881b049 100644 --- a/src/main/java/org/jabref/gui/util/BackgroundTask.java +++ b/src/main/java/org/jabref/gui/util/BackgroundTask.java @@ -3,6 +3,7 @@ import java.util.concurrent.Callable; import java.util.concurrent.Future; import java.util.function.Consumer; +import java.util.function.Function; import javafx.beans.property.DoubleProperty; import javafx.beans.property.ObjectProperty; @@ -120,11 +121,33 @@ public BackgroundTask onFinished(Runnable onFinished) { return this; } + /** + * Creates a {@link BackgroundTask} that first runs this task and based on the result runs a second task. + * + * @param nextTaskFactory the function that creates the new task + * @param type of the return value of the second task + */ + public BackgroundTask then(Function> nextTaskFactory) { + return new BackgroundTask() { + @Override + protected T call() throws Exception { + V result = BackgroundTask.this.call(); + BackgroundTask nextTask = nextTaskFactory.apply(result); + EasyBind.subscribe(nextTask.progressProperty(), this::updateProgress); + return nextTask.call(); + } + }; + } + + protected void updateProgress(BackgroundProgress newProgress) { + progress.setValue(newProgress); + } + protected void updateProgress(double workDone, double max) { - progress.setValue(new BackgroundProgress(workDone, max)); + updateProgress(new BackgroundProgress(workDone, max)); } - public class BackgroundProgress { + class BackgroundProgress { private final double workDone; private final double max;