revisted the model to speed up the validation and to have a better control how much revalitaions have to be done when something changes

This commit is contained in:
2016-08-07 23:13:02 +02:00
parent bc59f08bbb
commit a7bd8d5a3e
24 changed files with 565 additions and 330 deletions

View File

@@ -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<CSVMode
while ((customerMap = mapReader.read(header)) != null) {
CSVRow row = model.addRow();
for (String column : header) {
row.addValue(column, customerMap.get(column));
model.addValue(row, column, customerMap.get(column));
}
}

View File

@@ -72,6 +72,7 @@ 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;
@@ -352,7 +353,7 @@ public class SmartCSVController extends FXMLController {
public void addRow(ActionEvent actionEvent) {
CSVRow row = currentCsvFile.getContent().addRow();
for (String column : currentCsvFile.getContent().getHeader()) {
row.addValue(column, "");
currentCsvFile.getContent().addValue(row, column, "");
}
currentCsvFile.setFileChanged(true);
resetContent();
@@ -408,7 +409,7 @@ public class SmartCSVController extends FXMLController {
runLater(() -> {
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();
});
}
});

View File

@@ -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<List<ValidationError>> {
private Validator validator;
private List<CSVRow> rows;
private String[] header;
public void setValidator(Validator validator) {
this.validator = validator;
}
public void setRows(List<CSVRow> rows) {
this.rows = rows;
}
public void setHeader(String[] header) {
this.header = header;
}
@Override
protected Task<List<ValidationError>> createTask() {
return new Task<List<ValidationError>>() {
@Override
protected List<ValidationError> call() throws Exception {
List<ValidationError> 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<String, ObjectProperty<CSVValue>> table = row.getColumns();
Set<String> 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;
}
};
}
}
}

View File

@@ -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<String, ObjectProperty<CSVValue>> 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;
}
}

View File

@@ -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;
}
}

View File

@@ -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");
}

View File

@@ -274,6 +274,8 @@ public class ValidationEditorController extends FXMLController {
} else {
validationConfiguration.setValueOfRuleFor(selectedColumn.getValue(), null);
}
}
private void updateForm() {

View File

@@ -1,9 +1,34 @@
/*
The MIT License (MIT)
-----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
package ninja.javafx.smartcsv.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

View File

@@ -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<String, Map<Validation.Type, Validation>> columnValidationMap = new HashMap<>();
public void add(String column, Validation validation) {
Map<Validation.Type, Validation> 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<Validation.Type, Validation> 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<Validation.Type, Validation> 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;
}
}

View File

@@ -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
}

View File

@@ -1,9 +1,34 @@
/*
The MIT License (MIT)
-----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
package ninja.javafx.smartcsv.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 {

View File

@@ -1,9 +1,34 @@
/*
The MIT License (MIT)
-----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
package ninja.javafx.smartcsv.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 {

View File

@@ -1,3 +1,28 @@
/*
The MIT License (MIT)
-----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
package ninja.javafx.smartcsv.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 {

View File

@@ -1,9 +1,34 @@
/*
The MIT License (MIT)
-----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
package ninja.javafx.smartcsv.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 {

View File

@@ -1,9 +1,34 @@
/*
The MIT License (MIT)
-----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
package ninja.javafx.smartcsv.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 {

View File

@@ -1,9 +1,34 @@
/*
The MIT License (MIT)
-----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
package ninja.javafx.smartcsv.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 {

View File

@@ -1,9 +1,34 @@
/*
The MIT License (MIT)
-----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
package ninja.javafx.smartcsv.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 {

View File

@@ -1,9 +1,34 @@
/*
The MIT License (MIT)
-----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
package ninja.javafx.smartcsv.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 {

View File

@@ -0,0 +1,110 @@
/*
The MIT License (MIT)
-----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
package ninja.javafx.smartcsv.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<List<ValidationError>> {
private static final Logger logger = LogManager.getLogger(RevalidationService.class);
private Validator validator;
private List<CSVRow> rows;
private String[] header;
public void setValidator(Validator validator) {
this.validator = validator;
}
public void setRows(List<CSVRow> rows) {
this.rows = rows;
}
public void setHeader(String[] header) {
this.header = header;
}
@Override
protected Task<List<ValidationError>> createTask() {
return new Task<List<ValidationError>>() {
@Override
protected List<ValidationError> call() throws Exception {
List<ValidationError> 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<String, ObjectProperty<CSVValue>> table = row.getColumns();
Set<String> 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;
}
};
}
}

View File

@@ -1,9 +1,34 @@
/*
The MIT License (MIT)
-----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
package ninja.javafx.smartcsv.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 {

View File

@@ -1,7 +1,32 @@
/*
The MIT License (MIT)
-----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
package ninja.javafx.smartcsv.validation;
/**
* Created by abi on 07.08.2016.
* Interface for all validations
*/
public interface Validation {

View File

@@ -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<String, Map<Validation.Type, Validation>> columnValidationMap = new HashMap<>();
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// constructors
@@ -57,6 +49,7 @@ public class Validator {
/**
* JSON configuration for this validator
*
* @param validationConfig
*/
public Validator(ValidationConfiguration validationConfig) {
@@ -69,16 +62,40 @@ public class Validator {
// public methods
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public boolean needsColumnValidation(String column) {
Map<Validation.Type, Validation> 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
* @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<Validation.Type, Validation> 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<Validation.Type, Validation> 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<Validation.Type, Validation> validationMap = columnValidationMap.get(column);
if (validationMap != null) {
validationMap.clear();
}
}
private void initColumnValidations() {
if (hasConfig()) {
String[] columns = validationConfig.headerNames();
for (String column : columns) {
initializeColumnWithRules(column);
}
}
}
private void initializeColumnWithRules(String column) {
Boolean alphaNumeric = validationConfig.getAlphanumericRuleFor(column);
if (alphaNumeric != null && alphaNumeric) {
columnValidations.add(column, new AlphaNumericValidation());
add(column, new AlphaNumericValidation());
}
Boolean doubleRule = validationConfig.getDoubleRuleFor(column);
if (doubleRule != null && doubleRule) {
columnValidations.add(column, new DoubleValidation());
add(column, new DoubleValidation());
}
Boolean integerRule = validationConfig.getIntegerRuleFor(column);
if (integerRule != null && integerRule) {
columnValidations.add(column, new IntegerValidation());
add(column, new IntegerValidation());
}
Boolean notEmptyRule = validationConfig.getNotEmptyRuleFor(column);
if (notEmptyRule != null && notEmptyRule) {
columnValidations.add(column, new NotEmptyValidation());
add(column, new NotEmptyValidation());
}
Boolean uniqueRule = validationConfig.getUniqueRuleFor(column);
if (uniqueRule != null && uniqueRule) {
columnValidations.add(column, new UniqueValidation());
add(column, new UniqueValidation());
}
String dateRule = validationConfig.getDateRuleFor(column);
if (dateRule != null && !dateRule.trim().isEmpty()) {
columnValidations.add(column, new DateValidation(dateRule));
add(column, new DateValidation(dateRule));
}
Integer minLength = validationConfig.getMinLengthRuleFor(column);
if (minLength != null) {
columnValidations.add(column, new MinLengthValidation(minLength));
add(column, new MinLengthValidation(minLength));
}
Integer maxLength = validationConfig.getMaxLengthRuleFor(column);
if (maxLength != null) {
columnValidations.add(column, new MaxLengthValidation(maxLength));
add(column, new MaxLengthValidation(maxLength));
}
String regexp = validationConfig.getRegexpRuleFor(column);
if (regexp != null && !regexp.trim().isEmpty()) {
columnValidations.add(column, new RegExpValidation(regexp));
add(column, new RegExpValidation(regexp));
}
String groovy = validationConfig.getGroovyRuleFor(column);
if (groovy != null && !groovy.trim().isEmpty()) {
columnValidations.add(column, new GroovyValidation(groovy));
add(column, new GroovyValidation(groovy));
}
List<String> valueOfRule = validationConfig.getValueOfRuleFor(column);
if (valueOfRule != null && !valueOfRule.isEmpty()) {
columnValidations.add(column, new ValueOfValidation(valueOfRule));
}
}
add(column, new ValueOfValidation(valueOfRule));
}
}

View File

@@ -1,3 +1,28 @@
/*
The MIT License (MIT)
-----------------------------------------------------------------------------
Copyright (c) 2015 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
package ninja.javafx.smartcsv.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 {

View File

@@ -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));
}
}