1 package net.sumaris.core.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 import com.google.common.collect.ImmutableList;
26 import net.sumaris.core.dao.referential.ReferentialDao;
27 import net.sumaris.core.dao.technical.SortDirection;
28 import net.sumaris.core.dao.technical.hibernate.HibernateDaoSupport;
29 import net.sumaris.core.model.referential.taxon.*;
30 import net.sumaris.core.model.technical.optimization.taxon.TaxonGroup2TaxonHierarchy;
31 import net.sumaris.core.util.Beans;
32 import net.sumaris.core.vo.filter.TaxonNameFilterVO;
33 import net.sumaris.core.vo.referential.TaxonNameVO;
34 import org.apache.commons.collections4.CollectionUtils;
35 import org.apache.commons.lang3.ArrayUtils;
36 import org.apache.commons.lang3.StringUtils;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
39 import org.springframework.beans.factory.annotation.Autowired;
40 import org.springframework.stereotype.Repository;
41
42 import javax.persistence.EntityManager;
43 import javax.persistence.TypedQuery;
44 import javax.persistence.criteria.*;
45 import java.util.Collection;
46 import java.util.List;
47 import java.util.stream.Collectors;
48
49 @Repository("taxonNameDao")
50 public class TaxonNameDaoImpl extends HibernateDaoSupport implements TaxonNameDao {
51
52
53 private static final Logger log =
54 LoggerFactory.getLogger(TaxonNameDaoImpl.class);
55
56 @Autowired
57 private ReferentialDao referentialDao;
58
59 @Override
60 public List<TaxonNameVO> findByFilter(TaxonNameFilterVO filter, int offset, int size,
61 String sortAttribute, SortDirection sortDirection) {
62 EntityManager em = getEntityManager();
63 CriteriaBuilder builder = em.getCriteriaBuilder();
64
65
66 boolean withSynonyms = filter.getWithSynonyms() != null ? filter.getWithSynonyms() : false;
67
68
69 ParameterExpression<Collection> taxonGroupIdsParam = builder.parameter(Collection.class);
70
71
72 ReferentialDao.QueryVisitor<TaxonName> queryVisitor = (query, root) -> {
73
74 Expression<Boolean> whereClause = null;
75 if (!withSynonyms) {
76 whereClause = builder.equal(root.get(TaxonName.Fields.IS_REFERENT), Boolean.TRUE);
77 }
78
79 Expression<Boolean> taxonGroupClause = null;
80 if (ArrayUtils.isNotEmpty(filter.getTaxonGroupIds())) {
81 Join<TaxonName, ReferenceTaxon> rt = root.join(TaxonName.Fields.REFERENCE_TAXON, JoinType.INNER);
82 ListJoin<ReferenceTaxon, TaxonGroup2TaxonHierarchy> tgh = rt.joinList(ReferenceTaxon.Fields.PARENT_TAXON_GROUPS, JoinType.INNER);
83 taxonGroupClause = builder.in(tgh.get(TaxonGroup2TaxonHierarchy.Fields.PARENT_TAXON_GROUP).get(TaxonGroup.Fields.ID))
84 .value(taxonGroupIdsParam);
85 whereClause = whereClause == null ? taxonGroupClause : builder.and(whereClause, taxonGroupClause);
86 }
87
88 return whereClause;
89 };
90
91 TypedQuery<TaxonName> typedQuery = referentialDao.createFindQuery(TaxonName.class,
92 null,
93 filter.getTaxonomicLevelIds(),
94 StringUtils.trimToNull(filter.getSearchText()),
95 StringUtils.trimToNull(filter.getSearchAttribute()),
96 filter.getStatusIds(),
97 sortAttribute,
98 sortDirection,
99 queryVisitor);
100
101 if (ArrayUtils.isNotEmpty(filter.getTaxonGroupIds())) {
102 typedQuery.setParameter(taxonGroupIdsParam, ImmutableList.copyOf(filter.getTaxonGroupIds()));
103 }
104
105 return typedQuery.getResultStream()
106 .map(this::toTaxonNameVO)
107 .collect(Collectors.toList());
108 }
109
110 @Override
111 public List<TaxonNameVO> getAll(boolean withSynonyms) {
112 EntityManager em = getEntityManager();
113 CriteriaBuilder builder = em.getCriteriaBuilder();
114 CriteriaQuery<TaxonName> query = builder.createQuery(TaxonName.class);
115 Root<TaxonName> root = query.from(TaxonName.class);
116
117 ParameterExpression<Boolean> withSynonymParam = builder.parameter(Boolean.class);
118
119 query.select(root)
120 .where(builder.and(
121
122 builder.in(root.get(TaxonName.Fields.TAXONOMIC_LEVEL).get(TaxonomicLevel.Fields.ID))
123 .value(ImmutableList.of(TaxonomicLevelId.SPECIES.getId(), TaxonomicLevelId.SUBSPECIES.getId())),
124
125 builder.or(
126 builder.isNull(withSynonymParam),
127 builder.equal(root.get(TaxonName.Fields.IS_REFERENT), Boolean.TRUE)
128 )
129 ));
130
131 return em.createQuery(query)
132 .setParameter(withSynonymParam, withSynonyms ? null : false)
133 .getResultStream()
134 .map(this::toTaxonNameVO)
135 .collect(Collectors.toList());
136 }
137
138 @Override
139 public TaxonNameVO getTaxonNameReferent(Integer referenceTaxonId) {
140 EntityManager em = getEntityManager();
141 CriteriaBuilder builder = em.getCriteriaBuilder();
142 CriteriaQuery<TaxonName> query = builder.createQuery(TaxonName.class);
143 Root<TaxonName> root = query.from(TaxonName.class);
144
145 ParameterExpression<Integer> idParam = builder.parameter(Integer.class);
146
147 query.select(root)
148 .where(builder.equal(root.get(TaxonName.Fields.REFERENCE_TAXON).get(ReferenceTaxon.Fields.ID), idParam));
149
150 TypedQuery<TaxonName> q = em.createQuery(query)
151 .setParameter(idParam, referenceTaxonId);
152 List<TaxonName> referenceTaxons = q.getResultList();
153 if (CollectionUtils.isEmpty(referenceTaxons)) return null;
154 if (referenceTaxons.size() > 1) {
155 log.warn(String.format("ReferenceTaxon {id=%} has more than one TaxonNames, with IS_REFERENT=1. Will use the first found.", referenceTaxonId));
156 }
157
158 return toTaxonNameVO(referenceTaxons.get(0));
159 }
160
161 @Override
162 public List<TaxonName> getAllTaxonNameByParentIds(Collection<Integer> taxonNameParentIds) {
163 CriteriaBuilder builder = getEntityManager().getCriteriaBuilder();
164 CriteriaQuery<TaxonName> query = builder.createQuery(TaxonName.class);
165 Root<TaxonName> root = query.from(TaxonName.class);
166
167 ParameterExpression<Collection> parentIdsParam = builder.parameter(Collection.class);
168
169 query.where(builder.in(root.get(TaxonName.Fields.PARENT_TAXON_NAME).get(TaxonName.Fields.ID)).value(parentIdsParam));
170
171 return getEntityManager().createQuery(query)
172 .setParameter(parentIdsParam, taxonNameParentIds)
173 .getResultList();
174 }
175
176 @Override
177 public List<TaxonNameVO> getAllByTaxonGroupId(Integer taxonGroupId) {
178 EntityManager em = getEntityManager();
179 CriteriaBuilder builder = em.getCriteriaBuilder();
180 CriteriaQuery<TaxonName> query = builder.createQuery(TaxonName.class);
181 Root<TaxonGroup2TaxonHierarchy> root = query.from(TaxonGroup2TaxonHierarchy.class);
182
183 ParameterExpression<Integer> taxonGroupIdParam = builder.parameter(Integer.class);
184
185 Join<TaxonGroup2TaxonHierarchy, ReferenceTaxon> rt = root.join(TaxonGroup2TaxonHierarchy.Fields.CHILD_REFERENCE_TAXON, JoinType.INNER);
186 Join<ReferenceTaxon, TaxonName> tn = rt.joinList(ReferenceTaxon.Fields.TAXON_NAMES, JoinType.INNER);
187
188 query.select(tn)
189 .where(builder.and(
190
191 builder.equal(root.get(TaxonGroup2TaxonHierarchy.Fields.PARENT_TAXON_GROUP).get(TaxonGroup.Fields.ID), taxonGroupIdParam),
192
193 builder.in(tn.get(TaxonName.Fields.TAXONOMIC_LEVEL).get(TaxonomicLevel.Fields.ID))
194 .value(ImmutableList.of(TaxonomicLevelId.SPECIES.getId(), TaxonomicLevelId.SUBSPECIES.getId())),
195
196 builder.equal(tn.get(TaxonName.Fields.IS_REFERENT), Boolean.TRUE)
197 ));
198
199 return em.createQuery(query)
200 .setParameter(taxonGroupIdParam, taxonGroupId)
201 .getResultStream()
202 .map(this::toTaxonNameVO)
203 .collect(Collectors.toList());
204 }
205
206
207
208 protected List<TaxonNameVO> toTaxonNameVOs(List<TaxonName> source) {
209 return source.stream().map(this::toTaxonNameVO).collect(Collectors.toList());
210 }
211
212 protected TaxonNameVO toTaxonNameVO(TaxonName source) {
213 if (source == null) return null;
214
215 TaxonNameVOtial/TaxonNameVO.html#TaxonNameVO">TaxonNameVO target = new TaxonNameVO();
216
217 Beans.copyProperties(source, target);
218
219
220 target.setReferenceTaxonId(source.getReferenceTaxon().getId());
221 return target;
222 }
223 }