2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
9 package eu
.etaxonomy
.cdm
.persistence
.dao
.hibernate
.term
;
11 import java
.util
.ArrayList
;
12 import java
.util
.Collection
;
13 import java
.util
.Enumeration
;
14 import java
.util
.Iterator
;
15 import java
.util
.List
;
16 import java
.util
.Locale
;
18 import java
.util
.UUID
;
20 import org
.apache
.commons
.lang
.StringUtils
;
21 import org
.apache
.log4j
.Logger
;
22 import org
.hibernate
.Criteria
;
23 import org
.hibernate
.Query
;
24 import org
.hibernate
.Session
;
25 import org
.hibernate
.criterion
.Criterion
;
26 import org
.hibernate
.criterion
.Disjunction
;
27 import org
.hibernate
.criterion
.Order
;
28 import org
.hibernate
.criterion
.Projections
;
29 import org
.hibernate
.criterion
.Restrictions
;
30 import org
.hibernate
.envers
.query
.AuditEntity
;
31 import org
.hibernate
.envers
.query
.AuditQuery
;
32 import org
.springframework
.stereotype
.Repository
;
34 import eu
.etaxonomy
.cdm
.common
.URI
;
35 import eu
.etaxonomy
.cdm
.model
.common
.AnnotationType
;
36 import eu
.etaxonomy
.cdm
.model
.common
.CdmBase
;
37 import eu
.etaxonomy
.cdm
.model
.common
.ExtensionType
;
38 import eu
.etaxonomy
.cdm
.model
.common
.Language
;
39 import eu
.etaxonomy
.cdm
.model
.common
.MarkerType
;
40 import eu
.etaxonomy
.cdm
.model
.description
.MeasurementUnit
;
41 import eu
.etaxonomy
.cdm
.model
.description
.PresenceAbsenceTerm
;
42 import eu
.etaxonomy
.cdm
.model
.description
.State
;
43 import eu
.etaxonomy
.cdm
.model
.description
.StatisticalMeasure
;
44 import eu
.etaxonomy
.cdm
.model
.description
.TextFormat
;
45 import eu
.etaxonomy
.cdm
.model
.location
.Country
;
46 import eu
.etaxonomy
.cdm
.model
.location
.NamedArea
;
47 import eu
.etaxonomy
.cdm
.model
.location
.NamedAreaLevel
;
48 import eu
.etaxonomy
.cdm
.model
.location
.NamedAreaType
;
49 import eu
.etaxonomy
.cdm
.model
.location
.ReferenceSystem
;
50 import eu
.etaxonomy
.cdm
.model
.media
.Media
;
51 import eu
.etaxonomy
.cdm
.model
.media
.RightsType
;
52 import eu
.etaxonomy
.cdm
.model
.metadata
.TermSearchField
;
53 import eu
.etaxonomy
.cdm
.model
.name
.HybridRelationshipType
;
54 import eu
.etaxonomy
.cdm
.model
.name
.NameRelationshipType
;
55 import eu
.etaxonomy
.cdm
.model
.name
.NameTypeDesignationStatus
;
56 import eu
.etaxonomy
.cdm
.model
.name
.NomenclaturalStatusType
;
57 import eu
.etaxonomy
.cdm
.model
.name
.Rank
;
58 import eu
.etaxonomy
.cdm
.model
.name
.SpecimenTypeDesignationStatus
;
59 import eu
.etaxonomy
.cdm
.model
.occurrence
.DerivationEventType
;
60 import eu
.etaxonomy
.cdm
.model
.taxon
.SynonymType
;
61 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonRelationshipType
;
62 import eu
.etaxonomy
.cdm
.model
.term
.DefinedTerm
;
63 import eu
.etaxonomy
.cdm
.model
.term
.DefinedTermBase
;
64 import eu
.etaxonomy
.cdm
.model
.term
.TermType
;
65 import eu
.etaxonomy
.cdm
.model
.term
.TermVocabulary
;
66 import eu
.etaxonomy
.cdm
.model
.view
.AuditEvent
;
67 import eu
.etaxonomy
.cdm
.persistence
.dao
.hibernate
.common
.IdentifiableDaoBase
;
68 import eu
.etaxonomy
.cdm
.persistence
.dao
.term
.IDefinedTermDao
;
69 import eu
.etaxonomy
.cdm
.persistence
.dto
.FeatureDto
;
70 import eu
.etaxonomy
.cdm
.persistence
.dto
.TermDto
;
71 import eu
.etaxonomy
.cdm
.persistence
.query
.MatchMode
;
72 import eu
.etaxonomy
.cdm
.persistence
.query
.OrderHint
;
75 * @author a.kohlbecker
79 public class DefinedTermDaoImpl
80 extends IdentifiableDaoBase
<DefinedTermBase
>
81 implements IDefinedTermDao
{
83 private static final Logger logger
= Logger
.getLogger(DefinedTermDaoImpl
.class);
85 @SuppressWarnings("unchecked")
86 public DefinedTermDaoImpl() {
87 super(DefinedTermBase
.class);
88 indexedClasses
= new Class
[25];
89 indexedClasses
[0] = Rank
.class;
90 indexedClasses
[1] = AnnotationType
.class;
91 indexedClasses
[2] = ExtensionType
.class;
92 indexedClasses
[3] = Language
.class;
93 indexedClasses
[4] = MarkerType
.class;
94 indexedClasses
[5] = MeasurementUnit
.class;
95 indexedClasses
[6] = DefinedTerm
.class;
96 indexedClasses
[7] = PresenceAbsenceTerm
.class;
97 indexedClasses
[8] = State
.class;
98 indexedClasses
[9] = StatisticalMeasure
.class;
99 indexedClasses
[10] = TextFormat
.class;
100 indexedClasses
[11] = DerivationEventType
.class;
101 indexedClasses
[12] = NamedArea
.class;
102 indexedClasses
[13] = NamedAreaLevel
.class;
103 indexedClasses
[14] = NamedAreaType
.class;
104 indexedClasses
[15] = ReferenceSystem
.class;
105 indexedClasses
[16] = Country
.class;
106 indexedClasses
[17] = RightsType
.class;
107 indexedClasses
[18] = HybridRelationshipType
.class;
108 indexedClasses
[19] = NameRelationshipType
.class;
109 indexedClasses
[20] = NameTypeDesignationStatus
.class;
110 indexedClasses
[21] = NomenclaturalStatusType
.class;
111 indexedClasses
[22] = SpecimenTypeDesignationStatus
.class;
112 indexedClasses
[23] = SynonymType
.class;
113 indexedClasses
[24] = TaxonRelationshipType
.class;
120 public List
<DefinedTermBase
> findByTitle(String queryString
) {
121 return findByTitle(queryString
, null);
128 public List
<DefinedTermBase
> findByTitle(String queryString
, CdmBase sessionObject
) {
129 checkNotInPriorView("DefinedTermDaoImpl.findByTitle(String queryString, CdmBase sessionObject)");
130 Session session
= getSession();
131 if ( sessionObject
!= null ) {//attache the object to the session, TODO needed?
132 session
.update(sessionObject
);
134 Query query
= session
.createQuery("select term from DefinedTermBase term join fetch term.representations representation where representation.label = :label");
135 query
.setParameter("label", queryString
);
136 @SuppressWarnings({ "unchecked", "rawtypes" })
137 List
<DefinedTermBase
> result
= deduplicateResult(query
.list());
142 public List
<DefinedTermBase
> findByTitle(String queryString
, MatchMode matchMode
, int page
, int pagesize
, List
<Criterion
> criteria
) {
143 //FIXME is query parametrised?
144 checkNotInPriorView("DefinedTermDaoImpl.findByTitle(String queryString, ITitledDao.MATCH_MODE matchMode, int page, int pagesize, List<Criterion> criteria)");
145 Criteria crit
= getSession().createCriteria(type
);
146 crit
.add(Restrictions
.ilike("titleCache", matchMode
.queryStringFrom(queryString
)));
147 crit
.setMaxResults(pagesize
);
148 int firstItem
= (page
- 1) * pagesize
+ 1;
149 crit
.setFirstResult(firstItem
);
150 @SuppressWarnings("unchecked")
151 List
<DefinedTermBase
> results
= deduplicateResult(crit
.list());
156 public Country
getCountryByIso(String iso3166
) {
157 // If iso639 = "" query returns non-unique result. We prevent this here:
158 if (StringUtils
.isBlank(iso3166
) || iso3166
.length()<2 || iso3166
.length()>3) { return null; }
159 AuditEvent auditEvent
= getAuditEventFromContext();
160 if(auditEvent
.equals(AuditEvent
.CURRENT_VIEW
)) {
161 Query query
= getSession().createQuery("from Country where iso3166_A2 = :isoCode OR idInVocabulary = :isoCode");
162 query
.setParameter("isoCode", iso3166
);
163 return (Country
) query
.uniqueResult();
165 AuditQuery query
= getAuditReader().createQuery().forEntitiesAtRevision(Country
.class,auditEvent
.getRevisionNumber());
166 query
.add(AuditEntity
.property("iso3166_A2").eq(iso3166
));
167 query
.add(AuditEntity
.property("idInVocabulary").eq(iso3166
));
168 return (Country
) query
.getSingleResult();
173 public <T
extends DefinedTermBase
> List
<T
> getDefinedTermByRepresentationText(String text
, Class
<T
> clazz
) {
174 return getDefinedTermByRepresentationText(text
,clazz
,null,null);
178 public <T
extends DefinedTermBase
> List
<T
> getDefinedTermByRepresentationText(String text
, Class
<T
> clazz
, Integer pageSize
,Integer pageNumber
) {
179 checkNotInPriorView("DefinedTermDaoImpl.getDefinedTermByRepresentationText(String text, Class<T> clazz, Integer pageSize,Integer pageNumber)");
181 Criteria criteria
= getCriteria(clazz
);
183 criteria
.createAlias("representations", "r").add(Restrictions
.like("r.text", text
));
185 addPageSizeAndNumber(criteria
, pageSize
, pageNumber
);
187 @SuppressWarnings("unchecked")
188 List
<T
> result
= deduplicateResult(criteria
.list());
193 public long countDefinedTermByRepresentationText(String text
, Class
<?
extends DefinedTermBase
> clazz
) {
194 checkNotInPriorView("DefinedTermDaoImpl.countDefinedTermByRepresentationText(String text, Class<? extends DefinedTermBase> clazz)");
195 Criteria criteria
= getCriteria(clazz
);
197 criteria
.createAlias("representations", "r").add(Restrictions
.like("r.text", text
));
199 criteria
.setProjection(Projections
.rowCount());
201 return (Long
)criteria
.uniqueResult();
205 public <T
extends DefinedTermBase
> List
<T
> getDefinedTermByIdInVocabulary(String label
, UUID vocUuid
, Class
<T
> clazz
, Integer pageSize
, Integer pageNumber
) {
206 checkNotInPriorView("DefinedTermDaoImpl.getDefinedTermByIdInVocabulary(String label, UUID vocUuid, Class<T> clazz, Integer pageSize, Integer pageNumber)");
208 Criteria criteria
= getCriteria(clazz
);
210 criteria
.createAlias("vocabulary", "voc")
211 .add(Restrictions
.like("voc.uuid", vocUuid
))
212 .add(Restrictions
.like("idInVocabulary", label
, org
.hibernate
.criterion
.MatchMode
.EXACT
));
214 addPageSizeAndNumber(criteria
, pageSize
, pageNumber
);
216 @SuppressWarnings("unchecked")
217 List
<T
> result
= deduplicateResult(criteria
.list());
222 public <T
extends DefinedTermBase
> List
<T
> getDefinedTermByRepresentationAbbrev(String text
, Class
<T
> clazz
, Integer pageSize
,Integer pageNumber
) {
223 checkNotInPriorView("DefinedTermDaoImpl.getDefinedTermByRepresentationAbbrev(String abbrev, Class<T> clazz, Integer pageSize,Integer pageNumber)");
225 Criteria criteria
= getCriteria(clazz
);
227 criteria
.createAlias("representations", "r").add(Restrictions
.like("r.abbreviatedLabel", text
));
229 addPageSizeAndNumber(criteria
, pageSize
, pageNumber
);
231 @SuppressWarnings("unchecked")
232 List
<T
> result
= deduplicateResult(criteria
.list());
237 public long countDefinedTermByRepresentationAbbrev(String text
, Class
<?
extends DefinedTermBase
> clazz
) {
238 checkNotInPriorView("DefinedTermDaoImpl.countDefinedTermByRepresentationAbbrev(String abbrev, Class<? extends DefinedTermBase> clazz)");
239 Criteria criteria
= getCriteria(clazz
);
241 criteria
.createAlias("representations", "r").add(Restrictions
.like("r.abbreviatedLabel", text
));
242 criteria
.setProjection(Projections
.rowCount());
244 return (Long
)criteria
.uniqueResult();
248 public Language
getLanguageByIso(String iso639
) {
249 if (iso639
.length() < 2 || iso639
.length() > 3) {
250 logger
.warn("Invalid length " + iso639
.length() + " of ISO code. Length must be 2 or 3.");
253 boolean isIso639_1
= iso639
.length() == 2;
257 queryStr
= "FROM Language WHERE iso639_1 = :isoCode";
259 queryStr
= "FROM Language WHERE idInVocabulary = :isoCode AND vocabulary.uuid = :vocUuid";
261 AuditEvent auditEvent
= getAuditEventFromContext();
262 if(auditEvent
.equals(AuditEvent
.CURRENT_VIEW
)) {
263 Query query
= getSession().createQuery(queryStr
);
264 query
.setParameter("isoCode", iso639
);
266 query
.setParameter("vocUuid", Language
.uuidLanguageVocabulary
);
268 return (Language
) query
.uniqueResult();
270 AuditQuery query
= getAuditReader().createQuery().forEntitiesAtRevision(Language
.class,auditEvent
.getRevisionNumber());
272 query
.add(AuditEntity
.property("iso639_1").eq(iso639
));
274 query
.add(AuditEntity
.property("iso639_2").eq(iso639
));
275 query
.add(AuditEntity
.property("vocabulary.uuid").eq(Language
.uuidLanguageVocabulary
));
278 return (Language
)query
.getSingleResult();
283 * FIXME this will result in a query per language - could you, given that iso codes
284 * are unique, use from Language where iso639_1 in (:isoCode) or iso639_2 in (:isoCode)
287 public List
<Language
> getLanguagesByIso(List
<String
> iso639List
) {
288 List
<Language
> languages
= new ArrayList
<>(iso639List
.size());
289 for (String iso639
: iso639List
) {
290 languages
.add(getLanguageByIso(iso639
));
296 public List
<Language
> getLanguagesByLocale(Enumeration
<Locale
> locales
) {
297 List
<Language
> languages
= new ArrayList
<>();
298 while(locales
.hasMoreElements()) {
299 Locale locale
= locales
.nextElement();
300 languages
.add(getLanguageByIso(locale
.getLanguage()));
306 public long count(NamedAreaLevel level
, NamedAreaType type
) {
307 AuditEvent auditEvent
= getAuditEventFromContext();
308 if(auditEvent
.equals(AuditEvent
.CURRENT_VIEW
)) {
309 Criteria criteria
= getCriteria(NamedArea
.class);
312 criteria
.add(Restrictions
.eq("level",level
));
316 criteria
.add(Restrictions
.eq("type", type
));
319 criteria
.setProjection(Projections
.rowCount());
321 return (Long
)criteria
.uniqueResult();
323 AuditQuery query
= makeAuditQuery(NamedArea
.class, auditEvent
);
326 query
.add(AuditEntity
.relatedId("level").eq(level
.getId()));
330 query
.add(AuditEntity
.relatedId("type").eq(type
.getId()));
332 query
.addProjection(AuditEntity
.id().count());
333 return (Long
)query
.getSingleResult();
338 public long countMedia(DefinedTermBase definedTerm
) {
339 checkNotInPriorView("DefinedTermDaoImpl.countMedia(DefinedTermBase definedTerm)");
340 Query query
= getSession().createQuery("select count(media) from DefinedTermBase definedTerm join definedTerm.media media where definedTerm = :definedTerm");
341 query
.setParameter("definedTerm", definedTerm
);
343 return (Long
)query
.uniqueResult();
347 public List
<Media
> getMedia(DefinedTermBase definedTerm
, Integer pageSize
, Integer pageNumber
) {
348 checkNotInPriorView("DefinedTermDaoImpl.getMedia(DefinedTermBase definedTerm, Integer pageSize, Integer pageNumber)");
349 Query query
= getSession().createQuery(
351 + " FROM DefinedTermBase definedTerm "
352 + " JOIN definedTerm.media media "
353 + " WHERE definedTerm = :definedTerm");
354 query
.setParameter("definedTerm", definedTerm
);
356 addPageSizeAndNumber(query
, pageSize
, pageNumber
);
358 @SuppressWarnings("unchecked")
359 List
<Media
> result
= query
.list();
364 public List
<NamedArea
> list(NamedAreaLevel level
, NamedAreaType type
, Integer pageSize
, Integer pageNumber
) {
365 AuditEvent auditEvent
= getAuditEventFromContext();
366 if(auditEvent
.equals(AuditEvent
.CURRENT_VIEW
)) {
367 Criteria criteria
= getCriteria(NamedArea
.class);
370 criteria
.add(Restrictions
.eq("level",level
));
374 criteria
.add(Restrictions
.eq("type", type
));
377 addPageSizeAndNumber(criteria
, pageSize
, pageNumber
);
379 @SuppressWarnings("unchecked")
380 List
<NamedArea
> result
= deduplicateResult(criteria
.list());
383 AuditQuery query
= makeAuditQuery(NamedArea
.class, auditEvent
);
386 query
.add(AuditEntity
.relatedId("level").eq(level
.getId()));
390 query
.add(AuditEntity
.relatedId("type").eq(type
.getId()));
393 @SuppressWarnings("unchecked")
394 List
<NamedArea
> result
= deduplicateResult(query
.getResultList());
400 public List
<NamedArea
> list(NamedAreaLevel level
, NamedAreaType type
, Integer pageSize
, Integer pageNumber
,
401 List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
403 List
<NamedArea
> result
;
405 AuditEvent auditEvent
= getAuditEventFromContext();
406 if (auditEvent
.equals(AuditEvent
.CURRENT_VIEW
)) {
407 Criteria criteria
= getCriteria(NamedArea
.class);
410 criteria
.add(Restrictions
.eq("level", level
));
413 criteria
.add(Restrictions
.eq("type", type
));
415 addOrder(criteria
,orderHints
);
416 addPageSizeAndNumber(criteria
, pageSize
, pageNumber
);
418 result
= deduplicateResult(criteria
.list());
421 AuditQuery query
= getAuditReader().createQuery().forEntitiesAtRevision(NamedArea
.class,
422 auditEvent
.getRevisionNumber());
424 query
.add(AuditEntity
.relatedId("level").eq(level
.getId()));
427 query
.add(AuditEntity
.relatedId("type").eq(type
.getId()));
429 result
= deduplicateResult(query
.getResultList());
432 defaultBeanInitializer
.initializeAll(result
, propertyPaths
);
439 public <T
extends DefinedTermBase
> long countGeneralizationOf(T kindOf
) {
440 AuditEvent auditEvent
= getAuditEventFromContext();
441 if(auditEvent
.equals(AuditEvent
.CURRENT_VIEW
)) {
442 Query query
= getSession().createQuery("select count(term) from DefinedTermBase term where term.kindOf = :kindOf");
443 query
.setParameter("kindOf", kindOf
);
444 return (Long
)query
.uniqueResult();
446 AuditQuery query
= makeAuditQuery(DefinedTermBase
.class,auditEvent
);
447 query
.add(AuditEntity
.relatedId("kindOf").eq(kindOf
.getId()));
448 query
.addProjection(AuditEntity
.id().count());
449 return (Long
)query
.getSingleResult();
454 public <T
extends DefinedTermBase
> long countIncludes(Collection
<T
> partOf
) {
455 if (partOf
== null || partOf
.isEmpty()){
458 AuditEvent auditEvent
= getAuditEventFromContext();
459 if(auditEvent
.equals(AuditEvent
.CURRENT_VIEW
)) {
460 Query query
= getSession().createQuery("select count(term) from DefinedTermBase term where term.partOf in (:partOf)");
461 query
.setParameterList("partOf", partOf
);
462 return (Long
)query
.uniqueResult();
466 AuditQuery query
= makeAuditQuery(DefinedTermBase
.class, auditEvent
);
467 query
.add(AuditEntity
.relatedId("partOf").eq(t
.getId()));
468 query
.addProjection(AuditEntity
.id().count());
469 count
+= (Long
)query
.getSingleResult();
476 public <T
extends DefinedTermBase
> List
<T
> getGeneralizationOf(T kindOf
, Integer pageSize
, Integer pageNumber
) {
477 AuditEvent auditEvent
= getAuditEventFromContext();
478 if(auditEvent
.equals(AuditEvent
.CURRENT_VIEW
)) {
479 Query query
= getSession().createQuery("select term from DefinedTermBase term where term.kindOf = :kindOf");
480 query
.setParameter("kindOf", kindOf
);
482 addPageSizeAndNumber(query
, pageSize
, pageNumber
);
484 @SuppressWarnings("unchecked")
485 List
<T
> result
= deduplicateResult(query
.list());
488 AuditQuery query
= makeAuditQuery(DefinedTermBase
.class, auditEvent
);
489 query
.add(AuditEntity
.relatedId("kindOf").eq(kindOf
.getId()));
491 addPageSizeAndNumber(query
, pageSize
, pageNumber
);
493 @SuppressWarnings("unchecked")
494 List
<T
> result
= deduplicateResult(query
.getResultList());
500 public <T
extends DefinedTermBase
> List
<T
> getIncludes(Collection
<T
> partOf
, Integer pageSize
, Integer pageNumber
, List
<String
> propertyPaths
) {
501 if (partOf
== null || partOf
.isEmpty()){
502 return new ArrayList
<>();
504 AuditEvent auditEvent
= getAuditEventFromContext();
505 if(auditEvent
.equals(AuditEvent
.CURRENT_VIEW
)) {
506 Query query
= getSession().createQuery("select term from DefinedTermBase term where term.partOf in (:partOf)");
507 query
.setParameterList("partOf", partOf
);
509 addPageSizeAndNumber(query
, pageSize
, pageNumber
);
511 @SuppressWarnings("unchecked")
512 List
<T
> results
= deduplicateResult(query
.list());
513 defaultBeanInitializer
.initializeAll(results
, propertyPaths
);
516 List
<T
> result
= new ArrayList
<>();
518 AuditQuery query
= makeAuditQuery(DefinedTermBase
.class, auditEvent
);
519 query
.add(AuditEntity
.relatedId("partOf").eq(t
.getId()));
520 addPageSizeAndNumber(query
, pageSize
, pageNumber
);
522 result
.addAll(deduplicateResult(query
.getResultList()));
524 defaultBeanInitializer
.initializeAll(result
, propertyPaths
);
530 public <T
extends DefinedTermBase
> long countPartOf(Set
<T
> definedTerms
) {
531 checkNotInPriorView("DefinedTermDaoImpl.countPartOf(Set<T> definedTerms)");
532 Query query
= getSession().createQuery("select count(distinct definedTerm) from DefinedTermBase definedTerm join definedTerm.includes included where included in (:definedTerms)");
533 query
.setParameterList("definedTerms", definedTerms
);
534 return (Long
)query
.uniqueResult();
538 public <T
extends DefinedTermBase
> List
<T
> getPartOf(Set
<T
> definedTerms
, Integer pageSize
, Integer pageNumber
, List
<String
> propertyPaths
) {
539 checkNotInPriorView("DefinedTermDaoImpl.getPartOf(Set<T> definedTerms, Integer pageSize, Integer pageNumber)");
540 Query query
= getSession().createQuery("select distinct definedTerm from DefinedTermBase definedTerm join definedTerm.includes included where included in (:definedTerms)");
541 query
.setParameterList("definedTerms", definedTerms
);
543 addPageSizeAndNumber(query
, pageSize
, pageNumber
);
545 @SuppressWarnings("unchecked")
546 List
<T
> r
= query
.list();
548 * For some weird reason, hibernate returns proxies (extending the superclass), not the actual class on this,
549 * despite querying the damn database and returning the discriminator along with the rest of the object properties!
551 * Probably a bug in hibernate, but we'll manually deproxy for now since the objects are initialized anyway, the
552 * performance implications are small (we're swapping one array of references for another, not hitting the db or
555 List
<T
> results
= new ArrayList
<>();
556 if(!definedTerms
.isEmpty()) {
558 T deproxied
= CdmBase
.deproxy(t
);
559 results
.add(deproxied
);
561 defaultBeanInitializer
.initializeAll(results
, propertyPaths
);
567 public DefinedTermBase
findByUri(URI uri
) {
568 AuditEvent auditEvent
= getAuditEventFromContext();
569 if(auditEvent
.equals(AuditEvent
.CURRENT_VIEW
)) {
570 Query query
= getSession().createQuery("select term from DefinedTermBase term where term.uri = :uri");
571 query
.setParameter("uri", uri
);
572 return (DefinedTermBase
<?
>)query
.uniqueResult();
574 AuditQuery query
= makeAuditQuery(DefinedTermBase
.class, auditEvent
);
575 query
.add(AuditEntity
.property("uri").eq(uri
));
576 return (DefinedTermBase
<?
>)query
.getSingleResult();
581 public <T
extends DefinedTermBase
> List
<T
> listByTermType(TermType termType
, Integer limit
, Integer start
,
582 List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
583 Query query
= getSession().createQuery("SELECT term FROM DefinedTermBase term WHERE term.termType = :termType");
584 query
.setParameter("termType", termType
);
586 @SuppressWarnings("unchecked")
587 List
<T
> result
= deduplicateResult(query
.list());
589 defaultBeanInitializer
.initializeAll(result
, propertyPaths
);
594 public <TERM
extends DefinedTermBase
> List
<TERM
> listByTermClass(Class
<TERM
> clazz
, Integer limit
, Integer start
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
595 // checkNotInPriorView("DefinedTermDaoImpl.listByTermClass(Class<TERM> clazz, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths)");
597 Query query
= getSession().createQuery("FROM " + clazz
.getSimpleName());
599 @SuppressWarnings("unchecked")
600 List
<TERM
> result
= deduplicateResult(query
.list());
602 defaultBeanInitializer
.initializeAll(result
, propertyPaths
);
608 public <S
extends DefinedTermBase
> List
<S
> list(Class
<S
> type
, Integer limit
, Integer start
,
609 List
<OrderHint
> orderHints
, List
<String
> propertyPath
) {
611 return deduplicateResult(super.list(type
, limit
, start
, orderHints
, propertyPath
));
615 * Workaround for https://dev.e-taxonomy.eu/redmine/issues/5871 and #5945
616 * Terms with multiple representations return identical duplicates
617 * due to eager representation loading. We expect these duplicates to appear
618 * in line wo we only compare one term with its predecessor. If it already
619 * exists we remove it from the result.
623 protected static <S
extends CdmBase
> List
<S
> deduplicateResult(List
<S
> orginals
) {
624 List
<S
> result
= new ArrayList
<>();
625 Iterator
<S
> it
= orginals
.iterator();
627 while (it
.hasNext()){
630 if (!result
.contains(a
)){
640 public <S
extends DefinedTermBase
> List
<S
> list(Class
<S
> clazz
, List
<TermVocabulary
> vocs
, Integer limit
, String pattern
) {
641 return list(clazz
, vocs
, 0, limit
, pattern
, MatchMode
.BEGINNING
);
645 public <S
extends DefinedTermBase
> List
<S
> list(Class
<S
> clazz
, List
<TermVocabulary
> vocs
, Integer pageNumber
, Integer limit
, String pattern
, MatchMode matchmode
){
646 Session session
= getSession();
650 Criteria crit
= getSession().createCriteria(clazz
, "term");
651 if (!StringUtils
.isBlank(pattern
)){
652 crit
.createAlias("term.representations", "reps");
653 Disjunction or
= Restrictions
.disjunction();
654 if (matchmode
== MatchMode
.EXACT
) {
655 or
.add(Restrictions
.eq("titleCache", matchmode
.queryStringFrom(pattern
)));
656 or
.add(Restrictions
.eq("reps.label", matchmode
.queryStringFrom(pattern
)));
658 or
.add(Restrictions
.like("titleCache", matchmode
.queryStringFrom(pattern
)));
659 or
.add(Restrictions
.like("reps.label", matchmode
.queryStringFrom(pattern
)));
664 if (limit
!= null && limit
>= 0) {
665 crit
.setMaxResults(limit
);
668 if (vocs
!= null &&!vocs
.isEmpty()){
669 crit
.createAlias("term.vocabulary", "voc");
670 Disjunction or
= Restrictions
.disjunction();
671 for (TermVocabulary
<?
> voc
: vocs
){
672 Criterion criterion
= Restrictions
.eq("voc.id", voc
.getId());
678 crit
.addOrder(Order
.asc("titleCache"));
682 crit
.setFirstResult(0);
683 @SuppressWarnings("unchecked")
684 List
<S
> results
= deduplicateResult(crit
.list());
689 public <S
extends DefinedTermBase
> List
<S
> listByAbbrev(Class
<S
> clazz
, List
<TermVocabulary
> vocs
, Integer limit
, String pattern
, TermSearchField type
) {
690 return listByAbbrev(clazz
, vocs
, 0, limit
, pattern
, MatchMode
.BEGINNING
, type
);
694 public <S
extends DefinedTermBase
> List
<S
> listByAbbrev(Class
<S
> clazz
, List
<TermVocabulary
> vocs
, Integer pageNumber
, Integer limit
, String pattern
, MatchMode matchmode
, TermSearchField abbrevType
){
699 Criteria crit
= getSession().createCriteria(clazz
, "type");
700 if (!StringUtils
.isBlank(pattern
)){
701 if (matchmode
== MatchMode
.EXACT
) {
702 crit
.add(Restrictions
.eq(abbrevType
.getKey(), matchmode
.queryStringFrom(pattern
)));
704 crit
.add(Restrictions
.like(abbrevType
.getKey(), matchmode
.queryStringFrom(pattern
)));
707 if (limit
!= null && limit
>= 0) {
708 crit
.setMaxResults(limit
);
711 if (vocs
!= null &&!vocs
.isEmpty()){
712 crit
.createAlias("type.vocabulary", "voc");
713 Disjunction or
= Restrictions
.disjunction();
714 for (TermVocabulary
<?
> voc
: vocs
){
715 Criterion criterion
= Restrictions
.eq("voc.id", voc
.getId());
721 crit
.addOrder(Order
.asc(abbrevType
.getKey()));
725 // int firstItem = (pageNumber - 1) * limit;
727 crit
.setFirstResult(0);
728 @SuppressWarnings("unchecked")
729 List
<S
> results
= deduplicateResult(crit
.list());
735 public Collection
<TermDto
> getIncludesAsDto(
736 TermDto parentTerm
) {
738 if (parentTerm
.getTermType().equals(TermType
.NamedArea
)){
739 queryString
= TermDto
.getTermDtoSelectNamedArea();
741 queryString
= TermDto
.getTermDtoSelect();
743 queryString
= queryString
744 + "where a.partOf.uuid = :parentUuid";
745 Query query
= getSession().createQuery(queryString
);
746 query
.setParameter("parentUuid", parentTerm
.getUuid());
748 @SuppressWarnings("unchecked")
749 List
<Object
[]> result
= query
.list();
751 List
<TermDto
> list
= TermDto
.termDtoListFrom(result
);
756 public Collection
<TermDto
> getKindOfsAsDto(TermDto parentTerm
) {
759 if (parentTerm
.getTermType().equals(TermType
.NamedArea
)){
760 queryString
= TermDto
.getTermDtoSelectNamedArea();
762 queryString
= TermDto
.getTermDtoSelect();
764 queryString
= queryString
+ "where a.kindOf.uuid = :parentUuid";
765 Query query
= getSession().createQuery(queryString
);
766 query
.setParameter("parentUuid", parentTerm
.getUuid());
768 @SuppressWarnings("unchecked")
769 List
<Object
[]> result
= query
.list();
771 List
<TermDto
> list
= TermDto
.termDtoListFrom(result
);
776 public Collection
<TermDto
> findByTitleAsDto(String title
, TermType termType
) {
777 String queryString
= TermDto
.getTermDtoSelect()
778 + " where a.titleCache like :title "
779 + (termType
!=null?
" and a.termType = :termType ":"");
781 title
= title
.replace("*", "%");
782 Query query
= getSession().createQuery(queryString
);
783 query
.setParameter("title", "%"+title
+"%");
785 query
.setParameter("termType", termType
);
788 @SuppressWarnings("unchecked")
789 List
<Object
[]> result
= query
.list();
791 List
<TermDto
> list
= TermDto
.termDtoListFrom(result
);
796 public Collection
<TermDto
> findByTypeAsDto(TermType termType
) {
797 if (termType
== null){
800 String queryString
= TermDto
.getTermDtoSelect()
801 + " where a.termType = :termType ";
802 Query query
= getSession().createQuery(queryString
);
804 query
.setParameter("termType", termType
);
806 @SuppressWarnings("unchecked")
807 List
<Object
[]> result
= query
.list();
809 List
<TermDto
> list
= TermDto
.termDtoListFrom(result
);
814 public Collection
<TermDto
> findByUriAsDto(URI uri
, String termLabel
, TermType termType
) {
815 String queryString
= TermDto
.getTermDtoSelect()
816 + " where a.uri like :uri "
817 + (termType
!=null?
" and a.termType = :termType ":"")
818 + (termLabel
!=null?
" and a.titleCache = :termLabel ":"")
820 Query query
= getSession().createQuery(queryString
);
821 query
.setParameter("uri", uri
.toString());
823 query
.setParameter("termLabel", "%"+termLabel
+"%");
826 query
.setParameter("termType", termType
);
829 @SuppressWarnings("unchecked")
830 List
<Object
[]> result
= query
.list();
832 List
<TermDto
> list
= TermDto
.termDtoListFrom(result
);
837 public List
<TermDto
> getSupportedStatesForFeature(UUID featureUuid
){
838 List
<TermDto
> list
= new ArrayList
<>();
839 String supportedCategoriesQueryString
= "SELECT cat.uuid "
840 + "from DefinedTermBase t "
841 + "join t.supportedCategoricalEnumerations as cat "
842 + "where t.uuid = :featureUuid";
843 Query supportedCategoriesQuery
= getSession().createQuery(supportedCategoriesQueryString
);
844 supportedCategoriesQuery
.setParameter("featureUuid", featureUuid
);
845 @SuppressWarnings("unchecked")
846 List
<UUID
> supportedCategories
= supportedCategoriesQuery
.list();
847 if(supportedCategories
.isEmpty()){
851 String queryString
= TermDto
.getTermDtoSelect()
852 + "where v.uuid in (:supportedCategories) "
853 + "order by a.titleCache";
854 Query query
= getSession().createQuery(queryString
);
855 query
.setParameterList("supportedCategories", supportedCategories
);
857 @SuppressWarnings("unchecked")
858 List
<Object
[]> result
= query
.list();
860 list
= TermDto
.termDtoListFrom(result
);
865 public Collection
<TermDto
> findByUUIDsAsDto(List
<UUID
> uuidList
) {
866 List
<TermDto
> list
= new ArrayList
<>();
867 if (uuidList
== null || uuidList
.isEmpty()){
871 String queryString
= TermDto
.getTermDtoSelect()
872 + "where a.uuid in :uuidList "
873 + "order by a.titleCache";
874 Query query
= getSession().createQuery(queryString
);
875 query
.setParameterList("uuidList", uuidList
);
877 @SuppressWarnings("unchecked")
878 List
<Object
[]> result
= query
.list();
880 list
= TermDto
.termDtoListFrom(result
);
885 public Collection
<TermDto
> findFeatureByUUIDsAsDto(List
<UUID
> uuidList
) {
886 List
<TermDto
> list
= new ArrayList
<>();
887 if (uuidList
== null || uuidList
.isEmpty()){
891 String queryString
= FeatureDto
.getTermDtoSelect()
892 + "where a.uuid in :uuidList "
893 + "order by a.titleCache";
894 Query query
= getSession().createQuery(queryString
);
895 query
.setParameterList("uuidList", uuidList
);
897 @SuppressWarnings("unchecked")
898 List
<Object
[]> result
= query
.list();
900 list
= FeatureDto
.termDtoListFrom(result
);
905 public Collection
<TermDto
> findFeatureByTitleAsDto(String pattern
) {
906 String queryString
= FeatureDto
.getTermDtoSelect()
907 + " where a.titleCache like :title "
908 + " and a.termType = :termType ";
910 pattern
= pattern
.replace("*", "%");
911 Query query
= getSession().createQuery(queryString
);
912 query
.setParameter("title", "%"+pattern
+"%");
913 query
.setParameter("termType", TermType
.Feature
);
916 @SuppressWarnings("unchecked")
917 List
<Object
[]> result
= query
.list();
919 List
<TermDto
> list
= FeatureDto
.termDtoListFrom(result
);