// $Id$\r
/**\r
* Copyright (C) 2007 EDIT\r
- * European Distributed Institute of Taxonomy \r
+ * European Distributed Institute of Taxonomy\r
* http://www.e-taxonomy.eu\r
- * \r
+ *\r
* The contents of this file are subject to the Mozilla Public License Version 1.1\r
* See LICENSE.TXT at the top of this package for the full license terms.\r
*/\r
\r
package eu.etaxonomy.cdm.api.service;\r
\r
+import java.io.IOException;\r
import java.util.ArrayList;\r
+import java.util.Arrays;\r
import java.util.Collection;\r
+import java.util.HashMap;\r
+import java.util.HashSet;\r
import java.util.List;\r
import java.util.Map;\r
+import java.util.Map.Entry;\r
+import java.util.Set;\r
import java.util.UUID;\r
\r
import org.apache.log4j.Logger;\r
+import org.apache.lucene.index.CorruptIndexException;\r
+import org.apache.lucene.queryParser.ParseException;\r
+import org.apache.lucene.search.BooleanClause.Occur;\r
+import org.apache.lucene.search.BooleanQuery;\r
+import org.apache.lucene.search.SortField;\r
+import org.hibernate.TransientObjectException;\r
+import org.hibernate.search.spatial.impl.Rectangle;\r
import org.springframework.beans.factory.annotation.Autowired;\r
import org.springframework.stereotype.Service;\r
import org.springframework.transaction.annotation.Transactional;\r
\r
+import eu.etaxonomy.cdm.api.facade.DerivedUnitFacade;\r
+import eu.etaxonomy.cdm.api.facade.DerivedUnitFacadeConfigurator;\r
+import eu.etaxonomy.cdm.api.facade.DerivedUnitFacadeNotSupportedException;\r
+import eu.etaxonomy.cdm.api.service.dto.DerivateHierarchyDTO;\r
+import eu.etaxonomy.cdm.api.service.molecular.ISequenceService;\r
import eu.etaxonomy.cdm.api.service.pager.Pager;\r
import eu.etaxonomy.cdm.api.service.pager.impl.DefaultPagerImpl;\r
-import eu.etaxonomy.cdm.model.common.Annotation;\r
+import eu.etaxonomy.cdm.api.service.search.ILuceneIndexToolProvider;\r
+import eu.etaxonomy.cdm.api.service.search.ISearchResultBuilder;\r
+import eu.etaxonomy.cdm.api.service.search.LuceneSearch;\r
+import eu.etaxonomy.cdm.api.service.search.LuceneSearch.TopGroupsWithMaxScore;\r
+import eu.etaxonomy.cdm.api.service.search.QueryFactory;\r
+import eu.etaxonomy.cdm.api.service.search.SearchResult;\r
+import eu.etaxonomy.cdm.api.service.search.SearchResultBuilder;\r
+import eu.etaxonomy.cdm.api.service.util.TaxonRelationshipEdge;\r
+import eu.etaxonomy.cdm.common.monitor.IProgressMonitor;\r
+import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;\r
+import eu.etaxonomy.cdm.model.CdmBaseType;\r
import eu.etaxonomy.cdm.model.common.DefinedTermBase;\r
-import eu.etaxonomy.cdm.model.location.WaterbodyOrCountry;\r
+import eu.etaxonomy.cdm.model.common.Language;\r
+import eu.etaxonomy.cdm.model.common.UuidAndTitleCache;\r
+import eu.etaxonomy.cdm.model.description.DescriptionBase;\r
+import eu.etaxonomy.cdm.model.description.DescriptionElementBase;\r
+import eu.etaxonomy.cdm.model.description.IndividualsAssociation;\r
+import eu.etaxonomy.cdm.model.location.Country;\r
import eu.etaxonomy.cdm.model.media.Media;\r
+import eu.etaxonomy.cdm.model.media.MediaRepresentation;\r
+import eu.etaxonomy.cdm.model.media.MediaRepresentationPart;\r
+import eu.etaxonomy.cdm.model.molecular.DnaSample;\r
+import eu.etaxonomy.cdm.model.molecular.Sequence;\r
+import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignation;\r
+import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignationStatus;\r
+import eu.etaxonomy.cdm.model.name.TaxonNameBase;\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.GatheringEvent;\r
+import eu.etaxonomy.cdm.model.occurrence.MediaSpecimen;\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.IDefinedTermDao;\r
-import eu.etaxonomy.cdm.persistence.dao.occurrence.ICollectionDao;\r
+import eu.etaxonomy.cdm.persistence.dao.initializer.AbstractBeanInitializer;\r
import eu.etaxonomy.cdm.persistence.dao.occurrence.IOccurrenceDao;\r
+import eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao;\r
import eu.etaxonomy.cdm.persistence.query.OrderHint;\r
+import eu.etaxonomy.cdm.strategy.cache.common.IIdentifiableEntityCacheStrategy;\r
\r
/**\r
* @author a.babadshanjan\r
@Transactional(readOnly = true)\r
public class OccurrenceServiceImpl extends IdentifiableServiceBase<SpecimenOrObservationBase,IOccurrenceDao> implements IOccurrenceService {\r
\r
- static private final Logger logger = Logger.getLogger(OccurrenceServiceImpl.class);\r
- \r
- @Autowired\r
- private IDefinedTermDao definedTermDao;\r
- \r
- @Autowired\r
- private IOccurrenceDao occurenceDao;\r
- \r
- @Autowired\r
- private ICollectionDao collectionDao;\r
- \r
-\r
- public OccurrenceServiceImpl() {\r
- logger.debug("Load OccurrenceService Bean");\r
- }\r
- \r
- /**\r
- * FIXME Candidate for harmonization\r
- * list\r
- * (non-Javadoc)\r
- * @see eu.etaxonomy.cdm.api.service.IOccurrenceService#getAllspecimenOrObservationBases(int, int)\r
- */\r
- public List<SpecimenOrObservationBase> getAllSpecimenOrObservationBases(\r
- int limit, int start) {\r
- return dao.list(limit, start);\r
- }\r
-\r
- /**\r
- * FIXME Candidate for harmonization\r
- * save(Set<SpecimenOrObservationBase> specimens)\r
- * (non-Javadoc)\r
- * @see eu.etaxonomy.cdm.api.service.IOccurrenceService#saveSpecimenOrObservationBaseAll(java.util.Collection)\r
- */\r
- @Transactional(readOnly = false)\r
- public Map<UUID, ? extends SpecimenOrObservationBase> saveSpecimenOrObservationBaseAll(\r
- Collection<? extends SpecimenOrObservationBase> specimenOrObservationBaseCollection) {\r
- return saveCdmObjectAll(specimenOrObservationBaseCollection);\r
- }\r
-\r
- /**\r
- * FIXME Candidate for harmonization\r
- * save\r
- */\r
- @Transactional(readOnly = false)\r
- public UUID saveSpecimenOrObservationBase(\r
- SpecimenOrObservationBase specimenOrObservationBase) {\r
- return super.saveCdmObject(specimenOrObservationBase);\r
- }\r
- \r
- /* (non-Javadoc)\r
- * @see eu.etaxonomy.cdm.api.service.IIdentifiableEntityService#generateTitleCache()\r
- */\r
- public void generateTitleCache() {\r
- // TODO Auto-generated method stub\r
- logger.warn("Not yet implemented");\r
- }\r
-\r
- /**\r
- * FIXME Candidate for harmonization\r
- * move to termService\r
- */\r
- public WaterbodyOrCountry getCountryByIso(String iso639) {\r
- return this.definedTermDao.getCountryByIso(iso639);\r
- \r
- }\r
-\r
- /**\r
- * FIXME Candidate for harmonization\r
- * move to termService\r
- */\r
- public List<WaterbodyOrCountry> getWaterbodyOrCountryByName(String name) {\r
- List<? extends DefinedTermBase> terms = this.definedTermDao.getDefinedTermByRepresentationText(name, WaterbodyOrCountry.class);\r
- List<WaterbodyOrCountry> countries = new ArrayList<WaterbodyOrCountry>();\r
- for (int i=0;i<terms.size();i++){\r
- countries.add((WaterbodyOrCountry)terms.get(i));\r
- }\r
- return countries;\r
- }\r
- \r
- /**\r
- * FIXME Candidate for harmonization\r
- * move to collectionService\r
- */\r
- public List<eu.etaxonomy.cdm.model.occurrence.Collection> searchCollectionByCode(String code) {\r
- return this.collectionDao.getCollectionByCode(code);\r
- }\r
-\r
- @Autowired\r
- protected void setDao(IOccurrenceDao dao) {\r
- this.dao = dao;\r
- }\r
-\r
- public Pager<DerivationEvent> getDerivationEvents(SpecimenOrObservationBase occurence, Integer pageSize,Integer pageNumber, List<String> propertyPaths) {\r
+ static private final Logger logger = Logger.getLogger(OccurrenceServiceImpl.class);\r
+\r
+ @Autowired\r
+ private IDefinedTermDao definedTermDao;\r
+\r
+ @Autowired\r
+ private IDescriptionService descriptionService;\r
+\r
+ @Autowired\r
+ private ITaxonService taxonService;\r
+\r
+ @Autowired\r
+ private ISequenceService sequenceService;\r
+\r
+ @Autowired\r
+ private AbstractBeanInitializer beanInitializer;\r
+\r
+ @Autowired\r
+ private ITaxonDao taxonDao;\r
+\r
+ @Autowired\r
+ private ILuceneIndexToolProvider luceneIndexToolProvider;\r
+\r
+\r
+ public OccurrenceServiceImpl() {\r
+ logger.debug("Load OccurrenceService Bean");\r
+ }\r
+\r
+\r
+ /* (non-Javadoc)\r
+ * @see eu.etaxonomy.cdm.api.service.IIdentifiableEntityService#updateTitleCache(java.lang.Integer, eu.etaxonomy.cdm.strategy.cache.common.IIdentifiableEntityCacheStrategy)\r
+ */\r
+ @Override\r
+ @Transactional(readOnly = false)\r
+ public void updateTitleCache(Class<? extends SpecimenOrObservationBase> clazz, Integer stepSize, IIdentifiableEntityCacheStrategy<SpecimenOrObservationBase> cacheStrategy, IProgressMonitor monitor) {\r
+ if (clazz == null){\r
+ clazz = SpecimenOrObservationBase.class;\r
+ }\r
+ super.updateTitleCacheImpl(clazz, stepSize, cacheStrategy, monitor);\r
+ }\r
+\r
+\r
+ /**\r
+ * FIXME Candidate for harmonization\r
+ * move to termService\r
+ */\r
+ @Override\r
+ public Country getCountryByIso(String iso639) {\r
+ return this.definedTermDao.getCountryByIso(iso639);\r
+\r
+ }\r
+\r
+ /**\r
+ * FIXME Candidate for harmonization\r
+ * move to termService\r
+ */\r
+ @Override\r
+ public List<Country> getCountryByName(String name) {\r
+ List<? extends DefinedTermBase> terms = this.definedTermDao.findByTitle(Country.class, name, null, null, null, null, null, null) ;\r
+ List<Country> countries = new ArrayList<Country>();\r
+ for (int i=0;i<terms.size();i++){\r
+ countries.add((Country)terms.get(i));\r
+ }\r
+ return countries;\r
+ }\r
+\r
+ @Override\r
+ @Autowired\r
+ protected void setDao(IOccurrenceDao dao) {\r
+ this.dao = dao;\r
+ }\r
+\r
+ @Override\r
+ public Pager<DerivationEvent> getDerivationEvents(SpecimenOrObservationBase occurence, Integer pageSize,Integer pageNumber, List<String> propertyPaths) {\r
Integer numberOfResults = dao.countDerivationEvents(occurence);\r
- \r
- List<DerivationEvent> results = new ArrayList<DerivationEvent>();\r
- if(numberOfResults > 0) { // no point checking again\r
- results = dao.getDerivationEvents(occurence, pageSize, pageNumber,propertyPaths); \r
- }\r
- \r
- return new DefaultPagerImpl<DerivationEvent>(pageNumber, numberOfResults, pageSize, results);\r
- }\r
-\r
- public Pager<DeterminationEvent> getDeterminations(SpecimenOrObservationBase occurence, Integer pageSize,Integer pageNumber, List<String> propertyPaths) {\r
- Integer numberOfResults = dao.countDeterminations(occurence);\r
- \r
- List<DeterminationEvent> results = new ArrayList<DeterminationEvent>();\r
- if(numberOfResults > 0) { // no point checking again\r
- results = dao.getDeterminations(occurence, pageSize, pageNumber, propertyPaths); \r
- }\r
- \r
- return new DefaultPagerImpl<DeterminationEvent>(pageNumber, numberOfResults, pageSize, results);\r
- }\r
-\r
- public Pager<Media> getMedia(SpecimenOrObservationBase occurence,Integer pageSize, Integer pageNumber, List<String> propertyPaths) {\r
+\r
+ List<DerivationEvent> results = new ArrayList<DerivationEvent>();\r
+ if(numberOfResults > 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)\r
+ results = dao.getDerivationEvents(occurence, pageSize, pageNumber,propertyPaths);\r
+ }\r
+\r
+ return new DefaultPagerImpl<DerivationEvent>(pageNumber, numberOfResults, pageSize, results);\r
+ }\r
+\r
+ /* (non-Javadoc)\r
+ * @see eu.etaxonomy.cdm.api.service.IOccurrenceService#countDeterminations(eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase, eu.etaxonomy.cdm.model.taxon.TaxonBase)\r
+ */\r
+ @Override\r
+ public int countDeterminations(SpecimenOrObservationBase occurence, TaxonBase taxonbase) {\r
+ return dao.countDeterminations(occurence, taxonbase);\r
+ }\r
+\r
+ @Override\r
+ public Pager<DeterminationEvent> getDeterminations(SpecimenOrObservationBase occurrence, TaxonBase taxonBase, Integer pageSize,Integer pageNumber, List<String> propertyPaths) {\r
+ Integer numberOfResults = dao.countDeterminations(occurrence, taxonBase);\r
+\r
+ List<DeterminationEvent> results = new ArrayList<DeterminationEvent>();\r
+ if(numberOfResults > 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)\r
+ results = dao.getDeterminations(occurrence,taxonBase, pageSize, pageNumber, propertyPaths);\r
+ }\r
+\r
+ return new DefaultPagerImpl<DeterminationEvent>(pageNumber, numberOfResults, pageSize, results);\r
+ }\r
+\r
+ @Override\r
+ public Pager<Media> getMedia(SpecimenOrObservationBase occurence,Integer pageSize, Integer pageNumber, List<String> propertyPaths) {\r
Integer numberOfResults = dao.countMedia(occurence);\r
- \r
- List<Media> results = new ArrayList<Media>();\r
- if(numberOfResults > 0) { // no point checking again\r
- results = dao.getMedia(occurence, pageSize, pageNumber, propertyPaths); \r
- }\r
- \r
- return new DefaultPagerImpl<Media>(pageNumber, numberOfResults, pageSize, results);\r
- }\r
-\r
- /**\r
- * FIXME Candidate for harmonization\r
- * collectionService.save\r
- */\r
- public UUID saveCollection(eu.etaxonomy.cdm.model.occurrence.Collection collection) {\r
- return collectionDao.save(collection);\r
- }\r
-\r
- public Pager<SpecimenOrObservationBase> search(Class<? extends SpecimenOrObservationBase> clazz, String queryString, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {\r
- Integer numberOfResults = dao.count(clazz,queryString);\r
- \r
- List<SpecimenOrObservationBase> results = new ArrayList<SpecimenOrObservationBase>();\r
- if(numberOfResults > 0) { // no point checking again\r
- results = dao.search(clazz,queryString, pageSize, pageNumber, orderHints, propertyPaths); \r
- }\r
- \r
- return new DefaultPagerImpl<SpecimenOrObservationBase>(pageNumber, numberOfResults, pageSize, results);\r
- } \r
+\r
+ List<Media> results = new ArrayList<Media>();\r
+ if(numberOfResults > 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)\r
+ results = dao.getMedia(occurence, pageSize, pageNumber, propertyPaths);\r
+ }\r
+\r
+ return new DefaultPagerImpl<Media>(pageNumber, numberOfResults, pageSize, results);\r
+ }\r
+\r
+ /* (non-Javadoc)\r
+ * @see eu.etaxonomy.cdm.api.service.IOccurrenceService#list(java.lang.Class, eu.etaxonomy.cdm.model.taxon.TaxonBase, java.lang.Integer, java.lang.Integer, java.util.List, java.util.List)\r
+ */\r
+ @Override\r
+ public Pager<SpecimenOrObservationBase> list(Class<? extends SpecimenOrObservationBase> type, TaxonBase determinedAs, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {\r
+ Integer numberOfResults = dao.count(type,determinedAs);\r
+ List<SpecimenOrObservationBase> results = new ArrayList<SpecimenOrObservationBase>();\r
+ pageNumber = pageNumber == null ? 0 : pageNumber;\r
+ if(numberOfResults > 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)\r
+ Integer start = pageSize == null ? 0 : pageSize * pageNumber;\r
+ results = dao.list(type,determinedAs, pageSize, start, orderHints,propertyPaths);\r
+ }\r
+ return new DefaultPagerImpl<SpecimenOrObservationBase>(pageNumber, numberOfResults, pageSize, results);\r
+ }\r
+\r
+ @Override\r
+ public List<UuidAndTitleCache<DerivedUnit>> getDerivedUnitUuidAndTitleCache() {\r
+ return dao.getDerivedUnitUuidAndTitleCache();\r
+ }\r
+\r
+ @Override\r
+ public List<UuidAndTitleCache<FieldUnit>> getFieldUnitUuidAndTitleCache() {\r
+ return dao.getFieldUnitUuidAndTitleCache();\r
+ }\r
+\r
+ /* (non-Javadoc)\r
+ * @see eu.etaxonomy.cdm.api.service.IOccurrenceService#getDerivedUnitFacade(eu.etaxonomy.cdm.model.occurrence.DerivedUnit)\r
+ */\r
+ @Override\r
+ public DerivedUnitFacade getDerivedUnitFacade(DerivedUnit derivedUnit, List<String> propertyPaths) throws DerivedUnitFacadeNotSupportedException {\r
+ derivedUnit = (DerivedUnit)dao.load(derivedUnit.getUuid(), null);\r
+ DerivedUnitFacadeConfigurator config = DerivedUnitFacadeConfigurator.NewInstance();\r
+ config.setThrowExceptionForNonSpecimenPreservationMethodRequest(false);\r
+ DerivedUnitFacade derivedUnitFacade = DerivedUnitFacade.NewInstance(derivedUnit, config);\r
+ beanInitializer.initialize(derivedUnitFacade, propertyPaths);\r
+ return derivedUnitFacade;\r
+ }\r
+\r
+ /* (non-Javadoc)\r
+ * @see eu.etaxonomy.cdm.api.service.IOccurrenceService#listDerivedUnitFacades(eu.etaxonomy.cdm.model.description.DescriptionBase, java.util.List)\r
+ */\r
+ @Override\r
+ public List<DerivedUnitFacade> listDerivedUnitFacades(\r
+ DescriptionBase description, List<String> propertyPaths) {\r
+\r
+ List<DerivedUnitFacade> derivedUnitFacadeList = new ArrayList<DerivedUnitFacade>();\r
+ IndividualsAssociation tempIndividualsAssociation;\r
+ SpecimenOrObservationBase tempSpecimenOrObservationBase;\r
+ List<DescriptionElementBase> elements = descriptionService.listDescriptionElements(description, null, IndividualsAssociation.class, null, 0, Arrays.asList(new String []{"associatedSpecimenOrObservation"}));\r
+ for(DescriptionElementBase element : elements){\r
+ if(element instanceof IndividualsAssociation){\r
+ tempIndividualsAssociation = (IndividualsAssociation)element;\r
+ if(tempIndividualsAssociation.getAssociatedSpecimenOrObservation() != null){\r
+ tempSpecimenOrObservationBase = HibernateProxyHelper.deproxy(tempIndividualsAssociation.getAssociatedSpecimenOrObservation(), SpecimenOrObservationBase.class);\r
+ if(tempSpecimenOrObservationBase instanceof DerivedUnit){\r
+ try {\r
+ derivedUnitFacadeList.add(DerivedUnitFacade.NewInstance((DerivedUnit)tempSpecimenOrObservationBase));\r
+ } catch (DerivedUnitFacadeNotSupportedException e) {\r
+ logger.warn(tempIndividualsAssociation.getAssociatedSpecimenOrObservation().getTitleCache() + " : " +e.getMessage());\r
+ }\r
+ }\r
+ }\r
+\r
+ }\r
+ }\r
+\r
+ beanInitializer.initializeAll(derivedUnitFacadeList, propertyPaths);\r
+\r
+ return derivedUnitFacadeList;\r
+ }\r
+\r
+\r
+ /* (non-Javadoc)\r
+ * @see eu.etaxonomy.cdm.api.service.IOccurrenceService#listByAnyAssociation(java.lang.Class, java.util.Set, eu.etaxonomy.cdm.model.taxon.Taxon, java.lang.Integer, java.lang.Integer, java.util.List, java.util.List)\r
+ */\r
+ @Override\r
+ public <T extends SpecimenOrObservationBase> List<T> listByAssociatedTaxon(Class<T> type, Set<TaxonRelationshipEdge> includeRelationships,\r
+ Taxon associatedTaxon, Integer maxDepth, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {\r
+\r
+ return pageByAssociatedTaxon(type, includeRelationships, associatedTaxon, maxDepth, pageSize, pageNumber, orderHints, propertyPaths).getRecords();\r
+ }\r
+\r
+ /* (non-Javadoc)\r
+ * @see eu.etaxonomy.cdm.api.service.IOccurrenceService#listByAnyAssociation(java.lang.Class, java.util.Set, eu.etaxonomy.cdm.model.taxon.Taxon, java.lang.Integer, java.lang.Integer, java.util.List, java.util.List)\r
+ */\r
+ @Override\r
+ public Collection<FieldUnit> listFieldUnitsByAssociatedTaxon(Set<TaxonRelationshipEdge> includeRelationships,\r
+ Taxon associatedTaxon, Integer maxDepth, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {\r
+\r
+ if(!getSession().contains(associatedTaxon)){\r
+ associatedTaxon = (Taxon) taxonDao.load(associatedTaxon.getUuid());\r
+ }\r
+\r
+ Set<FieldUnit> fieldUnits = new HashSet<FieldUnit>();\r
+\r
+ List<SpecimenOrObservationBase> records = pageByAssociatedTaxon(null, includeRelationships, associatedTaxon, maxDepth, pageSize, pageNumber, orderHints, propertyPaths).getRecords();\r
+ for(SpecimenOrObservationBase<?> specimen:records){\r
+ fieldUnits.addAll(getFieldUnits(specimen.getUuid()));\r
+ }\r
+ return fieldUnits;\r
+ }\r
+\r
+ @Override\r
+ public Collection<DerivateHierarchyDTO> listDerivateHierarchyDTOsByAssociatedTaxon(Set<TaxonRelationshipEdge> includeRelationships,\r
+ Taxon associatedTaxon, Integer maxDepth, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {\r
+\r
+ if(!getSession().contains(associatedTaxon)){\r
+ associatedTaxon = (Taxon) taxonDao.load(associatedTaxon.getUuid());\r
+ }\r
+\r
+ Collection<FieldUnit> fieldUnits = listFieldUnitsByAssociatedTaxon(includeRelationships, associatedTaxon, maxDepth, pageSize, pageNumber, orderHints, propertyPaths);\r
+\r
+ Collection<DerivateHierarchyDTO> derivateHierarchyDTOs = new ArrayList<DerivateHierarchyDTO>();\r
+ for(FieldUnit fieldUnit:fieldUnits){\r
+ derivateHierarchyDTOs.add(assembleDerivateHierarchyDTO(fieldUnit, associatedTaxon));\r
+ }\r
+ return derivateHierarchyDTOs;\r
+ }\r
+\r
+ private DerivateHierarchyDTO assembleDerivateHierarchyDTO(FieldUnit fieldUnit, Taxon associatedTaxon){\r
+ final String separator = ", ";\r
+\r
+ DerivateHierarchyDTO dto = new DerivateHierarchyDTO();\r
+ Map<UUID, SpecimenTypeDesignation> typeSpecimenUUIDtoTypeDesignation = new HashMap<UUID, SpecimenTypeDesignation>();\r
+\r
+ //types\r
+ TaxonNameBase<?,?> name = associatedTaxon.getName();\r
+ Set<?> typeDesignations = name.getSpecimenTypeDesignations();\r
+ for (Object object : typeDesignations) {\r
+ if(object instanceof SpecimenTypeDesignation){\r
+ SpecimenTypeDesignation specimenTypeDesignation = (SpecimenTypeDesignation)object;\r
+ DerivedUnit typeSpecimen = specimenTypeDesignation.getTypeSpecimen();\r
+ typeSpecimenUUIDtoTypeDesignation.put(typeSpecimen.getUuid(), specimenTypeDesignation);\r
+ }\r
+ }\r
+\r
+ if(fieldUnit.getGatheringEvent()!=null){\r
+ GatheringEvent gatheringEvent = fieldUnit.getGatheringEvent();\r
+ //Country\r
+ dto.setCountry(gatheringEvent.getCountry()!=null?gatheringEvent.getCountry().getDescription():"");\r
+ //Collection\r
+ dto.setCollection((gatheringEvent.getCollector()!=null?gatheringEvent.getCollector():"") + fieldUnit.getFieldNumber()!=null?fieldUnit.getFieldNumber():"");\r
+ //Date\r
+ dto.setDate(gatheringEvent.getGatheringDate()!=null?gatheringEvent.getGatheringDate().toString():"");\r
+ }\r
+\r
+ //Taxon Name\r
+ dto.setTaxonName(associatedTaxon.getName().getFullTitleCache());\r
+\r
+\r
+ Collection<DerivedUnit> derivedUnits = new ArrayList<DerivedUnit>();\r
+ getDerivedUnitsFor(fieldUnit, derivedUnits);\r
+ //Herbaria map\r
+ Map<eu.etaxonomy.cdm.model.occurrence.Collection, Integer> collectionToCountMap = new HashMap<eu.etaxonomy.cdm.model.occurrence.Collection, Integer>();\r
+ //Type map\r
+ Map<String, List<String>> typeStatusToAccessionNumber = new HashMap<String, List<String>>();\r
+\r
+ //iterate over sub derivates\r
+ for (DerivedUnit derivedUnit : derivedUnits) {\r
+ //current accession number\r
+ String currentAccessionNumber = derivedUnit.getAccessionNumber()!=null?derivedUnit.getAccessionNumber():"";\r
+ //current herbarium\r
+ String currentHerbarium = "";\r
+ eu.etaxonomy.cdm.model.occurrence.Collection collection = derivedUnit.getCollection();\r
+ if(collection!=null){\r
+ currentHerbarium = collection.getCode()!=null?collection.getCode():"";\r
+ //count herbaria\r
+ Integer count = collectionToCountMap.get(collection);\r
+ if(count==null){\r
+ count = 1;\r
+ }\r
+ else{\r
+ count++;\r
+ }\r
+ collectionToCountMap.put(collection, count);\r
+ }\r
+ //check if derived unit is a type\r
+ if(typeSpecimenUUIDtoTypeDesignation.keySet().contains(derivedUnit.getUuid())){\r
+ dto.setHasType(true);\r
+ SpecimenTypeDesignation specimenTypeDesignation = typeSpecimenUUIDtoTypeDesignation.get(derivedUnit.getUuid());\r
+ SpecimenTypeDesignationStatus specimenTypeDesignationStatus = specimenTypeDesignation.getTypeStatus();\r
+ String typeStatus = specimenTypeDesignationStatus.getLabel(Language.DEFAULT());\r
+ dto.addTypes(typeStatus, currentAccessionNumber);\r
+ }\r
+ //assemble molecular data\r
+ if(derivedUnit instanceof DnaSample){//.getRecordBasis()==SpecimenOrObservationType.DnaSample){\r
+ dto.setHasDna(true);\r
+\r
+ DnaSample dna = (DnaSample)derivedUnit;\r
+ if(dna.getBankNumber()!=null){\r
+ dto.addMolecularData(dna.getBankNumber(), "SampleDesignation?");//FIXME replace with actual getter\r
+ }\r
+ }\r
+ //assemble media data\r
+ else if(derivedUnit instanceof MediaSpecimen){\r
+\r
+ MediaSpecimen media = (MediaSpecimen)derivedUnit;\r
+ String mediaUriString = getMediaUriString(media);\r
+ if(media.getKindOfUnit()!=null){\r
+ if(media.getKindOfUnit().getUuid().equals(UUID.fromString("acda15be-c0e2-4ea8-8783-b9b0c4ad7f03"))){\r
+ dto.setHasSpecimenScan(true);\r
+ if(mediaUriString!=null){\r
+ dto.addSpecimenScan(mediaUriString, currentHerbarium+" "+currentAccessionNumber);\r
+ }\r
+ }\r
+ else if(media.getKindOfUnit().getUuid().equals(UUID.fromString("31eb8d02-bf5d-437c-bcc6-87a626445f34"))){\r
+ dto.setHasDetailImage(true);\r
+ if(mediaUriString!=null){\r
+ String motif = "";\r
+ if(media.getMediaSpecimen()!=null && media.getMediaSpecimen().getTitle(Language.DEFAULT())!=null){\r
+ motif = media.getMediaSpecimen().getTitle(Language.DEFAULT()).getText();\r
+ }\r
+ dto.addDetailImage(mediaUriString, motif);\r
+ }\r
+ }\r
+ }\r
+ }\r
+ //assemble preserved specimen data\r
+ else if(derivedUnit.getRecordBasis()==SpecimenOrObservationType.PreservedSpecimen){\r
+\r
+ }\r
+ }\r
+\r
+ //assemble citation\r
+ String citation = "";\r
+ citation += dto.getCountry();\r
+ citation += separator;\r
+ if(fieldUnit.getGatheringEvent()!=null){\r
+ if(fieldUnit.getGatheringEvent().getLocality()!=null){\r
+ citation += fieldUnit.getGatheringEvent().getLocality().getText();\r
+ citation += separator;\r
+ }\r
+ if(fieldUnit.getGatheringEvent().getExactLocation()!=null\r
+ && fieldUnit.getGatheringEvent().getExactLocation().getLatitude()!=null\r
+ && fieldUnit.getGatheringEvent().getExactLocation().getLongitude()!=null){\r
+ citation += fieldUnit.getGatheringEvent().getExactLocation().getLatitude().toString();\r
+ citation += separator;\r
+ citation += fieldUnit.getGatheringEvent().getExactLocation().getLongitude().toString();\r
+ citation += separator;\r
+ }\r
+ }\r
+ if(citation.endsWith(separator)){\r
+ citation = citation.substring(0, citation.length()-separator.length());\r
+ }\r
+ dto.setCitation(citation);\r
+\r
+ //assemble herbaria string\r
+ String herbariaString = "";\r
+ for(Entry<eu.etaxonomy.cdm.model.occurrence.Collection, Integer> e:collectionToCountMap.entrySet()){\r
+ eu.etaxonomy.cdm.model.occurrence.Collection collection = e.getKey();\r
+ if(collection.getCode()!=null){\r
+ herbariaString += collection.getCode();\r
+ }\r
+ if(e.getValue()>1){\r
+ herbariaString += "("+e.getValue()+")";\r
+ }\r
+ herbariaString += separator;\r
+ }\r
+ if(herbariaString.endsWith(separator)){\r
+ herbariaString = herbariaString.substring(0, herbariaString.length()-separator.length());\r
+ }\r
+ dto.setHerbarium(herbariaString);\r
+ return dto;\r
+ }\r
+\r
+ private String getMediaUriString(MediaSpecimen mediaSpecimen){\r
+ if(!getSession().contains(mediaSpecimen)){\r
+ mediaSpecimen = (MediaSpecimen) load(mediaSpecimen.getUuid());\r
+ }\r
+ String mediaUri = null;\r
+ Collection<MediaRepresentation> mediaRepresentations = mediaSpecimen.getMediaSpecimen().getRepresentations();\r
+ if(mediaRepresentations!=null && !mediaRepresentations.isEmpty()){\r
+ Collection<MediaRepresentationPart> mediaRepresentationParts = mediaRepresentations.iterator().next().getParts();\r
+ if(mediaRepresentationParts!=null && !mediaRepresentationParts.isEmpty()){\r
+ MediaRepresentationPart part = mediaRepresentationParts.iterator().next();\r
+ if(part.getUri()!=null){\r
+ mediaUri = part.getUri().toASCIIString();\r
+ }\r
+ }\r
+ }\r
+ return mediaUri;\r
+ }\r
+\r
+ private void getDerivedUnitsFor(SpecimenOrObservationBase<?> specimen, Collection<DerivedUnit> derivedUnits){\r
+ for(DerivationEvent derivationEvent:specimen.getDerivationEvents()){\r
+ for(DerivedUnit derivative:derivationEvent.getDerivatives()){\r
+ derivedUnits.add(derivative);\r
+ getDerivedUnitsFor(derivative, derivedUnits);\r
+ }\r
+ }\r
+ }\r
+\r
+\r
+ /* (non-Javadoc)\r
+ * @see eu.etaxonomy.cdm.api.service.IOccurrenceService#pageByAssociatedTaxon(java.lang.Class, java.util.Set, eu.etaxonomy.cdm.model.taxon.Taxon, java.lang.Integer, java.lang.Integer, java.lang.Integer, java.util.List, java.util.List)\r
+ */\r
+ @SuppressWarnings("unchecked")\r
+ @Override\r
+ public <T extends SpecimenOrObservationBase> Pager<T> pageByAssociatedTaxon(Class<T> type, Set<TaxonRelationshipEdge> includeRelationships,\r
+ Taxon associatedTaxon, Integer maxDepth, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {\r
+\r
+ Set<Taxon> taxa = new HashSet<Taxon>();\r
+ Set<Integer> occurrenceIds = new HashSet<Integer>();\r
+ List<T> occurrences = new ArrayList<T>();\r
+\r
+// Integer limit = PagerUtils.limitFor(pageSize);\r
+// Integer start = PagerUtils.startFor(pageSize, pageNumber);\r
+\r
+ if(!getSession().contains(associatedTaxon)){\r
+ associatedTaxon = (Taxon) taxonDao.load(associatedTaxon.getUuid());\r
+ }\r
+\r
+ if(includeRelationships != null) {\r
+ taxa = taxonService.listRelatedTaxa(associatedTaxon, includeRelationships, maxDepth, null, null, propertyPaths);\r
+ }\r
+\r
+ taxa.add(associatedTaxon);\r
+\r
+ for (Taxon taxon : taxa) {\r
+ List<T> perTaxonOccurrences = dao.listByAssociatedTaxon(type, taxon, null, null, orderHints, propertyPaths);\r
+ for (SpecimenOrObservationBase o : perTaxonOccurrences) {\r
+ occurrenceIds.add(o.getId());\r
+ }\r
+ }\r
+ occurrences = (List<T>) dao.listByIds(occurrenceIds, pageSize, pageNumber, orderHints, propertyPaths);\r
+\r
+ return new DefaultPagerImpl<T>(pageNumber, occurrenceIds.size(), pageSize, occurrences);\r
+\r
+ }\r
+\r
+ /* (non-Javadoc)\r
+ * @see eu.etaxonomy.cdm.api.service.IOccurrenceService#pageByAssociatedTaxon(java.lang.Class, java.util.Set, eu.etaxonomy.cdm.model.taxon.Taxon, java.lang.Integer, java.lang.Integer, java.lang.Integer, java.util.List, java.util.List)\r
+ */\r
+ @SuppressWarnings("unchecked")\r
+ @Override\r
+ public <T extends SpecimenOrObservationBase> Pager<T> pageByAssociatedTaxon(Class<T> type, Set<TaxonRelationshipEdge> includeRelationships,\r
+ String taxonUUID, Integer maxDepth, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {\r
+\r
+ UUID uuid = UUID.fromString(taxonUUID);\r
+ Taxon tax = (Taxon) taxonDao.load(uuid);\r
+ //TODO REMOVE NULL STATEMENT\r
+type=null;\r
+ return pageByAssociatedTaxon( type,includeRelationships,tax, maxDepth, pageSize, pageNumber, orderHints, propertyPaths );\r
+\r
+ }\r
+\r
+\r
+ @Override\r
+ public Pager<SearchResult<SpecimenOrObservationBase>> findByFullText(\r
+ Class<? extends SpecimenOrObservationBase> clazz, String queryString, Rectangle boundingBox, List<Language> languages,\r
+ boolean highlightFragments, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints,\r
+ List<String> propertyPaths) throws CorruptIndexException, IOException, ParseException {\r
+\r
+ LuceneSearch luceneSearch = prepareByFullTextSearch(clazz, queryString, boundingBox, languages, highlightFragments);\r
+\r
+ // --- execute search\r
+ TopGroupsWithMaxScore topDocsResultSet = luceneSearch.executeSearch(pageSize, pageNumber);\r
+\r
+ Map<CdmBaseType, String> idFieldMap = new HashMap<CdmBaseType, String>();\r
+ idFieldMap.put(CdmBaseType.SPECIMEN_OR_OBSERVATIONBASE, "id");\r
+\r
+ // --- initialize taxa, highlight matches ....\r
+ ISearchResultBuilder searchResultBuilder = new SearchResultBuilder(luceneSearch, luceneSearch.getQuery());\r
+ @SuppressWarnings("rawtypes")\r
+ List<SearchResult<SpecimenOrObservationBase>> searchResults = searchResultBuilder.createResultSet(\r
+ topDocsResultSet, luceneSearch.getHighlightFields(), dao, idFieldMap, propertyPaths);\r
+\r
+ int totalHits = topDocsResultSet != null ? topDocsResultSet.topGroups.totalGroupCount : 0;\r
+\r
+ return new DefaultPagerImpl<SearchResult<SpecimenOrObservationBase>>(pageNumber, totalHits, pageSize,\r
+ searchResults);\r
+\r
+ }\r
+\r
+\r
+ /**\r
+ * @param clazz\r
+ * @param queryString\r
+ * @param languages\r
+ * @param highlightFragments\r
+ * @return\r
+ */\r
+ private LuceneSearch prepareByFullTextSearch(Class<? extends SpecimenOrObservationBase> clazz, String queryString, Rectangle bbox,\r
+ List<Language> languages, boolean highlightFragments) {\r
+\r
+ BooleanQuery finalQuery = new BooleanQuery();\r
+ BooleanQuery textQuery = new BooleanQuery();\r
+\r
+ LuceneSearch luceneSearch = new LuceneSearch(luceneIndexToolProvider, FieldUnit.class);\r
+ QueryFactory queryFactory = luceneIndexToolProvider.newQueryFactoryFor(FieldUnit.class);\r
+\r
+ // --- criteria\r
+ luceneSearch.setCdmTypRestriction(clazz);\r
+ if(queryString != null){\r
+ textQuery.add(queryFactory.newTermQuery("titleCache", queryString), Occur.SHOULD);\r
+ finalQuery.add(textQuery, Occur.MUST);\r
+ }\r
+\r
+ // --- spacial query\r
+ if(bbox != null){\r
+ finalQuery.add(QueryFactory.buildSpatialQueryByRange(bbox, "gatheringEvent.exactLocation.point"), Occur.MUST);\r
+ }\r
+\r
+ luceneSearch.setQuery(finalQuery);\r
+\r
+ // --- sorting\r
+ SortField[] sortFields = new SortField[]{SortField.FIELD_SCORE, new SortField("titleCache__sort", SortField.STRING, false)};\r
+ luceneSearch.setSortFields(sortFields);\r
+\r
+ if(highlightFragments){\r
+ luceneSearch.setHighlightFields(queryFactory.getTextFieldNamesAsArray());\r
+ }\r
+ return luceneSearch;\r
+ }\r
+\r
+\r
+ /* (non-Javadoc)\r
+ * @see eu.etaxonomy.cdm.api.service.IOccurrenceService#getFieldUnits(eu.etaxonomy.cdm.model.occurrence.DerivedUnit)\r
+ */\r
+ @Override\r
+ public Collection<FieldUnit> getFieldUnits(UUID derivedUnitUuid) {\r
+ //It will search recursively over all {@link DerivationEvent}s and get the "originals" ({@link SpecimenOrObservationBase})\r
+ //from which this DerivedUnit was derived until all FieldUnits are found.\r
+\r
+ //FIXME: use HQL queries to increase performance\r
+ SpecimenOrObservationBase<?> specimen = load(derivedUnitUuid);\r
+// specimen = HibernateProxyHelper.deproxy(specimen, SpecimenOrObservationBase.class);\r
+ Collection<FieldUnit> fieldUnits = new ArrayList<FieldUnit>();\r
+\r
+ if(specimen instanceof FieldUnit){\r
+ fieldUnits.add((FieldUnit) specimen);\r
+ }\r
+ else if(specimen instanceof DerivedUnit){\r
+ getFieldUnits((DerivedUnit) specimen, fieldUnits);\r
+ }\r
+ return fieldUnits;\r
+ }\r
+\r
+\r
+ /**\r
+ * @param original\r
+ * @param fieldUnits\r
+ */\r
+ private void getFieldUnits(DerivedUnit derivedUnit, Collection<FieldUnit> fieldUnits) {\r
+ Set<SpecimenOrObservationBase> originals = derivedUnit.getOriginals();\r
+ if(originals!=null && !originals.isEmpty()){\r
+ for(SpecimenOrObservationBase<?> original:originals){\r
+ if(original instanceof FieldUnit){\r
+ fieldUnits.add((FieldUnit) original);\r
+ }\r
+ else if(original instanceof DerivedUnit){\r
+ getFieldUnits((DerivedUnit) original, fieldUnits);\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ /* (non-Javadoc)\r
+ * @see eu.etaxonomy.cdm.api.service.IOccurrenceService#moveSequence(eu.etaxonomy.cdm.model.molecular.DnaSample, eu.etaxonomy.cdm.model.molecular.DnaSample, eu.etaxonomy.cdm.model.molecular.Sequence)\r
+ */\r
+ @Override\r
+ public boolean moveSequence(DnaSample from, DnaSample to, Sequence sequence) {\r
+ //reload specimens to avoid session conflicts\r
+ from = (DnaSample) load(from.getUuid());\r
+ to = (DnaSample) load(to.getUuid());\r
+ sequence = sequenceService.load(sequence.getUuid());\r
+\r
+ if(from==null || to==null || sequence==null){\r
+ throw new TransientObjectException("One of the CDM entities has not been saved to the data base yet. Moving only works for persisted/saved CDM entities.\n" +\r
+ "Operation was move "+sequence+ " from "+from+" to "+to);\r
+ }\r
+ from.removeSequence(sequence);\r
+ saveOrUpdate(from);\r
+ to.addSequence(sequence);\r
+ saveOrUpdate(to);\r
+ return true;\r
+ }\r
+\r
+ /* (non-Javadoc)\r
+ * @see eu.etaxonomy.cdm.api.service.IOccurrenceService#moveDerivate(eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase, eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase, eu.etaxonomy.cdm.model.occurrence.DerivedUnit)\r
+ */\r
+ @Override\r
+ public boolean moveDerivate(SpecimenOrObservationBase<?> from, SpecimenOrObservationBase<?> to, DerivedUnit derivate) {\r
+ //reload specimens to avoid session conflicts\r
+ from = load(from.getUuid());\r
+ to = load(to.getUuid());\r
+ derivate = (DerivedUnit) load(derivate.getUuid());\r
+\r
+ if(from==null || to==null || derivate==null){\r
+ throw new TransientObjectException("One of the CDM entities has not been saved to the data base yet. Moving only works for persisted/saved CDM entities.\n" +\r
+ "Operation was move "+derivate+ " from "+from+" to "+to);\r
+ }\r
+\r
+ SpecimenOrObservationType derivateType = derivate.getRecordBasis();\r
+ SpecimenOrObservationType toType = to.getRecordBasis();\r
+ //check if type is a sub derivate type\r
+ if(toType==SpecimenOrObservationType.FieldUnit //moving to FieldUnit always works\r
+ || derivateType==SpecimenOrObservationType.Media //moving media always works\r
+ || (derivateType.isKindOf(toType) && toType!=derivateType)){ //moving only to parent derivate type\r
+ //remove derivation event from parent specimen of dragged object\r
+ DerivationEvent eventToRemove = null;\r
+ for(DerivationEvent event:from.getDerivationEvents()){\r
+ if(event.getDerivatives().contains(derivate)){\r
+ eventToRemove = event;\r
+ break;\r
+ }\r
+ }\r
+ from.removeDerivationEvent(eventToRemove);\r
+ saveOrUpdate(from);\r
+ //add new derivation event to target\r
+ to.addDerivationEvent(DerivationEvent.NewSimpleInstance(to, derivate, eventToRemove==null?null:eventToRemove.getType()));\r
+ saveOrUpdate(to);\r
+ return true;\r
+ }\r
+ return false;\r
+ }\r
+\r
}\r