1 package fr.ifremer.reefdb.dao.data.samplingoperation;
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 import com.google.common.collect.Lists;
27 import fr.ifremer.quadrige3.core.dao.administration.program.Program;
28 import fr.ifremer.quadrige3.core.dao.administration.user.DepartmentImpl;
29 import fr.ifremer.quadrige3.core.dao.data.samplingoperation.SamplingOperation;
30 import fr.ifremer.quadrige3.core.dao.data.samplingoperation.SamplingOperationDaoImpl;
31 import fr.ifremer.quadrige3.core.dao.data.survey.Survey;
32 import fr.ifremer.quadrige3.core.dao.data.survey.SurveyImpl;
33 import fr.ifremer.quadrige3.core.dao.referential.*;
34 import fr.ifremer.quadrige3.core.dao.referential.monitoringLocation.PositionningSystemImpl;
35 import fr.ifremer.quadrige3.core.dao.system.*;
36 import fr.ifremer.quadrige3.core.dao.technical.Assert;
37 import fr.ifremer.quadrige3.core.dao.technical.Daos;
38 import fr.ifremer.reefdb.config.ReefDbConfiguration;
39 import fr.ifremer.reefdb.dao.administration.user.ReefDbDepartmentDao;
40 import fr.ifremer.reefdb.dao.data.measurement.ReefDbMeasurementDao;
41 import fr.ifremer.reefdb.dao.data.photo.ReefDbPhotoDao;
42 import fr.ifremer.reefdb.dao.referential.ReefDbReferentialDao;
43 import fr.ifremer.reefdb.dao.referential.ReefDbSamplingEquipmentDao;
44 import fr.ifremer.reefdb.dao.referential.ReefDbUnitDao;
45 import fr.ifremer.reefdb.dao.technical.Geometries;
46 import fr.ifremer.reefdb.dto.ReefDbBeanFactory;
47 import fr.ifremer.reefdb.dto.ReefDbBeans;
48 import fr.ifremer.reefdb.dto.data.measurement.MeasurementDTO;
49 import fr.ifremer.reefdb.dto.data.sampling.SamplingOperationDTO;
50 import fr.ifremer.reefdb.service.ReefDbDataContext;
51 import org.apache.commons.collections4.CollectionUtils;
52 import org.hibernate.Session;
53 import org.hibernate.SessionFactory;
54 import org.hibernate.type.DateType;
55 import org.hibernate.type.IntegerType;
56 import org.springframework.beans.factory.InitializingBean;
57 import org.springframework.beans.factory.annotation.Autowired;
58 import org.springframework.dao.DataIntegrityViolationException;
59 import org.springframework.stereotype.Repository;
60
61 import javax.annotation.Resource;
62 import java.util.*;
63
64
65
66
67
68
69 @Repository("reefDbSamplingOperationDao")
70 public class ReefDbSamplingOperationDaoImpl extends SamplingOperationDaoImpl implements ReefDbSamplingOperationDao, InitializingBean {
71
72
73
74 @Resource(name = "reefDbReferentialDao")
75 protected ReefDbReferentialDao referentialDao;
76
77 @Resource(name = "reefDbSamplingEquipmentDao")
78 protected ReefDbSamplingEquipmentDao samplingEquipmentDao;
79
80 @Resource(name = "reefDbDepartmentDao")
81 protected ReefDbDepartmentDao departmentDao;
82
83 @Resource(name = "reefDbMeasurementDao")
84 protected ReefDbMeasurementDao measurementDao;
85
86 @Resource(name = "reefDbPhotoDao")
87 protected ReefDbPhotoDao photoDao;
88
89 @Resource(name = "reefDbUnitDao")
90 protected ReefDbUnitDao unitDao;
91
92 @Resource(name = "reefdbDataContext")
93 protected ReefDbDataContext dataContext;
94
95 @Resource
96 protected ReefDbConfiguration config;
97
98 private int unitIdMeter;
99
100
101
102
103
104
105 @Autowired
106 public ReefDbSamplingOperationDaoImpl(SessionFactory sessionFactory) {
107 super(sessionFactory);
108 }
109
110 @Override
111 public void afterPropertiesSet() {
112 initConstants();
113 }
114
115 private void initConstants() {
116 unitIdMeter = UnitId.METER.getValue();
117 if (config.isDbCheckConstantsEnable()) {
118 Session session = getSessionFactory().openSession();
119 try {
120 Assert.notNull(session.get(UnitImpl.class, unitIdMeter));
121 } finally {
122 fr.ifremer.reefdb.dao.technical.Daos.closeSilently(session);
123 }
124 }
125 }
126
127
128 @Override
129 public List<SamplingOperationDTO> getSamplingOperationsBySurveyId(int surveyId, boolean withIndividualMeasurements) {
130
131 Iterator<Object[]> it = queryIterator("samplingOperationsBySurveyId",
132 "surveyId", IntegerType.INSTANCE, surveyId);
133
134 List<SamplingOperationDTO> result = Lists.newArrayList();
135
136 while (it.hasNext()) {
137 Object[] source = it.next();
138 SamplingOperationDTO samplingOperation = toSamplingOperationDTO(Arrays.asList(source).iterator());
139
140
141 loadMeasurements(samplingOperation, withIndividualMeasurements);
142
143 result.add(samplingOperation);
144 }
145
146 return result;
147 }
148
149
150 @Override
151 public void saveSamplingOperationsBySurveyId(int surveyId, Collection<SamplingOperationDTO> samplingOperations) {
152
153 Survey survey = load(SurveyImpl.class, surveyId);
154 List<Integer> existingSamplingOperationIds = ReefDbBeans.collectProperties(survey.getSamplingOperations(), "samplingOperId");
155
156 if (CollectionUtils.isNotEmpty(samplingOperations)) {
157 for (SamplingOperationDTO samplingOperation : samplingOperations) {
158 SamplingOperation target;
159 if (samplingOperation.getId() == null) {
160 samplingOperation.setDirty(true);
161 target = SamplingOperation.Factory.newInstance();
162 } else {
163 target = get(samplingOperation.getId());
164 existingSamplingOperationIds.remove(target.getSamplingOperId());
165
166
167 if (!Objects.equals(target.getSamplingOperUtFormat(), survey.getSurveyUtFormat())) {
168 samplingOperation.setDirty(true);
169 }
170
171
172 if (!Daos.safeConvertToBoolean(target.getSamplingOperActualPosition())) {
173 samplingOperation.setDirty(true);
174 }
175 }
176
177
178 if (samplingOperation.isDirty()) {
179
180 beanToEntity(samplingOperation, target, survey);
181
182
183 target.setSurvey(survey);
184
185 getSession().save(target);
186
187
188 saveGeometry(samplingOperation, target, survey);
189
190
191 samplingOperation.setId(target.getSamplingOperId());
192
193
194 if (samplingOperation.isMeasurementsLoaded()) {
195 List<MeasurementDTO> allMeasurements = Lists.newArrayList();
196 allMeasurements.addAll(samplingOperation.getMeasurements());
197 if (samplingOperation.isIndividualMeasurementsLoaded()) {
198 allMeasurements.addAll(samplingOperation.getIndividualMeasurements());
199 }
200 measurementDao.saveMeasurementsBySamplingOperationId(samplingOperation.getId(), allMeasurements, samplingOperation.isIndividualMeasurementsLoaded());
201 }
202
203 getSession().flush();
204 getSession().clear();
205 samplingOperation.setDirty(false);
206 }
207 }
208 }
209
210
211 if (!existingSamplingOperationIds.isEmpty()) {
212 for (Integer samplingOperationId : existingSamplingOperationIds) {
213 remove(samplingOperationId);
214 }
215 getSession().flush();
216 getSession().clear();
217 }
218 }
219
220 private void loadMeasurements(SamplingOperationDTO samplingOperation, boolean withIndividual) {
221
222 List<MeasurementDTO> allMeasurements = measurementDao.getMeasurementsBySamplingOperationId(samplingOperation.getId(), withIndividual);
223 if (CollectionUtils.isNotEmpty(allMeasurements)) {
224
225
226 for (MeasurementDTO measurement : allMeasurements) {
227
228
229 measurement.setSamplingOperation(samplingOperation);
230
231 if (measurement.getIndividualId() == null) {
232
233 samplingOperation.addMeasurements(measurement);
234 } else if (withIndividual) {
235
236 samplingOperation.addIndividualMeasurements(measurement);
237 }
238 }
239 }
240
241 samplingOperation.setMeasurementsLoaded(true);
242 samplingOperation.setIndividualMeasurementsLoaded(withIndividual);
243 }
244
245
246 @Override
247 public void removeBySurveyId(int surveyId) {
248
249
250 Iterator<Object[]> it = queryIterator("samplingOperationsBySurveyId",
251 "surveyId", IntegerType.INSTANCE, surveyId);
252
253 List<Integer> samplingOperationIds = Lists.newArrayList();
254 while (it.hasNext()) {
255 Object[] source = it.next();
256
257
258 samplingOperationIds.add((Integer) source[0]);
259 }
260
261 for (Integer samplingOperationId : samplingOperationIds) {
262 remove(samplingOperationId);
263 }
264 }
265
266
267 @Override
268 public void remove(Integer samplingOperationId) {
269
270
271 measurementDao.removeAllMeasurementsBySamplingOperationId(samplingOperationId);
272
273
274 photoDao.removeBySamplingOperationId(samplingOperationId);
275
276 super.remove(samplingOperationId);
277 }
278
279 @Override
280 public int validateBySurveyIds(Collection<Integer> surveyIds, Date validationDate) {
281 return createQuery("validateSamplingOperationBySurveyIds",
282 "validationDate", DateType.INSTANCE, validationDate)
283 .setParameterList("surveyIds", surveyIds)
284 .executeUpdate();
285 }
286
287 @Override
288 public int unvalidateBySurveyIds(Collection<Integer> surveyIds) {
289 return createQuery("unvalidateSamplingOperationBySurveyIds")
290 .setParameterList("surveyIds", surveyIds)
291 .executeUpdate();
292 }
293
294 @Override
295 public void updateSamplingOperationsControlDate(Collection<Integer> controlledElementsPks, Date controlDate) {
296 createQuery("updateSamplingOperationControlDate")
297 .setParameterList("operationIds", controlledElementsPks)
298 .setParameter("controlDate", controlDate).executeUpdate();
299
300
301 }
302
303
304 private SamplingOperationDTO toSamplingOperationDTO(Iterator<Object> it) {
305 SamplingOperationDTO result = ReefDbBeanFactory.newSamplingOperationDTO();
306
307 result.setId((Integer) it.next());
308 result.setName((String) it.next());
309 result.setTime(Daos.convertToInteger((Number) it.next()));
310 result.setComment((String) it.next());
311 result.setControlDate(Daos.convertToDate(it.next()));
312 result.setSamplingEquipment(samplingEquipmentDao.getSamplingEquipmentById((int) it.next()));
313 result.setSamplingDepartment(departmentDao.getDepartmentById((int) it.next()));
314 result.setSize(Daos.convertToDouble((Float) it.next()));
315
316
317 Integer unitId = (Integer) it.next();
318 if (unitId != null) {
319 result.setSizeUnit(unitDao.getUnitById(unitId));
320 }
321 Integer depthLevelId = (Integer) it.next();
322 if (depthLevelId != null) {
323 result.setDepthLevel(referentialDao.getDepthLevelById(depthLevelId));
324 }
325 result.setDepth(Daos.convertToDouble((Float) it.next()));
326 result.setMaxDepth(Daos.convertToDouble((Float) it.next()));
327 result.setMinDepth(Daos.convertToDouble((Float) it.next()));
328 result.setIndividualCount(Daos.convertToInteger((Number) it.next()));
329
330
331 Integer posSystemId = (Integer) it.next();
332
333
334 boolean isActualPosition = Daos.safeConvertToBoolean(it.next(), false);
335
336
337
338 String geometryStr = (String) it.next();
339 if (isActualPosition) {
340 result.setCoordinate(Geometries.getCoordinate(geometryStr));
341
342 if (posSystemId != null) {
343 result.setPositioning(referentialDao.getPositioningSystemById(posSystemId));
344 }
345 }
346
347 return result;
348 }
349
350 private void beanToEntity(SamplingOperationDTO bean, SamplingOperation entity, Survey survey) {
351
352 entity.setSamplingOperLb(bean.getName());
353 entity.setSamplingOperTime(bean.getTime());
354 entity.setSamplingOperUtFormat(survey.getSurveyUtFormat());
355 entity.setSamplingOperCm(bean.getComment());
356 entity.setSamplingOperControlDt(bean.getControlDate());
357 entity.setSamplingEquipment(load(SamplingEquipmentImpl.class, bean.getSamplingEquipment().getId()));
358 entity.setDepartment(load(DepartmentImpl.class, bean.getSamplingDepartment().getId()));
359
360
361 if (entity.getRecorderDepartment() == null) {
362 entity.setRecorderDepartment(load(DepartmentImpl.class, dataContext.getRecorderDepartmentId()));
363 }
364
365 if (entity.getQualityFlag() == null) {
366 entity.setQualityFlag(getDefaultQualityFlag());
367 }
368 if (CollectionUtils.isNotEmpty(survey.getPrograms())) {
369 for (Program program: survey.getPrograms()) {
370 entity.addPrograms(program);
371 }
372 }
373
374 entity.setSamplingOperSize(bean.getSize() == null ? null : bean.getSize().floatValue());
375
376 if (bean.getSizeUnit() == null) {
377 entity.setSizeUnit(null);
378 } else {
379 entity.setSizeUnit(load(UnitImpl.class, bean.getSizeUnit().getId()));
380 }
381
382 if (bean.getDepthLevel() == null) {
383 entity.setDepthLevel(null);
384 } else {
385 entity.setDepthLevel(load(DepthLevelImpl.class, bean.getDepthLevel().getId()));
386 }
387 entity.setSamplingOperDepth(bean.getDepth() == null ? null : bean.getDepth().floatValue());
388 entity.setSamplingOperMaxDepth(bean.getMaxDepth() == null ? null : bean.getMaxDepth().floatValue());
389 entity.setSamplingOperMinDepth(bean.getMinDepth() == null ? null : bean.getMinDepth().floatValue());
390
391 if (entity.getSamplingOperDepth() != null || entity.getSamplingOperMinDepth() != null || entity.getSamplingOperMaxDepth() != null) {
392 entity.setDepthUnit(load(UnitImpl.class, unitIdMeter));
393 } else {
394 entity.setDepthUnit(null);
395 }
396
397 entity.setSamplingOperNumberIndiv(bean.getIndividualCount());
398
399 if (bean.getPositioning() == null) {
400 entity.setPositionningSystem(null);
401 } else {
402 entity.setPositionningSystem(load(PositionningSystemImpl.class, bean.getPositioning().getId()));
403 }
404
405 }
406
407 private void saveGeometry(SamplingOperationDTO bean, SamplingOperation entity, Survey survey) {
408
409
410 if (Geometries.isValid(bean.getCoordinate())) {
411
412 if (Geometries.isPoint(bean.getCoordinate())) {
413
414
415 if (entity.getSamplingOperPoints() != null && entity.getSamplingOperPoints().size() == 1) {
416
417 SamplingOperPoint pointToUpdate = entity.getSamplingOperPoints().iterator().next();
418 if (!Geometries.equals(bean.getCoordinate(), pointToUpdate.getSamplingOperPosition())) {
419 pointToUpdate.setSamplingOperPosition(Geometries.getPointPosition(bean.getCoordinate()));
420 getSession().update(pointToUpdate);
421 }
422
423 } else {
424
425 SamplingOperPoint point = SamplingOperPoint.Factory.newInstance();
426 point.setSamplingOperation(entity);
427 point.setSamplingOperPosition(Geometries.getPointPosition(bean.getCoordinate()));
428 getSession().save(point);
429 entity.getSamplingOperPoints().clear();
430 entity.addSamplingOperPoints(point);
431 }
432 entity.getSamplingOperAreas().clear();
433
434 } else {
435
436
437 if (entity.getSamplingOperAreas() != null && entity.getSamplingOperAreas().size() == 1) {
438
439 SamplingOperArea areaToUpdate = entity.getSamplingOperAreas().iterator().next();
440 if (!Geometries.equals(bean.getCoordinate(), areaToUpdate.getSamplingOperPosition())) {
441 areaToUpdate.setSamplingOperPosition(Geometries.getAreaPosition(bean.getCoordinate()));
442 getSession().update(areaToUpdate);
443 }
444
445 } else {
446
447 SamplingOperArea area = SamplingOperArea.Factory.newInstance();
448 area.setSamplingOperation(entity);
449 area.setSamplingOperPosition(Geometries.getAreaPosition(bean.getCoordinate()));
450 getSession().save(area);
451 entity.getSamplingOperAreas().clear();
452 entity.addSamplingOperAreas(area);
453 }
454 entity.getSamplingOperPoints().clear();
455
456 }
457
458
459 entity.getSamplingOperLines().clear();
460
461
462 entity.setSamplingOperActualPosition(fr.ifremer.reefdb.dao.technical.Daos.convertToString(true));
463
464 } else {
465 saveGeometryFromSurvey(entity, survey);
466 }
467
468
469
470 update(entity);
471
472 }
473
474 private void saveGeometryFromSurvey(SamplingOperation entity, Survey survey) {
475
476
477 if (CollectionUtils.size(survey.getSurveyPoints()) == 1) {
478 SurveyPoint sourcePoint = CollectionUtils.extractSingleton(survey.getSurveyPoints());
479
480
481 if (CollectionUtils.size(entity.getSamplingOperPoints()) == 1) {
482 SamplingOperPoint targetPoint = CollectionUtils.extractSingleton(entity.getSamplingOperPoints());
483 if (!Objects.equals(targetPoint.getSamplingOperPosition(), sourcePoint.getSurveyPosition())) {
484 targetPoint.setSamplingOperPosition(sourcePoint.getSurveyPosition());
485 getSession().update(targetPoint);
486 }
487 }
488
489
490 else {
491 SamplingOperPoint targetPoint = SamplingOperPoint.Factory.newInstance();
492 targetPoint.setSamplingOperation(entity);
493 targetPoint.setSamplingOperPosition(sourcePoint.getSurveyPosition());
494 getSession().save(targetPoint);
495 entity.getSamplingOperPoints().clear();
496 entity.addSamplingOperPoints(targetPoint);
497 }
498
499
500 entity.getSamplingOperLines().clear();
501 entity.getSamplingOperAreas().clear();
502 }
503
504
505 else if (CollectionUtils.size(survey.getSurveyLines()) == 1) {
506 SurveyLine sourceLine = CollectionUtils.extractSingleton(survey.getSurveyLines());
507
508
509 if (CollectionUtils.size(entity.getSamplingOperLines()) == 1) {
510 SamplingOperLine targetLine = CollectionUtils.extractSingleton(entity.getSamplingOperLines());
511 if (!Objects.equals(sourceLine.getSurveyPosition(), targetLine.getSamplingOperPosition())) {
512 targetLine.setSamplingOperPosition(sourceLine.getSurveyPosition());
513 getSession().update(targetLine);
514 }
515 }
516
517
518 else {
519 SamplingOperLine targetLine = SamplingOperLine.Factory.newInstance();
520 targetLine.setSamplingOperation(entity);
521 targetLine.setSamplingOperPosition(sourceLine.getSurveyPosition());
522 getSession().save(targetLine);
523 entity.getSamplingOperLines().clear();
524 entity.addSamplingOperLines(targetLine);
525 }
526
527
528 entity.getSamplingOperPoints().clear();
529 entity.getSamplingOperAreas().clear();
530 }
531
532
533 else if (CollectionUtils.size(survey.getSurveyAreas()) == 1) {
534 SurveyArea sourceArea = CollectionUtils.extractSingleton(survey.getSurveyAreas());
535
536
537 if (CollectionUtils.size(entity.getSamplingOperAreas()) == 1) {
538 SamplingOperArea targetArea = CollectionUtils.extractSingleton(entity.getSamplingOperAreas());
539 if (!Objects.equals(sourceArea.getSurveyPosition(), targetArea.getSamplingOperPosition())) {
540 targetArea.setSamplingOperPosition(sourceArea.getSurveyPosition());
541 getSession().update(targetArea);
542 }
543 }
544
545
546 else {
547 SamplingOperArea targetArea = SamplingOperArea.Factory.newInstance();
548 targetArea.setSamplingOperation(entity);
549 targetArea.setSamplingOperPosition(sourceArea.getSurveyPosition());
550 getSession().save(targetArea);
551 entity.getSamplingOperAreas().clear();
552 entity.addSamplingOperAreas(targetArea);
553 }
554
555
556 entity.getSamplingOperPoints().clear();
557 entity.getSamplingOperLines().clear();
558 }
559 else {
560 throw new DataIntegrityViolationException(String.format("Could not found geometry on survey [surveyId=%s].", survey.getSurveyId()));
561 }
562
563
564 entity.setSamplingOperActualPosition(fr.ifremer.reefdb.dao.technical.Daos.convertToString(false));
565
566
567 entity.setPositionningSystem(survey.getPositionningSystem());
568 }
569
570
571
572
573
574
575 private QualityFlag getDefaultQualityFlag() {
576 return load(QualityFlagImpl.class, QualityFlagCode.NOT_QUALIFIED.getValue());
577 }
578
579 }