View Javadoc
1   package fr.ifremer.quadrige3.core.dao.administration.strategy;
2   
3   /*-
4    * #%L
5    * Quadrige3 Core :: Quadrige3 Client Core
6    * $Id:$
7    * $HeadURL:$
8    * %%
9    * Copyright (C) 2017 Ifremer
10   * %%
11   * This program is free software: you can redistribute it and/or modify
12   * it under the terms of the GNU Affero General Public License as published by
13   * the Free Software Foundation, either version 3 of the License, or
14   * (at your option) any later version.
15   *
16   * This program is distributed in the hope that it will be useful,
17   * but WITHOUT ANY WARRANTY; without even the implied warranty of
18   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19   * GNU General Public License for more details.
20   *
21   * You should have received a copy of the GNU Affero General Public License
22   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
23   * #L%
24   */
25  
26  import com.google.common.collect.Maps;
27  import fr.ifremer.quadrige3.core.dao.administration.program.Program;
28  import fr.ifremer.quadrige3.core.dao.administration.program.ProgramImpl;
29  import fr.ifremer.quadrige3.core.dao.administration.user.Department;
30  import fr.ifremer.quadrige3.core.dao.administration.user.DepartmentImpl;
31  import fr.ifremer.quadrige3.core.dao.administration.user.Quser;
32  import fr.ifremer.quadrige3.core.dao.administration.user.QuserImpl;
33  import fr.ifremer.quadrige3.core.dao.technical.Assert;
34  import fr.ifremer.quadrige3.core.dao.technical.Beans;
35  import fr.ifremer.quadrige3.core.dao.technical.Daos;
36  import fr.ifremer.quadrige3.core.vo.administration.strategy.AppliedStrategyVO;
37  import fr.ifremer.quadrige3.core.vo.administration.strategy.PmfmStrategyVO;
38  import fr.ifremer.quadrige3.core.vo.administration.strategy.StrategyVO;
39  import org.apache.commons.collections4.CollectionUtils;
40  import org.apache.commons.collections4.MapUtils;
41  import org.apache.commons.lang3.ArrayUtils;
42  import org.hibernate.SessionFactory;
43  import org.springframework.beans.factory.annotation.Autowired;
44  import org.springframework.context.annotation.Lazy;
45  import org.springframework.stereotype.Repository;
46  
47  import javax.annotation.Resource;
48  import java.sql.Timestamp;
49  import java.util.Collection;
50  import java.util.Map;
51  import java.util.stream.Collectors;
52  
53  /**
54   * <p>
55   * StrategyDaoImpl class.
56   * </p>
57   *
58   * @see Strategy
59   */
60  @Repository("strategyDao")
61  @Lazy
62  public class StrategyDaoImpl
63          extends StrategyDaoBase {
64  
65      @Resource
66      private AppliedStrategyDao appliedStrategyDao;
67  
68      @Resource
69      private PmfmStrategyDao pmfmStrategyDao;
70  
71      /**
72       * Constructor used by Spring
73       *
74       * @param sessionFactory a {@link org.hibernate.SessionFactory} object.
75       */
76      @Autowired
77      public StrategyDaoImpl(SessionFactory sessionFactory) {
78          super();
79          setSessionFactory(sessionFactory);
80      }
81  
82      /**
83       * {@inheritDoc}
84       */
85      @Override
86      public void remove(Collection<Strategy> entities) {
87          Assert.notEmpty(entities);
88  
89          entities.forEach(this::remove);
90      }
91  
92      /**
93       * {@inheritDoc}
94       */
95      @Override
96      public void remove(Integer stratId) {
97          Strategy entity = get(stratId);
98          remove(entity);
99      }
100 
101     /**
102      * {@inheritDoc}
103      */
104     @Override
105     public void remove(Strategy entity) {
106 
107         // Remove applied strategies
108         if (CollectionUtils.isNotEmpty(entity.getAppliedStrategies())) {
109             // Check if these applied strategies can be removed
110             appliedStrategyDao.checkCanRemove(entity.getAppliedStrategies().stream().map(AppliedStrategy::getAppliedStratId).collect(Collectors.toSet()));
111             appliedStrategyDao.remove(entity.getAppliedStrategies());
112             entity.getAppliedStrategies().clear();
113         }
114 
115         getSession().flush();
116 
117         // Remove PmfmStrategies
118         if (CollectionUtils.isNotEmpty(entity.getPmfmStrategies())) {
119             pmfmStrategyDao.remove(entity.getPmfmStrategies());
120             entity.getPmfmStrategies().clear();
121         }
122 
123         getSession().flush();
124 
125         entity.getProgram().removeStrategies(entity);
126         super.remove(entity);
127     }
128 
129     /**
130      * {@inheritDoc}
131      */
132     public void toStrategyVO(
133             Strategy source,
134             StrategyVO target) {
135         // Copy basic attributes
136         super.toStrategyVO(source, target);
137 
138         // Program
139         if (source.getProgram() == null) {
140             target.setProgCd(null);
141         } else {
142             target.setProgCd(source.getProgram().getProgCd());
143         }
144 
145         // resp deps
146         if (CollectionUtils.isEmpty(source.getDepartments())) {
147             target.setRespDepIds(null);
148         } else {
149             target.setRespDepIds(source.getDepartments().stream().map(Department::getDepId).toArray(Integer[]::new));
150         }
151 
152         // Resp qusers
153         if (CollectionUtils.isEmpty(source.getQusers())) {
154             target.setRespQuserIds(null);
155         } else {
156             target.setRespQuserIds(source.getQusers().stream().map(Quser::getQuserId).toArray(Integer[]::new));
157         }
158 
159         // Applied strategies
160         if (CollectionUtils.isEmpty(source.getAppliedStrategies())) {
161             target.setAppliedStrategyVOs(null);
162         } else {
163             target.setAppliedStrategyVOs(appliedStrategyDao.toAppliedStrategyVOArray(source.getAppliedStrategies()));
164         }
165 
166         // Pmfm strategies
167         if (CollectionUtils.isEmpty(source.getPmfmStrategies())) {
168             target.setPmfmStrategyVOs(null);
169         } else {
170             target.setPmfmStrategyVOs(pmfmStrategyDao.toPmfmStrategyVOArray(source.getPmfmStrategies()));
171         }
172 
173     }
174 
175     /**
176      * Retrieves the entity object that is associated with the specified value object
177      * from the object store. If no such entity object exists in the object store,
178      * a new, blank entity is created
179      */
180     private Strategy loadStrategyFromStrategyVO(StrategyVO strategyVO) {
181 
182         Strategy strategy = null;
183         if (strategyVO.getStratId() != null) {
184             strategy = this.get(strategyVO.getStratId());
185         }
186         if (strategy == null) {
187             strategy = Strategy.Factory.newInstance();
188         }
189         return strategy;
190     }
191 
192     /**
193      * {@inheritDoc}
194      */
195     public Strategy strategyVOToEntity(StrategyVO strategyVO) {
196         Strategy entity = this.loadStrategyFromStrategyVO(strategyVO);
197         this.strategyVOToEntity(strategyVO, entity, true);
198         return entity;
199     }
200 
201     /**
202      * {@inheritDoc}
203      */
204     public void strategyVOToEntity(
205             StrategyVO source,
206             Strategy target,
207             boolean copyIfNull) {
208         super.strategyVOToEntity(source, target, copyIfNull);
209 
210         // Program
211         if (copyIfNull || source.getProgCd() != null) {
212             if (source.getProgCd() == null) {
213                 target.setProgram(null);
214             } else {
215                 target.setProgram(load(ProgramImpl.class, source.getProgCd()));
216             }
217         }
218 
219         // Resp departments
220         if (copyIfNull || ArrayUtils.isNotEmpty(source.getRespDepIds())) {
221             if (ArrayUtils.isEmpty(source.getRespDepIds())) {
222                 target.getDepartments().clear();
223             } else {
224                 Daos.replaceEntities(
225                         target.getDepartments(),
226                         source.getRespDepIds(),
227                         depId -> load(DepartmentImpl.class, depId)
228                 );
229             }
230         }
231 
232         // Resp qusers
233         if (copyIfNull || ArrayUtils.isNotEmpty(source.getRespQuserIds())) {
234             if (ArrayUtils.isEmpty(source.getRespQuserIds())) {
235                 target.getQusers().clear();
236             } else {
237                 Daos.replaceEntities(
238                         target.getQusers(),
239                         source.getRespQuserIds(),
240                         quserId -> load(QuserImpl.class, quserId)
241                 );
242             }
243         }
244     }
245 
246     /* -- Internal method -- */
247 
248     /**
249      * {@inheritDoc}
250      */
251     @Override
252     protected StrategyVO handleSave(StrategyVO source, Timestamp updateDt) {
253         Assert.notNull(source);
254         Assert.notNull(source.getProgCd());
255 
256         // Load parent
257         Program parent = get(ProgramImpl.class, source.getProgCd());
258 
259         // Load entity
260         Strategy entity = null;
261         boolean isNew = false;
262         if (source.getStratId() != null) {
263             entity = get(source.getStratId());
264         }
265         if (entity == null) {
266             entity = Strategy.Factory.newInstance();
267             parent.addStrategies(entity);
268             entity.setProgram(parent);
269             entity.setStratId(source.getStratId()); // assigned id
270             isNew = true;
271         }
272 
273         // Check update_dt :
274         // NOT NEED on a client database
275 
276         // Update update_dt
277         // NOT NEED on a client database
278 
279         // VO -> Entity
280         strategyVOToEntity(source, entity, true);
281 
282         // Save entity
283         if (isNew) {
284             Integer stratId = (Integer) getSession().save(entity);
285             source.setStratId(stratId);
286         } else {
287             getSession().update(entity);
288         }
289 
290         // Keep trace of items to remove
291         Map<Integer, PmfmStrategy> pmfmStrategiesToRemove = Beans.mapByProperty(entity.getPmfmStrategies(), "pmfmStratId");
292         Map<Integer, AppliedStrategy> appliedStrategiesToRemove = Beans.mapByProperty(entity.getAppliedStrategies(), "appliedStratId");
293 
294         // Save pmfm strategies
295         Map<Integer, Integer> pmfmStratIdMapping = Maps.newHashMap();
296         if (ArrayUtils.isNotEmpty(source.getPmfmStrategyVOs())) {
297             for (PmfmStrategyVO pmfmStrategy : source.getPmfmStrategyVOs()) {
298                 // Remember old applied strategy
299                 Integer oldPmfmStratId = pmfmStrategy.getPmfmStratId();
300 
301                 // Update stratId (could have change)
302                 pmfmStrategy.setStratId(entity.getStratId());
303 
304                 PmfmStrategyVO savedPmfmStrategy = pmfmStrategyDao.save(pmfmStrategy, updateDt);
305 
306                 if (oldPmfmStratId != null) {
307                     pmfmStratIdMapping.put(oldPmfmStratId, savedPmfmStrategy.getPmfmStratId());
308                 }
309 
310                 // Remove from items to remove
311                 pmfmStrategiesToRemove.remove(savedPmfmStrategy.getPmfmStratId());
312             }
313         }
314 
315         // Save applied strategies
316         if (ArrayUtils.isNotEmpty(source.getAppliedStrategyVOs())) {
317             for (AppliedStrategyVO appliedStrategy : source.getAppliedStrategyVOs()) {
318 
319                 // Update stratId (could have change)
320                 appliedStrategy.setStratId(entity.getStratId());
321 
322                 AppliedStrategyVO savedAppliedStrategyVO = appliedStrategyDao.save(appliedStrategy, pmfmStratIdMapping, updateDt);
323 
324                 // Remove from items to remove
325                 appliedStrategiesToRemove.remove(savedAppliedStrategyVO.getAppliedStratId());
326             }
327         }
328 
329         // Remove unused pmfm strategies
330         if (MapUtils.isNotEmpty(pmfmStrategiesToRemove)) {
331             pmfmStrategyDao.remove(pmfmStrategiesToRemove.values());
332             entity.getPmfmStrategies().removeAll(pmfmStrategiesToRemove.values());
333         }
334 
335         // Remove unused applied strategies
336         if (MapUtils.isNotEmpty(appliedStrategiesToRemove)) {
337             appliedStrategyDao.checkCanRemove(appliedStrategiesToRemove.keySet());
338             appliedStrategyDao.remove(appliedStrategiesToRemove.values());
339             entity.getAppliedStrategies().removeAll(appliedStrategiesToRemove.values());
340         }
341 
342         return source;
343     }
344 
345     /**
346      * {@inheritDoc}
347      */
348     @Override
349     protected void handleRemoveByIds(Collection<Integer> stratIds) {
350         Assert.notEmpty(stratIds);
351 
352         stratIds.forEach(this::remove);
353     }
354 
355 }