-/**\r
-* Copyright (C) 2008 EDIT\r
-* European Distributed Institute of Taxonomy\r
-* http://www.e-taxonomy.eu\r
-*/\r
-\r
-package eu.etaxonomy.cdm.persistence.dao.hibernate.occurrence;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Collection;\r
-import java.util.Collections;\r
-import java.util.HashSet;\r
-import java.util.List;\r
-import java.util.Set;\r
-import java.util.UUID;\r
-\r
-import org.apache.log4j.Logger;\r
-import org.hibernate.Criteria;\r
-import org.hibernate.Hibernate;\r
-import org.hibernate.Query;\r
-import org.hibernate.Session;\r
-import org.hibernate.criterion.Projections;\r
-import org.hibernate.criterion.Restrictions;\r
-import org.hibernate.envers.query.AuditEntity;\r
-import org.hibernate.envers.query.AuditQuery;\r
-import org.hibernate.search.FullTextSession;\r
-import org.hibernate.search.Search;\r
-import org.springframework.beans.factory.annotation.Autowired;\r
-import org.springframework.stereotype.Repository;\r
-\r
-import eu.etaxonomy.cdm.model.description.DescriptionBase;\r
-import eu.etaxonomy.cdm.model.description.IndividualsAssociation;\r
-import eu.etaxonomy.cdm.model.media.Media;\r
-import eu.etaxonomy.cdm.model.molecular.DnaSample;\r
-import eu.etaxonomy.cdm.model.name.HomotypicalGroup;\r
-import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignation;\r
-import eu.etaxonomy.cdm.model.occurrence.DerivationEvent;\r
-import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;\r
-import eu.etaxonomy.cdm.model.occurrence.DeterminationEvent;\r
-import eu.etaxonomy.cdm.model.occurrence.FieldUnit;\r
-import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;\r
-import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationType;\r
-import eu.etaxonomy.cdm.model.taxon.Taxon;\r
-import eu.etaxonomy.cdm.model.taxon.TaxonBase;\r
-import eu.etaxonomy.cdm.model.view.AuditEvent;\r
-import eu.etaxonomy.cdm.persistence.dao.description.IDescriptionDao;\r
-import eu.etaxonomy.cdm.persistence.dao.hibernate.common.IdentifiableDaoBase;\r
-import eu.etaxonomy.cdm.persistence.dao.hibernate.taxon.TaxonDaoHibernateImpl;\r
-import eu.etaxonomy.cdm.persistence.dao.name.IHomotypicalGroupDao;\r
-import eu.etaxonomy.cdm.persistence.dao.name.ITaxonNameDao;\r
-import eu.etaxonomy.cdm.persistence.dao.occurrence.IOccurrenceDao;\r
-import eu.etaxonomy.cdm.persistence.dto.UuidAndTitleCache;\r
-import eu.etaxonomy.cdm.persistence.query.MatchMode;\r
-import eu.etaxonomy.cdm.persistence.query.OrderHint;\r
-\r
-/**\r
- * @author a.babadshanjan\r
- * @created 01.09.2008\r
- */\r
-@Repository\r
-public class OccurrenceDaoHibernateImpl extends IdentifiableDaoBase<SpecimenOrObservationBase> implements IOccurrenceDao {\r
-\r
- @SuppressWarnings("unused")\r
- private static final Logger logger = Logger.getLogger(TaxonDaoHibernateImpl.class);\r
-\r
- @Autowired\r
- private IDescriptionDao descriptionDao;\r
-\r
- @Autowired\r
- private ITaxonNameDao taxonNameDao;\r
-\r
- @Autowired\r
- private IHomotypicalGroupDao homotypicalGroupDao;\r
-\r
- public OccurrenceDaoHibernateImpl() {\r
- super(SpecimenOrObservationBase.class);\r
- indexedClasses = new Class[7];\r
- indexedClasses[0] = FieldUnit.class;\r
- indexedClasses[1] = DerivedUnit.class;\r
- indexedClasses[5] = DnaSample.class;\r
- }\r
-\r
- @Override\r
- public int countDerivationEvents(SpecimenOrObservationBase occurence) {\r
- checkNotInPriorView("OccurrenceDaoHibernateImpl.countDerivationEvents(SpecimenOrObservationBase occurence)");\r
- Query query = getSession().createQuery("select count(distinct derivationEvent) from DerivationEvent derivationEvent join derivationEvent.originals occurence where occurence = :occurence");\r
- query.setParameter("occurence", occurence);\r
-\r
- return ((Long)query.uniqueResult()).intValue();\r
- }\r
-\r
- @Override\r
- public int countDeterminations(SpecimenOrObservationBase occurrence, TaxonBase taxonBase) {\r
- AuditEvent auditEvent = getAuditEventFromContext();\r
- if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {\r
- Criteria criteria = getSession().createCriteria(DeterminationEvent.class);\r
- if(occurrence != null) {\r
- criteria.add(Restrictions.eq("identifiedUnit",occurrence));\r
- }\r
-\r
- if(taxonBase != null) {\r
- criteria.add(Restrictions.eq("taxon",taxonBase));\r
- }\r
-\r
- criteria.setProjection(Projections.rowCount());\r
- return ((Number)criteria.uniqueResult()).intValue();\r
- } else {\r
- AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(DeterminationEvent.class,auditEvent.getRevisionNumber());\r
-\r
- if(occurrence != null) {\r
- query.add(AuditEntity.relatedId("identifiedUnit").eq(occurrence.getId()));\r
- }\r
-\r
- if(taxonBase != null) {\r
- query.add(AuditEntity.relatedId("taxon").eq(taxonBase.getId()));\r
- }\r
- query.addProjection(AuditEntity.id().count("id"));\r
-\r
- return ((Long)query.getSingleResult()).intValue();\r
- }\r
- }\r
-\r
- @Override\r
- public int countMedia(SpecimenOrObservationBase occurence) {\r
- checkNotInPriorView("OccurrenceDaoHibernateImpl.countMedia(SpecimenOrObservationBase occurence)");\r
- Query query = getSession().createQuery("select count(media) from SpecimenOrObservationBase occurence join occurence.media media where occurence = :occurence");\r
- query.setParameter("occurence", occurence);\r
-\r
- return ((Long)query.uniqueResult()).intValue();\r
- }\r
-\r
- @Override\r
- public List<DerivationEvent> getDerivationEvents(SpecimenOrObservationBase occurence, Integer pageSize,Integer pageNumber, List<String> propertyPaths) {\r
- checkNotInPriorView("OccurrenceDaoHibernateImpl.getDerivationEvents(SpecimenOrObservationBase occurence, Integer pageSize,Integer pageNumber)");\r
- Query query = getSession().createQuery("select distinct derivationEvent from DerivationEvent derivationEvent join derivationEvent.originals occurence where occurence = :occurence");\r
- query.setParameter("occurence", occurence);\r
-\r
- if(pageSize != null) {\r
- query.setMaxResults(pageSize);\r
- if(pageNumber != null) {\r
- query.setFirstResult(pageNumber * pageSize);\r
- } else {\r
- query.setFirstResult(0);\r
- }\r
- }\r
-\r
- List<DerivationEvent> result = query.list();\r
- defaultBeanInitializer.initializeAll(result, propertyPaths);\r
- return result;\r
- }\r
-\r
- @Override\r
- public List<DeterminationEvent> getDeterminations(SpecimenOrObservationBase occurrence, TaxonBase taxonBase, Integer pageSize, Integer pageNumber, List<String> propertyPaths) {\r
- AuditEvent auditEvent = getAuditEventFromContext();\r
- if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {\r
- Criteria criteria = getSession().createCriteria(DeterminationEvent.class);\r
- if(occurrence != null) {\r
- criteria.add(Restrictions.eq("identifiedUnit",occurrence));\r
- }\r
-\r
- if(taxonBase != null) {\r
- criteria.add(Restrictions.eq("taxon",taxonBase));\r
- }\r
-\r
- if(pageSize != null) {\r
- criteria.setMaxResults(pageSize);\r
- if(pageNumber != null) {\r
- criteria.setFirstResult(pageNumber * pageSize);\r
- } else {\r
- criteria.setFirstResult(0);\r
- }\r
- }\r
- List<DeterminationEvent> result = criteria.list();\r
- defaultBeanInitializer.initializeAll(result, propertyPaths);\r
- return result;\r
- } else {\r
- AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(DeterminationEvent.class,auditEvent.getRevisionNumber());\r
- if(occurrence != null) {\r
- query.add(AuditEntity.relatedId("identifiedUnit").eq(occurrence.getId()));\r
- }\r
-\r
- if(taxonBase != null) {\r
- query.add(AuditEntity.relatedId("taxon").eq(taxonBase.getId()));\r
- }\r
- if(pageSize != null) {\r
- query.setMaxResults(pageSize);\r
- if(pageNumber != null) {\r
- query.setFirstResult(pageNumber * pageSize);\r
- } else {\r
- query.setFirstResult(0);\r
- }\r
- }\r
- List<DeterminationEvent> result = query.getResultList();\r
- defaultBeanInitializer.initializeAll(result, propertyPaths);\r
- return result;\r
- }\r
- }\r
-\r
- @Override\r
- public List<Media> getMedia(SpecimenOrObservationBase occurence, Integer pageSize, Integer pageNumber, List<String> propertyPaths) {\r
- checkNotInPriorView("OccurrenceDaoHibernateImpl.getMedia(SpecimenOrObservationBase occurence, Integer pageSize, Integer pageNumber, List<String> propertyPaths)");\r
- Query query = getSession().createQuery("select media from SpecimenOrObservationBase occurence join occurence.media media where occurence = :occurence");\r
- query.setParameter("occurence", occurence);\r
-\r
- if(pageSize != null) {\r
- query.setMaxResults(pageSize);\r
- if(pageNumber != null) {\r
- query.setFirstResult(pageNumber * pageSize);\r
- } else {\r
- query.setFirstResult(0);\r
- }\r
- }\r
-\r
- List<Media> results = query.list();\r
- defaultBeanInitializer.initializeAll(results, propertyPaths);\r
- return results;\r
- }\r
-\r
- @Override\r
- public void rebuildIndex() {\r
- FullTextSession fullTextSession = Search.getFullTextSession(getSession());\r
-\r
- for(SpecimenOrObservationBase occurrence : list(null,null)) { // re-index all taxon base\r
-\r
- for(DeterminationEvent determination : (Set<DeterminationEvent>)occurrence.getDeterminations()) {\r
- Hibernate.initialize(determination.getActor());\r
- Hibernate.initialize(determination.getTaxon());\r
- }\r
- Hibernate.initialize(occurrence.getDefinition());\r
- if(occurrence instanceof DerivedUnit) {\r
- DerivedUnit derivedUnit = (DerivedUnit) occurrence;\r
- Hibernate.initialize(derivedUnit.getCollection());\r
- if(derivedUnit.getCollection() != null) {\r
- Hibernate.initialize(derivedUnit.getCollection().getSuperCollection());\r
- Hibernate.initialize(derivedUnit.getCollection().getInstitute());\r
- }\r
- Hibernate.initialize(derivedUnit.getStoredUnder());\r
- SpecimenOrObservationBase original = derivedUnit.getOriginalUnit();\r
- if(original != null && original.isInstanceOf(FieldUnit.class)) {\r
- FieldUnit fieldUnit = original.deproxy(original, FieldUnit.class);\r
- Hibernate.initialize(fieldUnit.getGatheringEvent());\r
- if(fieldUnit.getGatheringEvent() != null) {\r
- Hibernate.initialize(fieldUnit.getGatheringEvent().getActor());\r
- }\r
- }\r
- }\r
- fullTextSession.index(occurrence);\r
- }\r
- fullTextSession.flushToIndexes();\r
- }\r
-\r
- @Override\r
- public int count(Class<? extends SpecimenOrObservationBase> clazz, TaxonBase determinedAs) {\r
-\r
- Criteria criteria = null;\r
- if(clazz == null) {\r
- criteria = getSession().createCriteria(type);\r
- } else {\r
- criteria = getSession().createCriteria(clazz);\r
- }\r
-\r
- criteria.createCriteria("determinations").add(Restrictions.eq("taxon", determinedAs));\r
- criteria.setProjection(Projections.projectionList().add(Projections.rowCount()));\r
- return ((Number)criteria.uniqueResult()).intValue();\r
- }\r
-\r
- @Override\r
- public List<SpecimenOrObservationBase> list(Class<? extends SpecimenOrObservationBase> clazz, TaxonBase determinedAs, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {\r
- Criteria criteria = null;\r
- if(clazz == null) {\r
- criteria = getSession().createCriteria(type);\r
- } else {\r
- criteria = getSession().createCriteria(clazz);\r
- }\r
-\r
- criteria.createCriteria("determinations").add(Restrictions.eq("taxon", determinedAs));\r
-\r
- if(limit != null) {\r
- if(start != null) {\r
- criteria.setFirstResult(start);\r
- } else {\r
- criteria.setFirstResult(0);\r
- }\r
- criteria.setMaxResults(limit);\r
- }\r
-\r
- addOrder(criteria,orderHints);\r
-\r
- List<SpecimenOrObservationBase> results = criteria.list();\r
- defaultBeanInitializer.initializeAll(results, propertyPaths);\r
- return results;\r
- }\r
-\r
- @Override\r
- public <T extends SpecimenOrObservationBase> List<T> findOccurrences(Class<T> clazz, String queryString,\r
- String significantIdentifier, SpecimenOrObservationType recordBasis, Taxon associatedTaxon,\r
- MatchMode matchmode, Integer limit,\r
- Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {\r
-\r
- Criteria criteria = createFindOccurrenceCriteria(clazz, queryString, significantIdentifier, recordBasis,\r
- associatedTaxon, matchmode, limit, start, orderHints, propertyPaths);\r
-\r
- if(criteria!=null){\r
-\r
- if(limit != null) {\r
- if(start != null) {\r
- criteria.setFirstResult(start);\r
- } else {\r
- criteria.setFirstResult(0);\r
- }\r
- criteria.setMaxResults(limit);\r
- }\r
-\r
- if(orderHints!=null){\r
- addOrder(criteria,orderHints);\r
- }\r
-\r
- List<T> results = criteria.list();\r
- defaultBeanInitializer.initializeAll(results, propertyPaths);\r
- return results;\r
- }\r
- return Collections.EMPTY_LIST;\r
- }\r
-\r
- /**\r
- * @param clazz\r
- * @param queryString\r
- * @param recordBasis\r
- * @param associatedTaxon\r
- * @param matchmode\r
- * @param limit\r
- * @param start\r
- * @param orderHints\r
- * @param propertyPaths\r
- * @return\r
- */\r
- private <T extends SpecimenOrObservationBase> Criteria createFindOccurrenceCriteria(Class<T> clazz, String queryString,\r
- String significantIdentifier, SpecimenOrObservationType recordBasis, Taxon associatedTaxon, MatchMode matchmode, Integer limit,\r
- Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {\r
- Criteria criteria = null;\r
-\r
- if(clazz == null) {\r
- criteria = getSession().createCriteria(type);\r
- } else {\r
- criteria = getSession().createCriteria(clazz);\r
- }\r
-\r
- //queryString\r
- if (queryString != null) {\r
- if(matchmode == null) {\r
- matchmode = MatchMode.ANYWHERE;\r
- criteria.add(Restrictions.ilike("titleCache", matchmode.queryStringFrom(queryString)));\r
- } else if(matchmode == MatchMode.BEGINNING) {\r
- criteria.add(Restrictions.ilike("titleCache", matchmode.queryStringFrom(queryString), org.hibernate.criterion.MatchMode.START));\r
- } else if(matchmode == MatchMode.END) {\r
- criteria.add(Restrictions.ilike("titleCache", matchmode.queryStringFrom(queryString), org.hibernate.criterion.MatchMode.END));\r
- } else if(matchmode == MatchMode.EXACT) {\r
- criteria.add(Restrictions.ilike("titleCache", matchmode.queryStringFrom(queryString), org.hibernate.criterion.MatchMode.EXACT));\r
- } else {\r
- criteria.add(Restrictions.ilike("titleCache", matchmode.queryStringFrom(queryString), org.hibernate.criterion.MatchMode.ANYWHERE));\r
- }\r
- }\r
-\r
- //significant identifier\r
- if (significantIdentifier != null) {\r
- criteria.add(Restrictions.or(Restrictions.ilike("accessionNumber", significantIdentifier),\r
- Restrictions.ilike("catalogNumber", significantIdentifier), Restrictions.ilike("barcode", significantIdentifier)));\r
- }\r
-\r
- //recordBasis/SpecimenOrObservationType\r
- if(recordBasis!=null){\r
- Set<SpecimenOrObservationType> typeAndSubtypes = recordBasis.getGeneralizationOf(true);\r
- typeAndSubtypes.add(recordBasis);\r
- criteria.add(Restrictions.in("recordBasis", typeAndSubtypes));\r
- }\r
-\r
- //taxon associations\r
- if(associatedTaxon!=null){\r
- List<UUID> associatedTaxonUuids = new ArrayList<UUID>();\r
- List<? extends SpecimenOrObservationBase> associatedTaxaList = listByAssociatedTaxon(clazz!=null?clazz:type, associatedTaxon, limit, start, orderHints, propertyPaths);\r
- if(associatedTaxaList!=null){\r
- for (SpecimenOrObservationBase specimenOrObservationBase : associatedTaxaList) {\r
- associatedTaxonUuids.add(specimenOrObservationBase.getUuid());\r
- }\r
- }\r
- if(!associatedTaxonUuids.isEmpty()){\r
- criteria.add(Restrictions.in("uuid", associatedTaxonUuids));\r
- }\r
- else{\r
- return null;\r
- }\r
- }\r
-\r
- return criteria;\r
- }\r
-\r
-\r
- @Override\r
- public <T extends SpecimenOrObservationBase> int countOccurrences(Class<T> clazz, String queryString,\r
- String significantIdentifier, SpecimenOrObservationType recordBasis, Taxon associatedTaxon,\r
- MatchMode matchmode, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {\r
- Criteria criteria = createFindOccurrenceCriteria(clazz, queryString, significantIdentifier, recordBasis,\r
- associatedTaxon, matchmode, limit, start, orderHints, propertyPaths);\r
-\r
- if(criteria!=null){\r
-\r
- criteria.setProjection(Projections.rowCount());\r
-\r
- return ((Number)criteria.uniqueResult()).intValue();\r
- }\r
- return 0;\r
- }\r
-\r
- @Override\r
- public List<UuidAndTitleCache<DerivedUnit>> getDerivedUnitUuidAndTitleCache() {\r
- List<UuidAndTitleCache<DerivedUnit>> list = new ArrayList<UuidAndTitleCache<DerivedUnit>>();\r
- Session session = getSession();\r
-\r
- Query query = session.createQuery("select uuid, id, titleCache from " + type.getSimpleName() + " where NOT dtype = " + FieldUnit.class.getSimpleName());\r
-\r
- List<Object[]> result = query.list();\r
-\r
- for(Object[] object : result){\r
- list.add(new UuidAndTitleCache<DerivedUnit>(DerivedUnit.class, (UUID) object[0], (Integer)object[1], (String) object[2]));\r
- }\r
-\r
- return list;\r
- }\r
-\r
- @Override\r
- public List<UuidAndTitleCache<FieldUnit>> getFieldUnitUuidAndTitleCache() {\r
- List<UuidAndTitleCache<FieldUnit>> list = new ArrayList<UuidAndTitleCache<FieldUnit>>();\r
- Session session = getSession();\r
-\r
- Query query = session.createQuery("select uuid, id, titleCache from " + type.getSimpleName() + " where dtype = " + FieldUnit.class.getSimpleName());\r
-\r
- List<Object[]> result = query.list();\r
-\r
- for(Object[] object : result){\r
- list.add(new UuidAndTitleCache<FieldUnit>(FieldUnit.class, (UUID) object[0], (Integer)object[1], (String) object[2]));\r
- }\r
-\r
- return list;\r
- }\r
-\r
- @Override\r
- public <T extends SpecimenOrObservationBase> List<T> listByAssociatedTaxon(Class<T> type,\r
- Taxon associatedTaxon, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {\r
-\r
- Set<SpecimenOrObservationBase> setOfAll = new HashSet<SpecimenOrObservationBase>();\r
-\r
- // A Taxon may be referenced by the DeterminationEvent of the SpecimenOrObservationBase\r
- List<SpecimenOrObservationBase> byDetermination = list(type, associatedTaxon, null, 0, null, null);\r
- setOfAll.addAll(byDetermination);\r
-\r
- // The IndividualsAssociation elements in a TaxonDescription contain DerivedUnits\r
- List<IndividualsAssociation> byIndividualsAssociation = descriptionDao.getDescriptionElementForTaxon(\r
- associatedTaxon.getUuid(), null, IndividualsAssociation.class, null, 0, null);\r
- for(IndividualsAssociation individualsAssociation : byIndividualsAssociation){\r
- setOfAll.add(individualsAssociation.getAssociatedSpecimenOrObservation());\r
- }\r
-\r
- // SpecimenTypeDesignations may be associated with the TaxonName.\r
- List<SpecimenTypeDesignation> bySpecimenTypeDesignation = taxonNameDao.getTypeDesignations(associatedTaxon.getName(),\r
- SpecimenTypeDesignation.class, null, null, 0, null);\r
- for (SpecimenTypeDesignation specimenTypeDesignation : bySpecimenTypeDesignation) {\r
- setOfAll.add(specimenTypeDesignation.getTypeSpecimen());\r
- }\r
-\r
- // SpecimenTypeDesignations may be associated with any HomotypicalGroup related to the specific Taxon.\r
- for(HomotypicalGroup homotypicalGroup : associatedTaxon.getHomotypicSynonymyGroups()) {\r
- List<SpecimenTypeDesignation> byHomotypicalGroup = homotypicalGroupDao.getTypeDesignations(homotypicalGroup, SpecimenTypeDesignation.class, null, null, 0, null);\r
- for (SpecimenTypeDesignation specimenTypeDesignation : byHomotypicalGroup) {\r
- setOfAll.add(specimenTypeDesignation.getTypeSpecimen());\r
- }\r
- }\r
-\r
- if(setOfAll.size() == 0){\r
- // no need querying the data base\r
- return new ArrayList<T>();\r
- }\r
-\r
- String queryString =\r
- "select sob " +\r
- " from SpecimenOrObservationBase sob" +\r
- " where sob in (:setOfAll)";\r
-\r
- if(type != null){\r
- queryString += " and sob.class = :type";\r
- }\r
-\r
- if(orderHints != null && orderHints.size() > 0){\r
- queryString += " order by ";\r
- String orderStr = "";\r
- for(OrderHint orderHint : orderHints){\r
- if(orderStr.length() > 0){\r
- orderStr += ", ";\r
- }\r
- queryString += "sob." + orderHint.getPropertyName() + " " + orderHint.getSortOrder().toHql();\r
- }\r
- queryString += orderStr;\r
- }\r
-\r
- Query query = getSession().createQuery(queryString);\r
- query.setParameterList("setOfAll", setOfAll);\r
-\r
- if(type != null){\r
- query.setParameter("type", type.getSimpleName());\r
- }\r
-\r
- if(limit != null) {\r
- if(start != null) {\r
- query.setFirstResult(start);\r
- } else {\r
- query.setFirstResult(0);\r
- }\r
- query.setMaxResults(limit);\r
- }\r
-\r
-\r
- List<T> results = query.list();\r
- defaultBeanInitializer.initializeAll(results, propertyPaths);\r
- return results;\r
- }\r
-\r
- @Override\r
- public Collection<SpecimenTypeDesignation> listBySpecimenOrObservationType(SpecimenOrObservationType type, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {\r
- String queryString = "FROM SpecimenOrObservationBase specimens WHERE specimens.recordBasis = :type";\r
-\r
- if(orderHints != null && orderHints.size() > 0){\r
- queryString += " order by ";\r
- String orderStr = "";\r
- for(OrderHint orderHint : orderHints){\r
- if(orderStr.length() > 0){\r
- orderStr += ", ";\r
- }\r
- queryString += "specimens." + orderHint.getPropertyName() + " " + orderHint.getSortOrder().toHql();\r
- }\r
- queryString += orderStr;\r
- }\r
-\r
- Query query = getSession().createQuery(queryString);\r
- query.setParameter("type", type);\r
-\r
- if(limit != null) {\r
- if(start != null) {\r
- query.setFirstResult(start);\r
- } else {\r
- query.setFirstResult(0);\r
- }\r
- query.setMaxResults(limit);\r
- }\r
-\r
- List results = query.list();\r
- defaultBeanInitializer.initializeAll(results, propertyPaths);\r
- return results;\r
- }\r
-\r
- @Override\r
- public Collection<SpecimenTypeDesignation> listTypeDesignations(SpecimenOrObservationBase<?> specimen, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {\r
- String queryString = "FROM SpecimenTypeDesignation designations WHERE designations.typeSpecimen = :specimen";\r
-\r
- if(orderHints != null && orderHints.size() > 0){\r
- queryString += " order by ";\r
- String orderStr = "";\r
- for(OrderHint orderHint : orderHints){\r
- if(orderStr.length() > 0){\r
- orderStr += ", ";\r
- }\r
- queryString += "designations." + orderHint.getPropertyName() + " " + orderHint.getSortOrder().toHql();\r
- }\r
- queryString += orderStr;\r
- }\r
-\r
- Query query = getSession().createQuery(queryString);\r
- query.setParameter("specimen", specimen);\r
-\r
- if(limit != null) {\r
- if(start != null) {\r
- query.setFirstResult(start);\r
- } else {\r
- query.setFirstResult(0);\r
- }\r
- query.setMaxResults(limit);\r
- }\r
-\r
- List results = query.list();\r
- defaultBeanInitializer.initializeAll(results, propertyPaths);\r
- return results;\r
- }\r
-\r
- @Override\r
- public Collection<IndividualsAssociation> listIndividualsAssociations(SpecimenOrObservationBase<?> specimen, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {\r
- //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\r
- String queryString = "FROM IndividualsAssociation associations WHERE associations.associatedSpecimenOrObservation = :specimen";\r
-\r
- if(orderHints != null && orderHints.size() > 0){\r
- queryString += " order by ";\r
- String orderStr = "";\r
- for(OrderHint orderHint : orderHints){\r
- if(orderStr.length() > 0){\r
- orderStr += ", ";\r
- }\r
- queryString += "associations." + orderHint.getPropertyName() + " " + orderHint.getSortOrder().toHql();\r
- }\r
- queryString += orderStr;\r
- }\r
-\r
- Query query = getSession().createQuery(queryString);\r
- query.setParameter("specimen", specimen);\r
-\r
- if(limit != null) {\r
- if(start != null) {\r
- query.setFirstResult(start);\r
- } else {\r
- query.setFirstResult(0);\r
- }\r
- query.setMaxResults(limit);\r
- }\r
-\r
- List results = query.list();\r
- defaultBeanInitializer.initializeAll(results, propertyPaths);\r
- return results;\r
- }\r
-\r
- @Override\r
- public Collection<DescriptionBase<?>> listDescriptionsWithDescriptionSpecimen(SpecimenOrObservationBase<?> specimen, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {\r
- //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\r
- String queryString = "FROM DescriptionBase descriptions WHERE descriptions.describedSpecimenOrObservation = :specimen";\r
-\r
- if(orderHints != null && orderHints.size() > 0){\r
- queryString += " order by ";\r
- String orderStr = "";\r
- for(OrderHint orderHint : orderHints){\r
- if(orderStr.length() > 0){\r
- orderStr += ", ";\r
- }\r
- queryString += "descriptions." + orderHint.getPropertyName() + " " + orderHint.getSortOrder().toHql();\r
- }\r
- queryString += orderStr;\r
- }\r
-\r
- Query query = getSession().createQuery(queryString);\r
- query.setParameter("specimen", specimen);\r
-\r
- if(limit != null) {\r
- if(start != null) {\r
- query.setFirstResult(start);\r
- } else {\r
- query.setFirstResult(0);\r
- }\r
- query.setMaxResults(limit);\r
- }\r
-\r
- List results = query.list();\r
- defaultBeanInitializer.initializeAll(results, propertyPaths);\r
- return results;\r
- }\r
-\r
+/**
+* Copyright (C) 2008 EDIT
+* European Distributed Institute of Taxonomy
+* http://www.e-taxonomy.eu
+*/
+
+package eu.etaxonomy.cdm.persistence.dao.hibernate.occurrence;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.UUID;
+
+import org.apache.log4j.Logger;
+import org.hibernate.Criteria;
+import org.hibernate.Hibernate;
+import org.hibernate.Query;
+import org.hibernate.Session;
+import org.hibernate.criterion.Projections;
+import org.hibernate.criterion.Restrictions;
+import org.hibernate.envers.query.AuditEntity;
+import org.hibernate.envers.query.AuditQuery;
+import org.hibernate.search.FullTextSession;
+import org.hibernate.search.Search;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Repository;
+
+import eu.etaxonomy.cdm.model.description.DescriptionBase;
+import eu.etaxonomy.cdm.model.description.IndividualsAssociation;
+import eu.etaxonomy.cdm.model.media.Media;
+import eu.etaxonomy.cdm.model.molecular.DnaSample;
+import eu.etaxonomy.cdm.model.name.HomotypicalGroup;
+import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignation;
+import eu.etaxonomy.cdm.model.occurrence.DerivationEvent;
+import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
+import eu.etaxonomy.cdm.model.occurrence.DeterminationEvent;
+import eu.etaxonomy.cdm.model.occurrence.FieldUnit;
+import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
+import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationType;
+import eu.etaxonomy.cdm.model.taxon.Taxon;
+import eu.etaxonomy.cdm.model.taxon.TaxonBase;
+import eu.etaxonomy.cdm.model.view.AuditEvent;
+import eu.etaxonomy.cdm.persistence.dao.description.IDescriptionDao;
+import eu.etaxonomy.cdm.persistence.dao.hibernate.common.IdentifiableDaoBase;
+import eu.etaxonomy.cdm.persistence.dao.hibernate.taxon.TaxonDaoHibernateImpl;
+import eu.etaxonomy.cdm.persistence.dao.name.IHomotypicalGroupDao;
+import eu.etaxonomy.cdm.persistence.dao.name.ITaxonNameDao;
+import eu.etaxonomy.cdm.persistence.dao.occurrence.IOccurrenceDao;
+import eu.etaxonomy.cdm.persistence.dto.UuidAndTitleCache;
+import eu.etaxonomy.cdm.persistence.query.MatchMode;
+import eu.etaxonomy.cdm.persistence.query.OrderHint;
+
+/**
+ * @author a.babadshanjan
+ * @created 01.09.2008
+ */
+@Repository
+public class OccurrenceDaoHibernateImpl extends IdentifiableDaoBase<SpecimenOrObservationBase> implements IOccurrenceDao {
+
+ @SuppressWarnings("unused")
+ private static final Logger logger = Logger.getLogger(TaxonDaoHibernateImpl.class);
+
+ @Autowired
+ private IDescriptionDao descriptionDao;
+
+ @Autowired
+ private ITaxonNameDao taxonNameDao;
+
+ @Autowired
+ private IHomotypicalGroupDao homotypicalGroupDao;
+
+ public OccurrenceDaoHibernateImpl() {
+ super(SpecimenOrObservationBase.class);
+ indexedClasses = new Class[7];
+ indexedClasses[0] = FieldUnit.class;
+ indexedClasses[1] = DerivedUnit.class;
+ indexedClasses[5] = DnaSample.class;
+ }
+
+ @Override
+ public int countDerivationEvents(SpecimenOrObservationBase occurence) {
+ checkNotInPriorView("OccurrenceDaoHibernateImpl.countDerivationEvents(SpecimenOrObservationBase occurence)");
+ Query query = getSession().createQuery("select count(distinct derivationEvent) from DerivationEvent derivationEvent join derivationEvent.originals occurence where occurence = :occurence");
+ query.setParameter("occurence", occurence);
+
+ return ((Long)query.uniqueResult()).intValue();
+ }
+
+ @Override
+ public int countDeterminations(SpecimenOrObservationBase occurrence, TaxonBase taxonBase) {
+ AuditEvent auditEvent = getAuditEventFromContext();
+ if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
+ Criteria criteria = getSession().createCriteria(DeterminationEvent.class);
+ if(occurrence != null) {
+ criteria.add(Restrictions.eq("identifiedUnit",occurrence));
+ }
+
+ if(taxonBase != null) {
+ criteria.add(Restrictions.eq("taxon",taxonBase));
+ }
+
+ criteria.setProjection(Projections.rowCount());
+ return ((Number)criteria.uniqueResult()).intValue();
+ } else {
+ AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(DeterminationEvent.class,auditEvent.getRevisionNumber());
+
+ if(occurrence != null) {
+ query.add(AuditEntity.relatedId("identifiedUnit").eq(occurrence.getId()));
+ }
+
+ if(taxonBase != null) {
+ query.add(AuditEntity.relatedId("taxon").eq(taxonBase.getId()));
+ }
+ query.addProjection(AuditEntity.id().count("id"));
+
+ return ((Long)query.getSingleResult()).intValue();
+ }
+ }
+
+ @Override
+ public int countMedia(SpecimenOrObservationBase occurence) {
+ checkNotInPriorView("OccurrenceDaoHibernateImpl.countMedia(SpecimenOrObservationBase occurence)");
+ Query query = getSession().createQuery("select count(media) from SpecimenOrObservationBase occurence join occurence.media media where occurence = :occurence");
+ query.setParameter("occurence", occurence);
+
+ return ((Long)query.uniqueResult()).intValue();
+ }
+
+ @Override
+ public List<DerivationEvent> getDerivationEvents(SpecimenOrObservationBase occurence, Integer pageSize,Integer pageNumber, List<String> propertyPaths) {
+ checkNotInPriorView("OccurrenceDaoHibernateImpl.getDerivationEvents(SpecimenOrObservationBase occurence, Integer pageSize,Integer pageNumber)");
+ Query query = getSession().createQuery("select distinct derivationEvent from DerivationEvent derivationEvent join derivationEvent.originals occurence where occurence = :occurence");
+ query.setParameter("occurence", occurence);
+
+ if(pageSize != null) {
+ query.setMaxResults(pageSize);
+ if(pageNumber != null) {
+ query.setFirstResult(pageNumber * pageSize);
+ } else {
+ query.setFirstResult(0);
+ }
+ }
+
+ List<DerivationEvent> result = query.list();
+ defaultBeanInitializer.initializeAll(result, propertyPaths);
+ return result;
+ }
+
+ @Override
+ public List<DeterminationEvent> getDeterminations(SpecimenOrObservationBase occurrence, TaxonBase taxonBase, Integer pageSize, Integer pageNumber, List<String> propertyPaths) {
+ AuditEvent auditEvent = getAuditEventFromContext();
+ if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
+ Criteria criteria = getSession().createCriteria(DeterminationEvent.class);
+ if(occurrence != null) {
+ criteria.add(Restrictions.eq("identifiedUnit",occurrence));
+ }
+
+ if(taxonBase != null) {
+ criteria.add(Restrictions.eq("taxon",taxonBase));
+ }
+
+ if(pageSize != null) {
+ criteria.setMaxResults(pageSize);
+ if(pageNumber != null) {
+ criteria.setFirstResult(pageNumber * pageSize);
+ } else {
+ criteria.setFirstResult(0);
+ }
+ }
+ List<DeterminationEvent> result = criteria.list();
+ defaultBeanInitializer.initializeAll(result, propertyPaths);
+ return result;
+ } else {
+ AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(DeterminationEvent.class,auditEvent.getRevisionNumber());
+ if(occurrence != null) {
+ query.add(AuditEntity.relatedId("identifiedUnit").eq(occurrence.getId()));
+ }
+
+ if(taxonBase != null) {
+ query.add(AuditEntity.relatedId("taxon").eq(taxonBase.getId()));
+ }
+ if(pageSize != null) {
+ query.setMaxResults(pageSize);
+ if(pageNumber != null) {
+ query.setFirstResult(pageNumber * pageSize);
+ } else {
+ query.setFirstResult(0);
+ }
+ }
+ List<DeterminationEvent> result = query.getResultList();
+ defaultBeanInitializer.initializeAll(result, propertyPaths);
+ return result;
+ }
+ }
+
+ @Override
+ public List<Media> getMedia(SpecimenOrObservationBase occurence, Integer pageSize, Integer pageNumber, List<String> propertyPaths) {
+ checkNotInPriorView("OccurrenceDaoHibernateImpl.getMedia(SpecimenOrObservationBase occurence, Integer pageSize, Integer pageNumber, List<String> propertyPaths)");
+ Query query = getSession().createQuery("select media from SpecimenOrObservationBase occurence join occurence.media media where occurence = :occurence");
+ query.setParameter("occurence", occurence);
+
+ if(pageSize != null) {
+ query.setMaxResults(pageSize);
+ if(pageNumber != null) {
+ query.setFirstResult(pageNumber * pageSize);
+ } else {
+ query.setFirstResult(0);
+ }
+ }
+
+ List<Media> results = query.list();
+ defaultBeanInitializer.initializeAll(results, propertyPaths);
+ return results;
+ }
+
+ @Override
+ public void rebuildIndex() {
+ FullTextSession fullTextSession = Search.getFullTextSession(getSession());
+
+ for(SpecimenOrObservationBase occurrence : list(null,null)) { // re-index all taxon base
+
+ for(DeterminationEvent determination : (Set<DeterminationEvent>)occurrence.getDeterminations()) {
+ Hibernate.initialize(determination.getActor());
+ Hibernate.initialize(determination.getTaxon());
+ }
+ Hibernate.initialize(occurrence.getDefinition());
+ if(occurrence instanceof DerivedUnit) {
+ DerivedUnit derivedUnit = (DerivedUnit) occurrence;
+ Hibernate.initialize(derivedUnit.getCollection());
+ if(derivedUnit.getCollection() != null) {
+ Hibernate.initialize(derivedUnit.getCollection().getSuperCollection());
+ Hibernate.initialize(derivedUnit.getCollection().getInstitute());
+ }
+ Hibernate.initialize(derivedUnit.getStoredUnder());
+ SpecimenOrObservationBase original = derivedUnit.getOriginalUnit();
+ if(original != null && original.isInstanceOf(FieldUnit.class)) {
+ FieldUnit fieldUnit = original.deproxy(original, FieldUnit.class);
+ Hibernate.initialize(fieldUnit.getGatheringEvent());
+ if(fieldUnit.getGatheringEvent() != null) {
+ Hibernate.initialize(fieldUnit.getGatheringEvent().getActor());
+ }
+ }
+ }
+ fullTextSession.index(occurrence);
+ }
+ fullTextSession.flushToIndexes();
+ }
+
+ @Override
+ public int count(Class<? extends SpecimenOrObservationBase> clazz, TaxonBase determinedAs) {
+
+ Criteria criteria = null;
+ if(clazz == null) {
+ criteria = getSession().createCriteria(type);
+ } else {
+ criteria = getSession().createCriteria(clazz);
+ }
+
+ criteria.createCriteria("determinations").add(Restrictions.eq("taxon", determinedAs));
+ criteria.setProjection(Projections.projectionList().add(Projections.rowCount()));
+ return ((Number)criteria.uniqueResult()).intValue();
+ }
+
+ @Override
+ public List<SpecimenOrObservationBase> list(Class<? extends SpecimenOrObservationBase> clazz, TaxonBase determinedAs, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {
+ Criteria criteria = null;
+ if(clazz == null) {
+ criteria = getSession().createCriteria(type);
+ } else {
+ criteria = getSession().createCriteria(clazz);
+ }
+
+ criteria.createCriteria("determinations").add(Restrictions.eq("taxon", determinedAs));
+
+ if(limit != null) {
+ if(start != null) {
+ criteria.setFirstResult(start);
+ } else {
+ criteria.setFirstResult(0);
+ }
+ criteria.setMaxResults(limit);
+ }
+
+ addOrder(criteria,orderHints);
+
+ List<SpecimenOrObservationBase> results = criteria.list();
+ defaultBeanInitializer.initializeAll(results, propertyPaths);
+ return results;
+ }
+
+ @Override
+ public <T extends SpecimenOrObservationBase> List<T> findOccurrences(Class<T> clazz, String queryString,
+ String significantIdentifier, SpecimenOrObservationType recordBasis, Taxon associatedTaxon,
+ MatchMode matchmode, Integer limit,
+ Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {
+
+ Criteria criteria = createFindOccurrenceCriteria(clazz, queryString, significantIdentifier, recordBasis,
+ associatedTaxon, matchmode, limit, start, orderHints, propertyPaths);
+
+ if(criteria!=null){
+
+ if(limit != null) {
+ if(start != null) {
+ criteria.setFirstResult(start);
+ } else {
+ criteria.setFirstResult(0);
+ }
+ criteria.setMaxResults(limit);
+ }
+
+ if(orderHints!=null){
+ addOrder(criteria,orderHints);
+ }
+
+ List<T> results = criteria.list();
+ defaultBeanInitializer.initializeAll(results, propertyPaths);
+ return results;
+ }
+ return Collections.EMPTY_LIST;
+ }
+
+ /**
+ * @param clazz
+ * @param queryString
+ * @param recordBasis
+ * @param associatedTaxon
+ * @param matchmode
+ * @param limit
+ * @param start
+ * @param orderHints
+ * @param propertyPaths
+ * @return
+ */
+ private <T extends SpecimenOrObservationBase> Criteria createFindOccurrenceCriteria(Class<T> clazz, String queryString,
+ String significantIdentifier, SpecimenOrObservationType recordBasis, Taxon associatedTaxon, MatchMode matchmode, Integer limit,
+ Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {
+ Criteria criteria = null;
+
+ if(clazz == null) {
+ criteria = getSession().createCriteria(type);
+ } else {
+ criteria = getSession().createCriteria(clazz);
+ }
+
+ //queryString
+ if (queryString != null) {
+ if(matchmode == null) {
+ matchmode = MatchMode.ANYWHERE;
+ criteria.add(Restrictions.ilike("titleCache", matchmode.queryStringFrom(queryString)));
+ } else if(matchmode == MatchMode.BEGINNING) {
+ criteria.add(Restrictions.ilike("titleCache", matchmode.queryStringFrom(queryString), org.hibernate.criterion.MatchMode.START));
+ } else if(matchmode == MatchMode.END) {
+ criteria.add(Restrictions.ilike("titleCache", matchmode.queryStringFrom(queryString), org.hibernate.criterion.MatchMode.END));
+ } else if(matchmode == MatchMode.EXACT) {
+ criteria.add(Restrictions.ilike("titleCache", matchmode.queryStringFrom(queryString), org.hibernate.criterion.MatchMode.EXACT));
+ } else {
+ criteria.add(Restrictions.ilike("titleCache", matchmode.queryStringFrom(queryString), org.hibernate.criterion.MatchMode.ANYWHERE));
+ }
+ }
+
+ //significant identifier
+ if (significantIdentifier != null) {
+ criteria.add(Restrictions.or(Restrictions.ilike("accessionNumber", significantIdentifier),
+ Restrictions.ilike("catalogNumber", significantIdentifier), Restrictions.ilike("barcode", significantIdentifier)));
+ }
+
+ //recordBasis/SpecimenOrObservationType
+ if(recordBasis!=null){
+ Set<SpecimenOrObservationType> typeAndSubtypes = recordBasis.getGeneralizationOf(true);
+ typeAndSubtypes.add(recordBasis);
+ criteria.add(Restrictions.in("recordBasis", typeAndSubtypes));
+ }
+
+ //taxon associations
+ if(associatedTaxon!=null){
+ List<UUID> associatedTaxonUuids = new ArrayList<UUID>();
+ List<? extends SpecimenOrObservationBase> associatedTaxaList = listByAssociatedTaxon(clazz!=null?clazz:type, associatedTaxon, limit, start, orderHints, propertyPaths);
+ if(associatedTaxaList!=null){
+ for (SpecimenOrObservationBase specimenOrObservationBase : associatedTaxaList) {
+ associatedTaxonUuids.add(specimenOrObservationBase.getUuid());
+ }
+ }
+ if(!associatedTaxonUuids.isEmpty()){
+ criteria.add(Restrictions.in("uuid", associatedTaxonUuids));
+ }
+ else{
+ return null;
+ }
+ }
+
+ return criteria;
+ }
+
+
+ @Override
+ public <T extends SpecimenOrObservationBase> int countOccurrences(Class<T> clazz, String queryString,
+ String significantIdentifier, SpecimenOrObservationType recordBasis, Taxon associatedTaxon,
+ MatchMode matchmode, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {
+ Criteria criteria = createFindOccurrenceCriteria(clazz, queryString, significantIdentifier, recordBasis,
+ associatedTaxon, matchmode, limit, start, orderHints, propertyPaths);
+
+ if(criteria!=null){
+
+ criteria.setProjection(Projections.rowCount());
+
+ return ((Number)criteria.uniqueResult()).intValue();
+ }
+ return 0;
+ }
+
+ @Override
+ public List<UuidAndTitleCache<DerivedUnit>> getDerivedUnitUuidAndTitleCache() {
+ List<UuidAndTitleCache<DerivedUnit>> list = new ArrayList<UuidAndTitleCache<DerivedUnit>>();
+ Session session = getSession();
+
+ Query query = session.createQuery("select uuid, id, titleCache from " + type.getSimpleName() + " where NOT dtype = " + FieldUnit.class.getSimpleName());
+
+ List<Object[]> result = query.list();
+
+ for(Object[] object : result){
+ list.add(new UuidAndTitleCache<DerivedUnit>(DerivedUnit.class, (UUID) object[0], (Integer)object[1], (String) object[2]));
+ }
+
+ return list;
+ }
+
+ @Override
+ public List<UuidAndTitleCache<FieldUnit>> getFieldUnitUuidAndTitleCache() {
+ List<UuidAndTitleCache<FieldUnit>> list = new ArrayList<UuidAndTitleCache<FieldUnit>>();
+ Session session = getSession();
+
+ Query query = session.createQuery("select uuid, id, titleCache from " + type.getSimpleName() + " where dtype = " + FieldUnit.class.getSimpleName());
+
+ List<Object[]> result = query.list();
+
+ for(Object[] object : result){
+ list.add(new UuidAndTitleCache<FieldUnit>(FieldUnit.class, (UUID) object[0], (Integer)object[1], (String) object[2]));
+ }
+
+ return list;
+ }
+
+ @Override
+ public <T extends SpecimenOrObservationBase> List<T> listByAssociatedTaxon(Class<T> type,
+ Taxon associatedTaxon, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {
+
+ Set<SpecimenOrObservationBase> setOfAll = new HashSet<SpecimenOrObservationBase>();
+
+ // A Taxon may be referenced by the DeterminationEvent of the SpecimenOrObservationBase
+ List<SpecimenOrObservationBase> byDetermination = list(type, associatedTaxon, null, 0, null, null);
+ setOfAll.addAll(byDetermination);
+
+ // The IndividualsAssociation elements in a TaxonDescription contain DerivedUnits
+ List<IndividualsAssociation> byIndividualsAssociation = descriptionDao.getDescriptionElementForTaxon(
+ associatedTaxon.getUuid(), null, IndividualsAssociation.class, null, 0, null);
+ for(IndividualsAssociation individualsAssociation : byIndividualsAssociation){
+ setOfAll.add(individualsAssociation.getAssociatedSpecimenOrObservation());
+ }
+
+ // SpecimenTypeDesignations may be associated with the TaxonName.
+ List<SpecimenTypeDesignation> bySpecimenTypeDesignation = taxonNameDao.getTypeDesignations(associatedTaxon.getName(),
+ SpecimenTypeDesignation.class, null, null, 0, null);
+ for (SpecimenTypeDesignation specimenTypeDesignation : bySpecimenTypeDesignation) {
+ setOfAll.add(specimenTypeDesignation.getTypeSpecimen());
+ }
+
+ // SpecimenTypeDesignations may be associated with any HomotypicalGroup related to the specific Taxon.
+ for(HomotypicalGroup homotypicalGroup : associatedTaxon.getHomotypicSynonymyGroups()) {
+ List<SpecimenTypeDesignation> byHomotypicalGroup = homotypicalGroupDao.getTypeDesignations(homotypicalGroup, SpecimenTypeDesignation.class, null, null, 0, null);
+ for (SpecimenTypeDesignation specimenTypeDesignation : byHomotypicalGroup) {
+ setOfAll.add(specimenTypeDesignation.getTypeSpecimen());
+ }
+ }
+
+ if(setOfAll.size() == 0){
+ // no need querying the data base
+ return new ArrayList<T>();
+ }
+
+ String queryString =
+ "select sob " +
+ " from SpecimenOrObservationBase sob" +
+ " where sob in (:setOfAll)";
+
+ if(type != null){
+ queryString += " and sob.class = :type";
+ }
+
+ if(orderHints != null && orderHints.size() > 0){
+ queryString += " order by ";
+ String orderStr = "";
+ for(OrderHint orderHint : orderHints){
+ if(orderStr.length() > 0){
+ orderStr += ", ";
+ }
+ queryString += "sob." + orderHint.getPropertyName() + " " + orderHint.getSortOrder().toHql();
+ }
+ queryString += orderStr;
+ }
+
+ Query query = getSession().createQuery(queryString);
+ query.setParameterList("setOfAll", setOfAll);
+
+ if(type != null){
+ query.setParameter("type", type.getSimpleName());
+ }
+
+ if(limit != null) {
+ if(start != null) {
+ query.setFirstResult(start);
+ } else {
+ query.setFirstResult(0);
+ }
+ query.setMaxResults(limit);
+ }
+
+
+ List<T> results = query.list();
+ defaultBeanInitializer.initializeAll(results, propertyPaths);
+ return results;
+ }
+
+ @Override
+ public Collection<SpecimenOrObservationBase> listBySpecimenOrObservationType(SpecimenOrObservationType type, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {
+ String queryString = "FROM SpecimenOrObservationBase specimens WHERE specimens.recordBasis = :type";
+
+ if(orderHints != null && orderHints.size() > 0){
+ queryString += " order by ";
+ String orderStr = "";
+ for(OrderHint orderHint : orderHints){
+ if(orderStr.length() > 0){
+ orderStr += ", ";
+ }
+ queryString += "specimens." + orderHint.getPropertyName() + " " + orderHint.getSortOrder().toHql();
+ }
+ queryString += orderStr;
+ }
+
+ Query query = getSession().createQuery(queryString);
+ query.setParameter("type", type);
+
+ if(limit != null) {
+ if(start != null) {
+ query.setFirstResult(start);
+ } else {
+ query.setFirstResult(0);
+ }
+ query.setMaxResults(limit);
+ }
+
+ List results = query.list();
+ defaultBeanInitializer.initializeAll(results, propertyPaths);
+ return results;
+ }
+
+ @Override
+ public Collection<SpecimenTypeDesignation> listTypeDesignations(SpecimenOrObservationBase<?> specimen, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {
+ String queryString = "FROM SpecimenTypeDesignation designations WHERE designations.typeSpecimen = :specimen";
+
+ if(orderHints != null && orderHints.size() > 0){
+ queryString += " order by ";
+ String orderStr = "";
+ for(OrderHint orderHint : orderHints){
+ if(orderStr.length() > 0){
+ orderStr += ", ";
+ }
+ queryString += "designations." + orderHint.getPropertyName() + " " + orderHint.getSortOrder().toHql();
+ }
+ queryString += orderStr;
+ }
+
+ Query query = getSession().createQuery(queryString);
+ query.setParameter("specimen", specimen);
+
+ if(limit != null) {
+ if(start != null) {
+ query.setFirstResult(start);
+ } else {
+ query.setFirstResult(0);
+ }
+ query.setMaxResults(limit);
+ }
+
+ List results = query.list();
+ defaultBeanInitializer.initializeAll(results, propertyPaths);
+ return results;
+ }
+
+ @Override
+ public Collection<IndividualsAssociation> listIndividualsAssociations(SpecimenOrObservationBase<?> specimen, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {
+ //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
+ String queryString = "FROM IndividualsAssociation associations WHERE associations.associatedSpecimenOrObservation = :specimen";
+
+ if(orderHints != null && orderHints.size() > 0){
+ queryString += " order by ";
+ String orderStr = "";
+ for(OrderHint orderHint : orderHints){
+ if(orderStr.length() > 0){
+ orderStr += ", ";
+ }
+ queryString += "associations." + orderHint.getPropertyName() + " " + orderHint.getSortOrder().toHql();
+ }
+ queryString += orderStr;
+ }
+
+ Query query = getSession().createQuery(queryString);
+ query.setParameter("specimen", specimen);
+
+ if(limit != null) {
+ if(start != null) {
+ query.setFirstResult(start);
+ } else {
+ query.setFirstResult(0);
+ }
+ query.setMaxResults(limit);
+ }
+
+ List results = query.list();
+ defaultBeanInitializer.initializeAll(results, propertyPaths);
+ return results;
+ }
+
+ @Override
+ public Collection<DescriptionBase<?>> listDescriptionsWithDescriptionSpecimen(SpecimenOrObservationBase<?> specimen, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {
+ //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
+ String queryString = "FROM DescriptionBase descriptions WHERE descriptions.describedSpecimenOrObservation = :specimen";
+
+ if(orderHints != null && orderHints.size() > 0){
+ queryString += " order by ";
+ String orderStr = "";
+ for(OrderHint orderHint : orderHints){
+ if(orderStr.length() > 0){
+ orderStr += ", ";
+ }
+ queryString += "descriptions." + orderHint.getPropertyName() + " " + orderHint.getSortOrder().toHql();
+ }
+ queryString += orderStr;
+ }
+
+ Query query = getSession().createQuery(queryString);
+ query.setParameter("specimen", specimen);
+
+ if(limit != null) {
+ if(start != null) {
+ query.setFirstResult(start);
+ } else {
+ query.setFirstResult(0);
+ }
+ query.setMaxResults(limit);
+ }
+
+ List results = query.list();
+ defaultBeanInitializer.initializeAll(results, propertyPaths);
+ return results;
+ }
+
}
\ No newline at end of file
-/**\r
-* Copyright (C) 2008 EDIT\r
-* European Distributed Institute of Taxonomy\r
-* http://www.e-taxonomy.eu\r
-*/\r
-\r
-package eu.etaxonomy.cdm.persistence.dao.occurrence;\r
-\r
-import java.util.Collection;\r
-import java.util.List;\r
-import java.util.UUID;\r
-\r
-import org.springframework.dao.DataAccessException;\r
-\r
-import eu.etaxonomy.cdm.model.description.DescriptionBase;\r
-import eu.etaxonomy.cdm.model.description.IndividualsAssociation;\r
-import eu.etaxonomy.cdm.model.description.TaxonDescription;\r
-import eu.etaxonomy.cdm.model.media.Media;\r
-import eu.etaxonomy.cdm.model.name.HomotypicalGroup;\r
-import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignation;\r
-import eu.etaxonomy.cdm.model.occurrence.DerivationEvent;\r
-import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;\r
-import eu.etaxonomy.cdm.model.occurrence.DeterminationEvent;\r
-import eu.etaxonomy.cdm.model.occurrence.FieldUnit;\r
-import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;\r
-import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationType;\r
-import eu.etaxonomy.cdm.model.taxon.Taxon;\r
-import eu.etaxonomy.cdm.model.taxon.TaxonBase;\r
-import eu.etaxonomy.cdm.persistence.dao.common.IIdentifiableDao;\r
-import eu.etaxonomy.cdm.persistence.dao.initializer.IBeanInitializer;\r
-import eu.etaxonomy.cdm.persistence.dto.UuidAndTitleCache;\r
-import eu.etaxonomy.cdm.persistence.query.MatchMode;\r
-import eu.etaxonomy.cdm.persistence.query.OrderHint;\r
-\r
-/**\r
- * @author a.babadshanjan\r
- * @created 01.09.2008\r
- */\r
-public interface IOccurrenceDao extends IIdentifiableDao<SpecimenOrObservationBase> {\r
-\r
- /**\r
- * Returns the number of occurences belonging to a certain subclass - which must extend SpecimenOrObservationBase\r
- * @param clazz optionally restrict the counted occurrences to those of a certain subclass of SpecimenOrObservationBase\r
- * @param determinedAs the taxon concept that these specimens are determined to belong to\r
- * @return\r
- */\r
- public int count(Class<? extends SpecimenOrObservationBase> clazz,TaxonBase determinedAs);\r
-\r
- /**\r
- * Returns a sublist of SpecimenOrObservationBase instances stored in the database. A maximum\r
- * of 'limit' objects are returned, starting at object with index 'start'. Only occurrences which\r
- * have been determined to belong to the supplied concept are returned.\r
- *\r
- * @param type\r
- * @param determinedAs the taxon concept that these specimens are determined to belong to\r
- * @param limit\r
- * the maximum number of entities returned (can be null to return\r
- * all entities)\r
- * @param start\r
- * @param orderHints\r
- * Supports path like <code>orderHints.propertyNames</code> which\r
- * include *-to-one properties like createdBy.username or\r
- * authorTeam.persistentTitleCache\r
- * @return\r
- * @throws DataAccessException\r
- */\r
- public List<SpecimenOrObservationBase> list(Class<? extends SpecimenOrObservationBase> type, TaxonBase determinedAs, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths);\r
-\r
- /**\r
- * Queries the database for specimens which match the given criteria\r
- *\r
- * @param clazz\r
- * the class to match\r
- * @param queryString\r
- * the queryString to match\r
- * @param type\r
- * the {@link SpecimenOrObservationType} to match\r
- * @param associatedTaxon\r
- * the taxon these specimens are in any way associated to via\r
- * determination, type designations, individuals associations,\r
- * etc.\r
- * @param matchmode\r
- * determines how the query string should be matched\r
- * @param limit\r
- * the maximum number of entities returned (can be null to return\r
- * all entities)\r
- * @param start\r
- * @param orderHints\r
- * Supports path like <code>orderHints.propertyNames</code> which\r
- * include *-to-one properties like createdBy.username or\r
- * authorTeam.persistentTitleCache\r
- * @param propertyPaths\r
- * @return a list of specimens that match the given parameters\r
- */\r
- public <T extends SpecimenOrObservationBase> List<T> findOccurrences(Class<T> clazz, String queryString,\r
- String significantIdentifier, SpecimenOrObservationType type, Taxon determinedAs, MatchMode matchmode,\r
- Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths);\r
-\r
- /**\r
- * Returns the number of specimens that match the given parameters\r
- * @param clazz the class to match\r
- * @param queryString the queryString to match\r
- * @param type the {@link SpecimenOrObservationType} to match\r
- * @param associatedTaxon the taxon these specimens are in any way associated to via\r
- * determination, type designations, individuals associations, etc.\r
- * @param matchmode determines how the query string should be matched\r
- * @param limit\r
- * the maximum number of entities returned (can be null to return\r
- * all entities)\r
- * @param start\r
- * @param orderHints\r
- * Supports path like <code>orderHints.propertyNames</code> which\r
- * include *-to-one properties like createdBy.username or\r
- * authorTeam.persistentTitleCache\r
- * @return the number of found specimens\r
- */\r
- public <T extends SpecimenOrObservationBase> int countOccurrences(Class<T> clazz, String queryString,\r
- String significantIdentifier, SpecimenOrObservationType recordBasis, Taxon associatedTaxon,\r
- MatchMode matchmode, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths);\r
-\r
- /**\r
- * Returns a count of Media that are associated with a given occurence\r
- *\r
- * @param occurence the occurence associated with these media\r
- * @return a count of media instances\r
- */\r
- public int countMedia(SpecimenOrObservationBase occurence);\r
-\r
- /**\r
- * Returns a List of Media that are associated with a given occurence\r
- *\r
- * @param occurence the occurence associated with these media\r
- * @param pageSize The maximum number of media returned (can be null for all related media)\r
- * @param pageNumber The offset (in pageSize chunks) from the start of the result set (0 - based)\r
- * @param propertyPaths properties to initialize - see {@link IBeanInitializer#initialize(Object, List)}\r
- * @return a List of media instances\r
- */\r
- public List<Media> getMedia(SpecimenOrObservationBase occurence, Integer pageSize, Integer pageNumber, List<String> propertyPaths);\r
-\r
- /**\r
- * Returns a count of determinations that have been made for a given occurence and for a given taxon concept\r
- *\r
- * @param occurence the occurence associated with these determinations (can be null for all occurrences)\r
- * @param taxonbase the taxon concept associated with these determinations (can be null for all taxon concepts)\r
- * @return a count of determination events\r
- */\r
- public int countDeterminations(SpecimenOrObservationBase occurence,TaxonBase taxonbase);\r
-\r
- /**\r
- * Returns a List of determinations that have been made for a given occurence and for a given taxon concept\r
- *\r
- * @param occurence the occurence associated with these determinations (can be null for all occurrences)\r
- * @param taxonbase the taxon concept associated with these determinations (can be null for all taxon concepts)\r
- * @param pageSize The maximum number of determinations returned (can be null for all related determinations)\r
- * @param pageNumber The offset (in pageSize chunks) from the start of the result set (0 - based)\r
- * @param propertyPaths properties to initialize - see {@link IBeanInitializer#initialize(Object, List)}\r
- * @return a List of determination instances\r
- */\r
- public List<DeterminationEvent> getDeterminations(SpecimenOrObservationBase occurence,TaxonBase taxonbase, Integer pageSize, Integer pageNumber, List<String> propertyPaths);\r
-\r
- /**\r
- * Returns a count of derivation events that have involved creating new DerivedUnits from this occurence\r
- *\r
- * @param occurence the occurence that was a source of these derivation events\r
- * @return a count of derivation events\r
- */\r
- public int countDerivationEvents(SpecimenOrObservationBase occurence);\r
-\r
- /**\r
- * Returns a list of derivation events that have involved creating new DerivedUnits from this occurence\r
- *\r
- * @param occurence the occurence that was a source of these derivation events\r
- * @param pageSize The maximum number of derivation events returned (can be null for all related derivation events)\r
- * @param pageNumber The offset (in pageSize chunks) from the start of the result set (0 - based)\r
- * @param propertyPaths properties to initialize - see {@link IBeanInitializer#initialize(Object, List)}\r
- * @return a List of derivation events\r
- */\r
- public List<DerivationEvent> getDerivationEvents(SpecimenOrObservationBase occurence, Integer pageSize, Integer pageNumber, List<String> propertyPaths);\r
-\r
- /**\r
- * Retrieves the {@link UUID} and the string representation (title cache) of all\r
- * {@link FieldUnit}s found in the data base.\r
- * @return a list of {@link UuidAndTitleCache}\r
- */\r
- public List<UuidAndTitleCache<FieldUnit>> getFieldUnitUuidAndTitleCache();\r
-\r
- /**\r
- * Retrieves the {@link UUID} and the string representation (title cache) of all\r
- * {@link DerivedUnit}s found in the data base.\r
- * @return a list of {@link UuidAndTitleCache}\r
- */\r
- public List<UuidAndTitleCache<DerivedUnit>> getDerivedUnitUuidAndTitleCache();\r
-\r
- /**\r
- * Lists all instances of {@link SpecimenOrObservationBase} which are associated with the <code>taxon</code> specified as parameter.\r
- * SpecimenOrObservationBase instances can be associated to taxa in multiple ways, all these possible relations are taken into account:\r
- * <ul>\r
- * <li>The {@link IndividualsAssociation} elements in a {@link TaxonDescription} contain {@link DerivedUnit}s</li>\r
- * <li>{@link SpecimenTypeDesignation}s may be associated with any {@link HomotypicalGroup} related to the specific {@link Taxon}.</li>\r
- * <li>A {@link Taxon} may be referenced by the {@link DeterminationEvent} of the {@link SpecimenOrObservationBase}</li>\r
- * </ul>\r
- *\r
- * @param <T>\r
- * @param type\r
- * @param associatedTaxon\r
- * @param limit\r
- * @param start\r
- * @param orderHints\r
- * @param propertyPaths\r
- * @return\r
- */\r
- public <T extends SpecimenOrObservationBase> List<T> listByAssociatedTaxon(Class<T> type, Taxon associatedTaxon,\r
- Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths);\r
-\r
- /**\r
- * Retrieves all {@link IndividualsAssociation} with the given specimen.<br>\r
- * @param specimen the specimen for which the associations are retrieved\r
- * @param limit\r
- * @param start\r
- * @param orderHints\r
- * @param propertyPaths\r
- * @return collection of all associations\r
- */\r
- public Collection<IndividualsAssociation> listIndividualsAssociations(SpecimenOrObservationBase<?> specimen, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths);\r
-\r
- /**\r
- * Retrieves all {@link SpecimenTypeDesignation}s which have the given specimen as a type specimen.\r
- * @param specimen the type specimen\r
- * @param limit\r
- * @param start\r
- * @param orderHints\r
- * @param propertyPaths\r
- * @return collection of all designations with the given type specimen\r
- */\r
- public Collection<SpecimenTypeDesignation> listTypeDesignations(SpecimenOrObservationBase<?> specimen, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths);\r
-\r
- /**\r
- * Retrieves all {@link DescriptionBase}s that have the given specimen set as described specimen.\r
- * @param specimen the described specimen\r
- * @param limit\r
- * @param start\r
- * @param orderHints\r
- * @param propertyPaths\r
- * @return collection of all descriptions with the given described specimen\r
- */\r
- public Collection<DescriptionBase<?>> listDescriptionsWithDescriptionSpecimen(SpecimenOrObservationBase<?> specimen, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths);\r
-\r
- /**\r
- * Retrieves all {@link SpecimenOrObservationBase}s that have the given {@link SpecimenOrObservationType}.\r
- * @param type\r
- * @param limit\r
- * @param start\r
- * @param orderHints\r
- * @param propertyPaths\r
- * @return collection of specimen with the given type\r
- */\r
- public Collection<SpecimenTypeDesignation> listBySpecimenOrObservationType(SpecimenOrObservationType type, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths);\r
-}\r
+/**
+* Copyright (C) 2008 EDIT
+* European Distributed Institute of Taxonomy
+* http://www.e-taxonomy.eu
+*/
+
+package eu.etaxonomy.cdm.persistence.dao.occurrence;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.UUID;
+
+import org.springframework.dao.DataAccessException;
+
+import eu.etaxonomy.cdm.model.description.DescriptionBase;
+import eu.etaxonomy.cdm.model.description.IndividualsAssociation;
+import eu.etaxonomy.cdm.model.description.TaxonDescription;
+import eu.etaxonomy.cdm.model.media.Media;
+import eu.etaxonomy.cdm.model.name.HomotypicalGroup;
+import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignation;
+import eu.etaxonomy.cdm.model.occurrence.DerivationEvent;
+import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
+import eu.etaxonomy.cdm.model.occurrence.DeterminationEvent;
+import eu.etaxonomy.cdm.model.occurrence.FieldUnit;
+import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
+import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationType;
+import eu.etaxonomy.cdm.model.taxon.Taxon;
+import eu.etaxonomy.cdm.model.taxon.TaxonBase;
+import eu.etaxonomy.cdm.persistence.dao.common.IIdentifiableDao;
+import eu.etaxonomy.cdm.persistence.dao.initializer.IBeanInitializer;
+import eu.etaxonomy.cdm.persistence.dto.UuidAndTitleCache;
+import eu.etaxonomy.cdm.persistence.query.MatchMode;
+import eu.etaxonomy.cdm.persistence.query.OrderHint;
+
+/**
+ * @author a.babadshanjan
+ * @created 01.09.2008
+ */
+public interface IOccurrenceDao extends IIdentifiableDao<SpecimenOrObservationBase> {
+
+ /**
+ * Returns the number of occurences belonging to a certain subclass - which must extend SpecimenOrObservationBase
+ * @param clazz optionally restrict the counted occurrences to those of a certain subclass of SpecimenOrObservationBase
+ * @param determinedAs the taxon concept that these specimens are determined to belong to
+ * @return
+ */
+ public int count(Class<? extends SpecimenOrObservationBase> clazz,TaxonBase determinedAs);
+
+ /**
+ * Returns a sublist of SpecimenOrObservationBase instances stored in the database. A maximum
+ * of 'limit' objects are returned, starting at object with index 'start'. Only occurrences which
+ * have been determined to belong to the supplied concept are returned.
+ *
+ * @param type
+ * @param determinedAs the taxon concept that these specimens are determined to belong to
+ * @param limit
+ * the maximum number of entities returned (can be null to return
+ * all entities)
+ * @param start
+ * @param orderHints
+ * Supports path like <code>orderHints.propertyNames</code> which
+ * include *-to-one properties like createdBy.username or
+ * authorTeam.persistentTitleCache
+ * @return
+ * @throws DataAccessException
+ */
+ public List<SpecimenOrObservationBase> list(Class<? extends SpecimenOrObservationBase> type, TaxonBase determinedAs, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths);
+
+ /**
+ * Queries the database for specimens which match the given criteria
+ *
+ * @param clazz
+ * the class to match
+ * @param queryString
+ * the queryString to match
+ * @param type
+ * the {@link SpecimenOrObservationType} to match
+ * @param associatedTaxon
+ * the taxon these specimens are in any way associated to via
+ * determination, type designations, individuals associations,
+ * etc.
+ * @param matchmode
+ * determines how the query string should be matched
+ * @param limit
+ * the maximum number of entities returned (can be null to return
+ * all entities)
+ * @param start
+ * @param orderHints
+ * Supports path like <code>orderHints.propertyNames</code> which
+ * include *-to-one properties like createdBy.username or
+ * authorTeam.persistentTitleCache
+ * @param propertyPaths
+ * @return a list of specimens that match the given parameters
+ */
+ public <T extends SpecimenOrObservationBase> List<T> findOccurrences(Class<T> clazz, String queryString,
+ String significantIdentifier, SpecimenOrObservationType type, Taxon determinedAs, MatchMode matchmode,
+ Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths);
+
+ /**
+ * Returns the number of specimens that match the given parameters
+ * @param clazz the class to match
+ * @param queryString the queryString to match
+ * @param type the {@link SpecimenOrObservationType} to match
+ * @param associatedTaxon the taxon these specimens are in any way associated to via
+ * determination, type designations, individuals associations, etc.
+ * @param matchmode determines how the query string should be matched
+ * @param limit
+ * the maximum number of entities returned (can be null to return
+ * all entities)
+ * @param start
+ * @param orderHints
+ * Supports path like <code>orderHints.propertyNames</code> which
+ * include *-to-one properties like createdBy.username or
+ * authorTeam.persistentTitleCache
+ * @return the number of found specimens
+ */
+ public <T extends SpecimenOrObservationBase> int countOccurrences(Class<T> clazz, String queryString,
+ String significantIdentifier, SpecimenOrObservationType recordBasis, Taxon associatedTaxon,
+ MatchMode matchmode, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths);
+
+ /**
+ * Returns a count of Media that are associated with a given occurence
+ *
+ * @param occurence the occurence associated with these media
+ * @return a count of media instances
+ */
+ public int countMedia(SpecimenOrObservationBase occurence);
+
+ /**
+ * Returns a List of Media that are associated with a given occurence
+ *
+ * @param occurence the occurence associated with these media
+ * @param pageSize The maximum number of media returned (can be null for all related media)
+ * @param pageNumber The offset (in pageSize chunks) from the start of the result set (0 - based)
+ * @param propertyPaths properties to initialize - see {@link IBeanInitializer#initialize(Object, List)}
+ * @return a List of media instances
+ */
+ public List<Media> getMedia(SpecimenOrObservationBase occurence, Integer pageSize, Integer pageNumber, List<String> propertyPaths);
+
+ /**
+ * Returns a count of determinations that have been made for a given occurence and for a given taxon concept
+ *
+ * @param occurence the occurence associated with these determinations (can be null for all occurrences)
+ * @param taxonbase the taxon concept associated with these determinations (can be null for all taxon concepts)
+ * @return a count of determination events
+ */
+ public int countDeterminations(SpecimenOrObservationBase occurence,TaxonBase taxonbase);
+
+ /**
+ * Returns a List of determinations that have been made for a given occurence and for a given taxon concept
+ *
+ * @param occurence the occurence associated with these determinations (can be null for all occurrences)
+ * @param taxonbase the taxon concept associated with these determinations (can be null for all taxon concepts)
+ * @param pageSize The maximum number of determinations returned (can be null for all related determinations)
+ * @param pageNumber The offset (in pageSize chunks) from the start of the result set (0 - based)
+ * @param propertyPaths properties to initialize - see {@link IBeanInitializer#initialize(Object, List)}
+ * @return a List of determination instances
+ */
+ public List<DeterminationEvent> getDeterminations(SpecimenOrObservationBase occurence,TaxonBase taxonbase, Integer pageSize, Integer pageNumber, List<String> propertyPaths);
+
+ /**
+ * Returns a count of derivation events that have involved creating new DerivedUnits from this occurence
+ *
+ * @param occurence the occurence that was a source of these derivation events
+ * @return a count of derivation events
+ */
+ public int countDerivationEvents(SpecimenOrObservationBase occurence);
+
+ /**
+ * Returns a list of derivation events that have involved creating new DerivedUnits from this occurence
+ *
+ * @param occurence the occurence that was a source of these derivation events
+ * @param pageSize The maximum number of derivation events returned (can be null for all related derivation events)
+ * @param pageNumber The offset (in pageSize chunks) from the start of the result set (0 - based)
+ * @param propertyPaths properties to initialize - see {@link IBeanInitializer#initialize(Object, List)}
+ * @return a List of derivation events
+ */
+ public List<DerivationEvent> getDerivationEvents(SpecimenOrObservationBase occurence, Integer pageSize, Integer pageNumber, List<String> propertyPaths);
+
+ /**
+ * Retrieves the {@link UUID} and the string representation (title cache) of all
+ * {@link FieldUnit}s found in the data base.
+ * @return a list of {@link UuidAndTitleCache}
+ */
+ public List<UuidAndTitleCache<FieldUnit>> getFieldUnitUuidAndTitleCache();
+
+ /**
+ * Retrieves the {@link UUID} and the string representation (title cache) of all
+ * {@link DerivedUnit}s found in the data base.
+ * @return a list of {@link UuidAndTitleCache}
+ */
+ public List<UuidAndTitleCache<DerivedUnit>> getDerivedUnitUuidAndTitleCache();
+
+ /**
+ * Lists all instances of {@link SpecimenOrObservationBase} which are associated with the <code>taxon</code> specified as parameter.
+ * SpecimenOrObservationBase instances can be associated to taxa in multiple ways, all these possible relations are taken into account:
+ * <ul>
+ * <li>The {@link IndividualsAssociation} elements in a {@link TaxonDescription} contain {@link DerivedUnit}s</li>
+ * <li>{@link SpecimenTypeDesignation}s may be associated with any {@link HomotypicalGroup} related to the specific {@link Taxon}.</li>
+ * <li>A {@link Taxon} may be referenced by the {@link DeterminationEvent} of the {@link SpecimenOrObservationBase}</li>
+ * </ul>
+ *
+ * @param <T>
+ * @param type
+ * @param associatedTaxon
+ * @param limit
+ * @param start
+ * @param orderHints
+ * @param propertyPaths
+ * @return
+ */
+ public <T extends SpecimenOrObservationBase> List<T> listByAssociatedTaxon(Class<T> type, Taxon associatedTaxon,
+ Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths);
+
+ /**
+ * Retrieves all {@link IndividualsAssociation} with the given specimen.<br>
+ * @param specimen the specimen for which the associations are retrieved
+ * @param limit
+ * @param start
+ * @param orderHints
+ * @param propertyPaths
+ * @return collection of all associations
+ */
+ public Collection<IndividualsAssociation> listIndividualsAssociations(SpecimenOrObservationBase<?> specimen, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths);
+
+ /**
+ * Retrieves all {@link SpecimenTypeDesignation}s which have the given specimen as a type specimen.
+ * @param specimen the type specimen
+ * @param limit
+ * @param start
+ * @param orderHints
+ * @param propertyPaths
+ * @return collection of all designations with the given type specimen
+ */
+ public Collection<SpecimenTypeDesignation> listTypeDesignations(SpecimenOrObservationBase<?> specimen, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths);
+
+ /**
+ * Retrieves all {@link DescriptionBase}s that have the given specimen set as described specimen.
+ * @param specimen the described specimen
+ * @param limit
+ * @param start
+ * @param orderHints
+ * @param propertyPaths
+ * @return collection of all descriptions with the given described specimen
+ */
+ public Collection<DescriptionBase<?>> listDescriptionsWithDescriptionSpecimen(SpecimenOrObservationBase<?> specimen, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths);
+
+ /**
+ * Retrieves all {@link SpecimenOrObservationBase}s that have the given {@link SpecimenOrObservationType}.
+ * @param type
+ * @param limit
+ * @param start
+ * @param orderHints
+ * @param propertyPaths
+ * @return collection of specimen with the given type
+ */
+ public Collection<SpecimenOrObservationBase> listBySpecimenOrObservationType(SpecimenOrObservationType type, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths);
+}