View Javadoc
1   package fr.ifremer.tutti.service.bigfin.csv;
2   
3   /*
4    * #%L
5    * Tutti :: Service
6    * $Id:$
7    * $HeadURL:$
8    * %%
9    * Copyright (C) 2012 - 2014 Ifremer
10   * %%
11   * This program is free software: you can redistribute it and/or modify
12   * it under the terms of the GNU General Public License as
13   * published by the Free Software Foundation, either version 3 of the
14   * License, or (at your option) any later version.
15   * 
16   * This program is distributed in the hope that it will be useful,
17   * but WITHOUT ANY WARRANTY; without even the implied warranty of
18   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19   * GNU General Public License for more details.
20   * 
21   * You should have received a copy of the GNU General Public
22   * License along with this program.  If not, see
23   * <http://www.gnu.org/licenses/gpl-3.0.html>.
24   * #L%
25   */
26  
27  import fr.ifremer.tutti.persistence.entities.data.SpeciesBatch;
28  import fr.ifremer.tutti.persistence.entities.referential.Species;
29  import fr.ifremer.tutti.persistence.entities.referential.Speciess;
30  import fr.ifremer.tutti.service.bigfin.signs.Sex;
31  import fr.ifremer.tutti.service.bigfin.signs.Size;
32  import fr.ifremer.tutti.service.bigfin.signs.VracHorsVrac;
33  import fr.ifremer.tutti.service.csv.AbstractTuttiImportModel;
34  import org.apache.commons.lang3.StringUtils;
35  import org.nuiton.csv.Common;
36  import org.nuiton.csv.ValueParser;
37  
38  import java.text.ParseException;
39  import java.util.HashMap;
40  import java.util.Map;
41  
42  /**
43   * @author Kevin Morin (Code Lutin)
44   * @since 3.8
45   */
46  public class BigfinDataRowModel extends AbstractTuttiImportModel<BigfinDataRow> {
47  
48      public BigfinDataRowModel(Map<String, Species> speciesBySurveyCode, Map<Integer, SpeciesBatch> speciesBatchesById) {
49  
50          super(',');
51  
52          newIgnoredColumn("Study name");
53  
54          newMandatoryColumn("ID", BigfinDataRow.PROPERTY_RECORD_ID);
55  
56          // date et heure de l'enregistrement (non importé mais utile pour contrôle à l'import)
57          newMandatoryColumn("Date", BigfinDataRow.PROPERTY_DATE, new Common.DateValue("MM/dd/yy HH:mm:ss"));
58  
59          newIgnoredColumn("LOC");
60  
61          // n° de la station (non importé mais utile pour contrôle à l'import)
62          newMandatoryColumn("STA", BigfinDataRow.PROPERTY_STATION);
63  
64          newMandatoryColumn("COMMENT", BigfinDataRow.PROPERTY_VRAC_HORS_VRAC, new VracHorsVracValueParser());
65  
66          newIgnoredColumn("GPS X");
67  
68          newIgnoredColumn("GPS Y");
69  
70          newIgnoredColumn("SP CODE");
71  
72          // code espèce = code campagne (saisie libre donc risque fort de mauvaise saisie)
73          newMandatoryColumn("SPEC", BigfinDataRow.PROPERTY_SPECIES_OR_SPECIES_BATCH, new SpeciesOrSpeciesBatchValueParser(speciesBySurveyCode, speciesBatchesById));
74  
75          newMandatoryColumn("LENGTH (mm)", BigfinDataRow.PROPERTY_LENGTH, Common.PRIMITIVE_FLOAT);
76  
77          newMandatoryColumn("WEIGHT (g)", BigfinDataRow.PROPERTY_WEIGHT, Common.FLOAT);
78  
79          newMandatoryColumn("SEX", BigfinDataRow.PROPERTY_SEX, new SexValueParser());
80  
81          // sz class : si code différents de 0 1 ou 2 alors tout bloquer et donner l'id des lignes en anomalies
82          newMandatoryColumn("SIZE", BigfinDataRow.PROPERTY_SIZE, new SizeValueParser());
83  
84          newIgnoredColumn("MT");
85          newIgnoredColumn("MS");
86  
87      }
88  
89      @Override
90      public BigfinDataRow newEmptyInstance() {
91          return new BigfinDataRow();
92      }
93  
94      private static class SpeciesOrSpeciesBatchValueParser implements ValueParser<SpeciesOrSpeciesBatch> {
95  
96          final Map<String, Species> foundSpecies = new HashMap<>();
97  
98          private final Map<String, Species> speciesBySurveyCode;
99  
100         private final Map<Integer, SpeciesBatch> speciesBatches;
101 
102         public SpeciesOrSpeciesBatchValueParser(Map<String, Species> speciesBySurveyCode, Map<Integer, SpeciesBatch> speciesBatchesById) {
103             this.speciesBySurveyCode = speciesBySurveyCode;
104             this.speciesBatches = speciesBatchesById;
105         }
106 
107         @Override
108         public SpeciesOrSpeciesBatch parse(String value) throws ParseException {
109 
110             SpeciesBatch speciesBatch = null;
111             Species species = null;
112 
113             if (StringUtils.isNotBlank(value)) {
114 
115                 speciesBatch = getSpeciesBatch(value);
116 
117                 if (speciesBatch == null) {
118 
119                     // try a species
120                     species = getSpecies(value);
121                 }
122 
123             }
124 
125             SpeciesOrSpeciesBatch result;
126 
127             if (speciesBatch == null) {
128 
129                 // Just a species
130                 result = new SpeciesOrSpeciesBatch(species);
131             } else {
132 
133                 // SpeciesBatch
134                 result = new SpeciesOrSpeciesBatch(speciesBatch);
135             }
136 
137             return result;
138 
139         }
140 
141         protected SpeciesBatch getSpeciesBatch(String value) {
142 
143             SpeciesBatch speciesBatch = null;
144 
145             if (StringUtils.isNotBlank(value)) {
146                 try {
147                     Integer batchId = Integer.valueOf(value);
148                     speciesBatch = speciesBatches.get(batchId);
149                 } catch (NumberFormatException e) {
150                     // Not a number
151                     // Not a species batch
152                 }
153 
154             }
155 
156             return speciesBatch;
157 
158         }
159 
160         protected Species getSpecies(String value) {
161 
162             Species species;
163 
164             if (StringUtils.isBlank(value)) {
165 
166                 species = Speciess.newSpecies();
167 
168             } else {
169 
170                 // use upper case
171                 value = value.toUpperCase();
172 
173                 // if code already found
174                 species = foundSpecies.get(value);
175 
176                 //if not found, look for it in the survey codes
177                 if (species == null) {
178                     species = speciesBySurveyCode.get(value);
179                 }
180 
181                 // Si on ne trouve pas une espèce de code campagne XXXXXXX, on essaye alors avec le code XXXX-XXX
182                 if (species == null) {
183                     String alternativeSpeciesCode = value.substring(0, 4) + '-' + value.substring(4);
184                     species = speciesBySurveyCode.get(alternativeSpeciesCode);
185                 }
186 
187                 if (species == null) {
188                     species = Speciess.newSpecies();
189                     species.setExternalCode(value);
190                 }
191 
192                 // record the code in the found codes
193                 foundSpecies.put(value, species);
194 
195             }
196 
197             return species;
198 
199         }
200 
201     }
202 
203     private static class SizeValueParser implements ValueParser<Size> {
204         @Override
205         public Size parse(String value) throws ParseException {
206             return Size.getValue(value.toUpperCase());
207         }
208     }
209 
210     private static class SexValueParser implements ValueParser<Sex> {
211         @Override
212         public Sex parse(String value) throws ParseException {
213             Sex result = Sex.getValue(value.toUpperCase());
214             if (result == null) {
215                 throw new ParseException("Could not parse Sex value: " + value, 0);
216             }
217             return result;
218         }
219     }
220 
221     private static class VracHorsVracValueParser implements ValueParser<VracHorsVrac> {
222         @Override
223         public VracHorsVrac parse(String value) throws ParseException {
224             // On importe dans le Vrac par défaut, sauf si il y a le texte HV ou hv dans le champ text
225             VracHorsVrac result = VracHorsVrac.getValue(value.toUpperCase());
226             if (result == null) {
227                 result = VracHorsVrac.VRAC;
228             }
229             return result;
230         }
231     }
232 }