View Javadoc
1   package fr.ifremer.reefdb.dao.referential.pmfm;
2   
3   /*
4    * #%L
5    * Reef DB :: Core
6    * $Id:$
7    * $HeadURL:$
8    * %%
9    * Copyright (C) 2014 - 2015 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.ImmutableList;
27  import com.google.common.collect.ImmutableListMultimap;
28  import com.google.common.collect.Lists;
29  import com.google.common.collect.Multimap;
30  import fr.ifremer.quadrige3.core.dao.referential.StatusCode;
31  import fr.ifremer.quadrige3.core.dao.referential.StatusImpl;
32  import fr.ifremer.quadrige3.core.dao.referential.pmfm.Fraction;
33  import fr.ifremer.quadrige3.core.dao.referential.pmfm.FractionImpl;
34  import fr.ifremer.quadrige3.core.dao.referential.pmfm.Matrix;
35  import fr.ifremer.quadrige3.core.dao.referential.pmfm.MatrixDaoImpl;
36  import fr.ifremer.quadrige3.core.dao.technical.Assert;
37  import fr.ifremer.quadrige3.core.dao.technical.hibernate.TemporaryDataHelper;
38  import fr.ifremer.quadrige3.core.service.technical.CacheService;
39  import fr.ifremer.reefdb.dao.technical.Daos;
40  import fr.ifremer.reefdb.dto.ReefDbBeanFactory;
41  import fr.ifremer.reefdb.dto.ReefDbBeans;
42  import fr.ifremer.reefdb.dto.referential.pmfm.FractionDTO;
43  import fr.ifremer.reefdb.dto.referential.pmfm.MatrixDTO;
44  import org.apache.commons.collections4.CollectionUtils;
45  import org.hibernate.Query;
46  import org.hibernate.SessionFactory;
47  import org.hibernate.type.IntegerType;
48  import org.springframework.beans.factory.annotation.Autowired;
49  import org.springframework.dao.DataRetrievalFailureException;
50  import org.springframework.stereotype.Repository;
51  
52  import javax.annotation.Resource;
53  import java.util.*;
54  
55  /**
56   * Matrix DAO
57   * Created by Ludovic on 29/07/2015.
58   */
59  @Repository("reefDbMatrixDao")
60  public class ReefDbMatrixDaoImpl extends MatrixDaoImpl implements ReefDbMatrixDao {
61  
62      private static final Multimap<String, String> columnNamesByRulesTableNames = ImmutableListMultimap.<String, String>builder()
63              .put("RULE_PMFM", "MATRIX_ID").build();
64  
65      private static final Multimap<String, String> columnNamesByReferentialTableNames = ImmutableListMultimap.<String, String>builder()
66              .put("FRACTION_MATRIX", "MATRIX_ID")
67              .put("PMFM", "MATRIX_ID").build();
68  
69      @Resource
70      protected CacheService cacheService;
71  
72      @Resource(name = "reefDbFractionDao")
73      protected ReefDbFractionDao fractionDao;
74  
75      /**
76       * Constructor used by Spring
77       *
78       * @param sessionFactory a {@link org.hibernate.SessionFactory} object.
79       */
80      @Autowired
81      public ReefDbMatrixDaoImpl(SessionFactory sessionFactory) {
82          super(sessionFactory);
83      }
84  
85      /** {@inheritDoc} */
86      @Override
87      public List<MatrixDTO> getAllMatrices(List<String> statusCodes) {
88  
89          Iterator<Object[]> it = Daos.queryIteratorWithStatus(createQuery("allMatrices"), statusCodes);
90  
91          List<MatrixDTO> result = Lists.newArrayList();
92          while (it.hasNext()) {
93              Object[] source = it.next();
94              MatrixDTO matrix = toMatrixDTO(Arrays.asList(source).iterator());
95              // add fractions
96              matrix.addAllFractions(fractionDao.getFractionsByMatrixId(matrix.getId()));
97              result.add(matrix);
98          }
99  
100         return ImmutableList.copyOf(result);
101     }
102 
103     /** {@inheritDoc} */
104     @Override
105     public MatrixDTO getMatrixById(int matrixId) {
106 
107         Object[] source = queryUnique("matrixById", "matrixId", IntegerType.INSTANCE, matrixId);
108 
109         if (source == null) {
110             throw new DataRetrievalFailureException("can't load matrix with id = " + matrixId);
111         }
112 
113         MatrixDTO result = toMatrixDTO(Arrays.asList(source).iterator());
114 
115         // add fractions
116         result.addAllFractions(fractionDao.getFractionsByMatrixId(result.getId()));
117 
118         return result;
119     }
120 
121     /** {@inheritDoc} */
122     @Override
123     public List<MatrixDTO> findMatrices(Integer matrixId, List<String> statusCodes) {
124 
125         Query query = createQuery("matrixByCriteria", "matrixId", IntegerType.INSTANCE, matrixId);
126         Iterator<Object[]> it = Daos.queryIteratorWithStatus(query, statusCodes);
127 
128         List<MatrixDTO> result = Lists.newArrayList();
129         while (it.hasNext()) {
130             Object[] source = it.next();
131             MatrixDTO matrix = toMatrixDTO(Arrays.asList(source).iterator());
132             // add fractions
133             matrix.addAllFractions(fractionDao.getFractionsByMatrixId(matrix.getId()));
134 
135             result.add(matrix);
136         }
137 
138         return ImmutableList.copyOf(result);
139 
140     }
141 
142     /** {@inheritDoc} */
143     @Override
144     public void saveMatrices(List<? extends MatrixDTO> matrices) {
145         if (CollectionUtils.isEmpty(matrices)) {
146             return;
147         }
148 
149         for (MatrixDTO matrix : matrices) {
150             if (matrix.isDirty()) {
151                 saveMatrix(matrix);
152                 matrix.setDirty(false);
153             }
154         }
155         getSession().flush();
156         getSession().clear();
157     }
158 
159     /** {@inheritDoc} */
160     @Override
161     public void deleteMatrices(List<Integer> matrixIds) {
162         if (matrixIds == null) return;
163         matrixIds.stream().filter(Objects::nonNull).distinct().forEach(this::remove);
164         getSession().flush();
165         getSession().clear();
166     }
167 
168     /** {@inheritDoc} */
169     @Override
170     public void replaceTemporaryMatrix(Integer sourceId, Integer targetId, boolean delete) {
171         Assert.notNull(sourceId);
172         Assert.notNull(targetId);
173 
174         executeMultipleUpdate(columnNamesByReferentialTableNames, sourceId, targetId);
175 
176         if (delete) {
177             // delete temporary
178             remove(sourceId);
179         }
180 
181         getSession().flush();
182         getSession().clear();
183     }
184 
185     /** {@inheritDoc} */
186     @Override
187     public boolean isMatrixUsedInProgram(int matrixId) {
188 
189         return queryCount("countPmfmStrategyByMatrixId", "matrixId", IntegerType.INSTANCE, matrixId) > 0;
190    }
191 
192     /** {@inheritDoc} */
193     @Override
194     public boolean isMatrixUsedInRules(int matrixId) {
195 
196         return executeMultipleCount(columnNamesByRulesTableNames, matrixId);
197     }
198 
199     /** {@inheritDoc} */
200     @Override
201     public boolean isMatrixUsedInReferential(int matrixId) {
202 
203         return executeMultipleCount(columnNamesByReferentialTableNames, matrixId) || isMatrixUsedInRules(matrixId);
204     }
205 
206     private void saveMatrix(MatrixDTO matrix) {
207         Assert.notNull(matrix);
208         Assert.notBlank(matrix.getName());
209 
210         if (matrix.getStatus() == null) {
211             matrix.setStatus(Daos.getStatus(StatusCode.LOCAL_ENABLE));
212         }
213         Assert.isTrue(ReefDbBeans.isLocalStatus(matrix.getStatus()), "source must have local status");
214 
215         Matrix target;
216         if (matrix.getId() == null) {
217             target = Matrix.Factory.newInstance();
218             target.setMatrixId(TemporaryDataHelper.getNewNegativeIdForTemporaryData(getSession(), target.getClass()));
219         } else {
220             target = get(matrix.getId());
221             Assert.isTrue(ReefDbBeans.isLocalStatus(target.getStatus()), "target must have local status");
222         }
223 
224         target.setStatus(load(StatusImpl.class, matrix.getStatus().getCode()));
225         target.setMatrixNm(matrix.getName());
226         target.setMatrixDc(matrix.getDescription());
227         if (target.getMatrixCreationDt() == null) {
228             target.setMatrixCreationDt(newCreateDate());
229         }
230         target.setUpdateDt(newUpdateTimestamp());
231 
232         getSession().save(target);
233         matrix.setId(target.getMatrixId());
234 
235         // save associated fractions
236         if (matrix.sizeFractions() > 0) {
237 
238             Map<Integer, Fraction> remainingFractions = ReefDbBeans.mapByProperty(target.getFractions(), "fractionId");
239             for (FractionDTO fraction : matrix.getFractions()) {
240                 if (remainingFractions.remove(fraction.getId()) == null) {
241                     // add fraction
242                     target.addFractions(load(FractionImpl.class, fraction.getId()));
243                 }
244             }
245 
246             if (!remainingFractions.isEmpty()) {
247                 target.getFractions().removeAll(remainingFractions.values());
248             }
249 
250         } else if (target.getFractions() != null) {
251             target.getFractions().clear();
252         }
253 
254         getSession().save(target);
255 
256     }
257 
258     private MatrixDTO toMatrixDTO(Iterator<Object> source) {
259         MatrixDTO result = ReefDbBeanFactory.newMatrixDTO();
260         result.setId((Integer) source.next());
261         result.setName((String) source.next());
262         result.setDescription((String) source.next());
263         result.setStatus(Daos.getStatus((String) source.next()));
264         result.setComment((String) source.next());
265         result.setCreationDate(Daos.convertToDate(source.next()));
266         result.setUpdateDate(Daos.convertToDate(source.next()));
267         return result;
268     }
269 
270 }