1 package fr.ifremer.dali.dao.system.filter;
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 com.google.common.collect.Maps;
28 import com.google.common.collect.Sets;
29 import fr.ifremer.dali.config.DaliConfiguration;
30 import fr.ifremer.dali.dao.administration.user.DaliQuserDao;
31 import fr.ifremer.dali.dao.technical.Daos;
32 import fr.ifremer.dali.dto.DaliBeanFactory;
33 import fr.ifremer.dali.dto.DaliBeans;
34 import fr.ifremer.dali.dto.configuration.filter.FilterDTO;
35 import fr.ifremer.dali.dto.enums.ExtractionFilterTypeValues;
36 import fr.ifremer.dali.dto.enums.FilterTypeValues;
37 import fr.ifremer.dali.service.DaliBusinessException;
38 import fr.ifremer.quadrige3.core.dao.system.filter.*;
39 import fr.ifremer.quadrige3.core.dao.technical.Assert;
40 import fr.ifremer.quadrige3.core.service.technical.CacheService;
41 import org.apache.commons.collections4.CollectionUtils;
42 import org.apache.commons.lang3.StringUtils;
43 import org.hibernate.Query;
44 import org.hibernate.Session;
45 import org.hibernate.SessionFactory;
46 import org.hibernate.type.IntegerType;
47 import org.hibernate.type.StringType;
48 import org.springframework.beans.factory.InitializingBean;
49 import org.springframework.beans.factory.annotation.Autowired;
50 import org.springframework.dao.DataIntegrityViolationException;
51 import org.springframework.dao.DataRetrievalFailureException;
52 import org.springframework.stereotype.Repository;
53
54 import javax.annotation.Resource;
55 import java.util.*;
56
57 import static org.nuiton.i18n.I18n.t;
58
59
60
61
62
63
64 @Repository("daliFilterDao")
65 public class DaliFilterDaoImpl extends FilterDaoImpl implements DaliFilterDao, InitializingBean {
66
67 @Resource(name = "filterTypeDao")
68 private FilterTypeDao filterTypeDao;
69
70 @Resource(name = "filterCriteriaTypeDao")
71 private FilterCriteriaTypeDao filterCriteriaTypeDao;
72
73 @Resource(name = "filterOperatorTypeDao")
74 private FilterOperatorTypeDao filterOperatorTypeDao;
75
76 @Resource(name = "daliQuserDao")
77 private DaliQuserDao quserDao;
78
79 @Resource
80 protected CacheService cacheService;
81
82 @Resource
83 protected DaliConfiguration config;
84
85
86
87
88
89
90 @Autowired
91 public DaliFilterDaoImpl(SessionFactory sessionFactory) {
92 super(sessionFactory);
93 }
94
95
96 @Override
97 public void afterPropertiesSet() {
98
99
100 checkDbConstants();
101
102 }
103
104
105 @Override
106 public FilterDTO getFilterById(Integer filterId) {
107 Assert.notNull(filterId);
108
109
110 Filter f = get(filterId);
111
112 if (f == null) {
113 return null;
114 }
115
116 Integer filterTypeId = f.getFilterType().getFilterTypeId();
117 FilterTypeValues filterType = FilterTypeValues.getFilterType(filterTypeId);
118 ExtractionFilterTypeValues extractionFilterType = ExtractionFilterTypeValues.getExtractionFilterType(filterTypeId);
119
120 if (filterType == null && extractionFilterType == null) {
121 throw new DataRetrievalFailureException("Cannot determine type of filter (id=" + filterId + ", type=" + filterTypeId + ")");
122 }
123
124 return initFilterDTO(filterId, f.getFilterNm(), filterTypeId);
125 }
126
127
128 @Override
129 public List<FilterDTO> getAllContextFilters(Integer contextId, Integer filterTypeId) {
130
131 List<FilterDTO> result = Lists.newArrayList();
132 if (contextId == null && filterTypeId == null) {
133 return result;
134 }
135
136 Iterator<Object[]> it;
137
138 if (filterTypeId == null) {
139 it = queryIterator("filtersByContext",
140 "contextId", IntegerType.INSTANCE, contextId);
141
142 } else if (contextId == null) {
143 it = queryIterator("allContextFiltersByType",
144 "filterTypeId", IntegerType.INSTANCE, filterTypeId);
145
146 } else {
147 it = queryIterator("allFiltersByContextAndType",
148 "contextId", IntegerType.INSTANCE, contextId,
149 "filterTypeId", IntegerType.INSTANCE, filterTypeId);
150 }
151
152 while (it.hasNext()) {
153 Object[] row = it.next();
154 result.add(toFilterDTO(Arrays.asList(row).iterator()));
155 }
156 return result;
157 }
158
159
160 @Override
161 public List<FilterDTO> getAllExtractionFilters(Integer filterTypeId) {
162 List<FilterDTO> result = Lists.newArrayList();
163 if (filterTypeId != null) {
164 Iterator<Object[]> it = queryIterator("allExtractionFiltersByType",
165 "filterTypeId", IntegerType.INSTANCE, filterTypeId);
166
167 while (it.hasNext()) {
168 Object[] row = it.next();
169 FilterDTO filter = toFilterDTO(Arrays.asList(row).iterator());
170 result.add(filter);
171 }
172 }
173 return result;
174 }
175
176
177
178
179
180
181
182 @Override
183 public Filter saveFilter(FilterDTO filter, int quserId) {
184
185 Assert.notNull(filter);
186 Assert.notNull(filter.getFilterTypeId());
187
188 Filter target;
189 boolean isExtractorFilter;
190
191 FilterTypeValues filterType = FilterTypeValues.getFilterType(filter.getFilterTypeId());
192 ExtractionFilterTypeValues extractionFilterType = ExtractionFilterTypeValues.getExtractionFilterType(filter.getFilterTypeId());
193
194 if (filterType == null && extractionFilterType == null) {
195 throw new DaliBusinessException(t("dali.error.referential.missing", "FILTER_TYPE"));
196 }
197
198
199 isExtractorFilter = filterType == null;
200
201 Long filterCount = queryCount("countFiltersByNameAndType",
202 "filterName", StringType.INSTANCE, filter.getName(),
203 "filterTypeId", IntegerType.INSTANCE, filter.getFilterTypeId());
204
205 if (filter.getId() == null) {
206
207 if (filterCount > 0) {
208 throw new DataIntegrityViolationException("A filter of type " + filterType + " already exists with the name: " + filter.getName());
209 } else {
210
211 target = Filter.Factory.newInstance(quserDao.get(quserId), filterTypeDao.get(filter.getFilterTypeId()));
212 target = create(target);
213
214 filter.setId(target.getFilterId());
215
216
217 target.setFilterNm(filter.getName());
218
219 target.setFilterIsExtract(Daos.convertToString(isExtractorFilter));
220 }
221
222 } else {
223
224 target = get(filter.getId());
225
226 if (StringUtils.isNotEmpty(filter.getName()) && !filter.getName().equals(target.getFilterNm())) {
227
228 if (filterCount > 0) {
229 throw new DataIntegrityViolationException("A filter of type " + filterType + " already exists with the name: " + filter.getName());
230 } else {
231
232 target.setFilterNm(filter.getName());
233 }
234 }
235
236 }
237
238 int filterOperatorTypeId = -1;
239 int filterCriteriaTypeId = -1;
240
241 List<String> criteriaValues = Lists.newArrayList();
242
243
244 if (filter.isFilterLoaded()) {
245
246
247 if (isExtractorFilter) {
248
249 switch (extractionFilterType) {
250 case ORDER_ITEM_TYPE:
251 filterCriteriaTypeId = FilterCriteriaTypeId.ORDER_ITEM_TYPE_CODE.getValue();
252 filterOperatorTypeId = FilterOperatorTypeId.TEXT_EQUAL.getValue();
253 criteriaValues.addAll(DaliBeans.transformCollection(filter.getElements(), DaliBeans.GET_CODE));
254 break;
255 }
256
257 } else {
258
259 switch (filterType) {
260 case LOCATION:
261 filterCriteriaTypeId = FilterCriteriaTypeId.MONITORING_LOCATION_ID.getValue();
262 filterOperatorTypeId = FilterOperatorTypeId.MONITORING_LOCATION_IN.getValue();
263 criteriaValues.addAll(DaliBeans.transformCollection(filter.getElements(), DaliBeans.GET_ID_STRING));
264 break;
265 case PROGRAM:
266 filterCriteriaTypeId = FilterCriteriaTypeId.PROGRAM_CODE.getValue();
267 filterOperatorTypeId = FilterOperatorTypeId.PROGRAM_IN.getValue();
268 criteriaValues.addAll(DaliBeans.transformCollection(filter.getElements(), DaliBeans.GET_CODE));
269 break;
270 case CAMPAIGN:
271 filterCriteriaTypeId = FilterCriteriaTypeId.CAMPAIGN_ID.getValue();
272 filterOperatorTypeId = FilterOperatorTypeId.CAMPAIGN_IN.getValue();
273 criteriaValues.addAll(DaliBeans.transformCollection(filter.getElements(), DaliBeans.GET_ID_STRING));
274 break;
275 case PMFM:
276 filterCriteriaTypeId = FilterCriteriaTypeId.PMFM_ID.getValue();
277 filterOperatorTypeId = FilterOperatorTypeId.PMFM_IN.getValue();
278 criteriaValues.addAll(DaliBeans.transformCollection(filter.getElements(), DaliBeans.GET_ID_STRING));
279 break;
280 case DEPARTMENT:
281 filterCriteriaTypeId = FilterCriteriaTypeId.DEPARTMENT_ID.getValue();
282 filterOperatorTypeId = FilterOperatorTypeId.DEPARTMENT_IN.getValue();
283 criteriaValues.addAll(DaliBeans.transformCollection(filter.getElements(), DaliBeans.GET_ID_STRING));
284 break;
285 case TAXON:
286 filterCriteriaTypeId = FilterCriteriaTypeId.TAXON_NAME_ID.getValue();
287 filterOperatorTypeId = FilterOperatorTypeId.TAXON_NAME_IN.getValue();
288 criteriaValues.addAll(DaliBeans.transformCollection(filter.getElements(), DaliBeans.GET_ID_STRING));
289 break;
290 case TAXON_GROUP:
291 filterCriteriaTypeId = FilterCriteriaTypeId.TAXON_GROUP_ID.getValue();
292 filterOperatorTypeId = FilterOperatorTypeId.TAXON_GROUP_IN.getValue();
293 criteriaValues.addAll(DaliBeans.transformCollection(filter.getElements(), DaliBeans.GET_ID_STRING));
294 break;
295 case ANALYSIS_INSTRUMENT:
296 filterCriteriaTypeId = FilterCriteriaTypeId.ANALYSIS_INSTRUMENT_ID.getValue();
297 filterOperatorTypeId = FilterOperatorTypeId.ANALYSIS_INSTRUMENT_IN.getValue();
298 criteriaValues.addAll(DaliBeans.transformCollection(filter.getElements(), DaliBeans.GET_ID_STRING));
299 break;
300 case SAMPLING_EQUIPMENT:
301 filterCriteriaTypeId = FilterCriteriaTypeId.SAMPLING_EQUIPMENT_ID.getValue();
302 filterOperatorTypeId = FilterOperatorTypeId.SAMPLING_EQUIPMENT_IN.getValue();
303 criteriaValues.addAll(DaliBeans.transformCollection(filter.getElements(), DaliBeans.GET_ID_STRING));
304 break;
305 case USER:
306 filterCriteriaTypeId = FilterCriteriaTypeId.QUSER_ID.getValue();
307 filterOperatorTypeId = FilterOperatorTypeId.QUSER_IN.getValue();
308 criteriaValues.addAll(DaliBeans.transformCollection(filter.getElements(), DaliBeans.GET_ID_STRING));
309 }
310 }
311
312 if (filterCriteriaTypeId < 0) {
313 throw new DaliBusinessException(t("dali.error.referential.missing", "FILTER_CRITERIA_TYPE"));
314 }
315 if (filterOperatorTypeId < 0) {
316 throw new DaliBusinessException(t("dali.error.referential.missing", "FILTER_OPERATOR_TYPE"));
317 }
318
319
320 FilterBlock fb;
321 Collection<FilterBlock> fbs = target.getFilterBlocks();
322
323 if (criteriaValues.isEmpty()) {
324 if (CollectionUtils.isNotEmpty(fbs)) {
325
326 FilterCriteria existingFc = getFilterCriteria(target.getFilterId(), filterCriteriaTypeId, filterOperatorTypeId);
327
328
329 if (existingFc != null) {
330
331 if (existingFc.getFilterBlock().getFilterCriterias().size() < 2) {
332 fbs.remove(existingFc.getFilterBlock());
333 getSession().delete(existingFc.getFilterBlock());
334
335 } else {
336 getSession().delete(existingFc);
337 }
338 }
339
340 }
341
342 } else {
343
344 FilterCriteria fc = null;
345
346
347 Map<String, FilterCriteriaValue> fcvs = Maps.newHashMap();
348
349 if (CollectionUtils.isEmpty(fbs)) {
350
351 fb = FilterBlock.Factory.newInstance(target);
352
353 getSession().save(fb);
354
355 target.addFilterBlocks(fb);
356
357 } else {
358
359 fb = fbs.iterator().next();
360
361
362 fc = getFilterCriteria(target.getFilterId(), filterCriteriaTypeId, filterOperatorTypeId);
363
364 if (fc != null) {
365
366 for (FilterCriteriaValue fcv : fc.getFilterCriteriaValues()) {
367
368 fcvs.put(fcv.getFilterCritValueNm(), fcv);
369
370 }
371 }
372 }
373
374 if (fc == null) {
375
376
377
378 FilterCriteriaType fct = filterCriteriaTypeDao.get(filterCriteriaTypeId);
379
380 FilterOperatorType fot = filterOperatorTypeDao.get(filterOperatorTypeId);
381
382 fc = FilterCriteria.Factory.newInstance(fct, fot, fb);
383 fb.addFilterCriterias(fc);
384 }
385
386 Collection<FilterCriteriaValue> filteredElements = fc.getFilterCriteriaValues();
387 if (filteredElements == null) {
388 filteredElements = Sets.newHashSet();
389 fc.setFilterCriteriaValues(filteredElements);
390 }
391
392
393 filteredElements.clear();
394
395 for (String objectId : criteriaValues) {
396 if (fcvs.keySet().contains(objectId)) {
397 filteredElements.add(fcvs.remove(objectId));
398 } else {
399
400 FilterCriteriaValue newFcv = FilterCriteriaValue.Factory.newInstance(objectId, fc);
401
402 filteredElements.add(newFcv);
403 }
404 }
405
406
407 getSession().saveOrUpdate(fc);
408
409
410 for (String objectIdToRemove : fcvs.keySet()) {
411
412 getSession().delete(fcvs.get(objectIdToRemove));
413 }
414 }
415 }
416
417 update(target);
418 getSession().flush();
419 getSession().clear();
420
421 return target;
422 }
423
424
425 @Override
426 public void deleteFilters(List<Integer> filterIds) {
427 if (CollectionUtils.isEmpty(filterIds)) {
428 return;
429 }
430
431 createQuery("deleteFilters").setParameterList("filterIds", filterIds).executeUpdate();
432 getSession().flush();
433 getSession().clear();
434 }
435
436
437 @Override
438 public boolean checkFiltersNotUsedInContext(List<Integer> filterIds) {
439
440 Query q = createQuery("countContextsUsingFilters").setParameterList("filterIds", filterIds);
441 Long count = (Long) q.uniqueResult();
442
443 return count == 0;
444 }
445
446
447 @Override
448 public List<String> getFilteredElementsByFilterId(Integer filterId) {
449 return queryListTyped("filteredElementsByFilterId", "filterId", IntegerType.INSTANCE, filterId);
450 }
451
452
453
454 private void checkDbConstants() {
455
456 if (config.isDbCheckConstantsEnable()) {
457 Session session = getSessionFactory().openSession();
458 try {
459 Assert.notNull(session.get(FilterTypeImpl.class, FilterTypeValues.LOCATION.getFilterTypeId()));
460 Assert.notNull(session.get(FilterTypeImpl.class, FilterTypeValues.PROGRAM.getFilterTypeId()));
461 Assert.notNull(session.get(FilterTypeImpl.class, FilterTypeValues.CAMPAIGN.getFilterTypeId()));
462 Assert.notNull(session.get(FilterTypeImpl.class, FilterTypeValues.DEPARTMENT.getFilterTypeId()));
463 Assert.notNull(session.get(FilterTypeImpl.class, FilterTypeValues.PMFM.getFilterTypeId()));
464 Assert.notNull(session.get(FilterTypeImpl.class, FilterTypeValues.TAXON.getFilterTypeId()));
465 Assert.notNull(session.get(FilterTypeImpl.class, FilterTypeValues.TAXON_GROUP.getFilterTypeId()));
466 Assert.notNull(session.get(FilterTypeImpl.class, FilterTypeValues.ANALYSIS_INSTRUMENT.getFilterTypeId()));
467 Assert.notNull(session.get(FilterTypeImpl.class, FilterTypeValues.SAMPLING_EQUIPMENT.getFilterTypeId()));
468 Assert.notNull(session.get(FilterTypeImpl.class, FilterTypeValues.USER.getFilterTypeId()));
469 Assert.notNull(session.get(FilterTypeImpl.class, ExtractionFilterTypeValues.ORDER_ITEM_TYPE.getFilterTypeId()));
470 Assert.notNull(session.get(FilterCriteriaTypeImpl.class, FilterCriteriaTypeId.MONITORING_LOCATION_ID.getValue()));
471 Assert.notNull(session.get(FilterCriteriaTypeImpl.class, FilterCriteriaTypeId.PROGRAM_CODE.getValue()));
472 Assert.notNull(session.get(FilterCriteriaTypeImpl.class, FilterCriteriaTypeId.CAMPAIGN_ID.getValue()));
473 Assert.notNull(session.get(FilterCriteriaTypeImpl.class, FilterCriteriaTypeId.DEPARTMENT_ID.getValue()));
474 Assert.notNull(session.get(FilterCriteriaTypeImpl.class, FilterCriteriaTypeId.PMFM_ID.getValue()));
475 Assert.notNull(session.get(FilterCriteriaTypeImpl.class, FilterCriteriaTypeId.TAXON_NAME_ID.getValue()));
476 Assert.notNull(session.get(FilterCriteriaTypeImpl.class, FilterCriteriaTypeId.TAXON_GROUP_ID.getValue()));
477 Assert.notNull(session.get(FilterCriteriaTypeImpl.class, FilterCriteriaTypeId.ANALYSIS_INSTRUMENT_ID.getValue()));
478 Assert.notNull(session.get(FilterCriteriaTypeImpl.class, FilterCriteriaTypeId.SAMPLING_EQUIPMENT_ID.getValue()));
479 Assert.notNull(session.get(FilterCriteriaTypeImpl.class, FilterCriteriaTypeId.QUSER_ID.getValue()));
480 Assert.notNull(session.get(FilterCriteriaTypeImpl.class, FilterCriteriaTypeId.ORDER_ITEM_TYPE_CODE.getValue()));
481 Assert.notNull(session.get(FilterOperatorTypeImpl.class, FilterOperatorTypeId.MONITORING_LOCATION_IN.getValue()));
482 Assert.notNull(session.get(FilterOperatorTypeImpl.class, FilterOperatorTypeId.PROGRAM_IN.getValue()));
483 Assert.notNull(session.get(FilterOperatorTypeImpl.class, FilterOperatorTypeId.CAMPAIGN_IN.getValue()));
484 Assert.notNull(session.get(FilterOperatorTypeImpl.class, FilterOperatorTypeId.DEPARTMENT_IN.getValue()));
485 Assert.notNull(session.get(FilterOperatorTypeImpl.class, FilterOperatorTypeId.PMFM_IN.getValue()));
486 Assert.notNull(session.get(FilterOperatorTypeImpl.class, FilterOperatorTypeId.TAXON_NAME_IN.getValue()));
487 Assert.notNull(session.get(FilterOperatorTypeImpl.class, FilterOperatorTypeId.TAXON_GROUP_IN.getValue()));
488 Assert.notNull(session.get(FilterOperatorTypeImpl.class, FilterOperatorTypeId.ANALYSIS_INSTRUMENT_IN.getValue()));
489 Assert.notNull(session.get(FilterOperatorTypeImpl.class, FilterOperatorTypeId.SAMPLING_EQUIPMENT_IN.getValue()));
490 Assert.notNull(session.get(FilterOperatorTypeImpl.class, FilterOperatorTypeId.QUSER_IN.getValue()));
491 Assert.notNull(session.get(FilterOperatorTypeImpl.class, FilterOperatorTypeId.TEXT_EQUAL.getValue()));
492
493 } finally {
494 Daos.closeSilently(session);
495 }
496
497 }
498 }
499
500 private FilterCriteria getFilterCriteria(Integer filterId, Integer filterCriteriaTypeId, Integer filterOperatorTypeId) {
501 return queryUniqueTyped("filterCriteriaByFilterId",
502 "filterId", IntegerType.INSTANCE, filterId,
503 "filterCriteriaTypeId", IntegerType.INSTANCE, filterCriteriaTypeId,
504 "filterOperatorTypeId", IntegerType.INSTANCE, filterOperatorTypeId);
505 }
506
507 private FilterDTO initFilterDTO(Integer filterId, String filterName, Integer filterTypeId) {
508 FilterDTO bean = DaliBeanFactory.newFilterDTO();
509
510 bean.setId(filterId);
511 bean.setName(filterName);
512 bean.setFilterTypeId(filterTypeId);
513
514 return bean;
515 }
516
517 private FilterDTO toFilterDTO(Iterator<Object> source) {
518 FilterDTO target = DaliBeanFactory.newFilterDTO();
519
520 target.setId((Integer) source.next());
521 target.setName((String) source.next());
522 target.setFilterTypeId((Integer) source.next());
523
524 return target;
525 }
526
527 }