diff --git a/src/main/java/ninja/javafx/smartcsv/csv/CSVFileReader.java b/src/main/java/ninja/javafx/smartcsv/csv/CSVFileReader.java index a48570f..6f09efc 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 ninja.javafx.smartcsv.fx.table.model.CSVValue; import org.springframework.stereotype.Service; import org.supercsv.io.CsvMapReader; import org.supercsv.io.ICsvMapReader; @@ -60,7 +61,7 @@ public class CSVFileReader extends CSVConfigurable implements FileReader { validationEditorController.updateConfiguration(); currentCsvFile.setFileChanged(true); - currentCsvFile.getContent().revalidate(); + currentCsvFile.getContent().revalidate(column); }); } } @@ -590,7 +591,7 @@ public class SmartCSVController extends FXMLController { * @param header name of the column header * @param tableView the tableview */ - private void addColumn(String header, TableView tableView) { + private void addColumn(final String header, TableView tableView) { TableColumn column = new TableColumn(header); column.setCellValueFactory(new ObservableMapValueFactory(header)); column.setCellFactory(cellFactory); @@ -607,7 +608,6 @@ public class SmartCSVController extends FXMLController { getColumns().get(header).setValue(event.getNewValue()); runLater(() -> { currentCsvFile.setFileChanged(true); - currentCsvFile.getContent().revalidate(); }); } }); diff --git a/src/main/java/ninja/javafx/smartcsv/fx/table/model/CSVModel.java b/src/main/java/ninja/javafx/smartcsv/fx/table/model/CSVModel.java index 4837acb..8dce7da 100644 --- a/src/main/java/ninja/javafx/smartcsv/fx/table/model/CSVModel.java +++ b/src/main/java/ninja/javafx/smartcsv/fx/table/model/CSVModel.java @@ -26,27 +26,20 @@ package ninja.javafx.smartcsv.fx.table.model; -import javafx.beans.property.ObjectProperty; import javafx.collections.FXCollections; import javafx.collections.ObservableList; -import javafx.concurrent.Service; -import javafx.concurrent.Task; +import ninja.javafx.smartcsv.validation.RevalidationService; import ninja.javafx.smartcsv.validation.ValidationConfiguration; import ninja.javafx.smartcsv.validation.ValidationError; import ninja.javafx.smartcsv.validation.Validator; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Set; - /** * The CSVModel is the client representation for the csv filepath. * It holds the data in rows, stores the header and manages the validator. */ -public class CSVModel { +public final class CSVModel { private static final Logger logger = LogManager.getLogger(CSVModel.class); @@ -86,12 +79,22 @@ public class CSVModel { */ public CSVRow addRow() { CSVRow row = new CSVRow(); - row.setValidator(validator); row.setRowNumber(rows.size()); rows.add(row); return row; } + public void addValue(final CSVRow row, final String column, final String value) { + final CSVValue csvValue = row.addValue(column, value); + csvValue.valueProperty().addListener(observable -> { + if (validator.needsColumnValidation(column)) { + revalidate(); + } else { + csvValue.setValidationError(validator.isValid(row.getRowNumber(), column, csvValue.getValue())); + } + }); + } + /** * sets the column headers as string array * @@ -112,6 +115,12 @@ public class CSVModel { } + public void revalidate(String column) { + if (!hasValidator()) return; + validator.reinitializeColumn(column); + revalidate(); + } + /** * walks through the data and validates each value */ @@ -141,73 +150,6 @@ public class CSVModel { return newValidationConfiguration; } - private static class RevalidationService extends Service> { - private Validator validator; - private List rows; - private String[] header; - - public void setValidator(Validator validator) { - this.validator = validator; - } - - public void setRows(List rows) { - this.rows = rows; - } - - public void setHeader(String[] header) { - this.header = header; - } - - @Override - protected Task> createTask() { - return new Task>() { - @Override - protected List call() throws Exception { - List errors = new ArrayList<>(); - try { - if (header != null) { - ValidationError headerError = validator.isHeaderValid(header); - if (headerError != null) { - logger.info("revalidate: header error found"); - errors.add(headerError); - } - } - - - int maxRows = rows.size(); - for (int lineNumber = 0; lineNumber < maxRows; lineNumber++) { - CSVRow row = rows.get(lineNumber); - row.setValidator(validator); - - Map> table = row.getColumns(); - Set columns = table.keySet(); - - for (String column : columns) { - CSVValue value = table.get(column).getValue(); - value.setValidator(validator); - if (validator != null) { - ValidationError validationError = validator.isValid(lineNumber, column, value.getValue()); - if (validationError != null) { - logger.info("revalidate: {} errors found in line {}", validationError.getMessages().size(), lineNumber); - errors.add(validationError); - value.setValidationError(validationError); - } else { - value.setValidationError(null); - } - } else { - value.setValidationError(null); - } - } - } - - } catch (Throwable t) { - logger.error("validation error", t); - } - return errors; - } - }; - } - } } diff --git a/src/main/java/ninja/javafx/smartcsv/fx/table/model/CSVRow.java b/src/main/java/ninja/javafx/smartcsv/fx/table/model/CSVRow.java index 7f144bd..2d10ff0 100644 --- a/src/main/java/ninja/javafx/smartcsv/fx/table/model/CSVRow.java +++ b/src/main/java/ninja/javafx/smartcsv/fx/table/model/CSVRow.java @@ -28,6 +28,8 @@ package ninja.javafx.smartcsv.fx.table.model; import javafx.beans.property.ObjectProperty; import javafx.beans.property.SimpleObjectProperty; +import javafx.beans.value.ChangeListener; +import javafx.beans.value.ObservableValue; import javafx.collections.FXCollections; import javafx.collections.ObservableMap; import ninja.javafx.smartcsv.validation.Validator; @@ -36,18 +38,9 @@ import ninja.javafx.smartcsv.validation.Validator; * This class represents a single row in the csv file. */ public class CSVRow { - private Validator validator; private ObservableMap> columns = FXCollections.observableHashMap(); private int rowNumber; - /** - * single row - * @param validator the reference to the validator - */ - public void setValidator(Validator validator) { - this.validator = validator; - } - /** * sets the row number * @param rowNumber @@ -78,13 +71,11 @@ public class CSVRow { * @param column column name * @param value the value to store */ - public void addValue(String column, String value) { + CSVValue addValue(String column, String value) { CSVValue v = new CSVValue(); - v.setValidator(validator); - v.setColumn(column); - v.setRowNumber(rowNumber); v.setValue(value); columns.put(column, new SimpleObjectProperty<>(v)); + return v; } } diff --git a/src/main/java/ninja/javafx/smartcsv/fx/table/model/CSVValue.java b/src/main/java/ninja/javafx/smartcsv/fx/table/model/CSVValue.java index 3a372f7..57ae498 100644 --- a/src/main/java/ninja/javafx/smartcsv/fx/table/model/CSVValue.java +++ b/src/main/java/ninja/javafx/smartcsv/fx/table/model/CSVValue.java @@ -37,36 +37,9 @@ import ninja.javafx.smartcsv.validation.Validator; * and if the value is valid based on the validator. */ public class CSVValue { - private Validator validator; - private int rowNumber; - private String column; private StringProperty value = new SimpleStringProperty(); private ValidationError valid; - /** - * single value of a cell - * @param validator the reference to the validator - */ - public void setValidator(Validator validator) { - this.validator = validator; - } - - /** - * the row number this value is stored in - * @param row row number - */ - public void setRowNumber(int row) { - this.rowNumber = row; - } - - /** - * the column this value is stored in - * @param column header name of the column - */ - public void setColumn(String column) { - this.column = column; - } - /** * returns the real value * @return the real value @@ -88,9 +61,6 @@ public class CSVValue { * @param value the real value */ public void setValue(String value) { - if (validator != null) { - valid = validator.isValid(rowNumber, column, value); - } this.value.set(value); } @@ -106,7 +76,7 @@ public class CSVValue { * sets the state if a value is valid or not * @param valid the validation state */ - protected void setValidationError(ValidationError valid) { + public void setValidationError(ValidationError valid) { this.valid = valid; } } 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 071a54e..a518b7d 100644 --- a/src/main/java/ninja/javafx/smartcsv/fx/util/I18nValidationUtil.java +++ b/src/main/java/ninja/javafx/smartcsv/fx/util/I18nValidationUtil.java @@ -62,7 +62,7 @@ public class I18nValidationUtil { if (resourceBundle.containsKey(validationMessage.getKey())) { String resourceText = resourceBundle.getString(validationMessage.getKey()); if (validationMessage.getParameters().length > 0) { - message.append(format(resourceText, validationMessage.getParameters())).append("\n"); + message.append(format(resourceText, (Object[]) validationMessage.getParameters())).append("\n"); } else { message.append(resourceText).append("\n"); } diff --git a/src/main/java/ninja/javafx/smartcsv/fx/validation/ValidationEditorController.java b/src/main/java/ninja/javafx/smartcsv/fx/validation/ValidationEditorController.java index ac6615e..dd20e9a 100644 --- a/src/main/java/ninja/javafx/smartcsv/fx/validation/ValidationEditorController.java +++ b/src/main/java/ninja/javafx/smartcsv/fx/validation/ValidationEditorController.java @@ -274,6 +274,8 @@ public class ValidationEditorController extends FXMLController { } else { validationConfiguration.setValueOfRuleFor(selectedColumn.getValue(), null); } + + } private void updateForm() { diff --git a/src/main/java/ninja/javafx/smartcsv/validation/AlphaNumericValidation.java b/src/main/java/ninja/javafx/smartcsv/validation/AlphaNumericValidation.java index 13b7be9..c8cc094 100644 --- a/src/main/java/ninja/javafx/smartcsv/validation/AlphaNumericValidation.java +++ b/src/main/java/ninja/javafx/smartcsv/validation/AlphaNumericValidation.java @@ -1,9 +1,34 @@ +/* + The MIT License (MIT) + ----------------------------------------------------------------------------- + + Copyright (c) 2015 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.validation; import static org.apache.commons.validator.GenericValidator.matchRegexp; /** - * Created by abi on 07.08.2016. + * Checks if the value is alpha numeric */ public class AlphaNumericValidation implements Validation { @Override diff --git a/src/main/java/ninja/javafx/smartcsv/validation/ColumnValidations.java b/src/main/java/ninja/javafx/smartcsv/validation/ColumnValidations.java deleted file mode 100644 index 023ddfb..0000000 --- a/src/main/java/ninja/javafx/smartcsv/validation/ColumnValidations.java +++ /dev/null @@ -1,47 +0,0 @@ -package ninja.javafx.smartcsv.validation; - -import java.util.HashMap; -import java.util.Map; - -/** - * Created by abi on 07.08.2016. - */ -public class ColumnValidations { - - private Map> columnValidationMap = new HashMap<>(); - - public void add(String column, Validation validation) { - Map validationMap = columnValidationMap.get(column); - if (validationMap == null) { - validationMap = new HashMap<>(); - columnValidationMap.put(column, validationMap); - } - validationMap.put(validation.getType(), validation); - } - - public void remove(String column, Validation.Type type) { - Map validationMap = columnValidationMap.get(column); - if (validationMap != null) { - validationMap.remove(type); - } - } - - public ValidationError isValid(int row, String column, String value) { - ValidationError error = ValidationError.withLineNumber(row); - Map validationMap = columnValidationMap.get(column); - if (validationMap != null) { - for (Validation validation: validationMap.values()) { - - if (validation.getType() == Validation.Type.NOT_EMPTY) { - validation.check(row, value, error); - } else { - if (value != null && !value.isEmpty()) { - validation.check(row, value, error); - } - } - } - } - return error; - } - -} diff --git a/src/main/java/ninja/javafx/smartcsv/validation/ColumnValidationsBuilder.java b/src/main/java/ninja/javafx/smartcsv/validation/ColumnValidationsBuilder.java deleted file mode 100644 index 42de7fb..0000000 --- a/src/main/java/ninja/javafx/smartcsv/validation/ColumnValidationsBuilder.java +++ /dev/null @@ -1,16 +0,0 @@ -package ninja.javafx.smartcsv.validation; - -/** - * Created by abi on 07.08.2016. - */ -public class ColumnValidationsBuilder { - - private ColumnValidationsBuilder() {} - - public static ColumnValidationsBuilder columnValidationsBuilder() { - return new ColumnValidationsBuilder(); - } - - //private - -} diff --git a/src/main/java/ninja/javafx/smartcsv/validation/DateValidation.java b/src/main/java/ninja/javafx/smartcsv/validation/DateValidation.java index 7d29608..65db299 100644 --- a/src/main/java/ninja/javafx/smartcsv/validation/DateValidation.java +++ b/src/main/java/ninja/javafx/smartcsv/validation/DateValidation.java @@ -1,9 +1,34 @@ +/* + The MIT License (MIT) + ----------------------------------------------------------------------------- + + Copyright (c) 2015 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.validation; import static org.apache.commons.validator.GenericValidator.isDate; /** - * Created by abi on 07.08.2016. + * Checks if the date has the right format */ public class DateValidation implements Validation { diff --git a/src/main/java/ninja/javafx/smartcsv/validation/DoubleValidation.java b/src/main/java/ninja/javafx/smartcsv/validation/DoubleValidation.java index 566211e..8224e3d 100644 --- a/src/main/java/ninja/javafx/smartcsv/validation/DoubleValidation.java +++ b/src/main/java/ninja/javafx/smartcsv/validation/DoubleValidation.java @@ -1,9 +1,34 @@ +/* + The MIT License (MIT) + ----------------------------------------------------------------------------- + + Copyright (c) 2015 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.validation; import static org.apache.commons.validator.GenericValidator.isDouble; /** - * Created by abi on 07.08.2016. + * Checks if the value is a double */ public class DoubleValidation implements Validation { diff --git a/src/main/java/ninja/javafx/smartcsv/validation/GroovyValidation.java b/src/main/java/ninja/javafx/smartcsv/validation/GroovyValidation.java index 186d1d6..3d74bd8 100644 --- a/src/main/java/ninja/javafx/smartcsv/validation/GroovyValidation.java +++ b/src/main/java/ninja/javafx/smartcsv/validation/GroovyValidation.java @@ -1,3 +1,28 @@ +/* + The MIT License (MIT) + ----------------------------------------------------------------------------- + + Copyright (c) 2015 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.validation; import groovy.lang.Binding; @@ -6,7 +31,7 @@ import groovy.lang.Script; import org.codehaus.groovy.control.CompilationFailedException; /** - * Created by abi on 07.08.2016. + * Executes the given groovy as check */ public class GroovyValidation implements Validation { diff --git a/src/main/java/ninja/javafx/smartcsv/validation/IntegerValidation.java b/src/main/java/ninja/javafx/smartcsv/validation/IntegerValidation.java index 6460b59..198bf36 100644 --- a/src/main/java/ninja/javafx/smartcsv/validation/IntegerValidation.java +++ b/src/main/java/ninja/javafx/smartcsv/validation/IntegerValidation.java @@ -1,9 +1,34 @@ +/* + The MIT License (MIT) + ----------------------------------------------------------------------------- + + Copyright (c) 2015 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.validation; import static org.apache.commons.validator.GenericValidator.isInt; /** - * Created by abi on 07.08.2016. + * Checks if the value is an integer */ public class IntegerValidation implements Validation { diff --git a/src/main/java/ninja/javafx/smartcsv/validation/MaxLengthValidation.java b/src/main/java/ninja/javafx/smartcsv/validation/MaxLengthValidation.java index 44259eb..add6740 100644 --- a/src/main/java/ninja/javafx/smartcsv/validation/MaxLengthValidation.java +++ b/src/main/java/ninja/javafx/smartcsv/validation/MaxLengthValidation.java @@ -1,9 +1,34 @@ +/* + The MIT License (MIT) + ----------------------------------------------------------------------------- + + Copyright (c) 2015 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.validation; import static org.apache.commons.validator.GenericValidator.maxLength; /** - * Created by abi on 07.08.2016. + * Checks if the value is shorter or exactly as long as the given max length */ public class MaxLengthValidation implements Validation { diff --git a/src/main/java/ninja/javafx/smartcsv/validation/MinLengthValidation.java b/src/main/java/ninja/javafx/smartcsv/validation/MinLengthValidation.java index c71bda3..7a2080c 100644 --- a/src/main/java/ninja/javafx/smartcsv/validation/MinLengthValidation.java +++ b/src/main/java/ninja/javafx/smartcsv/validation/MinLengthValidation.java @@ -1,9 +1,34 @@ +/* + The MIT License (MIT) + ----------------------------------------------------------------------------- + + Copyright (c) 2015 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.validation; import static org.apache.commons.validator.GenericValidator.minLength; /** - * Created by abi on 07.08.2016. + * Checks if the value is at minimum long as the given min length */ public class MinLengthValidation implements Validation { diff --git a/src/main/java/ninja/javafx/smartcsv/validation/NotEmptyValidation.java b/src/main/java/ninja/javafx/smartcsv/validation/NotEmptyValidation.java index 492dc48..12deaba 100644 --- a/src/main/java/ninja/javafx/smartcsv/validation/NotEmptyValidation.java +++ b/src/main/java/ninja/javafx/smartcsv/validation/NotEmptyValidation.java @@ -1,9 +1,34 @@ +/* + The MIT License (MIT) + ----------------------------------------------------------------------------- + + Copyright (c) 2015 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.validation; import static org.apache.commons.validator.GenericValidator.isBlankOrNull; /** - * Created by abi on 07.08.2016. + * Checks if the value is not empty */ public class NotEmptyValidation implements Validation { diff --git a/src/main/java/ninja/javafx/smartcsv/validation/RegExpValidation.java b/src/main/java/ninja/javafx/smartcsv/validation/RegExpValidation.java index 8b2d099..0f6f6be 100644 --- a/src/main/java/ninja/javafx/smartcsv/validation/RegExpValidation.java +++ b/src/main/java/ninja/javafx/smartcsv/validation/RegExpValidation.java @@ -1,9 +1,34 @@ +/* + The MIT License (MIT) + ----------------------------------------------------------------------------- + + Copyright (c) 2015 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.validation; import static org.apache.commons.validator.GenericValidator.matchRegexp; /** - * Created by abi on 07.08.2016. + * Checks the value against the given reg exp */ public class RegExpValidation implements Validation { diff --git a/src/main/java/ninja/javafx/smartcsv/validation/RevalidationService.java b/src/main/java/ninja/javafx/smartcsv/validation/RevalidationService.java new file mode 100644 index 0000000..9a36af2 --- /dev/null +++ b/src/main/java/ninja/javafx/smartcsv/validation/RevalidationService.java @@ -0,0 +1,110 @@ +/* + The MIT License (MIT) + ----------------------------------------------------------------------------- + + Copyright (c) 2015 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.validation; + +import javafx.beans.property.ObjectProperty; +import javafx.concurrent.Service; +import javafx.concurrent.Task; +import ninja.javafx.smartcsv.fx.table.model.CSVRow; +import ninja.javafx.smartcsv.fx.table.model.CSVValue; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * Service for running the validation async of the ui thread + */ +public class RevalidationService extends Service> { + + private static final Logger logger = LogManager.getLogger(RevalidationService.class); + + private Validator validator; + private List rows; + private String[] header; + + public void setValidator(Validator validator) { + this.validator = validator; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public void setHeader(String[] header) { + this.header = header; + } + + @Override + protected Task> createTask() { + return new Task>() { + @Override + protected List call() throws Exception { + List errors = new ArrayList<>(); + try { + if (header != null) { + ValidationError headerError = validator.isHeaderValid(header); + if (headerError != null) { + logger.info("revalidate: header error found"); + errors.add(headerError); + } + } + + int maxRows = rows.size(); + for (int lineNumber = 0; lineNumber < maxRows; lineNumber++) { + CSVRow row = rows.get(lineNumber); + + Map> table = row.getColumns(); + Set columns = table.keySet(); + + for (String column : columns) { + CSVValue value = table.get(column).getValue(); + if (validator != null) { + ValidationError validationError = validator.isValid(lineNumber, column, value.getValue()); + if (validationError != null) { + logger.info("revalidate: {} errors found in line {}", validationError.getMessages().size(), lineNumber); + errors.add(validationError); + value.setValidationError(validationError); + } else { + value.setValidationError(null); + } + } else { + value.setValidationError(null); + } + } + } + + } catch (Throwable t) { + logger.error("validation error", t); + } + return errors; + } + }; + } +} \ No newline at end of file diff --git a/src/main/java/ninja/javafx/smartcsv/validation/UniqueValidation.java b/src/main/java/ninja/javafx/smartcsv/validation/UniqueValidation.java index 8f15dc1..4b769c0 100644 --- a/src/main/java/ninja/javafx/smartcsv/validation/UniqueValidation.java +++ b/src/main/java/ninja/javafx/smartcsv/validation/UniqueValidation.java @@ -1,9 +1,34 @@ +/* + The MIT License (MIT) + ----------------------------------------------------------------------------- + + Copyright (c) 2015 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.validation; import java.util.HashMap; /** - * Created by abi on 07.08.2016. + * Checks if the value is unique in the column */ public class UniqueValidation implements Validation { diff --git a/src/main/java/ninja/javafx/smartcsv/validation/Validation.java b/src/main/java/ninja/javafx/smartcsv/validation/Validation.java index 47f7064..27c4b76 100644 --- a/src/main/java/ninja/javafx/smartcsv/validation/Validation.java +++ b/src/main/java/ninja/javafx/smartcsv/validation/Validation.java @@ -1,7 +1,32 @@ +/* + The MIT License (MIT) + ----------------------------------------------------------------------------- + + Copyright (c) 2015 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.validation; /** - * Created by abi on 07.08.2016. + * Interface for all validations */ public interface Validation { diff --git a/src/main/java/ninja/javafx/smartcsv/validation/Validator.java b/src/main/java/ninja/javafx/smartcsv/validation/Validator.java index e23afd0..b7de5a4 100644 --- a/src/main/java/ninja/javafx/smartcsv/validation/Validator.java +++ b/src/main/java/ninja/javafx/smartcsv/validation/Validator.java @@ -26,18 +26,10 @@ package ninja.javafx.smartcsv.validation; -import groovy.lang.Binding; -import groovy.lang.GroovyShell; -import groovy.lang.Script; -import org.codehaus.groovy.control.CompilationFailedException; - import java.util.HashMap; import java.util.List; import java.util.Map; -import static java.util.stream.Collectors.joining; -import static org.apache.commons.validator.GenericValidator.*; - /** * This class checks all the validations defined in the * Config against a given value @@ -49,7 +41,7 @@ public class Validator { //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// private ValidationConfiguration validationConfig; - private ColumnValidations columnValidations = new ColumnValidations(); + private Map> columnValidationMap = new HashMap<>(); //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // constructors @@ -57,10 +49,11 @@ public class Validator { /** * JSON configuration for this validator + * * @param validationConfig */ public Validator(ValidationConfiguration validationConfig) { - this.validationConfig = validationConfig; + this.validationConfig = validationConfig; initColumnValidations(); } @@ -69,16 +62,40 @@ public class Validator { // public methods //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + public boolean needsColumnValidation(String column) { + Map validationMap = columnValidationMap.get(column); + if (validationMap != null) { + return validationMap.containsKey(Validation.Type.UNIQUE); + } + return false; + + } + + /** * checks if the value is valid for the column configuration + * * @param column the column name - * @param value the value to check + * @param value the value to check * @return ValidationError with information if valid and if not which getMessage happened */ - public ValidationError isValid(Integer lineNumber, String column, String value) { + public ValidationError isValid(Integer row, String column, String value) { ValidationError result = null; if (hasConfig()) { - ValidationError error = columnValidations.isValid(lineNumber, column, value); + ValidationError error = ValidationError.withLineNumber(row); + Map validationMap = columnValidationMap.get(column); + if (validationMap != null) { + for (Validation validation: validationMap.values()) { + + if (validation.getType() == Validation.Type.NOT_EMPTY) { + validation.check(row, value, error); + } else { + if (value != null && !value.isEmpty()) { + validation.check(row, value, error); + } + } + } + } if (!error.isEmpty()) { result = error; } @@ -91,68 +108,93 @@ public class Validator { return validationConfig != null; } + public void reinitializeColumn(String column) { + clear(column); + initializeColumnWithRules(column); + } + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // private methods //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + private void add(String column, Validation validation) { + Map validationMap = columnValidationMap.get(column); + if (validationMap == null) { + validationMap = new HashMap<>(); + columnValidationMap.put(column, validationMap); + } + validationMap.put(validation.getType(), validation); + } + + private void clear(String column) { + Map validationMap = columnValidationMap.get(column); + if (validationMap != null) { + validationMap.clear(); + } + } + private void initColumnValidations() { if (hasConfig()) { - String[] columns = validationConfig.headerNames(); - for(String column: columns) { - Boolean alphaNumeric = validationConfig.getAlphanumericRuleFor(column); - if (alphaNumeric != null && alphaNumeric) { - columnValidations.add(column, new AlphaNumericValidation()); - } - - Boolean doubleRule = validationConfig.getDoubleRuleFor(column); - if (doubleRule != null && doubleRule) { - columnValidations.add(column, new DoubleValidation()); - } - - Boolean integerRule = validationConfig.getIntegerRuleFor(column); - if (integerRule != null && integerRule) { - columnValidations.add(column, new IntegerValidation()); - } - - Boolean notEmptyRule = validationConfig.getNotEmptyRuleFor(column); - if (notEmptyRule != null && notEmptyRule) { - columnValidations.add(column, new NotEmptyValidation()); - } - - Boolean uniqueRule = validationConfig.getUniqueRuleFor(column); - if (uniqueRule != null && uniqueRule) { - columnValidations.add(column, new UniqueValidation()); - } - - String dateRule = validationConfig.getDateRuleFor(column); - if (dateRule != null && !dateRule.trim().isEmpty()) { - columnValidations.add(column, new DateValidation(dateRule)); - } - - Integer minLength = validationConfig.getMinLengthRuleFor(column); - if (minLength != null) { - columnValidations.add(column, new MinLengthValidation(minLength)); - } - - Integer maxLength = validationConfig.getMaxLengthRuleFor(column); - if (maxLength != null) { - columnValidations.add(column, new MaxLengthValidation(maxLength)); - } - - String regexp = validationConfig.getRegexpRuleFor(column); - if (regexp != null && !regexp.trim().isEmpty()) { - columnValidations.add(column, new RegExpValidation(regexp)); - } - - String groovy = validationConfig.getGroovyRuleFor(column); - if (groovy != null && !groovy.trim().isEmpty()) { - columnValidations.add(column, new GroovyValidation(groovy)); - } - List valueOfRule = validationConfig.getValueOfRuleFor(column); - if (valueOfRule != null && !valueOfRule.isEmpty()) { - columnValidations.add(column, new ValueOfValidation(valueOfRule)); + String[] columns = validationConfig.headerNames(); + for (String column : columns) { + initializeColumnWithRules(column); } } + } + + private void initializeColumnWithRules(String column) { + Boolean alphaNumeric = validationConfig.getAlphanumericRuleFor(column); + if (alphaNumeric != null && alphaNumeric) { + add(column, new AlphaNumericValidation()); + } + + Boolean doubleRule = validationConfig.getDoubleRuleFor(column); + if (doubleRule != null && doubleRule) { + add(column, new DoubleValidation()); + } + + Boolean integerRule = validationConfig.getIntegerRuleFor(column); + if (integerRule != null && integerRule) { + add(column, new IntegerValidation()); + } + + Boolean notEmptyRule = validationConfig.getNotEmptyRuleFor(column); + if (notEmptyRule != null && notEmptyRule) { + add(column, new NotEmptyValidation()); + } + + Boolean uniqueRule = validationConfig.getUniqueRuleFor(column); + if (uniqueRule != null && uniqueRule) { + add(column, new UniqueValidation()); + } + + String dateRule = validationConfig.getDateRuleFor(column); + if (dateRule != null && !dateRule.trim().isEmpty()) { + add(column, new DateValidation(dateRule)); + } + + Integer minLength = validationConfig.getMinLengthRuleFor(column); + if (minLength != null) { + add(column, new MinLengthValidation(minLength)); + } + + Integer maxLength = validationConfig.getMaxLengthRuleFor(column); + if (maxLength != null) { + add(column, new MaxLengthValidation(maxLength)); + } + + String regexp = validationConfig.getRegexpRuleFor(column); + if (regexp != null && !regexp.trim().isEmpty()) { + add(column, new RegExpValidation(regexp)); + } + + String groovy = validationConfig.getGroovyRuleFor(column); + if (groovy != null && !groovy.trim().isEmpty()) { + add(column, new GroovyValidation(groovy)); + } + List valueOfRule = validationConfig.getValueOfRuleFor(column); + if (valueOfRule != null && !valueOfRule.isEmpty()) { + add(column, new ValueOfValidation(valueOfRule)); } } @@ -171,7 +213,7 @@ public class Validator { ValidationError error = ValidationError.withoutLineNumber(); - for(int i=0; i + + 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.validation; import java.util.List; @@ -5,7 +30,7 @@ import java.util.List; import static java.util.stream.Collectors.joining; /** - * Created by abi on 07.08.2016. + * Checks if the value is part of a list of values */ public class ValueOfValidation implements Validation { diff --git a/src/test/java/ninja/javafx/smartcsv/fx/table/model/CSVValueTest.java b/src/test/java/ninja/javafx/smartcsv/fx/table/model/CSVValueTest.java deleted file mode 100644 index 7523bf3..0000000 --- a/src/test/java/ninja/javafx/smartcsv/fx/table/model/CSVValueTest.java +++ /dev/null @@ -1,60 +0,0 @@ -package ninja.javafx.smartcsv.fx.table.model; - -import ninja.javafx.smartcsv.validation.Validator; -import org.junit.Before; -import org.junit.Test; - -import static org.mockito.Matchers.anyInt; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; - -/** - * unit test for the value class - */ -public class CSVValueTest { - - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // constants - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - static final String COLUMN = "COLUMN"; - static final String VALUE = "VALUE"; - - - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // mocks - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - Validator validator = mock(Validator.class); - - - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // subject under test - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - CSVValue sut; - - - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // init - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - @Before - public void initialize() { - sut = new CSVValue(); - sut.setValidator(validator); - } - - - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // tests - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - @Test - public void set_value_calls_validation() { - //setup - sut.setColumn(COLUMN); - - // execution - sut.setValue(VALUE); - - // assertion - verify(validator).isValid(anyInt(), eq(COLUMN), eq(VALUE)); - } -} \ No newline at end of file