From e6742a4e3033cb93b16349d4c332209285f0d154 Mon Sep 17 00:00:00 2001 From: Andreas Billmann Date: Wed, 10 Aug 2016 23:41:47 +0200 Subject: [PATCH] error export implemented and message on error side bar includes column name --- build.gradle | 2 +- .../javafx/smartcsv/export/ErrorExport.java | 71 +++++++++++++++++++ .../smartcsv/fx/SmartCSVController.java | 49 +++++++++++++ .../javafx/smartcsv/fx/list/ErrorSideBar.java | 4 +- .../smartcsv/fx/util/I18nValidationUtil.java | 9 +++ .../smartcsv/validation/ValidationError.java | 10 +++ .../javafx/smartcsv/validation/Validator.java | 2 +- .../javafx/smartcsv/fx/application.properties | 2 +- .../ninja/javafx/smartcsv/fx/smartcsv.css | 12 +++- .../ninja/javafx/smartcsv/fx/smartcsv.fxml | 13 ++++ .../javafx/smartcsv/fx/smartcsv.properties | 8 ++- .../javafx/smartcsv/fx/smartcsv_de.properties | 8 ++- 12 files changed, 182 insertions(+), 8 deletions(-) create mode 100644 src/main/java/ninja/javafx/smartcsv/export/ErrorExport.java diff --git a/build.gradle b/build.gradle index 6da511a..6614bb2 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ group 'ninja.javafx' -version '0.6-SNAPSHOT' +version '0.7-SNAPSHOT' apply plugin: 'java' apply plugin: 'groovy' diff --git a/src/main/java/ninja/javafx/smartcsv/export/ErrorExport.java b/src/main/java/ninja/javafx/smartcsv/export/ErrorExport.java new file mode 100644 index 0000000..6ec2107 --- /dev/null +++ b/src/main/java/ninja/javafx/smartcsv/export/ErrorExport.java @@ -0,0 +1,71 @@ +package ninja.javafx.smartcsv.export; + +import javafx.concurrent.Service; +import javafx.concurrent.Task; +import ninja.javafx.smartcsv.fx.table.model.CSVModel; +import ninja.javafx.smartcsv.validation.ValidationError; + +import java.io.File; +import java.io.StringWriter; +import java.nio.file.Files; +import java.util.ResourceBundle; + +import static java.text.MessageFormat.format; +import static ninja.javafx.smartcsv.fx.util.I18nValidationUtil.getI18nValidatioMessage; + +/** + * this class exports the error messages into a log file + */ +@org.springframework.stereotype.Service +public class ErrorExport extends Service { + + private CSVModel model; + private File file; + private ResourceBundle resourceBundle; + private String csvFilename; + + public void setCsvFilename(String csvFilename) { + this.csvFilename = csvFilename; + } + + public void setResourceBundle(ResourceBundle resourceBundle) { + this.resourceBundle = resourceBundle; + } + + public void setModel(CSVModel model) { + this.model = model; + } + + public void setFile(File file) { + this.file = file; + } + + @Override + protected Task createTask() { + return new Task() { + @Override + protected Void call() throws Exception { + try { + StringWriter log = new StringWriter(); + log.append( + format(resourceBundle.getString("log.header.message"), + csvFilename, + Integer.toString(model.getValidationError().size()))).append("\n\n"); + for (ValidationError error:model.getValidationError()) { + log.append( + format(resourceBundle.getString("log.message"), + error.getLineNumber().toString(), + error.getColumn(), + getI18nValidatioMessage(resourceBundle, error))).append("\n"); + } + Files.write(file.toPath(), log.toString().getBytes()); + + } catch (Throwable ex) { + ex.printStackTrace(); + } + return null; + } + }; + } + +} diff --git a/src/main/java/ninja/javafx/smartcsv/fx/SmartCSVController.java b/src/main/java/ninja/javafx/smartcsv/fx/SmartCSVController.java index 567a1b0..0fe66df 100644 --- a/src/main/java/ninja/javafx/smartcsv/fx/SmartCSVController.java +++ b/src/main/java/ninja/javafx/smartcsv/fx/SmartCSVController.java @@ -26,6 +26,7 @@ package ninja.javafx.smartcsv.fx; +import javafx.beans.binding.Bindings; import javafx.collections.ListChangeListener; import javafx.collections.WeakListChangeListener; import javafx.concurrent.WorkerStateEvent; @@ -39,6 +40,7 @@ import javafx.scene.layout.BorderPane; import javafx.stage.FileChooser; import ninja.javafx.smartcsv.csv.CSVFileReader; import ninja.javafx.smartcsv.csv.CSVFileWriter; +import ninja.javafx.smartcsv.export.ErrorExport; import ninja.javafx.smartcsv.files.FileStorage; import ninja.javafx.smartcsv.fx.about.AboutController; import ninja.javafx.smartcsv.fx.list.ErrorSideBar; @@ -95,6 +97,9 @@ public class SmartCSVController extends FXMLController { public static final String CSV_FILTER_EXTENSION = "*.csv"; public static final String JSON_FILTER_TEXT = "JSON files (*.json)"; public static final String JSON_FILTER_EXTENSION = "*.json"; + public static final String EXPORT_LOG_FILTER_TEXT = "Error log files (*.log)"; + public static final String EXPORT_LOG_FILTER_EXTENSION = "*.log"; + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // injections @@ -115,6 +120,9 @@ public class SmartCSVController extends FXMLController { @Autowired private SaveFileService saveFileService; + @Autowired + private ErrorExport errorExport; + @FXML private BorderPane applicationPane; @@ -157,6 +165,9 @@ public class SmartCSVController extends FXMLController { @FXML private MenuItem gotoLineMenuItem; + @FXML + private MenuItem exportMenuItem; + @FXML private Button saveButton; @@ -181,6 +192,9 @@ public class SmartCSVController extends FXMLController { @FXML private Button addRowButton; + @FXML + private Button exportButton; + @FXML private Label currentLineNumber; @@ -370,6 +384,26 @@ public class SmartCSVController extends FXMLController { } } + @FXML + public void export(ActionEvent actionEvent) { + final FileChooser fileChooser = new FileChooser(); + + //Set extension filter + final FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter(EXPORT_LOG_FILTER_TEXT, EXPORT_LOG_FILTER_EXTENSION); + fileChooser.getExtensionFilters().add(extFilter); + fileChooser.setTitle("Save"); + + //Show open file dialog + File file = fileChooser.showSaveDialog(applicationPane.getScene().getWindow()); + if (file != null) { + errorExport.setCsvFilename(currentCsvFile.getFile().getName()); + errorExport.setModel(currentCsvFile.getContent()); + errorExport.setFile(file); + errorExport.setResourceBundle(resourceBundle); + errorExport.restart(); + } + } + public boolean canExit() { boolean canExit = true; if (currentCsvFile.getContent() != null && currentCsvFile.isFileChanged()) { @@ -552,6 +586,8 @@ public class SmartCSVController extends FXMLController { * Creates new table view and add the new content */ private void resetContent() { + resetExportButtons(); + if (currentCsvFile.getContent() != null) { currentCsvFile.getContent().getValidationError().addListener(weakErrorListListener); currentCsvFile.getContent().setValidationConfiguration(currentConfigFile.getContent()); @@ -575,9 +611,22 @@ public class SmartCSVController extends FXMLController { setRightAnchor(tableView, 0.0); tableWrapper.getChildren().setAll(tableView); errorSideBar.setModel(currentCsvFile.getContent()); + binExportButtons(); } } + private void binExportButtons() { + exportButton.disableProperty().bind(Bindings.isEmpty(currentCsvFile.getContent().getValidationError())); + exportMenuItem.disableProperty().bind(Bindings.isEmpty(currentCsvFile.getContent().getValidationError())); + } + + private void resetExportButtons() { + exportButton.disableProperty().unbind(); + exportMenuItem.disableProperty().unbind(); + exportButton.disableProperty().setValue(true); + exportMenuItem.disableProperty().setValue(true); + } + /** * Adds a column with the given name to the tableview * @param header name of the column header diff --git a/src/main/java/ninja/javafx/smartcsv/fx/list/ErrorSideBar.java b/src/main/java/ninja/javafx/smartcsv/fx/list/ErrorSideBar.java index 6b2cfa4..9d89011 100644 --- a/src/main/java/ninja/javafx/smartcsv/fx/list/ErrorSideBar.java +++ b/src/main/java/ninja/javafx/smartcsv/fx/list/ErrorSideBar.java @@ -48,7 +48,7 @@ import java.util.ResourceBundle; import static javafx.geometry.Pos.CENTER; import static ninja.javafx.smartcsv.fx.util.ColorConstants.ERROR_COLOR; import static ninja.javafx.smartcsv.fx.util.ColorConstants.OK_COLOR; -import static ninja.javafx.smartcsv.fx.util.I18nValidationUtil.getI18nValidatioMessage; +import static ninja.javafx.smartcsv.fx.util.I18nValidationUtil.getI18nValidatioMessageWithColumn; /** * clickable side bar with error markers @@ -158,7 +158,7 @@ public class ErrorSideBar extends Region { errorMarker.setStyle("-fx-background-color: " + ERROR_COLOR); errorMarker.setOnMouseClicked(event -> selectedValidationError.setValue(error)); errorMarker.setOnMouseEntered(event -> { - popOver.setContentNode(popupContent(getI18nValidatioMessage(resourceBundle, error))); + popOver.setContentNode(popupContent(getI18nValidatioMessageWithColumn(resourceBundle, error))); popOver.show(errorMarker, -16); }); return errorMarker; diff --git a/src/main/java/ninja/javafx/smartcsv/fx/util/I18nValidationUtil.java b/src/main/java/ninja/javafx/smartcsv/fx/util/I18nValidationUtil.java index a518b7d..5fa81fe 100644 --- a/src/main/java/ninja/javafx/smartcsv/fx/util/I18nValidationUtil.java +++ b/src/main/java/ninja/javafx/smartcsv/fx/util/I18nValidationUtil.java @@ -54,11 +54,20 @@ public class I18nValidationUtil { return ""; } + public static String getI18nValidatioMessageWithColumn(ResourceBundle resourceBundle, ValidationError error) { + return getI18nValidatioMessage(resourceBundle, error, resourceBundle.getString("column") + " " + error.getColumn() + " : "); + } + public static String getI18nValidatioMessage(ResourceBundle resourceBundle, ValidationError error) { + return getI18nValidatioMessage(resourceBundle, error, ""); + } + + private static String getI18nValidatioMessage(ResourceBundle resourceBundle, ValidationError error, String prefix) { List validationMessages = error.getMessages(); StringWriter message = new StringWriter(); for (ValidationMessage validationMessage: validationMessages) { + message.append(prefix); if (resourceBundle.containsKey(validationMessage.getKey())) { String resourceText = resourceBundle.getString(validationMessage.getKey()); if (validationMessage.getParameters().length > 0) { diff --git a/src/main/java/ninja/javafx/smartcsv/validation/ValidationError.java b/src/main/java/ninja/javafx/smartcsv/validation/ValidationError.java index 32da30e..7a8b487 100644 --- a/src/main/java/ninja/javafx/smartcsv/validation/ValidationError.java +++ b/src/main/java/ninja/javafx/smartcsv/validation/ValidationError.java @@ -38,6 +38,7 @@ public class ValidationError { private List messages = new ArrayList<>(); private Integer lineNumber; + private String column = ""; private ValidationError(Integer lineNumber) { this.lineNumber = lineNumber; @@ -51,10 +52,19 @@ public class ValidationError { return new ValidationError(-1); } + public ValidationError column(String column) { + this.column = column; + return this; + } + public Integer getLineNumber() { return lineNumber; } + public String getColumn() { + return column; + } + public List getMessages() { return messages; } diff --git a/src/main/java/ninja/javafx/smartcsv/validation/Validator.java b/src/main/java/ninja/javafx/smartcsv/validation/Validator.java index bc5fea9..cd620f4 100644 --- a/src/main/java/ninja/javafx/smartcsv/validation/Validator.java +++ b/src/main/java/ninja/javafx/smartcsv/validation/Validator.java @@ -86,7 +86,7 @@ public class Validator { public ValidationError isValid(Integer row, String column, String value) { ValidationError result = null; if (hasConfig()) { - ValidationError error = ValidationError.withLineNumber(row); + ValidationError error = ValidationError.withLineNumber(row).column(column); Map validationMap = columnValidationMap.get(column); if (validationMap != null) { for (Validation validation: validationMap.values()) { diff --git a/src/main/resources/ninja/javafx/smartcsv/fx/application.properties b/src/main/resources/ninja/javafx/smartcsv/fx/application.properties index 95e8e89..4548d10 100644 --- a/src/main/resources/ninja/javafx/smartcsv/fx/application.properties +++ b/src/main/resources/ninja/javafx/smartcsv/fx/application.properties @@ -1,5 +1,5 @@ application.name = SmartCSV.fx -application.version = 0.6 +application.version = 0.7 # fxml views fxml.smartcvs.view = /ninja/javafx/smartcsv/fx/smartcsv.fxml diff --git a/src/main/resources/ninja/javafx/smartcsv/fx/smartcsv.css b/src/main/resources/ninja/javafx/smartcsv/fx/smartcsv.css index 29850f3..2042b66 100644 --- a/src/main/resources/ninja/javafx/smartcsv/fx/smartcsv.css +++ b/src/main/resources/ninja/javafx/smartcsv/fx/smartcsv.css @@ -82,9 +82,14 @@ .goto-icon { -glyph-name: "SUBDIRECTORY_ARROW_RIGHT"; -glyph-size: 16px; - } +.export-icon { + -glyph-name: "BUG"; + -glyph-size: 16px; +} + + /* toolbar customization based on http://fxexperience.com/2012/02/customized-segmented-toolbar-buttons/ */ #background { @@ -149,6 +154,11 @@ -fx-fill: white; } +.tool-bar .export-icon { + -glyph-size: 16px; + -fx-fill: white; +} + .segmented-button-bar .button { -fx-background-color: -darkest-black, diff --git a/src/main/resources/ninja/javafx/smartcsv/fx/smartcsv.fxml b/src/main/resources/ninja/javafx/smartcsv/fx/smartcsv.fxml index 86e7046..36cd843 100644 --- a/src/main/resources/ninja/javafx/smartcsv/fx/smartcsv.fxml +++ b/src/main/resources/ninja/javafx/smartcsv/fx/smartcsv.fxml @@ -78,6 +78,11 @@ + + + + + @@ -229,6 +234,14 @@ +