1 package fr.ifremer.reefdb.service.rulescontrol;
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.base.Joiner;
27 import com.google.common.collect.HashMultimap;
28 import com.google.common.collect.Multimap;
29 import fr.ifremer.quadrige3.core.dao.system.rule.RuleListDao;
30 import fr.ifremer.quadrige3.core.dao.technical.Assert;
31 import fr.ifremer.quadrige3.core.dao.technical.Dates;
32 import fr.ifremer.quadrige3.core.dao.technical.factorization.pmfm.AllowedQualitativeValuesMap;
33 import fr.ifremer.quadrige3.core.security.AuthenticationInfo;
34 import fr.ifremer.quadrige3.core.vo.system.rule.RuleListVO;
35 import fr.ifremer.quadrige3.synchro.service.client.SynchroRestClientService;
36 import fr.ifremer.quadrige3.ui.core.dto.referential.BaseReferentialDTO;
37 import fr.ifremer.reefdb.config.ReefDbConfiguration;
38 import fr.ifremer.reefdb.dao.system.rule.ReefDbRuleDao;
39 import fr.ifremer.reefdb.dao.system.rule.ReefDbRuleListDao;
40 import fr.ifremer.reefdb.dto.ReefDbBeanFactory;
41 import fr.ifremer.reefdb.dto.ReefDbBeans;
42 import fr.ifremer.reefdb.dto.configuration.control.*;
43 import fr.ifremer.reefdb.dto.data.measurement.MeasurementDTO;
44 import fr.ifremer.reefdb.dto.data.survey.SurveyDTO;
45 import fr.ifremer.reefdb.dto.enums.ControlElementValues;
46 import fr.ifremer.reefdb.dto.enums.ControlFeatureMeasurementValues;
47 import fr.ifremer.reefdb.dto.enums.ControlFunctionValues;
48 import fr.ifremer.reefdb.dto.referential.pmfm.QualitativeValueDTO;
49 import fr.ifremer.reefdb.service.ReefDbDataContext;
50 import fr.ifremer.reefdb.service.referential.ReferentialService;
51 import org.apache.commons.collections4.CollectionUtils;
52 import org.apache.commons.lang3.StringUtils;
53 import org.apache.commons.lang3.mutable.MutableInt;
54 import org.apache.commons.logging.Log;
55 import org.apache.commons.logging.LogFactory;
56 import org.springframework.beans.factory.annotation.Autowired;
57 import org.springframework.stereotype.Service;
58
59 import javax.annotation.Resource;
60 import java.math.BigDecimal;
61 import java.util.*;
62 import java.util.stream.Collectors;
63
64
65
66
67 @Service("reefDbRuleListService")
68 public class RuleListServiceImpl implements RuleListService {
69
70 private static final Log LOG = LogFactory.getLog(RuleListServiceImpl.class);
71
72 @Resource(name = "reefDbRuleListDao")
73 protected ReefDbRuleListDao ruleListDao;
74 @Resource(name = "reefDbRuleDao")
75 protected ReefDbRuleDao ruleDao;
76 @Resource(name = "reefdbDataContext")
77 protected ReefDbDataContext dataContext;
78 @Resource(name = "synchroRestClientService")
79 protected SynchroRestClientService synchroRestClientService;
80 @Resource(name = "reefdbReferentialService")
81 protected ReferentialService referentialService;
82 @Resource(name = "reefDbControlRuleService")
83 protected ControlRuleService controlRuleService;
84 @Autowired
85 protected ReefDbConfiguration configuration;
86
87
88
89
90 @Override
91 public RuleListDTO getRuleList(String ruleListCode) {
92 Assert.notBlank(ruleListCode);
93 return ruleListDao.getRuleList(ruleListCode);
94 }
95
96
97
98
99 @Override
100 public List<RuleListDTO> getRuleLists() {
101 return ruleListDao.getRuleLists();
102 }
103
104 @Override
105 public List<RuleListDTO> getRuleListsForProgram(String programCode) {
106 return ruleListDao.getRuleListsForProgram(programCode);
107 }
108
109 @Override
110 public boolean ruleListCodeExists(String ruleListCode) {
111 return ruleListDao.ruleListExists(ruleListCode);
112 }
113
114
115
116
117 @Override
118 public void saveRuleLists(AuthenticationInfo authenticationInfo, List<? extends RuleListDTO> ruleLists) {
119
120 Assert.notNull(ruleLists);
121
122
123 List<RuleListDTO> dirtyRuleList = ruleLists.stream().filter(RuleListDTO::isDirty).collect(Collectors.toList());
124
125
126 if (CollectionUtils.isEmpty(dirtyRuleList)) return;
127
128
129 Set<String> ruleListCodes = dirtyRuleList.stream().map(ruleList -> {
130
131
132 Assert.notBlank(ruleList.getCode());
133 Assert.notEmpty(ruleList.getPrograms());
134
135
136 ruleListDao.saveRuleList(ruleList, dataContext.getRecorderPersonId());
137
138 return ruleList.getCode();
139
140 }).collect(Collectors.toSet());
141
142
143 saveRuleListsOnServer(authenticationInfo, ruleListCodes);
144
145
146 dirtyRuleList.forEach(ruleList -> {
147 ruleList.setDirty(false);
148 ruleList.setNewCode(false);
149 ruleList.getControlRules().forEach(controlRule -> controlRule.setNewCode(false));
150 });
151 }
152
153 private void saveRuleListsOnServer(AuthenticationInfo authenticationInfo, Set<String> ruleListCodes) {
154
155 if (CollectionUtils.isEmpty(ruleListCodes)) return;
156
157 if (LOG.isDebugEnabled()) {
158 LOG.debug(String.format("Sending rule lists [%s] to server", Joiner.on(',').join(ruleListCodes)));
159 }
160
161
162 List<RuleListVO> ruleListToSend = ruleListCodes.stream()
163 .map(ruleListCode -> (RuleListVO) ruleListDao.load(RuleListDao.TRANSFORM_RULELISTVO, ruleListCode))
164 .filter(ruleListVO -> !ReefDbBeans.isLocalStatus(ruleListVO.getStatusCd()))
165 .collect(Collectors.toList());
166
167 if (ruleListToSend.isEmpty()) return;
168
169
170 List<RuleListVO> savedRuleLists = synchroRestClientService.saveRuleLists(authenticationInfo, ruleListToSend);
171
172 if (LOG.isDebugEnabled()) {
173 LOG.debug(String.format("Saving rule lists [%s] from server response", Joiner.on(',').join(savedRuleLists.stream().map(RuleListVO::getRuleListCd).collect(Collectors.toList()))));
174 }
175
176
177 for (RuleListVO savedRuleList : savedRuleLists) {
178 ruleListDao.save(savedRuleList);
179 }
180
181 }
182
183
184
185
186 @Override
187 public void deleteRuleLists(AuthenticationInfo authenticationInfo, List<RuleListDTO> ruleLists) {
188 if (CollectionUtils.isEmpty(ruleLists)) return;
189
190
191 ruleLists.forEach(ruleList -> ruleListDao.remove(ruleList.getCode()));
192
193
194 deleteRuleListsOnServer(authenticationInfo, ruleLists);
195 }
196
197 private void deleteRuleListsOnServer(AuthenticationInfo authenticationInfo, List<RuleListDTO> ruleLists) {
198
199 if (LOG.isDebugEnabled()) {
200 LOG.debug(String.format("Delete rule lists [%s] from server", Joiner.on(',').join(ruleLists.stream().map(RuleListDTO::getCode).collect(Collectors.toList()))));
201 }
202
203
204 Set<RuleListDTO> ruleListsToDelete = ruleLists.stream()
205 .filter(ruleList -> {
206 if (ReefDbBeans.isLocalStatus(ruleList.getStatus())) return false;
207 if (synchroRestClientService.getRuleListByCode(authenticationInfo, ruleList.getCode()) != null) {
208 return true;
209 } else {
210 if (LOG.isDebugEnabled()) {
211 LOG.debug(String.format("Rule List [%s] doesn't exists on server, skip it", ruleList));
212 }
213 return false;
214 }
215 })
216 .collect(Collectors.toSet());
217
218 if (CollectionUtils.isNotEmpty(ruleListsToDelete)) {
219
220 List<String> ruleListCodesToDelete = ruleListsToDelete.stream().map(RuleListDTO::getCode).collect(Collectors.toList());
221
222
223 synchroRestClientService.deleteRuleLists(authenticationInfo, ruleListCodesToDelete);
224
225 if (LOG.isDebugEnabled()) {
226 LOG.debug(String.format("Rule lists [%s] deleted from server", Joiner.on(',').join(ruleListCodesToDelete)));
227 }
228 }
229 }
230
231
232
233
234 @Override
235 public RuleListDTO duplicateRuleList(RuleListDTO ruleList, String newCode, boolean isDuplicateRulesEnabled) {
236
237 RuleListDTO duplicatedRuleList = ReefDbBeans.clone(ruleList);
238
239 duplicatedRuleList.setCode(newCode);
240 duplicatedRuleList.setNewCode(true);
241 duplicatedRuleList.setStatus(ruleList.getStatus());
242 duplicatedRuleList.setDepartments(ReefDbBeans.clone(ruleList.getDepartments()));
243 duplicatedRuleList.setPrograms(ReefDbBeans.clone(ruleList.getPrograms()));
244 duplicatedRuleList.setErrors(new ArrayList<>());
245
246 duplicatedRuleList.setControlRules(new ArrayList<>());
247 if (isDuplicateRulesEnabled && CollectionUtils.isNotEmpty(ruleList.getControlRules())) {
248 MutableInt suffixIndex = getUniqueMutableIndex();
249 for (ControlRuleDTO controlRule : ruleList.getControlRules()) {
250 ControlRuleDTO duplicatedControlRule = duplicateControlRule(controlRule, duplicatedRuleList);
251
252 if (!controlRule.isPreconditionsEmpty()) {
253 duplicatePreconditions(controlRule, duplicatedControlRule, suffixIndex);
254 }
255 duplicatedRuleList.addControlRules(duplicatedControlRule);
256 }
257 }
258
259 return duplicatedRuleList;
260 }
261
262 private ControlRuleDTO duplicateControlRule(ControlRuleDTO controlRule, RuleListDTO ruleList) {
263
264 ControlRuleDTO duplicatedControlRule = ReefDbBeans.clone(controlRule);
265
266 duplicatedControlRule.setCode(ruleList != null ? getNextRuleCode(ruleList) : null);
267 duplicatedControlRule.setNewCode(true);
268 duplicatedControlRule.setErrors(null);
269 duplicatedControlRule.setPreconditions(null);
270 duplicatedControlRule.setRulePmfms(null);
271
272
273 for (RulePmfmDTO rulePmfm : controlRule.getRulePmfms()) {
274 RulePmfmDTO duplicatedRulePmfm = ReefDbBeans.clone(rulePmfm);
275 duplicatedRulePmfm.setId(null);
276 duplicatedControlRule.addRulePmfms(duplicatedRulePmfm);
277 }
278
279 return duplicatedControlRule;
280 }
281
282 private void duplicatePreconditions(ControlRuleDTO controlRule, ControlRuleDTO duplicatedControlRule, MutableInt suffixIndex) {
283
284 for (PreconditionRuleDTO precondition : controlRule.getPreconditions()) {
285 PreconditionRuleDTO duplicatedPrecondition = ReefDbBeans.clone(precondition);
286 duplicatedPrecondition.setId(null);
287 duplicatedPrecondition.setRule(duplicatedControlRule);
288 duplicatedPrecondition.setName(duplicatedControlRule.getCode());
289 duplicatedPrecondition.setBaseRule(duplicateControlRule(precondition.getBaseRule(), null));
290 duplicatedPrecondition.getBaseRule().setCode(getNextRuleCode(duplicatedControlRule.getCode(), suffixIndex));
291 duplicatedPrecondition.setUsedRule(duplicateControlRule(precondition.getUsedRule(), null));
292 duplicatedPrecondition.getUsedRule().setCode(getNextRuleCode(duplicatedControlRule.getCode(), suffixIndex));
293 duplicatedControlRule.addPreconditions(duplicatedPrecondition);
294 }
295
296 }
297
298
299
300
301 @Override
302 public ControlRuleDTO newControlRule(RuleListDTO ruleList) {
303
304 Assert.notNull(ruleList);
305 Assert.notBlank(ruleList.getCode());
306
307 ControlRuleDTO rule = ReefDbBeanFactory.newControlRuleDTO();
308
309 rule.setCode(getNextRuleCode(ruleList));
310 rule.setNewCode(true);
311 rule.setActive(true);
312 rule.setBlocking(false);
313
314 return rule;
315 }
316
317 @Override
318 public boolean ruleCodeExists(String ruleCode) {
319 Assert.notBlank(ruleCode);
320
321 return ruleDao.ruleExists(ruleCode);
322 }
323
324 @Override
325 public List<ControlRuleDTO> getPreconditionedControlRulesForSurvey(SurveyDTO survey) {
326 Assert.notNull(survey);
327 Assert.notNull(survey.getDate());
328 Assert.notNull(survey.getProgram());
329 Assert.notNull(survey.getRecorderDepartment());
330
331 List<ControlRuleDTO> preconditionedRules = ruleDao.findActivePreconditionedRules(
332 Dates.convertToDate(survey.getDate(), configuration.getDbTimezone()),
333 survey.getProgram().getCode(),
334 survey.getRecorderDepartment().getId());
335 buildPmfmInformation(preconditionedRules);
336 return preconditionedRules;
337 }
338
339 @Override
340 public List<ControlRuleDTO> getGroupedControlRulesForSurvey(SurveyDTO survey) {
341 Assert.notNull(survey);
342 Assert.notNull(survey.getDate());
343 Assert.notNull(survey.getProgram());
344 Assert.notNull(survey.getRecorderDepartment());
345
346 List<ControlRuleDTO> preconditionedRules = ruleDao.findActiveGroupedRules(
347 Dates.convertToDate(survey.getDate(), configuration.getDbTimezone()),
348 survey.getProgram().getCode(), survey.getRecorderDepartment().getId());
349 buildPmfmInformation(preconditionedRules);
350 return preconditionedRules;
351 }
352
353 @Override
354 public List<ControlRuleDTO> getPreconditionedControlRulesForProgramCodes(List<String> programCodes) {
355 Assert.notEmpty(programCodes);
356
357 List<ControlRuleDTO> preconditionedRules = ruleDao.findActivePreconditionedRules(programCodes);
358 buildPmfmInformation(preconditionedRules);
359 return preconditionedRules;
360
361 }
362
363 @Override
364 public void buildAllowedValuesByPmfmId(MeasurementDTO measurement,
365 Collection<Integer> targetPmfmIds,
366 Collection<PreconditionRuleDTO> preconditions,
367 AllowedQualitativeValuesMap allowedQualitativeValuesMap) {
368
369 int sourcePmfmId = measurement.getPmfm().getId();
370
371 for (PreconditionRuleDTO precondition : preconditions) {
372
373 ControlRuleDTO sourceRule;
374 ControlRuleDTO targetRule;
375
376
377 if (!precondition.isBidirectional() || Objects.equals(precondition.getBaseRule().getRulePmfms(0).getPmfm().getId(), sourcePmfmId)) {
378
379 sourceRule = precondition.getBaseRule();
380 targetRule = precondition.getUsedRule();
381 } else {
382
383 sourceRule = precondition.getUsedRule();
384 targetRule = precondition.getBaseRule();
385 }
386
387
388 int targetPmfmId = targetRule.getRulePmfms(0).getPmfm().getId();
389 if (!targetPmfmIds.contains(targetPmfmId)) continue;
390
391
392 if (ReefDbBeans.isQualitativeControlRule(targetRule)) {
393
394 if (ReefDbBeans.isQualitativeControlRule(sourceRule)) {
395 BaseReferentialDTO sourceValue = measurement.getQualitativeValue();
396
397
398 if (controlRuleService.controlUniqueObject(sourceRule, sourceValue)) {
399
400
401 allowedQualitativeValuesMap.addTargetValues(targetPmfmId, sourcePmfmId, sourceValue.getId(), getAllowedValueIds(targetRule));
402
403 } else {
404
405
406 AllowedQualitativeValuesMap.AllowedValues allowedValues =
407 allowedQualitativeValuesMap.getAllowedValues(targetPmfmId, sourcePmfmId, sourceValue != null ? sourceValue.getId() : null);
408 if (allowedValues != null && sourceValue == null) {
409 allowedValues.setAllAllowed();
410 }
411
412 }
413
414 } else if (ReefDbBeans.isNumericalControlRule(sourceRule)) {
415 BigDecimal sourceValue = measurement.getNumericalValue();
416
417
418 if (controlRuleService.controlUniqueObject(sourceRule, sourceValue)) {
419
420
421 allowedQualitativeValuesMap.addTargetValues(targetPmfmId, sourcePmfmId, sourceValue, getAllowedValueIds(targetRule));
422
423 } else {
424
425
426 AllowedQualitativeValuesMap.AllowedValues allowedValues =
427 allowedQualitativeValuesMap.getAllowedValues(targetPmfmId, sourcePmfmId, sourceValue);
428 if (allowedValues != null && sourceValue == null) {
429 allowedValues.setAllAllowed();
430 }
431
432 }
433
434
435 } else {
436
437
438 LOG.warn(String.format("invalid source rule %s", sourceRule.getCode()));
439 }
440
441 } else if (ReefDbBeans.isNumericalControlRule(targetRule)) {
442
443
444
445
446 } else {
447
448
449 LOG.warn(String.format("invalid target rule %s", targetRule.getCode()));
450 }
451
452 }
453 }
454
455 private Set<Integer> getAllowedValueIds(ControlRuleDTO rule) {
456 return ReefDbBeans.getIntegerSetFromString(rule.getAllowedValues(), configuration.getValueSeparator());
457 }
458
459 @Override
460 public Multimap<QualitativeValueDTO, QualitativeValueDTO> buildQualitativeValueMapFromPreconditions(Collection<PreconditionRuleDTO> preconditions) {
461 Multimap<QualitativeValueDTO, QualitativeValueDTO> multimap = HashMultimap.create();
462 for (PreconditionRuleDTO precondition : preconditions) {
463
464 List<QualitativeValueDTO> baseValues = referentialService.getQualitativeValues(
465 ReefDbBeans.getIntegerSetFromString(precondition.getBaseRule().getAllowedValues(), configuration.getValueSeparator()));
466 for (QualitativeValueDTO baseValue : baseValues) {
467 multimap.putAll(
468 baseValue,
469 referentialService.getQualitativeValues(
470 ReefDbBeans.getIntegerSetFromString(precondition.getUsedRule().getAllowedValues(), configuration.getValueSeparator()))
471 );
472 }
473 }
474 return multimap;
475 }
476
477 @Override
478 public void buildPreconditionsFromQualitativeValueMap(ControlRuleDTO rule, Multimap<QualitativeValueDTO, QualitativeValueDTO> multimap) {
479 Map<String, PreconditionRuleDTO> existingRulePreconditionsByBaseValues = getRulePreconditionsByBaseValues(rule);
480
481 MutableInt suffixIndex = getUniqueMutableIndex();
482
483 for (QualitativeValueDTO baseValue : multimap.keySet()) {
484 PreconditionRuleDTO precondition = existingRulePreconditionsByBaseValues.remove(baseValue.getId().toString());
485 if (precondition == null) {
486 precondition = createPreconditionRule(rule);
487 }
488 precondition.setActive(rule.isActive());
489 precondition.setName(rule.getCode());
490
491 ControlRuleDTO baseRule = precondition.getBaseRule();
492 if (baseRule == null) {
493 baseRule = createQualitativeControlRule(rule, suffixIndex);
494 baseRule.addRulePmfms(cloneRulePmfm(rule.getRulePmfms(0)));
495 baseRule.setAllowedValues(baseValue.getId().toString());
496 precondition.setBaseRule(baseRule);
497 }
498
499 ControlRuleDTO usedRule = precondition.getUsedRule();
500 if (usedRule == null) {
501 usedRule = createQualitativeControlRule(rule, suffixIndex);
502 usedRule.addRulePmfms(cloneRulePmfm(rule.getRulePmfms(1)));
503 precondition.setUsedRule(usedRule);
504 }
505 usedRule.setAllowedValues(ReefDbBeans.joinIds(multimap.get(baseValue), configuration.getValueSeparator()));
506
507 }
508
509
510 rule.removeAllPreconditions(existingRulePreconditionsByBaseValues.values());
511
512 }
513
514 @Override
515 public List<NumericPreconditionDTO> buildNumericPreconditionListFromPreconditions(Collection<PreconditionRuleDTO> preconditions) {
516 List<NumericPreconditionDTO> list = new ArrayList<>();
517 for (PreconditionRuleDTO precondition : preconditions) {
518 NumericPreconditionDTO numericPrecondition = ReefDbBeanFactory.newNumericPreconditionDTO();
519 Set<Integer> qvIds = ReefDbBeans.getIntegerSetFromString(precondition.getBaseRule().getAllowedValues(), configuration.getValueSeparator());
520 if (qvIds.isEmpty()) continue;
521 numericPrecondition.setQualitativeValue(referentialService.getQualitativeValue(qvIds.iterator().next()));
522 numericPrecondition.setMin((Double) precondition.getUsedRule().getMin());
523 numericPrecondition.setMax((Double) precondition.getUsedRule().getMax());
524 list.add(numericPrecondition);
525 }
526
527 return list;
528 }
529
530 @Override
531 public void buildPreconditionsFromNumericPreconditionList(ControlRuleDTO rule, List<NumericPreconditionDTO> list) {
532 Map<String, PreconditionRuleDTO> existingRulePreconditionsByBaseValues = getRulePreconditionsByBaseValues(rule);
533
534 MutableInt suffixIndex = getUniqueMutableIndex();
535
536 for (NumericPreconditionDTO baseValue : list) {
537 PreconditionRuleDTO precondition = existingRulePreconditionsByBaseValues.remove(baseValue.getQualitativeValue().getId().toString());
538 if (precondition == null) {
539 precondition = createPreconditionRule(rule);
540 }
541 precondition.setActive(rule.isActive());
542 precondition.setName(rule.getCode());
543
544 ControlRuleDTO baseRule = precondition.getBaseRule();
545 if (baseRule == null) {
546 baseRule = createQualitativeControlRule(rule, suffixIndex);
547 baseRule.addRulePmfms(cloneRulePmfm(rule.getRulePmfms(0)));
548 baseRule.setAllowedValues(baseValue.getQualitativeValue().getId().toString());
549 precondition.setBaseRule(baseRule);
550 }
551
552 ControlRuleDTO usedRule = precondition.getUsedRule();
553 if (usedRule == null) {
554 usedRule = createNumericalControlRule(rule, suffixIndex);
555 usedRule.addRulePmfms(cloneRulePmfm(rule.getRulePmfms(1)));
556 precondition.setUsedRule(usedRule);
557 }
558 usedRule.setMin(baseValue.getMin());
559 usedRule.setMax(baseValue.getMax());
560 }
561
562
563 rule.removeAllPreconditions(existingRulePreconditionsByBaseValues.values());
564
565 }
566
567 @Override
568 public void buildNotEmptyConditionalGroupsFromGroupedRule(ControlRuleDTO groupedRule) {
569
570
571 if (groupedRule.isRulePmfmsEmpty() || !ReefDbBeans.isGroupedRule(groupedRule)) {
572 groupedRule.setGroups(null);
573 return;
574 }
575
576 RuleGroupDTO taxonGroupRuleGroup = null;
577 RuleGroupDTO taxonRuleGroup = null;
578 RuleGroupDTO pmfmRuleGroup = null;
579 MutableInt suffixIndex = getUniqueMutableIndex();
580
581
582 for (RuleGroupDTO group: groupedRule.getGroups()) {
583 if (group.getRule() == null) continue;
584 if (ControlFunctionValues.NOT_EMPTY.equals(group.getRule().getFunction())
585 && ControlElementValues.MEASUREMENT.equals(group.getRule().getControlElement())
586 && ControlFeatureMeasurementValues.TAXON_GROUP.equals(group.getRule().getControlFeature())) {
587 taxonGroupRuleGroup = group;
588 }
589 if (ControlFunctionValues.NOT_EMPTY.equals(group.getRule().getFunction())
590 && ControlElementValues.MEASUREMENT.equals(group.getRule().getControlElement())
591 && ControlFeatureMeasurementValues.TAXON.equals(group.getRule().getControlFeature())) {
592 taxonRuleGroup = group;
593 }
594 if (ControlFunctionValues.NOT_EMPTY.equals(group.getRule().getFunction())
595 && ControlElementValues.MEASUREMENT.equals(group.getRule().getControlElement())
596 && ControlFeatureMeasurementValues.PMFM.equals(group.getRule().getControlFeature())) {
597 pmfmRuleGroup = group;
598 }
599 }
600
601 if (taxonGroupRuleGroup == null) {
602 taxonGroupRuleGroup = ReefDbBeanFactory.newRuleGroupDTO();
603 taxonGroupRuleGroup.setIsOr(true);
604 groupedRule.addGroups(taxonGroupRuleGroup);
605
606 ControlRuleDTO taxonGroupRule = ReefDbBeanFactory.newControlRuleDTO();
607 taxonGroupRule.setCode(getNextRuleCode(groupedRule.getCode(), suffixIndex));
608 taxonGroupRule.setFunction(ControlFunctionValues.NOT_EMPTY.toFunctionDTO());
609 taxonGroupRule.setControlElement(ControlElementValues.MEASUREMENT.toControlElementDTO());
610 taxonGroupRule.setControlFeature(ControlFeatureMeasurementValues.TAXON_GROUP.toControlFeatureDTO());
611 taxonGroupRule.setActive(false);
612 taxonGroupRuleGroup.setRule(taxonGroupRule);
613 }
614 taxonGroupRuleGroup.setName(groupedRule.getCode());
615 taxonGroupRuleGroup.setActive(groupedRule.isActive());
616 taxonGroupRuleGroup.getRule().setDescription(groupedRule.getDescription());
617 taxonGroupRuleGroup.getRule().setMessage(groupedRule.getMessage());
618
619 if (taxonRuleGroup == null) {
620 taxonRuleGroup = ReefDbBeanFactory.newRuleGroupDTO();
621 taxonRuleGroup.setIsOr(true);
622 groupedRule.addGroups(taxonRuleGroup);
623
624 ControlRuleDTO taxonRule = ReefDbBeanFactory.newControlRuleDTO();
625 taxonRule.setCode(getNextRuleCode(groupedRule.getCode(), suffixIndex));
626 taxonRule.setFunction(ControlFunctionValues.NOT_EMPTY.toFunctionDTO());
627 taxonRule.setControlElement(ControlElementValues.MEASUREMENT.toControlElementDTO());
628 taxonRule.setControlFeature(ControlFeatureMeasurementValues.TAXON.toControlFeatureDTO());
629 taxonRule.setActive(false);
630 taxonRuleGroup.setRule(taxonRule);
631 }
632 taxonRuleGroup.setName(groupedRule.getCode());
633 taxonRuleGroup.setActive(groupedRule.isActive());
634 taxonRuleGroup.getRule().setDescription(groupedRule.getDescription());
635 taxonRuleGroup.getRule().setMessage(groupedRule.getMessage());
636
637 if (pmfmRuleGroup == null) {
638 pmfmRuleGroup = ReefDbBeanFactory.newRuleGroupDTO();
639 pmfmRuleGroup.setIsOr(true);
640 groupedRule.addGroups(pmfmRuleGroup);
641
642 ControlRuleDTO pmfmRule = ReefDbBeanFactory.newControlRuleDTO();
643 pmfmRule.setCode(getNextRuleCode(groupedRule.getCode(), suffixIndex));
644 pmfmRule.setFunction(ControlFunctionValues.NOT_EMPTY.toFunctionDTO());
645 pmfmRule.setControlElement(ControlElementValues.MEASUREMENT.toControlElementDTO());
646 pmfmRule.setControlFeature(ControlFeatureMeasurementValues.PMFM.toControlFeatureDTO());
647 pmfmRule.setActive(false);
648 pmfmRuleGroup.setRule(pmfmRule);
649 }
650 pmfmRuleGroup.setName(groupedRule.getCode());
651 pmfmRuleGroup.setActive(groupedRule.isActive());
652 pmfmRuleGroup.getRule().setRulePmfms(new ArrayList<>(groupedRule.getRulePmfms()));
653 pmfmRuleGroup.getRule().setDescription(groupedRule.getDescription());
654 pmfmRuleGroup.getRule().setMessage(groupedRule.getMessage());
655
656
657 Assert.equals(groupedRule.sizeGroups(), 3, "the groups count must be 3");
658 }
659
660 private void buildPmfmInformation(List<ControlRuleDTO> controlRules) {
661 if (controlRules != null) {
662 for (ControlRuleDTO controlRule : controlRules) {
663
664 for (RulePmfmDTO rulePmfm : controlRule.getRulePmfms()) {
665 rulePmfm.getPmfm().setId(referentialService.getUniquePmfmIdFromPmfm(rulePmfm.getPmfm()));
666 }
667 for (PreconditionRuleDTO precondition : controlRule.getPreconditions()) {
668 precondition.getBaseRule().getRulePmfms(0).getPmfm().setId(referentialService.getUniquePmfmIdFromPmfm(precondition.getBaseRule().getRulePmfms(0).getPmfm()));
669 precondition.getUsedRule().getRulePmfms(0).getPmfm().setId(referentialService.getUniquePmfmIdFromPmfm(precondition.getUsedRule().getRulePmfms(0).getPmfm()));
670 }
671 for (RuleGroupDTO group: controlRule.getGroups()) {
672 for (RulePmfmDTO rulePmfm : group.getRule().getRulePmfms()) {
673 rulePmfm.getPmfm().setId(referentialService.getUniquePmfmIdFromPmfm(rulePmfm.getPmfm()));
674 }
675 }
676 }
677 }
678 }
679
680
681
682
683
684
685
686 private String getNextRuleCode(RuleListDTO ruleList) {
687 Assert.notNull(ruleList);
688 int maxSuffix = 0;
689
690 if (CollectionUtils.isNotEmpty(ruleList.getControlRules())) {
691
692 for (ControlRuleDTO r : ruleList.getControlRules()) {
693 String ruleCode = r.getCode();
694
695 if (StringUtils.isNotBlank(ruleCode)
696 && ruleCode.startsWith(ruleList.getCode())) {
697 int lastIndex = ruleCode.lastIndexOf('_');
698 if (lastIndex == -1) {
699 lastIndex = ruleCode.lastIndexOf('-');
700 }
701
702 if (lastIndex != -1 && lastIndex != ruleCode.length() - 1) {
703 String suffix = ruleCode.substring(lastIndex + 1);
704 try {
705 maxSuffix = Math.max(maxSuffix, Integer.parseInt(suffix));
706 } catch (NumberFormatException e) {
707
708 }
709 }
710 }
711 }
712 }
713
714
715 return String.format("%s_%d", ruleList.getCode(), maxSuffix + 1);
716 }
717
718 @Override
719 public MutableInt getUniqueMutableIndex() {
720 return new MutableInt(System.currentTimeMillis() / 1000);
721 }
722
723
724
725
726
727
728
729
730 @Override
731 public String getNextRuleCode(String targetName, MutableInt suffixIndex) {
732 String ruleCode;
733 do {
734
735 String suffix = Integer.toString(suffixIndex.getAndIncrement());
736 int suffixLength = suffix.length() + 1;
737 int totalLength = targetName.length() + suffixLength;
738 if (totalLength > 40) {
739 targetName = targetName.substring(0, 40 - suffixLength);
740 }
741 ruleCode = String.format("%s_%s", targetName, suffix);
742 } while (ruleCodeExists(ruleCode));
743 return ruleCode;
744 }
745
746 private Map<String, PreconditionRuleDTO> getRulePreconditionsByBaseValues(ControlRuleDTO rule) {
747 return ReefDbBeans.mapByProperty(rule.getPreconditions(), PreconditionRuleDTO.PROPERTY_BASE_RULE + "." + ControlRuleDTO.PROPERTY_ALLOWED_VALUES);
748 }
749
750 private PreconditionRuleDTO createPreconditionRule(ControlRuleDTO parentRule) {
751 PreconditionRuleDTO precondition = ReefDbBeanFactory.newPreconditionRuleDTO();
752 precondition.setRule(parentRule);
753 precondition.setBidirectional(true);
754 parentRule.addPreconditions(precondition);
755 return precondition;
756 }
757
758 private ControlRuleDTO createQualitativeControlRule(ControlRuleDTO parentRule, MutableInt suffixIndex) {
759 ControlRuleDTO rule = ReefDbBeanFactory.newControlRuleDTO();
760 rule.setCode(getNextRuleCode(parentRule.getCode(), suffixIndex));
761 rule.setFunction(ControlFunctionValues.IS_AMONG.toFunctionDTO());
762 rule.setControlElement(ControlElementValues.MEASUREMENT.toControlElementDTO());
763 rule.setControlFeature(ControlFeatureMeasurementValues.QUALITATIVE_VALUE.toControlFeatureDTO());
764 rule.setActive(false);
765 return rule;
766 }
767
768 private ControlRuleDTO createNumericalControlRule(ControlRuleDTO parentRule, MutableInt suffixIndex) {
769 ControlRuleDTO rule = ReefDbBeanFactory.newControlRuleDTO();
770 rule.setCode(getNextRuleCode(parentRule.getCode(), suffixIndex));
771 rule.setFunction(ControlFunctionValues.MIN_MAX.toFunctionDTO());
772 rule.setControlElement(ControlElementValues.MEASUREMENT.toControlElementDTO());
773 rule.setControlFeature(ControlFeatureMeasurementValues.NUMERICAL_VALUE.toControlFeatureDTO());
774 rule.setActive(false);
775 return rule;
776 }
777
778 private RulePmfmDTO cloneRulePmfm(RulePmfmDTO rulePmfm) {
779 RulePmfmDTO result = ReefDbBeanFactory.newRulePmfmDTO();
780 result.setPmfm(ReefDbBeans.clone(rulePmfm.getPmfm()));
781 return result;
782 }
783
784 }