View Javadoc
1   package fr.ifremer.quadrige3.core.dao.system.rule;
2   
3   /*-
4    * #%L
5    * Quadrige3 Core :: Quadrige3 Client Core
6    * %%
7    * Copyright (C) 2017 Ifremer
8    * %%
9    * This program is free software: you can redistribute it and/or modify
10   * it under the terms of the GNU Affero General Public License as published by
11   * the Free Software Foundation, either version 3 of the License, or
12   * (at your option) any later version.
13   * 
14   * This program is distributed in the hope that it will be useful,
15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   * GNU General Public License for more details.
18   * 
19   * You should have received a copy of the GNU Affero General Public License
20   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21   * #L%
22   */
23  
24  import fr.ifremer.quadrige3.core.dao.technical.Assert;
25  import fr.ifremer.quadrige3.core.dao.technical.Beans;
26  import fr.ifremer.quadrige3.core.dao.technical.Daos;
27  import fr.ifremer.quadrige3.core.vo.system.rule.RuleParameterVO;
28  import fr.ifremer.quadrige3.core.vo.system.rule.RulePmfmVO;
29  import fr.ifremer.quadrige3.core.vo.system.rule.RuleVO;
30  import org.apache.commons.collections4.CollectionUtils;
31  import org.apache.commons.collections4.MapUtils;
32  import org.apache.commons.lang3.ArrayUtils;
33  import org.hibernate.SessionFactory;
34  import org.springframework.beans.factory.annotation.Autowired;
35  import org.springframework.context.annotation.Lazy;
36  import org.springframework.stereotype.Repository;
37  
38  import javax.annotation.Resource;
39  import java.sql.Timestamp;
40  import java.util.Arrays;
41  import java.util.Collection;
42  import java.util.Map;
43  import java.util.Objects;
44  import java.util.stream.Collectors;
45  
46  /**
47   * @see Rule
48   */
49  @Repository("ruleDao")
50  @Lazy
51  public class RuleDaoImpl
52      extends RuleDaoBase
53  {
54  
55      @Resource
56      private RuleParameterDao ruleParameterDao;
57  
58      @Resource
59      private RulePmfmDao rulePmfmDao;
60  
61      @Resource
62      private RulePreconditionDao rulePreconditionDao;
63  
64      @Resource
65      private RuleGroupDao ruleGroupDao;
66  
67      /**
68       * Constructor used by Spring
69       */
70  	@Autowired
71  	public RuleDaoImpl(SessionFactory sessionFactory) {
72  		super();
73  		setSessionFactory(sessionFactory);
74  	}
75  
76      /** {@inheritDoc} */
77      @Override
78      public void remove(Collection<Rule> entities) {
79          Assert.notEmpty(entities);
80  
81          Collection<Rule> rulesWithPreconditions = entities.stream().filter(rule -> CollectionUtils.isNotEmpty(rule.getRulePreconditions())).collect(Collectors.toList());
82          Collection<Rule> rules = CollectionUtils.removeAll(entities, rulesWithPreconditions);
83          Collection<Rule> rulesWithGroups = entities.stream().filter(rule -> CollectionUtils.isNotEmpty(rule.getRuleGroups())).collect(Collectors.toList());
84          rules.removeAll(rulesWithGroups);
85          // Remove rules with preconditions first
86          rulesWithPreconditions.forEach(this::remove);
87          // Remove rules associated to a group
88          rulesWithGroups.forEach(this::remove);
89          // Then, remove other rules
90          rules.forEach(this::remove);
91      }
92  
93      /** {@inheritDoc} */
94      @Override
95      public void remove(Rule entity) {
96  
97          // Remove rule preconditions
98          if (CollectionUtils.isNotEmpty(entity.getRulePreconditions())) {
99              rulePreconditionDao.remove(entity.getRulePreconditions());
100             entity.getRulePreconditions().clear();
101         }
102 
103         getSession().flush();
104 
105         // Remove rule groups
106         if (CollectionUtils.isNotEmpty(entity.getRuleGroups())) {
107             ruleGroupDao.remove(entity.getRuleGroups());
108             entity.getRuleGroups().clear();
109         }
110 
111         getSession().flush();
112 
113         // Remove rule parameters
114         if (CollectionUtils.isNotEmpty(entity.getRuleParameters())) {
115             ruleParameterDao.remove(entity.getRuleParameters());
116             entity.getRuleParameters().clear();
117         }
118 
119         getSession().flush();
120 
121         // Remove rule pmfm
122         if (CollectionUtils.isNotEmpty(entity.getRulePmfms())) {
123             rulePmfmDao.remove(entity.getRulePmfms());
124             entity.getRulePmfms().clear();
125         }
126 
127         getSession().flush();
128 
129         super.remove(entity);
130     }
131 
132     /**
133      * {@inheritDoc}
134      */
135     protected RuleVO handleSave(RuleVO source, Timestamp updateDt) {
136         Assert.notNull(source);
137         Assert.notNull(source.getRuleCd());
138 
139         // Load parent
140         RuleList parent = get(RuleListImpl.class, source.getRuleListCd());
141 
142         // Load entity
143         Rule entity = get(source.getRuleCd());
144         boolean isNew = false;
145         if (entity == null) {
146             entity = Rule.Factory.newInstance();
147             parent.addRules(entity);
148             entity.setRuleList(parent);
149             isNew = true;
150         }
151 
152         // Check update_dt :
153         // NOT NEED on a client database
154 
155         // Update update_dt
156         // NOT NEED on a client database
157 
158         // VO -> Entity
159         ruleVOToEntity(source, entity, true, false /*children not need*/);
160 
161         // Save entity
162         if (isNew) {
163             getSession().save(entity);
164         } else {
165             getSession().update(entity);
166         }
167 
168         // Keep trace of items to remove
169         Map<Integer, RuleParameter> ruleParametersToRemove = Beans.mapByProperty(entity.getRuleParameters(), "ruleParId");
170         Map<Integer, RulePmfm> rulePmfmsToRemove = Beans.mapByProperty(entity.getRulePmfms(), "rulePmfmId");
171 
172         // Save rule parameters
173         if (ArrayUtils.isNotEmpty(source.getRuleParameterVOs())) {
174             for (RuleParameterVO ruleParameterVO : source.getRuleParameterVOs()) {
175                 ruleParameterVO.setRuleCd(entity.getRuleCd());
176                 ruleParameterVO = ruleParameterDao.save(ruleParameterVO, null);
177                 ruleParametersToRemove.remove(ruleParameterVO.getRuleParId());
178             }
179         }
180 
181         // Save rule pmfm
182         if (ArrayUtils.isNotEmpty(source.getRulePmfmVOs())) {
183             for (RulePmfmVO rulePmfmVO : source.getRulePmfmVOs()) {
184                 rulePmfmVO.setRuleCd(entity.getRuleCd());
185                 rulePmfmVO = rulePmfmDao.save(rulePmfmVO, null);
186                 rulePmfmsToRemove.remove(rulePmfmVO.getRulePmfmId());
187             }
188         }
189 
190         // Remove unused rule parameters
191         if (MapUtils.isNotEmpty(ruleParametersToRemove)) {
192             ruleParameterDao.remove(ruleParametersToRemove.values());
193             entity.getRuleParameters().removeAll(ruleParametersToRemove.values());
194         }
195 
196         // Remove unused rule pmfm
197         if (MapUtils.isNotEmpty(rulePmfmsToRemove)) {
198             rulePmfmDao.remove(rulePmfmsToRemove.values());
199             entity.getRulePmfms().removeAll(rulePmfmsToRemove.values());
200         }
201 
202         getSession().update(entity);
203 
204         return source;
205     }
206 
207     /**
208      * {@inheritDoc}
209      */
210     protected void handleRemoveByCds(String[] ruleCds) {
211         remove(Arrays.stream(ruleCds).map(this::get).filter(Objects::nonNull).collect(Collectors.toList()));
212     }
213 
214     /**
215      * {@inheritDoc}
216      */
217     public void toRuleVO(
218         Rule source,
219         RuleVO target)
220     {
221         // base attributes
222         super.toRuleVO(source, target);
223 
224         // Parent
225         if (source.getRuleList() == null) {
226             target.setRuleListCd(null);
227         }
228         else {
229             target.setRuleListCd(source.getRuleList().getRuleListCd());
230         }
231 
232         // Function
233         if (source.getFunction() == null) {
234             target.setFunctionId(null);
235         } else {
236             target.setFunctionId(source.getFunction().getFunctionId());
237         }
238 
239         // Rules parameters
240         if (CollectionUtils.isEmpty(source.getRuleParameters())) {
241             target.setRuleParameterVOs(null);
242         }
243         else {
244             target.setRuleParameterVOs(ruleParameterDao.toRuleParameterVOArray(source.getRuleParameters()));
245         }
246 
247         // Rules pmfm
248         if (CollectionUtils.isEmpty(source.getRulePmfms())) {
249             target.setRulePmfmVOs(null);
250         }
251         else {
252             target.setRulePmfmVOs(rulePmfmDao.toRulePmfmVOArray(source.getRulePmfms()));
253         }
254     }
255 
256     /**
257      * Retrieves the entity object that is associated with the specified value object
258      * from the object store. If no such entity object exists in the object store,
259      * a new, blank entity is created
260      */
261     private Rule loadRuleFromRuleVO(RuleVO ruleVO)
262     {
263         Rule rule = null;
264         if (ruleVO.getRuleCd() != null) {
265             rule = this.get(ruleVO.getRuleCd());
266         }
267         if (rule == null)
268         {
269             rule = Rule.Factory.newInstance();
270         }
271         return rule;
272     }
273 
274     /**
275      * {@inheritDoc}
276      */
277     public Rule ruleVOToEntity(RuleVO ruleVO)
278     {
279         Rule entity = this.loadRuleFromRuleVO(ruleVO);
280         this.ruleVOToEntity(ruleVO, entity, true);
281         return entity;
282     }
283 
284     /**
285      * {@inheritDoc}
286      */
287     @Override
288     public void ruleVOToEntity(
289         RuleVO source,
290         Rule target,
291         boolean copyIfNull)
292     {
293         this.ruleVOToEntity(source, target, copyIfNull, false/*withChildrenEntities*/);
294     }
295 
296 
297     /* -- protected methods -- */
298 
299     protected void ruleVOToEntity(
300             RuleVO source,
301             Rule target,
302             boolean copyIfNull,
303             boolean withChildrenEntities)
304     {
305         // Base attributes
306         super.ruleVOToEntity(source, target, copyIfNull);
307 
308         // Code
309         if (copyIfNull || source.getRuleCd() != null)
310         {
311             target.setRuleCd(source.getRuleCd());
312         }
313 
314         // Rule list
315         if (copyIfNull || source.getRuleListCd() != null) {
316             if (source.getRuleListCd() == null) {
317                 target.setRuleList(null);
318             }
319             else {
320                 target.setRuleList(load(RuleListImpl.class, source.getRuleListCd()));
321             }
322         }
323 
324         // Function
325         if (copyIfNull || source.getFunctionId() != null)
326         {
327             if (source.getFunctionId() == null) {
328                 target.setFunction(null);
329             }
330             else {
331                 target.setFunction(load(FunctionImpl.class, source.getFunctionId()));
332             }
333         }
334 
335         if (withChildrenEntities) {
336 
337             // Rules parameters
338             if (copyIfNull || ArrayUtils.isNotEmpty(source.getRuleParameterVOs())) {
339                 if (ArrayUtils.isEmpty(source.getRuleParameterVOs())) {
340                     target.getRuleParameters().clear();
341                 } else {
342                     Daos.replaceEntities(target.getRuleParameters(),
343                             source.getRuleParameterVOs(),
344                             vo -> ruleParameterDao.ruleParameterVOToEntity(vo));
345                 }
346             }
347 
348             // Rules pmfm
349             if (copyIfNull || ArrayUtils.isNotEmpty(source.getRulePmfmVOs())) {
350                 if (ArrayUtils.isEmpty(source.getRulePmfmVOs())) {
351                     target.getRulePmfms().clear();
352                 } else {
353                     Daos.replaceEntities(target.getRulePmfms(),
354                             source.getRulePmfmVOs(),
355                             vo -> rulePmfmDao.rulePmfmVOToEntity(vo));
356                 }
357             }
358         }
359     }
360 }