View Javadoc
1   package fr.ifremer.tutti.service.psionimport;
2   
3   /*
4    * #%L
5    * Tutti :: Service
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.ArrayListMultimap;
26  import com.google.common.collect.ImmutableList;
27  import com.google.common.collect.ImmutableSet;
28  import com.google.common.collect.Lists;
29  import com.google.common.collect.Multimap;
30  import com.google.common.collect.Sets;
31  import fr.ifremer.tutti.persistence.entities.data.SampleCategoryModel;
32  import fr.ifremer.tutti.persistence.entities.data.SampleCategoryModelEntry;
33  import fr.ifremer.tutti.persistence.entities.referential.Species;
34  import fr.ifremer.tutti.type.WeightUnit;
35  import org.apache.commons.collections4.CollectionUtils;
36  import org.apache.commons.logging.Log;
37  import org.apache.commons.logging.LogFactory;
38  
39  import java.io.IOException;
40  import java.util.ArrayList;
41  import java.util.Collection;
42  import java.util.Iterator;
43  import java.util.LinkedHashSet;
44  import java.util.List;
45  import java.util.Map;
46  import java.util.Set;
47  
48  import static org.nuiton.i18n.I18n.t;
49  
50  /**
51   * Created on 1/20/14.
52   *
53   * @author Tony Chemit - chemit@codelutin.com
54   * @since 3.0.1
55   */
56  public class PsionImportModel {
57  
58      /** Logger. */
59      private static final Log log = LogFactory.getLog(PsionImportModel.class);
60  
61      /**
62       * All registred species in their registred order.
63       */
64      protected final LinkedHashSet<Species> speciesSet;
65  
66      /**
67       * All sorted batch indexed by their species.
68       *
69       * @since 3.4.2
70       */
71      protected final Multimap<Species, PsionImportBatchModel> sortedBatchsBySpecies;
72  
73      /**
74       * All unsorted batch indexed by their species.
75       *
76       * @since 3.4.2
77       */
78      protected final Multimap<Species, PsionImportBatchModel> unsortedBatchsBySpecies;
79  
80      protected final List<String> errors;
81  
82      public PsionImportModel() {
83          speciesSet = new LinkedHashSet<>();
84          sortedBatchsBySpecies = ArrayListMultimap.create();
85          unsortedBatchsBySpecies = ArrayListMultimap.create();
86          errors = Lists.newArrayList();
87      }
88  
89      public boolean withBatchs() {
90          return !speciesSet.isEmpty();
91      }
92  
93      public Set<Species> getSpecies() {
94          return ImmutableSet.copyOf(speciesSet);
95      }
96  
97      public List<PsionImportBatchModel> getUnsortedBatches(Species species) {
98          Collection<PsionImportBatchModel> batches = unsortedBatchsBySpecies.get(species);
99          List<PsionImportBatchModel> result = null;
100 
101         if (batches != null) {
102             result = ImmutableList.copyOf(batches);
103 
104         }
105         return result;
106     }
107 
108     public List<PsionImportBatchModel> getSortedBatches(Species species) {
109         Collection<PsionImportBatchModel> batches = sortedBatchsBySpecies.get(species);
110         List<PsionImportBatchModel> result = null;
111 
112         if (batches != null) {
113             result = ImmutableList.copyOf(batches);
114         }
115         return result;
116     }
117 
118     public Set<Integer> getSampleCategoryIdUsed() {
119         Set<Integer> result = Sets.newHashSet();
120         for (PsionImportBatchModel batch : sortedBatchsBySpecies.values()) {
121             Iterator<PsionImportBatchModel.SampleCategory> categoryIterator = batch.getCategoryIterator();
122             while (categoryIterator.hasNext()) {
123                 PsionImportBatchModel.SampleCategory next = categoryIterator.next();
124 
125                 result.add(next.getCategoryId());
126             }
127         }
128         for (PsionImportBatchModel batch : unsortedBatchsBySpecies.values()) {
129             Iterator<PsionImportBatchModel.SampleCategory> categoryIterator = batch.getCategoryIterator();
130             while (categoryIterator.hasNext()) {
131                 PsionImportBatchModel.SampleCategory next = categoryIterator.next();
132 
133                 result.add(next.getCategoryId());
134             }
135         }
136         return result;
137     }
138 
139     public boolean withErrors() {
140         return !errors.isEmpty();
141     }
142 
143     public List<String> getErrors() {
144         return errors;
145     }
146 
147     void addBatch(PsionImportBatchModel batchModel) {
148 
149         Species species = batchModel.getSpecies();
150         speciesSet.add(species);
151 
152         String categoryCode = batchModel.getCategoryCode();
153         Float weight = batchModel.getWeight();
154         Float sampleWeight = batchModel.getSampleWeight();
155 
156         Multimap<Species, PsionImportBatchModel> store;
157 
158         // --- Guess if sorted or unsorted batch --- //
159         if (WeightUnit.KG.isGreaterThanZero(weight) && WeightUnit.KG.isEquals(weight, sampleWeight)) {
160 
161             store = unsortedBatchsBySpecies;
162             if (log.isInfoEnabled()) {
163                 log.info(String.format("Found a unsorted batch [%s] %s - %s", species.getSurveyCode(), weight, sampleWeight));
164             }
165         } else {
166 
167             store = sortedBatchsBySpecies;
168             if (log.isInfoEnabled()) {
169                 log.info(String.format("Found a sorted batch [%s] %s - %s", species.getSurveyCode(), weight, sampleWeight));
170             }
171         }
172 
173         // --- Get if exist the previous batch --- //
174 
175         Collection<PsionImportBatchModel> psionImportBatchModels = store.get(species);
176 
177         PsionImportBatchModel mergeBatch = null;
178 
179         if (CollectionUtils.isNotEmpty(psionImportBatchModels)) {
180 
181             for (PsionImportBatchModel importBatchModel : psionImportBatchModels) {
182                 if (categoryCode.equals(importBatchModel.getCategoryCode())) {
183                     mergeBatch = importBatchModel;
184                     break;
185                 }
186             }
187         }
188 
189         if (mergeBatch == null) {
190 
191             // new batch
192             store.put(species, batchModel);
193 
194             if (log.isDebugEnabled()) {
195                 log.debug("Added " + batchModel);
196             }
197         } else {
198 
199             // merge batch
200             mergeBatch.merge(batchModel);
201 
202             if (log.isDebugEnabled()) {
203                 log.debug("Merged " + batchModel + " to " + mergeBatch);
204             }
205         }
206     }
207 
208     void addError(String error) {
209         errors.add(error);
210     }
211 
212     void cleanSortedBatches() {
213 
214         for (Species species : sortedBatchsBySpecies.keySet()) {
215 
216             for (PsionImportBatchModel batchModel : sortedBatchsBySpecies.get(species)) {
217 
218                 Float weight = batchModel.getWeight();
219                 Float sampleWeight = batchModel.getSampleWeight();
220 
221                 if (WeightUnit.KG.isZero(weight) && WeightUnit.KG.isGreaterThanZero(sampleWeight)) {
222 
223                     // POID = 0 et TAIL != POID : un seul poids à positionner
224                     batchModel.setWeight(sampleWeight);
225                     batchModel.setSampleWeight(null);
226 
227                 }
228 
229             }
230 
231         }
232 
233     }
234 
235     void cleanUnsortedBatches() {
236 
237         for (Species species : unsortedBatchsBySpecies.keySet()) {
238 
239             for (PsionImportBatchModel batchModel : unsortedBatchsBySpecies.get(species)) {
240 
241                 // POID = TAIL  un seul poids à positionner
242                 batchModel.setSampleWeight(null);
243             }
244 
245         }
246     }
247 
248     void checkSortedBatches(SampleCategoryModel sampleCategoryModel) throws IOException {
249 
250         Map<Integer, SampleCategoryModelEntry> categoriesById =
251                 sampleCategoryModel.getCategoryMap();
252 
253         for (Species species : sortedBatchsBySpecies.keySet()) {
254 
255             Collection<PsionImportBatchModel> speciesBatchesWithDoubleWeight = new ArrayList<>();
256             Collection<PsionImportBatchModel> speciesBatchesWithDoubleWeightAndCat = new ArrayList<>();
257 
258             for (PsionImportBatchModel batchModel : sortedBatchsBySpecies.get(species)) {
259 
260                 checkSampleCategoryModel(categoriesById, batchModel);
261 
262                 Float weight = batchModel.getWeight();
263                 Float sampleWeight = batchModel.getSampleWeight();
264 
265                 if (WeightUnit.KG.isZero(weight) && WeightUnit.KG.isGreaterThanZero(sampleWeight)) {
266 
267                     // POID = 0 et TAIL != POID : un seul poids à positionner
268                     continue;
269                 }
270 
271                 if (WeightUnit.KG.isGreaterThanZero(weight) && WeightUnit.KG.isGreaterThan(weight, sampleWeight)) {
272 
273                     // POID > 0 et POID > TAIL : deux poids à positionner
274                     speciesBatchesWithDoubleWeight.add(batchModel);
275 
276                     if (batchModel.withCategories()) {
277 
278                         speciesBatchesWithDoubleWeightAndCat.add(batchModel);
279                     }
280 
281                 }
282 
283             }
284 
285             if (!speciesBatchesWithDoubleWeight.isEmpty()) {
286 
287                 if (speciesBatchesWithDoubleWeightAndCat.size() == speciesBatchesWithDoubleWeight.size()) {
288 
289                     // tous les lots sont categories
290                     // on marque les lots pour que weight soit sur la categorie et sampleWeight comme poids de sous echantillon
291 
292                     for (PsionImportBatchModel batchModel : speciesBatchesWithDoubleWeight) {
293                         batchModel.setApplyBothWeightOnCategorizedBatch(true);
294                     }
295                 } else if (speciesBatchesWithDoubleWeight.size() == 1 && speciesBatchesWithDoubleWeightAndCat.isEmpty()) {
296 
297                     // un seul lot non categorise
298                 } else {
299 
300                     // on bloque l'import
301                     throw new IOException(
302                             t("tutti.service.psionimport.error.inconsistentVracCategory.message", species.getSurveyCode()));
303                 }
304 
305             }
306 
307         }
308 
309     }
310 
311     protected void checkSampleCategoryModel(Map<Integer, SampleCategoryModelEntry> categoriesById,
312                                             PsionImportBatchModel batchModel) throws IOException {
313 
314         SampleCategoryModelEntry lastSampleCategory = null;
315 
316         if (batchModel.withCategories()) {
317 
318             Iterator<PsionImportBatchModel.SampleCategory> categoryIterator = batchModel.getCategoryIterator();
319             while (categoryIterator.hasNext()) {
320                 PsionImportBatchModel.SampleCategory nextCat = categoryIterator.next();
321                 SampleCategoryModelEntry actualCategory = categoriesById.get(nextCat.getCategoryId());
322 
323                 if (lastSampleCategory != null) {
324 
325                     if (actualCategory.getOrder() < lastSampleCategory.getOrder()) {
326 
327                         throw new IOException(t("tutti.service.psionimport.error.mismatchSampleCategory.message", batchModel.getSpecies().getSurveyCode(), actualCategory, lastSampleCategory));
328 
329                     }
330                 }
331                 lastSampleCategory = actualCategory;
332 
333             }
334 
335         }
336 
337     }
338 }