View Javadoc
1   package fr.ifremer.tutti.persistence.service.batch;
2   
3   /*
4    * #%L
5    * Tutti :: Persistence
6    * %%
7    * Copyright (C) 2012 - 2014 Ifremer
8    * %%
9    * This program is free software: you can redistribute it and/or modify
10   * it under the terms of the GNU General Public License as
11   * published by the Free Software Foundation, either version 3 of the 
12   * License, or (at your option) any later version.
13   * 
14   * This program is distributed in the hope that it will be useful,
15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   * GNU General Public License for more details.
18   * 
19   * You should have received a copy of the GNU General Public 
20   * License along with this program.  If not, see
21   * <http://www.gnu.org/licenses/gpl-3.0.html>.
22   * #L%
23   */
24  
25  import com.google.common.collect.Lists;
26  import fr.ifremer.adagio.core.dao.data.batch.CatchBatch;
27  import fr.ifremer.adagio.core.dao.data.batch.SortingBatch;
28  import fr.ifremer.adagio.core.dao.data.batch.validator.CatchBatchValidationError;
29  import fr.ifremer.tutti.persistence.entities.data.BatchContainer;
30  import fr.ifremer.tutti.persistence.entities.data.SampleCategoryModel;
31  import fr.ifremer.tutti.persistence.entities.data.SampleCategoryModelEntry;
32  import fr.ifremer.tutti.persistence.entities.data.SpeciesBatch;
33  import fr.ifremer.tutti.persistence.service.util.tree.BatchTreeHelper;
34  import org.apache.commons.logging.Log;
35  import org.apache.commons.logging.LogFactory;
36  import org.springframework.stereotype.Component;
37  
38  import javax.annotation.Resource;
39  import java.util.List;
40  import java.util.Map;
41  
42  import static org.nuiton.i18n.I18n.n;
43  import static org.nuiton.i18n.I18n.t;
44  
45  @Component(value = "scientificCruiseCatchBatchValidator")
46  public class ScientificCruiseCatchBatchValidator implements TuttiCatchBatchValidator {
47  
48      /** Logger. */
49      private static final Log log =
50              LogFactory.getLog(ScientificCruiseCatchBatchValidator.class);
51  
52      @Resource(name = "batchTreeHelper")
53      protected BatchTreeHelper batchTreeHelper;
54  
55      // -----------------------------------------------------------------------//
56      // -- CatchBatchValidator methods                                       --//
57      // -----------------------------------------------------------------------//
58  
59      @Override
60      public boolean isEnable(CatchBatch catchBatch) {
61          // Apply validation only on catch batch for fishingOperation
62          return (catchBatch.getFishingOperation() != null);
63      }
64  
65      @Override
66      public List<CatchBatchValidationError> validate(CatchBatch catchBatch) {
67          List<CatchBatchValidationError> errors = Lists.newArrayList();
68          validateCatchBatch(catchBatch, errors);
69          return errors;
70      }
71  
72      // -----------------------------------------------------------------------//
73      // -- TuttiCatchBatchValidator methods                                  --//
74      // -----------------------------------------------------------------------//
75  
76      @Override
77      public List<CatchBatchValidationError> validateSpecies(SampleCategoryModel sampleCategoryModel,
78                                                             BatchContainer<SpeciesBatch> species) {
79  
80          List<CatchBatchValidationError> errors = Lists.newArrayList();
81  
82          Map<Integer, SampleCategoryModelEntry> categoriesById =
83                  sampleCategoryModel.getCategoryMap();
84  
85          for (SpeciesBatch speciesBatch : species.getChildren()) {
86  
87              // check all sample categories are accepted
88              validateSampleCategoriesUniverse(
89                      sampleCategoryModel,
90                      errors,
91                      speciesBatch,
92                      n("tutti.persistence.batch.validation.invalid.species.sampleCategoryId"));
93  
94  
95              if (errors.isEmpty()) {
96  
97                  // check sample categories order is ok
98  
99                  validateSampleCategoriesOrder(
100                         categoriesById,
101                         errors,
102                         speciesBatch,
103                         null,
104                         n("tutti.persistence.batch.validation.invalid.species.sampleCategoryId.order"));
105             }
106         }
107         return errors;
108     }
109 
110     @Override
111     public List<CatchBatchValidationError> validateBenthos(SampleCategoryModel sampleCategoryModel,
112                                                            BatchContainer<SpeciesBatch> benthos) {
113 
114         List<CatchBatchValidationError> errors = Lists.newArrayList();
115 
116         Map<Integer, SampleCategoryModelEntry> categoriesById =
117                 sampleCategoryModel.getCategoryMap();
118 
119         for (SpeciesBatch benthosBatch : benthos.getChildren()) {
120 
121             // check all sample categories are accepted
122             validateSampleCategoriesUniverse(
123                     sampleCategoryModel,
124                     errors,
125                     benthosBatch,
126                     n("tutti.persistence.batch.validation.invalid.benthos.sampleCategoryId"));
127 
128             if (errors.isEmpty()) {
129 
130                 // check sample categories order is ok
131 
132                 validateSampleCategoriesOrder(
133                         categoriesById,
134                         errors,
135                         benthosBatch,
136                         null,
137                         n("tutti.persistence.batch.validation.invalid.benthos.sampleCategoryId.order"));
138             }
139         }
140         return errors;
141     }
142 
143     // -----------------------------------------------------------------------//
144     // -- Internal methods                                                  --//
145     // -----------------------------------------------------------------------//
146 
147     protected void validateCatchBatch(CatchBatch batch,
148                                       List<CatchBatchValidationError> errors) {
149 
150         // -- Vrac
151         SortingBatch vracBatch = batchTreeHelper.getVracBatch(batch);
152 
153         if (log.isDebugEnabled()) {
154             log.debug("Try to validate Vrac batch model " + vracBatch);
155         }
156 
157         if (vracBatch == null) {
158             addError(errors, n("tutti.persistence.batch.validation.vracNotFound"));
159         } else {
160             // -- Vrac > Species
161             SortingBatch speciesBatch = batchTreeHelper.getSpeciesVracRootBatch(vracBatch);
162 
163             // -- Vrac > Benthos
164             SortingBatch benthosBatch = batchTreeHelper.getBenthosVracRootBatch(vracBatch);
165 
166             if (speciesBatch == null) {
167 
168                 if (benthosBatch == null) {
169                     addError(errors, n("tutti.persistence.batch.validation.vracSpeciesNotFound"));
170                 } else {
171                     addWarning(errors, n("tutti.persistence.batch.validation.vracSpeciesNotFound"));
172                 }
173             } else {
174                 // -- Vrac > Species > Alive not itemized
175                 SortingBatch livingNotItemizedBatch = batchTreeHelper.getSpeciesVracAliveNotItemizedRootBatch(speciesBatch);
176                 if (livingNotItemizedBatch == null) {
177                     addWarning(errors, n("tutti.persistence.batch.validation.vracSpeciesLifeNotFound"));
178                 }
179 
180                 // -- Vrac > Species > Inert
181                 SortingBatch inertBatch = batchTreeHelper.getSpeciesVracInertRootBatch(speciesBatch);
182                 if (inertBatch == null) {
183                     addWarning(errors, n("tutti.persistence.batch.validation.vracSpeciesInertNotFound"));
184                 }
185 
186                 // -- Vrac > Species > Alive itemized
187                 SortingBatch aliveItemizedBatch = batchTreeHelper.getSpeciesVracAliveItemizedRootBatch(speciesBatch);
188                 if (aliveItemizedBatch == null) {
189                     addWarning(errors, n("tutti.persistence.batch.validation.vracSpeciesAliveItemizedNotFound"));
190                 }
191 
192                 // TODO verifier que les espèces en haut de grappe ont bien la catégorie voulue (sorted-unsorted)
193             }
194 
195             if (benthosBatch == null) {
196                 if (speciesBatch == null) {
197                     addError(errors, n("tutti.persistence.batch.validation.vracBenthosNotFound"));
198                 } else {
199                     addWarning(errors, n("tutti.persistence.batch.validation.vracBenthosNotFound"));
200                 }
201             } else {
202 
203                 // -- Vrac > Benthos > Alive not itemized
204                 SortingBatch livingNotItemizedBatch = batchTreeHelper.getBenthosVracAliveNotItemizedRootBatch(benthosBatch);
205                 if (livingNotItemizedBatch == null) {
206                     addWarning(errors, n("tutti.persistence.batch.validation.vracBenthosLifeNotFound"));
207                 }
208 
209                 // -- Vrac > Benthos > Inert
210                 SortingBatch inertBatch = batchTreeHelper.getBenthosVracInertRootBatch(benthosBatch);
211                 if (inertBatch == null) {
212                     addWarning(errors, n("tutti.persistence.batch.validation.vracBenthosInertNotFound"));
213                 }
214 
215                 // -- Vrac > Benthos > Alive itemized
216                 SortingBatch aliveItemizedBatch = batchTreeHelper.getBenthosVracAliveItemizedRootBatch(benthosBatch);
217                 if (aliveItemizedBatch == null) {
218                     addWarning(errors, n("tutti.persistence.batch.validation.vracBenthosAliveItemizedNotFound"));
219                 }
220             }
221         }
222 
223         // -- Hors Vrac
224         SortingBatch horsVracBatch = batchTreeHelper.getHorsVracBatch(batch);
225         if (horsVracBatch == null) {
226             addWarning(errors, n("tutti.persistence.batch.validation.horsVracNotFound"));
227         } else {
228             // -- Hors Vrac > Species
229             SortingBatch speciesBatch = batchTreeHelper.getSpeciesHorsVracRootBatch(horsVracBatch);
230             if (speciesBatch == null) {
231                 addWarning(errors, n("tutti.persistence.batch.validation.horsVracSpeciesNotFound"));
232             }
233 
234             // -- Hors Vrac > Benthos
235             SortingBatch benthosBatch = batchTreeHelper.getBenthosHorsVracRootBatch(horsVracBatch);
236             if (benthosBatch == null) {
237                 addWarning(errors, n("tutti.persistence.batch.validation.horsVracBenthosNotFound"));
238             }
239             // -- Hors Vrac > Marine Litter
240             SortingBatch marineLitterBatch = batchTreeHelper.getMarineLitterRootBatch(horsVracBatch);
241 
242             if (marineLitterBatch == null) {
243                 addWarning(errors, n("tutti.persistence.batch.validation.horsVracMarineLitterNotFound"));
244             }
245         }
246 
247         // -- Unsorted
248         SortingBatch unsortedBatch = batchTreeHelper.getRejectedBatch(batch);
249         if (unsortedBatch == null) {
250             addWarning(errors, n("tutti.persistence.batch.validation.unsortedNotFound"));
251         }
252     }
253 
254     protected void validateSampleCategoriesUniverse(SampleCategoryModel sampleCategoryModel,
255                                                     List<CatchBatchValidationError> errors,
256                                                     SpeciesBatch aBatch,
257                                                     String messageKey) {
258 
259         Integer sampleCategoryId = aBatch.getSampleCategoryId();
260 
261         if (!sampleCategoryModel.containsCategoryId(sampleCategoryId)) {
262 
263             // invalid sample category id
264 
265             addError(errors,
266                      messageKey,
267                      aBatch.getId(),
268                      aBatch.getSpecies().getName(),
269                      sampleCategoryId);
270         }
271 
272         if (!aBatch.isChildBatchsEmpty()) {
273 
274             for (SpeciesBatch speciesAbleBatch : aBatch.getChildBatchs()) {
275 
276                 validateSampleCategoriesUniverse(sampleCategoryModel,
277                                                  errors,
278                                                  speciesAbleBatch,
279                                                  messageKey);
280             }
281         }
282     }
283 
284     protected void validateSampleCategoriesOrder(Map<Integer, SampleCategoryModelEntry> categoriesById,
285                                                  List<CatchBatchValidationError> errors,
286                                                  SpeciesBatch aBatch,
287                                                  SampleCategoryModelEntry lastSampleCategory,
288                                                  String messageKey) {
289 
290         Integer sampleCategoryId = aBatch.getSampleCategoryId();
291 
292         SampleCategoryModelEntry actualCategory =
293                 categoriesById.get(sampleCategoryId);
294 
295         if (lastSampleCategory != null) {
296 
297             // check the category is after the last one
298 
299             if (actualCategory.getOrder() < lastSampleCategory.getOrder()) {
300 
301                 // bad order
302 
303                 addError(errors,
304                          messageKey,
305                          aBatch.getId(),
306                          aBatch.getSpecies().getName(),
307                          actualCategory.getLabel(),
308                          lastSampleCategory.getLabel());
309 
310                 // no need to continue, we got a bad order
311                 return;
312             }
313 
314         }
315 
316         // keep the last sample category
317         lastSampleCategory = actualCategory;
318 
319         if (!aBatch.isChildBatchsEmpty()) {
320 
321             for (SpeciesBatch speciesAbleBatch : aBatch.getChildBatchs()) {
322 
323                 validateSampleCategoriesOrder(
324                         categoriesById,
325                         errors,
326                         speciesAbleBatch,
327                         lastSampleCategory,
328                         messageKey);
329             }
330         }
331     }
332 
333     protected void addError(List<CatchBatchValidationError> errors,
334                             String messageKey) {
335         CatchBatchValidationError error = new CatchBatchValidationError(
336                 messageKey,
337                 t(messageKey),
338                 CatchBatchValidationError.GRAVITY_ERROR);
339         errors.add(error);
340     }
341 
342     protected void addError(List<CatchBatchValidationError> errors,
343                             String messageKey, Object... params) {
344         CatchBatchValidationError error = new CatchBatchValidationError(
345                 messageKey,
346                 t(messageKey, params),
347                 CatchBatchValidationError.GRAVITY_ERROR);
348         errors.add(error);
349     }
350 
351     protected void addWarning(List<CatchBatchValidationError> errors,
352                               String messageKey) {
353         CatchBatchValidationError error = new CatchBatchValidationError(
354                 messageKey,
355                 t(messageKey),
356                 CatchBatchValidationError.GRAVITY_WARNING);
357         errors.add(error);
358     }
359 
360 }