1 package fr.ifremer.dali.dao.referential.taxon;
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.*;
27 import fr.ifremer.dali.config.DaliConfiguration;
28 import fr.ifremer.dali.dao.referential.DaliReferentialDao;
29 import fr.ifremer.dali.dao.technical.Daos;
30 import fr.ifremer.dali.dto.DaliBeanFactory;
31 import fr.ifremer.dali.dto.referential.CitationDTO;
32 import fr.ifremer.dali.dto.referential.TaxonDTO;
33 import fr.ifremer.quadrige3.core.dao.referential.StatusCode;
34 import fr.ifremer.quadrige3.core.dao.referential.TaxonGroupTypeCode;
35 import fr.ifremer.quadrige3.core.dao.referential.taxon.TaxonNameDaoImpl;
36 import fr.ifremer.quadrige3.core.dao.technical.Dates;
37 import fr.ifremer.quadrige3.core.service.technical.CacheService;
38 import org.apache.commons.collections4.CollectionUtils;
39 import org.apache.commons.lang3.StringUtils;
40 import org.apache.commons.logging.Log;
41 import org.apache.commons.logging.LogFactory;
42 import org.hibernate.SessionFactory;
43 import org.hibernate.type.DateType;
44 import org.hibernate.type.IntegerType;
45 import org.hibernate.type.StringType;
46 import org.springframework.beans.factory.annotation.Autowired;
47 import org.springframework.cache.Cache;
48 import org.springframework.dao.DataRetrievalFailureException;
49 import org.springframework.stereotype.Repository;
50
51 import javax.annotation.Nonnull;
52 import javax.annotation.Resource;
53 import java.time.LocalDate;
54 import java.util.*;
55 import java.util.stream.Collectors;
56
57
58
59
60
61 @Repository("daliTaxonNameDao")
62 public class DaliTaxonNameDaoImpl extends TaxonNameDaoImpl implements DaliTaxonNameDao {
63
64 private static final Log LOG = LogFactory.getLog(DaliTaxonNameDaoImpl.class);
65
66 @Resource
67 protected CacheService cacheService;
68
69 @Resource
70 protected DaliConfiguration config;
71
72 @Resource(name = "daliReferentialDao")
73 private DaliReferentialDao referentialDao;
74
75 @Resource(name = "daliTaxonNameDao")
76 private DaliTaxonNameDao loopbackTaxonNameDao;
77
78
79
80
81
82
83 @Autowired
84 public DaliTaxonNameDaoImpl(SessionFactory sessionFactory) {
85 super(sessionFactory);
86 }
87
88
89 @Override
90 public List<TaxonDTO> getAllTaxonNames() {
91
92 Cache cacheByReferenceId = cacheService.getCache(TAXON_NAME_BY_REFERENCE_ID_CACHE);
93 Cache cacheById = cacheService.getCache(TAXON_NAME_BY_ID_CACHE);
94
95 Map<Integer, String> taxRefMap = loopbackTaxonNameDao.getTaxRefByTaxonNameId();
96 Map<Integer, String> wormsMap = loopbackTaxonNameDao.getWormsByTaxonNameId();
97
98 Iterator<Object[]> it = queryIterator("allTaxonName");
99
100 long nbTaxonName = 0;
101 long nbRefTaxon = 0;
102 List<TaxonDTO> result = new ArrayList<>();
103 while (it.hasNext()) {
104 Object[] source = it.next();
105 TaxonDTO taxon = toTaxonDTO(Arrays.asList(source).iterator());
106
107
108 taxon.setTaxRef(taxRefMap.get(taxon.getId()));
109 taxon.setWormsRef(wormsMap.get(taxon.getId()));
110
111 result.add(taxon);
112
113
114 cacheById.put(taxon.getId(), taxon);
115 nbTaxonName++;
116
117 if (taxon.isReferent()) {
118 cacheByReferenceId.put(taxon.getReferenceTaxonId(), taxon);
119 nbRefTaxon++;
120 }
121 }
122
123 if (LOG.isDebugEnabled()) {
124 LOG.debug(String.format("%s Taxon name loaded, %s reference taxon loaded", nbTaxonName, nbRefTaxon));
125 }
126 return ImmutableList.copyOf(result);
127 }
128
129
130 @Override
131 public TaxonDTO getTaxonNameByReferenceId(int referenceTaxonId) {
132
133 Object[] source = queryUnique("taxonNameByReferenceId", "taxonReferenceId", IntegerType.INSTANCE, referenceTaxonId);
134
135 if (source == null) {
136 throw new DataRetrievalFailureException("Can't load taxon name with reference taxon id = " + referenceTaxonId);
137 }
138
139 return toTaxonDTO(Arrays.asList(source).iterator());
140 }
141
142
143 @Override
144 public TaxonDTO getTaxonNameById(int taxonId) {
145
146 Object[] source = queryUnique("taxonNameById", "taxonNameId", IntegerType.INSTANCE, taxonId);
147
148 if (source == null) {
149 return null;
150 }
151
152 TaxonDTO taxon = toTaxonDTO(Arrays.asList(source).iterator());
153 fillReferent(taxon);
154 return taxon;
155 }
156
157
158 @Override
159 public Multimap<Integer, TaxonDTO> getAllTaxonNamesMapByTaxonGroupId(@Nonnull LocalDate date) {
160
161 Iterator<Object[]> it = queryIterator("taxonNameIdsWithTaxonGroupId",
162 "referenceDate", DateType.INSTANCE, Dates.convertToDate(date, config.getDbTimezone()),
163 "taxonGroupTypeCode", StringType.INSTANCE, TaxonGroupTypeCode.IDENTIFICATION.getValue());
164
165 Multimap<Integer, TaxonDTO> result = ArrayListMultimap.create();
166 while (it.hasNext()) {
167 Object[] source = it.next();
168 Iterator<Object> row = Arrays.asList(source).iterator();
169 Integer taxonGroupId = (Integer) row.next();
170 result.put(taxonGroupId, loopbackTaxonNameDao.getTaxonNameById((Integer) row.next()));
171 }
172 return result;
173 }
174
175
176 @Override
177 public List<TaxonDTO> getTaxonNamesByIds(List<Integer> taxonIds) {
178
179 if (CollectionUtils.isEmpty(taxonIds)) return new ArrayList<>();
180
181 return loopbackTaxonNameDao.getAllTaxonNames().stream().filter(taxon -> taxonIds.contains(taxon.getId())).collect(Collectors.toList());
182 }
183
184
185 @Override
186 public void fillTaxonsProperties(List<TaxonDTO> taxons) {
187
188 if (CollectionUtils.isEmpty(taxons)) {
189 return;
190 }
191
192 Map<Integer, String> taxRefMap = loopbackTaxonNameDao.getTaxRefByTaxonNameId();
193 Map<Integer, String> wormsMap = loopbackTaxonNameDao.getWormsByTaxonNameId();
194
195 for (TaxonDTO taxon : taxons) {
196
197
198 fillParentAndReferent(taxon);
199
200
201 if (taxon.isVirtual()) {
202 taxon.setCompositeTaxons(loopbackTaxonNameDao.getCompositeTaxonNames(taxon.getId()));
203 }
204
205
206 taxon.setTaxRef(taxRefMap.get(taxon.getId()));
207 taxon.setWormsRef(wormsMap.get(taxon.getId()));
208
209 }
210 }
211
212 private void fillTaxonProperties(TaxonDTO taxon) {
213
214
215 fillParentAndReferent(taxon);
216
217
218 taxon.setTaxRef(loopbackTaxonNameDao.getTaxRefByTaxonNameId().get(taxon.getId()));
219 taxon.setWormsRef(loopbackTaxonNameDao.getWormsByTaxonNameId().get(taxon.getId()));
220
221 }
222
223
224 @Override
225 public List<TaxonDTO> findFullTaxonNamesByCriteria(String levelCode, String name, boolean isStrictName) {
226 List<TaxonDTO> result = findTaxonNamesByCriteria(levelCode, name, isStrictName);
227
228 fillTaxonsProperties(result);
229
230 return result;
231 }
232
233
234 @Override
235 public List<TaxonDTO> findTaxonNamesByCriteria(String levelCode, String name, boolean isStrictName) {
236
237 List<TaxonDTO> result = new ArrayList<>();
238
239
240 if (StringUtils.isBlank(levelCode) && StringUtils.isBlank(name)) {
241
242 result.addAll(loopbackTaxonNameDao.getAllTaxonNames());
243
244 } else {
245
246 Iterator<Object[]> it = queryIterator("taxonNamesByCriteria",
247 "levelCd", StringType.INSTANCE, levelCode,
248 "name", StringType.INSTANCE, isStrictName ? null : name,
249 "strictName", StringType.INSTANCE, isStrictName ? name : null);
250
251 while (it.hasNext()) {
252 Object[] source = it.next();
253 result.add(toTaxonDTO(Arrays.asList(source).iterator()));
254 }
255 }
256
257 fillReferents(result);
258
259 return ImmutableList.copyOf(result);
260 }
261
262
263 @Override
264 public List<TaxonDTO> getCompositeTaxonNames(Integer taxonNameId) {
265 Iterator<Object[]> it = queryIterator("compositeTaxonNamesByTaxonNameId",
266 "taxonNameId", IntegerType.INSTANCE, taxonNameId);
267
268 List<TaxonDTO> result = new ArrayList<>();
269 while (it.hasNext()) {
270 Object[] source = it.next();
271 TaxonDTO taxon = toTaxonDTO(Arrays.asList(source).iterator());
272 fillTaxonProperties(taxon);
273 result.add(taxon);
274 }
275 return result;
276 }
277
278
279 @Override
280 public Map<Integer, String> getTaxRefByTaxonNameId() {
281
282 return getAlternateReferencesMap(config.getAlternativeTaxonOriginTaxRef());
283 }
284
285
286 @Override
287 public Map<Integer, String> getWormsByTaxonNameId() {
288
289 return getAlternateReferencesMap(config.getAlternativeTaxonOriginWorms());
290 }
291
292 private Map<Integer, String> getAlternateReferencesMap(String originCode) {
293
294 Map<Integer, String> result = Maps.newHashMap();
295 if (StringUtils.isNotBlank(originCode)) {
296
297 Iterator<Object[]> rows = queryIterator("alternateTaxonCode",
298 "originCode", StringType.INSTANCE, originCode);
299
300 while (rows.hasNext()) {
301 Object[] row = rows.next();
302 result.put((Integer) row[0], (String) row[1]);
303 }
304 }
305
306 return result;
307 }
308
309
310
311 private TaxonDTO toTaxonDTO(Iterator<Object> source) {
312 TaxonDTO result = DaliBeanFactory.newTaxonDTO();
313
314
315 result.setId((Integer) source.next());
316
317
318 result.setName((String) source.next());
319
320 result.setComment((String) source.next());
321
322 result.setReferent((Boolean) source.next());
323 result.setVirtual((Boolean) source.next());
324 result.setObsolete((Boolean) source.next());
325 result.setTemporary((Boolean) source.next());
326
327 result.setReferenceTaxonId((Integer) source.next());
328 result.setParentTaxonId((Integer) source.next());
329
330 String levelCode = (String) source.next();
331 Integer citationId = (Integer) source.next();
332 String citationName = (String) source.next();
333
334 result.setCreationDate(Daos.convertToDate(source.next()));
335 result.setUpdateDate(Daos.convertToDate(source.next()));
336
337
338 if (levelCode != null) {
339 result.setLevel(referentialDao.getTaxonomicLevelByCode(levelCode));
340 }
341
342
343 if (citationId != null) {
344 CitationDTO citation = DaliBeanFactory.newCitationDTO();
345 citation.setId(citationId);
346 citation.setName(citationName);
347
348 result.setCitation(citation);
349 }
350
351
352 String statusCode = Boolean.TRUE.equals(result.isTemporary())
353 ? StatusCode.TEMPORARY.getValue()
354 : StatusCode.ENABLE.getValue();
355 result.setStatus(referentialDao.getStatusByCode(statusCode));
356
357 return result;
358 }
359
360
361 @Override
362 public void fillParentAndReferent(TaxonDTO taxon) {
363
364
365 fillReferent(taxon);
366
367
368 if (taxon.getParentTaxonId() != null) {
369 if (taxon.getParentTaxonId().equals(taxon.getId())) {
370 taxon.setParentTaxon(taxon);
371 } else {
372 taxon.setParentTaxon(loopbackTaxonNameDao.getTaxonNameById(taxon.getParentTaxonId()));
373 }
374 }
375 }
376
377 @Override
378 public void fillReferents(List<TaxonDTO> taxons) {
379
380 if (taxons == null) return;
381 taxons.forEach(this::fillReferent);
382
383 }
384
385 private void fillReferent(TaxonDTO taxon) {
386
387
388 if (taxon.getReferenceTaxon() == null || !Objects.equals(taxon.getReferenceTaxon().getId(), taxon.getReferenceTaxonId())) {
389 taxon.setReferenceTaxon(loopbackTaxonNameDao.getTaxonNameByReferenceId(taxon.getReferenceTaxonId()));
390 }
391 }
392
393 }