bugfix for DescriptionDaoImpl.getDescriptionElementForTaxon (missing implementation...
[cdmlib.git] / cdmlib-services / src / main / java / eu / etaxonomy / cdm / api / service / TaxonServiceImpl.java
index 8bcf233c14a60f967f2c5f7809152835e99ebe20..b31118b6304f121239f5a024268d201e4392b325 100644 (file)
@@ -12,7 +12,6 @@ package eu.etaxonomy.cdm.api.service;
 \r
 import java.util.ArrayList;\r
 import java.util.Comparator;\r
-import java.util.HashSet;\r
 import java.util.List;\r
 import java.util.Set;\r
 import java.util.UUID;\r
@@ -26,7 +25,7 @@ import org.springframework.transaction.annotation.Transactional;
 import eu.etaxonomy.cdm.api.service.config.ITaxonServiceConfigurator;\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.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
@@ -41,16 +40,15 @@ import eu.etaxonomy.cdm.model.media.MediaUtils;
 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.Taxon;\r
 import eu.etaxonomy.cdm.model.taxon.TaxonBase;\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.common.IOrderedTermVocabularyDao;\r
 import eu.etaxonomy.cdm.persistence.dao.description.IDescriptionDao;\r
 import eu.etaxonomy.cdm.persistence.dao.name.ITaxonNameDao;\r
@@ -58,6 +56,7 @@ import eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao;
 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
@@ -90,7 +89,7 @@ public class TaxonServiceImpl extends IdentifiableServiceBase<TaxonBase,ITaxonDa
         * FIXME Candidate for harmonization\r
         * rename searchByName ? \r
         */\r
-       public List<TaxonBase> searchTaxaByName(String name, ReferenceBase sec) {\r
+       public List<TaxonBase> searchTaxaByName(String name, Reference sec) {\r
                return dao.getTaxaByName(name, sec);\r
        }\r
        \r
@@ -117,21 +116,21 @@ public class TaxonServiceImpl extends IdentifiableServiceBase<TaxonBase,ITaxonDa
 \r
        /**\r
         * FIXME Candidate for harmonization\r
-        * merge with getRootTaxa(ReferenceBase sec, ..., ...)\r
+        * merge with getRootTaxa(Reference sec, ..., ...)\r
         *  (non-Javadoc)\r
-        * @see eu.etaxonomy.cdm.api.service.ITaxonService#getRootTaxa(eu.etaxonomy.cdm.model.reference.ReferenceBase)\r
+        * @see eu.etaxonomy.cdm.api.service.ITaxonService#getRootTaxa(eu.etaxonomy.cdm.model.reference.Reference)\r
         */\r
-       public List<Taxon> getRootTaxa(ReferenceBase sec){\r
+       public List<Taxon> getRootTaxa(Reference sec){\r
                return getRootTaxa(sec, CdmFetch.FETCH_CHILDTAXA(), true);\r
        }\r
 \r
        /**\r
         * FIXME Candidate for harmonization\r
-        * merge with getRootTaxa(ReferenceBase sec, ..., ...)\r
+        * merge with getRootTaxa(Reference sec, ..., ...)\r
         *  (non-Javadoc)\r
-        * @see eu.etaxonomy.cdm.api.service.ITaxonService#getRootTaxa(eu.etaxonomy.cdm.model.reference.ReferenceBase, boolean)\r
+        * @see eu.etaxonomy.cdm.api.service.ITaxonService#getRootTaxa(eu.etaxonomy.cdm.model.reference.Reference, boolean)\r
         */\r
-       public List<Taxon> getRootTaxa(ReferenceBase sec, CdmFetch cdmFetch, boolean onlyWithChildren) {\r
+       public List<Taxon> getRootTaxa(Reference sec, CdmFetch cdmFetch, boolean onlyWithChildren) {\r
                if (cdmFetch == null){\r
                        cdmFetch = CdmFetch.NO_FETCH();\r
                }\r
@@ -140,23 +139,26 @@ public class TaxonServiceImpl extends IdentifiableServiceBase<TaxonBase,ITaxonDa
        \r
        /**\r
         * FIXME Candidate for harmonization\r
-        * merge with getRootTaxa(ReferenceBase sec, ..., ...)\r
+        * merge with getRootTaxa(Reference sec, ..., ...)\r
         *  (non-Javadoc)\r
-        * @see eu.etaxonomy.cdm.api.service.ITaxonService#getRootTaxa(eu.etaxonomy.cdm.model.reference.ReferenceBase, boolean, boolean)\r
+        * @see eu.etaxonomy.cdm.api.service.ITaxonService#getRootTaxa(eu.etaxonomy.cdm.model.reference.Reference, boolean, boolean)\r
         */\r
-       public List<Taxon> getRootTaxa(ReferenceBase sec, boolean onlyWithChildren,\r
+       public List<Taxon> getRootTaxa(Reference 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
+        * @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, ReferenceBase sec, boolean onlyWithChildren,\r
+       public List<Taxon> getRootTaxa(Rank rank, Reference sec, boolean onlyWithChildren,\r
                        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
@@ -175,81 +177,7 @@ public class TaxonServiceImpl extends IdentifiableServiceBase<TaxonBase,ITaxonDa
                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 changeAcceptedTaxonToSynonym(TaxonNode oldTaxonNode, TaxonNode newAcceptedTaxonNode, SynonymRelationshipType synonymRelationshipType, ReferenceBase citation, String citationMicroReference) {\r
-\r
-               // TODO at the moment this method only moves synonym-, concept relations and descriptions to the new accepted taxon\r
-               // in a future version we also want to move cdm data like annotations, marker, so., but we will need a policy for that\r
-               if (oldTaxonNode == null || newAcceptedTaxonNode == null || oldTaxonNode.getTaxon().getName() == null){\r
-                       throw new IllegalArgumentException("A mandatory parameter was null.");\r
-               }\r
-               \r
-               if(oldTaxonNode.equals(newAcceptedTaxonNode)){\r
-                       throw new IllegalArgumentException("Taxon can not be made synonym of its own.");\r
-               }\r
-               \r
-               Taxon oldTaxon = (Taxon) HibernateProxyHelper.deproxy(oldTaxonNode.getTaxon());\r
-               Taxon newAcceptedTaxon = (Taxon) HibernateProxyHelper.deproxy(newAcceptedTaxonNode.getTaxon());\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
-                       }else{\r
-                               synonymRelationshipType = SynonymRelationshipType.HETEROTYPIC_SYNONYM_OF();\r
-                       }\r
-               }\r
-               SynonymRelationship synonmyRelationship = 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
-               \r
-               // CHILD NODES\r
-               if(oldTaxonNode.getChildNodes() != null && oldTaxonNode.getChildNodes().size() != 0){\r
-                       for(TaxonNode childNode : oldTaxonNode.getChildNodes()){\r
-                               newAcceptedTaxonNode.addChildNode(childNode, childNode.getReference(), childNode.getMicroReference(), childNode.getSynonymToBeUsed());\r
-                       }\r
-               }\r
-               \r
-               //Move Taxon RelationShips to new Taxon\r
-               Set<TaxonRelationship> obsoleteTaxonRelationships = new HashSet<TaxonRelationship>();\r
-               for(TaxonRelationship taxonRelationship : oldTaxon.getTaxonRelations()){\r
-                       Taxon fromTaxon = (Taxon) HibernateProxyHelper.deproxy(taxonRelationship.getFromTaxon());\r
-                       Taxon toTaxon = (Taxon) HibernateProxyHelper.deproxy(taxonRelationship.getToTaxon());\r
-                       if (fromTaxon == oldTaxon){\r
-                               newAcceptedTaxon.addTaxonRelation(taxonRelationship.getToTaxon(), taxonRelationship.getType(), \r
-                                               taxonRelationship.getCitation(), taxonRelationship.getCitationMicroReference());\r
-                               \r
-                       }else if(toTaxon == oldTaxon){\r
-                               taxonRelationship.getFromTaxon().addTaxonRelation(newAcceptedTaxon, taxonRelationship.getType(), \r
-                                               taxonRelationship.getCitation(), taxonRelationship.getCitationMicroReference());\r
-\r
-                       }else{\r
-                               logger.warn("Taxon is not part of its own Taxonrelationship");\r
-                       }\r
-                       // Remove old relationships\r
-                       taxonRelationship.setToTaxon(null);\r
-                       taxonRelationship.setFromTaxon(null);\r
-               }\r
-               \r
-               //Move descriptions to new taxon\r
-               for(TaxonDescription description : oldTaxon.getDescriptions()){\r
-                       description.setTitleCache("Description copied from former accepted taxon: " + oldTaxon.getTitleCache() + "(Old title: " + description.getTitleCache()  + ")");\r
-                       newAcceptedTaxon.addDescription(description);\r
-               }\r
-                               \r
-               oldTaxonNode.delete();\r
-               \r
-               return synonmyRelationship.getSynonym();\r
-       }\r
+       \r
 \r
        /*\r
         * (non-Javadoc)\r
@@ -272,24 +200,49 @@ public class TaxonServiceImpl extends IdentifiableServiceBase<TaxonBase,ITaxonDa
        }\r
                \r
        \r
-       /*\r
-        * (non-Javadoc)\r
-        * @see eu.etaxonomy.cdm.api.service.ITaxonService#makeSynonymAcceptedTaxon(eu.etaxonomy.cdm.model.taxon.Synonym, eu.etaxonomy.cdm.model.taxon.Taxon)\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 Taxon changeSynonymToAcceptedTaxon(Synonym synonym, Taxon acceptedTaxon){\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 IllegalArgumentException{\r
+               \r
+               TaxonNameBase acceptedName = acceptedTaxon.getName();\r
+               TaxonNameBase synonymName = synonym.getName();\r
+               HomotypicalGroup synonymHomotypicGroup = synonymName.getHomotypicalGroup();\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 IllegalArgumentException(message);\r
+               }\r
                \r
                Taxon newAcceptedTaxon = Taxon.NewInstance(synonym.getName(), acceptedTaxon.getSec());\r
                \r
-               acceptedTaxon.removeSynonym(synonym);\r
+               SynonymRelationshipType relType = SynonymRelationshipType.HOMOTYPIC_SYNONYM_OF();\r
+               List<Synonym> heteroSynonyms = synonymHomotypicGroup.getSynonymsInGroup(acceptedTaxon.getSec());\r
+               for (Synonym heteroSynonym : heteroSynonyms){\r
+                       if (synonym.equals(heteroSynonym)){\r
+                               acceptedTaxon.removeSynonym(heteroSynonym, false);\r
+                       }else{\r
+                               heteroSynonym.replaceAcceptedTaxon(newAcceptedTaxon, relType, copyCitationInfo, citation, microCitation);\r
+                       }\r
+               }\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
+//             synonym.getName().removeTaxonBase(synonym);\r
+               //TODO correct delete handling still needs to be implemented / checked\r
+               if (deleteSynonym){\r
+                       try {\r
+                               this.delete(synonym);\r
+                       } catch (Exception e) {\r
+                               logger.info("Can't delete old synonym from database");\r
+                       }\r
+               }\r
                \r
+       \r
                return newAcceptedTaxon;\r
        }\r
        \r
-       public Taxon changeSynonymToRelatedTaxon(Synonym synonym, Taxon toTaxon, TaxonRelationshipType taxonRelationshipType, ReferenceBase citation, String microcitation){\r
+       public Taxon changeSynonymToRelatedTaxon(Synonym synonym, Taxon toTaxon, TaxonRelationshipType taxonRelationshipType, Reference citation, String microcitation){\r
                \r
                // Get name from synonym\r
                TaxonNameBase<?, ?> synonymName = synonym.getName();\r
@@ -309,22 +262,90 @@ public class TaxonServiceImpl extends IdentifiableServiceBase<TaxonBase,ITaxonDa
                \r
                return fromTaxon;\r
        }\r
-\r
+       \r
        /* (non-Javadoc)\r
-        * @see eu.etaxonomy.cdm.api.service.IIdentifiableEntityService#updateTitleCache()\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
-       @Override\r
        @Transactional(readOnly = false)\r
-       public void updateTitleCache() {\r
-               Class<TaxonBase> clazz = TaxonBase.class;\r
-               super.updateTitleCache(clazz, null, null);\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
@@ -336,6 +357,9 @@ public class TaxonServiceImpl extends IdentifiableServiceBase<TaxonBase,ITaxonDa
                return new DefaultPagerImpl<TaxonBase>(pageNumber, numberOfResults, pageSize, results);\r
        }\r
 \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
@@ -347,6 +371,9 @@ public class TaxonServiceImpl extends IdentifiableServiceBase<TaxonBase,ITaxonDa
                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
@@ -357,6 +384,9 @@ public class TaxonServiceImpl extends IdentifiableServiceBase<TaxonBase,ITaxonDa
                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
@@ -367,6 +397,9 @@ public class TaxonServiceImpl extends IdentifiableServiceBase<TaxonBase,ITaxonDa
                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
@@ -377,6 +410,9 @@ public class TaxonServiceImpl extends IdentifiableServiceBase<TaxonBase,ITaxonDa
                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
@@ -387,6 +423,9 @@ public class TaxonServiceImpl extends IdentifiableServiceBase<TaxonBase,ITaxonDa
                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
@@ -398,6 +437,9 @@ public class TaxonServiceImpl extends IdentifiableServiceBase<TaxonBase,ITaxonDa
                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
@@ -409,11 +451,17 @@ public class TaxonServiceImpl extends IdentifiableServiceBase<TaxonBase,ITaxonDa
                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
@@ -424,6 +472,26 @@ public class TaxonServiceImpl extends IdentifiableServiceBase<TaxonBase,ITaxonDa
                return heterotypicSynonymyGroups;\r
        }\r
        \r
+       public List<UuidAndTitleCache<TaxonBase>> findTaxaAndNamesForEditor(ITaxonServiceConfigurator configurator){\r
+               \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
+               \r
+               result = dao.getTaxaByNameForEditor(clazz, configurator.getSearchString(), configurator.getClassification(), configurator.getMatchMode(), configurator.getNamedAreas());\r
+               return result;\r
+       }\r
        /* (non-Javadoc)\r
         * @see eu.etaxonomy.cdm.api.service.ITaxonService#findTaxaAndNames(eu.etaxonomy.cdm.api.service.config.ITaxonServiceConfigurator)\r
         */\r
@@ -457,12 +525,13 @@ public class TaxonServiceImpl extends IdentifiableServiceBase<TaxonBase,ITaxonDa
                        if(configurator.getPageSize() != null){ // no point counting if we need all anyway\r
                                numberTaxaResults = \r
                                        dao.countTaxaByName(clazz, \r
-                                               configurator.getSearchString(), configurator.getTaxonomicTree(), configurator.getMatchMode(),\r
+                                               configurator.getSearchString(), 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.getSearchString(), configurator.getTaxonomicTree(), configurator.getMatchMode(),\r
+                                       configurator.getSearchString(), configurator.getClassification(), configurator.getMatchMode(),\r
                                        configurator.getNamedAreas(), configurator.getPageSize(), \r
                                        configurator.getPageNumber(), propertyPath);\r
                        }\r
@@ -502,10 +571,10 @@ public class TaxonServiceImpl extends IdentifiableServiceBase<TaxonBase,ITaxonDa
                        taxa = null;\r
                        numberTaxaResults = 0;\r
                        if(configurator.getPageSize() != null){// no point counting if we need all anyway\r
-                               numberTaxaResults = dao.countTaxaByCommonName(configurator.getSearchString(), configurator.getTaxonomicTree(), configurator.getMatchMode(), configurator.getNamedAreas());\r
+                               numberTaxaResults = dao.countTaxaByCommonName(configurator.getSearchString(), configurator.getClassification(), configurator.getMatchMode(), configurator.getNamedAreas());\r
                        }\r
                        if(configurator.getPageSize() == null || numberTaxaResults > configurator.getPageSize() * configurator.getPageNumber()){\r
-                               taxa = dao.getTaxaByCommonName(configurator.getSearchString(), configurator.getTaxonomicTree(), configurator.getMatchMode(), configurator.getNamedAreas(), configurator.getPageSize(), configurator.getPageNumber(), configurator.getTaxonPropertyPath());\r
+                               taxa = dao.getTaxaByCommonName(configurator.getSearchString(), configurator.getClassification(), configurator.getMatchMode(), configurator.getNamedAreas(), configurator.getPageSize(), configurator.getPageNumber(), configurator.getTaxonPropertyPath());\r
                        }\r
                        if(taxa != null){\r
                                results.addAll(taxa);\r
@@ -522,6 +591,9 @@ public class TaxonServiceImpl extends IdentifiableServiceBase<TaxonBase,ITaxonDa
                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
@@ -540,35 +612,56 @@ public class TaxonServiceImpl extends IdentifiableServiceBase<TaxonBase,ITaxonDa
                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
-       public List<Synonym> createAllInferredSynonyms(TaxonomicTree tree,\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
-       public List<Synonym> createInferredSynonyms(TaxonomicTree tree, Taxon taxon, SynonymRelationshipType type) {\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
                \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
                \r
                return this.dao.findIdenticalTaxonNames(propertyPath);\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
                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
@@ -583,12 +676,18 @@ public class TaxonServiceImpl extends IdentifiableServiceBase<TaxonBase,ITaxonDa
                \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
                \r
                return dao.deleteSynonymRelationships(syn);\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
@@ -602,7 +701,7 @@ public class TaxonServiceImpl extends IdentifiableServiceBase<TaxonBase,ITaxonDa
        }\r
 \r
        /* (non-Javadoc)\r
-        * @see eu.etaxonomy.cdm.api.service.ITaxonService#matchToTaxon(eu.etaxonomy.cdm.model.name.NonViralName)\r
+        * @see eu.etaxonomy.cdm.api.service.ITaxonService#findBestMatchingTaxon(java.lang.String)\r
         */\r
        @Override\r
        public Taxon findBestMatchingTaxon(String taxonName) {\r
@@ -651,6 +750,9 @@ public class TaxonServiceImpl extends IdentifiableServiceBase<TaxonBase,ITaxonDa
                return matchedTaxon;\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
@@ -666,6 +768,37 @@ public class TaxonServiceImpl extends IdentifiableServiceBase<TaxonBase,ITaxonDa
                }\r
                return null;\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, eu.etaxonomy.cdm.model.reference.Reference, java.lang.String)\r
+        */\r
+       @Override\r
+       public Taxon moveSynonymToAnotherTaxon(SynonymRelationship synonymRelation,\r
+                       Taxon toTaxon, SynonymRelationshipType synonymRelationshipType, Reference reference, String referenceDetail) {\r
+               Taxon fromTaxon = synonymRelation.getAcceptedTaxon();\r
+\r
+               toTaxon.addSynonym(synonymRelation.getSynonym(), synonymRelationshipType, reference, referenceDetail);\r
+               \r
+               fromTaxon.removeSynonymRelation(synonymRelation);\r
+                               \r
+               return toTaxon;\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
 }\r