package org.jabref.gui.util; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.FutureTask; import java.util.function.Consumer; import javafx.application.Platform; import javafx.concurrent.Task; import org.jabref.gui.externalfiles.FileDownloadTask; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * A very simple implementation of the {@link TaskExecutor} interface. * Every submitted task is invoked in a separate thread. */ public class DefaultTaskExecutor implements TaskExecutor { private static final Log LOGGER = LogFactory.getLog(DefaultTaskExecutor.class); private ExecutorService executor = Executors.newFixedThreadPool(5); public static <V> V runInJavaFXThread(Callable<V> callable) { FutureTask<V> task = new FutureTask<>(callable); Platform.runLater(task); try { return task.get(); } catch (InterruptedException | ExecutionException e) { LOGGER.error(e); return null; } } public static void runInJavaFXThread(Runnable runnable) { Platform.runLater(runnable); } @Override public <V> void execute(BackgroundTask<V> task) { executor.submit(getJavaFXTask(task)); } @Override public void execute(FileDownloadTask downloadTask) { executor.submit(downloadTask); } @Override public void shutdown() { executor.shutdownNow(); } private <V> Task<V> getJavaFXTask(BackgroundTask<V> task) { Task<V> javaTask = new Task<V>() { @Override public V call() throws Exception { return task.call(); } }; Runnable onRunning = task.getOnRunning(); if (onRunning != null) { javaTask.setOnRunning(event -> onRunning.run()); } Consumer<V> onSuccess = task.getOnSuccess(); if (onSuccess != null) { javaTask.setOnSucceeded(event -> onSuccess.accept(javaTask.getValue())); } Consumer<Exception> onException = task.getOnException(); if (onException != null) { javaTask.setOnFailed(event -> onException.accept(convertToException(javaTask.getException()))); } return javaTask; } private Exception convertToException(Throwable throwable) { if (throwable instanceof Exception) { return (Exception) throwable; } else { return new Exception(throwable); } } }