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

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