1 package fr.ifremer.tutti.service.protocol;
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 import com.google.common.base.Preconditions;
28 import com.google.common.collect.Maps;
29 import com.google.common.io.Files;
30 import fr.ifremer.tutti.persistence.entities.protocol.CaracteristicMappingRow;
31 import fr.ifremer.tutti.persistence.entities.protocol.CaracteristicMappingRowBean;
32 import fr.ifremer.tutti.persistence.entities.protocol.CaracteristicType;
33 import fr.ifremer.tutti.persistence.entities.protocol.MaturityCaracteristic;
34 import fr.ifremer.tutti.persistence.entities.protocol.MaturityCaracteristics;
35 import fr.ifremer.tutti.persistence.entities.protocol.TuttiProtocol;
36 import fr.ifremer.tutti.persistence.entities.referential.Caracteristic;
37 import fr.ifremer.tutti.service.AbstractTuttiService;
38 import org.apache.commons.logging.Log;
39 import org.apache.commons.logging.LogFactory;
40 import org.nuiton.csv.Export;
41 import org.nuiton.csv.Import;
42 import org.nuiton.csv.ImportRuntimeException;
43 import org.nuiton.csv.ext.CsvReaders;
44 import org.nuiton.jaxx.application.ApplicationTechnicalException;
45
46 import java.io.BufferedWriter;
47 import java.io.File;
48 import java.io.IOException;
49 import java.io.Reader;
50 import java.nio.charset.StandardCharsets;
51 import java.util.ArrayList;
52 import java.util.Collections;
53 import java.util.LinkedHashMap;
54 import java.util.LinkedHashSet;
55 import java.util.List;
56 import java.util.Map;
57 import java.util.function.Function;
58 import java.util.stream.Collectors;
59
60 import static org.nuiton.i18n.I18n.t;
61
62
63
64
65
66
67
68 public class ProtocolCaracteristicsImportExportService extends AbstractTuttiService {
69
70
71 private static final Log log = LogFactory.getLog(ProtocolCaracteristicsImportExportService.class);
72
73 public void importProtocolCaracteristic(File file,
74 TuttiProtocol protocol,
75 Map<String, Caracteristic> caracteristicMap) throws IOException {
76 if (log.isInfoEnabled()) {
77 log.info("Will import protocol caracteristic from file: " + file);
78 }
79
80 List<String> lengthClassesPmfmIds = new ArrayList<>(protocol.getLengthClassesPmfmId());
81 List<String> individualObservationPmfmId = new ArrayList<>(protocol.getIndividualObservationPmfmId());
82 Map<String, MaturityCaracteristic> maturityCaracteristics = new LinkedHashMap<>();
83 if (!protocol.isMaturityCaracteristicsEmpty()) {
84 maturityCaracteristics.putAll(Maps.uniqueIndex(protocol.getMaturityCaracteristics(), MaturityCaracteristic::getId));
85 }
86
87 Map<String, CaracteristicMappingRow> rowsByCaracteristicId = new LinkedHashMap<>();
88 if (!protocol.isCaracteristicMappingEmpty()) {
89 rowsByCaracteristicId.putAll(Maps.uniqueIndex(protocol.getCaracteristicMapping(), CaracteristicMappingRow::getPmfmId));
90 }
91
92 try (Reader reader = Files.newReader(file, StandardCharsets.UTF_8)) {
93
94 CaracteristicRowModel csvModel = CaracteristicRowModel.forImport(getCsvSeparator(), caracteristicMap);
95 try (Import<CaracteristicRow> importer = Import.newImport(csvModel, reader)) {
96
97 for (CaracteristicRow bean : importer) {
98
99 CaracteristicType caracteristicType = bean.getPmfmType();
100 Caracteristic caracteristic = bean.getPmfm();
101 String id = caracteristic.getId();
102 switch (caracteristicType) {
103
104 case INDIVIDUAL_OBSERVATION:
105 individualObservationPmfmId.add(id);
106 break;
107 case LENGTH_STEP:
108 lengthClassesPmfmIds.add(id);
109 break;
110 case MATURITY:
111 MaturityCaracteristic maturityCaracteristic = maturityCaracteristics.get(id);
112 if (maturityCaracteristic == null) {
113 maturityCaracteristic = MaturityCaracteristics.newMaturityCaracteristic();
114 maturityCaracteristic.setId(id);
115 maturityCaracteristic.setMatureStateIds(bean.getMatureStateIds());
116 maturityCaracteristics.put(id, maturityCaracteristic);
117 }
118 break;
119
120 case VESSEL_USE_FEATURE:
121 case GEAR_USE_FEATURE:
122 CaracteristicMappingRow row = rowsByCaracteristicId.get(id);
123 if (row == null) {
124 row = new CaracteristicMappingRowBean();
125 row.setPmfmId(id);
126 row.setTab(caracteristicType.name());
127 rowsByCaracteristicId.put(id, row);
128 }
129 break;
130
131 }
132
133 }
134
135 }
136
137 } catch (ImportRuntimeException e) {
138 throw e;
139 } catch (Exception e) {
140 throw new ImportRuntimeException("Could not import protocol [" + protocol.getName() + "] caracteristic from file " + file, e);
141 }
142
143 protocol.setLengthClassesPmfmId(lengthClassesPmfmIds);
144 protocol.setIndividualObservationPmfmId(individualObservationPmfmId);
145 protocol.setMaturityCaracteristics(new ArrayList<>(maturityCaracteristics.values()));
146 protocol.setCaracteristicMapping(new ArrayList<>(rowsByCaracteristicId.values()));
147
148 }
149
150 public void exportAllCaracteristic(File file, Map<String, Caracteristic> caracteristicMap) {
151
152 if (log.isInfoEnabled()) {
153 log.info("Will export all caracteristics to file: " + file);
154 }
155
156 PmfmIdToCaracteristicRowFunction function = new PmfmIdToCaracteristicRowFunction(caracteristicMap);
157
158 List<CaracteristicRow> rows = caracteristicMap.keySet().stream().map(function).collect(Collectors.toList());
159
160 try (BufferedWriter writer = Files.newWriter(file, StandardCharsets.UTF_8)) {
161
162 CaracteristicRowModel csvModel = CaracteristicRowModel.forExport(getCsvSeparator());
163 Export export = Export.newExport(csvModel, rows);
164 export.write(writer);
165
166 } catch (Exception e) {
167 throw new ImportRuntimeException(t("tutti.service.protocol.export.caracteristics.all.error", file), e);
168 }
169
170 }
171
172 public void exportProtocolCaracteristic(File file,
173 TuttiProtocol protocol,
174 Map<String, Caracteristic> caracteristicMap) {
175
176 if (log.isInfoEnabled()) {
177 log.info("Will export all caracteristics to file: " + file);
178 }
179
180 List<CaracteristicRow> rows = new ArrayList<>();
181
182 PmfmIdToCaracteristicRowFunction function = new PmfmIdToCaracteristicRowFunction(caracteristicMap);
183
184 if (!protocol.isLengthClassesPmfmIdEmpty()) {
185 for (String pmfmId : protocol.getLengthClassesPmfmId()) {
186
187 CaracteristicRow row = getCaracteristicRow(CaracteristicType.LENGTH_STEP, pmfmId, function);
188 rows.add(row);
189
190 }
191 }
192
193 if (!protocol.isIndividualObservationPmfmIdEmpty()) {
194 for (String pmfmId : protocol.getIndividualObservationPmfmId()) {
195
196 CaracteristicRow row = getCaracteristicRow(CaracteristicType.INDIVIDUAL_OBSERVATION, pmfmId, function);
197 rows.add(row);
198
199 }
200
201 }
202
203 if (!protocol.isMaturityCaracteristicsEmpty()) {
204
205 for (MaturityCaracteristic maturityCaracteristic : protocol.getMaturityCaracteristics()) {
206
207 CaracteristicRow row = getCaracteristicRow(CaracteristicType.MATURITY, maturityCaracteristic.getId(), function);
208 if (!maturityCaracteristic.isMatureStateIdsEmpty()) {
209 row.setMatureStateIds(new LinkedHashSet<>(maturityCaracteristic.getMatureStateIds()));
210 }
211 rows.add(row);
212
213 }
214
215 }
216
217 if (!protocol.isCaracteristicMappingEmpty()) {
218 for (CaracteristicMappingRow mappingRow : protocol.getCaracteristicMapping()) {
219
220 CaracteristicRow row = getCaracteristicRow(CaracteristicType.valueOf(mappingRow.getTab()), mappingRow.getPmfmId(), function);
221 rows.add(row);
222
223 }
224 }
225
226 try (BufferedWriter writer = Files.newWriter(file, StandardCharsets.UTF_8)) {
227
228 CaracteristicRowModel csvModel = CaracteristicRowModel.forExport(getCsvSeparator());
229 Export export = Export.newExport(csvModel, rows);
230 export.write(writer);
231
232 } catch (Exception e) {
233 throw new ApplicationTechnicalException(t("tutti.service.protocol.export.caracteristics.protocol.error", protocol.getName(), file), e);
234 }
235 }
236
237 public List<String> loadProtocolCaracteristicsImportColumns(File columnsFile) throws IOException {
238
239 String[] headers = CsvReaders.getHeader(columnsFile, ';');
240 List<String> result = new ArrayList<>(headers.length);
241 for (String header : headers) {
242 if ((header.startsWith("\"") && header.endsWith("\"")) ||
243 (header.startsWith("'") && header.endsWith("'"))) {
244 header = header.substring(1, header.length() - 1);
245 }
246 result.add(header);
247 }
248 Collections.sort(result);
249 return result;
250
251 }
252
253 private CaracteristicRow getCaracteristicRow(CaracteristicType caracteristicType, String id, PmfmIdToCaracteristicRowFunction function) {
254 CaracteristicRow row = function.apply(id);
255 row.setPmfmType(caracteristicType);
256 return row;
257 }
258
259
260 private static class PmfmIdToCaracteristicRowFunction implements Function<String, CaracteristicRow> {
261
262 private final Map<String, Caracteristic> caracteristicMap;
263
264 public PmfmIdToCaracteristicRowFunction(Map<String, Caracteristic> caracteristicMap) {
265 this.caracteristicMap = caracteristicMap;
266 }
267
268 @Override
269 public CaracteristicRow apply(String input) {
270 Caracteristic caracteristic = caracteristicMap.get(input);
271 Preconditions.checkNotNull(caracteristic, "Could not find a caracteristic with id: " + input);
272 CaracteristicRow result = new CaracteristicRow();
273 result.setPmfm(caracteristic);
274 return result;
275 }
276
277 }
278
279 private char getCsvSeparator() {
280 return context.getConfig().getCsvSeparator();
281 }
282
283 }