1 package fr.ifremer.reefdb.dao.referential.pmfm;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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
57
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
77
78
79
80 @Autowired
81 public ReefDbMatrixDaoImpl(SessionFactory sessionFactory) {
82 super(sessionFactory);
83 }
84
85
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
96 matrix.addAllFractions(fractionDao.getFractionsByMatrixId(matrix.getId()));
97 result.add(matrix);
98 }
99
100 return ImmutableList.copyOf(result);
101 }
102
103
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
116 result.addAllFractions(fractionDao.getFractionsByMatrixId(result.getId()));
117
118 return result;
119 }
120
121
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
133 matrix.addAllFractions(fractionDao.getFractionsByMatrixId(matrix.getId()));
134
135 result.add(matrix);
136 }
137
138 return ImmutableList.copyOf(result);
139
140 }
141
142
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
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
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
178 remove(sourceId);
179 }
180
181 getSession().flush();
182 getSession().clear();
183 }
184
185
186 @Override
187 public boolean isMatrixUsedInProgram(int matrixId) {
188
189 return queryCount("countPmfmStrategyByMatrixId", "matrixId", IntegerType.INSTANCE, matrixId) > 0;
190 }
191
192
193 @Override
194 public boolean isMatrixUsedInRules(int matrixId) {
195
196 return executeMultipleCount(columnNamesByRulesTableNames, matrixId);
197 }
198
199
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
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
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 }