diff --git a/src/main/java/ninja/javafx/smartcsv/csv/CSVFileReader.java b/src/main/java/ninja/javafx/smartcsv/csv/CSVFileReader.java index 0878c89..8225578 100644 --- a/src/main/java/ninja/javafx/smartcsv/csv/CSVFileReader.java +++ b/src/main/java/ninja/javafx/smartcsv/csv/CSVFileReader.java @@ -29,6 +29,7 @@ package ninja.javafx.smartcsv.csv; import ninja.javafx.smartcsv.FileReader; import ninja.javafx.smartcsv.fx.table.model.CSVModel; import ninja.javafx.smartcsv.fx.table.model.CSVRow; +import org.supercsv.exception.SuperCsvException; import org.supercsv.io.CsvMapReader; import org.supercsv.io.ICsvMapReader; @@ -47,10 +48,8 @@ public class CSVFileReader extends CSVConfigurable implements FileReader resetContent()); + useLoadFileService(storageFile, t -> resetContent(), () -> storageFile.setFile(previousFile)); } } @@ -625,13 +628,20 @@ public class SmartCSVController extends FXMLController { return file; } - private void useLoadFileService(FileStorage fileStorage, EventHandler onSucceededHandler) { + private void useLoadFileService(FileStorage fileStorage, EventHandler onSucceededHandler) { + useLoadFileService(fileStorage, onSucceededHandler, () -> { + // nothing to rollback + }); + } + + private void useLoadFileService(FileStorage fileStorage, EventHandler onSucceededHandler, Runnable rollbackAction) { loadFileService.setFileStorage(fileStorage); loadFileService.restart(); loadFileService.setOnSucceeded(onSucceededHandler); + loadFileService.setOnFailed(event -> JavaFxUtils.onServiceError(event, "LoadFileService Error", "Failed to load the file.", rollbackAction)); } - private void useSaveFileService(FileStorage fileStorage) { + private void useSaveFileService(FileStorage fileStorage) { saveFileService.setFileStorage(fileStorage); saveFileService.restart(); saveFileService.setOnSucceeded(t -> resetContent()); diff --git a/src/main/java/ninja/javafx/smartcsv/fx/util/JavaFxUtils.java b/src/main/java/ninja/javafx/smartcsv/fx/util/JavaFxUtils.java new file mode 100644 index 0000000..d6764ce --- /dev/null +++ b/src/main/java/ninja/javafx/smartcsv/fx/util/JavaFxUtils.java @@ -0,0 +1,73 @@ +/* + The MIT License (MIT) + ----------------------------------------------------------------------------- + + Copyright (c) 2021 javafx.ninja + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + +*/ +package ninja.javafx.smartcsv.fx.util; + +import javafx.concurrent.Worker; +import javafx.concurrent.WorkerStateEvent; +import javafx.scene.control.Alert; +import ninja.javafx.smartcsv.fx.SmartCSVController; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +/** + * This class helps extract useful messages from exceptions + * TODO: make I18n maybe? + */ +public final class JavaFxUtils { + + private static final Logger logger = LogManager.getLogger(SmartCSVController.class); + + private JavaFxUtils() { + } + + public static void onServiceError(WorkerStateEvent event, String windowTitle, String errorHeader) { + onServiceError(event, windowTitle, errorHeader, () -> { + }); + } + + public static void onServiceError(WorkerStateEvent event, String windowTitle, String errorHeader, Runnable rollbackAction) { + Alert alert = new Alert(Alert.AlertType.ERROR); + alert.setTitle(windowTitle); + alert.setHeaderText(errorHeader); + alert.setContentText(findExceptionMessage(event.getSource())); + alert.showAndWait(); + } + + private static String findExceptionMessage(Worker source) { + if (source == null) { + return "Cannot identify the source of the event!"; + } else if (source.getException() == null) { + return "The event did not have an exception?"; + } + Throwable exception = source.getException(); + logger.error("Error in " + source.getClass().getSimpleName(), exception); + if (exception.getMessage() == null) { + return "Exception of type " + exception.getClass() + " had no message, check the logs."; + } + return exception.getMessage(); + } + +} diff --git a/src/main/java/ninja/javafx/smartcsv/fx/util/LoadFileService.java b/src/main/java/ninja/javafx/smartcsv/fx/util/LoadFileService.java index 8ba3b2f..48280c1 100644 --- a/src/main/java/ninja/javafx/smartcsv/fx/util/LoadFileService.java +++ b/src/main/java/ninja/javafx/smartcsv/fx/util/LoadFileService.java @@ -34,17 +34,17 @@ import ninja.javafx.smartcsv.files.FileStorage; * Service class for async load of a csv file */ @org.springframework.stereotype.Service -public class LoadFileService extends Service { +public class LoadFileService extends Service { - private FileStorage file; + private FileStorage file; - public void setFileStorage(FileStorage file) { + public void setFileStorage(FileStorage file) { this.file = file; } @Override - protected Task createTask() { - return new Task() { + protected Task createTask() { + return new Task<>() { @Override protected Void call() throws Exception { if (file != null) { diff --git a/src/main/java/ninja/javafx/smartcsv/fx/util/SaveFileService.java b/src/main/java/ninja/javafx/smartcsv/fx/util/SaveFileService.java index 6b0ca59..92150fe 100644 --- a/src/main/java/ninja/javafx/smartcsv/fx/util/SaveFileService.java +++ b/src/main/java/ninja/javafx/smartcsv/fx/util/SaveFileService.java @@ -31,22 +31,22 @@ import javafx.concurrent.Task; import ninja.javafx.smartcsv.files.FileStorage; /** - * Service class for async load of a csv file + * Service class for async save of a csv file */ @org.springframework.stereotype.Service -public class SaveFileService extends Service { +public class SaveFileService extends Service { - private FileStorage file; + private FileStorage file; - public void setFileStorage(FileStorage value) { + public void setFileStorage(FileStorage value) { file = value; } @Override - protected Task createTask() { - return new Task() { + protected Task createTask() { + return new Task<>() { @Override - protected Void call() throws Exception { + protected Void call() { try { file.save(); } catch (Throwable ex) {