From bc59f08bbb11f29d93eae9950b4ceadd44fd4c71 Mon Sep 17 00:00:00 2001 From: Andreas Billmann Date: Sun, 7 Aug 2016 16:57:55 +0200 Subject: [PATCH 1/3] first version of new validation algorithm, that is a lot faster --- .../smartcsv/fx/table/model/CSVModel.java | 12 +- .../smartcsv/fx/table/model/CSVValue.java | 2 +- .../validation/AlphaNumericValidation.java | 20 ++ .../validation/ColumnValidations.java | 47 ++++ .../validation/ColumnValidationsBuilder.java | 16 ++ .../smartcsv/validation/DateValidation.java | 28 +++ .../smartcsv/validation/DoubleValidation.java | 21 ++ .../smartcsv/validation/GroovyValidation.java | 53 +++++ .../validation/IntegerValidation.java | 21 ++ .../validation/MaxLengthValidation.java | 27 +++ .../validation/MinLengthValidation.java | 27 +++ .../validation/NotEmptyValidation.java | 21 ++ .../smartcsv/validation/RegExpValidation.java | 27 +++ .../smartcsv/validation/UniqueValidation.java | 29 +++ .../smartcsv/validation/Validation.java | 11 + .../javafx/smartcsv/validation/Validator.java | 223 +++++------------- .../validation/ValueOfValidation.java | 30 +++ .../smartcsv/fx/table/model/CSVValueTest.java | 2 +- .../smartcsv/validation/ValidatorTest.java | 6 +- 19 files changed, 454 insertions(+), 169 deletions(-) create mode 100644 src/main/java/ninja/javafx/smartcsv/validation/AlphaNumericValidation.java create mode 100644 src/main/java/ninja/javafx/smartcsv/validation/ColumnValidations.java create mode 100644 src/main/java/ninja/javafx/smartcsv/validation/ColumnValidationsBuilder.java create mode 100644 src/main/java/ninja/javafx/smartcsv/validation/DateValidation.java create mode 100644 src/main/java/ninja/javafx/smartcsv/validation/DoubleValidation.java create mode 100644 src/main/java/ninja/javafx/smartcsv/validation/GroovyValidation.java create mode 100644 src/main/java/ninja/javafx/smartcsv/validation/IntegerValidation.java create mode 100644 src/main/java/ninja/javafx/smartcsv/validation/MaxLengthValidation.java create mode 100644 src/main/java/ninja/javafx/smartcsv/validation/MinLengthValidation.java create mode 100644 src/main/java/ninja/javafx/smartcsv/validation/NotEmptyValidation.java create mode 100644 src/main/java/ninja/javafx/smartcsv/validation/RegExpValidation.java create mode 100644 src/main/java/ninja/javafx/smartcsv/validation/UniqueValidation.java create mode 100644 src/main/java/ninja/javafx/smartcsv/validation/Validation.java create mode 100644 src/main/java/ninja/javafx/smartcsv/validation/ValueOfValidation.java 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 7356d83..4837acb 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 @@ -53,11 +53,12 @@ public class CSVModel { private Validator validator; private ObservableList rows = FXCollections.observableArrayList(); private String[] header; - private ObservableList validationError = FXCollections.observableArrayList(); + private ObservableList validationError = FXCollections.observableArrayList(); private RevalidationService revalidationService = new RevalidationService(); /** * sets the validator configuration for the data revalidates + * * @param validationConfiguration the validator configuration for this data */ public void setValidationConfiguration(ValidationConfiguration validationConfiguration) { @@ -67,6 +68,7 @@ public class CSVModel { /** * returns the data as a list of rows of the + * * @return list of rows */ public ObservableList getRows() { @@ -79,6 +81,7 @@ public class CSVModel { /** * adds a new and empty row + * * @return the new row */ public CSVRow addRow() { @@ -91,6 +94,7 @@ public class CSVModel { /** * sets the column headers as string array + * * @param header the headers of the columns */ public void setHeader(String[] header) { @@ -100,6 +104,7 @@ public class CSVModel { /** * returns the column headers + * * @return the column headers */ public String[] getHeader() { @@ -116,8 +121,6 @@ public class CSVModel { logger.info("revalidate: hasValidator -> {}", hasValidator()); if (!hasValidator()) return; - - validator.clearScriptCache(); revalidationService.setHeader(header); revalidationService.setRows(rows); revalidationService.setValidator(validator); @@ -171,6 +174,7 @@ public class CSVModel { } } + int maxRows = rows.size(); for (int lineNumber = 0; lineNumber < maxRows; lineNumber++) { CSVRow row = rows.get(lineNumber); @@ -183,7 +187,7 @@ public class CSVModel { CSVValue value = table.get(column).getValue(); value.setValidator(validator); if (validator != null) { - ValidationError validationError = validator.isValid(column, value.getValue(), lineNumber); + 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); 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 3a573b3..3a372f7 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 @@ -89,7 +89,7 @@ public class CSVValue { */ public void setValue(String value) { if (validator != null) { - valid = validator.isValid(column, value, rowNumber); + valid = validator.isValid(rowNumber, column, value); } this.value.set(value); } diff --git a/src/main/java/ninja/javafx/smartcsv/validation/AlphaNumericValidation.java b/src/main/java/ninja/javafx/smartcsv/validation/AlphaNumericValidation.java new file mode 100644 index 0000000..13b7be9 --- /dev/null +++ b/src/main/java/ninja/javafx/smartcsv/validation/AlphaNumericValidation.java @@ -0,0 +1,20 @@ +package ninja.javafx.smartcsv.validation; + +import static org.apache.commons.validator.GenericValidator.matchRegexp; + +/** + * Created by abi on 07.08.2016. + */ +public class AlphaNumericValidation implements Validation { + @Override + public void check(int row, String value, ValidationError error) { + if (!matchRegexp(value, "[0-9a-zA-Z]*")) { + error.add("validation.message.alphanumeric"); + } + } + + @Override + public Type getType() { + return Type.ALPHANUMERIC; + } +} diff --git a/src/main/java/ninja/javafx/smartcsv/validation/ColumnValidations.java b/src/main/java/ninja/javafx/smartcsv/validation/ColumnValidations.java new file mode 100644 index 0000000..023ddfb --- /dev/null +++ b/src/main/java/ninja/javafx/smartcsv/validation/ColumnValidations.java @@ -0,0 +1,47 @@ +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 new file mode 100644 index 0000000..42de7fb --- /dev/null +++ b/src/main/java/ninja/javafx/smartcsv/validation/ColumnValidationsBuilder.java @@ -0,0 +1,16 @@ +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 new file mode 100644 index 0000000..7d29608 --- /dev/null +++ b/src/main/java/ninja/javafx/smartcsv/validation/DateValidation.java @@ -0,0 +1,28 @@ +package ninja.javafx.smartcsv.validation; + +import static org.apache.commons.validator.GenericValidator.isDate; + +/** + * Created by abi on 07.08.2016. + */ +public class DateValidation implements Validation { + + private String dateformat; + + public DateValidation(String dateformat) { + assert dateformat != null && !dateformat.trim().isEmpty() : "empty date format for date validation"; + this.dateformat = dateformat; + } + + @Override + public void check(int row, String value, ValidationError error) { + if (!isDate(value, dateformat, true)) { + error.add("validation.message.date.format", dateformat); + } + } + + @Override + public Type getType() { + return Type.DATE; + } +} diff --git a/src/main/java/ninja/javafx/smartcsv/validation/DoubleValidation.java b/src/main/java/ninja/javafx/smartcsv/validation/DoubleValidation.java new file mode 100644 index 0000000..566211e --- /dev/null +++ b/src/main/java/ninja/javafx/smartcsv/validation/DoubleValidation.java @@ -0,0 +1,21 @@ +package ninja.javafx.smartcsv.validation; + +import static org.apache.commons.validator.GenericValidator.isDouble; + +/** + * Created by abi on 07.08.2016. + */ +public class DoubleValidation implements Validation { + + @Override + public void check(int row, String value, ValidationError error) { + if (!isDouble(value)) { + error.add("validation.message.double"); + } + } + + @Override + public Type getType() { + return Type.DOUBLE; + } +} diff --git a/src/main/java/ninja/javafx/smartcsv/validation/GroovyValidation.java b/src/main/java/ninja/javafx/smartcsv/validation/GroovyValidation.java new file mode 100644 index 0000000..186d1d6 --- /dev/null +++ b/src/main/java/ninja/javafx/smartcsv/validation/GroovyValidation.java @@ -0,0 +1,53 @@ +package ninja.javafx.smartcsv.validation; + +import groovy.lang.Binding; +import groovy.lang.GroovyShell; +import groovy.lang.Script; +import org.codehaus.groovy.control.CompilationFailedException; + +/** + * Created by abi on 07.08.2016. + */ +public class GroovyValidation implements Validation { + + private String groovyScript; + private GroovyShell shell = new GroovyShell(); + private Script script; + + public GroovyValidation(String groovyScript) { + this.groovyScript = groovyScript; + script = shell.parse(groovyScript); + } + + + @Override + public void check(int row, String value, ValidationError error) { + Binding binding = new Binding(); + binding.setVariable("value", value); + script.setBinding(binding); + + Object groovyResult = null; + try { + groovyResult = script.run(); + } catch (CompilationFailedException e) { + error.add("validation.message.groovy.exception", groovyScript, e.getMessage()); + e.printStackTrace(); + } + if (groovyResult == null) { + error.add("validation.message.groovy.return.null", groovyScript); + } + + if (!isScriptResultTrue(groovyResult)) { + error.add(groovyResult.toString()); + } + } + + @Override + public Type getType() { + return Type.GROOVY; + } + + private boolean isScriptResultTrue(Object groovyResult) { + return groovyResult.equals(true) || groovyResult.toString().trim().toLowerCase().equals("true"); + } +} diff --git a/src/main/java/ninja/javafx/smartcsv/validation/IntegerValidation.java b/src/main/java/ninja/javafx/smartcsv/validation/IntegerValidation.java new file mode 100644 index 0000000..6460b59 --- /dev/null +++ b/src/main/java/ninja/javafx/smartcsv/validation/IntegerValidation.java @@ -0,0 +1,21 @@ +package ninja.javafx.smartcsv.validation; + +import static org.apache.commons.validator.GenericValidator.isInt; + +/** + * Created by abi on 07.08.2016. + */ +public class IntegerValidation implements Validation { + + @Override + public void check(int row, String value, ValidationError error) { + if (!isInt(value)) { + error.add("validation.message.integer"); + } + } + + @Override + public Type getType() { + return Type.INTEGER; + } +} diff --git a/src/main/java/ninja/javafx/smartcsv/validation/MaxLengthValidation.java b/src/main/java/ninja/javafx/smartcsv/validation/MaxLengthValidation.java new file mode 100644 index 0000000..44259eb --- /dev/null +++ b/src/main/java/ninja/javafx/smartcsv/validation/MaxLengthValidation.java @@ -0,0 +1,27 @@ +package ninja.javafx.smartcsv.validation; + +import static org.apache.commons.validator.GenericValidator.maxLength; + +/** + * Created by abi on 07.08.2016. + */ +public class MaxLengthValidation implements Validation { + + private int maxLength; + + public MaxLengthValidation(int maxLength) { + this.maxLength = maxLength; + } + + @Override + public void check(int row, String value, ValidationError error) { + if (!maxLength(value, maxLength)) { + error.add("validation.message.max.length", Integer.toString(maxLength)); + } + } + + @Override + public Type getType() { + return Type.MAX_LENGTH; + } +} diff --git a/src/main/java/ninja/javafx/smartcsv/validation/MinLengthValidation.java b/src/main/java/ninja/javafx/smartcsv/validation/MinLengthValidation.java new file mode 100644 index 0000000..c71bda3 --- /dev/null +++ b/src/main/java/ninja/javafx/smartcsv/validation/MinLengthValidation.java @@ -0,0 +1,27 @@ +package ninja.javafx.smartcsv.validation; + +import static org.apache.commons.validator.GenericValidator.minLength; + +/** + * Created by abi on 07.08.2016. + */ +public class MinLengthValidation implements Validation { + + private int minLength; + + public MinLengthValidation(int minLength) { + this.minLength = minLength; + } + + @Override + public void check(int row, String value, ValidationError error) { + if (!minLength(value, minLength)) { + error.add("validation.message.min.length", Integer.toString(minLength)); + } + } + + @Override + public Type getType() { + return Type.MIN_LENGTH; + } +} diff --git a/src/main/java/ninja/javafx/smartcsv/validation/NotEmptyValidation.java b/src/main/java/ninja/javafx/smartcsv/validation/NotEmptyValidation.java new file mode 100644 index 0000000..492dc48 --- /dev/null +++ b/src/main/java/ninja/javafx/smartcsv/validation/NotEmptyValidation.java @@ -0,0 +1,21 @@ +package ninja.javafx.smartcsv.validation; + +import static org.apache.commons.validator.GenericValidator.isBlankOrNull; + +/** + * Created by abi on 07.08.2016. + */ +public class NotEmptyValidation implements Validation { + + @Override + public void check(int row, String value, ValidationError error) { + if (isBlankOrNull(value)) { + error.add("validation.message.not.empty"); + } + } + + @Override + public Type getType() { + return Type.NOT_EMPTY; + } +} diff --git a/src/main/java/ninja/javafx/smartcsv/validation/RegExpValidation.java b/src/main/java/ninja/javafx/smartcsv/validation/RegExpValidation.java new file mode 100644 index 0000000..8b2d099 --- /dev/null +++ b/src/main/java/ninja/javafx/smartcsv/validation/RegExpValidation.java @@ -0,0 +1,27 @@ +package ninja.javafx.smartcsv.validation; + +import static org.apache.commons.validator.GenericValidator.matchRegexp; + +/** + * Created by abi on 07.08.2016. + */ +public class RegExpValidation implements Validation { + + private String regexp; + + public RegExpValidation(String regexp) { + this.regexp = regexp; + } + + @Override + public void check(int row, String value, ValidationError error) { + if (!matchRegexp(value, regexp)) { + error.add("validation.message.regexp", regexp); + } + } + + @Override + public Type getType() { + return Type.REGEXP; + } +} diff --git a/src/main/java/ninja/javafx/smartcsv/validation/UniqueValidation.java b/src/main/java/ninja/javafx/smartcsv/validation/UniqueValidation.java new file mode 100644 index 0000000..8f15dc1 --- /dev/null +++ b/src/main/java/ninja/javafx/smartcsv/validation/UniqueValidation.java @@ -0,0 +1,29 @@ +package ninja.javafx.smartcsv.validation; + +import java.util.HashMap; + +/** + * Created by abi on 07.08.2016. + */ +public class UniqueValidation implements Validation { + + private HashMap columnValueMap = new HashMap<>(); + + @Override + public void check(int row, String value, ValidationError error) { + Integer valueInLineNumber = columnValueMap.get(value); + if (valueInLineNumber != null) { + if (!valueInLineNumber.equals(row)) { + valueInLineNumber += 1; // show not 0 based line numbers to user + error.add("validation.message.uniqueness", value, valueInLineNumber.toString()); + } + } else { + columnValueMap.put(value, row); + } + } + + @Override + public Type getType() { + return Type.UNIQUE; + } +} diff --git a/src/main/java/ninja/javafx/smartcsv/validation/Validation.java b/src/main/java/ninja/javafx/smartcsv/validation/Validation.java new file mode 100644 index 0000000..47f7064 --- /dev/null +++ b/src/main/java/ninja/javafx/smartcsv/validation/Validation.java @@ -0,0 +1,11 @@ +package ninja.javafx.smartcsv.validation; + +/** + * Created by abi on 07.08.2016. + */ +public interface Validation { + + enum Type { NOT_EMPTY, UNIQUE, DOUBLE, INTEGER, MIN_LENGTH, MAX_LENGTH, DATE, ALPHANUMERIC, REGEXP, VALUE_OF, GROOVY } + void check(int row, String value, ValidationError error); + Type getType(); +} diff --git a/src/main/java/ninja/javafx/smartcsv/validation/Validator.java b/src/main/java/ninja/javafx/smartcsv/validation/Validator.java index 0c4c820..e23afd0 100644 --- a/src/main/java/ninja/javafx/smartcsv/validation/Validator.java +++ b/src/main/java/ninja/javafx/smartcsv/validation/Validator.java @@ -49,9 +49,7 @@ public class Validator { //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// private ValidationConfiguration validationConfig; - private GroovyShell shell = new GroovyShell(); - private Map scriptCache = new HashMap<>(); - private Map> uniquenessLookupTable = new HashMap<>(); + private ColumnValidations columnValidations = new ColumnValidations(); //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // constructors @@ -63,6 +61,7 @@ public class Validator { */ public Validator(ValidationConfiguration validationConfig) { this.validationConfig = validationConfig; + initColumnValidations(); } @@ -76,25 +75,10 @@ public class Validator { * @param value the value to check * @return ValidationError with information if valid and if not which getMessage happened */ - public ValidationError isValid(String column, String value, Integer lineNumber) { + public ValidationError isValid(Integer lineNumber, String column, String value) { ValidationError result = null; if (hasConfig()) { - - ValidationError error = ValidationError.withLineNumber(lineNumber); - checkBlankOrNull(column, value, error); - if (value != null && !value.isEmpty()) { - checkRegularExpression(column, value, error); - checkAlphaNumeric(column, value, error); - checkDate(column, value, error); - checkMaxLength(column, value, error); - checkMinLength(column, value, error); - checkInteger(column, value, error); - checkGroovy(column, value, error); - checkValueOf(column, value, error); - checkDouble(column, value, error); - checkUniqueness(column, value, lineNumber, error); - } - + ValidationError error = columnValidations.isValid(lineNumber, column, value); if (!error.isEmpty()) { result = error; } @@ -102,6 +86,7 @@ public class Validator { return result; } + public boolean hasConfig() { return validationConfig != null; } @@ -110,147 +95,67 @@ public class Validator { // private methods //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - private void checkUniqueness(String column, String value, Integer lineNumber, ValidationError error) { - Boolean uniqueRule = validationConfig.getUniqueRuleFor(column); - if (uniqueRule != null && uniqueRule) { - HashMap columnValueMap = uniquenessLookupTable.get(column); - columnValueMap = getColumnValueMap(column, columnValueMap); - Integer valueInLineNumber = columnValueMap.get(value); - if (valueInLineNumber != null) { - if (!valueInLineNumber.equals(lineNumber)) { - error.add("validation.message.uniqueness", value, valueInLineNumber.toString()); - } - } else { - columnValueMap.put(value, lineNumber); + 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)); + } + } } } - private HashMap getColumnValueMap(String column, HashMap valueLineNumber) { - if (valueLineNumber == null) { - valueLineNumber = new HashMap<>(); - uniquenessLookupTable.put(column, valueLineNumber); - } - return valueLineNumber; - } - - private void checkGroovy(String column, String value, ValidationError error) { - String groovyScript = validationConfig.getGroovyRuleFor(column); - if (groovyScript != null) { - - Script script = scriptCache.get(column); - if (script == null) { - script = shell.parse(groovyScript); - scriptCache.put(column, script); - } - - Binding binding = new Binding(); - binding.setVariable("value", value); - script.setBinding(binding); - - Object groovyResult = null; - try { - groovyResult = script.run(); - } catch (CompilationFailedException e) { - error.add("validation.message.groovy.exception", groovyScript, e.getMessage()); - e.printStackTrace(); - } - if (groovyResult == null) { - error.add("validation.message.groovy.return.null", groovyScript); - } - - if (!isScriptResultTrue(groovyResult)) { - error.add(groovyResult.toString()); - } - - } - } - - private boolean isScriptResultTrue(Object groovyResult) { - return groovyResult.equals(true) || groovyResult.toString().trim().toLowerCase().equals("true"); - } - - private void checkValueOf(String column, String value, ValidationError error) { - List values = validationConfig.getValueOfRuleFor(column); - if (values != null) { - if (!values.contains(value)) { - String commaSeparated = values.stream().collect(joining(", ")); - error.add("validation.message.value.of", value, commaSeparated); - } - } - } - - private void checkBlankOrNull(String column, String value, ValidationError error) { - Boolean notEmptyRule = validationConfig.getNotEmptyRuleFor(column); - if (notEmptyRule != null && notEmptyRule) { - if (isBlankOrNull(value)) { - error.add("validation.message.not.empty"); - } - } - } - - private void checkInteger(String column, String value, ValidationError error) { - Boolean integerRule = validationConfig.getIntegerRuleFor(column); - if (integerRule != null && integerRule) { - if (!isInt(value)) { - error.add("validation.message.integer"); - } - } - } - - private void checkDouble(String column, String value, ValidationError error) { - Boolean doubleRule = validationConfig.getDoubleRuleFor(column); - if (doubleRule != null && doubleRule) { - if (!isDouble(value)) { - error.add("validation.message.double"); - } - } - } - - private void checkMinLength(String column, String value, ValidationError error) { - Integer minLength = validationConfig.getMinLengthRuleFor(column); - if (minLength != null) { - if (!minLength(value, minLength)) { - error.add("validation.message.min.length", minLength.toString()); - } - } - } - - private void checkMaxLength(String column, String value, ValidationError error) { - Integer maxLength = validationConfig.getMaxLengthRuleFor(column); - if (maxLength != null) { - if (!maxLength(value, maxLength)) { - error.add("validation.message.max.length", maxLength.toString()); - } - } - } - - private void checkDate(String column, String value, ValidationError error) { - String dateformat = validationConfig.getDateRuleFor(column); - if (dateformat != null && !dateformat.trim().isEmpty()) { - if (!isDate(value, dateformat, true)) { - error.add("validation.message.date.format", dateformat); - } - } - } - - private void checkAlphaNumeric(String column, String value, ValidationError error) { - Boolean alphaNumericRule = validationConfig.getAlphanumericRuleFor(column); - if (alphaNumericRule != null && alphaNumericRule) { - if (!matchRegexp(value, "[0-9a-zA-Z]*")) { - error.add("validation.message.alphanumeric"); - } - } - } - - private void checkRegularExpression(String column, String value, ValidationError error) { - String regexp = validationConfig.getRegexpRuleFor(column); - if (regexp != null && !regexp.trim().isEmpty()) { - if (!matchRegexp(value, regexp)) { - error.add("validation.message.regexp", regexp); - } - } - } public ValidationError isHeaderValid(String[] headerNames) { ValidationError result = null; @@ -281,8 +186,4 @@ public class Validator { } return result; } - - public void clearScriptCache() { - scriptCache.clear(); - } } diff --git a/src/main/java/ninja/javafx/smartcsv/validation/ValueOfValidation.java b/src/main/java/ninja/javafx/smartcsv/validation/ValueOfValidation.java new file mode 100644 index 0000000..24333c5 --- /dev/null +++ b/src/main/java/ninja/javafx/smartcsv/validation/ValueOfValidation.java @@ -0,0 +1,30 @@ +package ninja.javafx.smartcsv.validation; + +import java.util.List; + +import static java.util.stream.Collectors.joining; + +/** + * Created by abi on 07.08.2016. + */ +public class ValueOfValidation implements Validation { + + private List values; + + public ValueOfValidation(List values) { + this.values = values; + } + + @Override + public void check(int row, String value, ValidationError error) { + if (!values.contains(value)) { + String commaSeparated = values.stream().collect(joining(", ")); + error.add("validation.message.value.of", value, commaSeparated); + } + } + + @Override + public Type getType() { + return Type.VALUE_OF; + } +} 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 index acf016e..7523bf3 100644 --- a/src/test/java/ninja/javafx/smartcsv/fx/table/model/CSVValueTest.java +++ b/src/test/java/ninja/javafx/smartcsv/fx/table/model/CSVValueTest.java @@ -55,6 +55,6 @@ public class CSVValueTest { sut.setValue(VALUE); // assertion - verify(validator).isValid(eq(COLUMN), eq(VALUE), anyInt()); + verify(validator).isValid(anyInt(), eq(COLUMN), eq(VALUE)); } } \ No newline at end of file diff --git a/src/test/java/ninja/javafx/smartcsv/validation/ValidatorTest.java b/src/test/java/ninja/javafx/smartcsv/validation/ValidatorTest.java index 0f8c649..0a833f6 100644 --- a/src/test/java/ninja/javafx/smartcsv/validation/ValidatorTest.java +++ b/src/test/java/ninja/javafx/smartcsv/validation/ValidatorTest.java @@ -70,8 +70,10 @@ public class ValidatorTest { //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @Test public void validation() { + System.out.println(column + " " + value + " " + expectedResult + " " + expectedError); + // execution - ValidationError result = sut.isValid(column, value, 0); + ValidationError result = sut.isValid(0, column, value); // assertion assertThat(result == null, is(expectedResult)); @@ -112,7 +114,7 @@ public class ValidatorTest { } public static String json(String column, String rule, Object value) { - String json = "{\"columns\":{\"" + column + "\":{\"" + rule + "\":"; + String json = "{\"headers\": { \"list\": [\""+column+"\"]},\"columns\":{\"" + column + "\":{\"" + rule + "\":"; if (value instanceof String) { json += "\""+ value + "\""; } else if (value instanceof List) { From a7bd8d5a3e94583fbede4a4d4021000014247686 Mon Sep 17 00:00:00 2001 From: Andreas Billmann Date: Sun, 7 Aug 2016 23:13:02 +0200 Subject: [PATCH 2/3] revisted the model to speed up the validation and to have a better control how much revalitaions have to be done when something changes --- .../javafx/smartcsv/csv/CSVFileReader.java | 3 +- .../smartcsv/fx/SmartCSVController.java | 8 +- .../smartcsv/fx/table/model/CSVModel.java | 96 ++-------- .../smartcsv/fx/table/model/CSVRow.java | 17 +- .../smartcsv/fx/table/model/CSVValue.java | 32 +--- .../smartcsv/fx/util/I18nValidationUtil.java | 2 +- .../ValidationEditorController.java | 2 + .../validation/AlphaNumericValidation.java | 27 ++- .../validation/ColumnValidations.java | 47 ----- .../validation/ColumnValidationsBuilder.java | 16 -- .../smartcsv/validation/DateValidation.java | 27 ++- .../smartcsv/validation/DoubleValidation.java | 27 ++- .../smartcsv/validation/GroovyValidation.java | 27 ++- .../validation/IntegerValidation.java | 27 ++- .../validation/MaxLengthValidation.java | 27 ++- .../validation/MinLengthValidation.java | 27 ++- .../validation/NotEmptyValidation.java | 27 ++- .../smartcsv/validation/RegExpValidation.java | 27 ++- .../validation/RevalidationService.java | 110 +++++++++++ .../smartcsv/validation/UniqueValidation.java | 27 ++- .../smartcsv/validation/Validation.java | 27 ++- .../javafx/smartcsv/validation/Validator.java | 178 +++++++++++------- .../validation/ValueOfValidation.java | 27 ++- .../smartcsv/fx/table/model/CSVValueTest.java | 60 ------ 24 files changed, 565 insertions(+), 330 deletions(-) delete mode 100644 src/main/java/ninja/javafx/smartcsv/validation/ColumnValidations.java delete mode 100644 src/main/java/ninja/javafx/smartcsv/validation/ColumnValidationsBuilder.java create mode 100644 src/main/java/ninja/javafx/smartcsv/validation/RevalidationService.java delete mode 100644 src/test/java/ninja/javafx/smartcsv/fx/table/model/CSVValueTest.java 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 From ab952aa98ff10e348540e48c39b84b88785262a8 Mon Sep 17 00:00:00 2001 From: Andreas Billmann Date: Sun, 7 Aug 2016 23:13:47 +0200 Subject: [PATCH 3/3] optimized imports based on intellij IDEA --- .../javafx/smartcsv/csv/CSVFileReader.java | 2 -- .../javafx/smartcsv/csv/CSVFileWriter.java | 1 - .../ninja/javafx/smartcsv/fx/SmartCSV.java | 2 -- .../smartcsv/fx/SmartCSVController.java | 8 ------ .../javafx/smartcsv/fx/list/ErrorSideBar.java | 1 - .../smartcsv/fx/list/GotoLineDialog.java | 1 - .../fx/table/EditableValidationCell.java | 1 - .../smartcsv/fx/table/model/CSVRow.java | 3 --- .../smartcsv/fx/table/model/CSVValue.java | 1 - .../smartcsv/fx/util/LoadFileService.java | 3 --- .../smartcsv/fx/util/SaveFileService.java | 6 ----- .../preferences/PreferencesFileReader.java | 1 - .../preferences/PreferencesFileWriter.java | 1 - .../validation/ValidationFileReader.java | 1 - .../validation/ValidationFileWriter.java | 1 - .../ninja/javafx/smartcsv/fx/about/about.fxml | 13 +++------- .../smartcsv/fx/preferences/preferences.fxml | 4 +-- .../ninja/javafx/smartcsv/fx/smartcsv.fxml | 26 ++++--------------- .../fx/validation/validationEditor.fxml | 12 +++------ .../smartcsv/fx/table/model/CSVModelTest.java | 5 +--- .../smartcsv/fx/table/model/CSVRowTest.java | 5 +--- 21 files changed, 14 insertions(+), 84 deletions(-) diff --git a/src/main/java/ninja/javafx/smartcsv/csv/CSVFileReader.java b/src/main/java/ninja/javafx/smartcsv/csv/CSVFileReader.java index 6f09efc..99f077f 100644 --- a/src/main/java/ninja/javafx/smartcsv/csv/CSVFileReader.java +++ b/src/main/java/ninja/javafx/smartcsv/csv/CSVFileReader.java @@ -29,8 +29,6 @@ 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; diff --git a/src/main/java/ninja/javafx/smartcsv/csv/CSVFileWriter.java b/src/main/java/ninja/javafx/smartcsv/csv/CSVFileWriter.java index 9e63ccf..0fe6d9f 100644 --- a/src/main/java/ninja/javafx/smartcsv/csv/CSVFileWriter.java +++ b/src/main/java/ninja/javafx/smartcsv/csv/CSVFileWriter.java @@ -28,7 +28,6 @@ package ninja.javafx.smartcsv.csv; import ninja.javafx.smartcsv.fx.table.model.CSVModel; import ninja.javafx.smartcsv.fx.table.model.CSVRow; -import org.springframework.stereotype.Service; import org.supercsv.io.CsvMapWriter; import org.supercsv.io.ICsvMapWriter; diff --git a/src/main/java/ninja/javafx/smartcsv/fx/SmartCSV.java b/src/main/java/ninja/javafx/smartcsv/fx/SmartCSV.java index 19bfb12..881c3f5 100644 --- a/src/main/java/ninja/javafx/smartcsv/fx/SmartCSV.java +++ b/src/main/java/ninja/javafx/smartcsv/fx/SmartCSV.java @@ -28,11 +28,9 @@ package ninja.javafx.smartcsv.fx; import javafx.application.Application; import javafx.application.Platform; -import javafx.event.EventHandler; import javafx.scene.Parent; import javafx.scene.Scene; import javafx.stage.Stage; -import javafx.stage.WindowEvent; import ninja.javafx.smartcsv.fx.about.AboutController; import org.springframework.context.annotation.*; import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; diff --git a/src/main/java/ninja/javafx/smartcsv/fx/SmartCSVController.java b/src/main/java/ninja/javafx/smartcsv/fx/SmartCSVController.java index b2c7918..567a1b0 100644 --- a/src/main/java/ninja/javafx/smartcsv/fx/SmartCSVController.java +++ b/src/main/java/ninja/javafx/smartcsv/fx/SmartCSVController.java @@ -26,10 +26,6 @@ package ninja.javafx.smartcsv.fx; -import javafx.beans.InvalidationListener; -import javafx.beans.Observable; -import javafx.beans.value.ChangeListener; -import javafx.beans.value.ObservableValue; import javafx.collections.ListChangeListener; import javafx.collections.WeakListChangeListener; import javafx.concurrent.WorkerStateEvent; @@ -41,7 +37,6 @@ import javafx.scene.control.*; import javafx.scene.layout.AnchorPane; import javafx.scene.layout.BorderPane; import javafx.stage.FileChooser; -import javafx.util.converter.NumberStringConverter; import ninja.javafx.smartcsv.csv.CSVFileReader; import ninja.javafx.smartcsv.csv.CSVFileWriter; import ninja.javafx.smartcsv.files.FileStorage; @@ -71,12 +66,9 @@ import org.supercsv.prefs.CsvPreference; import java.io.File; import java.io.IOException; import java.net.URL; -import java.text.MessageFormat; -import java.util.Collection; import java.util.Optional; import java.util.ResourceBundle; -import static java.lang.Integer.parseInt; import static java.lang.Math.max; import static java.text.MessageFormat.format; import static javafx.application.Platform.exit; 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 cca48f6..6b2cfa4 100644 --- a/src/main/java/ninja/javafx/smartcsv/fx/list/ErrorSideBar.java +++ b/src/main/java/ninja/javafx/smartcsv/fx/list/ErrorSideBar.java @@ -36,7 +36,6 @@ import javafx.scene.layout.Region; import javafx.scene.layout.VBox; import javafx.scene.text.Text; import ninja.javafx.smartcsv.fx.table.model.CSVModel; -import ninja.javafx.smartcsv.fx.util.ColorConstants; import ninja.javafx.smartcsv.validation.ValidationError; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; diff --git a/src/main/java/ninja/javafx/smartcsv/fx/list/GotoLineDialog.java b/src/main/java/ninja/javafx/smartcsv/fx/list/GotoLineDialog.java index f187ff6..e92e2ef 100644 --- a/src/main/java/ninja/javafx/smartcsv/fx/list/GotoLineDialog.java +++ b/src/main/java/ninja/javafx/smartcsv/fx/list/GotoLineDialog.java @@ -1,6 +1,5 @@ package ninja.javafx.smartcsv.fx.list; -import com.sun.javafx.scene.control.skin.resources.ControlResources; import javafx.application.Platform; import javafx.geometry.Pos; import javafx.scene.control.*; diff --git a/src/main/java/ninja/javafx/smartcsv/fx/table/EditableValidationCell.java b/src/main/java/ninja/javafx/smartcsv/fx/table/EditableValidationCell.java index 98453b0..c4054cf 100644 --- a/src/main/java/ninja/javafx/smartcsv/fx/table/EditableValidationCell.java +++ b/src/main/java/ninja/javafx/smartcsv/fx/table/EditableValidationCell.java @@ -33,7 +33,6 @@ import javafx.scene.control.Tooltip; import javafx.scene.input.KeyCode; import ninja.javafx.smartcsv.fx.table.model.CSVRow; import ninja.javafx.smartcsv.fx.table.model.CSVValue; -import ninja.javafx.smartcsv.fx.util.ColorConstants; import java.util.ResourceBundle; 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 2d10ff0..fcd0429 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,11 +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; /** * This class represents a single row in the csv file. 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 57ae498..7903655 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 @@ -29,7 +29,6 @@ package ninja.javafx.smartcsv.fx.table.model; import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.StringProperty; import ninja.javafx.smartcsv.validation.ValidationError; -import ninja.javafx.smartcsv.validation.Validator; /** * The csv value represents the value of a single cell. diff --git a/src/main/java/ninja/javafx/smartcsv/fx/util/LoadFileService.java b/src/main/java/ninja/javafx/smartcsv/fx/util/LoadFileService.java index 3aa3335..49606f0 100644 --- a/src/main/java/ninja/javafx/smartcsv/fx/util/LoadFileService.java +++ b/src/main/java/ninja/javafx/smartcsv/fx/util/LoadFileService.java @@ -28,11 +28,8 @@ package ninja.javafx.smartcsv.fx.util; import javafx.concurrent.Service; import javafx.concurrent.Task; -import ninja.javafx.smartcsv.FileReader; import ninja.javafx.smartcsv.files.FileStorage; -import java.io.File; - /** * Service class for async load of a csv file */ diff --git a/src/main/java/ninja/javafx/smartcsv/fx/util/SaveFileService.java b/src/main/java/ninja/javafx/smartcsv/fx/util/SaveFileService.java index 86c6295..03c943b 100644 --- a/src/main/java/ninja/javafx/smartcsv/fx/util/SaveFileService.java +++ b/src/main/java/ninja/javafx/smartcsv/fx/util/SaveFileService.java @@ -28,14 +28,8 @@ package ninja.javafx.smartcsv.fx.util; import javafx.concurrent.Service; import javafx.concurrent.Task; -import ninja.javafx.smartcsv.FileWriter; -import ninja.javafx.smartcsv.csv.CSVFileWriter; import ninja.javafx.smartcsv.files.FileStorage; -import java.io.File; - -import static javafx.application.Platform.runLater; - /** * Service class for async load of a csv file */ diff --git a/src/main/java/ninja/javafx/smartcsv/preferences/PreferencesFileReader.java b/src/main/java/ninja/javafx/smartcsv/preferences/PreferencesFileReader.java index 5a9c920..f6258f6 100644 --- a/src/main/java/ninja/javafx/smartcsv/preferences/PreferencesFileReader.java +++ b/src/main/java/ninja/javafx/smartcsv/preferences/PreferencesFileReader.java @@ -28,7 +28,6 @@ package ninja.javafx.smartcsv.preferences; import com.google.gson.GsonBuilder; import ninja.javafx.smartcsv.FileReader; -import org.springframework.stereotype.Service; import org.supercsv.prefs.CsvPreference; import org.supercsv.quote.AlwaysQuoteMode; diff --git a/src/main/java/ninja/javafx/smartcsv/preferences/PreferencesFileWriter.java b/src/main/java/ninja/javafx/smartcsv/preferences/PreferencesFileWriter.java index 9b70649..76fe6e9 100644 --- a/src/main/java/ninja/javafx/smartcsv/preferences/PreferencesFileWriter.java +++ b/src/main/java/ninja/javafx/smartcsv/preferences/PreferencesFileWriter.java @@ -29,7 +29,6 @@ package ninja.javafx.smartcsv.preferences; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import ninja.javafx.smartcsv.FileWriter; -import org.springframework.stereotype.Service; import org.supercsv.prefs.CsvPreference; import java.io.File; diff --git a/src/main/java/ninja/javafx/smartcsv/validation/ValidationFileReader.java b/src/main/java/ninja/javafx/smartcsv/validation/ValidationFileReader.java index 6d4ede7..45e8a60 100644 --- a/src/main/java/ninja/javafx/smartcsv/validation/ValidationFileReader.java +++ b/src/main/java/ninja/javafx/smartcsv/validation/ValidationFileReader.java @@ -28,7 +28,6 @@ package ninja.javafx.smartcsv.validation; import com.google.gson.GsonBuilder; import ninja.javafx.smartcsv.FileReader; -import org.springframework.stereotype.Service; import java.io.File; import java.io.IOException; diff --git a/src/main/java/ninja/javafx/smartcsv/validation/ValidationFileWriter.java b/src/main/java/ninja/javafx/smartcsv/validation/ValidationFileWriter.java index 8fe2a49..328fcb9 100644 --- a/src/main/java/ninja/javafx/smartcsv/validation/ValidationFileWriter.java +++ b/src/main/java/ninja/javafx/smartcsv/validation/ValidationFileWriter.java @@ -29,7 +29,6 @@ package ninja.javafx.smartcsv.validation; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import ninja.javafx.smartcsv.FileWriter; -import org.springframework.stereotype.Service; import java.io.File; import java.io.IOException; diff --git a/src/main/resources/ninja/javafx/smartcsv/fx/about/about.fxml b/src/main/resources/ninja/javafx/smartcsv/fx/about/about.fxml index 20ed5f5..55b5cab 100644 --- a/src/main/resources/ninja/javafx/smartcsv/fx/about/about.fxml +++ b/src/main/resources/ninja/javafx/smartcsv/fx/about/about.fxml @@ -1,16 +1,9 @@ - - - - - - - - - + + + -