2 * Copyright (C) 2008 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
7 package eu
.etaxonomy
.cdm
.persistence
.dao
.hibernate
.occurrence
;
9 import java
.util
.ArrayList
;
10 import java
.util
.Collection
;
11 import java
.util
.Collections
;
12 import java
.util
.HashSet
;
13 import java
.util
.List
;
15 import java
.util
.UUID
;
17 import org
.apache
.log4j
.Logger
;
18 import org
.hibernate
.Criteria
;
19 import org
.hibernate
.Hibernate
;
20 import org
.hibernate
.Query
;
21 import org
.hibernate
.Session
;
22 import org
.hibernate
.criterion
.Disjunction
;
23 import org
.hibernate
.criterion
.ProjectionList
;
24 import org
.hibernate
.criterion
.Projections
;
25 import org
.hibernate
.criterion
.Restrictions
;
26 import org
.hibernate
.envers
.query
.AuditEntity
;
27 import org
.hibernate
.envers
.query
.AuditQuery
;
28 import org
.hibernate
.search
.FullTextSession
;
29 import org
.hibernate
.search
.Search
;
30 import org
.springframework
.beans
.factory
.annotation
.Autowired
;
31 import org
.springframework
.stereotype
.Repository
;
33 import eu
.etaxonomy
.cdm
.model
.common
.CdmBase
;
34 import eu
.etaxonomy
.cdm
.model
.description
.DescriptionBase
;
35 import eu
.etaxonomy
.cdm
.model
.description
.IndividualsAssociation
;
36 import eu
.etaxonomy
.cdm
.model
.media
.Media
;
37 import eu
.etaxonomy
.cdm
.model
.molecular
.DnaSample
;
38 import eu
.etaxonomy
.cdm
.model
.name
.HomotypicalGroup
;
39 import eu
.etaxonomy
.cdm
.model
.name
.SpecimenTypeDesignation
;
40 import eu
.etaxonomy
.cdm
.model
.name
.TaxonName
;
41 import eu
.etaxonomy
.cdm
.model
.occurrence
.DerivationEvent
;
42 import eu
.etaxonomy
.cdm
.model
.occurrence
.DerivedUnit
;
43 import eu
.etaxonomy
.cdm
.model
.occurrence
.DeterminationEvent
;
44 import eu
.etaxonomy
.cdm
.model
.occurrence
.FieldUnit
;
45 import eu
.etaxonomy
.cdm
.model
.occurrence
.SpecimenOrObservationBase
;
46 import eu
.etaxonomy
.cdm
.model
.occurrence
.SpecimenOrObservationType
;
47 import eu
.etaxonomy
.cdm
.model
.taxon
.Synonym
;
48 import eu
.etaxonomy
.cdm
.model
.taxon
.Taxon
;
49 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonBase
;
50 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonNode
;
51 import eu
.etaxonomy
.cdm
.model
.view
.AuditEvent
;
52 import eu
.etaxonomy
.cdm
.persistence
.dao
.description
.IDescriptionDao
;
53 import eu
.etaxonomy
.cdm
.persistence
.dao
.hibernate
.common
.IdentifiableDaoBase
;
54 import eu
.etaxonomy
.cdm
.persistence
.dao
.hibernate
.taxon
.TaxonDaoHibernateImpl
;
55 import eu
.etaxonomy
.cdm
.persistence
.dao
.name
.IHomotypicalGroupDao
;
56 import eu
.etaxonomy
.cdm
.persistence
.dao
.name
.ITaxonNameDao
;
57 import eu
.etaxonomy
.cdm
.persistence
.dao
.occurrence
.IOccurrenceDao
;
58 import eu
.etaxonomy
.cdm
.persistence
.dto
.SpecimenNodeWrapper
;
59 import eu
.etaxonomy
.cdm
.persistence
.dto
.UuidAndTitleCache
;
60 import eu
.etaxonomy
.cdm
.persistence
.query
.MatchMode
;
61 import eu
.etaxonomy
.cdm
.persistence
.query
.OrderHint
;
64 * @author a.babadshanjan
68 public class OccurrenceDaoHibernateImpl
extends IdentifiableDaoBase
<SpecimenOrObservationBase
> implements IOccurrenceDao
{
70 @SuppressWarnings("unused")
71 private static final Logger logger
= Logger
.getLogger(TaxonDaoHibernateImpl
.class);
74 private IDescriptionDao descriptionDao
;
77 private ITaxonNameDao taxonNameDao
;
80 private IHomotypicalGroupDao homotypicalGroupDao
;
82 public OccurrenceDaoHibernateImpl() {
83 super(SpecimenOrObservationBase
.class);
84 indexedClasses
= new Class
[7];
85 indexedClasses
[0] = FieldUnit
.class;
86 indexedClasses
[1] = DerivedUnit
.class;
87 indexedClasses
[5] = DnaSample
.class;
91 public int countDerivationEvents(SpecimenOrObservationBase occurence
) {
92 checkNotInPriorView("OccurrenceDaoHibernateImpl.countDerivationEvents(SpecimenOrObservationBase occurence)");
93 Query query
= getSession().createQuery("select count(distinct derivationEvent) from DerivationEvent derivationEvent join derivationEvent.originals occurence where occurence = :occurence");
94 query
.setParameter("occurence", occurence
);
96 return ((Long
)query
.uniqueResult()).intValue();
100 public int countDeterminations(SpecimenOrObservationBase occurrence
, TaxonBase taxonBase
) {
101 AuditEvent auditEvent
= getAuditEventFromContext();
102 if(auditEvent
.equals(AuditEvent
.CURRENT_VIEW
)) {
103 Criteria criteria
= getSession().createCriteria(DeterminationEvent
.class);
104 if(occurrence
!= null) {
105 criteria
.add(Restrictions
.eq("identifiedUnit",occurrence
));
108 if(taxonBase
!= null) {
109 criteria
.add(Restrictions
.eq("taxon",taxonBase
));
112 criteria
.setProjection(Projections
.rowCount());
113 return ((Number
)criteria
.uniqueResult()).intValue();
115 AuditQuery query
= getAuditReader().createQuery().forEntitiesAtRevision(DeterminationEvent
.class,auditEvent
.getRevisionNumber());
117 if(occurrence
!= null) {
118 query
.add(AuditEntity
.relatedId("identifiedUnit").eq(occurrence
.getId()));
121 if(taxonBase
!= null) {
122 query
.add(AuditEntity
.relatedId("taxon").eq(taxonBase
.getId()));
124 query
.addProjection(AuditEntity
.id().count());
126 return ((Long
)query
.getSingleResult()).intValue();
131 public int countMedia(SpecimenOrObservationBase occurence
) {
132 checkNotInPriorView("OccurrenceDaoHibernateImpl.countMedia(SpecimenOrObservationBase occurence)");
133 Query query
= getSession().createQuery("select count(media) from SpecimenOrObservationBase occurence join occurence.media media where occurence = :occurence");
134 query
.setParameter("occurence", occurence
);
136 return ((Long
)query
.uniqueResult()).intValue();
140 public List
<DerivationEvent
> getDerivationEvents(SpecimenOrObservationBase occurence
, Integer pageSize
,Integer pageNumber
, List
<String
> propertyPaths
) {
141 checkNotInPriorView("OccurrenceDaoHibernateImpl.getDerivationEvents(SpecimenOrObservationBase occurence, Integer pageSize,Integer pageNumber)");
142 Query query
= getSession().createQuery("select distinct derivationEvent from DerivationEvent derivationEvent join derivationEvent.originals occurence where occurence = :occurence");
143 query
.setParameter("occurence", occurence
);
145 if(pageSize
!= null) {
146 query
.setMaxResults(pageSize
);
147 if(pageNumber
!= null) {
148 query
.setFirstResult(pageNumber
* pageSize
);
150 query
.setFirstResult(0);
154 List
<DerivationEvent
> result
= query
.list();
155 defaultBeanInitializer
.initializeAll(result
, propertyPaths
);
160 public List
<DeterminationEvent
> getDeterminations(SpecimenOrObservationBase occurrence
, TaxonBase taxonBase
, Integer pageSize
, Integer pageNumber
, List
<String
> propertyPaths
) {
161 AuditEvent auditEvent
= getAuditEventFromContext();
162 if(auditEvent
.equals(AuditEvent
.CURRENT_VIEW
)) {
163 Criteria criteria
= getSession().createCriteria(DeterminationEvent
.class);
164 if(occurrence
!= null) {
165 criteria
.add(Restrictions
.eq("identifiedUnit",occurrence
));
168 if(taxonBase
!= null) {
169 criteria
.add(Restrictions
.eq("taxon",taxonBase
));
172 if(pageSize
!= null) {
173 criteria
.setMaxResults(pageSize
);
174 if(pageNumber
!= null) {
175 criteria
.setFirstResult(pageNumber
* pageSize
);
177 criteria
.setFirstResult(0);
180 List
<DeterminationEvent
> result
= criteria
.list();
181 defaultBeanInitializer
.initializeAll(result
, propertyPaths
);
184 AuditQuery query
= getAuditReader().createQuery().forEntitiesAtRevision(DeterminationEvent
.class,auditEvent
.getRevisionNumber());
185 if(occurrence
!= null) {
186 query
.add(AuditEntity
.relatedId("identifiedUnit").eq(occurrence
.getId()));
189 if(taxonBase
!= null) {
190 query
.add(AuditEntity
.relatedId("taxon").eq(taxonBase
.getId()));
192 if(pageSize
!= null) {
193 query
.setMaxResults(pageSize
);
194 if(pageNumber
!= null) {
195 query
.setFirstResult(pageNumber
* pageSize
);
197 query
.setFirstResult(0);
200 List
<DeterminationEvent
> result
= query
.getResultList();
201 defaultBeanInitializer
.initializeAll(result
, propertyPaths
);
207 public List
<Media
> getMedia(SpecimenOrObservationBase occurence
, Integer pageSize
, Integer pageNumber
, List
<String
> propertyPaths
) {
208 checkNotInPriorView("OccurrenceDaoHibernateImpl.getMedia(SpecimenOrObservationBase occurence, Integer pageSize, Integer pageNumber, List<String> propertyPaths)");
209 Query query
= getSession().createQuery("select media from SpecimenOrObservationBase occurence join occurence.media media where occurence = :occurence");
210 query
.setParameter("occurence", occurence
);
212 if(pageSize
!= null) {
213 query
.setMaxResults(pageSize
);
214 if(pageNumber
!= null) {
215 query
.setFirstResult(pageNumber
* pageSize
);
217 query
.setFirstResult(0);
221 List
<Media
> results
= query
.list();
222 defaultBeanInitializer
.initializeAll(results
, propertyPaths
);
227 public void rebuildIndex() {
228 FullTextSession fullTextSession
= Search
.getFullTextSession(getSession());
230 for(SpecimenOrObservationBase
<?
> occurrence
: list(null,null)) { // re-index all taxon base
232 for(DeterminationEvent determination
: occurrence
.getDeterminations()) {
233 Hibernate
.initialize(determination
.getActor());
234 Hibernate
.initialize(determination
.getTaxon());
236 Hibernate
.initialize(occurrence
.getDefinition());
237 if(occurrence
instanceof DerivedUnit
) {
238 DerivedUnit derivedUnit
= (DerivedUnit
) occurrence
;
239 Hibernate
.initialize(derivedUnit
.getCollection());
240 if(derivedUnit
.getCollection() != null) {
241 Hibernate
.initialize(derivedUnit
.getCollection().getSuperCollection());
242 Hibernate
.initialize(derivedUnit
.getCollection().getInstitute());
244 Hibernate
.initialize(derivedUnit
.getStoredUnder());
245 SpecimenOrObservationBase
<?
> original
= derivedUnit
.getOriginalUnit();
246 if(original
!= null && original
.isInstanceOf(FieldUnit
.class)) {
247 FieldUnit fieldUnit
= CdmBase
.deproxy(original
, FieldUnit
.class);
248 Hibernate
.initialize(fieldUnit
.getGatheringEvent());
249 if(fieldUnit
.getGatheringEvent() != null) {
250 Hibernate
.initialize(fieldUnit
.getGatheringEvent().getActor());
254 fullTextSession
.index(occurrence
);
256 fullTextSession
.flushToIndexes();
260 public int count(Class
<?
extends SpecimenOrObservationBase
> clazz
, TaxonName determinedAs
) {
262 Criteria criteria
= null;
264 criteria
= getSession().createCriteria(type
);
266 criteria
= getSession().createCriteria(clazz
);
269 criteria
.createCriteria("determinations").add(Restrictions
.eq("taxonName", determinedAs
));
270 criteria
.setProjection(Projections
.projectionList().add(Projections
.rowCount()));
271 return ((Number
)criteria
.uniqueResult()).intValue();
275 public List
<SpecimenOrObservationBase
> list(Class
<?
extends SpecimenOrObservationBase
> clazz
, TaxonName determinedAs
, Integer limit
, Integer start
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
276 Criteria criteria
= null;
278 criteria
= getSession().createCriteria(type
);
280 criteria
= getSession().createCriteria(clazz
);
283 criteria
.createCriteria("determinations").add(Restrictions
.eq("taxonName", determinedAs
));
287 criteria
.setFirstResult(start
);
289 criteria
.setFirstResult(0);
291 criteria
.setMaxResults(limit
);
294 addOrder(criteria
,orderHints
);
296 @SuppressWarnings("unchecked")
297 List
<SpecimenOrObservationBase
> results
= criteria
.list();
298 defaultBeanInitializer
.initializeAll(results
, propertyPaths
);
303 public int count(Class
<?
extends SpecimenOrObservationBase
> clazz
, TaxonBase determinedAs
) {
305 Criteria criteria
= null;
307 criteria
= getSession().createCriteria(type
);
309 criteria
= getSession().createCriteria(clazz
);
312 criteria
.createCriteria("determinations").add(Restrictions
.eq("taxon", determinedAs
));
313 criteria
.setProjection(Projections
.projectionList().add(Projections
.rowCount()));
314 return ((Number
)criteria
.uniqueResult()).intValue();
318 public List
<SpecimenOrObservationBase
> list(Class
<?
extends SpecimenOrObservationBase
> clazz
, TaxonBase determinedAs
, Integer limit
, Integer start
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
319 Criteria criteria
= null;
321 criteria
= getSession().createCriteria(type
);
323 criteria
= getSession().createCriteria(clazz
);
326 criteria
.createCriteria("determinations").add(Restrictions
.eq("taxon", determinedAs
));
330 criteria
.setFirstResult(start
);
332 criteria
.setFirstResult(0);
334 criteria
.setMaxResults(limit
);
337 addOrder(criteria
,orderHints
);
339 @SuppressWarnings("unchecked")
340 List
<SpecimenOrObservationBase
> results
= criteria
.list();
341 defaultBeanInitializer
.initializeAll(results
, propertyPaths
);
346 public <T
extends SpecimenOrObservationBase
> List
<UuidAndTitleCache
<SpecimenOrObservationBase
>> findOccurrencesUuidAndTitleCache(
347 Class
<T
> clazz
, String queryString
, String significantIdentifier
, SpecimenOrObservationType recordBasis
,
348 Taxon associatedTaxon
, TaxonName associatedTaxonName
, MatchMode matchmode
, Integer limit
, Integer start
,
349 List
<OrderHint
> orderHints
) {
350 Criteria criteria
= createFindOccurrenceCriteria(clazz
, queryString
, significantIdentifier
, recordBasis
,
351 associatedTaxon
, associatedTaxonName
, matchmode
, limit
, start
, orderHints
, null);
353 ProjectionList projectionList
= Projections
.projectionList();
354 projectionList
.add(Projections
.property("uuid"));
355 projectionList
.add(Projections
.property("id"));
356 projectionList
.add(Projections
.property("titleCache"));
357 criteria
.setProjection(projectionList
);
359 List
<Object
[]> result
= criteria
.list();
360 List
<UuidAndTitleCache
<SpecimenOrObservationBase
>> uuidAndTitleCacheList
= new ArrayList
<>();
361 for(Object
[] object
: result
){
362 uuidAndTitleCacheList
.add(new UuidAndTitleCache
<SpecimenOrObservationBase
>((UUID
) object
[0],(Integer
) object
[1], (String
) object
[2]));
364 return uuidAndTitleCacheList
;
366 return Collections
.emptyList();
370 public <T
extends SpecimenOrObservationBase
> List
<T
> findOccurrences(Class
<T
> clazz
, String queryString
,
371 String significantIdentifier
, SpecimenOrObservationType recordBasis
, Taxon associatedTaxon
, TaxonName associatedTaxonName
,
372 MatchMode matchmode
, Integer limit
, Integer start
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
374 Criteria criteria
= createFindOccurrenceCriteria(clazz
, queryString
, significantIdentifier
, recordBasis
,
375 associatedTaxon
, associatedTaxonName
, matchmode
, limit
, start
, orderHints
, propertyPaths
);
377 @SuppressWarnings("unchecked")
378 List
<T
> results
= criteria
.list();
379 defaultBeanInitializer
.initializeAll(results
, propertyPaths
);
382 return Collections
.emptyList();
385 private <T
extends SpecimenOrObservationBase
> Criteria
createFindOccurrenceCriteria(Class
<T
> clazz
, String queryString
,
386 String significantIdentifier
, SpecimenOrObservationType recordBasis
, Taxon associatedTaxon
, TaxonName associatedTaxonName
, MatchMode matchmode
, Integer limit
,
387 Integer start
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
388 Criteria criteria
= null;
391 criteria
= getSession().createCriteria(type
);
393 criteria
= getSession().createCriteria(clazz
);
397 if (queryString
!= null) {
398 if(matchmode
== null) {
399 matchmode
= MatchMode
.ANYWHERE
;
400 criteria
.add(Restrictions
.ilike("titleCache", matchmode
.queryStringFrom(queryString
)));
401 } else if(matchmode
== MatchMode
.BEGINNING
) {
402 criteria
.add(Restrictions
.ilike("titleCache", matchmode
.queryStringFrom(queryString
), org
.hibernate
.criterion
.MatchMode
.START
));
403 } else if(matchmode
== MatchMode
.END
) {
404 criteria
.add(Restrictions
.ilike("titleCache", matchmode
.queryStringFrom(queryString
), org
.hibernate
.criterion
.MatchMode
.END
));
405 } else if(matchmode
== MatchMode
.EXACT
) {
406 criteria
.add(Restrictions
.ilike("titleCache", matchmode
.queryStringFrom(queryString
), org
.hibernate
.criterion
.MatchMode
.EXACT
));
408 criteria
.add(Restrictions
.ilike("titleCache", matchmode
.queryStringFrom(queryString
), org
.hibernate
.criterion
.MatchMode
.ANYWHERE
));
412 //significant identifier
413 if (significantIdentifier
!= null) {
414 criteria
.add(Restrictions
.or(Restrictions
.ilike("accessionNumber", significantIdentifier
),
415 Restrictions
.ilike("catalogNumber", significantIdentifier
), Restrictions
.ilike("barcode", significantIdentifier
)));
418 //recordBasis/SpecimenOrObservationType
419 Set
<SpecimenOrObservationType
> typeAndSubtypes
= new HashSet
<SpecimenOrObservationType
>();
420 if(recordBasis
==null){
422 SpecimenOrObservationType
[] values
= SpecimenOrObservationType
.values();
423 for (SpecimenOrObservationType specimenOrObservationType
: values
) {
424 typeAndSubtypes
.add(specimenOrObservationType
);
428 typeAndSubtypes
= recordBasis
.getGeneralizationOf(true);
429 typeAndSubtypes
.add(recordBasis
);
431 criteria
.add(Restrictions
.in("recordBasis", typeAndSubtypes
));
433 Set
<UUID
> associationUuids
= new HashSet
<UUID
>();
435 if(associatedTaxon
!=null){
436 List
<UuidAndTitleCache
<SpecimenOrObservationBase
>> associatedTaxaList
= listUuidAndTitleCacheByAssociatedTaxon(clazz
, associatedTaxon
, limit
, start
, orderHints
);
437 if(associatedTaxaList
!=null){
438 for (UuidAndTitleCache
<SpecimenOrObservationBase
> uuidAndTitleCache
: associatedTaxaList
) {
439 associationUuids
.add(uuidAndTitleCache
.getUuid());
443 //taxon name associations
444 else if(associatedTaxonName
!=null){
445 List
<?
extends SpecimenOrObservationBase
> associatedTaxaList
= listByAssociatedTaxonName(clazz
, associatedTaxonName
, limit
, start
, orderHints
, propertyPaths
);
446 if(associatedTaxaList
!=null){
447 for (SpecimenOrObservationBase specimenOrObservationBase
: associatedTaxaList
) {
448 associationUuids
.add(specimenOrObservationBase
.getUuid());
452 if(associatedTaxon
!=null || associatedTaxonName
!=null){
453 if(!associationUuids
.isEmpty()){
454 criteria
.add(Restrictions
.in("uuid", associationUuids
));
462 criteria
.setFirstResult(start
);
464 criteria
.setFirstResult(0);
466 criteria
.setMaxResults(limit
);
469 if(orderHints
!=null){
470 addOrder(criteria
,orderHints
);
477 public <T
extends SpecimenOrObservationBase
> int countOccurrences(Class
<T
> clazz
, String queryString
,
478 String significantIdentifier
, SpecimenOrObservationType recordBasis
, Taxon associatedTaxon
, TaxonName associatedTaxonName
,
479 MatchMode matchmode
, Integer limit
, Integer start
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
480 Criteria criteria
= createFindOccurrenceCriteria(clazz
, queryString
, significantIdentifier
, recordBasis
,
481 associatedTaxon
, associatedTaxonName
, matchmode
, limit
, start
, orderHints
, propertyPaths
);
485 criteria
.setProjection(Projections
.rowCount());
487 return ((Number
)criteria
.uniqueResult()).intValue();
493 public List
<UuidAndTitleCache
<DerivedUnit
>> getDerivedUnitUuidAndTitleCache(Integer limit
, String pattern
) {
494 List
<UuidAndTitleCache
<DerivedUnit
>> list
= new ArrayList
<UuidAndTitleCache
<DerivedUnit
>>();
495 Session session
= getSession();
497 if (pattern
!= null){
498 query
= session
.createQuery("select uuid, id, titleCache from " + type
.getSimpleName() + " where NOT dtype = " + FieldUnit
.class.getSimpleName() +" AND titleCache like :pattern");
499 pattern
= pattern
.replace("*", "%");
500 pattern
= pattern
.replace("?", "_");
501 pattern
= pattern
+ "%";
502 query
.setParameter("pattern", pattern
);
504 query
= session
.createQuery("select uuid, id, titleCache from " + type
.getSimpleName() +" where NOT dtype = " + FieldUnit
.class.getSimpleName());
507 query
.setMaxResults(limit
);
512 List
<Object
[]> result
= query
.list();
514 for(Object
[] object
: result
){
515 list
.add(new UuidAndTitleCache
<DerivedUnit
>(DerivedUnit
.class, (UUID
) object
[0], (Integer
)object
[1], (String
) object
[2]));
522 public List
<UuidAndTitleCache
<FieldUnit
>> getFieldUnitUuidAndTitleCache() {
523 List
<UuidAndTitleCache
<FieldUnit
>> list
= new ArrayList
<UuidAndTitleCache
<FieldUnit
>>();
524 Session session
= getSession();
526 Query query
= session
.createQuery("select uuid, id, titleCache from " + type
.getSimpleName() + " where dtype = " + FieldUnit
.class.getSimpleName());
528 List
<Object
[]> result
= query
.list();
530 for(Object
[] object
: result
){
531 list
.add(new UuidAndTitleCache
<FieldUnit
>(FieldUnit
.class, (UUID
) object
[0], (Integer
)object
[1], (String
) object
[2]));
538 public <T
extends SpecimenOrObservationBase
> List
<T
> listByAssociatedTaxonName(Class
<T
> type
,
539 TaxonName associatedTaxonName
, Integer limit
, Integer start
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
540 Set
<SpecimenOrObservationBase
> setOfAll
= new HashSet
<SpecimenOrObservationBase
>();
542 // A Taxon name may be referenced by the DeterminationEvent of the SpecimenOrObservationBase
543 List
<SpecimenOrObservationBase
> byDetermination
= list(type
, associatedTaxonName
, null, 0, null, null);
544 setOfAll
.addAll(byDetermination
);
546 if(setOfAll
.size() == 0){
547 // no need querying the data base
548 return new ArrayList
<T
>();
553 " from SpecimenOrObservationBase sob" +
554 " where sob in (:setOfAll)";
556 if(type
!= null && !type
.equals(SpecimenOrObservationBase
.class)){
557 queryString
+= " and sob.class = :type";
560 if(orderHints
!= null && orderHints
.size() > 0){
561 queryString
+= " order by ";
562 String orderStr
= "";
563 for(OrderHint orderHint
: orderHints
){
564 if(orderStr
.length() > 0){
567 queryString
+= "sob." + orderHint
.getPropertyName() + " " + orderHint
.getSortOrder().toHql();
569 queryString
+= orderStr
;
572 Query query
= getSession().createQuery(queryString
);
573 query
.setParameterList("setOfAll", setOfAll
);
575 if(type
!= null && !type
.equals(SpecimenOrObservationBase
.class)){
576 query
.setParameter("type", type
.getSimpleName());
581 query
.setFirstResult(start
);
583 query
.setFirstResult(0);
585 query
.setMaxResults(limit
);
589 List
<T
> results
= query
.list();
590 defaultBeanInitializer
.initializeAll(results
, propertyPaths
);
594 private List
<SpecimenNodeWrapper
> querySpecimen(
595 Query query
, List
<UUID
> taxonNodeUuids
,
596 Integer limit
, Integer start
){
597 query
.setParameterList("taxonNodeUuids", taxonNodeUuids
);
601 query
.setFirstResult(start
);
603 query
.setFirstResult(0);
605 query
.setMaxResults(limit
);
608 List
<SpecimenNodeWrapper
> list
= new ArrayList
<>();
609 List
<Object
[]> result
= query
.list();
610 for(Object
[] object
: result
){
611 list
.add(new SpecimenNodeWrapper(
612 new UuidAndTitleCache
<SpecimenOrObservationBase
>(
616 (TaxonNode
)object
[3]));
621 private List
<SpecimenNodeWrapper
> queryIndividualAssociatedSpecimen(List
<UUID
> taxonNodeUuids
,
622 Integer limit
, Integer start
){
623 String queryString
= "SELECT "
624 + "de.associatedSpecimenOrObservation.uuid, "
625 + "de.associatedSpecimenOrObservation.id, "
626 + "de.associatedSpecimenOrObservation.titleCache, "
628 + "FROM DescriptionElementBase AS de "
629 + "LEFT JOIN de.inDescription AS d "
630 + "LEFT JOIN d.taxon AS t "
631 + "JOIN t.taxonNodes AS tn "
632 + "WHERE d.class = 'TaxonDescription' "
633 + "AND tn.uuid in (:taxonNodeUuids) "
635 Query query
= getSession().createQuery(queryString
);
636 return querySpecimen(query
, taxonNodeUuids
, limit
, start
);
639 private List
<SpecimenNodeWrapper
> queryTypeSpecimen(List
<UUID
> taxonNodeUuids
,
640 Integer limit
, Integer start
){
641 String queryString
= "SELECT "
642 + "td.typeSpecimen.uuid, "
643 + "td.typeSpecimen.id, "
644 + "td.typeSpecimen.titleCache, "
646 + "FROM SpecimenTypeDesignation AS td "
647 + "LEFT JOIN td.typifiedNames AS tn "
648 + "LEFT JOIN tn.taxonBases AS t "
649 + "JOIN t.taxonNodes AS tn "
650 + "WHERE tn.uuid in (:taxonNodeUuids) "
652 Query query
= getSession().createQuery(queryString
);
653 return querySpecimen(query
, taxonNodeUuids
, limit
, start
);
656 private List
<SpecimenNodeWrapper
> queryTaxonDeterminations(List
<UUID
> taxonNodeUuids
,
657 Integer limit
, Integer start
){
658 String queryString
= "SELECT "
659 + "det.identifiedUnit.uuid, "
660 + "det.identifiedUnit.id, "
661 + "det.identifiedUnit.titleCache, "
663 + "FROM DeterminationEvent AS det "
664 + "LEFT JOIN det.taxon AS t "
665 + "JOIN t.taxonNodes AS tn "
666 + "WHERE tn.uuid in (:taxonNodeUuids) "
668 Query query
= getSession().createQuery(queryString
);
669 return querySpecimen(query
, taxonNodeUuids
, limit
, start
);
672 private List
<SpecimenNodeWrapper
> queryTaxonNameDeterminations(List
<UUID
> taxonNodeUuids
,
673 Integer limit
, Integer start
){
674 String queryString
= "SELECT "
675 + "det.identifiedUnit.uuid, "
676 + "det.identifiedUnit.id, "
677 + "det.identifiedUnit.titleCache, "
679 + "FROM DeterminationEvent AS det "
680 + "LEFT JOIN det.taxonName AS n "
681 + "LEFT JOIN n.taxonBases AS t "
682 + "JOIN t.taxonNodes AS tn "
683 + "WHERE tn.uuid in (:taxonNodeUuids) "
685 Query query
= getSession().createQuery(queryString
);
686 return querySpecimen(query
, taxonNodeUuids
, limit
, start
);
690 public Collection
<SpecimenNodeWrapper
> listUuidAndTitleCacheByAssociatedTaxon(List
<UUID
> taxonNodeUuids
,
691 Integer limit
, Integer start
){
693 Collection
<SpecimenNodeWrapper
> wrappers
= new HashSet
<>();
694 wrappers
.addAll(queryIndividualAssociatedSpecimen(taxonNodeUuids
, limit
, start
));
695 wrappers
.addAll(queryTaxonDeterminations(taxonNodeUuids
, limit
, start
));
696 wrappers
.addAll(queryTaxonNameDeterminations(taxonNodeUuids
, limit
, start
));
697 wrappers
.addAll(queryTypeSpecimen(taxonNodeUuids
, limit
, start
));
703 public <T
extends SpecimenOrObservationBase
> List
<UuidAndTitleCache
<SpecimenOrObservationBase
>> listUuidAndTitleCacheByAssociatedTaxon(Class
<T
> clazz
, Taxon associatedTaxon
,
704 Integer limit
, Integer start
, List
<OrderHint
> orderHints
){
705 Query query
= createSpecimenQuery("sob.uuid, sob.id, sob.titleCache", clazz
, associatedTaxon
, limit
, start
, orderHints
, null);
707 return Collections
.emptyList();
709 List
<UuidAndTitleCache
<SpecimenOrObservationBase
>> list
= new ArrayList
<>();
710 List
<Object
[]> result
= query
.list();
711 for(Object
[] object
: result
){
712 list
.add(new UuidAndTitleCache
<SpecimenOrObservationBase
>((UUID
) object
[0],(Integer
) object
[1], (String
) object
[2]));
718 public <T
extends SpecimenOrObservationBase
> List
<T
> listByAssociatedTaxon(Class
<T
> clazz
,
719 Taxon associatedTaxon
, Integer limit
, Integer start
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
720 Query query
= createSpecimenQuery("sob", clazz
, associatedTaxon
, limit
, start
, orderHints
, propertyPaths
);
722 return Collections
.emptyList();
724 List
<T
> results
= query
.list();
725 defaultBeanInitializer
.initializeAll(results
, propertyPaths
);
729 private <T
extends SpecimenOrObservationBase
> Query
createSpecimenQuery(String select
, Class
<T
> clazz
,
730 Taxon associatedTaxon
, Integer limit
, Integer start
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
){
731 Set
<SpecimenOrObservationBase
> setOfAll
= new HashSet
<>();
732 Set
<Integer
> setOfAllIds
= new HashSet
<>();
734 Criteria criteria
= null;
736 criteria
= getSession().createCriteria(type
, "specimen");
738 criteria
= getSession().createCriteria(clazz
, "specimen");
741 Disjunction determinationOr
= Restrictions
.disjunction();
743 // A Taxon may be referenced by the DeterminationEvent of the SpecimenOrObservationBase
744 Criteria determinationsCriteria
= criteria
.createCriteria("determinations");
746 determinationOr
.add(Restrictions
.eq("taxon", associatedTaxon
));
747 //check also for synonyms
748 for (Synonym synonym
: associatedTaxon
.getSynonyms()) {
749 determinationOr
.add(Restrictions
.eq("taxon", synonym
));
752 //check also for name determinations
753 determinationOr
.add(Restrictions
.eq("taxonName", associatedTaxon
.getName()));
754 for (TaxonName synonymName
: associatedTaxon
.getSynonymNames()) {
755 determinationOr
.add(Restrictions
.eq("taxonName", synonymName
));
758 determinationsCriteria
.add(determinationOr
);
762 criteria
.setFirstResult(start
);
764 criteria
.setFirstResult(0);
766 criteria
.setMaxResults(limit
);
768 criteria
.setProjection(Projections
.property("id"));
770 addOrder(criteria
,orderHints
);
772 @SuppressWarnings("unchecked")
773 List
<Integer
> detResults
= criteria
.list();
774 setOfAllIds
.addAll(detResults
);
776 // The IndividualsAssociation elements in a TaxonDescription contain DerivedUnits
777 setOfAllIds
.addAll(descriptionDao
.getIndividualAssociationSpecimenIDs(
778 associatedTaxon
.getUuid(), null, null, 0, null));
781 // SpecimenTypeDesignations may be associated with the TaxonName.
782 setOfAllIds
.addAll(taxonNameDao
.getTypeSpecimenIdsForTaxonName(
783 associatedTaxon
.getName(), null, null, null));
785 // SpecimenTypeDesignations may be associated with any HomotypicalGroup related to the specific Taxon.
786 //TODO adapt to set of ids
787 for(HomotypicalGroup homotypicalGroup
: associatedTaxon
.getHomotypicSynonymyGroups()) {
788 List
<SpecimenTypeDesignation
> byHomotypicalGroup
= homotypicalGroupDao
.getTypeDesignations(homotypicalGroup
, SpecimenTypeDesignation
.class, null, null, 0, null);
789 for (SpecimenTypeDesignation specimenTypeDesignation
: byHomotypicalGroup
) {
790 setOfAll
.add(specimenTypeDesignation
.getTypeSpecimen());
794 if(setOfAllIds
.size() == 0){
795 // no need querying the data base
801 " from SpecimenOrObservationBase sob" +
802 " where sob.id in (:setOfAllIds)";
804 if(clazz
!= null && !clazz
.equals(SpecimenOrObservationBase
.class)){
805 queryString
+= " and sob.class = :type ";
808 if(orderHints
!= null && orderHints
.size() > 0){
809 queryString
+= " order by ";
810 String orderStr
= "";
811 for(OrderHint orderHint
: orderHints
){
812 if(orderStr
.length() > 0){
815 queryString
+= "sob." + orderHint
.getPropertyName() + " " + orderHint
.getSortOrder().toHql();
817 queryString
+= orderStr
;
820 Query query
= getSession().createQuery(queryString
);
821 query
.setParameterList("setOfAllIds", setOfAllIds
);
823 if(clazz
!= null && !clazz
.equals(SpecimenOrObservationBase
.class)){
824 query
.setParameter("type", clazz
.getSimpleName());
829 query
.setFirstResult(start
);
831 query
.setFirstResult(0);
833 query
.setMaxResults(limit
);
840 public Collection
<SpecimenOrObservationBase
> listBySpecimenOrObservationType(SpecimenOrObservationType type
, Integer limit
, Integer start
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
841 String queryString
= "FROM SpecimenOrObservationBase specimens WHERE specimens.recordBasis = :type";
843 if(orderHints
!= null && orderHints
.size() > 0){
844 queryString
+= " order by ";
845 String orderStr
= "";
846 for(OrderHint orderHint
: orderHints
){
847 if(orderStr
.length() > 0){
850 queryString
+= "specimens." + orderHint
.getPropertyName() + " " + orderHint
.getSortOrder().toHql();
852 queryString
+= orderStr
;
855 Query query
= getSession().createQuery(queryString
);
856 query
.setParameter("type", type
);
860 query
.setFirstResult(start
);
862 query
.setFirstResult(0);
864 query
.setMaxResults(limit
);
867 List results
= query
.list();
868 defaultBeanInitializer
.initializeAll(results
, propertyPaths
);
873 public Collection
<DeterminationEvent
> listDeterminationEvents(SpecimenOrObservationBase
<?
> specimen
, Integer limit
, Integer start
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
874 String queryString
= "FROM DeterminationEvent determination WHERE determination.identifiedUnit = :specimen";
876 if(orderHints
!= null && orderHints
.size() > 0){
877 queryString
+= " order by ";
878 String orderStr
= "";
879 for(OrderHint orderHint
: orderHints
){
880 if(orderStr
.length() > 0){
883 queryString
+= "determination." + orderHint
.getPropertyName() + " " + orderHint
.getSortOrder().toHql();
885 queryString
+= orderStr
;
888 Query query
= getSession().createQuery(queryString
);
889 query
.setParameter("specimen", specimen
);
893 query
.setFirstResult(start
);
895 query
.setFirstResult(0);
897 query
.setMaxResults(limit
);
900 List results
= query
.list();
901 defaultBeanInitializer
.initializeAll(results
, propertyPaths
);
906 public Collection
<SpecimenTypeDesignation
> listTypeDesignations(SpecimenOrObservationBase
<?
> specimen
, Integer limit
, Integer start
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
907 String queryString
= "FROM SpecimenTypeDesignation designations WHERE designations.typeSpecimen = :specimen";
909 if(orderHints
!= null && orderHints
.size() > 0){
910 queryString
+= " ORDER BY ";
911 String orderStr
= "";
912 for(OrderHint orderHint
: orderHints
){
913 if(orderStr
.length() > 0){
916 queryString
+= "designations." + orderHint
.getPropertyName() + " " + orderHint
.getSortOrder().toHql();
918 queryString
+= orderStr
;
921 Query query
= getSession().createQuery(queryString
);
922 query
.setParameter("specimen", specimen
);
926 query
.setFirstResult(start
);
928 query
.setFirstResult(0);
930 query
.setMaxResults(limit
);
933 @SuppressWarnings("unchecked")
934 List
<SpecimenTypeDesignation
> results
= query
.list();
935 defaultBeanInitializer
.initializeAll(results
, propertyPaths
);
940 public Collection
<IndividualsAssociation
> listIndividualsAssociations(SpecimenOrObservationBase
<?
> specimen
, Integer limit
, Integer start
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
941 //DISTINCT is necessary if more than one description exists for a taxon because we create the cross product of all taxon descriptions and description elements
942 String queryString
= "FROM IndividualsAssociation associations WHERE associations.associatedSpecimenOrObservation = :specimen";
944 if(orderHints
!= null && orderHints
.size() > 0){
945 queryString
+= " order by ";
946 String orderStr
= "";
947 for(OrderHint orderHint
: orderHints
){
948 if(orderStr
.length() > 0){
951 queryString
+= "associations." + orderHint
.getPropertyName() + " " + orderHint
.getSortOrder().toHql();
953 queryString
+= orderStr
;
956 Query query
= getSession().createQuery(queryString
);
957 query
.setParameter("specimen", specimen
);
961 query
.setFirstResult(start
);
963 query
.setFirstResult(0);
965 query
.setMaxResults(limit
);
968 List results
= query
.list();
969 defaultBeanInitializer
.initializeAll(results
, propertyPaths
);
974 public Collection
<DescriptionBase
<?
>> listDescriptionsWithDescriptionSpecimen(SpecimenOrObservationBase
<?
> specimen
, Integer limit
, Integer start
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
975 //DISTINCT is necessary if more than one description exists for a taxon because we create the cross product of all taxon descriptions and description elements
976 String queryString
= "FROM DescriptionBase descriptions WHERE descriptions.describedSpecimenOrObservation = :specimen";
978 if(orderHints
!= null && orderHints
.size() > 0){
979 queryString
+= " order by ";
980 String orderStr
= "";
981 for(OrderHint orderHint
: orderHints
){
982 if(orderStr
.length() > 0){
985 queryString
+= "descriptions." + orderHint
.getPropertyName() + " " + orderHint
.getSortOrder().toHql();
987 queryString
+= orderStr
;
990 Query query
= getSession().createQuery(queryString
);
991 query
.setParameter("specimen", specimen
);
995 query
.setFirstResult(start
);
997 query
.setFirstResult(0);
999 query
.setMaxResults(limit
);
1002 List results
= query
.list();
1003 defaultBeanInitializer
.initializeAll(results
, propertyPaths
);
1011 public List
<FieldUnit
> getFieldUnitsForGatheringEvent(UUID gatheringEventUuid
, Integer limit
, Integer start
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
1012 String queryString
= "FROM SpecimenOrObservationBase s WHERE s.gatheringEvent.uuid = :gatheringEventUuid";
1014 if(orderHints
!= null && orderHints
.size() > 0){
1015 queryString
+= " order by ";
1016 String orderStr
= "";
1017 for(OrderHint orderHint
: orderHints
){
1018 if(orderStr
.length() > 0){
1021 queryString
+= "descriptions." + orderHint
.getPropertyName() + " " + orderHint
.getSortOrder().toHql();
1023 queryString
+= orderStr
;
1026 Query query
= getSession().createQuery(queryString
);
1027 query
.setParameter("gatheringEventUuid", gatheringEventUuid
);
1031 query
.setFirstResult(start
);
1033 query
.setFirstResult(0);
1035 query
.setMaxResults(limit
);
1038 List results
= query
.list();
1039 defaultBeanInitializer
.initializeAll(results
, propertyPaths
);