Kenmegne
7 days ago 23a46b4be35277e06ec89f48730eeb694e686be8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
package com.megatim.fdxcommons.core.impl.db.validators;
 
import static com.megatim.fdxcommons.model.enumeration.Operateur.*;
import com.megatim.fdxcommons.model.enumeration.TypeDonnee;
import com.megatim.fdxcommons.model.integration.ColumnDefinition;
import com.megatim.fdxcommons.model.pojo.BetweenOperatorValues;
import com.megatim.fdxcommons.model.pojo.CriteriaEntity;
import com.megatim.fdxcommons.tools.exceptions.CommonApplicationValidationException;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.time.format.DateTimeParseException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.enterprise.context.Dependent;
import com.megatim.fdxcommons.core.ifaces.db.validators.CriteriaQueryValidator;
 
/**
 *
 * @author lenovo
 */
@Dependent
public class CriteriaQueryValidatorImpl implements CriteriaQueryValidator {
 
    @Override
    public List<String> validate(CriteriaEntity criterion, Map<String, ColumnDefinition> columnDefinitionsMap) {
        List<String> errors = new ArrayList<>();
//        int index = 1;
//        String numeroElt = " : Elément numéro " + index;
        TypeDonnee typeDonnee = null;
 
        if (criterion != null && isNotEmptyCriteria(criterion)) {
            if (criterion.getSubCriterias().isEmpty()) {
                if (!validateCriteriaNomColonne(columnDefinitionsMap, criterion)) {
                    errors.add("Colonne '" + criterion.getNomColonne() + "' des critères de sélection est introuvable");
 
                } else if ((typeDonnee = TypeDonnee.fromValeur(columnDefinitionsMap.get(criterion.getNomColonne().toLowerCase()).getTypeDonnee())) == null) {
                    errors.add("Le type de la colonne '" + criterion.getNomColonne() + "est introuvable");
 
                } else if (!validateCriteriaEntityValue(criterion, typeDonnee)) {
                    errors.add("Type de données de la colonne " + criterion.getNomColonne() + " incorrect");
                }
            } else {
                if (criterion.getCriteriaLogicConnector() == null) {
                    errors.add("Le connecteur logique est absent");
                }
                for (CriteriaEntity c : criterion.getSubCriterias()) {
                    errors.addAll(validate(c, columnDefinitionsMap));
                }
            }
        }
        return errors;
    }
 
    private boolean validateCriteriaNomColonne(Map<String, ColumnDefinition> columnDefinitionsMap, CriteriaEntity c) {
        return c.getNomColonne() != null
                && !c.getNomColonne().isEmpty()
                && columnDefinitionsMap.containsKey(c.getNomColonne().toLowerCase());
    }
 
    private boolean validateCriteriaEntityValue(CriteriaEntity criteriaEntity, TypeDonnee typeDonnee) {
        switch (criteriaEntity.getOperateur()) {
            case LIKE:
                return (criteriaEntity.getCriteriaValue() instanceof String) && columTypeIsString(typeDonnee);
            case IN:
            case NOT_IN:
                return (criteriaEntity.getCriteriaValue() instanceof List<?>) && elementsOfList((List) criteriaEntity.getCriteriaValue(), typeDonnee);
            case LOWER_OR_EQUALS_THAN:
            case LOWER_THAN:
            case GREATER_OR_EQUALS_THAN:
            case GREATER_THAN:
            case EQUALS:
            case NOT_EQUALS:
                return (criteriaEntity.getCriteriaValue() instanceof Comparable<?>) && criteriaValueHasCorrectType(criteriaEntity.getCriteriaValue(), typeDonnee);
            case BETWEEN:
            case NOT_BETWEEN:
                BetweenOperatorValues betweenOperatorValues = getBetweenOperatorValues(criteriaEntity.getCriteriaValue());
                criteriaEntity.setCriteriaValue(betweenOperatorValues);
 
                return betweenOperatorValues != null
                        && criteriaValueHasCorrectType(betweenOperatorValues.getLowerBound(), typeDonnee)
                        && criteriaValueHasCorrectType(betweenOperatorValues.getUpperBound(), typeDonnee)
                        && betweenOperatorValuesAreCorrect(betweenOperatorValues, typeDonnee);
            case IS_NULL:
            case IS_NOT_NULL:
                return criteriaEntity.getCriteriaValue() == null;
        }
        return false;
    }
 
    @Override
    public BetweenOperatorValues getBetweenOperatorValues(Object value) {
        BetweenOperatorValues betweenOperatorValues = null;
        if (!(value instanceof LinkedHashMap)) {
            throw new CommonApplicationValidationException("LinkedHashMap est attendu");
        }
        LinkedHashMap<String, String> map = (LinkedHashMap) value;
        String lowerBound = null;
        String upperBound = null;
 
        for (String key : map.keySet()) {
            if (key.equalsIgnoreCase("lowerBound")) {
                lowerBound = map.get(key);
            }
            if (key.equalsIgnoreCase("upperBound")) {
                upperBound = map.get(key);
            }
        }
        StringBuilder message = new StringBuilder("");
 
        if (lowerBound == null) {
            message.append("Borne inférieure absente\n");
        }
        if (upperBound == null) {
            message.append("Borne supérieure absente");
        }
        if (message.length() > 0) {
            throw new CommonApplicationValidationException(message.toString());
        }
        betweenOperatorValues = new BetweenOperatorValues(lowerBound, upperBound);
 
        return betweenOperatorValues;
    }
 
    /**
     * Vérifier que le borne inférieure est bel et bien inférieure à la borne
     * supérieure
     *
     * @param betweenOperatorValues
     * @param columnType
     * @return
     */
    private boolean betweenOperatorValuesAreCorrect(BetweenOperatorValues betweenOperatorValues, TypeDonnee typeDonnee) {
        boolean result = false;
        switch (typeDonnee) {
 
            case NUMERIQUE:
                try {
                Long lowerBound = Long.valueOf(betweenOperatorValues.getLowerBound().toString());
                Long upperBound = Long.valueOf(betweenOperatorValues.getUpperBound().toString());
 
                result = lowerBound <= upperBound;
                if (!result) {
                    throw new CommonApplicationValidationException("La borne inférieure ne peut être supérieure à la borne supérieure");
                }
            } catch (NumberFormatException ex) {
            }
            break;
 
            case DECIMAL:
                try {
                BigDecimal lowerBound = new BigDecimal(betweenOperatorValues.getLowerBound().toString());
                BigDecimal upperBound = new BigDecimal(betweenOperatorValues.getUpperBound().toString());
 
                result = lowerBound.compareTo(upperBound) <= 0;
                if (!result) {
                    throw new CommonApplicationValidationException("La borne inférieure ne peut être supérieure à la borne supérieure");
                }
            } catch (NumberFormatException ex) {
            }
            break;
 
            case DATE:
                try {
                Timestamp lowerBound = Timestamp.valueOf(LocalDateTime.parse(betweenOperatorValues.getLowerBound().toString()));
                Timestamp upperBound = Timestamp.valueOf(LocalDateTime.parse(betweenOperatorValues.getUpperBound().toString()));
 
                result = lowerBound.before(upperBound);
                if (!result) {
                    throw new CommonApplicationValidationException("La borne inférieure ne peut être supérieure à la borne supérieure");
                }
            } catch (DateTimeParseException ex) {
            }
            break;
 
            default:
                throw new CommonApplicationValidationException("L'opérarateur 'BETWEEN' n'est pas valable pour ce type de données " + typeDonnee);
 
        }
        return result;
    }
 
    private boolean elementsOfList(List<?> elements, TypeDonnee typeDonnee) {
        boolean result = true;
 
        for (Object elt : elements) {
            result = criteriaValueHasCorrectType(elt, typeDonnee);
 
            if (!result) {
                break;
            }
        }
        return result;
    }
 
    private boolean criteriaValueHasCorrectType(Object value, TypeDonnee typeDonnee) {
        boolean result = false;
 
        switch (typeDonnee) {
            case NUMERIQUE:
                try {
                Long.valueOf(value.toString());
                result = true;
            } catch (NumberFormatException ex) {
            }
            break;
 
            case DECIMAL:
                 try {
                new BigDecimal(value.toString());
                result = true;
            } catch (Exception ex) {
            }
            break;
 
            case DATE:
                try {
                Timestamp.valueOf(LocalDateTime.parse(value.toString()));
                result = true;
            } catch (IllegalArgumentException ex) {
            }
            break;
 
            case ALPHANUMERIQUE:
                result = value instanceof String;
                break;
 
            default:
                throw new CommonApplicationValidationException("Type de données inconnu");
        }
        return result;
    }
 
    private boolean columTypeIsString(TypeDonnee typeDonnee) {
        return typeDonnee.equals(TypeDonnee.ALPHANUMERIQUE);
    }
 
    private boolean isNotEmptyCriteria(CriteriaEntity c) {
        return c.getNomColonne() != null && !c.getNomColonne().isEmpty() && c.getOperateur() != null
                || c.getSubCriterias() != null && !c.getSubCriterias().isEmpty();
    }
}