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  import fr.ifremer.quadrige3.core.dao.administration.user.DepartmentImpl;
26  import fr.ifremer.quadrige3.core.dao.referential.FrequencyImpl;
27  import fr.ifremer.quadrige3.core.dao.referential.monitoringLocation.MonitoringLocationImpl;
28  import fr.ifremer.quadrige3.core.dao.referential.taxon.ReferenceTaxonImpl;
29  import fr.ifremer.quadrige3.core.dao.referential.taxon.TaxonGroupImpl;
30  import fr.ifremer.quadrige3.core.dao.technical.Assert;
31  import fr.ifremer.quadrige3.core.dao.technical.Beans;
32  import fr.ifremer.quadrige3.core.dao.technical.Daos;
33  import fr.ifremer.quadrige3.core.exception.QuadrigeTechnicalException;
34  import fr.ifremer.quadrige3.core.vo.administration.strategy.AppliedPeriodVO;
35  import fr.ifremer.quadrige3.core.vo.administration.strategy.AppliedStrategyVO;
36  import fr.ifremer.quadrige3.core.vo.administration.strategy.PmfmAppliedStrategyVO;
37  import org.apache.commons.collections4.CollectionUtils;
38  import org.apache.commons.collections4.MapUtils;
39  import org.apache.commons.lang3.ArrayUtils;
40  import org.hibernate.SessionFactory;
41  import org.springframework.beans.factory.annotation.Autowired;
42  import org.springframework.context.annotation.Lazy;
43  import org.springframework.stereotype.Repository;
44  
45  import javax.annotation.Resource;
46  import java.sql.Timestamp;
47  import java.util.Collection;
48  import java.util.Map;
49  
50  /**
51   * <p>
52   * AppliedStrategyDaoImpl class.
53   * </p>
54   * 
55   * @see AppliedStrategy
56   */
57  @Repository("appliedStrategyDao")
58  @Lazy
59  public class AppliedStrategyDaoImpl
60  		extends AppliedStrategyDaoBase
61  {
62  	@Resource
63  	private AppliedPeriodDao appliedPeriodDao;
64  
65  	@Resource
66  	private PmfmAppliedStrategyDao pmfmAppliedStrategyDao;
67  
68  	/**
69  	 * Constructor used by Spring
70  	 * 
71  	 * @param sessionFactory
72  	 *            a {@link org.hibernate.SessionFactory} object.
73  	 */
74  	@Autowired
75  	public AppliedStrategyDaoImpl(SessionFactory sessionFactory) {
76  		super();
77  		setSessionFactory(sessionFactory);
78  	}
79  
80  	/** {@inheritDoc} */
81  	@Override
82  	public void remove(Collection<AppliedStrategy> entities) {
83  		Assert.notEmpty(entities);
84  
85  		entities.forEach(this::remove);
86  	}
87  
88  	/** {@inheritDoc} */
89  	@Override
90  	public void remove(Integer stratId) {
91  		AppliedStrategy entity = get(stratId);
92  		remove(entity);
93  	}
94  
95  	/** {@inheritDoc} */
96  	@Override
97  	public void remove(AppliedStrategy entity) {
98  
99  		// Remove applied periods
100 		if (CollectionUtils.isNotEmpty(entity.getAppliedPeriods())) {
101 			appliedPeriodDao.remove(entity.getAppliedPeriods());
102 			entity.getAppliedPeriods().clear();
103 		}
104 
105 		// Remove Pmfm applied strategies
106 		if (CollectionUtils.isNotEmpty(entity.getPmfmAppliedStrategies())) {
107 			pmfmAppliedStrategyDao.remove(entity.getPmfmAppliedStrategies());
108 			entity.getPmfmAppliedStrategies().clear();
109 		}
110 
111 		super.remove(entity);
112 	}
113 
114 	/** {@inheritDoc} */
115 	public void toAppliedStrategyVO(
116 			AppliedStrategy source,
117 			AppliedStrategyVO target)
118 	{
119 		super.toAppliedStrategyVO(source, target);
120 
121 		// Strategy
122 		if (source.getStrategy() == null) {
123 			target.setStratId(null);
124 		}
125 		else {
126 			target.setStratId(source.getStrategy().getStratId());
127 		}
128 
129 		// Analysis department
130 		if (source.getDepartment() == null) {
131 			target.setDepId(null);
132 		}
133 		else {
134 			target.setDepId(source.getDepartment().getDepId());
135 		}
136 
137 		// Taxon group
138 		if (source.getTaxonGroup() == null) {
139 			target.setTaxonGroupId(null);
140 		}
141 		else {
142 			target.setTaxonGroupId(source.getTaxonGroup().getTaxonGroupId());
143 		}
144 
145 		// Reference taxon
146 		if (source.getReferenceTaxon() == null) {
147 			target.setRefTaxonId(null);
148 		}
149 		else {
150 			target.setRefTaxonId(source.getReferenceTaxon().getRefTaxonId());
151 		}
152 
153 		// Monitoring location
154 		if (source.getMonitoringLocation() == null) {
155 			target.setMonLocId(null);
156 		}
157 		else {
158 			target.setMonLocId(source.getMonitoringLocation().getMonLocId());
159 		}
160 
161 		// Frequency
162 		if (source.getFrequency() == null) {
163 			target.setFreqCd(null);
164 		}
165 		else {
166 			target.setFreqCd(source.getFrequency().getFreqCd());
167 		}
168 
169 		// Applied period
170 		if (CollectionUtils.isEmpty(source.getAppliedPeriods())) {
171 			target.setAppliedPeriodVOs(null);
172 		}
173 		else {
174 			target.setAppliedPeriodVOs(appliedPeriodDao.toAppliedPeriodVOArray(source.getAppliedPeriods()));
175 		}
176 
177 		// Pmfm applied strategies
178 		if (CollectionUtils.isEmpty(source.getPmfmAppliedStrategies())) {
179 			target.setPmfmAppliedStrategyVOs(null);
180 		}
181 		else {
182 			target.setPmfmAppliedStrategyVOs(pmfmAppliedStrategyDao.toPmfmAppliedStrategyVOArray(source.getPmfmAppliedStrategies()));
183 		}
184 	}
185 
186 	/**
187 	 * Retrieves the entity object that is associated with the specified value object
188 	 * from the object store. If no such entity object exists in the object store,
189 	 * a new, blank entity is created
190 	 */
191 	private AppliedStrategy loadAppliedStrategyFromAppliedStrategyVO(AppliedStrategyVO appliedStrategyVO)
192 	{
193 		AppliedStrategy appliedStrategy = null;
194 		if (appliedStrategyVO.getAppliedStratId() != null) {
195 			appliedStrategy = this.get(appliedStrategyVO.getAppliedStratId());
196 		}
197 		if (appliedStrategy == null)
198 		{
199 			appliedStrategy = AppliedStrategy.Factory.newInstance();
200 		}
201 		return appliedStrategy;
202 	}
203 
204 	/** {@inheritDoc} */
205 	public AppliedStrategy appliedStrategyVOToEntity(AppliedStrategyVO appliedStrategyVO)
206 	{
207 		AppliedStrategy entity = this.loadAppliedStrategyFromAppliedStrategyVO(appliedStrategyVO);
208 		this.appliedStrategyVOToEntity(appliedStrategyVO, entity, true);
209 		return entity;
210 	}
211 
212 	/** {@inheritDoc} */
213 	@Override
214 	public void appliedStrategyVOToEntity(
215 			AppliedStrategyVO source,
216 			AppliedStrategy target,
217 			boolean copyIfNull)
218 	{
219 		appliedStrategyVOToEntity(source, target, copyIfNull, null, false, false);
220 
221 	}
222 
223 	/* -- Internal methods -- */
224 
225 	/** {@inheritDoc} */
226 	@Override
227 	protected AppliedStrategyVO handleSave(AppliedStrategyVO source, Map<Integer, Integer> pmfmStratIdMapping, Timestamp updateDt) {
228 		Assert.notNull(source, "no source to save");
229 		Assert.isTrue(source.getStratId() != null || (source.getStrategyVO() != null && source.getStrategyVO().getStratId() != null), "must have a valid strategy id");
230 
231 		// Load
232 		Integer stratId = source.getStratId();
233 		if (stratId == null) {
234 			stratId = source.getStrategyVO().getStratId();
235 		}
236 		Strategy parent = get(StrategyImpl.class, stratId);
237 
238 		// Load entity
239 		AppliedStrategy entity = null;
240 		boolean isNew = false;
241 		if (source.getAppliedStratId() != null) {
242 			entity = get(source.getAppliedStratId());
243 		}
244 		if (entity == null) {
245 			entity = AppliedStrategy.Factory.newInstance();
246 			parent.addAppliedStrategies(entity);
247 			entity.setStrategy(parent);
248 			entity.setAppliedStratId(source.getAppliedStratId()); // assigned id
249 			isNew = true;
250 		}
251 
252 		// update update_dt
253 		// NOT NEED on a client database
254 
255 		// VO -> Entity
256 		appliedStrategyVOToEntity(source, entity, true, updateDt, false, false);
257 
258 		// Save entity
259 		if (isNew) {
260 			Integer appliedStratId = (Integer) getSession().save(entity);
261 			source.setAppliedStratId(appliedStratId);
262 		} else {
263 			getSession().update(entity);
264 		}
265 
266 		// Keep trace of items to remove
267 		Map<AppliedPeriodPK, AppliedPeriod> appliedPeriodsToRemove = Beans.mapByProperty(entity.getAppliedPeriods(), "appliedPeriodPk");
268 		Map<PmfmAppliedStrategyPK, PmfmAppliedStrategy> pmfmAppliedStrategiesToRemove = Beans.mapByProperty(entity.getPmfmAppliedStrategies(),
269 				"pmfmAppliedStrategyPk");
270 
271 		// Applied periods
272 		if (ArrayUtils.isNotEmpty(source.getAppliedPeriodVOs())) {
273 			for (AppliedPeriodVO appliedPeriodVO : source.getAppliedPeriodVOs()) {
274 
275 				// Make sure the link to current entity is OK
276 				appliedPeriodVO.setAppliedStratId(entity.getAppliedStratId());
277 
278 				// call dao save
279 				appliedPeriodVO = appliedPeriodDao.save(appliedPeriodVO, updateDt);
280 
281 				// Remove from items to remove
282 				AppliedPeriod appliedPeriodEntity = appliedPeriodDao.appliedPeriodVOToEntity(appliedPeriodVO);
283 				boolean isNewAppliedPeriod = (appliedPeriodsToRemove.remove(appliedPeriodEntity.getAppliedPeriodPk()) == null);
284 
285 				// If need, add it to the applied strategy
286 				if (isNewAppliedPeriod) {
287 					entity.addAppliedPeriods(appliedPeriodEntity);
288 				}
289 			}
290 		}
291 
292 		// Pmfm applied strategies
293 		if (ArrayUtils.isNotEmpty(source.getPmfmAppliedStrategyVOs())) {
294 			for (PmfmAppliedStrategyVO pmfmAppliedStrategyVO : source.getPmfmAppliedStrategyVOs()) {
295 
296 				pmfmAppliedStrategyVO.setAppliedStratId(entity.getAppliedStratId());
297 
298 				// Remap pmfm strat id
299 				Integer newPmfmStratId = pmfmStratIdMapping.get(pmfmAppliedStrategyVO.getPmfmStratId());
300 				if (newPmfmStratId == null) {
301 					throw new QuadrigeTechnicalException(String.format(
302 							"Could not retrieve a valid PMFM_STRAT_ID for the given PMFM_APPLIED_STRATEGY.PMFM_STRAT_ID [%s]",
303 							pmfmAppliedStrategyVO.getPmfmStratId()));
304 				}
305 				pmfmAppliedStrategyVO.setPmfmStratId(newPmfmStratId);
306 
307 				PmfmAppliedStrategy pmfmAppliedStrategyEntity = pmfmAppliedStrategyDao.pmfmAppliedStrategyVOToEntity(pmfmAppliedStrategyVO);
308 				if (updateDt != null) {
309 					pmfmAppliedStrategyEntity.setUpdateDt(updateDt);
310 				}
311 
312 				getSession().saveOrUpdate(pmfmAppliedStrategyEntity);
313 
314 				// Remove from items to remove
315 				boolean isNewPmfmAppliedStrategy = (pmfmAppliedStrategiesToRemove.remove(pmfmAppliedStrategyEntity.getPmfmAppliedStrategyPk()) == null);
316 
317 				// If need, add it to the applied strategy
318 				if (isNewPmfmAppliedStrategy) {
319 					entity.addPmfmAppliedStrategies(pmfmAppliedStrategyEntity);
320 				}
321 			}
322 		}
323 
324 		// Remove unused applied periods
325 		if (MapUtils.isNotEmpty(appliedPeriodsToRemove)) {
326 			entity.getAppliedPeriods().removeAll(appliedPeriodsToRemove.values());
327 			appliedPeriodDao.remove(appliedPeriodsToRemove.values());
328 		}
329 
330 		// Remove unused pmfm applied strategy
331 		if (MapUtils.isNotEmpty(pmfmAppliedStrategiesToRemove)) {
332 			pmfmAppliedStrategyDao.remove(pmfmAppliedStrategiesToRemove.values());
333 			entity.getPmfmAppliedStrategies().removeAll(pmfmAppliedStrategiesToRemove.values());
334 		}
335 
336 		return source;
337 	}
338 
339 	@Override
340 	protected void handleCheckCanRemove(Collection<Integer> appliedStratIds) throws Exception {
341 		if (CollectionUtils.isEmpty(appliedStratIds))
342 			return;
343 
344 		for (Integer appliedStratId: appliedStratIds) {
345 			AppliedStrategy appliedStrategy = get(appliedStratId);
346 			if (CollectionUtils.isNotEmpty(appliedStrategy.getAppliedPeriods())) {
347 				String progCd = appliedStrategy.getStrategy().getProgram().getProgCd();
348 				Integer monLocId = appliedStrategy.getMonitoringLocation().getMonLocId();
349 				// iterate through applied periods
350 				for (AppliedPeriod period: appliedStrategy.getAppliedPeriods()) {
351 					appliedPeriodDao.checkCanRemove(appliedStratId, progCd, monLocId,
352 						period.getAppliedPeriodStartDt(), period.getAppliedPeriodEndDt());
353 				}
354 			}
355 		}
356 	}
357 
358 	/**
359 	 * <p>
360 	 * appliedStrategyVOToEntity.
361 	 * </p>
362 	 * 
363 	 * @param source
364 	 *            a {@link fr.ifremer.quadrige3.core.vo.administration.strategy.AppliedStrategyVO} object.
365 	 * @param target
366 	 *            a {@link fr.ifremer.quadrige3.core.dao.administration.strategy.AppliedStrategy} object.
367 	 * @param copyIfNull
368 	 *            a boolean.
369 	 * @param updateDt
370 	 *            a {@link java.sql.Timestamp} object.
371 	 * @param withAppliedPeriods
372 	 *            a boolean.
373 	 * @param withPmfmAppliedStrategies
374 	 *            a boolean.
375 	 */
376 	protected void appliedStrategyVOToEntity(
377 			AppliedStrategyVO source,
378 			AppliedStrategy target,
379 			boolean copyIfNull,
380 			final Timestamp updateDt,
381 			boolean withAppliedPeriods,
382 			boolean withPmfmAppliedStrategies)
383 	{
384 		super.appliedStrategyVOToEntity(source, target, copyIfNull);
385 
386 		// Strategy
387 		if (copyIfNull || source.getStratId() != null || source.getStrategyVO() != null) {
388 			if (source.getStratId() == null && source.getStrategyVO() == null) {
389 				target.setStrategy(null);
390 
391 			}
392 			else {
393 				Integer stratId = source.getStratId();
394 				if (stratId == null) {
395 					stratId = source.getStrategyVO().getStratId();
396 				}
397 				target.setStrategy(load(StrategyImpl.class, stratId));
398 			}
399 		}
400 
401 		// Analysis department
402 		if (copyIfNull || source.getDepId() != null)
403 		{
404 			if (source.getDepId() == null) {
405 				target.setDepartment(null);
406 			}
407 			else {
408 				target.setDepartment(load(DepartmentImpl.class, source.getDepId()));
409 			}
410 		}
411 
412 		// Taxon group
413 		if (copyIfNull || source.getTaxonGroupId() != null)
414 		{
415 			if (source.getTaxonGroupId() == null) {
416 				target.setTaxonGroup(null);
417 			}
418 			else {
419 				target.setTaxonGroup(load(TaxonGroupImpl.class, source.getTaxonGroupId()));
420 			}
421 		}
422 
423 		// Reference taxon
424 		if (copyIfNull || source.getRefTaxonId() != null)
425 		{
426 			if (source.getRefTaxonId() == null) {
427 				target.setReferenceTaxon(null);
428 			}
429 			else {
430 				target.setReferenceTaxon(load(ReferenceTaxonImpl.class, source.getRefTaxonId()));
431 			}
432 		}
433 
434 		// Monitoring location
435 		if (copyIfNull || source.getMonLocId() != null)
436 		{
437 			if (source.getMonLocId() == null) {
438 				target.setMonitoringLocation(null);
439 			}
440 			else {
441 				target.setMonitoringLocation(load(MonitoringLocationImpl.class, source.getMonLocId()));
442 			}
443 		}
444 
445 		// Frequency
446 		if (copyIfNull || source.getFreqCd() != null)
447 		{
448 			if (source.getFreqCd() == null) {
449 				target.setFrequency(null);
450 			}
451 			else {
452 				target.setFrequency(load(FrequencyImpl.class, source.getFreqCd()));
453 			}
454 		}
455 
456 		// Applied periods
457 		if (withAppliedPeriods) {
458 			fillAppliedPeriod(source, target, copyIfNull, updateDt);
459 		}
460 
461 		// Pmfm applied strategies
462 		if (withPmfmAppliedStrategies) {
463 			fillPmfmAppliedStrategies(source, target, copyIfNull, updateDt);
464 		}
465 	}
466 
467 	/**
468 	 * <p>
469 	 * fillAppliedPeriod.
470 	 * </p>
471 	 * 
472 	 * @param source
473 	 *            a {@link fr.ifremer.quadrige3.core.vo.administration.strategy.AppliedStrategyVO} object.
474 	 * @param target
475 	 *            a {@link fr.ifremer.quadrige3.core.dao.administration.strategy.AppliedStrategy} object.
476 	 * @param copyIfNull
477 	 *            a boolean.
478 	 * @param updateDt
479 	 *            a {@link java.sql.Timestamp} object.
480 	 */
481 	protected void fillAppliedPeriod(AppliedStrategyVO source,
482 			final AppliedStrategy target,
483 			boolean copyIfNull,
484 			final Timestamp updateDt) {
485 
486 		// Applied periods
487 		if (copyIfNull || ArrayUtils.isNotEmpty(source.getAppliedPeriodVOs())) {
488 			if (ArrayUtils.isEmpty(source.getAppliedPeriodVOs())) {
489 				target.getAppliedPeriods().clear();
490 			}
491 			else {
492 				Daos.replaceEntities(
493 						target.getAppliedPeriods(),
494 						source.getAppliedPeriodVOs(),
495 						appliedPeriod -> {
496                             AppliedPeriod entity = appliedPeriodDao.appliedPeriodVOToEntity(appliedPeriod);
497                             entity.setAppliedStrategy(target);
498                             if (updateDt != null) {
499                                 entity.setUpdateDt(updateDt);
500                             }
501                             return entity;
502                         });
503 			}
504 		}
505 	}
506 
507 	/**
508 	 * <p>
509 	 * fillPmfmAppliedStrategies.
510 	 * </p>
511 	 * 
512 	 * @param source
513 	 *            a {@link fr.ifremer.quadrige3.core.vo.administration.strategy.AppliedStrategyVO} object.
514 	 * @param target
515 	 *            a {@link fr.ifremer.quadrige3.core.dao.administration.strategy.AppliedStrategy} object.
516 	 * @param copyIfNull
517 	 *            a boolean.
518 	 * @param updateDt
519 	 *            a {@link java.sql.Timestamp} object.
520 	 */
521 	protected void fillPmfmAppliedStrategies(AppliedStrategyVO source,
522 			AppliedStrategy target,
523 			boolean copyIfNull,
524 			final Timestamp updateDt) {
525 
526 		// Pmfm applied strategies
527 		if (copyIfNull || ArrayUtils.isNotEmpty(source.getPmfmAppliedStrategyVOs())) {
528 			if (ArrayUtils.isEmpty(source.getPmfmAppliedStrategyVOs())) {
529 				target.getPmfmAppliedStrategies().clear();
530 			}
531 			else {
532 				Daos.replaceEntities(
533 						target.getPmfmAppliedStrategies(),
534 						source.getPmfmAppliedStrategyVOs(),
535 						pmfmAppliedStrategy -> pmfmAppliedStrategyDao.pmfmAppliedStrategyVOToEntity(pmfmAppliedStrategy));
536 			}
537 		}
538 	}
539 }