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.FractionDaoImpl;
34 import fr.ifremer.quadrige3.core.dao.referential.pmfm.Matrix;
35 import fr.ifremer.quadrige3.core.dao.referential.pmfm.MatrixImpl;
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("reefDbFractionDao")
60 public class ReefDbFractionDaoImpl extends FractionDaoImpl implements ReefDbFractionDao {
61
62 private static final Multimap<String, String> columnNamesByRulesTableNames = ImmutableListMultimap.<String, String>builder()
63 .put("RULE_PMFM", "FRACTION_ID").build();
64
65 private static final Multimap<String, String> columnNamesByReferentialTableNames = ImmutableListMultimap.<String, String>builder()
66 .put("FRACTION_MATRIX", "FRACTION_ID")
67 .put("PMFM", "FRACTION_ID").build();
68
69 @Resource
70 protected CacheService cacheService;
71
72 @Resource(name = "reefDbMatrixDao")
73 protected ReefDbMatrixDao matrixDao;
74
75
76
77
78
79
80 @Autowired
81 public ReefDbFractionDaoImpl(SessionFactory sessionFactory) {
82 super(sessionFactory);
83 }
84
85
86 @Override
87 public List<FractionDTO> getAllFractions(List<String> statusCodes) {
88
89 Iterator<Object[]> it = Daos.queryIteratorWithStatus(createQuery("allFractions"), statusCodes);
90
91 List<FractionDTO> result = Lists.newArrayList();
92 FractionDTO fraction = null;
93 while (it.hasNext()) {
94 Object[] row = it.next();
95 Iterator<Object> rowIt = Arrays.asList(row).iterator();
96
97 if (fraction == null || !fraction.getId().equals(row[0])) {
98 fraction = toFractionDTO(rowIt);
99 result.add(fraction);
100 } else {
101
102 toFractionDTO(rowIt);
103 }
104
105
106 Integer matrixId = (Integer) rowIt.next();
107 if (matrixId != null) {
108 MatrixDTO matrix = matrixDao.getMatrixById(matrixId);
109 fraction.addMatrixes(matrix);
110 matrix.addFractions(fraction);
111 }
112 }
113
114 return ImmutableList.copyOf(result);
115 }
116
117
118 @Override
119 public FractionDTO getFractionById(int fractionId) {
120
121 Iterator<Object[]> it = queryIterator("fractionById", "fractionId", IntegerType.INSTANCE, fractionId);
122
123 if (!it.hasNext()) {
124 throw new DataRetrievalFailureException("can't load fraction with id = " + fractionId);
125 }
126
127 FractionDTO fraction = null;
128 while (it.hasNext()) {
129 Object[] row = it.next();
130 Iterator<Object> rowIt = Arrays.asList(row).iterator();
131 if (fraction == null) {
132 fraction = toFractionDTO(rowIt);
133 } else {
134 toFractionDTO(rowIt);
135 }
136
137 Integer matrixId = (Integer) rowIt.next();
138 if (matrixId != null) {
139 MatrixDTO matrix = matrixDao.getMatrixById(matrixId);
140 fraction.addMatrixes(matrix);
141 matrix.addFractions(fraction);
142 }
143 }
144 return fraction;
145 }
146
147
148 @Override
149 public List<FractionDTO> getFractionsByMatrixId(Integer matrixId) {
150 Iterator<Object[]> it = queryIterator("fractionsByMatrixId", "matrixId", IntegerType.INSTANCE, matrixId);
151
152 List<FractionDTO> result = Lists.newArrayList();
153 while (it.hasNext()) {
154 Object[] row = it.next();
155 result.add(toFractionDTO(Arrays.asList(row).iterator()));
156 }
157
158 return ImmutableList.copyOf(result);
159
160 }
161
162
163 @Override
164 public List<FractionDTO> findFractions(Integer fractionId, List<String> statusCodes) {
165
166 Query query = createQuery("fractionByCriteria", "fractionId", IntegerType.INSTANCE, fractionId);
167 Iterator<Object[]> it = Daos.queryIteratorWithStatus(query, statusCodes);
168
169 List<FractionDTO> result = Lists.newArrayList();
170 FractionDTO fraction = null;
171 while (it.hasNext()) {
172 Object[] row = it.next();
173 Iterator<Object> rowIt = Arrays.asList(row).iterator();
174
175 if (fraction == null || !fraction.getId().equals(row[0])) {
176 fraction = toFractionDTO(rowIt);
177 result.add(fraction);
178 } else {
179
180 toFractionDTO(rowIt);
181 }
182
183
184 Integer matrixId = (Integer) rowIt.next();
185 if (matrixId != null) {
186 MatrixDTO matrix = matrixDao.getMatrixById(matrixId);
187 fraction.addMatrixes(matrix);
188 matrix.addFractions(fraction);
189 }
190 }
191
192 return ImmutableList.copyOf(result);
193
194 }
195
196
197 @Override
198 public void saveFractions(List<? extends FractionDTO> fractions) {
199 if (CollectionUtils.isEmpty(fractions)) {
200 return;
201 }
202
203 for (FractionDTO fraction : fractions) {
204 if (fraction.isDirty()) {
205 saveFraction(fraction);
206 fraction.setDirty(false);
207 }
208 }
209 getSession().flush();
210 getSession().clear();
211 }
212
213
214 @Override
215 public void deleteFractions(List<Integer> fractionIds) {
216 if (fractionIds == null) return;
217 fractionIds.stream().filter(Objects::nonNull).distinct().forEach(this::remove);
218 getSession().flush();
219 getSession().clear();
220 }
221
222
223 @Override
224 public void replaceTemporaryFraction(Integer sourceId, Integer targetId, boolean delete) {
225 Assert.notNull(sourceId);
226 Assert.notNull(targetId);
227
228 executeMultipleUpdate(columnNamesByReferentialTableNames, sourceId, targetId);
229
230 if (delete) {
231
232 remove(sourceId);
233 }
234
235 getSession().flush();
236 getSession().clear();
237 }
238
239
240 @Override
241 public boolean isFractionUsedInProgram(int fractionId) {
242
243 return queryCount("countPmfmStrategyByFractionId", "fractionId", IntegerType.INSTANCE, fractionId) > 0;
244 }
245
246
247 @Override
248 public boolean isFractionUsedInRules(int fractionId) {
249
250 return executeMultipleCount(columnNamesByRulesTableNames, fractionId);
251 }
252
253
254 @Override
255 public boolean isFractionUsedInReferential(int fractionId) {
256
257 return executeMultipleCount(columnNamesByReferentialTableNames, fractionId) || isFractionUsedInRules(fractionId);
258 }
259
260 private void saveFraction(FractionDTO fraction) {
261 Assert.notNull(fraction);
262 Assert.notBlank(fraction.getName());
263
264 if (fraction.getStatus() == null) {
265 fraction.setStatus(Daos.getStatus(StatusCode.LOCAL_ENABLE));
266 }
267 Assert.isTrue(ReefDbBeans.isLocalStatus(fraction.getStatus()), "source must have local status");
268
269 Fraction target;
270 if (fraction.getId() == null) {
271 target = Fraction.Factory.newInstance();
272 target.setFractionId(TemporaryDataHelper.getNewNegativeIdForTemporaryData(getSession(), target.getClass()));
273 } else {
274 target = get(fraction.getId());
275 Assert.isTrue(ReefDbBeans.isLocalStatus(target.getStatus()), "target must have local status");
276 }
277
278 target.setFractionNm(fraction.getName());
279 target.setFractionDc(fraction.getDescription());
280 target.setStatus(load(StatusImpl.class, fraction.getStatus().getCode()));
281 if (target.getFractionCreationDt() == null) {
282 target.setFractionCreationDt(newCreateDate());
283 }
284 target.setUpdateDt(newUpdateTimestamp());
285
286 getSession().save(target);
287 fraction.setId(target.getFractionId());
288
289
290 if (fraction.sizeMatrixes() > 0) {
291
292 Map<Integer, Matrix> remainingMatrices = ReefDbBeans.mapByProperty(target.getMatrixes(), "matrixId");
293 for (MatrixDTO matrix : fraction.getMatrixes()) {
294 if (remainingMatrices.remove(matrix.getId()) == null) {
295
296 target.addMatrixes(load(MatrixImpl.class, matrix.getId()));
297 }
298 }
299
300 if (!remainingMatrices.isEmpty()) {
301 target.getMatrixes().removeAll(remainingMatrices.values());
302 }
303
304 } else if (target.getMatrixes() != null) {
305 target.getMatrixes().clear();
306 }
307
308 getSession().save(target);
309 }
310
311 private FractionDTO toFractionDTO(Iterator<Object> source) {
312 FractionDTO result = ReefDbBeanFactory.newFractionDTO();
313 result.setId((Integer) source.next());
314 result.setName((String) source.next());
315 result.setDescription((String) source.next());
316 result.setStatus(Daos.getStatus((String) source.next()));
317 result.setComment((String) source.next());
318 result.setCreationDate(Daos.convertToDate(source.next()));
319 result.setUpdateDate(Daos.convertToDate(source.next()));
320 return result;
321 }
322
323 }