View Javadoc
1   // Generated by: hibernate/SpringHibernateDaoImpl.vsl in andromda-spring-cartridge.
2   // license-header java merge-point
3   /**
4    * This is only generated once! It will never be overwritten.
5    * You can (and have to!) safely modify it by hand.
6    */
7   package fr.ifremer.quadrige2.core.dao.data.survey;
8   
9   /*-
10   * #%L
11   * Quadrige2 Core :: Quadrige2 Server Core
12   * %%
13   * Copyright (C) 2017 Ifremer
14   * %%
15   * This program is free software: you can redistribute it and/or modify
16   * it under the terms of the GNU Affero General Public License as published by
17   * the Free Software Foundation, either version 3 of the License, or
18   * (at your option) any later version.
19   * 
20   * This program is distributed in the hope that it will be useful,
21   * but WITHOUT ANY WARRANTY; without even the implied warranty of
22   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23   * GNU General Public License for more details.
24   * 
25   * You should have received a copy of the GNU Affero General Public License
26   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
27   * #L%
28   */
29  
30  import com.google.common.base.Preconditions;
31  import fr.ifremer.quadrige2.core.config.Quadrige2Configuration;
32  import fr.ifremer.quadrige2.core.dao.administration.program.ProgramStrategyJdbcDao;
33  import fr.ifremer.quadrige2.core.dao.administration.user.DepartmentImpl;
34  import fr.ifremer.quadrige2.core.dao.administration.user.QuserImpl;
35  import fr.ifremer.quadrige2.core.dao.system.synchronization.DeletedItemHistoryExtendDao;
36  import fr.ifremer.quadrige2.core.dao.technical.Beans;
37  import fr.ifremer.quadrige2.core.dao.technical.Daos;
38  import fr.ifremer.quadrige2.core.dao.technical.Dates;
39  import fr.ifremer.quadrige2.core.exception.BadUpdateDtException;
40  import fr.ifremer.quadrige2.core.exception.DataLockedException;
41  import fr.ifremer.quadrige2.core.exception.Quadrige2TechnicalException;
42  import fr.ifremer.quadrige2.core.vo.data.survey.CampaignVO;
43  import fr.ifremer.quadrige2.core.vo.data.survey.OccasionVO;
44  import org.apache.commons.collections4.CollectionUtils;
45  import org.apache.commons.lang3.ArrayUtils;
46  import org.hibernate.*;
47  import org.hibernate.exception.LockTimeoutException;
48  import org.hibernate.type.IntegerType;
49  import org.nuiton.i18n.I18n;
50  import org.springframework.beans.factory.annotation.Autowired;
51  import org.springframework.context.annotation.Lazy;
52  import org.springframework.stereotype.Repository;
53  
54  import javax.annotation.Resource;
55  import java.sql.Timestamp;
56  import java.util.Collection;
57  import java.util.List;
58  import java.util.Objects;
59  
60  /**
61   * @see Campaign
62   */
63  @Repository("campaignDao")
64  @Lazy
65  public class CampaignDaoImpl
66          extends CampaignDaoBase {
67      @Resource
68      private Quadrige2Configuration config;
69  
70      @Resource(name = "occasionDao")
71      private OccasionDao occasionDao;
72  
73      @Resource(name = "programStrategyJdbcDao")
74      private ProgramStrategyJdbcDao programStrategyJdbcDao;
75  
76      @Resource(name = "deletedItemHistoryDao")
77      private DeletedItemHistoryExtendDao deletedItemHistoryDao;
78  
79      /**
80       * Constructor used by Spring
81       */
82      @Autowired
83      public CampaignDaoImpl(SessionFactory sessionFactory) {
84          super();
85          setSessionFactory(sessionFactory);
86      }
87  
88      /**
89       * {@inheritDoc}
90       */
91      @Override
92      public void remove(Collection<Campaign> entities) {
93          Preconditions.checkNotNull(entities);
94          Preconditions.checkArgument(entities.size() > 0);
95  
96          for (Campaign entity : entities) {
97              remove(entity);
98          }
99      }
100 
101     /**
102      * {@inheritDoc}
103      */
104     @Override
105     public void remove(Campaign entity) {
106 
107         // Lock, if possible
108         try {
109             Session.LockRequest lockRequest = getSession().buildLockRequest(LockOptions.UPGRADE);
110             lockRequest.setLockMode(LockMode.UPGRADE_NOWAIT);
111             lockRequest.setScope(true); // cascaded to owned collections and relationships.
112             lockRequest.lock(entity);
113         } catch (LockTimeoutException e) {
114             throw new DataLockedException(I18n.t("quadrige2.dao.campaign.locked", entity.getCampaignId()), e);
115         }
116 
117         // Remove occasions
118         if (CollectionUtils.isNotEmpty(entity.getOccasions())) {
119             occasionDao.remove(entity.getOccasions());
120             entity.getOccasions().clear();
121         }
122 
123         getSession().flush();
124 
125         // Remove link to program
126         if (CollectionUtils.isNotEmpty(entity.getPrograms())) {
127             entity.getPrograms().clear();
128         }
129 
130         // Remove link to moratorium
131         if (CollectionUtils.isNotEmpty(entity.getMoratoria())) {
132             entity.getMoratoria().clear();
133         }
134 
135         // Insert into DeleteItemHistory
136         deletedItemHistoryDao.insertDeletedItem(CampaignImpl.class, entity);
137 
138         super.remove(entity);
139     }
140 
141     /**
142      * {@inheritDoc}
143      */
144     protected CampaignVO handleSave(CampaignVO source) {
145         Preconditions.checkNotNull(source.getQuserId());
146         Preconditions.checkNotNull(source.getRecDepId());
147         Preconditions.checkNotNull(source.getCampaignStartDt());
148         Preconditions.checkNotNull(source.getCampaignNm());
149 
150         // Already saved
151         Campaign entity = null;
152         if (source.getCampaignId() != null) {
153             entity = get(source.getCampaignId());
154         }
155 
156         // Load (or create) the entity
157         boolean isNew = false;
158         if (entity == null) {
159             entity = Campaign.Factory.newInstance();
160             isNew = true;
161         }
162 
163         // Check update_dt
164         if (!isNew) {
165             if (entity.getUpdateDt() != null) {
166                 Timestamp serverUpdateDtNoMillisecond = Dates.resetMillisecond(entity.getUpdateDt());
167                 if (source.getUpdateDt() == null) {
168                     throw new BadUpdateDtException(I18n.t("quadrige2.dao.campaign.badUpdateDt", source.getCampaignId(),
169                             serverUpdateDtNoMillisecond,
170                             "null"));
171                 }
172                 Timestamp sourceUpdateDtNoMillisecond = Dates.resetMillisecond(source.getUpdateDt());
173                 if (!Objects.equals(sourceUpdateDtNoMillisecond, serverUpdateDtNoMillisecond)) {
174                     throw new BadUpdateDtException(I18n.t("quadrige2.dao.campaign.badUpdateDt", source.getCampaignId(), serverUpdateDtNoMillisecond,
175                             sourceUpdateDtNoMillisecond));
176                 }
177             }
178 
179             // Lock, if possible
180             try {
181                 Session.LockRequest lockRequest = getSession().buildLockRequest(LockOptions.UPGRADE);
182                 lockRequest.setLockMode(LockMode.UPGRADE_NOWAIT);
183                 lockRequest.setScope(true); // cascaded to owned collections and relationships.
184                 lockRequest.lock(entity);
185             } catch (LockTimeoutException e) {
186                 throw new DataLockedException(I18n.t("quadrige2.dao.campaign.locked", source.getCampaignId()), e);
187             }
188         }
189 
190         // Update update_dt
191         Timestamp newUpdateDt = getDatabaseCurrentTimestamp();
192         // Add a delay (to make sure synchro will see it, event if this transaction is long)
193         newUpdateDt = Dates.addSeconds(newUpdateDt, config.getExportDataUpdateDateShortDelayInSecond());
194         source.setUpdateDt(newUpdateDt);
195 
196         // VO -> Entity
197         campaignVOToEntity(source, entity, true, false/* do not convert occasions */);
198 
199         // Save entity
200         if (isNew) {
201             Integer campaignId = (Integer) getSession().save(entity);
202             source.setCampaignId(campaignId);
203         } else {
204             getSession().update(entity);
205         }
206 
207         List<Integer> occasionsIdsToRemove = Beans.collectProperties(entity.getOccasions(), "occasId");
208 
209         // Save occasions
210         if (ArrayUtils.isNotEmpty(source.getOccasionVOs())) {
211             for (OccasionVO occasionVO : source.getOccasionVOs()) {
212                 occasionVO.setCampaignId(entity.getCampaignId());
213                 occasionVO = occasionDao.save(occasionVO, newUpdateDt);
214 
215                 occasionsIdsToRemove.remove(occasionVO.getOccasId());
216             }
217         }
218 
219         getSession().flush();
220         getSession().clear();
221 
222         // remove unused occasions
223         if (CollectionUtils.isNotEmpty(occasionsIdsToRemove)) {
224             occasionDao.removeByIds(occasionsIdsToRemove);
225         }
226 
227         return source;
228     }
229 
230     @Override
231     protected Long handleCountSurveyUsage(int campaignId) throws Exception {
232         try
233         {
234             return queryCount("countSurveyUsingCampaign",
235                     "campaignId", IntegerType.INSTANCE, campaignId);
236 
237         } catch (HibernateException he) {
238             throw new Quadrige2TechnicalException(String.format("Could not get the campaign usage in surveys : %s", he.getMessage()));
239         }
240     }
241 
242     /*
243     @Override
244     protected Integer[] handleGetWritableCampaignIdsByUserId(Integer quserId) throws Exception {
245 
246         // Get writable programs for user
247         List<ProgramVO> writablePrograms = programStrategyJdbcDao.getWritableProgramsByUserId(quserId);
248 
249         try {
250 
251             Query query = createQuery("writableCampaignIdsByQuserId",
252                     "quserId", IntegerType.INSTANCE, quserId);
253 
254             // Limit to active users
255             query.setParameterList("statusCodes", ImmutableList.of(StatusCode.ENABLE.getValue()));
256 
257             // Writable programs for user (if any)
258             if (CollectionUtils.isEmpty(writablePrograms)) {
259                 query.setParameter("progCds", null);
260                 query.setParameter("hasProgCds", null);
261             } else {
262                 query.setParameterList("progCds", Lists.transform(writablePrograms, ProgramVO::getProgCd));
263                 query.setParameter("hasProgCds", true);
264             }
265 
266             List<Integer> campaignIds = (List<Integer>) query.list();
267 
268             return campaignIds.toArray(new Integer[campaignIds.size()]);
269 
270         } catch (HibernateException he) {
271             throw new Quadrige2TechnicalException(String.format("Could not get the writable campaign Ids for user: %s", he.getMessage()));
272         }
273 
274     }
275 */
276     /**
277      * {@inheritDoc}
278      */
279     public void toCampaignVO(
280             Campaign source,
281             CampaignVO target) {
282 
283         // copy base attributes
284         super.toCampaignVO(source, target);
285 
286         // copy user and recorder department attributes
287         target.setQuserId(source.getQuser() != null ? source.getQuser().getQuserId() : null);
288         target.setRecDepId(source.getRecorderDepartment() != null ? source.getRecorderDepartment().getDepId() : null);
289 
290         // Occasions
291         if (CollectionUtils.isEmpty(source.getOccasions())) {
292             target.setOccasionVOs(null);
293         } else {
294             target.setOccasionVOs(occasionDao.toOccasionVOArray(source.getOccasions()));
295         }
296     }
297 
298     /**
299      * Retrieves the entity object that is associated with the specified value object
300      * from the object store. If no such entity object exists in the object store,
301      * a new, blank entity is created
302      */
303     private Campaign loadCampaignFromCampaignVO(CampaignVO campaignVO) {
304 
305         Campaign campaign = null;
306         if (campaignVO.getCampaignId() != null) {
307             campaign = get(campaignVO.getCampaignId());
308         }
309         if (campaign == null) {
310             campaign = Campaign.Factory.newInstance();
311         }
312         return campaign;
313     }
314 
315     /**
316      * {@inheritDoc}
317      */
318     public Campaign campaignVOToEntity(CampaignVO campaignVO) {
319 
320         Campaign entity = this.loadCampaignFromCampaignVO(campaignVO);
321         this.campaignVOToEntity(campaignVO, entity, true);
322         return entity;
323     }
324 
325     /**
326      * {@inheritDoc}
327      */
328     @Override
329     public void campaignVOToEntity(
330             CampaignVO source,
331             Campaign target,
332             boolean copyIfNull) {
333 
334         this.campaignVOToEntity(source, target, copyIfNull, false);
335     }
336 
337     /* -- protected méthods -- */
338 
339     protected void campaignVOToEntity(CampaignVO source, Campaign target, boolean copyIfNull, boolean withOccasions) {
340 
341         // copy base attributes
342         super.campaignVOToEntity(source, target, copyIfNull);
343 
344         // campaign id
345         if (copyIfNull || source.getCampaignId() != null) {
346             target.setCampaignId(source.getCampaignId());
347         }
348 
349         // quser
350         if (copyIfNull || source.getQuserId() != null) {
351             target.setQuser(source.getQuserId() != null ? load(QuserImpl.class, source.getQuserId()) : null);
352         }
353 
354         // recorder department
355         if (copyIfNull || source.getRecDepId() != null) {
356             target.setRecorderDepartment(source.getRecDepId() != null ? load(DepartmentImpl.class, source.getRecDepId()) : null);
357         }
358 
359         // Strategies
360         if (withOccasions)
361         {
362             if (copyIfNull || source.getOccasionVOs() != null) {
363                 if (source.getOccasionVOs() == null) {
364                     target.getOccasions().clear();
365                 } else {
366                     Daos.replaceEntities(target.getOccasions(),
367                             source.getOccasionVOs(),
368                             vo -> {
369                                 Occasion occasion = occasionDao.occasionVOToEntity(vo);
370                                 occasion.setCampaign(target);
371                                 return occasion;
372                             });
373                 }
374             }
375         }
376     }
377 
378 }