package com.megatim.fdxcommons.tools.database.queries.validation;
|
|
import com.megatim.fdxcommons.model.enumeration.TypeDonnee;
|
import com.megatim.fdxcommons.model.integration.ColumnDefinition;
|
import com.megatim.fdxcommons.tools.database.exceptions.LocalDateTimeValueParseError;
|
import com.megatim.fdxcommons.tools.database.queries.metadata.InsertionLocalDateTimeValue;
|
import java.util.ArrayList;
|
import java.util.LinkedHashMap;
|
import java.util.List;
|
import java.util.Map;
|
import java.util.stream.Collectors;
|
import org.apache.commons.validator.GenericValidator;
|
|
/**
|
*
|
* @author Gabuntu
|
*/
|
public class TableDataValidationError {
|
|
private final ArrayList<String> errors = new ArrayList<>();
|
|
private final Map<String, ColumnDefinition> columnNameToColumnDefinition;
|
private final List<ColumnDefinition> columnDefinitions;
|
private final List<LinkedHashMap<String, Object>> data;
|
private final boolean withOptionalColumn;
|
|
public TableDataValidationError(List<LinkedHashMap<String, Object>> data, List<ColumnDefinition> columnDefinitions) {
|
this(data, columnDefinitions, false);
|
}
|
|
public TableDataValidationError(List<LinkedHashMap<String, Object>> data, List<ColumnDefinition> columnDefinitions, boolean withOptionalColumn) {
|
this.data = data;
|
this.withOptionalColumn = withOptionalColumn;
|
this.columnDefinitions = columnDefinitions;
|
this.columnNameToColumnDefinition = columnDefinitions.stream().collect(Collectors.toMap(c -> c.getName().trim().toLowerCase(), c -> c));
|
}
|
|
public String validationError() {
|
if (errors.isEmpty()) {
|
int index = 1;
|
for (Map<String, Object> dataItem : data) {
|
processDataItem(dataItem, index++);
|
}
|
}
|
return error();
|
}
|
|
private String error() {
|
StringBuilder stringBuilder = new StringBuilder("");
|
errors.forEach(e -> {
|
if (e != null && !e.isEmpty()) {
|
stringBuilder.append(e).append("\n");
|
}
|
}
|
);
|
return stringBuilder.toString();
|
}
|
|
private void processDataItem(Map<String, Object> dataItem, int index) {
|
|
for (Map.Entry<String, Object> dataItemEntry : dataItem.entrySet()) {
|
|
String columnName = dataItemEntry.getKey();
|
Object columnValue = dataItemEntry.getValue();
|
|
ColumnDefinition columnDefinition = columnNameToColumnDefinition.get(columnName.trim().toLowerCase());
|
if (columnDefinition == null) {
|
errors.add("La colonne " + columnName + " n'existe pas pour ce fichier. " + lineNumberString(index));
|
return;
|
}
|
|
String error = columnValueError(columnValue, columnDefinition);
|
if (error != null && !error.isEmpty()) {
|
errors.add(error + " " + lineNumberString(index));
|
}
|
|
}
|
|
if (!withOptionalColumn) {
|
addErrorForNotFoundColumn(dataItem, index);
|
}
|
}
|
|
private void addErrorForNotFoundColumn(Map<String, Object> dataItem, int index) {
|
columnDefinitions.forEach(columnDefinition -> {
|
String columnDefinitionName = columnDefinition.getName().toLowerCase();
|
if (!columnNameExist(dataItem, columnDefinitionName)) {
|
errors.add("La colonne " + columnDefinitionName + " est manquante dans la requête. " + lineNumberString(index));
|
}
|
});
|
}
|
|
private String columnValueError(Object columnValue, ColumnDefinition columnDefinition) {
|
String columnType = columnDefinition.getTypeDonnee();
|
|
if (columnType.equals(TypeDonnee.ALPHANUMERIQUE.toString())) {
|
|
if (!isAlphaNumericColumn(columnValue)) {
|
return "La colonne " + columnDefinition.getName() + " doit être alpha numérique";
|
} else if (!lengthLowerOrEquals((String) columnValue, columnDefinition.getTaille())) {
|
return "La taille de la colonne " + columnDefinition.getName() + " doit être inférieure ou égale à" + columnDefinition.getTaille();
|
}
|
|
} else if (columnType.equals(TypeDonnee.DECIMAL.toString())) {
|
|
if (columnValue != null) {
|
|
String stringValue = columnValue.toString();
|
if (!GenericValidator.isDouble(stringValue)) {
|
return "La colonne " + columnDefinition.getName() + " doit être décimale";
|
} else if (!lengthLowerOrEquals(stringValue, columnDefinition.getTaille())) {
|
return "La taille de la colonne " + columnDefinition.getName() + " doit être inférieure ou égale à " + columnDefinition.getTaille();
|
}
|
|
}
|
|
} else if (columnType.equals(TypeDonnee.NUMERIQUE.toString())) {
|
|
if (columnValue != null) {
|
|
String stringValue = columnValue.toString();
|
if (!GenericValidator.isLong(stringValue)) {
|
return "La colonne " + columnDefinition.getName() + " doit être numérique";
|
} else if (!lengthLowerOrEquals(stringValue, columnDefinition.getTaille())) {
|
return "La taille de la colonne " + columnDefinition.getName() + " doit être inférieure ou égale à " + columnDefinition.getTaille();
|
}
|
|
}
|
|
} else if (columnType.equals(TypeDonnee.DATE.toString())) {
|
|
if (columnValue != null) {
|
|
String stringValue = columnValue.toString();
|
if (!GenericValidator.isDate(stringValue, columnDefinition.getFormatDate(), true)) {
|
return "La colonne " + columnDefinition.getName() + " doit être une date";
|
} else if (!lengthEquals(stringValue, columnDefinition.getTaille())) {
|
return "La taille de la colonne " + columnDefinition.getName() + " doit être égale à " + columnDefinition.getTaille();
|
}
|
|
try {
|
new InsertionLocalDateTimeValue(columnDefinition.getFormatDate(), columnValue).value();
|
} catch (LocalDateTimeValueParseError ex) {
|
return "Impossible de parser la valeur " + stringValue + " au format " + columnDefinition.getFormatDate() + " pour la colonne " + columnDefinition.getName();
|
}
|
|
}
|
|
}
|
|
return null;
|
}
|
|
private boolean isAlphaNumericColumn(Object columnValue) {
|
return (columnValue == null || columnValue instanceof String);
|
}
|
|
private boolean lengthEquals(String value, int columnMaxLength) {
|
return value.trim().length() == columnMaxLength;
|
}
|
|
private boolean lengthLowerOrEquals(String value, int columnMaxLength) {
|
return value.trim().length() <= columnMaxLength;
|
}
|
|
private String lineNumberString(int index) {
|
return "Ligne " + index;
|
}
|
|
private boolean columnNameExist(Map<String, Object> dataItem, String columnDefinitionName) {
|
return dataItem.entrySet().stream().map(e -> e.getKey()).filter(key -> key.trim().toLowerCase().equals(columnDefinitionName)).findAny().isPresent();
|
}
|
|
}
|