1 package fr.ifremer.dali.dao.administration.program;
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.ArrayListMultimap;
27 import com.google.common.collect.ImmutableList;
28 import com.google.common.collect.ImmutableListMultimap;
29 import com.google.common.collect.Multimap;
30 import fr.ifremer.dali.dao.administration.strategy.DaliStrategyDao;
31 import fr.ifremer.dali.dao.administration.user.DaliDepartmentDao;
32 import fr.ifremer.dali.dao.administration.user.DaliQuserDao;
33 import fr.ifremer.dali.dao.referential.DaliReferentialDao;
34 import fr.ifremer.dali.dao.technical.Daos;
35 import fr.ifremer.dali.dto.DaliBeanFactory;
36 import fr.ifremer.dali.dto.DaliBeans;
37 import fr.ifremer.dali.dto.configuration.programStrategy.ProgramDTO;
38 import fr.ifremer.dali.dto.configuration.programStrategy.StrategyDTO;
39 import fr.ifremer.dali.dto.referential.DepartmentDTO;
40 import fr.ifremer.dali.dto.referential.LocationDTO;
41 import fr.ifremer.dali.dto.referential.PersonDTO;
42 import fr.ifremer.quadrige3.core.dao.administration.program.*;
43 import fr.ifremer.quadrige3.core.dao.administration.user.DepartmentImpl;
44 import fr.ifremer.quadrige3.core.dao.administration.user.QuserImpl;
45 import fr.ifremer.quadrige3.core.dao.referential.monitoringLocation.MonitoringLocationImpl;
46 import fr.ifremer.quadrige3.core.dao.technical.Assert;
47 import fr.ifremer.quadrige3.core.dao.technical.hibernate.TemporaryDataHelper;
48 import fr.ifremer.quadrige3.core.service.technical.CacheService;
49 import fr.ifremer.quadrige3.ui.core.dto.QuadrigeBeans;
50 import org.apache.commons.collections4.CollectionUtils;
51 import org.apache.commons.collections4.MapUtils;
52 import org.apache.commons.logging.Log;
53 import org.apache.commons.logging.LogFactory;
54 import org.hibernate.Query;
55 import org.hibernate.SessionFactory;
56 import org.hibernate.type.DateType;
57 import org.hibernate.type.IntegerType;
58 import org.hibernate.type.StringType;
59 import org.springframework.beans.factory.annotation.Autowired;
60 import org.springframework.cache.Cache;
61 import org.springframework.dao.DataRetrievalFailureException;
62 import org.springframework.stereotype.Repository;
63
64 import javax.annotation.Resource;
65 import java.util.*;
66 import java.util.stream.Collectors;
67
68
69
70
71
72 @Repository("daliProgramDao")
73 public class DaliProgramDaoImpl extends ProgramDaoImpl implements DaliProgramDao {
74
75
76
77
78 private static final Log log = LogFactory.getLog(DaliProgramDaoImpl.class);
79
80 private static final Multimap<String, String> columnNamesByRulesTableNames = ImmutableListMultimap.<String, String>builder()
81 .put("RULE_LIST_PROG", "PROG_CD").build();
82
83 @Resource(name = "daliStrategyDao")
84 private DaliStrategyDao strategyDao;
85
86 @Resource(name = "daliQuserDao")
87 protected DaliQuserDao quserDao;
88
89 @Resource(name = "daliDepartmentDao")
90 protected DaliDepartmentDao departmentDao;
91
92 @Resource
93 private ProgQuserProgPrivDao progQuserProgPrivDao;
94
95 @Resource
96 private ProgDepProgPrivDao progDepProgPrivDao;
97
98 @Resource
99 protected CacheService cacheService;
100
101 @Resource(name = "daliReferentialDao")
102 protected DaliReferentialDao referentialDao;
103
104
105
106
107
108
109 @Autowired
110 public DaliProgramDaoImpl(SessionFactory sessionFactory) {
111 super(sessionFactory);
112 }
113
114
115 @Override
116 public List<ProgramDTO> getAllPrograms() {
117
118 Cache cacheByCode = cacheService.getCache(PROGRAM_BY_CODE_CACHE);
119
120 Iterator<Object[]> rows = queryIterator("allPrograms");
121
122 List<ProgramDTO> result = new ArrayList<>();
123 while (rows.hasNext()) {
124 ProgramDTO program = toProgramDTO(Arrays.asList(rows.next()).iterator());
125
126
127 getProgramPrivileges(program);
128
129 result.add(program);
130 cacheByCode.put(program.getCode(), program);
131 }
132
133 return ImmutableList.copyOf(result);
134 }
135
136 private void getProgramPrivileges(ProgramDTO program) {
137
138
139
140
141 Iterator<Object[]> rows = queryIterator("programPrivilegesForUsersByProgramCode",
142 "programCode", StringType.INSTANCE, program.getCode());
143
144 program.setManagerPersons(new ArrayList<>());
145 program.setRecorderPersons(new ArrayList<>());
146 while (rows.hasNext()) {
147 Object[] row = rows.next();
148 Integer privilegeId = (Integer) row[0];
149 Integer quserId = (Integer) row[1];
150
151 if (privilegeId != null && quserId != null) {
152 PersonDTO user = quserDao.getUserById(quserId);
153
154 if (ProgramPrivilegeIds.MANAGER.getValue().equals(privilegeId)) {
155 program.addManagerPersons(user);
156 } else if (ProgramPrivilegeIds.RECORDER.getValue().equals(privilegeId)) {
157 program.addRecorderPersons(user);
158 } else {
159 if (log.isDebugEnabled()) {
160 log.debug("ProgrammePrivilegeId = " + privilegeId + " is ignored");
161 }
162 }
163 }
164 }
165
166
167 rows = queryIterator("programPrivilegesForDepartmentsByProgramCode",
168 "programCode", StringType.INSTANCE, program.getCode());
169
170 program.setRecorderDepartments(new ArrayList<>());
171 while (rows.hasNext()) {
172 Object[] row = rows.next();
173 Integer privilegeId = (Integer) row[0];
174 Integer depId = (Integer) row[1];
175
176 if (privilegeId != null && depId != null) {
177 DepartmentDTO department = departmentDao.getDepartmentById(depId);
178
179 if (ProgramPrivilegeIds.RECORDER.getValue().equals(privilegeId)) {
180 program.addRecorderDepartments(department);
181 } else {
182 if (log.isDebugEnabled()) {
183 log.debug("ProgrammePrivilegeId = " + privilegeId + " is ignored");
184 }
185 }
186 }
187
188 }
189 }
190
191
192 @Override
193 public ProgramDTO getProgramByCode(String programCode) {
194 Assert.notBlank(programCode);
195
196 Object[] row = queryUnique("programByCode",
197 "programCode", StringType.INSTANCE, programCode);
198
199 if (row == null) {
200 throw new DataRetrievalFailureException("can't load program with code = " + programCode);
201 }
202
203 return toProgramDTO(Arrays.asList(row).iterator());
204 }
205
206
207 @Override
208 public List<ProgramDTO> getProgramsByCampaignId(Integer campaignId) {
209 Iterator<Object[]> rows = queryIterator("programsByCampaignId",
210 "campaignId", IntegerType.INSTANCE, campaignId);
211
212 List<ProgramDTO> result = new ArrayList<>();
213 while (rows.hasNext()) {
214 result.add(toProgramDTO(Arrays.asList(rows.next()).iterator()));
215 }
216
217 return result;
218 }
219
220
221 @Override
222 @SuppressWarnings("unchecked")
223 public List<ProgramDTO> getProgramsByCodes(List<String> programCodes) {
224
225 List<ProgramDTO> result = new ArrayList<>();
226 if (CollectionUtils.isEmpty(programCodes))
227 return result;
228
229 Iterator<Object[]> rows = createQuery("programsByCodes")
230 .setParameterList("programCodes", programCodes)
231 .iterate();
232
233 while (rows.hasNext()) {
234 result.add(toProgramDTO(Arrays.asList(rows.next()).iterator()));
235 }
236
237 return result;
238
239 }
240
241
242 @Override
243 public List<ProgramDTO> findProgramsByCodeAndName(List<String> statusCodes, String code, String name) {
244 Query query = createQuery("programsByCodeAndName",
245 "code", StringType.INSTANCE, code,
246 "name", StringType.INSTANCE, name);
247
248 Iterator<Object[]> rows = Daos.queryIteratorWithStatus(query, statusCodes);
249
250 List<ProgramDTO> result = new ArrayList<>();
251 while (rows.hasNext()) {
252 result.add(toProgramDTO(Arrays.asList(rows.next()).iterator()));
253 }
254
255 return result;
256 }
257
258
259 @Override
260 public List<ProgramDTO> findProgramsByLocationAndDate(List<String> statusCodes, int locationId, Date date) {
261 Query query = createQuery("programsByLocationAndDate",
262 "locationId", IntegerType.INSTANCE, locationId,
263 "date", DateType.INSTANCE, date);
264
265 Iterator<Object[]> rows = Daos.queryIteratorWithStatus(query, statusCodes);
266
267 List<ProgramDTO> result = new ArrayList<>();
268 while (rows.hasNext()) {
269 result.add(toProgramDTO(Arrays.asList(rows.next()).iterator()));
270 }
271
272 return result;
273 }
274
275
276 @Override
277 public boolean isProgramUsedByRuleList(String programCode) {
278 return executeMultipleCount(columnNamesByRulesTableNames, programCode);
279 }
280
281
282 @Override
283 public void saveProgram(ProgramDTO program) {
284 Assert.notNull(program);
285 Assert.notBlank(program.getCode());
286
287
288 Program target = get(program.getCode());
289 if (target == null) {
290 throw new DataRetrievalFailureException(String.format("Program with code %s doesn't exists in local database", program.getCode()));
291 }
292
293
294 programDTOToEntity(program, target);
295
296
297 getSession().update(target);
298
299
300 if (program.isLocationsLoaded() || !program.isLocationsEmpty()) {
301 if (program.isLocationsEmpty()) {
302
303 if (!target.getMonLocProgs().isEmpty()) {
304 target.getMonLocProgs().clear();
305 }
306 } else {
307
308 Multimap<Integer, MonLocProg> remainingMonLocProgs = ArrayListMultimap.create(
309 DaliBeans.<Integer, MonLocProg>populateByProperty(target.getMonLocProgs(), "monitoringLocation.monLocId")
310 );
311
312 for (LocationDTO locationDTO : program.getLocations()) {
313 boolean exists = remainingMonLocProgs.containsKey(locationDTO.getId());
314 if (!exists) {
315
316 MonLocProg monLocProg = MonLocProg.Factory.newInstance(target, load(MonitoringLocationImpl.class, locationDTO.getId()));
317 Integer monLocProgId = TemporaryDataHelper.getNewNegativeIdForTemporaryData(getSession(), monLocProg.getClass());
318 monLocProg.setMonLocProgId(monLocProgId);
319 getSession().save(monLocProg);
320 target.addMonLocProgs(monLocProg);
321 } else {
322 remainingMonLocProgs.removeAll(locationDTO.getId());
323 }
324 }
325
326
327 if (!remainingMonLocProgs.isEmpty()) {
328 target.getMonLocProgs().removeAll(remainingMonLocProgs.values());
329
330 deleteProgramLocations(program.getCode(), remainingMonLocProgs.keySet());
331
332
333 if (!program.isStrategiesEmpty()) {
334 for (StrategyDTO strategy : program.getStrategies()) {
335 if (!strategy.isAppliedStrategiesEmpty()) {
336 strategy.getAppliedStrategies().removeIf(lieu -> remainingMonLocProgs.containsKey(lieu.getId()));
337 }
338 }
339 }
340 }
341 }
342 }
343
344 getSession().flush();
345 getSession().clear();
346
347
348 if (program.isStrategiesLoaded() || !program.isStrategiesEmpty()) {
349 strategyDao.saveStrategies(program);
350
351
352 getSession().flush();
353 getSession().clear();
354 }
355 }
356
357
358 @Override
359 public void remove(String programCode) {
360 Assert.notBlank(programCode);
361
362
363 strategyDao.removeByProgramCode(programCode);
364
365
366 super.remove(programCode);
367
368 getSession().flush();
369 getSession().clear();
370 }
371
372
373 @Override
374 public void deleteProgramLocations(String programCode, Collection<Integer> monitoringLocationIds) {
375 Assert.notBlank(programCode);
376 if (monitoringLocationIds == null) return;
377 Set<Integer> idsToDelete = monitoringLocationIds.stream().filter(Objects::nonNull).collect(Collectors.toSet());
378 if (CollectionUtils.isEmpty(idsToDelete)) return;
379
380
381 Query query = createQuery("deleteMonitoringLocationsByProgramCode", "programCode", StringType.INSTANCE, programCode);
382 query.setParameterList("monitoringLocationIds", idsToDelete);
383 query.executeUpdate();
384
385
386 strategyDao.deleteAppliedStrategies(programCode, idsToDelete);
387
388 getSession().flush();
389 getSession().clear();
390 }
391
392
393
394 private ProgramDTO toProgramDTO(Iterator<Object> source) {
395 ProgramDTO result = DaliBeanFactory.newProgramDTO();
396
397
398 result.setCode((String) source.next());
399
400
401 result.setName((String) source.next());
402
403
404 result.setDescription((String) source.next());
405
406
407 result.setDepartmentHermetic(Daos.safeConvertToBoolean(source.next(), false));
408
409
410 result.setStatus(referentialDao.getStatusByCode((String) source.next()));
411
412 result.setComment((String) source.next());
413 result.setCreationDate(Daos.convertToDate(source.next()));
414 result.setUpdateDate(Daos.convertToDate(source.next()));
415
416 return result;
417 }
418
419 private void programDTOToEntity(final ProgramDTO source, final Program target) {
420 Assert.notNull(source);
421 Assert.notNull(target);
422
423 target.setProgNm(source.getName());
424 target.setProgDc(source.getComment());
425 target.setIsDepartmentHermetic(Daos.convertToString(source.isDepartmentHermetic()));
426
427
428 if (QuadrigeBeans.isLocalStatus(source.getStatus())) {
429 target.setUpdateDt(newUpdateTimestamp());
430 }
431
432
433 {
434 Map<ProgQuserProgPrivPK, ProgQuserProgPriv> quserProvPrivs = new HashMap<>();
435
436
437 if (CollectionUtils.isNotEmpty(source.getManagerPersons())) {
438 for (PersonDTO manager : source.getManagerPersons()) {
439 ProgQuserProgPriv progQuserProgPriv = loadProgQuserProgPriv(target, manager.getId(), ProgramPrivilegeIds.MANAGER);
440 quserProvPrivs.put(progQuserProgPriv.getProgQuserProgPrivPk(), progQuserProgPriv);
441 }
442 }
443
444
445 if (CollectionUtils.isNotEmpty(source.getRecorderPersons())) {
446 for (PersonDTO manager : source.getRecorderPersons()) {
447 ProgQuserProgPriv progQuserProgPriv = loadProgQuserProgPriv(target, manager.getId(), ProgramPrivilegeIds.RECORDER);
448 quserProvPrivs.put(progQuserProgPriv.getProgQuserProgPrivPk(), progQuserProgPriv);
449 }
450 }
451
452
453 if (CollectionUtils.isNotEmpty(target.getProgQuserProgPrivs())) {
454 for (ProgQuserProgPriv quserProgPriv : target.getProgQuserProgPrivs()) {
455 ProgramPrivilege programPrivilege = quserProgPriv.getProgQuserProgPrivPk().getProgramPrivilege();
456 if (Objects.equals(programPrivilege.getProgPrivId(), ProgramPrivilegeIds.VIEWER.getValue())) {
457 quserProvPrivs.put(quserProgPriv.getProgQuserProgPrivPk(), quserProgPriv);
458 }
459 }
460 }
461
462
463 if (MapUtils.isEmpty(quserProvPrivs)) {
464 if (CollectionUtils.isNotEmpty(target.getProgQuserProgPrivs())) {
465 target.getProgQuserProgPrivs().clear();
466 }
467 } else {
468 target.getProgQuserProgPrivs().clear();
469 target.getProgQuserProgPrivs().addAll(quserProvPrivs.values());
470 }
471 }
472
473
474 {
475 Map<ProgDepProgPrivPK, ProgDepProgPriv> depProvPrivs = new HashMap<>();
476
477
478
479 if (CollectionUtils.isNotEmpty(target.getProgDepProgPrivs())) {
480 for (ProgDepProgPriv depProgPriv : target.getProgDepProgPrivs()) {
481 ProgramPrivilege programPrivilege = depProgPriv.getProgDepProgPrivPk().getProgramPrivilege();
482 if (Objects.equals(programPrivilege.getProgPrivId(), ProgramPrivilegeIds.MANAGER.getValue())) {
483 depProvPrivs.put(depProgPriv.getProgDepProgPrivPk(), depProgPriv);
484 }
485 }
486 }
487
488
489 if (CollectionUtils.isNotEmpty(source.getRecorderDepartments())) {
490 for (DepartmentDTO departmentDTO : source.getRecorderDepartments()) {
491 ProgDepProgPriv progDepProgPriv = loadProgDepProgPriv(target, departmentDTO.getId(), ProgramPrivilegeIds.RECORDER);
492 depProvPrivs.put(progDepProgPriv.getProgDepProgPrivPk(), progDepProgPriv);
493 }
494 }
495
496
497 if (CollectionUtils.isNotEmpty(target.getProgDepProgPrivs())) {
498 for (ProgDepProgPriv depProgPriv : target.getProgDepProgPrivs()) {
499 ProgramPrivilege programPrivilege = depProgPriv.getProgDepProgPrivPk().getProgramPrivilege();
500 if (Objects.equals(programPrivilege.getProgPrivId(), ProgramPrivilegeIds.VIEWER.getValue())) {
501 depProvPrivs.put(depProgPriv.getProgDepProgPrivPk(), depProgPriv);
502 }
503 }
504 }
505
506
507 if (MapUtils.isEmpty(depProvPrivs)) {
508 if (CollectionUtils.isNotEmpty(target.getProgDepProgPrivs())) {
509 target.getProgDepProgPrivs().clear();
510 }
511 } else {
512 target.getProgDepProgPrivs().clear();
513 target.getProgDepProgPrivs().addAll(depProvPrivs.values());
514 }
515 }
516
517 }
518
519
520
521
522
523
524 private ProgQuserProgPriv loadProgQuserProgPriv(Program program, int quserId, ProgramPrivilegeIds programPrivilegeId) {
525 ProgQuserProgPrivPK pk = new ProgQuserProgPrivPK();
526
527 pk.setProgram((ProgramImpl) program);
528 pk.setQuser(load(QuserImpl.class, quserId));
529 pk.setProgramPrivilege(load(ProgramPrivilegeImpl.class, programPrivilegeId.getValue()));
530
531 ProgQuserProgPriv target = progQuserProgPrivDao.get(pk);
532 if (target == null) {
533 target = ProgQuserProgPriv.Factory.newInstance();
534 target.setProgQuserProgPrivPk(pk);
535 }
536 return target;
537 }
538
539 private ProgDepProgPriv loadProgDepProgPriv(Program program, int depId, ProgramPrivilegeIds programPrivilegeId) {
540 ProgDepProgPrivPK pk = new ProgDepProgPrivPK();
541
542 pk.setProgram((ProgramImpl) program);
543 pk.setDepartment(load(DepartmentImpl.class, depId));
544 pk.setProgramPrivilege(load(ProgramPrivilegeImpl.class, programPrivilegeId.getValue()));
545
546 ProgDepProgPriv target = progDepProgPrivDao.get(pk);
547 if (target == null) {
548 target = ProgDepProgPriv.Factory.newInstance();
549 target.setProgDepProgPrivPk(pk);
550 }
551 return target;
552 }
553 }