// $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
package eu.etaxonomy.cdm.api.service;\r
\r
import java.util.ArrayList;\r
-import java.util.Collection;\r
-import java.util.Collections;\r
-import java.util.Comparator;\r
-\r
import java.util.HashSet;\r
import java.util.List;\r
-import java.util.Map;\r
import java.util.Set;\r
-import java.util.TreeMap;\r
import java.util.UUID;\r
-import java.util.Map.Entry;\r
+\r
+import junit.framework.Assert;\r
\r
import org.apache.log4j.Logger;\r
-import org.hibernate.Hibernate;\r
import org.springframework.beans.factory.annotation.Autowired;\r
import org.springframework.stereotype.Service;\r
-import org.springframework.transaction.TransactionStatus;\r
+import org.springframework.transaction.annotation.Propagation;\r
import org.springframework.transaction.annotation.Transactional;\r
\r
import eu.etaxonomy.cdm.api.service.config.ITaxonServiceConfigurator;\r
+import eu.etaxonomy.cdm.api.service.config.MatchingTaxonConfigurator;\r
+import eu.etaxonomy.cdm.api.service.config.NameDeletionConfigurator;\r
+import eu.etaxonomy.cdm.api.service.exception.DataChangeNoRollbackException;\r
+import eu.etaxonomy.cdm.api.service.exception.HomotypicalGroupChangeException;\r
import eu.etaxonomy.cdm.api.service.pager.Pager;\r
import eu.etaxonomy.cdm.api.service.pager.impl.DefaultPagerImpl;\r
-import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;\r
+import eu.etaxonomy.cdm.common.monitor.IProgressMonitor;\r
+import eu.etaxonomy.cdm.model.common.CdmBase;\r
import eu.etaxonomy.cdm.model.common.IdentifiableEntity;\r
import eu.etaxonomy.cdm.model.common.OrderedTermVocabulary;\r
import eu.etaxonomy.cdm.model.common.RelationshipBase;\r
+import eu.etaxonomy.cdm.model.common.RelationshipBase.Direction;\r
import eu.etaxonomy.cdm.model.common.UuidAndTitleCache;\r
-import eu.etaxonomy.cdm.model.description.CommonTaxonName;\r
-import eu.etaxonomy.cdm.model.description.DescriptionBase;\r
import eu.etaxonomy.cdm.model.description.DescriptionElementBase;\r
import eu.etaxonomy.cdm.model.description.TaxonDescription;\r
import eu.etaxonomy.cdm.model.media.Media;\r
import eu.etaxonomy.cdm.model.media.MediaRepresentation;\r
+import eu.etaxonomy.cdm.model.media.MediaUtils;\r
import eu.etaxonomy.cdm.model.name.HomotypicalGroup;\r
import eu.etaxonomy.cdm.model.name.Rank;\r
import eu.etaxonomy.cdm.model.name.TaxonNameBase;\r
-import eu.etaxonomy.cdm.model.reference.ReferenceBase;\r
+import eu.etaxonomy.cdm.model.reference.Reference;\r
+import eu.etaxonomy.cdm.model.taxon.Classification;\r
import eu.etaxonomy.cdm.model.taxon.Synonym;\r
import eu.etaxonomy.cdm.model.taxon.SynonymRelationship;\r
import eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType;\r
import eu.etaxonomy.cdm.model.taxon.TaxonNode;\r
import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;\r
import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;\r
-import eu.etaxonomy.cdm.model.taxon.TaxonomicTree;\r
-import eu.etaxonomy.cdm.persistence.dao.BeanInitializer;\r
import eu.etaxonomy.cdm.persistence.dao.common.IOrderedTermVocabularyDao;\r
-import eu.etaxonomy.cdm.persistence.dao.description.IDescriptionDao;\r
import eu.etaxonomy.cdm.persistence.dao.name.ITaxonNameDao;\r
import eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao;\r
-import eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonNodeDao;\r
-import eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonomicTreeDao;\r
import eu.etaxonomy.cdm.persistence.fetch.CdmFetch;\r
+import eu.etaxonomy.cdm.persistence.query.MatchMode;\r
import eu.etaxonomy.cdm.persistence.query.OrderHint;\r
+import eu.etaxonomy.cdm.strategy.cache.common.IIdentifiableEntityCacheStrategy;\r
\r
\r
+/**\r
+ * @author a.kohlbecker\r
+ * @date 10.09.2010\r
+ *\r
+ */\r
@Service\r
-@Transactional(readOnly = true)\r
-public class TaxonServiceImpl extends IdentifiableServiceBase<TaxonBase,ITaxonDao> implements ITaxonService {\r
- private static final Logger logger = Logger.getLogger(TaxonServiceImpl.class);\r
+@Transactional(propagation = Propagation.SUPPORTS, readOnly = true)\r
+public class TaxonServiceImpl extends IdentifiableServiceBase<TaxonBase,ITaxonDao> implements ITaxonService{\r
+ private static final Logger logger = Logger.getLogger(TaxonServiceImpl.class);\r
\r
@Autowired\r
private ITaxonNameDao nameDao;\r
- @Autowired\r
- private ITaxonomicTreeDao taxonTreeDao;\r
- @Autowired\r
- private ITaxonNodeDao taxonNodeDao;\r
- @Autowired\r
- private ITaxonDao taxonDao;\r
- \r
- /**\r
- * FIXME Candidate for harmonization\r
- * remove commented out dao\r
- */\r
-// @Autowired\r
-// @Qualifier("nonViralNameDaoHibernateImpl")\r
-// private INonViralNameDao nonViralNameDao;\r
+\r
@Autowired\r
private IOrderedTermVocabularyDao orderedVocabularyDao;\r
- @Autowired\r
- private IDescriptionDao descriptionDao;\r
- @Autowired\r
- private BeanInitializer defaultBeanInitializer;\r
- \r
- private Comparator<? super TaxonNode> taxonNodeComparator;\r
- @Autowired\r
- public void setTaxonNodeComparator(ITaxonNodeComparator<? super TaxonNode> taxonNodeComparator){\r
- this.taxonNodeComparator = (Comparator<? super TaxonNode>) taxonNodeComparator;\r
- }\r
\r
+ @Autowired\r
+ private INameService nameService;\r
\r
/**\r
* Constructor\r
public TaxonServiceImpl(){\r
if (logger.isDebugEnabled()) { logger.debug("Load TaxonService Bean"); }\r
}\r
- \r
- /**\r
- * FIXME Candidate for harmonization\r
- * find\r
- * (non-Javadoc)\r
- * @see eu.etaxonomy.cdm.api.service.ITaxonService#getTaxonByUuid(java.util.UUID)\r
- */\r
- public TaxonBase getTaxonByUuid(UUID uuid) {\r
- return super.findByUuid(uuid);\r
- }\r
- \r
- /**\r
- * FIXME Candidate for harmonization\r
- * move to taxonTreeService\r
+\r
+ /**\r
+ * FIXME Candidate for harmonization\r
+ * rename searchByName ?\r
+ */\r
+ public List<TaxonBase> searchTaxaByName(String name, Reference sec) {\r
+ return dao.getTaxaByName(name, sec);\r
+ }\r
+\r
+ /**\r
+ * FIXME Candidate for harmonization\r
+ * list(Synonym.class, ...)\r
+ * (non-Javadoc)\r
+ * @see eu.etaxonomy.cdm.api.service.ITaxonService#getAllSynonyms(int, int)\r
+ */\r
+ public List<Synonym> getAllSynonyms(int limit, int start) {\r
+ return dao.getAllSynonyms(limit, start);\r
+ }\r
+\r
+ /**\r
+ * FIXME Candidate for harmonization\r
+ * list(Taxon.class, ...)\r
+ * (non-Javadoc)\r
+ * @see eu.etaxonomy.cdm.api.service.ITaxonService#getAllTaxa(int, int)\r
+ */\r
+ public List<Taxon> getAllTaxa(int limit, int start) {\r
+ return dao.getAllTaxa(limit, start);\r
+ }\r
+\r
+ /**\r
+ * FIXME Candidate for harmonization\r
+ * merge with getRootTaxa(Reference sec, ..., ...)\r
+ * (non-Javadoc)\r
+ * @see eu.etaxonomy.cdm.api.service.ITaxonService#getRootTaxa(eu.etaxonomy.cdm.model.reference.Reference, boolean)\r
+ */\r
+ public List<Taxon> getRootTaxa(Reference sec, CdmFetch cdmFetch, boolean onlyWithChildren) {\r
+ if (cdmFetch == null){\r
+ cdmFetch = CdmFetch.NO_FETCH();\r
+ }\r
+ return dao.getRootTaxa(sec, cdmFetch, onlyWithChildren, false);\r
+ }\r
+\r
+\r
+ /* (non-Javadoc)\r
+ * @see eu.etaxonomy.cdm.api.service.ITaxonService#getRootTaxa(eu.etaxonomy.cdm.model.name.Rank, eu.etaxonomy.cdm.model.reference.Reference, boolean, boolean)\r
+ */\r
+ public List<Taxon> getRootTaxa(Rank rank, Reference sec, boolean onlyWithChildren,boolean withMisapplications, List<String> propertyPaths) {\r
+ return dao.getRootTaxa(rank, sec, null, onlyWithChildren, withMisapplications, propertyPaths);\r
+ }\r
+\r
+ /* (non-Javadoc)\r
+ * @see eu.etaxonomy.cdm.api.service.ITaxonService#getAllRelationships(int, int)\r
+ */\r
+ public List<RelationshipBase> getAllRelationships(int limit, int start){\r
+ return dao.getAllRelationships(limit, start);\r
+ }\r
+\r
+ /**\r
+ * FIXME Candidate for harmonization\r
+ * is this the same as termService.getVocabulary(VocabularyEnum.TaxonRelationshipType) ?\r
+ */\r
+ @Deprecated\r
+ public OrderedTermVocabulary<TaxonRelationshipType> getTaxonRelationshipTypeVocabulary() {\r
+\r
+ String taxonRelTypeVocabularyId = "15db0cf7-7afc-4a86-a7d4-221c73b0c9ac";\r
+ UUID uuid = UUID.fromString(taxonRelTypeVocabularyId);\r
+ OrderedTermVocabulary<TaxonRelationshipType> taxonRelTypeVocabulary =\r
+ (OrderedTermVocabulary)orderedVocabularyDao.findByUuid(uuid);\r
+ return taxonRelTypeVocabulary;\r
+ }\r
+\r
+ \r
+ \r
+ /*\r
* (non-Javadoc)\r
- * @see eu.etaxonomy.cdm.api.service.ITaxonService#getTaxonNodeByUuid(java.util.UUID)\r
- */\r
- public TaxonNode getTaxonNodeByUuid(UUID uuid) {\r
- return taxonNodeDao.findByUuid(uuid);\r
- }\r
- /**\r
- * FIXME Candidate for harmonization\r
- * move to taxonTreeService\r
- */\r
- public TaxonNode loadTaxonNodeByTaxon(Taxon taxon, UUID taxonomicTreeUuid, List<String> propertyPaths){\r
- TaxonomicTree tree = taxonTreeDao.load(taxonomicTreeUuid);\r
- TaxonNode node = tree.getNode(taxon);\r
- defaultBeanInitializer.initialize(node, propertyPaths);\r
- return node;\r
- }\r
- /**\r
- * FIXME Candidate for harmonization\r
- * move to taxonTreeService \r
+ * @see eu.etaxonomy.cdm.api.service.ITaxonService#swapSynonymWithAcceptedTaxon(eu.etaxonomy.cdm.model.taxon.Synonym)\r
*/\r
- public List<TaxonNode> loadRankSpecificRootNodes(TaxonomicTree taxonomicTree, Rank rank, List<String> propertyPaths){\r
- TaxonomicTree tree = taxonTreeDao.load(taxonomicTree.getUuid());\r
- \r
- List<TaxonNode> rootNodes = tree.getRankSpecificRootNodes(rank);\r
- //sort nodes by TaxonName\r
+ @Transactional(readOnly = false)\r
+ public void swapSynonymAndAcceptedTaxon(Synonym synonym, Taxon acceptedTaxon){\r
\r
- Collections.sort(rootNodes, taxonNodeComparator);\r
+ TaxonNameBase<?,?> synonymName = synonym.getName();\r
+ synonymName.removeTaxonBase(synonym);\r
+ TaxonNameBase<?,?> taxonName = acceptedTaxon.getName();\r
+ taxonName.removeTaxonBase(acceptedTaxon);\r
\r
- // initialize all nodes\r
- defaultBeanInitializer.initializeAll(rootNodes, propertyPaths);\r
+ synonym.setName(taxonName);\r
+ acceptedTaxon.setName(synonymName);\r
\r
- return rootNodes;\r
+ // the accepted taxon needs a new uuid because the concept has changed\r
+ // FIXME this leads to an error "HibernateException: immutable natural identifier of an instance of eu.etaxonomy.cdm.model.taxon.Taxon was altered"\r
+ //acceptedTaxon.setUuid(UUID.randomUUID());\r
}\r
+\r
\r
- /**\r
- * (non-Javadoc)\r
- * @see eu.etaxonomy.cdm.api.service.ITaxonService#loadTreeBranchTo(eu.etaxonomy.cdm.model.taxon.TaxonNode, eu.etaxonomy.cdm.model.name.Rank, java.util.List)\r
- * FIXME Candidate for harmonization\r
- * move to taxonTreeService\r
+ /* (non-Javadoc)\r
+ * @see eu.etaxonomy.cdm.api.service.ITaxonService#changeSynonymToAcceptedTaxon(eu.etaxonomy.cdm.model.taxon.Synonym, eu.etaxonomy.cdm.model.taxon.Taxon)\r
*/\r
- public List<TaxonNode> loadTreeBranchTo(TaxonNode taxonNode, Rank baseRank, List<String> propertyPaths){\r
+ //TODO correct delete handling still needs to be implemented / checked\r
+ @Override\r
+ @Transactional(readOnly = false)\r
+ public Taxon changeSynonymToAcceptedTaxon(Synonym synonym, Taxon acceptedTaxon, boolean deleteSynonym, boolean copyCitationInfo, Reference citation, String microCitation) throws HomotypicalGroupChangeException{\r
\r
- TaxonNode thisNode = taxonNodeDao.load(taxonNode.getUuid(), propertyPaths);\r
- List<TaxonNode> pathToRoot = new ArrayList<TaxonNode>();\r
- pathToRoot.add(thisNode);\r
+ TaxonNameBase<?,?> acceptedName = acceptedTaxon.getName();\r
+ TaxonNameBase<?,?> synonymName = synonym.getName();\r
+ HomotypicalGroup synonymHomotypicGroup = synonymName.getHomotypicalGroup();\r
\r
- TaxonNode parentNode = thisNode.getParent();\r
- while(parentNode != null){\r
- Rank parentNodeRank = parentNode.getTaxon().getName().getRank();\r
- // stop if the next parent is higher than the baseRank\r
- if(baseRank != null && baseRank.isLower(parentNodeRank)){\r
- break;\r
- }\r
- pathToRoot.add(parentNode);\r
- parentNode = parentNode.getParent();\r
+ //check synonym is not homotypic\r
+ if (acceptedName.getHomotypicalGroup().equals(synonymHomotypicGroup)){\r
+ String message = "The accepted taxon and the synonym are part of the same homotypical group and therefore can not be both accepted.";\r
+ throw new HomotypicalGroupChangeException(message);\r
}\r
\r
- // initialize and invert order of nodes in list\r
- defaultBeanInitializer.initializeAll(pathToRoot, propertyPaths);\r
- Collections.reverse(pathToRoot);\r
- \r
- return pathToRoot;\r
- }\r
- \r
- /**\r
- * FIXME Candidate for harmonization\r
- * move to taxonTreeService\r
- */\r
- public List<TaxonNode> loadTreeBranchToTaxon(Taxon taxon, TaxonomicTree taxonomicTree, Rank baseRank, List<String> propertyPaths){\r
- TaxonomicTree tree = taxonTreeDao.load(taxonomicTree.getUuid());\r
- taxon = (Taxon)dao.load(taxon.getUuid());\r
- TaxonNode node = tree.getNode(taxon);\r
- if(node == null){\r
- logger.warn("The specified tacon is not found in the given tree.");\r
- return null;\r
- }\r
- return loadTreeBranchTo(node, baseRank, propertyPaths);\r
- }\r
- \r
- /**\r
- * FIXME Candidate for harmonization\r
- * move to taxonTreeService\r
- */\r
- public List<TaxonNode> loadChildNodesOfTaxon(Taxon taxon, TaxonomicTree taxonomicTree, List<String> propertyPaths){\r
- TaxonomicTree tree = taxonTreeDao.load(taxonomicTree.getUuid());\r
- taxon = (Taxon)dao.load(taxon.getUuid());\r
- List<TaxonNode> childNodes = new ArrayList<TaxonNode>();\r
- childNodes.addAll(tree.getNode(taxon).getChildNodes());\r
- Collections.sort(childNodes, taxonNodeComparator);\r
- defaultBeanInitializer.initializeAll(childNodes, propertyPaths);\r
- return childNodes;\r
- }\r
-\r
- /**\r
- * FIXME Candidate for harmonization\r
- * save\r
- * (non-Javadoc)\r
- * @see eu.etaxonomy.cdm.api.service.ITaxonService#saveTaxon(eu.etaxonomy.cdm.model.taxon.TaxonBase)\r
- */\r
- @Transactional(readOnly = false)\r
- public UUID saveTaxon(TaxonBase taxon) {\r
- return super.saveCdmObject(taxon);\r
- }\r
- \r
- /**\r
- * FIXME Candidate for harmonization\r
- * move to taxonTreeService\r
- * (non-Javadoc)\r
- * @see eu.etaxonomy.cdm.api.service.ITaxonService#saveTaxonNode(eu.etaxonomy.cdm.model.taxon.TaxonNode)\r
- */\r
- @Transactional(readOnly = false)\r
- public UUID saveTaxonNode(TaxonNode taxonNode) {\r
- return taxonNodeDao.save(taxonNode);\r
- }\r
-\r
- /**\r
- * FIXME Candidate for harmonization\r
- * this method seems redundant, remove\r
- * @param taxon\r
- * @param txStatus\r
- * @return\r
- */\r
- //@Transactional(readOnly = false)\r
- public UUID saveTaxon(TaxonBase taxon, TransactionStatus txStatus) {\r
- //return super.saveCdmObject(taxon, txStatus);\r
- return super.saveCdmObject(taxon);\r
- }\r
- \r
- \r
- /**\r
- * FIXME Candidate for harmonization\r
- * save(Set<Taxon> taxa)\r
- * (non-Javadoc)\r
- * @see eu.etaxonomy.cdm.api.service.ITaxonService#saveTaxonAll(java.util.Collection)\r
- */\r
- @Transactional(readOnly = false)\r
- public Map<UUID, ? extends TaxonBase> saveTaxonAll(Collection<? extends TaxonBase> taxonCollection){\r
- return saveCdmObjectAll(taxonCollection);\r
- }\r
- \r
- /**\r
- * FIXME Candidate for harmonization\r
- * move to taxonTreeService\r
- */\r
- public Map<UUID, TaxonNode> saveTaxonNodeAll(\r
- Collection<TaxonNode> taxonNodeCollection) {\r
- return taxonNodeDao.saveAll(taxonNodeCollection);\r
- }\r
-\r
- /**\r
- * FIXME Candidate for harmonization\r
- * delete\r
- * (non-Javadoc)\r
- * @see eu.etaxonomy.cdm.api.service.ITaxonService#removeTaxon(eu.etaxonomy.cdm.model.taxon.TaxonBase)\r
- */\r
- @Transactional(readOnly = false)\r
- public UUID removeTaxon(TaxonBase taxon) {\r
- return super.removeCdmObject(taxon);\r
- }\r
-\r
- /**\r
- * FIXME Candidate for harmonization\r
- * rename searchByName ? \r
- */\r
- public List<TaxonBase> searchTaxaByName(String name, ReferenceBase sec) {\r
- return dao.getTaxaByName(name, sec);\r
- }\r
-\r
- /**\r
- * FIXME Candidate for harmonization\r
- * list\r
- * (non-Javadoc)\r
- * @see eu.etaxonomy.cdm.api.service.ITaxonService#getAllTaxonBases(int, int)\r
- */\r
- public List<TaxonBase> getAllTaxonBases(int limit, int start){\r
- return dao.list(limit, start);\r
- }\r
-\r
- /**\r
- * FIXME Candidate for harmonization\r
- * list\r
- * (non-Javadoc)\r
- * @see eu.etaxonomy.cdm.api.service.ITaxonService#getAllTaxa(int, int)\r
- */\r
- public List<Taxon> getAllTaxa(int limit, int start){\r
- return dao.getAllTaxa(limit, start);\r
- }\r
- \r
- /**\r
- * FIXME Candidate for harmonization\r
- * list(Synonym.class, ...)\r
- * (non-Javadoc)\r
- * @see eu.etaxonomy.cdm.api.service.ITaxonService#getAllSynonyms(int, int)\r
- */\r
- public List<Synonym> getAllSynonyms(int limit, int start) {\r
- return dao.getAllSynonyms(limit, start);\r
- }\r
-\r
-\r
- /**\r
- * FIXME Candidate for harmonization\r
- * move to taxonTreeService\r
- * (non-Javadoc)\r
- * @see eu.etaxonomy.cdm.api.service.ITaxonService#getAllTaxonomicTrees(int, int)\r
- * \r
- */\r
- @Deprecated\r
- public List<TaxonomicTree> getAllTaxonomicTrees(int limit, int start) {\r
- return taxonTreeDao.list(limit, start);\r
- }\r
- \r
- /**\r
- * FIXME Candidate for harmonization\r
- * taxonTreeService.list\r
- */\r
- public List<TaxonomicTree> listTaxonomicTrees(Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {\r
- return taxonTreeDao.list(limit, start, orderHints, propertyPaths);\r
- } \r
-\r
- /**\r
- * FIXME Candidate for harmonization\r
- * taxonTreeService.find\r
- * (non-Javadoc)\r
- * @see eu.etaxonomy.cdm.api.service.ITaxonService#getTaxonomicTreeByUuid(java.util.UUID)\r
- */\r
- public TaxonomicTree getTaxonomicTreeByUuid(UUID uuid){\r
- return taxonTreeDao.findByUuid(uuid);\r
- }\r
- \r
- /**\r
- * FIXME Candidate for harmonization\r
- * taxonTreeService.delete\r
- * (non-Javadoc)\r
- * @see eu.etaxonomy.cdm.api.service.ITaxonService#removeTaxonomicTree(java.util.UUID)\r
- */\r
- @Transactional(readOnly = false)\r
- public UUID removeTaxonomicTree(TaxonomicTree taxonomicTree) {\r
- return taxonTreeDao.delete(taxonomicTree);\r
- }\r
- \r
- /**\r
- * FIXME Candidate for harmonization\r
- * taxonTreeService.save\r
- * (non-Javadoc)\r
- * @see eu.etaxonomy.cdm.api.service.ITaxonService#saveTaxonomicTree(eu.etaxonomy.cdm.model.taxon.TaxonomicTree)\r
- */\r
- @Transactional(readOnly = false)\r
- public UUID saveTaxonomicTree(TaxonomicTree tree){\r
- return taxonTreeDao.saveOrUpdate(tree);\r
- }\r
-\r
- /**\r
- * FIXME Candidate for harmonization\r
- * merge with getRootTaxa(ReferenceBase sec, ..., ...)\r
- * (non-Javadoc)\r
- * @see eu.etaxonomy.cdm.api.service.ITaxonService#getRootTaxa(eu.etaxonomy.cdm.model.reference.ReferenceBase)\r
- */\r
- public List<Taxon> getRootTaxa(ReferenceBase sec){\r
- return getRootTaxa(sec, CdmFetch.FETCH_CHILDTAXA(), true);\r
- }\r
-\r
- /**\r
- * FIXME Candidate for harmonization\r
- * merge with getRootTaxa(ReferenceBase sec, ..., ...)\r
- * (non-Javadoc)\r
- * @see eu.etaxonomy.cdm.api.service.ITaxonService#getRootTaxa(eu.etaxonomy.cdm.model.reference.ReferenceBase, boolean)\r
- */\r
- public List<Taxon> getRootTaxa(ReferenceBase sec, CdmFetch cdmFetch, boolean onlyWithChildren) {\r
- if (cdmFetch == null){\r
- cdmFetch = CdmFetch.NO_FETCH();\r
- }\r
- return dao.getRootTaxa(sec, cdmFetch, onlyWithChildren, false);\r
- }\r
- \r
- /**\r
- * FIXME Candidate for harmonization\r
- * merge with getRootTaxa(ReferenceBase sec, ..., ...)\r
- * (non-Javadoc)\r
- * @see eu.etaxonomy.cdm.api.service.ITaxonService#getRootTaxa(eu.etaxonomy.cdm.model.reference.ReferenceBase, boolean, boolean)\r
- */\r
- public List<Taxon> getRootTaxa(ReferenceBase sec, boolean onlyWithChildren,\r
- boolean withMisapplications) {\r
- return dao.getRootTaxa(sec, null, onlyWithChildren, withMisapplications);\r
- }\r
-\r
- /* (non-Javadoc)\r
- * @see eu.etaxonomy.cdm.api.service.ITaxonService#getRootTaxa(eu.etaxonomy.cdm.model.name.Rank, eu.etaxonomy.cdm.model.reference.ReferenceBase, boolean, boolean)\r
- */\r
- public List<Taxon> getRootTaxa(Rank rank, ReferenceBase sec, boolean onlyWithChildren,\r
- boolean withMisapplications, List<String> propertyPaths) {\r
- return dao.getRootTaxa(rank, sec, null, onlyWithChildren, withMisapplications, propertyPaths);\r
- }\r
-\r
- public List<RelationshipBase> getAllRelationships(int limit, int start){\r
- return dao.getAllRelationships(limit, start);\r
- }\r
- \r
- \r
- \r
- /**\r
- * FIXME Candidate for harmonization\r
- * is this the same as termService.getVocabulary(VocabularyEnum.TaxonRelationshipType) ? \r
- */\r
- @Deprecated\r
- public OrderedTermVocabulary<TaxonRelationshipType> getTaxonRelationshipTypeVocabulary() {\r
+ Taxon newAcceptedTaxon = Taxon.NewInstance(synonymName, acceptedTaxon.getSec());\r
\r
- String taxonRelTypeVocabularyId = "15db0cf7-7afc-4a86-a7d4-221c73b0c9ac";\r
- UUID uuid = UUID.fromString(taxonRelTypeVocabularyId);\r
- OrderedTermVocabulary<TaxonRelationshipType> taxonRelTypeVocabulary = \r
- (OrderedTermVocabulary)orderedVocabularyDao.findByUuid(uuid);\r
- return taxonRelTypeVocabulary;\r
- }\r
-\r
- /* (non-Javadoc)\r
- * @see eu.etaxonomy.cdm.api.service.ITaxonService#makeTaxonSynonym(eu.etaxonomy.cdm.model.taxon.Taxon, eu.etaxonomy.cdm.model.taxon.Taxon)\r
- */\r
- @Transactional(readOnly = false)\r
- public Synonym makeTaxonSynonym(Taxon oldTaxon, Taxon newAcceptedTaxon, SynonymRelationshipType synonymRelationshipType, ReferenceBase citation, String citationMicroReference) {\r
- if (oldTaxon == null || newAcceptedTaxon == null || oldTaxon.getName() == null){\r
- throw new IllegalArgumentException();\r
- }\r
+ SynonymRelationshipType relTypeForGroup = SynonymRelationshipType.HOMOTYPIC_SYNONYM_OF();\r
+ List<Synonym> heteroSynonyms = acceptedTaxon.getSynonymsInGroup(synonymHomotypicGroup);\r
\r
- // Move oldTaxon to newTaxon\r
- TaxonNameBase<?,?> synonymName = oldTaxon.getName();\r
- if (synonymRelationshipType == null){\r
- if (synonymName.isHomotypic(newAcceptedTaxon.getName())){\r
- synonymRelationshipType = SynonymRelationshipType.HOMOTYPIC_SYNONYM_OF();\r
+ for (Synonym heteroSynonym : heteroSynonyms){\r
+ if (synonym.equals(heteroSynonym)){\r
+ acceptedTaxon.removeSynonym(heteroSynonym, false);\r
}else{\r
- //TODO synonymType \r
- synonymRelationshipType = SynonymRelationshipType.HETEROTYPIC_SYNONYM_OF();\r
+ //move synonyms in same homotypic group to new accepted taxon\r
+ heteroSynonym.replaceAcceptedTaxon(newAcceptedTaxon, relTypeForGroup, copyCitationInfo, citation, microCitation);\r
}\r
}\r
- SynonymRelationship synRel = newAcceptedTaxon.addSynonymName(synonymName, synonymRelationshipType, citation, citationMicroReference);\r
- \r
- //Move Synonym Relations to new Taxon\r
- for(SynonymRelationship synRelation : oldTaxon.getSynonymRelations()){\r
- newAcceptedTaxon.addSynonym(synRelation.getSynonym(), synRelation.getType(), \r
- synRelation.getCitation(), synRelation.getCitationMicroReference());\r
- }\r
\r
- //Move Taxon RelationShips to new Taxon\r
- Set<TaxonRelationship> removableTaxonRels = new HashSet<TaxonRelationship>();\r
- for(TaxonRelationship taxonRelation : oldTaxon.getTaxonRelations()){\r
- //CHILDREN\r
- if (taxonRelation.getType().equals(TaxonRelationshipType.TAXONOMICALLY_INCLUDED_IN())){\r
- if (taxonRelation.getFromTaxon() == oldTaxon){\r
- removableTaxonRels.add(taxonRelation);\r
-// oldTaxon.removeTaxonRelation(taxonRelation);\r
- }else if(taxonRelation.getToTaxon() == oldTaxon){\r
- newAcceptedTaxon.addTaxonomicChild(taxonRelation.getFromTaxon(), taxonRelation.getCitation(), taxonRelation.getCitationMicroReference());\r
- removableTaxonRels.add(taxonRelation);\r
-// oldTaxon.removeTaxonRelation(taxonRelation);\r
- }else{\r
- logger.warn("Taxon is not part of its own Taxonrelationship");\r
- }\r
+ //synonym.getName().removeTaxonBase(synonym);\r
+ //TODO correct delete handling still needs to be implemented / checked\r
+ if (deleteSynonym){\r
+// deleteSynonym(synonym, taxon, false);\r
+ try {\r
+ this.dao.flush();\r
+ this.delete(synonym);\r
+ \r
+ } catch (Exception e) {\r
+ logger.info("Can't delete old synonym from database");\r
}\r
- //MISAPPLIED NAMES\r
- if (taxonRelation.getType().equals(TaxonRelationshipType.MISAPPLIED_NAME_FOR())){\r
- if (taxonRelation.getFromTaxon() == oldTaxon){\r
- newAcceptedTaxon.addMisappliedName(taxonRelation.getToTaxon(), taxonRelation.getCitation(), taxonRelation.getCitationMicroReference());\r
- removableTaxonRels.add(taxonRelation);\r
-// oldTaxon.removeTaxonRelation(taxonRelation);\r
- }else if(taxonRelation.getToTaxon() == oldTaxon){\r
- newAcceptedTaxon.addMisappliedName(taxonRelation.getFromTaxon(), taxonRelation.getCitation(), taxonRelation.getCitationMicroReference());\r
- removableTaxonRels.add(taxonRelation);\r
-// oldTaxon.removeTaxonRelation(taxonRelation);\r
- }else{\r
- logger.warn("Taxon is not part of its own Taxonrelationship");\r
- }\r
- }\r
- //Concept Relationships\r
- //FIXME implement\r
-// if (taxonRelation.getType().equals(TaxonRelationshipType.MISAPPLIEDNAMEFOR())){\r
-// if (taxonRelation.getFromTaxon() == oldTaxon){\r
-// newAcceptedTaxon.addMisappliedName(taxonRelation.getToTaxon(), taxonRelation.getCitation(), taxonRelation.getCitationMicroReference());\r
-// removableTaxonRels.add(taxonRelation);\r
-// }else if(taxonRelation.getToTaxon() == oldTaxon){\r
-// newAcceptedTaxon.addMisappliedName(taxonRelation.getFromTaxon(), taxonRelation.getCitation(), taxonRelation.getCitationMicroReference());\r
-// removableTaxonRels.add(taxonRelation);\r
-// }else{\r
-// logger.warn("Taxon is not part of its own Taxonrelationship");\r
-// }\r
-// }\r
}\r
\r
- for(TaxonRelationship taxonRel : removableTaxonRels) {\r
- oldTaxon.removeTaxonRelation(taxonRel);\r
- }\r
- \r
- //Move Descriptions to new Taxon\r
- for(TaxonDescription taxDescription : oldTaxon.getDescriptions()){\r
- newAcceptedTaxon.addDescription(taxDescription);\r
- }\r
- //delete old Taxon\r
- this.dao.saveOrUpdate(newAcceptedTaxon);\r
-// FIXME implement\r
-// this.dao.delete(oldTaxon);\r
- \r
- //return\r
-// this.dao.flush();\r
- return synRel.getSynonym();\r
+ return newAcceptedTaxon;\r
}\r
-\r
- /*\r
- * (non-Javadoc)\r
- * @see eu.etaxonomy.cdm.api.service.ITaxonService#swapSynonymWithAcceptedTaxon(eu.etaxonomy.cdm.model.taxon.Synonym)\r
- */\r
- @Transactional(readOnly = false)\r
- public void makeSynonymAcceptedTaxon(Synonym synonym, Taxon acceptedTaxon, SynonymRelationshipType synonymRelationshipType){\r
+ \r
+ \r
+ public Taxon changeSynonymToRelatedTaxon(Synonym synonym, Taxon toTaxon, TaxonRelationshipType taxonRelationshipType, Reference citation, String microcitation){\r
\r
- // create a new synonym with the old acceptedName\r
- TaxonNameBase oldAcceptedTaxonName = acceptedTaxon.getName();\r
+ // Get name from synonym\r
+ TaxonNameBase<?, ?> synonymName = synonym.getName();\r
\r
- // remove synonym from oldAcceptedTaxon\r
- acceptedTaxon.removeSynonym(synonym);\r
+ // remove synonym from taxon\r
+ toTaxon.removeSynonym(synonym);\r
\r
- // make synonym name the accepted taxons name\r
- TaxonNameBase newAcceptedTaxonName = synonym.getName();\r
- acceptedTaxon.setName(newAcceptedTaxonName);\r
+ // Create a taxon with synonym name\r
+ Taxon fromTaxon = Taxon.NewInstance(synonymName, null);\r
\r
- // add the new synonym to the acceptedTaxon\r
- if(synonymRelationshipType == null){\r
- synonymRelationshipType = SynonymRelationshipType.SYNONYM_OF();\r
- }\r
+ // Add taxon relation \r
+ fromTaxon.addTaxonRelation(toTaxon, taxonRelationshipType, citation, microcitation);\r
+ \r
+ // since we are swapping names, we have to detach the name from the synonym completely. \r
+ // Otherwise the synonym will still be in the list of typified names.\r
+ synonym.getName().removeTaxonBase(synonym);\r
\r
- acceptedTaxon.addSynonymName(oldAcceptedTaxonName, synonymRelationshipType);\r
+ return fromTaxon;\r
}\r
+ \r
\r
- public void generateTitleCache() {\r
- generateTitleCache(true);\r
- }\r
- //TODO\r
- public void generateTitleCache(boolean forceProtected) {\r
- logger.warn("generateTitleCache not yet fully implemented!");\r
-// for (TaxonBase tb : taxonDao.getAllTaxa(null,null)){\r
-// logger.warn("Old taxon title: " + tb.getTitleCache());\r
-// if (forceProtected || !tb.isProtectedTitleCache() ){\r
-// tb.setTitleCache(tb.generateTitle(), false);\r
-// taxonDao.update(tb);\r
-// logger.warn("New title: " + tb.getTitleCache());\r
-// }\r
-// }\r
- \r
- }\r
+ /* (non-Javadoc)\r
+ * @see eu.etaxonomy.cdm.api.service.ITaxonService#changeHomotypicalGroupOfSynonym(eu.etaxonomy.cdm.model.taxon.Synonym, eu.etaxonomy.cdm.model.name.HomotypicalGroup, eu.etaxonomy.cdm.model.taxon.Taxon, boolean, boolean)\r
+ */\r
+ @Transactional(readOnly = false)\r
+ @Override\r
+ public void changeHomotypicalGroupOfSynonym(Synonym synonym, HomotypicalGroup newHomotypicalGroup, Taxon targetTaxon,\r
+ boolean removeFromOtherTaxa, boolean setBasionymRelationIfApplicable){\r
+ // Get synonym name\r
+ TaxonNameBase synonymName = synonym.getName();\r
+ HomotypicalGroup oldHomotypicalGroup = synonymName.getHomotypicalGroup();\r
+\r
+\r
+ // Switch groups\r
+ oldHomotypicalGroup.removeTypifiedName(synonymName);\r
+ newHomotypicalGroup.addTypifiedName(synonymName);\r
+\r
+ //remove existing basionym relationships\r
+ synonymName.removeBasionyms();\r
+\r
+ //add basionym relationship\r
+ if (setBasionymRelationIfApplicable){\r
+ Set<TaxonNameBase> basionyms = newHomotypicalGroup.getBasionyms();\r
+ for (TaxonNameBase basionym : basionyms){\r
+ synonymName.addBasionym(basionym);\r
+ }\r
+ }\r
+\r
+ //set synonym relationship correctly\r
+// SynonymRelationship relToTaxon = null;\r
+ boolean relToTargetTaxonExists = false;\r
+ Set<SynonymRelationship> existingRelations = synonym.getSynonymRelations();\r
+ for (SynonymRelationship rel : existingRelations){\r
+ Taxon acceptedTaxon = rel.getAcceptedTaxon();\r
+ boolean isTargetTaxon = acceptedTaxon != null && acceptedTaxon.equals(targetTaxon);\r
+ HomotypicalGroup acceptedGroup = acceptedTaxon.getHomotypicGroup();\r
+ boolean isHomotypicToTaxon = acceptedGroup.equals(newHomotypicalGroup);\r
+ SynonymRelationshipType newRelationType = isHomotypicToTaxon? SynonymRelationshipType.HOMOTYPIC_SYNONYM_OF() : SynonymRelationshipType.HETEROTYPIC_SYNONYM_OF();\r
+ rel.setType(newRelationType);\r
+ //TODO handle citation and microCitation\r
+\r
+ if (isTargetTaxon){\r
+ relToTargetTaxonExists = true;\r
+ }else{\r
+ if (removeFromOtherTaxa){\r
+ acceptedTaxon.removeSynonym(synonym, false);\r
+ }else{\r
+ //do nothing\r
+ }\r
+ }\r
+ }\r
+ if (targetTaxon != null && ! relToTargetTaxonExists ){\r
+ Taxon acceptedTaxon = targetTaxon;\r
+ HomotypicalGroup acceptedGroup = acceptedTaxon.getHomotypicGroup();\r
+ boolean isHomotypicToTaxon = acceptedGroup.equals(newHomotypicalGroup);\r
+ SynonymRelationshipType relType = isHomotypicToTaxon? SynonymRelationshipType.HOMOTYPIC_SYNONYM_OF() : SynonymRelationshipType.HETEROTYPIC_SYNONYM_OF();\r
+ //TODO handle citation and microCitation\r
+ Reference citation = null;\r
+ String microCitation = null;\r
+ acceptedTaxon.addSynonym(synonym, relType, citation, microCitation);\r
+ }\r
+\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
+ public void updateTitleCache(Class<? extends TaxonBase> clazz, Integer stepSize, IIdentifiableEntityCacheStrategy<TaxonBase> cacheStrategy, IProgressMonitor monitor) {\r
+ if (clazz == null){\r
+ clazz = TaxonBase.class;\r
+ }\r
+ super.updateTitleCacheImpl(clazz, stepSize, cacheStrategy, monitor);\r
+ }\r
+\r
+ @Autowired\r
+ protected void setDao(ITaxonDao dao) {\r
+ this.dao = dao;\r
+ }\r
+\r
+ /* (non-Javadoc)\r
+ * @see eu.etaxonomy.cdm.api.service.ITaxonService#findTaxaByName(java.lang.Class, java.lang.String, java.lang.String, java.lang.String, java.lang.String, eu.etaxonomy.cdm.model.name.Rank, java.lang.Integer, java.lang.Integer)\r
+ */\r
+ public Pager<TaxonBase> findTaxaByName(Class<? extends TaxonBase> clazz, String uninomial, String infragenericEpithet, String specificEpithet, String infraspecificEpithet, Rank rank, Integer pageSize,Integer pageNumber) {\r
+ Integer numberOfResults = dao.countTaxaByName(clazz, uninomial, infragenericEpithet, specificEpithet, infraspecificEpithet, rank);\r
\r
- @Autowired\r
- protected void setDao(ITaxonDao dao) {\r
- this.dao = dao;\r
- }\r
+ List<TaxonBase> results = new ArrayList<TaxonBase>();\r
+ if(numberOfResults > 0) { // no point checking again\r
+ results = dao.findTaxaByName(clazz, uninomial, infragenericEpithet, specificEpithet, infraspecificEpithet, rank, pageSize, pageNumber);\r
+ }\r
+\r
+ return new DefaultPagerImpl<TaxonBase>(pageNumber, numberOfResults, pageSize, results);\r
+ }\r
\r
- public Pager<TaxonBase> findTaxaByName(Class<? extends TaxonBase> clazz, String uninomial, String infragenericEpithet, String specificEpithet, String infraspecificEpithet, Rank rank, Integer pageSize,Integer pageNumber) {\r
+ /* (non-Javadoc)\r
+ * @see eu.etaxonomy.cdm.api.service.ITaxonService#listTaxaByName(java.lang.Class, java.lang.String, java.lang.String, java.lang.String, java.lang.String, eu.etaxonomy.cdm.model.name.Rank, java.lang.Integer, java.lang.Integer)\r
+ */\r
+ public List<TaxonBase> listTaxaByName(Class<? extends TaxonBase> clazz, String uninomial, String infragenericEpithet, String specificEpithet, String infraspecificEpithet, Rank rank, Integer pageSize,Integer pageNumber) {\r
Integer numberOfResults = dao.countTaxaByName(clazz, uninomial, infragenericEpithet, specificEpithet, infraspecificEpithet, rank);\r
- \r
- List<TaxonBase> results = new ArrayList<TaxonBase>();\r
- if(numberOfResults > 0) { // no point checking again\r
- results = dao.findTaxaByName(clazz, uninomial, infragenericEpithet, specificEpithet, infraspecificEpithet, rank, pageSize, pageNumber); \r
- }\r
- \r
- return new DefaultPagerImpl<TaxonBase>(pageNumber, numberOfResults, pageSize, results);\r
- }\r
\r
- public List<TaxonRelationship> listToTaxonRelationships(Taxon taxon, TaxonRelationshipType type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths){\r
- Integer numberOfResults = dao.countTaxonRelationships(taxon, type, TaxonRelationship.Direction.relatedTo);\r
- \r
- List<TaxonRelationship> results = new ArrayList<TaxonRelationship>();\r
- if(numberOfResults > 0) { // no point checking again\r
- results = dao.getTaxonRelationships(taxon, type, pageSize, pageNumber, orderHints, propertyPaths, TaxonRelationship.Direction.relatedTo); \r
- }\r
- return results;\r
- }\r
- \r
- public Pager<TaxonRelationship> pageToTaxonRelationships(Taxon taxon, TaxonRelationshipType type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {\r
+ List<TaxonBase> results = new ArrayList<TaxonBase>();\r
+ if(numberOfResults > 0) { // no point checking again\r
+ results = dao.findTaxaByName(clazz, uninomial, infragenericEpithet, specificEpithet, infraspecificEpithet, rank, pageSize, pageNumber);\r
+ }\r
+\r
+ return results;\r
+ }\r
+\r
+ /* (non-Javadoc)\r
+ * @see eu.etaxonomy.cdm.api.service.ITaxonService#listToTaxonRelationships(eu.etaxonomy.cdm.model.taxon.Taxon, eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType, java.lang.Integer, java.lang.Integer, java.util.List, java.util.List)\r
+ */\r
+ public List<TaxonRelationship> listToTaxonRelationships(Taxon taxon, TaxonRelationshipType type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths){\r
Integer numberOfResults = dao.countTaxonRelationships(taxon, type, TaxonRelationship.Direction.relatedTo);\r
- \r
- List<TaxonRelationship> results = new ArrayList<TaxonRelationship>();\r
- if(numberOfResults > 0) { // no point checking again\r
- results = dao.getTaxonRelationships(taxon, type, pageSize, pageNumber, orderHints, propertyPaths, TaxonRelationship.Direction.relatedTo); \r
- }\r
- return new DefaultPagerImpl<TaxonRelationship>(pageNumber, numberOfResults, pageSize, results);\r
- }\r
- \r
- public List<TaxonRelationship> listFromTaxonRelationships(Taxon taxon, TaxonRelationshipType type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths){\r
- Integer numberOfResults = dao.countTaxonRelationships(taxon, type, TaxonRelationship.Direction.relatedFrom);\r
- \r
- List<TaxonRelationship> results = new ArrayList<TaxonRelationship>();\r
- if(numberOfResults > 0) { // no point checking again\r
- results = dao.getTaxonRelationships(taxon, type, pageSize, pageNumber, orderHints, propertyPaths, TaxonRelationship.Direction.relatedFrom); \r
- }\r
- return results;\r
- }\r
- \r
- public Pager<TaxonRelationship> pageFromTaxonRelationships(Taxon taxon, TaxonRelationshipType type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {\r
+\r
+ List<TaxonRelationship> results = new ArrayList<TaxonRelationship>();\r
+ if(numberOfResults > 0) { // no point checking again\r
+ results = dao.getTaxonRelationships(taxon, type, pageSize, pageNumber, orderHints, propertyPaths, TaxonRelationship.Direction.relatedTo);\r
+ }\r
+ return results;\r
+ }\r
+\r
+ /* (non-Javadoc)\r
+ * @see eu.etaxonomy.cdm.api.service.ITaxonService#pageToTaxonRelationships(eu.etaxonomy.cdm.model.taxon.Taxon, eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType, java.lang.Integer, java.lang.Integer, java.util.List, java.util.List)\r
+ */\r
+ public Pager<TaxonRelationship> pageToTaxonRelationships(Taxon taxon, TaxonRelationshipType type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {\r
+ Integer numberOfResults = dao.countTaxonRelationships(taxon, type, TaxonRelationship.Direction.relatedTo);\r
+\r
+ List<TaxonRelationship> results = new ArrayList<TaxonRelationship>();\r
+ if(numberOfResults > 0) { // no point checking again\r
+ results = dao.getTaxonRelationships(taxon, type, pageSize, pageNumber, orderHints, propertyPaths, TaxonRelationship.Direction.relatedTo);\r
+ }\r
+ return new DefaultPagerImpl<TaxonRelationship>(pageNumber, numberOfResults, pageSize, results);\r
+ }\r
+\r
+ /* (non-Javadoc)\r
+ * @see eu.etaxonomy.cdm.api.service.ITaxonService#listFromTaxonRelationships(eu.etaxonomy.cdm.model.taxon.Taxon, eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType, java.lang.Integer, java.lang.Integer, java.util.List, java.util.List)\r
+ */\r
+ public List<TaxonRelationship> listFromTaxonRelationships(Taxon taxon, TaxonRelationshipType type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths){\r
+ Integer numberOfResults = dao.countTaxonRelationships(taxon, type, TaxonRelationship.Direction.relatedFrom);\r
+\r
+ List<TaxonRelationship> results = new ArrayList<TaxonRelationship>();\r
+ if(numberOfResults > 0) { // no point checking again\r
+ results = dao.getTaxonRelationships(taxon, type, pageSize, pageNumber, orderHints, propertyPaths, TaxonRelationship.Direction.relatedFrom);\r
+ }\r
+ return results;\r
+ }\r
+\r
+ /* (non-Javadoc)\r
+ * @see eu.etaxonomy.cdm.api.service.ITaxonService#pageFromTaxonRelationships(eu.etaxonomy.cdm.model.taxon.Taxon, eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType, java.lang.Integer, java.lang.Integer, java.util.List, java.util.List)\r
+ */\r
+ public Pager<TaxonRelationship> pageFromTaxonRelationships(Taxon taxon, TaxonRelationshipType type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {\r
Integer numberOfResults = dao.countTaxonRelationships(taxon, type, TaxonRelationship.Direction.relatedFrom);\r
- \r
- List<TaxonRelationship> results = new ArrayList<TaxonRelationship>();\r
- if(numberOfResults > 0) { // no point checking again\r
- results = dao.getTaxonRelationships(taxon, type, pageSize, pageNumber, orderHints, propertyPaths, TaxonRelationship.Direction.relatedFrom); \r
- }\r
- return new DefaultPagerImpl<TaxonRelationship>(pageNumber, numberOfResults, pageSize, results);\r
- }\r
\r
- public Pager<SynonymRelationship> getSynonyms(Taxon taxon, SynonymRelationshipType type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {\r
+ List<TaxonRelationship> results = new ArrayList<TaxonRelationship>();\r
+ if(numberOfResults > 0) { // no point checking again\r
+ results = dao.getTaxonRelationships(taxon, type, pageSize, pageNumber, orderHints, propertyPaths, TaxonRelationship.Direction.relatedFrom);\r
+ }\r
+ return new DefaultPagerImpl<TaxonRelationship>(pageNumber, numberOfResults, pageSize, results);\r
+ }\r
+\r
+ /* (non-Javadoc)\r
+ * @see eu.etaxonomy.cdm.api.service.ITaxonService#getSynonyms(eu.etaxonomy.cdm.model.taxon.Taxon, eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType, java.lang.Integer, java.lang.Integer, java.util.List, java.util.List)\r
+ */\r
+ public Pager<SynonymRelationship> getSynonyms(Taxon taxon, SynonymRelationshipType type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {\r
Integer numberOfResults = dao.countSynonyms(taxon, type);\r
+\r
+ List<SynonymRelationship> results = new ArrayList<SynonymRelationship>();\r
+ if(numberOfResults > 0) { // no point checking again\r
+ results = dao.getSynonyms(taxon, type, pageSize, pageNumber, orderHints, propertyPaths);\r
+ }\r
+\r
+ return new DefaultPagerImpl<SynonymRelationship>(pageNumber, numberOfResults, pageSize, results);\r
+ }\r
+\r
+ /* (non-Javadoc)\r
+ * @see eu.etaxonomy.cdm.api.service.ITaxonService#getSynonyms(eu.etaxonomy.cdm.model.taxon.Synonym, eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType, java.lang.Integer, java.lang.Integer, java.util.List, java.util.List)\r
+ */\r
+ public Pager<SynonymRelationship> getSynonyms(Synonym synonym, SynonymRelationshipType type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {\r
+ Integer numberOfResults = dao.countSynonyms(synonym, type);\r
\r
List<SynonymRelationship> results = new ArrayList<SynonymRelationship>();\r
if(numberOfResults > 0) { // no point checking again\r
- results = dao.getSynonyms(taxon, type, pageSize, pageNumber, orderHints, propertyPaths); \r
+ results = dao.getSynonyms(synonym, type, pageSize, pageNumber, orderHints, propertyPaths);\r
}\r
- \r
- return new DefaultPagerImpl<SynonymRelationship>(pageNumber, numberOfResults, pageSize, results);\r
- }\r
- \r
+\r
+ return new DefaultPagerImpl<SynonymRelationship>(pageNumber, numberOfResults, pageSize, results);\r
+ }\r
+\r
+ /* (non-Javadoc)\r
+ * @see eu.etaxonomy.cdm.api.service.ITaxonService#getHomotypicSynonymsByHomotypicGroup(eu.etaxonomy.cdm.model.taxon.Taxon, java.util.List)\r
+ */\r
public List<Synonym> getHomotypicSynonymsByHomotypicGroup(Taxon taxon, List<String> propertyPaths){\r
Taxon t = (Taxon)dao.load(taxon.getUuid(), propertyPaths);\r
return t.getHomotypicSynonymsByHomotypicGroup();\r
}\r
\r
+ /* (non-Javadoc)\r
+ * @see eu.etaxonomy.cdm.api.service.ITaxonService#getHeterotypicSynonymyGroups(eu.etaxonomy.cdm.model.taxon.Taxon, java.util.List)\r
+ */\r
public List<List<Synonym>> getHeterotypicSynonymyGroups(Taxon taxon, List<String> propertyPaths){\r
Taxon t = (Taxon)dao.load(taxon.getUuid(), propertyPaths);\r
- List<HomotypicalGroup> hsgl = t.getHeterotypicSynonymyGroups();\r
- List<List<Synonym>> heterotypicSynonymyGroups = new ArrayList<List<Synonym>>(hsgl.size());\r
- for(HomotypicalGroup hsg : hsgl){\r
- heterotypicSynonymyGroups.add(hsg.getSynonymsInGroup(t.getSec()));\r
+ List<HomotypicalGroup> homotypicalGroups = t.getHeterotypicSynonymyGroups();\r
+ List<List<Synonym>> heterotypicSynonymyGroups = new ArrayList<List<Synonym>>(homotypicalGroups.size());\r
+ for(HomotypicalGroup homotypicalGroup : homotypicalGroups){\r
+ heterotypicSynonymyGroups.add(t.getSynonymsInGroup(homotypicalGroup));\r
}\r
return heterotypicSynonymyGroups;\r
}\r
\r
- public Pager<TaxonBase> search(Class<? extends TaxonBase> clazz, String queryString, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {\r
- Integer numberOfResults = dao.count(clazz,queryString);\r
+ public List<UuidAndTitleCache<TaxonBase>> findTaxaAndNamesForEditor(ITaxonServiceConfigurator configurator){\r
\r
- List<TaxonBase> results = new ArrayList<TaxonBase>();\r
- if(numberOfResults > 0) { // no point checking again\r
- results = dao.search(clazz,queryString, pageSize, pageNumber, orderHints, propertyPaths); \r
+ List<UuidAndTitleCache<TaxonBase>> result = new ArrayList<UuidAndTitleCache<TaxonBase>>();\r
+ Class<? extends TaxonBase> clazz = null;\r
+ if ((configurator.isDoTaxa() && configurator.isDoSynonyms())) {\r
+ clazz = TaxonBase.class;\r
+ //propertyPath.addAll(configurator.getTaxonPropertyPath());\r
+ //propertyPath.addAll(configurator.getSynonymPropertyPath());\r
+ } else if(configurator.isDoTaxa()) {\r
+ clazz = Taxon.class;\r
+ //propertyPath = configurator.getTaxonPropertyPath();\r
+ } else if (configurator.isDoSynonyms()) {\r
+ clazz = Synonym.class;\r
+ //propertyPath = configurator.getSynonymPropertyPath();\r
}\r
\r
- return new DefaultPagerImpl<TaxonBase>(pageNumber, numberOfResults, pageSize, results);\r
+ \r
+ result = dao.getTaxaByNameForEditor(clazz, configurator.getTitleSearchStringSqlized(), configurator.getClassification(), configurator.getMatchMode(), configurator.getNamedAreas());\r
+ return result;\r
}\r
\r
- \r
+ /* (non-Javadoc)\r
+ * @see eu.etaxonomy.cdm.api.service.ITaxonService#findTaxaAndNames(eu.etaxonomy.cdm.api.service.config.ITaxonServiceConfigurator)\r
+ */\r
public Pager<IdentifiableEntity> findTaxaAndNames(ITaxonServiceConfigurator configurator) {\r
\r
List<IdentifiableEntity> results = new ArrayList<IdentifiableEntity>();\r
int numberOfResults = 0; // overall number of results (as opposed to number of results per page)\r
List<TaxonBase> taxa = null; \r
\r
- // Taxa and synonyms\r
- long numberTaxaResults = 0L;\r
- \r
- Class<? extends TaxonBase> clazz = null;\r
- if (configurator.isDoTaxa() && configurator.isDoSynonyms()) {\r
- clazz = TaxonBase.class;\r
- } else if(configurator.isDoTaxa()) {\r
- clazz = Taxon.class;\r
- } else if (configurator.isDoSynonyms()) {\r
- clazz = Synonym.class;\r
+ // Taxa and synonyms\r
+ long numberTaxaResults = 0L;\r
+\r
+ Class<? extends TaxonBase> clazz = null;\r
+ List<String> propertyPath = new ArrayList<String>();\r
+ if(configurator.getTaxonPropertyPath() != null){\r
+ propertyPath.addAll(configurator.getTaxonPropertyPath());\r
+ }\r
+ if ((configurator.isDoTaxa() && configurator.isDoSynonyms())) {\r
+ clazz = TaxonBase.class;\r
+ //propertyPath.addAll(configurator.getTaxonPropertyPath());\r
+ //propertyPath.addAll(configurator.getSynonymPropertyPath());\r
+ } else if(configurator.isDoTaxa()) {\r
+ clazz = Taxon.class;\r
+ //propertyPath = configurator.getTaxonPropertyPath();\r
+ } else if (configurator.isDoSynonyms()) {\r
+ clazz = Synonym.class;\r
+ //propertyPath = configurator.getSynonymPropertyPath();\r
+ }\r
+\r
+ if(clazz != null){\r
+ if(configurator.getPageSize() != null){ // no point counting if we need all anyway\r
+ numberTaxaResults =\r
+ dao.countTaxaByName(clazz,\r
+ configurator.getTitleSearchStringSqlized(), configurator.getClassification(), configurator.getMatchMode(),\r
+ configurator.getNamedAreas());\r
+ }\r
+\r
+ if(configurator.getPageSize() == null || numberTaxaResults > configurator.getPageSize() * configurator.getPageNumber()){ // no point checking again if less results\r
+ taxa = dao.getTaxaByName(clazz,\r
+ configurator.getTitleSearchStringSqlized(), configurator.getClassification(), configurator.getMatchMode(),\r
+ configurator.getNamedAreas(), configurator.getPageSize(),\r
+ configurator.getPageNumber(), propertyPath);\r
+ }\r
+ }\r
+\r
+ if (logger.isDebugEnabled()) { logger.debug(numberTaxaResults + " matching taxa counted"); }\r
+\r
+ if(taxa != null){\r
+ results.addAll(taxa);\r
+ }\r
+\r
+ numberOfResults += numberTaxaResults;\r
+\r
+ // Names without taxa\r
+ if (configurator.isDoNamesWithoutTaxa()) {\r
+ int numberNameResults = 0;\r
+\r
+ List<? extends TaxonNameBase<?,?>> names =\r
+ nameDao.findByName(configurator.getTitleSearchStringSqlized(), configurator.getMatchMode(),\r
+ configurator.getPageSize(), configurator.getPageNumber(), null, configurator.getTaxonNamePropertyPath());\r
+ if (logger.isDebugEnabled()) { logger.debug(names.size() + " matching name(s) found"); }\r
+ if (names.size() > 0) {\r
+ for (TaxonNameBase<?,?> taxonName : names) {\r
+ if (taxonName.getTaxonBases().size() == 0) {\r
+ results.add(taxonName);\r
+ numberNameResults++;\r
+ }\r
+ }\r
+ if (logger.isDebugEnabled()) { logger.debug(numberNameResults + " matching name(s) without taxa found"); }\r
+ numberOfResults += numberNameResults;\r
+ }\r
+ }\r
+\r
+ // Taxa from common names\r
+\r
+ if (configurator.isDoTaxaByCommonNames()) {\r
+ taxa = null;\r
+ numberTaxaResults = 0;\r
+ if(configurator.getPageSize() != null){// no point counting if we need all anyway\r
+ numberTaxaResults = dao.countTaxaByCommonName(configurator.getTitleSearchStringSqlized(), configurator.getClassification(), configurator.getMatchMode(), configurator.getNamedAreas());\r
+ }\r
+ if(configurator.getPageSize() == null || numberTaxaResults > configurator.getPageSize() * configurator.getPageNumber()){\r
+ taxa = dao.getTaxaByCommonName(configurator.getTitleSearchStringSqlized(), configurator.getClassification(), configurator.getMatchMode(), configurator.getNamedAreas(), configurator.getPageSize(), configurator.getPageNumber(), configurator.getTaxonPropertyPath());\r
+ }\r
+ if(taxa != null){\r
+ results.addAll(taxa);\r
+ }\r
+ numberOfResults += numberTaxaResults;\r
+\r
+ }\r
+\r
+ return new DefaultPagerImpl<IdentifiableEntity>\r
+ (configurator.getPageNumber(), numberOfResults, configurator.getPageSize(), results);\r
+ }\r
+\r
+ public List<UuidAndTitleCache<TaxonBase>> getTaxonUuidAndTitleCache(){\r
+ return dao.getUuidAndTitleCache();\r
+ }\r
+\r
+ /* (non-Javadoc)\r
+ * @see eu.etaxonomy.cdm.api.service.ITaxonService#getAllMedia(eu.etaxonomy.cdm.model.taxon.Taxon, int, int, int, java.lang.String[])\r
+ */\r
+ public List<MediaRepresentation> getAllMedia(Taxon taxon, int size, int height, int widthOrDuration, String[] mimeTypes){\r
+ List<MediaRepresentation> medRep = new ArrayList<MediaRepresentation>();\r
+ taxon = (Taxon)dao.load(taxon.getUuid());\r
+ Set<TaxonDescription> descriptions = taxon.getDescriptions();\r
+ for (TaxonDescription taxDesc: descriptions){\r
+ Set<DescriptionElementBase> elements = taxDesc.getElements();\r
+ for (DescriptionElementBase descElem: elements){\r
+ for(Media media : descElem.getMedia()){\r
+\r
+ //find the best matching representation\r
+ medRep.add(MediaUtils.findBestMatchingRepresentation(media, null, size, height, widthOrDuration, mimeTypes));\r
+\r
+ }\r
+ }\r
+ }\r
+ return medRep;\r
+ }\r
+\r
+ /* (non-Javadoc)\r
+ * @see eu.etaxonomy.cdm.api.service.ITaxonService#findTaxaByID(java.util.Set)\r
+ */\r
+ public List<TaxonBase> findTaxaByID(Set<Integer> listOfIDs) {\r
+ return this.dao.findById(listOfIDs);\r
+ }\r
+\r
+ /* (non-Javadoc)\r
+ * @see eu.etaxonomy.cdm.api.service.ITaxonService#countAllRelationships()\r
+ */\r
+ public int countAllRelationships() {\r
+ return this.dao.countAllRelationships();\r
+ }\r
+\r
+ /* (non-Javadoc)\r
+ * @see eu.etaxonomy.cdm.api.service.ITaxonService#createAllInferredSynonyms(eu.etaxonomy.cdm.model.taxon.Classification, eu.etaxonomy.cdm.model.taxon.Taxon)\r
+ */\r
+ public List<Synonym> createAllInferredSynonyms(Classification tree,\r
+ Taxon taxon) {\r
+\r
+ return this.dao.createAllInferredSynonyms(taxon, tree);\r
+ }\r
+\r
+ /* (non-Javadoc)\r
+ * @see eu.etaxonomy.cdm.api.service.ITaxonService#createInferredSynonyms(eu.etaxonomy.cdm.model.taxon.Classification, eu.etaxonomy.cdm.model.taxon.Taxon, eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType)\r
+ */\r
+ public List<Synonym> createInferredSynonyms(Classification tree, Taxon taxon, SynonymRelationshipType type) {\r
+ return this.dao.createInferredSynonyms(taxon, tree, type);\r
+ }\r
+\r
+ /* (non-Javadoc)\r
+ * @see eu.etaxonomy.cdm.api.service.ITaxonService#findIdenticalTaxonNames(java.util.List)\r
+ */\r
+ public List<TaxonNameBase> findIdenticalTaxonNames(List<String> propertyPath) {\r
+ return this.dao.findIdenticalTaxonNames(propertyPath);\r
+ }\r
+\r
+\r
+ /* (non-Javadoc)\r
+ * @see eu.etaxonomy.cdm.api.service.ITaxonService#deleteSynonym(eu.etaxonomy.cdm.model.taxon.Synonym, eu.etaxonomy.cdm.model.taxon.Taxon, boolean, boolean)\r
+ */\r
+ @Transactional(readOnly = false)\r
+ @Override\r
+ public void deleteSynonym(Synonym synonym, Taxon taxon, boolean removeNameIfPossible,boolean newHomotypicGroupIfNeeded) {\r
+ if (synonym == null){\r
+ return;\r
}\r
- \r
- if(clazz != null){\r
- numberTaxaResults = \r
- dao.countTaxaByName(clazz, \r
- configurator.getSearchString(), configurator.getTaxonomicTree(), configurator.getMatchMode(),\r
- configurator.getNamedAreas());\r
- if(numberTaxaResults > configurator.getPageSize() * configurator.getPageNumber()){ // no point checking again if less results\r
- taxa = dao.getTaxaByName(clazz, \r
- configurator.getSearchString(), configurator.getTaxonomicTree(), configurator.getMatchMode(),\r
- configurator.getNamedAreas(), configurator.getPageSize(), \r
- configurator.getPageNumber(), configurator.getTaxonPropertyPath());\r
- }\r
+ synonym = CdmBase.deproxy(dao.merge(synonym), Synonym.class);\r
+ \r
+ //remove synonymRelationship\r
+ Set<Taxon> taxonSet = new HashSet<Taxon>();\r
+ if (taxon != null){\r
+ taxonSet.add(taxon);\r
+ }else{\r
+ taxonSet.addAll(synonym.getAcceptedTaxa());\r
}\r
-\r
- if (logger.isDebugEnabled()) { logger.debug(numberTaxaResults + " matching taxa counted"); }\r
- \r
- if(taxa != null){\r
- results.addAll(taxa);\r
+ for (Taxon relatedTaxon : taxonSet){\r
+// dao.deleteSynonymRelationships(synonym, relatedTaxon);\r
+ relatedTaxon.removeSynonym(synonym, newHomotypicGroupIfNeeded);\r
}\r
+ this.saveOrUpdate(synonym);\r
\r
- numberOfResults += numberTaxaResults;\r
- \r
- // Names without taxa \r
+ //TODO remove name from homotypical group?\r
\r
- if (configurator.isDoNamesWithoutTaxa()) {\r
- int numberNameResults = 0;\r
- //FIXME implement search by area\r
- List<? extends TaxonNameBase<?,?>> names = \r
- nameDao.findByName(configurator.getSearchString(), configurator.getMatchMode(), \r
- configurator.getPageSize(), configurator.getPageNumber(), null, null);\r
- if (logger.isDebugEnabled()) { logger.debug(names.size() + " matching name(s) found"); }\r
- if (names.size() > 0) {\r
- for (TaxonNameBase<?,?> taxonName : names) {\r
- if (taxonName.getTaxonBases().size() == 0) {\r
- results.add(taxonName);\r
- numberNameResults++;\r
- }\r
+ //remove synonym (if necessary)\r
+ if (synonym.getSynonymRelations().isEmpty()){\r
+ TaxonNameBase<?,?> name = synonym.getName();\r
+ synonym.setName(null);\r
+ dao.delete(synonym);\r
+ \r
+ //remove name if possible (and required)\r
+ if (name != null && removeNameIfPossible){\r
+ try{\r
+ nameService.delete(name, new NameDeletionConfigurator());\r
+ }catch (DataChangeNoRollbackException ex){\r
+ if (logger.isDebugEnabled())logger.debug("Name wasn't deleted as it is referenced");\r
}\r
- if (logger.isDebugEnabled()) { logger.debug(numberNameResults + " matching name(s) without taxa found"); }\r
- numberOfResults += numberNameResults;\r
}\r
}\r
- \r
- // Taxa from common names\r
- // FIXME the matching common names also must be returned\r
- // FIXME implement search by area\r
- if (configurator.isDoTaxaByCommonNames()) {\r
- int numberCommonNameResults = 0;\r
- List<CommonTaxonName> commonTaxonNames = \r
- descriptionDao.searchDescriptionByCommonName(configurator.getSearchString(), \r
- configurator.getMatchMode(), configurator.getPageSize(), configurator.getPageNumber());\r
- if (logger.isDebugEnabled()) { logger.debug(commonTaxonNames.size() + " matching common name(s) found"); }\r
- if (commonTaxonNames.size() > 0) {\r
- for (CommonTaxonName commonTaxonName : commonTaxonNames) {\r
- DescriptionBase description = commonTaxonName.getInDescription();\r
- description = HibernateProxyHelper.deproxy(description, DescriptionBase.class);\r
- if (description instanceof TaxonDescription) {\r
- TaxonDescription taxonDescription = HibernateProxyHelper.deproxy(description, TaxonDescription.class);\r
- Taxon taxon = taxonDescription.getTaxon();\r
- taxon = HibernateProxyHelper.deproxy(taxon, Taxon.class);\r
- if (!results.contains(taxon) && !taxon.isMisappliedName()) {\r
- defaultBeanInitializer.initialize(taxon, configurator.getTaxonPropertyPath());\r
- results.add(taxon);\r
- numberCommonNameResults++;\r
- }\r
- } else {\r
- logger.warn("Description of " + commonTaxonName.getName() + " is not an instance of TaxonDescription");\r
- }\r
- }\r
- numberOfResults += numberCommonNameResults;\r
- } \r
- }\r
- \r
- //FIXME does not work any more after model change\r
- logger.warn("Sort does currently not work on identifiable entities due to model changes (duplicated implementation of the Comparable interface).");\r
- //Collections.sort(results);\r
- return new DefaultPagerImpl<IdentifiableEntity>\r
- (configurator.getPageNumber(), numberOfResults, configurator.getPageSize(), results);\r
- }\r
-\r
- /**\r
- * FIXME Candidate for harmonization\r
- * remove, clearly this method is never used\r
- */\r
- public <TYPE extends TaxonBase> Pager<TYPE> list(Class<TYPE> type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {\r
- logger.warn("Pager<TYPE> list(xxx) method not yet implemented");\r
- return null;\r
- }\r
-\r
- /*\r
- * (non-Javadoc)\r
- * @see eu.etaxonomy.cdm.api.service.ITaxonService#getUuidAndTitleCacheOfAcceptedTaxa(eu.etaxonomy.cdm.model.taxon.TaxonomicTree)\r
- \r
- public List<UuidAndTitleCache> getTaxonNodeUuidAndTitleCacheOfAcceptedTaxaByTaxonomicTree(TaxonomicTree taxonomicTree) {\r
- return taxonDao.getTaxonNodeUuidAndTitleCacheOfAcceptedTaxaByTaxonomicTree(taxonomicTree);\r
}\r
- */\r
\r
- public Map<UUID, List<MediaRepresentation>> getAllMediaForChildNodes(Taxon taxon, TaxonomicTree taxTree, List<String> propertyPaths, int size, int height, int widthOrDuration, String[] mimeTypes){\r
- TreeMap<UUID, List<MediaRepresentation>> result = new TreeMap<UUID, List<MediaRepresentation>>();\r
- List<Media> taxonMedia = new ArrayList<Media>();\r
- List<MediaRepresentation> medRep = new ArrayList<MediaRepresentation>();\r
- //add all media of the children to the result map\r
- if (taxTree != null || taxon != null){\r
- \r
- taxTree = taxonTreeDao.load(taxTree.getUuid());\r
- //taxon = (Taxon)dao.load(taxon.getUuid());\r
- \r
- List<TaxonNode> taxNodes = loadChildNodesOfTaxon(taxon, taxTree, propertyPaths);\r
- if (taxNodes.size() != 0){\r
- \r
- defaultBeanInitializer.initializeAll(taxNodes, propertyPaths);\r
- TaxonNode taxNode = loadTaxonNodeByTaxon(taxon, taxTree.getUuid(), propertyPaths);\r
- \r
- //Set<TaxonNode> childNodes = taxNode.getAllNodes();\r
- taxNodes.add(taxNode);\r
- if (taxNodes != null){\r
- for(TaxonNode childNode : taxNodes){\r
- taxon = childNode.getTaxon();\r
- /*Set<TaxonDescription> descriptions = taxon.getDescriptions();\r
- for (TaxonDescription taxDesc: descriptions){\r
- Set<DescriptionElementBase> elements = taxDesc.getElements();\r
- for (DescriptionElementBase descElem: elements){\r
- for(Media media : descElem.getMedia()){\r
- taxonMedia.add(media);\r
- \r
- //find the best matching representation\r
- medRep.add(media.findBestMatchingRepresentation(size, height, widthOrDuration, mimeTypes));\r
- \r
- }\r
- }\r
- }*/\r
- result.put(taxon.getUuid(), getAllMedia(taxon, size, height, widthOrDuration,mimeTypes));\r
- \r
- } \r
- }\r
- }\r
- \r
- }\r
- \r
- \r
- return result;\r
- }\r
-\r
+ \r
+ /* (non-Javadoc)\r
+ * @see eu.etaxonomy.cdm.api.service.ITaxonService#findIdenticalTaxonNameIds(java.util.List)\r
+ */\r
+ public List<TaxonNameBase> findIdenticalTaxonNameIds(List<String> propertyPath) {\r
\r
- public List<MediaRepresentation> getAllMedia(Taxon taxon, int size, int height, int widthOrDuration, String[] mimeTypes){\r
- List<MediaRepresentation> medRep = new ArrayList<MediaRepresentation>();\r
- taxon = (Taxon)dao.load(taxon.getUuid());\r
- Set<TaxonDescription> descriptions = taxon.getDescriptions();\r
- for (TaxonDescription taxDesc: descriptions){\r
- Set<DescriptionElementBase> elements = taxDesc.getElements();\r
- for (DescriptionElementBase descElem: elements){\r
- for(Media media : descElem.getMedia()){\r
- \r
- //find the best matching representation\r
- medRep.add(media.findBestMatchingRepresentation(size, height, widthOrDuration, mimeTypes));\r
- \r
- }\r
- }\r
- }\r
- return medRep;\r
- }\r
+ return this.dao.findIdenticalNamesNew(propertyPath);\r
+ }\r
\r
+ /* (non-Javadoc)\r
+ * @see eu.etaxonomy.cdm.api.service.ITaxonService#getPhylumName(eu.etaxonomy.cdm.model.name.TaxonNameBase)\r
+ */\r
+ public String getPhylumName(TaxonNameBase name){\r
+ return this.dao.getPhylumName(name);\r
+ }\r
\r
- \r
- \r
- \r
+ /* (non-Javadoc)\r
+ * @see eu.etaxonomy.cdm.api.service.ITaxonService#deleteSynonymRelationships(eu.etaxonomy.cdm.model.taxon.Synonym)\r
+ */\r
+ public long deleteSynonymRelationships(Synonym syn) {\r
+ return dao.deleteSynonymRelationships(syn, null);\r
+ }\r
+\r
+\r
+ /* (non-Javadoc)\r
+ * @see eu.etaxonomy.cdm.api.service.ITaxonService#listSynonymRelationships(eu.etaxonomy.cdm.model.taxon.TaxonBase, eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType, java.lang.Integer, java.lang.Integer, java.util.List, java.util.List, eu.etaxonomy.cdm.model.common.RelationshipBase.Direction)\r
+ */\r
+ public List<SynonymRelationship> listSynonymRelationships(\r
+ TaxonBase taxonBase, SynonymRelationshipType type, Integer pageSize, Integer pageNumber,\r
+ List<OrderHint> orderHints, List<String> propertyPaths, Direction direction) {\r
+ Integer numberOfResults = dao.countSynonymRelationships(taxonBase, type, direction);\r
+\r
+ List<SynonymRelationship> results = new ArrayList<SynonymRelationship>();\r
+ if(numberOfResults > 0) { // no point checking again\r
+ results = dao.getSynonymRelationships(taxonBase, type, pageSize, pageNumber, orderHints, propertyPaths, direction);\r
+ }\r
+ return results;\r
+ }\r
+\r
+ /* (non-Javadoc)\r
+ * @see eu.etaxonomy.cdm.api.service.ITaxonService#findBestMatchingTaxon(java.lang.String)\r
+ */\r
+ @Override\r
+ public Taxon findBestMatchingTaxon(String taxonName) {\r
+ MatchingTaxonConfigurator config = MatchingTaxonConfigurator.NewInstance();\r
+ config.setTaxonNameTitle(taxonName);\r
+ return findBestMatchingTaxon(config);\r
+ }\r
+\r
+\r
+\r
+ @Override\r
+ public Taxon findBestMatchingTaxon(MatchingTaxonConfigurator config) {\r
+\r
+ Taxon bestCandidate = null;\r
+ try{\r
+ // 1. search for acceptet taxa\r
+ List<TaxonBase> taxonList = dao.findByNameTitleCache(Taxon.class, config.getTaxonNameTitle(), null, MatchMode.EXACT, null, 0, null, null);\r
+ boolean bestCandidateMatchesSecUuid = false;\r
+ boolean bestCandidateIsInClassification = false;\r
+ int countEqualCandidates = 0;\r
+ for(TaxonBase taxonBaseCandidate : taxonList){\r
+ if(taxonBaseCandidate instanceof Taxon){\r
+ Taxon newCanditate = CdmBase.deproxy(taxonBaseCandidate, Taxon.class);\r
+ boolean newCandidateMatchesSecUuid = isMatchesSecUuid(newCanditate, config);\r
+ if (! newCandidateMatchesSecUuid && config.isOnlyMatchingSecUuid() ){\r
+ continue;\r
+ }else if(newCandidateMatchesSecUuid && ! bestCandidateMatchesSecUuid){\r
+ bestCandidate = newCanditate;\r
+ countEqualCandidates = 1;\r
+ bestCandidateMatchesSecUuid = true;\r
+ continue;\r
+ }\r
+\r
+ boolean newCandidateInClassification = isInClassification(newCanditate, config);\r
+ if (! newCandidateInClassification && config.isOnlyMatchingClassificationUuid()){\r
+ continue;\r
+ }else if (newCandidateInClassification && ! bestCandidateIsInClassification){\r
+ bestCandidate = newCanditate;\r
+ countEqualCandidates = 1;\r
+ bestCandidateIsInClassification = true;\r
+ continue;\r
+ }\r
+ if (bestCandidate == null){\r
+ bestCandidate = newCanditate;\r
+ countEqualCandidates = 1;\r
+ continue;\r
+ }\r
+\r
+ }else{ //not Taxon.class\r
+ continue;\r
+ }\r
+ countEqualCandidates++;\r
+\r
+ }\r
+ if (bestCandidate != null){\r
+ if(countEqualCandidates > 1){\r
+ logger.info(countEqualCandidates + " equally matching TaxonBases found, using first accepted Taxon: " + bestCandidate.getTitleCache());\r
+ return bestCandidate;\r
+ } else {\r
+ logger.info("using accepted Taxon: " + bestCandidate.getTitleCache());\r
+ return bestCandidate;\r
+ }\r
+ }\r
+\r
+\r
+ // 2. search for synonyms\r
+ if (config.isIncludeSynonyms()){\r
+ List<TaxonBase> synonymList = dao.findByNameTitleCache(Synonym.class, config.getTaxonNameTitle(), null, MatchMode.EXACT, null, 0, null, null);\r
+ for(TaxonBase taxonBase : synonymList){\r
+ if(taxonBase instanceof Synonym){\r
+ Synonym synonym = CdmBase.deproxy(taxonBase, Synonym.class);\r
+ Set<Taxon> acceptetdCandidates = synonym.getAcceptedTaxa();\r
+ if(!acceptetdCandidates.isEmpty()){\r
+ bestCandidate = acceptetdCandidates.iterator().next();\r
+ if(acceptetdCandidates.size() == 1){\r
+ logger.info(acceptetdCandidates.size() + " Accepted taxa found for synonym " + taxonBase.getTitleCache() + ", using first one: " + bestCandidate.getTitleCache());\r
+ return bestCandidate;\r
+ } else {\r
+ logger.info("using accepted Taxon " + bestCandidate.getTitleCache() + "for synonym " + taxonBase.getTitleCache());\r
+ return bestCandidate;\r
+ }\r
+ //TODO extend method: search using treeUUID, using SecUUID, first find accepted then include synonyms until a matching taxon is found\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ } catch (Exception e){\r
+ logger.error(e);\r
+ }\r
+\r
+ return bestCandidate;\r
+ }\r
+\r
+ private boolean isInClassification(Taxon taxon, MatchingTaxonConfigurator config) {\r
+ UUID configClassificationUuid = config.getClassificationUuid();\r
+ if (configClassificationUuid == null){\r
+ return false;\r
+ }\r
+ for (TaxonNode node : taxon.getTaxonNodes()){\r
+ UUID classUuid = node.getClassification().getUuid();\r
+ if (configClassificationUuid.equals(classUuid)){\r
+ return true;\r
+ }\r
+ }\r
+ return false;\r
+ }\r
+\r
+ private boolean isMatchesSecUuid(Taxon taxon, MatchingTaxonConfigurator config) {\r
+ UUID configSecUuid = config.getSecUuid();\r
+ if (configSecUuid == null){\r
+ return false;\r
+ }\r
+ UUID taxonSecUuid = (taxon.getSec() == null)? null : taxon.getSec().getUuid();\r
+ return configSecUuid.equals(taxonSecUuid);\r
+ }\r
+\r
+ /* (non-Javadoc)\r
+ * @see eu.etaxonomy.cdm.api.service.ITaxonService#findBestMatchingSynonym(java.lang.String)\r
+ */\r
+ @Override\r
+ public Synonym findBestMatchingSynonym(String taxonName) {\r
+ List<TaxonBase> synonymList = dao.findByNameTitleCache(Synonym.class, taxonName, null, MatchMode.EXACT, null, 0, null, null);\r
+ if(! synonymList.isEmpty()){\r
+ Synonym result = CdmBase.deproxy(synonymList.iterator().next(), Synonym.class);\r
+ if(synonymList.size() == 1){\r
+ logger.info(synonymList.size() + " Synonym found " + result.getTitleCache() );\r
+ return result;\r
+ } else {\r
+ logger.info("Several matching synonyms found. Using first: " + result.getTitleCache());\r
+ return result;\r
+ }\r
+ }\r
+ return null;\r
+ }\r
+\r
+\r
+ /* (non-Javadoc)\r
+ * @see eu.etaxonomy.cdm.api.service.ITaxonService#moveSynonymToAnotherTaxon(eu.etaxonomy.cdm.model.taxon.SynonymRelationship, eu.etaxonomy.cdm.model.taxon.Taxon, boolean, eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType, eu.etaxonomy.cdm.model.reference.Reference, java.lang.String, boolean)\r
+ */\r
+ @Override\r
+ public SynonymRelationship moveSynonymToAnotherTaxon(SynonymRelationship oldSynonymRelation, Taxon newTaxon, boolean moveHomotypicGroup,\r
+ SynonymRelationshipType newSynonymRelationshipType, Reference reference, String referenceDetail, boolean keepReference) throws HomotypicalGroupChangeException {\r
+ \r
+ Synonym synonym = oldSynonymRelation.getSynonym();\r
+ Taxon fromTaxon = oldSynonymRelation.getAcceptedTaxon();\r
+ //TODO what if there is no name ?? Concepts may be cached (e.g. via TCS import)\r
+ TaxonNameBase<?,?> synonymName = synonym.getName();\r
+ TaxonNameBase<?,?> fromTaxonName = fromTaxon.getName();\r
+ //set default relationship type\r
+ if (newSynonymRelationshipType == null){\r
+ newSynonymRelationshipType = SynonymRelationshipType.HETEROTYPIC_SYNONYM_OF();\r
+ }\r
+ boolean newRelTypeIsHomotypic = newSynonymRelationshipType.equals(SynonymRelationshipType.HOMOTYPIC_SYNONYM_OF());\r
+ \r
+ HomotypicalGroup homotypicGroup = synonymName.getHomotypicalGroup();\r
+ int hgSize = homotypicGroup.getTypifiedNames().size();\r
+ boolean isSingleInGroup = !(hgSize > 1);\r
+ \r
+ if (! isSingleInGroup){\r
+ boolean isHomotypicToAccepted = synonymName.isHomotypic(fromTaxonName);\r
+ boolean hasHomotypicSynonymRelatives = isHomotypicToAccepted ? hgSize > 2 : hgSize > 1;\r
+ if (isHomotypicToAccepted){\r
+ String message = "Synonym is in homotypic group with accepted taxon%s. First remove synonym from homotypic group of accepted taxon before moving to other taxon.";\r
+ String homotypicRelatives = hasHomotypicSynonymRelatives ? " and other synonym(s)":"";\r
+ message = String.format(message, homotypicRelatives);\r
+ throw new HomotypicalGroupChangeException(message);\r
+ }\r
+ if (! moveHomotypicGroup){\r
+ String message = "Synonym is in homotypic group with other synonym(s). Either move complete homotypic group or remove synonym from homotypic group prior to moving to other taxon.";\r
+ throw new HomotypicalGroupChangeException(message);\r
+ }\r
+ }else{\r
+ moveHomotypicGroup = true; //single synonym always allows to moveCompleteGroup\r
+ }\r
+ Assert.assertTrue("Synonym can only be moved with complete homotypic group", moveHomotypicGroup);\r
+ \r
+ SynonymRelationship result = null;\r
+ //move all synonyms to new taxon\r
+ List<Synonym> homotypicSynonyms = fromTaxon.getSynonymsInGroup(homotypicGroup);\r
+ for (Synonym syn: homotypicSynonyms){\r
+ Set<SynonymRelationship> synRelations = syn.getSynonymRelations();\r
+ for (SynonymRelationship synRelation : synRelations){\r
+ if (fromTaxon.equals(synRelation.getAcceptedTaxon())){\r
+ Reference<?> newReference = reference;\r
+ if (newReference == null && keepReference){\r
+ newReference = synRelation.getCitation();\r
+ }\r
+ String newRefDetail = referenceDetail;\r
+ if (newRefDetail == null && keepReference){\r
+ newRefDetail = synRelation.getCitationMicroReference();\r
+ }\r
+ SynonymRelationship newSynRelation = newTaxon.addSynonym(syn, newSynonymRelationshipType, newReference, newRefDetail);\r
+ fromTaxon.removeSynonymRelation(synRelation, false);\r
+// \r
+ //change homotypic group of synonym if relType is 'homotypic'\r
+// if (newRelTypeIsHomotypic){\r
+// newTaxon.getName().getHomotypicalGroup().addTypifiedName(syn.getName());\r
+// }\r
+ //set result\r
+ if (synRelation.equals(oldSynonymRelation)){\r
+ result = newSynRelation;\r
+ }\r
+ }\r
+ }\r
+ \r
+ }\r
+ saveOrUpdate(newTaxon);\r
+ //Assert that there is a result \r
+ if (result == null){\r
+ String message = "Old synonym relation could not be transformed into new relation. This should not happen.";\r
+ throw new IllegalStateException(message);\r
+ }\r
+ return result;\r
+ }\r
+\r
+ /* (non-Javadoc)\r
+ * @see eu.etaxonomy.cdm.api.service.ITaxonService#getUuidAndTitleCacheTaxon()\r
+ */\r
+ @Override\r
+ public List<UuidAndTitleCache<TaxonBase>> getUuidAndTitleCacheTaxon() {\r
+ return dao.getUuidAndTitleCacheTaxon();\r
+ }\r
\r
+ /* (non-Javadoc)\r
+ * @see eu.etaxonomy.cdm.api.service.ITaxonService#getUuidAndTitleCacheSynonym()\r
+ */\r
+ @Override\r
+ public List<UuidAndTitleCache<TaxonBase>> getUuidAndTitleCacheSynonym() {\r
+ return dao.getUuidAndTitleCacheSynonym();\r
+ }\r
\r
}\r