1 package net.sumaris.core.dao.administration.programStrategy;
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 com.google.common.collect.ImmutableList;
27 import net.sumaris.core.dao.referential.ReferentialDao;
28 import net.sumaris.core.dao.referential.taxon.TaxonNameDao;
29 import net.sumaris.core.dao.technical.hibernate.HibernateDaoSupport;
30 import net.sumaris.core.dao.technical.model.IEntity;
31 import net.sumaris.core.model.administration.programStrategy.AcquisitionLevel;
32 import net.sumaris.core.model.administration.programStrategy.PmfmStrategy;
33 import net.sumaris.core.model.administration.programStrategy.Program;
34 import net.sumaris.core.model.administration.programStrategy.Strategy;
35 import net.sumaris.core.model.referential.Status;
36 import net.sumaris.core.model.referential.StatusEnum;
37 import net.sumaris.core.model.referential.gear.Gear;
38 import net.sumaris.core.model.referential.pmfm.Parameter;
39 import net.sumaris.core.model.referential.pmfm.Pmfm;
40 import net.sumaris.core.util.Beans;
41 import net.sumaris.core.vo.administration.programStrategy.*;
42 import net.sumaris.core.vo.referential.ParameterValueType;
43 import net.sumaris.core.vo.referential.ReferentialVO;
44 import net.sumaris.core.vo.referential.TaxonGroupVO;
45 import org.apache.commons.collections4.CollectionUtils;
46 import org.slf4j.Logger;
47 import org.slf4j.LoggerFactory;
48 import org.springframework.beans.factory.annotation.Autowired;
49 import org.springframework.stereotype.Repository;
50
51 import javax.annotation.PostConstruct;
52 import javax.persistence.EntityManager;
53 import javax.persistence.LockModeType;
54 import javax.persistence.criteria.*;
55 import java.sql.Timestamp;
56 import java.util.Comparator;
57 import java.util.List;
58 import java.util.Objects;
59 import java.util.stream.Collectors;
60
61 @Repository("strategyDao")
62 public class StrategyDaoImpl extends HibernateDaoSupport implements StrategyDao {
63
64
65
66
67 private static final Logger log =
68 LoggerFactory.getLogger(StrategyDaoImpl.class);
69
70
71 @Autowired
72 private ReferentialDao referentialDao;
73
74 @Autowired
75 private TaxonNameDao taxonNameDao;
76
77 private int unitIdNone;
78
79 @PostConstruct
80 protected void init() {
81 this.unitIdNone = config.getUnitIdNone();
82 }
83
84 @Override
85 public List<StrategyVO> findByProgram(int programId, StrategyFetchOptions fetchOptions) {
86 CriteriaBuilder builder = entityManager.getCriteriaBuilder();
87 CriteriaQuery<Strategy> query = builder.createQuery(Strategy.class);
88 Root<Strategy> root = query.from(Strategy.class);
89
90 ParameterExpression<Integer> programIdParam = builder.parameter(Integer.class);
91
92 query.select(root)
93 .where(
94 builder.equal(root.get(Strategy.Fields.PROGRAM).get(Program.Fields.ID), programIdParam));
95
96
97 query.orderBy(builder.asc(root.get(Strategy.Fields.ID)));
98
99 return getEntityManager()
100 .createQuery(query)
101 .setParameter(programIdParam, programId)
102 .getResultStream()
103 .map(s -> this.toStrategyVO(s, fetchOptions))
104 .collect(Collectors.toList());
105 }
106
107 @Override
108 public List<PmfmStrategyVO> getPmfmStrategies(int strategyId) {
109
110 CriteriaBuilder builder = entityManager.getCriteriaBuilder();
111 CriteriaQuery<PmfmStrategy> query = builder.createQuery(PmfmStrategy.class);
112 Root<PmfmStrategy> root = query.from(PmfmStrategy.class);
113
114 ParameterExpression<Integer> strategyIdParam = builder.parameter(Integer.class);
115
116 Join<PmfmStrategy, Strategy> strategyInnerJoin = root.join(PmfmStrategy.Fields.STRATEGY, JoinType.INNER);
117
118 query.select(root)
119 .where(builder.equal(strategyInnerJoin.get(Strategy.Fields.ID), strategyIdParam))
120
121 .orderBy(builder.asc(root.get(PmfmStrategy.Fields.RANK_ORDER)));
122
123 return getEntityManager()
124 .createQuery(query)
125 .setParameter(strategyIdParam, strategyId)
126 .getResultStream()
127 .map(this::toPmfmStrategyVO)
128 .collect(Collectors.toList());
129 }
130
131 @Override
132 public List<PmfmStrategyVO> getPmfmStrategiesByAcquisitionLevel(int programId, int acquisitionLevelId) {
133 CriteriaBuilder builder = entityManager.getCriteriaBuilder();
134 CriteriaQuery<PmfmStrategy> query = builder.createQuery(PmfmStrategy.class);
135 Root<PmfmStrategy> root = query.from(PmfmStrategy.class);
136
137 ParameterExpression<Integer> programIdParam = builder.parameter(Integer.class);
138 ParameterExpression<Integer> acquisitionLevelIdParam = builder.parameter(Integer.class);
139
140 Join<PmfmStrategy, Strategy> strategyInnerJoin = root.join(PmfmStrategy.Fields.STRATEGY, JoinType.INNER);
141
142 query.select(root)
143 .where(
144 builder.and(
145 builder.equal(strategyInnerJoin.get(Strategy.Fields.PROGRAM).get(Program.Fields.ID), programIdParam),
146 builder.equal(root.get(PmfmStrategy.Fields.ACQUISITION_LEVEL).get(AcquisitionLevel.Fields.ID), acquisitionLevelIdParam)
147 ));
148
149
150 query.orderBy(builder.asc(root.get(PmfmStrategy.Fields.RANK_ORDER)));
151
152 return getEntityManager()
153 .createQuery(query)
154 .setParameter(programIdParam, programId)
155 .setParameter(acquisitionLevelIdParam, acquisitionLevelId)
156 .getResultStream()
157 .map(this::toPmfmStrategyVO)
158 .collect(Collectors.toList());
159 }
160
161 @Override
162 public List<ReferentialVO> getGears(int strategyId) {
163 CriteriaBuilder builder = entityManager.getCriteriaBuilder();
164 CriteriaQuery<Gear> query = builder.createQuery(Gear.class);
165 Root<Gear> root = query.from(Gear.class);
166
167 ParameterExpression<Integer> strategyIdParam = builder.parameter(Integer.class);
168
169 Join<Gear, Strategy> gearInnerJoin = root.joinList(Gear.Fields.STRATEGIES, JoinType.INNER);
170
171 query.select(root)
172 .where(
173 builder.and(
174
175 builder.equal(gearInnerJoin.get(Strategy.Fields.ID), strategyIdParam),
176
177 builder.in(root.get(Gear.Fields.STATUS).get(Status.Fields.ID)).value(ImmutableList.of(StatusEnum.ENABLE.getId(), StatusEnum.TEMPORARY.getId()))
178 ));
179
180
181 query.orderBy(builder.asc(root.get(Gear.Fields.LABEL)));
182
183 return getEntityManager()
184 .createQuery(query)
185 .setParameter(strategyIdParam, strategyId)
186 .getResultStream()
187 .map(referentialDao::toReferentialVO)
188 .collect(Collectors.toList());
189 }
190
191 @Override
192 public List<TaxonGroupStrategyVO> getTaxonGroupStrategies(int strategyId) {
193 return getTaxonGroups(load(Strategy.class, strategyId));
194 }
195
196 @Override
197 public List<TaxonNameStrategyVO> getTaxonNameStrategies(int strategyId) {
198 return getTaxonNames(load(Strategy.class, strategyId));
199 }
200
201
202
203
204 protected StrategyVO toStrategyVO(Strategy source, StrategyFetchOptions fetchOptions) {
205 if (source == null) return null;
206
207 StrategyVOstration/programStrategy/StrategyVO.html#StrategyVO">StrategyVO target = new StrategyVO();
208
209 Beans.copyProperties(source, target);
210
211
212 target.setProgramId(source.getProgram().getId());
213
214
215 target.setStatusId(source.getStatus().getId());
216
217
218 if (CollectionUtils.isNotEmpty(source.getGears())) {
219 List<ReferentialVO> gears = source.getGears()
220 .stream()
221 .map(referentialDao::toReferentialVO)
222 .filter(Objects::nonNull)
223 .collect(Collectors.toList());
224 target.setGears(gears);
225 }
226
227
228 target.setTaxonGroups(getTaxonGroups(source));
229
230
231 target.setTaxonNames(getTaxonNames(source));
232
233
234 if (CollectionUtils.isNotEmpty(source.getPmfmStrategies())) {
235 List<PmfmStrategyVO> pmfmStrategies = source.getPmfmStrategies()
236 .stream()
237
238 .map(ps -> toPmfmStrategyVO(ps, fetchOptions))
239 .filter(Objects::nonNull)
240
241 .sorted(Comparator.comparing(ps -> String.format("%s#%s", ps.getAcquisitionLevel(), ps.getRankOrder())))
242 .collect(Collectors.toList());
243 target.setPmfmStrategies(pmfmStrategies);
244 }
245
246 return target;
247 }
248
249 protected PmfmStrategyVO toPmfmStrategyVO(PmfmStrategy source) {
250 return toPmfmStrategyVO(source, StrategyFetchOptions.builder().withPmfmStrategyInheritance(false).build());
251 }
252
253 protected PmfmStrategyVO toPmfmStrategyVO(PmfmStrategy source, StrategyFetchOptions fetchOptions) {
254 return toPmfmStrategyVO(source, fetchOptions.isWithPmfmStrategyInheritance());
255 }
256
257 @Override
258 public PmfmStrategyVO toPmfmStrategyVO(PmfmStrategy source, boolean enablePmfmInheritance) {
259 if (source == null) return null;
260
261 Pmfm pmfm = source.getPmfm();
262 Preconditions.checkNotNull(pmfm);
263
264 PmfmStrategyVOtion/programStrategy/PmfmStrategyVO.html#PmfmStrategyVO">PmfmStrategyVO target = new PmfmStrategyVO();
265
266
267 if (enablePmfmInheritance) {
268 Beans.copyProperties(pmfm, target);
269 }
270 Beans.copyProperties(source, target);
271
272
273 target.setPmfmId(pmfm.getId());
274
275
276 if (pmfm.getMethod() != null) {
277 target.setMethodId(pmfm.getMethod().getId());
278 }
279 if (target.getMinValue() == null) {
280 target.setMinValue(pmfm.getMinValue());
281 }
282 if (target.getMaxValue() == null) {
283 target.setMaxValue(pmfm.getMaxValue());
284 }
285 if (target.getDefaultValue() == null) {
286 target.setDefaultValue(pmfm.getDefaultValue());
287 }
288
289
290 Parameter parameter = pmfm.getParameter();
291 target.setName(parameter.getName());
292
293
294 ParameterValueType type = ParameterValueType.fromPmfm(pmfm);
295 target.setType(type.name().toLowerCase());
296
297
298 if (pmfm.getUnit() != null && pmfm.getUnit().getId().intValue() != unitIdNone) {
299 target.setUnit(pmfm.getUnit().getLabel());
300 }
301
302
303 if (source.getAcquisitionLevel() != null) {
304 target.setAcquisitionLevel(source.getAcquisitionLevel().getLabel());
305 }
306
307
308 if (CollectionUtils.isNotEmpty(parameter.getQualitativeValues())) {
309 List<ReferentialVO> qualitativeValues = parameter.getQualitativeValues()
310 .stream()
311 .map(referentialDao::toReferentialVO)
312 .collect(Collectors.toList());
313 target.setQualitativeValues(qualitativeValues);
314 }
315
316
317 if (CollectionUtils.isNotEmpty(source.getGears())) {
318 List<String> gears = source.getGears()
319 .stream()
320 .map(Gear::getLabel)
321 .filter(Objects::nonNull)
322 .collect(Collectors.toList());
323 target.setGears(gears);
324 }
325
326
327 if (CollectionUtils.isNotEmpty(source.getTaxonGroups())) {
328 List<Integer> taxonGroupIds = source.getTaxonGroups()
329 .stream()
330 .map(IEntity::getId)
331 .collect(Collectors.toList());
332 target.setTaxonGroupIds(taxonGroupIds);
333 }
334
335
336 if (CollectionUtils.isNotEmpty(source.getReferenceTaxons())) {
337 List<Integer> referenceTaxonIds = source.getReferenceTaxons()
338 .stream()
339 .map(IEntity::getId)
340 .collect(Collectors.toList());
341 target.setReferenceTaxonIds(referenceTaxonIds);
342 }
343
344 return target;
345 }
346
347 @Override
348 public List<StrategyVO> saveByProgramId(int programId, List<StrategyVO> sources) {
349
350 Program parent = get(Program.class, programId);
351
352
353 final List<Integer> sourcesIdsToRemove = Beans.collectIds(Beans.getList(parent.getStrategies()));
354
355
356 List<StrategyVO> result = sources.stream().map(source -> {
357 source.setProgramId(programId);
358 if (source.getId() != null) {
359 sourcesIdsToRemove.remove(source.getId());
360 }
361 return save(source);
362 }).collect(Collectors.toList());
363
364
365 if (CollectionUtils.isNotEmpty(sourcesIdsToRemove)) {
366 sourcesIdsToRemove.forEach(this::delete);
367 }
368
369 return result;
370 }
371
372 @Override
373 public StrategyVO"../../../../../../net/sumaris/core/vo/administration/programStrategy/StrategyVO.html#StrategyVO">StrategyVO save(StrategyVO source) {
374 Preconditions.checkNotNull(source);
375 Preconditions.checkNotNull(source.getProgramId(), "Missing 'programId'");
376 Preconditions.checkNotNull(source.getLabel(), "Missing 'label'");
377 Preconditions.checkNotNull(source.getName(), "Missing 'name'");
378 Preconditions.checkNotNull(source.getStatusId(), "Missing 'statusId'");
379
380 EntityManager entityManager = getEntityManager();
381 Strategy entity = null;
382 if (source.getId() != null) {
383 entity = get(Strategy.class, source.getId());
384 }
385 boolean isNew = (entity == null);
386 if (isNew) {
387 entity = new Strategy();
388 }
389
390
391 if (isNew) {
392
393 if (source.getStatusId() == null) {
394 source.setStatusId(config.getStatusIdTemporary());
395 }
396 }
397
398 else {
399
400
401 checkUpdateDateForUpdate(source, entity);
402
403
404 lockForUpdate(entity, LockModeType.PESSIMISTIC_WRITE);
405 }
406
407 strategyVOToEntity(source, entity, true);
408
409
410 Timestamp newUpdateDate = getDatabaseCurrentTimestamp();
411 entity.setUpdateDate(newUpdateDate);
412
413
414 if (isNew) {
415
416 entity.setCreationDate(newUpdateDate);
417 source.setCreationDate(newUpdateDate);
418
419 entityManager.persist(entity);
420 source.setId(entity.getId());
421 } else {
422 entityManager.merge(entity);
423 }
424
425 source.setUpdateDate(newUpdateDate);
426
427
428
429
430
431
432
433 return source;
434 }
435
436 public void delete(int id) {
437 log.debug(String.format("Deleting strategy {id=%s}...", id));
438 delete(Strategy.class, id);
439 }
440
441
442
443 protected void strategyVOToEntity(StrategyVO source, Strategy target, boolean copyIfNull) {
444
445
446 Beans.copyProperties(source, target);
447
448
449 if (copyIfNull || source.getProgramId() != null) {
450 if (source.getProgramId() == null) {
451 target.setProgram(null);
452 }
453 else {
454 target.setProgram(load(Program.class, source.getProgramId()));
455 }
456 }
457
458
459 if (copyIfNull || source.getStatusId() != null) {
460 if (source.getStatusId() == null) {
461 target.setStatus(null);
462 }
463 else {
464 target.setStatus(load(Status.class, source.getStatusId()));
465 }
466 }
467
468 }
469
470 protected List<TaxonNameStrategyVO> getTaxonNames(Strategy source) {
471 if (CollectionUtils.isEmpty(source.getReferenceTaxons())) return null;
472
473 return source.getReferenceTaxons()
474 .stream()
475
476 .sorted(Comparator.comparingInt(item -> item.getPriorityLevel() != null ?
477 item.getPriorityLevel().intValue() :
478 item.getReferenceTaxon().getId().intValue()))
479 .map(item -> {
480 TaxonNameStrategyVOprogramStrategy/TaxonNameStrategyVO.html#TaxonNameStrategyVO">TaxonNameStrategyVO target = new TaxonNameStrategyVO();
481 target.setStrategyId(source.getId());
482
483
484 target.setPriorityLevel(item.getPriorityLevel());
485
486
487 target.setTaxonName(taxonNameDao.getTaxonNameReferent(item.getReferenceTaxon().getId()));
488 return target;
489 })
490 .collect(Collectors.toList());
491 }
492
493 protected List<TaxonGroupStrategyVO> getTaxonGroups(Strategy source) {
494 if (CollectionUtils.isEmpty(source.getTaxonGroups())) return null;
495 return source.getTaxonGroups()
496 .stream()
497
498 .sorted(Comparator.comparingInt((item) -> item.getPriorityLevel() != null ?
499 item.getPriorityLevel().intValue() :
500 item.getTaxonGroup().getId().intValue()))
501 .map(item -> {
502 TaxonGroupStrategyVOrogramStrategy/TaxonGroupStrategyVO.html#TaxonGroupStrategyVO">TaxonGroupStrategyVO target = new TaxonGroupStrategyVO();
503 target.setStrategyId(source.getId());
504
505
506 target.setPriorityLevel(item.getPriorityLevel());
507
508
509 TaxonGroupVOrential/TaxonGroupVO.html#TaxonGroupVO">TaxonGroupVO tg = new TaxonGroupVO();
510 Beans.copyProperties(item.getTaxonGroup(), tg);
511 tg.setStatusId(item.getTaxonGroup().getStatus().getId());
512 target.setTaxonGroup(tg);
513
514 return target;
515 })
516 .collect(Collectors.toList());
517 }
518 }