mirror of
https://github.com/frosch95/SmartCSV.fx.git
synced 2026-04-11 13:38:23 +02:00
new feature: clickable error list
This commit is contained in:
@@ -16,6 +16,7 @@ repositories {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
testCompile group: 'junit', name: 'junit', version: '4.12'
|
testCompile group: 'junit', name: 'junit', version: '4.12'
|
||||||
|
testCompile group: 'org.hamcrest', name: 'hamcrest-library', version: '1.3'
|
||||||
testCompile group: 'org.mockito', name: 'mockito-all', version: '1.10.19'
|
testCompile group: 'org.mockito', name: 'mockito-all', version: '1.10.19'
|
||||||
compile group: 'org.codehaus.groovy', name: 'groovy-all', version: '2.4.5'
|
compile group: 'org.codehaus.groovy', name: 'groovy-all', version: '2.4.5'
|
||||||
compile group: 'org.springframework', name:'spring-context', version: '4.2.3.RELEASE'
|
compile group: 'org.springframework', name:'spring-context', version: '4.2.3.RELEASE'
|
||||||
|
|||||||
@@ -32,27 +32,26 @@ import javafx.concurrent.Task;
|
|||||||
import javafx.event.ActionEvent;
|
import javafx.event.ActionEvent;
|
||||||
import javafx.event.EventHandler;
|
import javafx.event.EventHandler;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.scene.control.Alert;
|
import javafx.scene.control.*;
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.layout.AnchorPane;
|
||||||
import javafx.scene.control.TableColumn;
|
|
||||||
import javafx.scene.control.TableView;
|
|
||||||
import javafx.scene.layout.BorderPane;
|
import javafx.scene.layout.BorderPane;
|
||||||
import javafx.stage.FileChooser;
|
import javafx.stage.FileChooser;
|
||||||
import ninja.javafx.smartcsv.FileReader;
|
import ninja.javafx.smartcsv.FileReader;
|
||||||
import ninja.javafx.smartcsv.csv.CSVFileReader;
|
import ninja.javafx.smartcsv.csv.CSVFileReader;
|
||||||
import ninja.javafx.smartcsv.csv.CSVFileWriter;
|
import ninja.javafx.smartcsv.csv.CSVFileWriter;
|
||||||
|
import ninja.javafx.smartcsv.fx.list.ValidationErrorListCell;
|
||||||
import ninja.javafx.smartcsv.fx.table.ObservableMapValueFactory;
|
import ninja.javafx.smartcsv.fx.table.ObservableMapValueFactory;
|
||||||
import ninja.javafx.smartcsv.fx.table.ValidationCellFactory;
|
import ninja.javafx.smartcsv.fx.table.ValidationCellFactory;
|
||||||
import ninja.javafx.smartcsv.fx.table.model.CSVModel;
|
import ninja.javafx.smartcsv.fx.table.model.CSVModel;
|
||||||
import ninja.javafx.smartcsv.fx.table.model.CSVValue;
|
import ninja.javafx.smartcsv.fx.table.model.CSVValue;
|
||||||
import ninja.javafx.smartcsv.fx.table.model.CSVRow;
|
import ninja.javafx.smartcsv.fx.table.model.CSVRow;
|
||||||
|
import ninja.javafx.smartcsv.validation.ValidationError;
|
||||||
import ninja.javafx.smartcsv.validation.ValidationFileReader;
|
import ninja.javafx.smartcsv.validation.ValidationFileReader;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.ResourceBundle;
|
import java.util.ResourceBundle;
|
||||||
|
|
||||||
@@ -83,6 +82,12 @@ public class SmartCSVController extends FXMLController {
|
|||||||
@FXML
|
@FXML
|
||||||
private Label stateline;
|
private Label stateline;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private ListView errorList;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private AnchorPane tableWrapper;
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// injections
|
// injections
|
||||||
@@ -92,6 +97,7 @@ public class SmartCSVController extends FXMLController {
|
|||||||
private final LoadCSVService loadCSVService = new LoadCSVService();
|
private final LoadCSVService loadCSVService = new LoadCSVService();
|
||||||
private final SaveCSVService saveCSVService = new SaveCSVService();
|
private final SaveCSVService saveCSVService = new SaveCSVService();
|
||||||
private CSVModel model;
|
private CSVModel model;
|
||||||
|
private TableView<CSVRow> tableView;
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -101,6 +107,10 @@ public class SmartCSVController extends FXMLController {
|
|||||||
@Override
|
@Override
|
||||||
public void initialize(URL location, ResourceBundle resources) {
|
public void initialize(URL location, ResourceBundle resources) {
|
||||||
stateline.setVisible(false);
|
stateline.setVisible(false);
|
||||||
|
errorList.setCellFactory(param -> new ValidationErrorListCell());
|
||||||
|
errorList.getSelectionModel().selectedItemProperty().addListener(
|
||||||
|
observable -> scrollToError()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -215,7 +225,7 @@ public class SmartCSVController extends FXMLController {
|
|||||||
model = csvLoader.getData();
|
model = csvLoader.getData();
|
||||||
model.setValidator(validationLoader.getValidator());
|
model.setValidator(validationLoader.getValidator());
|
||||||
|
|
||||||
TableView<CSVRow> tableView = new TableView<>();
|
tableView = new TableView<>();
|
||||||
|
|
||||||
for (String column: model.getHeader()) {
|
for (String column: model.getHeader()) {
|
||||||
addColumn(column, tableView);
|
addColumn(column, tableView);
|
||||||
@@ -223,7 +233,14 @@ public class SmartCSVController extends FXMLController {
|
|||||||
tableView.getItems().setAll(model.getRows());
|
tableView.getItems().setAll(model.getRows());
|
||||||
tableView.setEditable(true);
|
tableView.setEditable(true);
|
||||||
|
|
||||||
applicationPane.setCenter(tableView);
|
AnchorPane.setBottomAnchor(tableView, 0.0);
|
||||||
|
AnchorPane.setTopAnchor(tableView, 0.0);
|
||||||
|
AnchorPane.setLeftAnchor(tableView, 0.0);
|
||||||
|
AnchorPane.setRightAnchor(tableView, 0.0);
|
||||||
|
tableWrapper.getChildren().setAll(tableView);
|
||||||
|
|
||||||
|
|
||||||
|
errorList.setItems(model.getValidationError());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -248,6 +265,17 @@ public class SmartCSVController extends FXMLController {
|
|||||||
tableView.getColumns().add(column);
|
tableView.getColumns().add(column);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void scrollToError() {
|
||||||
|
ValidationError entry = (ValidationError)errorList.getSelectionModel().getSelectedItem();
|
||||||
|
if (entry != null) {
|
||||||
|
if (entry.getLineNumber() != null) {
|
||||||
|
tableView.scrollTo(entry.getLineNumber());
|
||||||
|
tableView.getSelectionModel().select(entry.getLineNumber());
|
||||||
|
} else {
|
||||||
|
tableView.scrollTo(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// inner class
|
// inner class
|
||||||
@@ -277,7 +305,7 @@ public class SmartCSVController extends FXMLController {
|
|||||||
try {
|
try {
|
||||||
fileReader.read(file);
|
fileReader.read(file);
|
||||||
runLater(SmartCSVController.this::resetContent);
|
runLater(SmartCSVController.this::resetContent);
|
||||||
} catch (IOException ex) {
|
} catch (Throwable ex) {
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -300,7 +328,7 @@ public class SmartCSVController extends FXMLController {
|
|||||||
try {
|
try {
|
||||||
csvFileWriter.saveFile(model);
|
csvFileWriter.saveFile(model);
|
||||||
runLater(SmartCSVController.this::resetContent);
|
runLater(SmartCSVController.this::resetContent);
|
||||||
} catch (IOException ex) {
|
} catch (Throwable ex) {
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
The MIT License (MIT)
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2015 javafx.ninja <info@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.list;
|
||||||
|
|
||||||
|
import javafx.scene.control.ListCell;
|
||||||
|
import javafx.scene.text.Text;
|
||||||
|
import ninja.javafx.smartcsv.validation.ValidationError;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO: DESCRIPTION!!!
|
||||||
|
*/
|
||||||
|
public class ValidationErrorListCell extends ListCell<ValidationError> {
|
||||||
|
|
||||||
|
private Text text;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateItem(ValidationError validationError, boolean empty) {
|
||||||
|
super.updateItem(validationError, empty);
|
||||||
|
if (empty) {
|
||||||
|
clearContent();
|
||||||
|
} else {
|
||||||
|
addContent(validationError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void clearContent() {
|
||||||
|
setText(null);
|
||||||
|
setGraphic(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addContent(ValidationError validationError) {
|
||||||
|
setText(null);
|
||||||
|
text = new Text(validationError.getMessage());
|
||||||
|
text.setWrappingWidth(180);
|
||||||
|
setGraphic(text);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -64,12 +64,12 @@ public class EditableValidationCell extends TableCell<CSVRow, CSVValue> {
|
|||||||
protected void updateItem(CSVValue item, boolean empty) {
|
protected void updateItem(CSVValue item, boolean empty) {
|
||||||
super.updateItem(item, empty);
|
super.updateItem(item, empty);
|
||||||
|
|
||||||
if (item == null || item.getValid().isValid() || isEditing()) {
|
if (item == null || item.getValidationError() == null || isEditing()) {
|
||||||
setStyle("");
|
setStyle("");
|
||||||
setTooltip(null);
|
setTooltip(null);
|
||||||
} else if (!item.getValid().isValid()) {
|
} else if (item.getValidationError() != null) {
|
||||||
setStyle("-fx-background-color: #ff8888");
|
setStyle("-fx-background-color: #ff8888");
|
||||||
setTooltip(new Tooltip(item.getValid().error()));
|
setTooltip(new Tooltip(item.getValidationError().getMessage()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item == null || empty) {
|
if (item == null || empty) {
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ package ninja.javafx.smartcsv.fx.table.model;
|
|||||||
|
|
||||||
import javafx.collections.FXCollections;
|
import javafx.collections.FXCollections;
|
||||||
import javafx.collections.ObservableList;
|
import javafx.collections.ObservableList;
|
||||||
import ninja.javafx.smartcsv.validation.ValidationState;
|
import ninja.javafx.smartcsv.validation.ValidationError;
|
||||||
import ninja.javafx.smartcsv.validation.Validator;
|
import ninja.javafx.smartcsv.validation.Validator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -41,6 +41,7 @@ public class CSVModel {
|
|||||||
private ObservableList<CSVRow> rows = FXCollections.observableArrayList();
|
private ObservableList<CSVRow> rows = FXCollections.observableArrayList();
|
||||||
private String[] header;
|
private String[] header;
|
||||||
private String filepath;
|
private String filepath;
|
||||||
|
private ObservableList<ValidationError> validationError = FXCollections.observableArrayList();
|
||||||
|
|
||||||
public CSVModel(String filepath) {
|
public CSVModel(String filepath) {
|
||||||
this.filepath = filepath;
|
this.filepath = filepath;
|
||||||
@@ -71,6 +72,10 @@ public class CSVModel {
|
|||||||
return rows;
|
return rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ObservableList<ValidationError> getValidationError() {
|
||||||
|
return validationError;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* adds a new and empty row
|
* adds a new and empty row
|
||||||
* @return the new row
|
* @return the new row
|
||||||
@@ -105,22 +110,37 @@ public class CSVModel {
|
|||||||
* walks through the data and validates each value
|
* walks through the data and validates each value
|
||||||
*/
|
*/
|
||||||
private void revalidate() {
|
private void revalidate() {
|
||||||
|
validationError.clear();
|
||||||
|
|
||||||
if (header != null && validator != null) {
|
if (header != null && validator != null) {
|
||||||
validator.isHeaderValid(header);
|
addValidationError(validator.isHeaderValid(header));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (CSVRow row: rows) {
|
for (int lineNumber = 0; lineNumber < rows.size(); lineNumber++) {
|
||||||
|
CSVRow row = rows.get(lineNumber);
|
||||||
row.setValidator(validator);
|
row.setValidator(validator);
|
||||||
for (String column: row.getColumns().keySet()) {
|
for (String column: row.getColumns().keySet()) {
|
||||||
CSVValue value = row.getColumns().get(column).getValue();
|
CSVValue value = row.getColumns().get(column).getValue();
|
||||||
value.setValidator(validator);
|
value.setValidator(validator);
|
||||||
if (validator != null) {
|
if (validator != null) {
|
||||||
value.setValid(validator.isValid(column, value.getValue()));
|
ValidationError validationError = validator.isValid(column, value.getValue(), lineNumber);
|
||||||
|
if (validationError != null) {
|
||||||
|
addValidationError(validationError);
|
||||||
|
value.setValidationError(validationError);
|
||||||
} else {
|
} else {
|
||||||
value.setValid(new ValidationState());
|
value.setValidationError(null);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
value.setValidationError(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addValidationError(ValidationError validationError) {
|
||||||
|
if (validationError != null) {
|
||||||
|
this.validationError.add(validationError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ package ninja.javafx.smartcsv.fx.table.model;
|
|||||||
|
|
||||||
import javafx.beans.property.SimpleStringProperty;
|
import javafx.beans.property.SimpleStringProperty;
|
||||||
import javafx.beans.property.StringProperty;
|
import javafx.beans.property.StringProperty;
|
||||||
import ninja.javafx.smartcsv.validation.ValidationState;
|
import ninja.javafx.smartcsv.validation.ValidationError;
|
||||||
import ninja.javafx.smartcsv.validation.Validator;
|
import ninja.javafx.smartcsv.validation.Validator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -41,7 +41,7 @@ public class CSVValue {
|
|||||||
private int rowNumber;
|
private int rowNumber;
|
||||||
private String column;
|
private String column;
|
||||||
private StringProperty value = new SimpleStringProperty();
|
private StringProperty value = new SimpleStringProperty();
|
||||||
private ValidationState valid = new ValidationState();
|
private ValidationError valid;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* single value of a cell
|
* single value of a cell
|
||||||
@@ -89,7 +89,7 @@ public class CSVValue {
|
|||||||
*/
|
*/
|
||||||
public void setValue(String value) {
|
public void setValue(String value) {
|
||||||
if (validator != null) {
|
if (validator != null) {
|
||||||
valid = validator.isValid(column, value);
|
valid = validator.isValid(column, value, rowNumber);
|
||||||
}
|
}
|
||||||
this.value.set(value);
|
this.value.set(value);
|
||||||
}
|
}
|
||||||
@@ -98,7 +98,7 @@ public class CSVValue {
|
|||||||
* returns if the value is valid to the rules of the validator
|
* returns if the value is valid to the rules of the validator
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public ValidationState getValid() {
|
public ValidationError getValidationError() {
|
||||||
return valid;
|
return valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,7 +106,7 @@ public class CSVValue {
|
|||||||
* sets the state if a value is valid or not
|
* sets the state if a value is valid or not
|
||||||
* @param valid the validation state
|
* @param valid the validation state
|
||||||
*/
|
*/
|
||||||
protected void setValid(ValidationState valid) {
|
protected void setValidationError(ValidationError valid) {
|
||||||
this.valid = valid;
|
this.valid = valid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,21 +31,26 @@ import java.io.StringWriter;
|
|||||||
/**
|
/**
|
||||||
* Created by Andreas on 28.11.2015.
|
* Created by Andreas on 28.11.2015.
|
||||||
*/
|
*/
|
||||||
public class ValidationState {
|
public class ValidationError {
|
||||||
private boolean valid = true;
|
|
||||||
private StringWriter messages = new StringWriter();
|
|
||||||
|
|
||||||
public void invalidate(String message) {
|
private String message;
|
||||||
valid = false;
|
private Integer lineNumber;
|
||||||
messages.append(message).append('\n');
|
|
||||||
|
public ValidationError(String message) {
|
||||||
|
this(message, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isValid() {
|
public ValidationError(String message, Integer lineNumber) {
|
||||||
return valid;
|
this.message = message;
|
||||||
|
this.lineNumber = lineNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String error() {
|
public Integer getLineNumber() {
|
||||||
return messages.toString();
|
return lineNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMessage() {
|
||||||
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -32,6 +32,7 @@ import groovy.lang.GroovyShell;
|
|||||||
import groovy.lang.Script;
|
import groovy.lang.Script;
|
||||||
import org.codehaus.groovy.control.CompilationFailedException;
|
import org.codehaus.groovy.control.CompilationFailedException;
|
||||||
|
|
||||||
|
import java.io.StringWriter;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -74,24 +75,30 @@ public class Validator {
|
|||||||
* checks if the value is valid for the column configuration
|
* checks if the value is valid for the column configuration
|
||||||
* @param column the column name
|
* @param column the column name
|
||||||
* @param value the value to check
|
* @param value the value to check
|
||||||
* @return ValidationState with information if valid and if not which error happened
|
* @return ValidationError with information if valid and if not which getMessage happened
|
||||||
*/
|
*/
|
||||||
public ValidationState isValid(String column, String value) {
|
public ValidationError isValid(String column, String value, Integer lineNumber) {
|
||||||
ValidationState result = new ValidationState();
|
ValidationError result = null;
|
||||||
if (validationConfig != null) {
|
if (validationConfig != null) {
|
||||||
Config columnSectionConfig = getColumnSectionConfig();
|
Config columnSectionConfig = getColumnSectionConfig();
|
||||||
if (columnSectionConfig != null) {
|
if (columnSectionConfig != null) {
|
||||||
Config columnConfig = getColumnConfig(columnSectionConfig, column);
|
Config columnConfig = getColumnConfig(columnSectionConfig, column);
|
||||||
if (columnConfig != null) {
|
if (columnConfig != null) {
|
||||||
checkBlankOrNull(columnConfig, value, result);
|
|
||||||
|
StringWriter errorMessage = new StringWriter();
|
||||||
|
checkBlankOrNull(columnConfig, value, errorMessage);
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
checkRegularExpression(columnConfig, value, result);
|
checkRegularExpression(columnConfig, value, errorMessage);
|
||||||
checkAlphaNumeric(columnConfig, value, result);
|
checkAlphaNumeric(columnConfig, value, errorMessage);
|
||||||
checkDate(columnConfig, value, result);
|
checkDate(columnConfig, value, errorMessage);
|
||||||
checkMaxLength(columnConfig, value, result);
|
checkMaxLength(columnConfig, value, errorMessage);
|
||||||
checkMinLength(columnConfig, value, result);
|
checkMinLength(columnConfig, value, errorMessage);
|
||||||
checkInteger(columnConfig, value, result);
|
checkInteger(columnConfig, value, errorMessage);
|
||||||
checkGroovy(column, columnConfig, value, result);
|
checkGroovy(column, columnConfig, value, errorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!errorMessage.toString().isEmpty()) {
|
||||||
|
result = new ValidationError(errorMessage.toString(), lineNumber);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -104,7 +111,7 @@ public class Validator {
|
|||||||
// private methods
|
// private methods
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
private void checkGroovy(String column, Config columnConfig, String value, ValidationState result) {
|
private void checkGroovy(String column, Config columnConfig, String value, StringWriter result) {
|
||||||
String groovyScript = getString(columnConfig, "groovy");
|
String groovyScript = getString(columnConfig, "groovy");
|
||||||
if (groovyScript != null) {
|
if (groovyScript != null) {
|
||||||
|
|
||||||
@@ -122,15 +129,15 @@ public class Validator {
|
|||||||
try {
|
try {
|
||||||
groovyResult = script.run();
|
groovyResult = script.run();
|
||||||
} catch (CompilationFailedException e) {
|
} catch (CompilationFailedException e) {
|
||||||
result.invalidate("groovy script '"+groovyScript+"' throws exception: "+e.getMessage());
|
result.append("groovy script '"+groovyScript+"' throws exception: "+e.getMessage()).append('\n');
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
if (groovyResult == null) {
|
if (groovyResult == null) {
|
||||||
result.invalidate("groovy script '"+groovyScript+"' returns null");
|
result.append("groovy script '"+groovyScript+"' returns null").append('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isScriptResultTrue(groovyResult)) {
|
if (!isScriptResultTrue(groovyResult)) {
|
||||||
result.invalidate(groovyResult.toString());
|
result.append(groovyResult.toString()).append('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -140,62 +147,62 @@ public class Validator {
|
|||||||
return groovyResult.equals(true) || groovyResult.toString().trim().toLowerCase().equals("true");
|
return groovyResult.equals(true) || groovyResult.toString().trim().toLowerCase().equals("true");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkBlankOrNull(Config columnConfig, String value, ValidationState result) {
|
private void checkBlankOrNull(Config columnConfig, String value, StringWriter result) {
|
||||||
if (getBoolean(columnConfig, "not empty")) {
|
if (getBoolean(columnConfig, "not empty")) {
|
||||||
if (isBlankOrNull(value)) {
|
if (isBlankOrNull(value)) {
|
||||||
result.invalidate("should not be empty");
|
result.append("should not be empty").append('\n');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkInteger(Config columnConfig, String value, ValidationState result) {
|
private void checkInteger(Config columnConfig, String value, StringWriter result) {
|
||||||
if (getBoolean(columnConfig, "integer")) {
|
if (getBoolean(columnConfig, "integer")) {
|
||||||
if (!isInt(value)) {
|
if (!isInt(value)) {
|
||||||
result.invalidate("should be an integer");
|
result.append("should be an integer").append('\n');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkMinLength(Config columnConfig, String value, ValidationState result) {
|
private void checkMinLength(Config columnConfig, String value, StringWriter result) {
|
||||||
Integer minLength = getInteger(columnConfig, "minlength");
|
Integer minLength = getInteger(columnConfig, "minlength");
|
||||||
if (minLength != null) {
|
if (minLength != null) {
|
||||||
if (!minLength(value, minLength)) {
|
if (!minLength(value, minLength)) {
|
||||||
result.invalidate("has not min length of " + minLength);
|
result.append("has not min length of " + minLength).append('\n');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkMaxLength(Config columnConfig, String value, ValidationState result) {
|
private void checkMaxLength(Config columnConfig, String value, StringWriter result) {
|
||||||
Integer maxLength = getInteger(columnConfig, "maxlength");
|
Integer maxLength = getInteger(columnConfig, "maxlength");
|
||||||
if (maxLength != null) {
|
if (maxLength != null) {
|
||||||
if (!maxLength(value, maxLength)) {
|
if (!maxLength(value, maxLength)) {
|
||||||
result.invalidate("has not max length of " + maxLength);
|
result.append("has not max length of " + maxLength).append('\n');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkDate(Config columnConfig, String value, ValidationState result) {
|
private void checkDate(Config columnConfig, String value, StringWriter result) {
|
||||||
String dateformat = getString(columnConfig, "date");
|
String dateformat = getString(columnConfig, "date");
|
||||||
if (dateformat != null && !dateformat.trim().isEmpty()) {
|
if (dateformat != null && !dateformat.trim().isEmpty()) {
|
||||||
if (!isDate(value, dateformat, true)) {
|
if (!isDate(value, dateformat, true)) {
|
||||||
result.invalidate("is not a date of format " + dateformat);
|
result.append("is not a date of format " + dateformat).append('\n');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkAlphaNumeric(Config columnConfig, String value, ValidationState result) {
|
private void checkAlphaNumeric(Config columnConfig, String value, StringWriter result) {
|
||||||
if (getBoolean(columnConfig, "alphanumeric")) {
|
if (getBoolean(columnConfig, "alphanumeric")) {
|
||||||
if (!matchRegexp(value, "[0-9a-zA-Z]*")) {
|
if (!matchRegexp(value, "[0-9a-zA-Z]*")) {
|
||||||
result.invalidate("should not be alphanumeric");
|
result.append("should not be alphanumeric").append('\n');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkRegularExpression(Config columnConfig, String value, ValidationState result) {
|
private void checkRegularExpression(Config columnConfig, String value, StringWriter result) {
|
||||||
String regexp = getString(columnConfig, "regexp");
|
String regexp = getString(columnConfig, "regexp");
|
||||||
if (regexp != null && !regexp.trim().isEmpty()) {
|
if (regexp != null && !regexp.trim().isEmpty()) {
|
||||||
if (!matchRegexp(value, regexp)) {
|
if (!matchRegexp(value, regexp)) {
|
||||||
result.invalidate("does not match " + regexp);
|
result.append("does not match " + regexp).append('\n');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -222,8 +229,8 @@ public class Validator {
|
|||||||
return columnConfig.hasPath(path) && columnConfig.getBoolean(path);
|
return columnConfig.hasPath(path) && columnConfig.getBoolean(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ValidationState isHeaderValid(String[] headerNames) {
|
public ValidationError isHeaderValid(String[] headerNames) {
|
||||||
ValidationState result = new ValidationState();
|
ValidationError result = null;
|
||||||
if (validationConfig != null) {
|
if (validationConfig != null) {
|
||||||
if (validationConfig.hasPath("headers")) {
|
if (validationConfig.hasPath("headers")) {
|
||||||
Config headerSectionConfig = validationConfig.getConfig("headers");
|
Config headerSectionConfig = validationConfig.getConfig("headers");
|
||||||
@@ -231,25 +238,30 @@ public class Validator {
|
|||||||
List<String> headerConfig = headerSectionConfig.getStringList("list");
|
List<String> headerConfig = headerSectionConfig.getStringList("list");
|
||||||
if (headerConfig != null) {
|
if (headerConfig != null) {
|
||||||
if (headerNames.length != headerConfig.size()) {
|
if (headerNames.length != headerConfig.size()) {
|
||||||
result.invalidate("number of headers is not correct! there are " +
|
result = new ValidationError("number of headers is not correct! there are " +
|
||||||
headerNames.length +
|
headerNames.length +
|
||||||
" but there should be " +
|
" but there should be " +
|
||||||
headerConfig.size());
|
headerConfig.size()+ "\n");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StringWriter errorMessage = new StringWriter();
|
||||||
|
|
||||||
for(int i=0; i<headerConfig.size(); i++) {
|
for(int i=0; i<headerConfig.size(); i++) {
|
||||||
String header = headerConfig.get(i);
|
String header = headerConfig.get(i);
|
||||||
if (!header.equals(headerNames[i])) {
|
if (!header.equals(headerNames[i])) {
|
||||||
result.invalidate("header number " +
|
errorMessage.append("header number " +
|
||||||
i +
|
i +
|
||||||
" does not match \"" +
|
" does not match \"" +
|
||||||
header +
|
header +
|
||||||
"\" should be \"" +
|
"\" should be \"" +
|
||||||
headerNames[i] +
|
headerNames[i] +
|
||||||
"\"");
|
"\""+ "\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!errorMessage.toString().isEmpty()) {
|
||||||
|
result = new ValidationError(errorMessage.toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,10 +39,26 @@
|
|||||||
</VBox>
|
</VBox>
|
||||||
</top>
|
</top>
|
||||||
<center>
|
<center>
|
||||||
<TableView fx:id="tableView" prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER">
|
<SplitPane dividerPositions="0.8" prefHeight="160.0" prefWidth="200.0" BorderPane.alignment="CENTER">
|
||||||
|
<items>
|
||||||
|
<AnchorPane fx:id="tableWrapper">
|
||||||
|
<TableView fx:id="tableView" prefHeight="200.0" prefWidth="200.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" BorderPane.alignment="CENTER">
|
||||||
<columns>
|
<columns>
|
||||||
</columns>
|
</columns>
|
||||||
</TableView>
|
</TableView>
|
||||||
|
</AnchorPane>
|
||||||
|
<VBox>
|
||||||
|
<children>
|
||||||
|
<Label text="Validation Errors">
|
||||||
|
<padding>
|
||||||
|
<Insets bottom="8.0" left="8.0" right="8.0" top="8.0" />
|
||||||
|
</padding>
|
||||||
|
</Label>
|
||||||
|
<ListView fx:id="errorList" minWidth="10.0" prefWidth="200.0" VBox.vgrow="ALWAYS" />
|
||||||
|
</children>
|
||||||
|
</VBox>
|
||||||
|
</items>
|
||||||
|
</SplitPane>
|
||||||
</center>
|
</center>
|
||||||
<bottom>
|
<bottom>
|
||||||
<HBox spacing="8.0" BorderPane.alignment="CENTER">
|
<HBox spacing="8.0" BorderPane.alignment="CENTER">
|
||||||
@@ -54,4 +70,6 @@
|
|||||||
</BorderPane.margin>
|
</BorderPane.margin>
|
||||||
</HBox>
|
</HBox>
|
||||||
</bottom>
|
</bottom>
|
||||||
|
<left>
|
||||||
|
</left>
|
||||||
</BorderPane>
|
</BorderPane>
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ public class CSVModelTest {
|
|||||||
sut.setValidator(validator);
|
sut.setValidator(validator);
|
||||||
|
|
||||||
// assertion
|
// assertion
|
||||||
verify(validator).isValid(TESTHEADER, TESTVALUE);
|
verify(validator).isValid(TESTHEADER, TESTVALUE, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import ninja.javafx.smartcsv.validation.Validator;
|
|||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.mockito.Matchers.anyInt;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
@@ -53,6 +54,6 @@ public class CSVValueTest {
|
|||||||
sut.setValue(VALUE);
|
sut.setValue(VALUE);
|
||||||
|
|
||||||
// assertion
|
// assertion
|
||||||
verify(validator).isValid(COLUMN, VALUE);
|
verify(validator).isValid(COLUMN, VALUE, anyInt());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -86,12 +86,12 @@ public class HeaderValidationTest {
|
|||||||
@Test
|
@Test
|
||||||
public void validation() {
|
public void validation() {
|
||||||
// execution
|
// execution
|
||||||
ValidationState result = sut.isHeaderValid(headerNames);
|
ValidationError result = sut.isHeaderValid(headerNames);
|
||||||
|
|
||||||
// assertion
|
// assertion
|
||||||
assertThat(result.isValid(), is(expectedResult));
|
assertThat(result == null, is(expectedResult));
|
||||||
if (!expectedResult) {
|
if (!expectedResult) {
|
||||||
assertThat(result.error(), is(expectedError));
|
assertThat(result.getMessage(), is(expectedError));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -68,12 +68,12 @@ public class ValidatorTest {
|
|||||||
@Test
|
@Test
|
||||||
public void validation() {
|
public void validation() {
|
||||||
// execution
|
// execution
|
||||||
ValidationState result = sut.isValid(column, value);
|
ValidationError result = sut.isValid(column, value, 0);
|
||||||
|
|
||||||
// assertion
|
// assertion
|
||||||
assertThat(result.isValid(), is(expectedResult));
|
assertThat(result == null, is(expectedResult));
|
||||||
if (!expectedResult) {
|
if (!expectedResult) {
|
||||||
assertThat(result.error(), is(expectedError));
|
assertThat(result.getMessage(), is(expectedError));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user