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 errors = new ArrayList<>(); private final Map columnNameToColumnDefinition; private final List columnDefinitions; private final List> data; private final boolean withOptionalColumn; public TableDataValidationError(List> data, List columnDefinitions) { this(data, columnDefinitions, false); } public TableDataValidationError(List> data, List 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 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 dataItem, int index) { for (Map.Entry 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 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 dataItem, String columnDefinitionName) { return dataItem.entrySet().stream().map(e -> e.getKey()).filter(key -> key.trim().toLowerCase().equals(columnDefinitionName)).findAny().isPresent(); } }