Tony CHEMIT pushed to branch develop-7.x at ultreiaio / ird-observe

Commits:

3 changed files:

Changes:

  • dto/src/main/java/fr/ird/observe/validation/validators/AbstractSpeciesFieldDtoValidator.java
    ... ... @@ -27,7 +27,6 @@ import com.opensymphony.xwork2.validator.validators.FieldValidatorSupport;
    27 27
     import fr.ird.observe.dto.referential.SpeciesDto;
    
    28 28
     import fr.ird.observe.dto.referential.SpeciesReference;
    
    29 29
     import io.ultreia.java4all.lang.Numbers;
    
    30
    -import org.apache.commons.lang3.StringUtils;
    
    31 30
     import org.apache.logging.log4j.LogManager;
    
    32 31
     import org.apache.logging.log4j.Logger;
    
    33 32
     
    
    ... ... @@ -61,87 +60,57 @@ import java.util.Objects;
    61 60
      */
    
    62 61
     public abstract class AbstractSpeciesFieldDtoValidator extends FieldValidatorSupport {
    
    63 62
     
    
    64
    -    /** Logger. */
    
    65 63
         private static final Logger log = LogManager.getLogger(AbstractSpeciesFieldDtoValidator.class);
    
    66 64
         /**
    
    67
    -     * Une expression qui si elle est remplie doit être vérifié avant de faire
    
    68
    -     * la validation par borne, si l'expression n'est pas vérifiée, alors
    
    69
    -     * le test sur les borne n'est pas effectué.
    
    65
    +     * Optional expression to enable of not this validator.
    
    66
    +     * <p>
    
    67
    +     * If set to not {@code null}, then will be enable only if evaluation of thi expression is true.
    
    68
    +     * Otherwise will always try to validate.
    
    70 69
          *
    
    70
    +     * @see #shouldValidateFromExpression(Object)
    
    71 71
          * @since 2.3
    
    72 72
          */
    
    73 73
         protected String expression;
    
    74
    +    /**
    
    75
    +     * If set to not {@code null}, then will be enable only if {@link #validationLengthWeightEnable} is set the exact same value.
    
    76
    +     * Otherwise will always try to validate.
    
    77
    +     *
    
    78
    +     * @see #validationLengthWeightEnable
    
    79
    +     * @see #shouldValidateFromEnable(Object)
    
    80
    +     */
    
    74 81
         private Boolean enable;
    
    75
    -    /** le ratio a appliquer sur les bornes définies dans le référentiel */
    
    82
    +
    
    83
    +    /**
    
    84
    +     * Loaded from validation context.
    
    85
    +     * Permits to enable or not this validator.
    
    86
    +     *
    
    87
    +     * @see #enable
    
    88
    +     * @see #shouldValidateFromEnable(Object)
    
    89
    +     */
    
    90
    +    private transient Boolean validationLengthWeightEnable;
    
    91
    +
    
    92
    +    /**
    
    93
    +     * Ration to apply to range of species value.
    
    94
    +     */
    
    76 95
         private Float ratio;
    
    96
    +    /**
    
    97
    +     * Field name where to find species value.
    
    98
    +     */
    
    77 99
         private String speciesField = "species";
    
    100
    +    /**
    
    101
    +     * Bound found from species
    
    102
    +     *
    
    103
    +     * @see SpeciesDto
    
    104
    +     */
    
    78 105
         private Bound bound;
    
    79
    -    private Bound boundWithRatio;
    
    80
    -
    
    81
    -    private String getSpeciesField() {
    
    82
    -        return speciesField;
    
    83
    -    }
    
    84
    -
    
    85
    -    public void setSpeciesField(String speciesField) {
    
    86
    -        this.speciesField = speciesField;
    
    87
    -    }
    
    88
    -
    
    89
    -    public void setRatio(String ratio) {
    
    90
    -        this.ratio = Float.parseFloat(Objects.requireNonNull(ratio));
    
    91
    -    }
    
    92
    -
    
    93
    -    public void setExpression(String expression) {
    
    94
    -        this.expression = expression;
    
    95
    -    }
    
    96
    -
    
    97
    -    public boolean isEnable() {
    
    98
    -        return enable;
    
    99
    -    }
    
    100
    -
    
    101
    -    public void setEnable(String enable) {
    
    102
    -        this.enable = Boolean.parseBoolean(Objects.requireNonNull(enable));
    
    103
    -    }
    
    104
    -
    
    105
    -    protected abstract Float getBoundMin(SpeciesDto referentiel);
    
    106
    -
    
    107
    -    protected abstract Float getBoundMax(SpeciesDto referentiel);
    
    108
    -
    
    109
    -    public Bound getBound() {
    
    110
    -        return bound;
    
    111
    -    }
    
    112
    -
    
    113
    -    private boolean shouldValidate(Object object) throws ValidationException {
    
    114
    -
    
    115
    -        Boolean enable = (Boolean) getFieldValue("validationLengthWeightEnable", object);
    
    116
    -        if (enable != null && this.enable != null) {
    
    117
    -
    
    118
    -            if (!Objects.equals(this.enable, enable)) {
    
    119
    -
    
    120
    -                if (log.isDebugEnabled()) {
    
    121
    -                    log.debug("Skip speed validation");
    
    122
    -                }
    
    123
    -                return false;
    
    124
    -            }
    
    106
    +    /**
    
    107
    +     * Computed bound with {@link #ratio} applied to {@link #bound}.
    
    108
    +     */
    
    109
    +    private Bound computedBound;
    
    125 110
     
    
    126
    -        }
    
    111
    +    protected abstract Float getBoundMin(SpeciesDto species);
    
    127 112
     
    
    128
    -        Boolean answer = true;
    
    129
    -        if (StringUtils.isNotEmpty(expression)) {
    
    130
    -            try {
    
    131
    -                answer = (Boolean) getFieldValue(expression, object);
    
    132
    -            } catch (ValidationException e) {
    
    133
    -                throw e;
    
    134
    -            } catch (Exception e) {
    
    135
    -                // let this pass, but it will be logged right below
    
    136
    -                if (log.isErrorEnabled()) {
    
    137
    -                    log.error("Could not get expression: " + expression);
    
    138
    -                }
    
    139
    -                answer = true;
    
    140
    -            }
    
    141
    -        }
    
    142
    -
    
    143
    -        return answer;
    
    144
    -    }
    
    113
    +    protected abstract Float getBoundMax(SpeciesDto species);
    
    145 114
     
    
    146 115
         @Override
    
    147 116
         public void validate(Object object) throws ValidationException {
    
    ... ... @@ -155,9 +124,8 @@ public abstract class AbstractSpeciesFieldDtoValidator extends FieldValidatorSup
    155 124
                 throw new ValidationException("No parameter 'fieldName' filled");
    
    156 125
             }
    
    157 126
     
    
    158
    -        String speciesFieldName = getSpeciesField();
    
    159
    -        if (speciesFieldName == null) {
    
    160
    -            throw new ValidationException("No parameter 'speciesFieldName' filled");
    
    127
    +        if (speciesField == null) {
    
    128
    +            throw new ValidationException("No parameter 'speciesField' filled");
    
    161 129
             }
    
    162 130
     
    
    163 131
             boolean shouldValidate = shouldValidate(object);
    
    ... ... @@ -166,54 +134,46 @@ public abstract class AbstractSpeciesFieldDtoValidator extends FieldValidatorSup
    166 134
                 return;
    
    167 135
             }
    
    168 136
     
    
    169
    -        // la donnee a valider
    
    137
    +        // data to validate
    
    170 138
             Object value = getFieldValue(fieldName, object);
    
    171 139
             Float data = value == null ? null : Float.valueOf(String.valueOf(value));
    
    172 140
     
    
    173 141
             if (data == null) {
    
    174
    -            // la donnee a valider n'est pas définie
    
    142
    +            // no data found, can not validate
    
    143
    +            log.debug("No data found, skip validate.");
    
    175 144
                 return;
    
    176 145
             }
    
    177 146
     
    
    178
    -        if (log.isDebugEnabled()) {
    
    179
    -            log.debug("data to validate : " + data);
    
    180
    -        }
    
    147
    +        log.debug(String.format("data to validate : %s", data));
    
    181 148
     
    
    182
    -        SpeciesReference speciesRef = (SpeciesReference) getFieldValue(speciesFieldName, object);
    
    149
    +        SpeciesReference speciesRef = (SpeciesReference) getFieldValue(speciesField, object);
    
    183 150
     
    
    184 151
             if (speciesRef == null) {
    
    185 152
     
    
    186
    -            // pas de species trouvée, on ne peut pas valider
    
    153
    +            // no species found, can not validate
    
    154
    +            log.debug("No species found, skip validate.");
    
    187 155
                 return;
    
    188 156
             }
    
    189 157
     
    
    190
    -        if (log.isDebugEnabled()) {
    
    191
    -            log.debug("Species to validate : " + speciesRef);
    
    192
    -        }
    
    158
    +        log.debug(String.format("Species to validate : %s", speciesRef));
    
    193 159
     
    
    194 160
             SpeciesDto speciesDto = (SpeciesDto) stack.findValue("getSpecies(\"" + speciesRef.getId() + "\")");
    
    195 161
     
    
    196 162
             bound = getBound(speciesDto);
    
    197 163
     
    
    198
    -        if (log.isDebugEnabled()) {
    
    199
    -            log.debug("Species Bound to validate : " + bound);
    
    200
    -        }
    
    164
    +        log.debug(String.format("Species Bound to validate : %s", bound));
    
    201 165
     
    
    202 166
             if (bound == null) {
    
    203 167
     
    
    204
    -            // pas de donnée dans le référentiel acceptable
    
    168
    +            // no bound found, can not validate
    
    169
    +            log.debug("No species bound found, skip validate.");
    
    205 170
                 return;
    
    206 171
             }
    
    207 172
     
    
    208
    -        boundWithRatio = bound.applyRatio(ratio);
    
    173
    +        computedBound = bound.applyRatio(ratio);
    
    174
    +        log.debug(String.format("Bound with ratio  : %s", computedBound));
    
    209 175
     
    
    210
    -        if (log.isDebugEnabled()) {
    
    211
    -            log.debug("Bound             : " + bound);
    
    212
    -            log.debug("Ratio to validate : " + ratio);
    
    213
    -            log.debug("Bound with ratio  : " + boundWithRatio);
    
    214
    -        }
    
    215
    -
    
    216
    -        boolean valid = validateBound(data, boundWithRatio);
    
    176
    +        boolean valid = computedBound.validate(data);
    
    217 177
     
    
    218 178
             if (!valid) {
    
    219 179
     
    
    ... ... @@ -221,61 +181,117 @@ public abstract class AbstractSpeciesFieldDtoValidator extends FieldValidatorSup
    221 181
             }
    
    222 182
         }
    
    223 183
     
    
    224
    -    private Bound getBound(SpeciesDto species) {
    
    184
    +    public void setSpeciesField(String speciesField) {
    
    185
    +        this.speciesField = speciesField;
    
    186
    +    }
    
    225 187
     
    
    226
    -        Float min = getBoundMin(species);
    
    227
    -        Float max = getBoundMax(species);
    
    188
    +    public void setRatio(String ratio) {
    
    189
    +        this.ratio = Float.parseFloat(Objects.requireNonNull(ratio));
    
    190
    +    }
    
    228 191
     
    
    229
    -        if (min == null || min == 0 || max == null || max == 0) {
    
    230
    -            // l'une des deux borne n'est pas définie, on ne peut pas utiliser
    
    231
    -            // la données
    
    232
    -            return null;
    
    233
    -        }
    
    234
    -        return new Bound(min, max);
    
    192
    +    public void setExpression(String expression) {
    
    193
    +        this.expression = expression;
    
    194
    +    }
    
    195
    +
    
    196
    +    public void setEnable(String enable) {
    
    197
    +        this.enable = Boolean.parseBoolean(Objects.requireNonNull(enable));
    
    235 198
         }
    
    236 199
     
    
    237
    -    private boolean validateBound(Float value, Bound bound) {
    
    238
    -        if (value == null) {
    
    200
    +    public Float getMin() {
    
    201
    +        return computedBound == null ? null : Numbers.roundThreeDigits(computedBound.getMin());
    
    202
    +    }
    
    239 203
     
    
    240
    -            // valeur non définie
    
    241
    -            return true;
    
    204
    +    public Float getMax() {
    
    205
    +        return computedBound == null ? null : Numbers.roundThreeDigits(computedBound.getMax());
    
    206
    +    }
    
    207
    +
    
    208
    +    private Boolean getValidationLengthWeightEnable(Object object) throws ValidationException {
    
    209
    +        if (validationLengthWeightEnable == null) {
    
    210
    +            validationLengthWeightEnable = (Boolean) getFieldValue("validationLengthWeightEnable", object);
    
    242 211
             }
    
    243
    -        boolean valid;
    
    212
    +        return validationLengthWeightEnable;
    
    213
    +    }
    
    214
    +
    
    215
    +    private boolean shouldValidate(Object object) throws ValidationException {
    
    216
    +        boolean shouldValidate = shouldValidateFromEnable(object);
    
    217
    +        if (!shouldValidate) {
    
    218
    +            log.debug("Skip speed validation from 'validationLengthWeightEnable'");
    
    219
    +        } else {
    
    220
    +            shouldValidate = shouldValidateFromExpression(object);
    
    244 221
     
    
    245
    -        float min = bound.getMin();
    
    246
    -        float max = bound.getMax();
    
    222
    +            if (!shouldValidate) {
    
    223
    +                log.debug("Skip speed validation from 'expression'");
    
    224
    +            }
    
    225
    +        }
    
    226
    +        return shouldValidate;
    
    227
    +    }
    
    247 228
     
    
    248
    -        valid = min <= value && value <= max;
    
    249
    -        return valid;
    
    229
    +    private boolean shouldValidateFromEnable(Object object) throws ValidationException {
    
    230
    +        boolean answer = true;
    
    231
    +        if (this.enable != null) {
    
    232
    +            Boolean enable;
    
    233
    +            try {
    
    234
    +                enable = getValidationLengthWeightEnable(object);
    
    235
    +            } catch (ValidationException e) {
    
    236
    +                // let this pass, but it will be logged right below
    
    237
    +                log.error("Could not get expression: validationLengthWeightEnable", e);
    
    238
    +                throw e;
    
    239
    +            }
    
    240
    +            answer = Objects.equals(this.enable, enable);
    
    241
    +        }
    
    242
    +        return answer;
    
    250 243
         }
    
    251 244
     
    
    252
    -    public Float getMin() {
    
    253
    -        return boundWithRatio == null ? null : Numbers.roundThreeDigits(boundWithRatio.getMin());
    
    245
    +    private boolean shouldValidateFromExpression(Object object) throws ValidationException {
    
    246
    +        boolean answer = true;
    
    247
    +        if (this.expression != null && !this.expression.isEmpty()) {
    
    248
    +            try {
    
    249
    +                Boolean answerObject = (Boolean) getFieldValue(expression, object);
    
    250
    +                answer = answerObject != null && answerObject;
    
    251
    +            } catch (ValidationException e) {
    
    252
    +                // let this pass, but it will be logged right below
    
    253
    +                log.error(String.format("Could not get expression: %s", expression), e);
    
    254
    +                throw e;
    
    255
    +            }
    
    256
    +        }
    
    257
    +        return answer;
    
    254 258
         }
    
    255 259
     
    
    256
    -    public Float getMax() {
    
    257
    -        return boundWithRatio == null ? null : Numbers.roundThreeDigits(boundWithRatio.getMax());
    
    260
    +    private Bound getBound(SpeciesDto species) {
    
    261
    +
    
    262
    +        Float min = getBoundMin(species);
    
    263
    +        Float max = getBoundMax(species);
    
    264
    +
    
    265
    +        if (min == null || min == 0 || max == null || max == 0) {
    
    266
    +            // one of range is missing, can not use this bound
    
    267
    +            return null;
    
    268
    +        }
    
    269
    +        return new Bound(min, max);
    
    258 270
         }
    
    259 271
     
    
    260 272
         public static class Bound {
    
    261 273
     
    
    262
    -        private final Float min;
    
    274
    +        private final float min;
    
    263 275
     
    
    264
    -        private final Float max;
    
    276
    +        private final float max;
    
    265 277
     
    
    266
    -        Bound(Float min, Float max) {
    
    278
    +        Bound(float min, float max) {
    
    267 279
                 this.min = min;
    
    268 280
                 this.max = max;
    
    269 281
             }
    
    270 282
     
    
    271
    -        public Float getMin() {
    
    283
    +        public float getMin() {
    
    272 284
                 return min;
    
    273 285
             }
    
    274 286
     
    
    275
    -        public Float getMax() {
    
    287
    +        public float getMax() {
    
    276 288
                 return max;
    
    277 289
             }
    
    278 290
     
    
    291
    +        boolean validate(float value) {
    
    292
    +            return min <= value && value <= max;
    
    293
    +        }
    
    294
    +
    
    279 295
             Bound applyRatio(float ratio) {
    
    280 296
                 float delta = min / 100 * ratio;
    
    281 297
                 float min = this.min - delta;
    

  • dto/src/main/java/fr/ird/observe/validation/validators/SpeciesLengthFieldDtoValidator.java
    ... ... @@ -33,13 +33,13 @@ import fr.ird.observe.dto.referential.SpeciesDto;
    33 33
     public class SpeciesLengthFieldDtoValidator extends AbstractSpeciesFieldDtoValidator {
    
    34 34
     
    
    35 35
         @Override
    
    36
    -    protected Float getBoundMin(SpeciesDto referentiel) {
    
    37
    -        return referentiel.getMinLength();
    
    36
    +    protected Float getBoundMin(SpeciesDto species) {
    
    37
    +        return species.getMinLength();
    
    38 38
         }
    
    39 39
     
    
    40 40
         @Override
    
    41
    -    protected Float getBoundMax(SpeciesDto referentiel) {
    
    42
    -        return referentiel.getMaxLength();
    
    41
    +    protected Float getBoundMax(SpeciesDto species) {
    
    42
    +        return species.getMaxLength();
    
    43 43
         }
    
    44 44
     
    
    45 45
         @Override
    

  • dto/src/main/java/fr/ird/observe/validation/validators/SpeciesWeightFieldDtoValidator.java
    ... ... @@ -33,13 +33,13 @@ import fr.ird.observe.dto.referential.SpeciesDto;
    33 33
     public class SpeciesWeightFieldDtoValidator extends AbstractSpeciesFieldDtoValidator {
    
    34 34
     
    
    35 35
         @Override
    
    36
    -    protected Float getBoundMin(SpeciesDto referentiel) {
    
    37
    -        return referentiel.getMinWeight();
    
    36
    +    protected Float getBoundMin(SpeciesDto species) {
    
    37
    +        return species.getMinWeight();
    
    38 38
         }
    
    39 39
     
    
    40 40
         @Override
    
    41
    -    protected Float getBoundMax(SpeciesDto referentiel) {
    
    42
    -        return referentiel.getMaxWeight();
    
    41
    +    protected Float getBoundMax(SpeciesDto species) {
    
    42
    +        return species.getMaxWeight();
    
    43 43
         }
    
    44 44
     
    
    45 45
         @Override