1 package net.sumaris.core.dao.data;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 import com.google.common.base.Preconditions;
26 import net.sumaris.core.dao.administration.user.PersonDao;
27 import net.sumaris.core.dao.referential.ReferentialDao;
28 import net.sumaris.core.dao.referential.taxon.TaxonNameDao;
29 import net.sumaris.core.model.administration.programStrategy.PmfmStrategy;
30 import net.sumaris.core.model.data.Batch;
31 import net.sumaris.core.model.data.Landing;
32 import net.sumaris.core.model.data.Operation;
33 import net.sumaris.core.model.data.Sample;
34 import net.sumaris.core.model.referential.pmfm.Matrix;
35 import net.sumaris.core.model.referential.pmfm.Unit;
36 import net.sumaris.core.model.referential.taxon.TaxonGroup;
37 import net.sumaris.core.model.referential.taxon.TaxonName;
38 import net.sumaris.core.util.Beans;
39 import net.sumaris.core.vo.administration.programStrategy.ProgramVO;
40 import net.sumaris.core.vo.administration.user.DepartmentVO;
41 import net.sumaris.core.vo.administration.user.PersonVO;
42 import net.sumaris.core.vo.data.LandingVO;
43 import net.sumaris.core.vo.data.OperationVO;
44 import net.sumaris.core.vo.data.SampleVO;
45 import net.sumaris.core.vo.referential.ReferentialVO;
46 import org.apache.commons.collections4.CollectionUtils;
47 import org.slf4j.Logger;
48 import org.slf4j.LoggerFactory;
49 import org.springframework.beans.factory.annotation.Autowired;
50 import org.springframework.stereotype.Repository;
51
52 import javax.annotation.PostConstruct;
53 import javax.persistence.EntityManager;
54 import javax.persistence.criteria.CriteriaBuilder;
55 import javax.persistence.criteria.CriteriaQuery;
56 import javax.persistence.criteria.ParameterExpression;
57 import javax.persistence.criteria.Root;
58 import java.sql.Timestamp;
59 import java.util.List;
60 import java.util.Objects;
61 import java.util.stream.Collectors;
62 import java.util.stream.Stream;
63
64 @Repository("sampleDao")
65 public class SampleDaoImpl extends BaseDataDaoImpl implements SampleDao {
66
67
68 private static final Logger log =
69 LoggerFactory.getLogger(SampleDaoImpl.class);
70
71 @Autowired
72 private ReferentialDao referentialDao;
73
74 @Autowired
75 private TaxonNameDao taxonNameDao;
76
77 @Autowired
78 private PersonDao personDao;
79
80 private int unitIdNone;
81
82 @PostConstruct
83 protected void init() {
84 this.unitIdNone = config.getUnitIdNone();
85 }
86
87 @Override
88 @SuppressWarnings("unchecked")
89 public List<SampleVO> getAllByOperationId(int operationId) {
90
91 CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();
92 CriteriaQuery<Sample> query = cb.createQuery(Sample.class);
93 Root<Sample> root = query.from(Sample.class);
94
95 query.select(root);
96
97 ParameterExpression<Integer> tripIdParam = cb.parameter(Integer.class);
98
99 query.where(cb.equal(root.get(Sample.Fields.OPERATION).get(Operation.Fields.ID), tripIdParam));
100
101
102 query.orderBy(cb.asc(root.get(PmfmStrategy.Fields.RANK_ORDER)));
103
104 return toSampleVOs(getEntityManager().createQuery(query)
105 .setParameter(tripIdParam, operationId).getResultList(), false);
106 }
107
108 @Override
109 @SuppressWarnings("unchecked")
110 public List<SampleVO> getAllByLandingId(int landingId) {
111
112 CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();
113 CriteriaQuery<Sample> query = cb.createQuery(Sample.class);
114 Root<Sample> root = query.from(Sample.class);
115
116 query.select(root);
117
118 ParameterExpression<Integer> idParam = cb.parameter(Integer.class);
119
120 query.where(cb.equal(root.get(Sample.Fields.LANDING).get(Landing.Fields.ID), idParam));
121
122
123 query.orderBy(cb.asc(root.get(PmfmStrategy.Fields.RANK_ORDER)));
124
125 return toSampleVOs(getEntityManager().createQuery(query)
126 .setParameter(idParam, landingId).getResultList(), false);
127 }
128
129
130 @Override
131 public SampleVO get(int id) {
132 Sample entity = get(Sample.class, id);
133 return toSampleVO(entity, false);
134 }
135
136 @Override
137 public List<SampleVO> saveByOperationId(int operationId, List<SampleVO> sources) {
138
139
140 Operation parent = get(Operation.class, operationId);
141 ProgramVOprogramStrategy/ProgramVO.html#ProgramVO">ProgramVO parentProgram = new ProgramVO();
142 parentProgram.setId(parent.getTrip().getProgram().getId());
143
144
145 final List<Integer> sourcesIdsToRemove = Beans.collectIds(Beans.getList(parent.getSamples()));
146
147
148 List<SampleVO> result = sources.stream().map(source -> {
149 source.setOperationId(operationId);
150 source.setProgram(parentProgram);
151 if (source.getId() != null) {
152 sourcesIdsToRemove.remove(source.getId());
153 }
154 return save(source);
155 }).collect(Collectors.toList());
156
157
158 if (CollectionUtils.isNotEmpty(sourcesIdsToRemove)) {
159 sourcesIdsToRemove.forEach(this::delete);
160 }
161
162
163 result.stream().forEach(sample -> {
164 if (sample.getParent() != null) {
165 sample.setParentId(sample.getParent().getId());
166 sample.setParent(null);
167 }
168 });
169
170 return result;
171 }
172
173 @Override
174 public List<SampleVO> saveByLandingId(int landingId, List<SampleVO> sources) {
175
176 Landing parent = get(Landing.class, landingId);
177 ProgramVOprogramStrategy/ProgramVO.html#ProgramVO">ProgramVO parentProgram = new ProgramVO();
178 parentProgram.setId(parent.getProgram().getId());
179
180
181 final List<Integer> sourcesIdsToRemove = Beans.collectIds(Beans.getList(parent.getSamples()));
182
183
184 List<SampleVO> result = sources.stream().map(source -> {
185 source.setLandingId(landingId);
186 source.setProgram(parentProgram);
187 if (source.getId() != null) {
188 sourcesIdsToRemove.remove(source.getId());
189 }
190 return save(source);
191 }).collect(Collectors.toList());
192
193
194 if (CollectionUtils.isNotEmpty(sourcesIdsToRemove)) {
195 sourcesIdsToRemove.forEach(this::delete);
196 }
197
198
199 result.stream().forEach(sample -> {
200 if (sample.getParent() != null) {
201 sample.setParentId(sample.getParent().getId());
202 sample.setParent(null);
203 }
204 });
205
206 return result;
207 }
208
209 @Override
210 public SampleVOf="../../../../../net/sumaris/core/vo/data/SampleVO.html#SampleVO">SampleVO save(SampleVO source) {
211 Preconditions.checkNotNull(source);
212
213 EntityManager entityManager = getEntityManager();
214 Sample entity = null;
215 if (source.getId() != null) {
216 entity = get(Sample.class, source.getId());
217 }
218 boolean isNew = (entity == null);
219 if (isNew) {
220 entity = new Sample();
221 }
222
223 if (!isNew) {
224
225
226
227
228
229
230 }
231
232
233 copySomeFieldsFromParent(source);
234
235
236 sampleVOToEntity(source, entity, true);
237
238
239 Timestamp newUpdateDate = getDatabaseCurrentTimestamp();
240 entity.setUpdateDate(newUpdateDate);
241
242
243 if (isNew) {
244
245 entity.setCreationDate(newUpdateDate);
246 source.setCreationDate(newUpdateDate);
247
248 entityManager.persist(entity);
249 source.setId(entity.getId());
250 } else {
251 if (entity.getCreationDate() == null) {
252 log.warn("Recording a sample without creation date. Should never occur! Sample ID=" + entity.getId());
253 entity.setCreationDate(newUpdateDate);
254 source.setCreationDate(newUpdateDate);
255 }
256 entityManager.merge(entity);
257 }
258
259 source.setUpdateDate(newUpdateDate);
260
261
262 if (source.getParentId() == null && entity.getParent() != null) {
263 source.setParentId(entity.getParent().getId());
264 }
265
266 entityManager.flush();
267 entityManager.clear();
268
269 return source;
270 }
271
272 @Override
273 public void delete(int id) {
274
275 log.debug(String.format("Deleting sample {id=%s}...", id));
276 delete(Sample.class, id);
277 }
278
279 @Override
280 public SampleVO toSampleVO(Sample source) {
281 return toSampleVO(source, true);
282 }
283
284
285
286
287 protected SampleVO toSampleVO(Sample source, boolean allFields) {
288
289 if (source == null) return null;
290
291 SampleVOmpleVO.html#SampleVO">SampleVO target = new SampleVO();
292
293 Beans.copyProperties(source, target);
294
295
296 ReferentialVO matrix = referentialDao.toReferentialVO(source.getMatrix());
297 target.setMatrix(matrix);
298
299
300 if (source.getSizeUnit() != null && source.getSizeUnit().getId().intValue() != unitIdNone) {
301 target.setSizeUnit(source.getSizeUnit().getLabel());
302 }
303
304
305 if (source.getTaxonGroup() != null) {
306 ReferentialVO taxonGroup = referentialDao.toReferentialVO(source.getTaxonGroup());
307 target.setTaxonGroup(taxonGroup);
308 }
309
310
311 if (source.getReferenceTaxon() != null) {
312 ReferentialVO taxonName = taxonNameDao.getTaxonNameReferent(source.getReferenceTaxon().getId());
313 target.setTaxonName(taxonName);
314 }
315
316
317 if (source.getParent() != null) {
318 target.setParentId(source.getParent().getId());
319 }
320
321
322 if (source.getOperation() != null) {
323 target.setOperationId(source.getOperation().getId());
324 }
325
326 if (source.getBatch() != null) {
327 target.setBatchId(source.getBatch().getId());
328 }
329
330
331 if (allFields) {
332
333 DepartmentVO recorderDepartment = referentialDao.toTypedVO(source.getRecorderDepartment(), DepartmentVO.class).orElse(null);
334 target.setRecorderDepartment(recorderDepartment);
335
336
337 if (source.getRecorderPerson() != null) {
338 PersonVO recorderPerson = personDao.toPersonVO(source.getRecorderPerson());
339 target.setRecorderPerson(recorderPerson);
340 }
341 }
342
343 return target;
344 }
345
346 protected void copySomeFieldsFromParent(SampleVO target) {
347 OperationVO operation = target.getOperation();
348 if (operation != null) {
349 target.setRecorderDepartment(operation.getRecorderDepartment());
350 return;
351 }
352 LandingVO landing = target.getLanding();
353 if (landing != null) {
354 target.setRecorderDepartment(landing.getRecorderDepartment());
355 return;
356 }
357 }
358
359 protected List<SampleVO> toSampleVOs(List<Sample> source, boolean allFields) {
360 return this.toSampleVOs(source.stream(), allFields);
361 }
362
363 protected List<SampleVO> toSampleVOs(Stream<Sample> source, boolean allFields) {
364 return source.map(s -> this.toSampleVO(s, allFields))
365 .filter(Objects::nonNull)
366 .collect(Collectors.toList());
367 }
368
369 protected void sampleVOToEntity(SampleVO source, Sample target, boolean copyIfNull) {
370
371 copyRootDataProperties(source, target, copyIfNull);
372
373
374 if (copyIfNull || source.getMatrix() != null) {
375 if (source.getMatrix() == null || source.getMatrix().getId() == null) {
376 target.setMatrix(null);
377 }
378 else {
379 target.setMatrix(load(Matrix.class, source.getMatrix().getId()));
380 }
381 }
382
383
384 if (copyIfNull || source.getSizeUnit() != null) {
385 if (source.getSizeUnit() == null) {
386 target.setSizeUnit(null);
387 }
388 else {
389 ReferentialVO unit = referentialDao.findByUniqueLabel(Unit.class.getSimpleName(), source.getSizeUnit());
390 Preconditions.checkNotNull(unit, String.format("Invalid 'sample.sizeUnit': unit symbol '%s' not exists", source.getSizeUnit()));
391 target.setSizeUnit(load(Unit.class, unit.getId()));
392 }
393 }
394
395
396 if (copyIfNull || source.getTaxonGroup() != null) {
397 if (source.getTaxonGroup() == null || source.getTaxonGroup().getId() == null) {
398 target.setTaxonGroup(null);
399 }
400 else {
401 target.setTaxonGroup(load(TaxonGroup.class, source.getTaxonGroup().getId()));
402 }
403 }
404
405
406 if (copyIfNull || source.getTaxonName() != null) {
407 if (source.getTaxonName() == null || source.getTaxonName().getId() == null) {
408 target.setReferenceTaxon(null);
409 }
410 else {
411
412 TaxonName taxonname = get(TaxonName.class, source.getTaxonName().getId());
413 target.setReferenceTaxon(taxonname.getReferenceTaxon());
414 }
415 }
416
417 Integer parentId = source.getParent() != null ? source.getParent().getId() : source.getParentId();
418 Integer opeId = source.getOperationId() != null ? source.getOperationId() : (source.getOperation() != null ? source.getOperation().getId() : null);
419 Integer landingId = source.getLandingId() != null ? source.getLandingId() : (source.getLanding() != null ? source.getLanding().getId() : null);
420
421
422 if (copyIfNull || (parentId != null)) {
423 if (parentId == null) {
424 target.setParent(null);
425 }
426 else {
427 Sample parent = load(Sample.class, parentId);
428 target.setParent(parent);
429
430
431 opeId = parent.getOperation().getId();
432 }
433 }
434
435
436 if (copyIfNull || (opeId != null)) {
437 if (opeId == null) {
438 target.setOperation(null);
439 } else {
440 target.setOperation(load(Operation.class, opeId));
441 }
442 }
443
444
445 if (copyIfNull || (landingId != null)) {
446 if (landingId == null) {
447 target.setLanding(null);
448 } else {
449 target.setLanding(load(Landing.class, landingId));
450 }
451 }
452
453
454 Integer batchId = source.getBatchId() != null ? source.getBatchId() : (source.getBatch() != null ? source.getBatch().getId() : null);
455 if (copyIfNull || (batchId != null)) {
456 if (batchId == null) {
457 target.setBatch(null);
458 }
459 else {
460 target.setBatch(load(Batch.class, batchId));
461 }
462 }
463 }
464 }