X-Git-Url: https://dev.e-taxonomy.eu/gitweb/cdmlib.git/blobdiff_plain/d44277a98c7c1eee85292086fa074054ad0b7f1d..e7b0669119e9bd65be692850b5277500e3fb36d9:/cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/TaxonServiceImpl.java diff --git a/cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/TaxonServiceImpl.java b/cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/TaxonServiceImpl.java index 7fb38a889c..2b8b30bcaf 100644 --- a/cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/TaxonServiceImpl.java +++ b/cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/TaxonServiceImpl.java @@ -11,39 +11,44 @@ package eu.etaxonomy.cdm.api.service; import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; +import java.util.Comparator; import java.util.HashSet; import java.util.List; -import java.util.Map; import java.util.Set; import java.util.UUID; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import org.springframework.transaction.TransactionStatus; +import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import eu.etaxonomy.cdm.api.service.config.ITaxonServiceConfigurator; import eu.etaxonomy.cdm.api.service.pager.Pager; import eu.etaxonomy.cdm.api.service.pager.impl.DefaultPagerImpl; import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper; +import eu.etaxonomy.cdm.model.common.CdmBase; import eu.etaxonomy.cdm.model.common.IdentifiableEntity; import eu.etaxonomy.cdm.model.common.OrderedTermVocabulary; import eu.etaxonomy.cdm.model.common.RelationshipBase; -import eu.etaxonomy.cdm.model.description.CommonTaxonName; -import eu.etaxonomy.cdm.model.description.DescriptionBase; +import eu.etaxonomy.cdm.model.common.RelationshipBase.Direction; +import eu.etaxonomy.cdm.model.common.UuidAndTitleCache; +import eu.etaxonomy.cdm.model.description.DescriptionElementBase; import eu.etaxonomy.cdm.model.description.TaxonDescription; +import eu.etaxonomy.cdm.model.media.Media; +import eu.etaxonomy.cdm.model.media.MediaRepresentation; +import eu.etaxonomy.cdm.model.media.MediaUtils; import eu.etaxonomy.cdm.model.name.HomotypicalGroup; import eu.etaxonomy.cdm.model.name.Rank; import eu.etaxonomy.cdm.model.name.TaxonNameBase; -import eu.etaxonomy.cdm.model.reference.ReferenceBase; +import eu.etaxonomy.cdm.model.reference.Reference; +import eu.etaxonomy.cdm.model.taxon.Classification; import eu.etaxonomy.cdm.model.taxon.Synonym; import eu.etaxonomy.cdm.model.taxon.SynonymRelationship; import eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType; import eu.etaxonomy.cdm.model.taxon.Taxon; import eu.etaxonomy.cdm.model.taxon.TaxonBase; +import eu.etaxonomy.cdm.model.taxon.TaxonNode; import eu.etaxonomy.cdm.model.taxon.TaxonRelationship; import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType; import eu.etaxonomy.cdm.persistence.dao.common.IOrderedTermVocabularyDao; @@ -51,24 +56,28 @@ import eu.etaxonomy.cdm.persistence.dao.description.IDescriptionDao; import eu.etaxonomy.cdm.persistence.dao.name.ITaxonNameDao; import eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao; import eu.etaxonomy.cdm.persistence.fetch.CdmFetch; +import eu.etaxonomy.cdm.persistence.query.MatchMode; import eu.etaxonomy.cdm.persistence.query.OrderHint; +/** + * @author a.kohlbecker + * @date 10.09.2010 + * + */ @Service -@Transactional(readOnly = true) -public class TaxonServiceImpl extends IdentifiableServiceBase implements ITaxonService { +@Transactional(propagation = Propagation.SUPPORTS, readOnly = true) +public class TaxonServiceImpl extends IdentifiableServiceBase implements ITaxonService{ private static final Logger logger = Logger.getLogger(TaxonServiceImpl.class); @Autowired private ITaxonNameDao nameDao; -// @Autowired -// @Qualifier("nonViralNameDaoHibernateImpl") -// private INonViralNameDao nonViralNameDao; - @Autowired - private IOrderedTermVocabularyDao orderedVocabularyDao; - @Autowired + + @Autowired private IDescriptionDao descriptionDao; + @Autowired + private IOrderedTermVocabularyDao orderedVocabularyDao; /** * Constructor @@ -76,80 +85,74 @@ public class TaxonServiceImpl extends IdentifiableServiceBase saveTaxonAll(Collection taxonCollection){ - return saveCdmObjectAll(taxonCollection); - } - @Transactional(readOnly = false) - public UUID removeTaxon(TaxonBase taxon) { - return super.removeCdmObject(taxon); - } - - public List searchTaxaByName(String name, ReferenceBase sec) { + /** + * FIXME Candidate for harmonization + * rename searchByName ? + */ + public List searchTaxaByName(String name, Reference sec) { return dao.getTaxaByName(name, sec); } - - public List getAllTaxonBases(int limit, int start){ - return dao.list(limit, start); - } - - public List getAllTaxa(int limit, int start){ - return dao.getAllTaxa(limit, start); - } + /** + * FIXME Candidate for harmonization + * list(Synonym.class, ...) + * (non-Javadoc) + * @see eu.etaxonomy.cdm.api.service.ITaxonService#getAllSynonyms(int, int) + */ public List getAllSynonyms(int limit, int start) { return dao.getAllSynonyms(limit, start); } - /* (non-Javadoc) - * @see eu.etaxonomy.cdm.api.service.ITaxonService#getRootTaxa(eu.etaxonomy.cdm.model.reference.ReferenceBase) + /** + * FIXME Candidate for harmonization + * list(Taxon.class, ...) + * (non-Javadoc) + * @see eu.etaxonomy.cdm.api.service.ITaxonService#getAllTaxa(int, int) + */ + public List getAllTaxa(int limit, int start) { + return dao.getAllTaxa(limit, start); + } + + + /** + * FIXME Candidate for harmonization + * merge with getRootTaxa(Reference sec, ..., ...) + * (non-Javadoc) + * @see eu.etaxonomy.cdm.api.service.ITaxonService#getRootTaxa(eu.etaxonomy.cdm.model.reference.Reference) */ - public List getRootTaxa(ReferenceBase sec){ + public List getRootTaxa(Reference sec){ return getRootTaxa(sec, CdmFetch.FETCH_CHILDTAXA(), true); } - /* (non-Javadoc) - * @see eu.etaxonomy.cdm.api.service.ITaxonService#getRootTaxa(eu.etaxonomy.cdm.model.reference.ReferenceBase, boolean) + /** + * FIXME Candidate for harmonization + * merge with getRootTaxa(Reference sec, ..., ...) + * (non-Javadoc) + * @see eu.etaxonomy.cdm.api.service.ITaxonService#getRootTaxa(eu.etaxonomy.cdm.model.reference.Reference, boolean) */ - public List getRootTaxa(ReferenceBase sec, CdmFetch cdmFetch, boolean onlyWithChildren) { + public List getRootTaxa(Reference sec, CdmFetch cdmFetch, boolean onlyWithChildren) { if (cdmFetch == null){ cdmFetch = CdmFetch.NO_FETCH(); } return dao.getRootTaxa(sec, cdmFetch, onlyWithChildren, false); } - - /* (non-Javadoc) - * @see eu.etaxonomy.cdm.api.service.ITaxonService#getRootTaxa(eu.etaxonomy.cdm.model.reference.ReferenceBase, boolean, boolean) + /** + * FIXME Candidate for harmonization + * merge with getRootTaxa(Reference sec, ..., ...) + * (non-Javadoc) + * @see eu.etaxonomy.cdm.api.service.ITaxonService#getRootTaxa(eu.etaxonomy.cdm.model.reference.Reference, boolean, boolean) */ - public List getRootTaxa(ReferenceBase sec, boolean onlyWithChildren, + public List getRootTaxa(Reference sec, boolean onlyWithChildren, boolean withMisapplications) { return dao.getRootTaxa(sec, null, onlyWithChildren, withMisapplications); } /* (non-Javadoc) - * @see eu.etaxonomy.cdm.api.service.ITaxonService#getRootTaxa(eu.etaxonomy.cdm.model.name.Rank, eu.etaxonomy.cdm.model.reference.ReferenceBase, boolean, boolean) + * @see eu.etaxonomy.cdm.api.service.ITaxonService#getRootTaxa(eu.etaxonomy.cdm.model.name.Rank, eu.etaxonomy.cdm.model.reference.Reference, boolean, boolean) */ - public List getRootTaxa(Rank rank, ReferenceBase sec, boolean onlyWithChildren, + public List getRootTaxa(Rank rank, Reference sec, boolean onlyWithChildren, boolean withMisapplications, List propertyPaths) { return dao.getRootTaxa(rank, sec, null, onlyWithChildren, withMisapplications, propertyPaths); } @@ -158,6 +161,11 @@ public class TaxonServiceImpl extends IdentifiableServiceBase getTaxonRelationshipTypeVocabulary() { String taxonRelTypeVocabularyId = "15db0cf7-7afc-4a86-a7d4-221c73b0c9ac"; @@ -171,22 +179,31 @@ public class TaxonServiceImpl extends IdentifiableServiceBase synonymName = oldTaxon.getName(); - if (synonymType == null){ + if (synonymRelationshipType == null){ if (synonymName.isHomotypic(newAcceptedTaxon.getName())){ - synonymType = SynonymRelationshipType.HOMOTYPIC_SYNONYM_OF(); + synonymRelationshipType = SynonymRelationshipType.HOMOTYPIC_SYNONYM_OF(); }else{ - //TODO synonymType - synonymType = SynonymRelationshipType.HETEROTYPIC_SYNONYM_OF(); + synonymRelationshipType = SynonymRelationshipType.HETEROTYPIC_SYNONYM_OF(); } } - SynonymRelationship synRel = newAcceptedTaxon.addSynonymName(synonymName, synonymType, citation, citationMicroReference); + SynonymRelationship synonmyRelationship = newAcceptedTaxon.addSynonymName(synonymName, synonymRelationshipType, citation, citationMicroReference); //Move Synonym Relations to new Taxon for(SynonymRelationship synRelation : oldTaxon.getSynonymRelations()){ @@ -194,111 +211,179 @@ public class TaxonServiceImpl extends IdentifiableServiceBase removableTaxonRels = new HashSet(); - for(TaxonRelationship taxonRelation : oldTaxon.getTaxonRelations()){ - //CHILDREN - if (taxonRelation.getType().equals(TaxonRelationshipType.TAXONOMICALLY_INCLUDED_IN())){ - if (taxonRelation.getFromTaxon() == oldTaxon){ - removableTaxonRels.add(taxonRelation); -// oldTaxon.removeTaxonRelation(taxonRelation); - }else if(taxonRelation.getToTaxon() == oldTaxon){ - newAcceptedTaxon.addTaxonomicChild(taxonRelation.getFromTaxon(), taxonRelation.getCitation(), taxonRelation.getCitationMicroReference()); - removableTaxonRels.add(taxonRelation); -// oldTaxon.removeTaxonRelation(taxonRelation); - }else{ - logger.warn("Taxon is not part of its own Taxonrelationship"); - } - } - //MISAPPLIED NAMES - if (taxonRelation.getType().equals(TaxonRelationshipType.MISAPPLIED_NAME_FOR())){ - if (taxonRelation.getFromTaxon() == oldTaxon){ - newAcceptedTaxon.addMisappliedName(taxonRelation.getToTaxon(), taxonRelation.getCitation(), taxonRelation.getCitationMicroReference()); - removableTaxonRels.add(taxonRelation); -// oldTaxon.removeTaxonRelation(taxonRelation); - }else if(taxonRelation.getToTaxon() == oldTaxon){ - newAcceptedTaxon.addMisappliedName(taxonRelation.getFromTaxon(), taxonRelation.getCitation(), taxonRelation.getCitationMicroReference()); - removableTaxonRels.add(taxonRelation); -// oldTaxon.removeTaxonRelation(taxonRelation); - }else{ - logger.warn("Taxon is not part of its own Taxonrelationship"); - } + + // CHILD NODES + if(oldTaxonNode.getChildNodes() != null && oldTaxonNode.getChildNodes().size() != 0){ + for(TaxonNode childNode : oldTaxonNode.getChildNodes()){ + newAcceptedTaxonNode.addChildNode(childNode, childNode.getReference(), childNode.getMicroReference(), childNode.getSynonymToBeUsed()); } - //Concept Relationships - //FIXME implement -// if (taxonRelation.getType().equals(TaxonRelationshipType.MISAPPLIEDNAMEFOR())){ -// if (taxonRelation.getFromTaxon() == oldTaxon){ -// newAcceptedTaxon.addMisappliedName(taxonRelation.getToTaxon(), taxonRelation.getCitation(), taxonRelation.getCitationMicroReference()); -// removableTaxonRels.add(taxonRelation); -// }else if(taxonRelation.getToTaxon() == oldTaxon){ -// newAcceptedTaxon.addMisappliedName(taxonRelation.getFromTaxon(), taxonRelation.getCitation(), taxonRelation.getCitationMicroReference()); -// removableTaxonRels.add(taxonRelation); -// }else{ -// logger.warn("Taxon is not part of its own Taxonrelationship"); -// } -// } } - for(TaxonRelationship taxonRel : removableTaxonRels) { - oldTaxon.removeTaxonRelation(taxonRel); + //Move Taxon RelationShips to new Taxon + Set obsoleteTaxonRelationships = new HashSet(); + for(TaxonRelationship taxonRelationship : oldTaxon.getTaxonRelations()){ + Taxon fromTaxon = (Taxon) HibernateProxyHelper.deproxy(taxonRelationship.getFromTaxon()); + Taxon toTaxon = (Taxon) HibernateProxyHelper.deproxy(taxonRelationship.getToTaxon()); + if (fromTaxon == oldTaxon){ + newAcceptedTaxon.addTaxonRelation(taxonRelationship.getToTaxon(), taxonRelationship.getType(), + taxonRelationship.getCitation(), taxonRelationship.getCitationMicroReference()); + + }else if(toTaxon == oldTaxon){ + taxonRelationship.getFromTaxon().addTaxonRelation(newAcceptedTaxon, taxonRelationship.getType(), + taxonRelationship.getCitation(), taxonRelationship.getCitationMicroReference()); + + }else{ + logger.warn("Taxon is not part of its own Taxonrelationship"); + } + // Remove old relationships + taxonRelationship.setToTaxon(null); + taxonRelationship.setFromTaxon(null); } - //Move Descriptions to new Taxon - for(TaxonDescription taxDescription : oldTaxon.getDescriptions()){ - newAcceptedTaxon.addDescription(taxDescription); + //Move descriptions to new taxon + for(TaxonDescription description : oldTaxon.getDescriptions()){ + description.setTitleCache("Description copied from former accepted taxon: " + oldTaxon.getTitleCache() + "(Old title: " + description.getTitleCache() + ")"); + newAcceptedTaxon.addDescription(description); } - //delete old Taxon - this.dao.saveOrUpdate(newAcceptedTaxon); -// FIXME implement -// this.dao.delete(oldTaxon); + + oldTaxonNode.delete(); - //return -// this.dao.flush(); - return synRel.getSynonym(); + return synonmyRelationship.getSynonym(); } - - public void generateTitleCache() { - generateTitleCache(true); + /* + * (non-Javadoc) + * @see eu.etaxonomy.cdm.api.service.ITaxonService#swapSynonymWithAcceptedTaxon(eu.etaxonomy.cdm.model.taxon.Synonym) + */ + @Transactional(readOnly = false) + public void swapSynonymAndAcceptedTaxon(Synonym synonym, Taxon acceptedTaxon){ + + TaxonNameBase synonymName = synonym.getName(); + synonymName.removeTaxonBase(synonym); + TaxonNameBase taxonName = acceptedTaxon.getName(); + taxonName.removeTaxonBase(acceptedTaxon); + + synonym.setName(taxonName); + acceptedTaxon.setName(synonymName); + + // the accepted taxon needs a new uuid because the concept has changed + // FIXME this leads to an error "HibernateException: immutable natural identifier of an instance of eu.etaxonomy.cdm.model.taxon.Taxon was altered" + //acceptedTaxon.setUuid(UUID.randomUUID()); } - //TODO - public void generateTitleCache(boolean forceProtected) { - logger.warn("generateTitleCache not yet fully implemented!"); -// for (TaxonBase tb : taxonDao.getAllTaxa(null,null)){ -// logger.warn("Old taxon title: " + tb.getTitleCache()); -// if (forceProtected || !tb.isProtectedTitleCache() ){ -// tb.setTitleCache(tb.generateTitle(), false); -// taxonDao.update(tb); -// logger.warn("New title: " + tb.getTitleCache()); -// } -// } + + /* + * (non-Javadoc) + * @see eu.etaxonomy.cdm.api.service.ITaxonService#makeSynonymAcceptedTaxon(eu.etaxonomy.cdm.model.taxon.Synonym, eu.etaxonomy.cdm.model.taxon.Taxon) + */ + public Taxon changeSynonymToAcceptedTaxon(Synonym synonym, Taxon acceptedTaxon){ + + Taxon newAcceptedTaxon = Taxon.NewInstance(synonym.getName(), acceptedTaxon.getSec()); + + acceptedTaxon.removeSynonym(synonym); + + // since we are swapping names, we have to detach the name from the synonym completely. + // Otherwise the synonym will still be in the list of typified names. + synonym.getName().removeTaxonBase(synonym); + + return newAcceptedTaxon; + } + + public Taxon changeSynonymToRelatedTaxon(Synonym synonym, Taxon toTaxon, TaxonRelationshipType taxonRelationshipType, Reference citation, String microcitation){ + + // Get name from synonym + TaxonNameBase synonymName = synonym.getName(); + + // remove synonym from taxon + toTaxon.removeSynonym(synonym); + + // Create a taxon with synonym name + Taxon fromTaxon = Taxon.NewInstance(synonymName, null); + + // Add taxon relation + fromTaxon.addTaxonRelation(toTaxon, taxonRelationshipType, citation, microcitation); + + // since we are swapping names, we have to detach the name from the synonym completely. + // Otherwise the synonym will still be in the list of typified names. + synonym.getName().removeTaxonBase(synonym); + + return fromTaxon; } + /* (non-Javadoc) + * @see eu.etaxonomy.cdm.api.service.IIdentifiableEntityService#updateTitleCache() + */ + @Override + @Transactional(readOnly = false) + public void updateTitleCache() { + Class clazz = TaxonBase.class; + super.updateTitleCache(clazz, null, null); + } + @Autowired protected void setDao(ITaxonDao dao) { this.dao = dao; } - public Pager findTaxaByName(Boolean accepted, String uninomial, String infragenericEpithet, String specificEpithet, String infraspecificEpithet, Rank rank, Integer pageSize,Integer pageNumber) { - Integer numberOfResults = dao.countTaxaByName(accepted, uninomial, infragenericEpithet, specificEpithet, infraspecificEpithet, rank); + public Pager findTaxaByName(Class clazz, String uninomial, String infragenericEpithet, String specificEpithet, String infraspecificEpithet, Rank rank, Integer pageSize,Integer pageNumber) { + Integer numberOfResults = dao.countTaxaByName(clazz, uninomial, infragenericEpithet, specificEpithet, infraspecificEpithet, rank); List results = new ArrayList(); if(numberOfResults > 0) { // no point checking again - results = dao.findTaxaByName(accepted, uninomial, infragenericEpithet, specificEpithet, infraspecificEpithet, rank, pageSize, pageNumber); + results = dao.findTaxaByName(clazz, uninomial, infragenericEpithet, specificEpithet, infraspecificEpithet, rank, pageSize, pageNumber); } return new DefaultPagerImpl(pageNumber, numberOfResults, pageSize, results); } - public Pager getRelatedTaxa(Taxon taxon, TaxonRelationshipType type, Integer pageSize, Integer pageNumber, List orderHints, List propertyPaths) { - Integer numberOfResults = dao.countRelatedTaxa(taxon, type); + public List listTaxaByName(Class clazz, String uninomial, String infragenericEpithet, String specificEpithet, String infraspecificEpithet, Rank rank, Integer pageSize,Integer pageNumber) { + Integer numberOfResults = dao.countTaxaByName(clazz, uninomial, infragenericEpithet, specificEpithet, infraspecificEpithet, rank); + + List results = new ArrayList(); + if(numberOfResults > 0) { // no point checking again + results = dao.findTaxaByName(clazz, uninomial, infragenericEpithet, specificEpithet, infraspecificEpithet, rank, pageSize, pageNumber); + } + + return results; + } + + public List listToTaxonRelationships(Taxon taxon, TaxonRelationshipType type, Integer pageSize, Integer pageNumber, List orderHints, List propertyPaths){ + Integer numberOfResults = dao.countTaxonRelationships(taxon, type, TaxonRelationship.Direction.relatedTo); List results = new ArrayList(); if(numberOfResults > 0) { // no point checking again - results = dao.getRelatedTaxa(taxon, type, pageSize, pageNumber, orderHints, propertyPaths); + results = dao.getTaxonRelationships(taxon, type, pageSize, pageNumber, orderHints, propertyPaths, TaxonRelationship.Direction.relatedTo); } + return results; + } + + public Pager pageToTaxonRelationships(Taxon taxon, TaxonRelationshipType type, Integer pageSize, Integer pageNumber, List orderHints, List propertyPaths) { + Integer numberOfResults = dao.countTaxonRelationships(taxon, type, TaxonRelationship.Direction.relatedTo); + List results = new ArrayList(); + if(numberOfResults > 0) { // no point checking again + results = dao.getTaxonRelationships(taxon, type, pageSize, pageNumber, orderHints, propertyPaths, TaxonRelationship.Direction.relatedTo); + } + return new DefaultPagerImpl(pageNumber, numberOfResults, pageSize, results); + } + + public List listFromTaxonRelationships(Taxon taxon, TaxonRelationshipType type, Integer pageSize, Integer pageNumber, List orderHints, List propertyPaths){ + Integer numberOfResults = dao.countTaxonRelationships(taxon, type, TaxonRelationship.Direction.relatedFrom); + + List results = new ArrayList(); + if(numberOfResults > 0) { // no point checking again + results = dao.getTaxonRelationships(taxon, type, pageSize, pageNumber, orderHints, propertyPaths, TaxonRelationship.Direction.relatedFrom); + } + return results; + } + + public Pager pageFromTaxonRelationships(Taxon taxon, TaxonRelationshipType type, Integer pageSize, Integer pageNumber, List orderHints, List propertyPaths) { + Integer numberOfResults = dao.countTaxonRelationships(taxon, type, TaxonRelationship.Direction.relatedFrom); + + List results = new ArrayList(); + if(numberOfResults > 0) { // no point checking again + results = dao.getTaxonRelationships(taxon, type, pageSize, pageNumber, orderHints, propertyPaths, TaxonRelationship.Direction.relatedFrom); + } return new DefaultPagerImpl(pageNumber, numberOfResults, pageSize, results); } @@ -313,6 +398,17 @@ public class TaxonServiceImpl extends IdentifiableServiceBase(pageNumber, numberOfResults, pageSize, results); } + public Pager getSynonyms(Synonym synonym, SynonymRelationshipType type, Integer pageSize, Integer pageNumber, List orderHints, List propertyPaths) { + Integer numberOfResults = dao.countSynonyms(synonym, type); + + List results = new ArrayList(); + if(numberOfResults > 0) { // no point checking again + results = dao.getSynonyms(synonym, type, pageSize, pageNumber, orderHints, propertyPaths); + } + + return new DefaultPagerImpl(pageNumber, numberOfResults, pageSize, results); + } + public List getHomotypicSynonymsByHomotypicGroup(Taxon taxon, List propertyPaths){ Taxon t = (Taxon)dao.load(taxon.getUuid(), propertyPaths); return t.getHomotypicSynonymsByHomotypicGroup(); @@ -327,60 +423,66 @@ public class TaxonServiceImpl extends IdentifiableServiceBase searchTaxa(String queryString, Boolean accepted, Integer pageSize, Integer pageNumber) { - Integer numberOfResults = dao.countTaxa(queryString, accepted); - - List results = new ArrayList(); - if(numberOfResults > 0) { // no point checking again - results = dao.searchTaxa(queryString, accepted, pageSize, pageNumber); - } - - return new DefaultPagerImpl(pageNumber, numberOfResults, pageSize, results); - } - + /* (non-Javadoc) + * @see eu.etaxonomy.cdm.api.service.ITaxonService#findTaxaAndNames(eu.etaxonomy.cdm.api.service.config.ITaxonServiceConfigurator) + */ public Pager findTaxaAndNames(ITaxonServiceConfigurator configurator) { List results = new ArrayList(); - int numberOfResults = 0; - - // TODO: Implement matching count-methods for the search methods - - if(configurator.isDoTaxa()) { - int numberTaxaResults = dao.countTaxaByName(configurator.getSearchString(), configurator.getMatchMode(), - true); -// int numberTaxaResults = dao.countTaxaByName(configurator.getSearchString(), true, configurator.getSec()); - List taxa = - dao.getTaxaByName(configurator.getSearchString(), configurator.getMatchMode(), - true, configurator.getPageSize(), configurator.getPageNumber()); -// dao.getTaxaByName(configurator.getSearchString(), true, configurator.getSec()); - if (logger.isDebugEnabled()) { logger.debug(taxa.size() + " matching taxa counted"); } - if (taxa.size() > 0) { - results.addAll(taxa); - numberOfResults += numberTaxaResults; + int numberOfResults = 0; // overall number of results (as opposed to number of results per page) + List taxa = null; + + // Taxa and synonyms + long numberTaxaResults = 0L; + + Class clazz = null; + List propertyPath = new ArrayList(); + if(configurator.getTaxonPropertyPath() != null){ + propertyPath.addAll(configurator.getTaxonPropertyPath()); + } + if ((configurator.isDoTaxa() && configurator.isDoSynonyms())) { + clazz = TaxonBase.class; + //propertyPath.addAll(configurator.getTaxonPropertyPath()); + //propertyPath.addAll(configurator.getSynonymPropertyPath()); + } else if(configurator.isDoTaxa()) { + clazz = Taxon.class; + //propertyPath = configurator.getTaxonPropertyPath(); + } else if (configurator.isDoSynonyms()) { + clazz = Synonym.class; + //propertyPath = configurator.getSynonymPropertyPath(); + } + + if(clazz != null){ + if(configurator.getPageSize() != null){ // no point counting if we need all anyway + numberTaxaResults = + dao.countTaxaByName(clazz, + configurator.getSearchString(), configurator.getClassification(), configurator.getMatchMode(), + configurator.getNamedAreas()); + } + if(configurator.getPageSize() == null || numberTaxaResults > configurator.getPageSize() * configurator.getPageNumber()){ // no point checking again if less results + taxa = dao.getTaxaByName(clazz, + configurator.getSearchString(), configurator.getClassification(), configurator.getMatchMode(), + configurator.getNamedAreas(), configurator.getPageSize(), + configurator.getPageNumber(), propertyPath); } } - if(configurator.isDoSynonyms()) { - int numberSynonymResults = dao.countTaxaByName(configurator.getSearchString(), configurator.getMatchMode(), - false); - List synonyms = - dao.getTaxaByName(configurator.getSearchString(), configurator.getMatchMode(), - false, configurator.getPageSize(), configurator.getPageNumber()); -// dao.getTaxaByName(configurator.getSearchString(), false, configurator.getSec()); - if (logger.isDebugEnabled()) { logger.debug(synonyms.size() + " matching synonym(s) counted"); } - if (synonyms.size() > 0) { - results.addAll(synonyms); - numberOfResults += numberSynonymResults; - } + if (logger.isDebugEnabled()) { logger.debug(numberTaxaResults + " matching taxa counted"); } + + if(taxa != null){ + results.addAll(taxa); } + + numberOfResults += numberTaxaResults; + // Names without taxa if (configurator.isDoNamesWithoutTaxa()) { - int numberNameResults = nameDao.countByName(configurator.getSearchString(), configurator.getMatchMode(), null); + int numberNameResults = 0; + List> names = nameDao.findByName(configurator.getSearchString(), configurator.getMatchMode(), - configurator.getPageSize(), configurator.getPageNumber(), null); + configurator.getPageSize(), configurator.getPageNumber(), null, configurator.getTaxonNamePropertyPath()); if (logger.isDebugEnabled()) { logger.debug(names.size() + " matching name(s) found"); } if (names.size() > 0) { for (TaxonNameBase taxonName : names) { @@ -394,32 +496,191 @@ public class TaxonServiceImpl extends IdentifiableServiceBase commonTaxonNames = - descriptionDao.searchDescriptionByCommonName(configurator.getSearchString(), - configurator.getMatchMode(), configurator.getPageSize(), configurator.getPageNumber()); - if (logger.isDebugEnabled()) { logger.debug(commonTaxonNames.size() + " matching common name(s) found"); } - if (commonTaxonNames.size() > 0) { - for (CommonTaxonName commonTaxonName : commonTaxonNames) { - DescriptionBase description = commonTaxonName.getInDescription(); - description = HibernateProxyHelper.deproxy(description, DescriptionBase.class); - if (description instanceof TaxonDescription) { - Taxon taxon = ((TaxonDescription)description).getTaxon(); - results.add(taxon); - numberCommonNameResults++; + taxa = null; + numberTaxaResults = 0; + if(configurator.getPageSize() != null){// no point counting if we need all anyway + numberTaxaResults = dao.countTaxaByCommonName(configurator.getSearchString(), configurator.getClassification(), configurator.getMatchMode(), configurator.getNamedAreas()); + } + if(configurator.getPageSize() == null || numberTaxaResults > configurator.getPageSize() * configurator.getPageNumber()){ + taxa = dao.getTaxaByCommonName(configurator.getSearchString(), configurator.getClassification(), configurator.getMatchMode(), configurator.getNamedAreas(), configurator.getPageSize(), configurator.getPageNumber(), configurator.getTaxonPropertyPath()); + } + if(taxa != null){ + results.addAll(taxa); + } + numberOfResults += numberTaxaResults; + + } + + return new DefaultPagerImpl + (configurator.getPageNumber(), numberOfResults, configurator.getPageSize(), results); + } + + public List> getTaxonUuidAndTitleCache(){ + return dao.getUuidAndTitleCache(); + } + + public List getAllMedia(Taxon taxon, int size, int height, int widthOrDuration, String[] mimeTypes){ + List medRep = new ArrayList(); + taxon = (Taxon)dao.load(taxon.getUuid()); + Set descriptions = taxon.getDescriptions(); + for (TaxonDescription taxDesc: descriptions){ + Set elements = taxDesc.getElements(); + for (DescriptionElementBase descElem: elements){ + for(Media media : descElem.getMedia()){ + + //find the best matching representation + medRep.add(MediaUtils.findBestMatchingRepresentation(media, size, height, widthOrDuration, mimeTypes)); + + } + } + } + return medRep; + } + + public List findTaxaByID(Set listOfIDs) { + return this.dao.findById(listOfIDs); + } + + public int countAllRelationships() { + return this.dao.countAllRelationships(); + } + + public List createAllInferredSynonyms(Classification tree, + Taxon taxon) { + + return this.dao.createAllInferredSynonyms(taxon, tree); + } + + public List createInferredSynonyms(Classification tree, Taxon taxon, SynonymRelationshipType type) { + + return this.dao.createInferredSynonyms(taxon, tree, type); + } + + public List findIdenticalTaxonNames(List propertyPath) { + + return this.dao.findIdenticalTaxonNames(propertyPath); + } + + public List findIdenticalTaxonNameIds(List propertyPath) { + + return this.dao.findIdenticalNamesNew(propertyPath); + } + + public String getPhylumName(TaxonNameBase name){ + return this.dao.getPhylumName(name); + } + + private class TaxonAndNameComparator implements Comparator{ + + public int compare(Object arg0, Object arg1) { + IdentifiableEntity castArg0 = (IdentifiableEntity) arg0; + IdentifiableEntity castArg1 = (IdentifiableEntity) arg1; + return castArg0.compareTo(castArg1); + } + + } + + public long deleteSynonymRelationships(Synonym syn) { + + return dao.deleteSynonymRelationships(syn); + } + + + public List listSynonymRelationships( + TaxonBase taxonBase, SynonymRelationshipType type, Integer pageSize, Integer pageNumber, + List orderHints, List propertyPaths, Direction direction) { + Integer numberOfResults = dao.countSynonymRelationships(taxonBase, type, direction); + + List results = new ArrayList(); + if(numberOfResults > 0) { // no point checking again + results = dao.getSynonymRelationships(taxonBase, type, pageSize, pageNumber, orderHints, propertyPaths, direction); + } + return results; + } + + /* (non-Javadoc) + * @see eu.etaxonomy.cdm.api.service.ITaxonService#matchToTaxon(eu.etaxonomy.cdm.model.name.NonViralName) + */ + @Override + public Taxon findBestMatchingTaxon(String taxonName) { + + Taxon matchedTaxon = null; + try{ + // 1. search for acceptet taxa + List taxonList = dao.findByNameTitleCache(Taxon.class, taxonName, null, MatchMode.EXACT, null, 0, null, null); + for(IdentifiableEntity taxonBaseCandidate : taxonList){ + if(taxonBaseCandidate instanceof Taxon){ + matchedTaxon = (Taxon)taxonBaseCandidate; + if(taxonList.size() > 1){ + logger.info(taxonList.size() + " TaxonBases found, using first accepted Taxon: " + matchedTaxon.getTitleCache()); + return matchedTaxon; } else { - logger.warn("Description of " + commonTaxonName.getName() + " is not an instance of TaxonDescription"); + logger.info("using accepted Taxon: " + matchedTaxon.getTitleCache()); + return matchedTaxon; + } + //TODO extend method: search using treeUUID, using SecUUID, first find accepted then include synonyms until a matching taxon is found + } + } + + // 2. search for synonyms + List synonymList = dao.findByNameTitleCache(Synonym.class, taxonName, null, MatchMode.EXACT, null, 0, null, null); + for(TaxonBase taxonBase : synonymList){ + if(taxonBase instanceof Synonym){ + Set acceptetdCandidates = ((Synonym)taxonBase).getAcceptedTaxa(); + if(!acceptetdCandidates.isEmpty()){ + matchedTaxon = acceptetdCandidates.iterator().next(); + if(acceptetdCandidates.size() == 1){ + logger.info(acceptetdCandidates.size() + " Accepted taxa found for synonym " + taxonBase.getTitleCache() + ", using first one: " + matchedTaxon.getTitleCache()); + return matchedTaxon; + } else { + logger.info("using accepted Taxon " + matchedTaxon.getTitleCache() + "for synonym " + taxonBase.getTitleCache()); + return matchedTaxon; + } + //TODO extend method: search using treeUUID, using SecUUID, first find accepted then include synonyms until a matching taxon is found } } - numberOfResults += numberCommonNameResults; - } + } + + } catch (Exception e){ + logger.error(e); } - Collections.sort(results); - return new DefaultPagerImpl - (configurator.getPageNumber(), numberOfResults, configurator.getPageSize(), results); + return matchedTaxon; } + @Override + public Synonym findBestMatchingSynonym(String taxonName) { + List synonymList = dao.findByNameTitleCache(Synonym.class, taxonName, null, MatchMode.EXACT, null, 0, null, null); + if(! synonymList.isEmpty()){ + Synonym result = CdmBase.deproxy(synonymList.iterator().next(), Synonym.class); + if(synonymList.size() == 1){ + logger.info(synonymList.size() + " Synonym found " + result.getTitleCache() ); + return result; + } else { + logger.info("Several matching synonyms found. Using first: " + result.getTitleCache()); + return result; + } + } + return null; + } + + /* (non-Javadoc) + * @see eu.etaxonomy.cdm.api.service.ITaxonService#moveSynonymToAnotherTaxon(eu.etaxonomy.cdm.model.taxon.SynonymRelationship, eu.etaxonomy.cdm.model.taxon.Taxon, eu.etaxonomy.cdm.model.reference.Reference, java.lang.String) + */ + @Override + public Taxon moveSynonymToAnotherTaxon(SynonymRelationship synonymRelation, + Taxon toTaxon, SynonymRelationshipType synonymRelationshipType, Reference reference, String referenceDetail) { + Taxon fromTaxon = synonymRelation.getAcceptedTaxon(); + + fromTaxon.removeSynonymRelation(synonymRelation); + + toTaxon.addSynonym(synonymRelation.getSynonym(), synonymRelationshipType); + + return toTaxon; + } + + }