Some commenting and cleaning code
[cdmlib.git] / cdmlib-services / src / main / java / eu / etaxonomy / cdm / api / service / TaxonServiceImpl.java
index 35a370b0f3a2c789d7ca8a4642f139d03e5e740c..1bcf7b446f7952eefbc596d1b8f64ca4ebf051e6 100644 (file)
@@ -27,16 +27,17 @@ import eu.etaxonomy.cdm.api.service.config.ITaxonServiceConfigurator;
 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.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.UuidAndTitleCache;\r
-import eu.etaxonomy.cdm.model.description.CommonTaxonName;\r
-import eu.etaxonomy.cdm.model.description.DescriptionBase;\r
+import eu.etaxonomy.cdm.model.common.RelationshipBase.Direction;\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
@@ -49,15 +50,21 @@ import eu.etaxonomy.cdm.model.taxon.TaxonBase;
 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.persistence.dao.BeanInitializer;\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
 import eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao;\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
 \r
 \r
+/**\r
+ * @author a.kohlbecker\r
+ * @date 10.09.2010\r
+ *\r
+ */\r
 @Service\r
 @Transactional(propagation = Propagation.SUPPORTS, readOnly = true)\r
 public class TaxonServiceImpl extends IdentifiableServiceBase<TaxonBase,ITaxonDao> implements ITaxonService{\r
@@ -66,19 +73,11 @@ public class TaxonServiceImpl extends IdentifiableServiceBase<TaxonBase,ITaxonDa
        @Autowired\r
        private ITaxonNameDao nameDao;\r
        \r
+       @Autowired \r
+       private IDescriptionDao descriptionDao;\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
        /**\r
         * Constructor\r
@@ -242,14 +241,9 @@ public class TaxonServiceImpl extends IdentifiableServiceBase<TaxonBase,ITaxonDa
                }\r
                \r
                //Move descriptions to new taxon\r
-               for(TaxonDescription oldDescription : oldTaxon.getDescriptions()){\r
-                       \r
-                       TaxonDescription newDescription = TaxonDescription.NewInstance(newAcceptedTaxon);\r
-                       newDescription.setTitleCache("Description copied from " + oldTaxon + ". Old title: " + oldDescription.getTitleCache());\r
-                       \r
-                       for(DescriptionElementBase element : oldDescription.getElements()){\r
-                               newDescription.addElement(element);\r
-                       }\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
@@ -262,27 +256,21 @@ public class TaxonServiceImpl extends IdentifiableServiceBase<TaxonBase,ITaxonDa
         * @see eu.etaxonomy.cdm.api.service.ITaxonService#swapSynonymWithAcceptedTaxon(eu.etaxonomy.cdm.model.taxon.Synonym)\r
         */\r
        @Transactional(readOnly = false)\r
-       public void swapSynonymAndAcceptedTaxon(Synonym synonym, Taxon acceptedTaxon, SynonymRelationshipType synonymRelationshipType){\r
+       public void swapSynonymAndAcceptedTaxon(Synonym synonym, Taxon acceptedTaxon){\r
                \r
-               // create a new synonym with the old acceptedName\r
-               TaxonNameBase oldAcceptedTaxonName = acceptedTaxon.getName();\r
+               TaxonNameBase synonymName = synonym.getName();\r
+               synonymName.removeTaxonBase(synonym);\r
+               TaxonNameBase taxonName = acceptedTaxon.getName();\r
+               taxonName.removeTaxonBase(acceptedTaxon);\r
                \r
-               // store the synonyms name\r
-               TaxonNameBase newAcceptedTaxonName = synonym.getName();\r
+               synonym.setName(taxonName);\r
+               acceptedTaxon.setName(synonymName);\r
                \r
-               // remove synonym from oldAcceptedTaxon\r
-               acceptedTaxon.removeSynonym(synonym);\r
-               \r
-               // make synonym name the accepted taxons name\r
-               acceptedTaxon.setName(newAcceptedTaxonName);\r
-               \r
-               // add the new synonym to the acceptedTaxon\r
-               if(synonymRelationshipType == null){\r
-                       synonymRelationshipType = SynonymRelationshipType.SYNONYM_OF();\r
-               }\r
-               \r
-               acceptedTaxon.addSynonymName(oldAcceptedTaxonName, synonymRelationshipType);\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
@@ -300,15 +288,38 @@ public class TaxonServiceImpl extends IdentifiableServiceBase<TaxonBase,ITaxonDa
                \r
                return newAcceptedTaxon;\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
+       \r
+       public Taxon changeSynonymToRelatedTaxon(Synonym synonym, Taxon toTaxon, TaxonRelationshipType taxonRelationshipType, ReferenceBase citation, String microcitation){\r
+               \r
+               // Get name from synonym\r
+               TaxonNameBase<?, ?> synonymName = synonym.getName();\r
+               \r
+               // remove synonym from taxon\r
+               toTaxon.removeSynonym(synonym);\r
+               \r
+               // Create a taxon with synonym name\r
+               Taxon fromTaxon = Taxon.NewInstance(synonymName, null);\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
+               return fromTaxon;\r
        }\r
 \r
+       /* (non-Javadoc)\r
+        * @see eu.etaxonomy.cdm.api.service.IIdentifiableEntityService#updateTitleCache()\r
+        */\r
+       @Override\r
+       @Transactional(readOnly = false)\r
+       public void updateTitleCache() {\r
+               Class<TaxonBase> clazz = TaxonBase.class;\r
+               super.updateTitleCache(clazz, null, null);\r
+       }\r
+       \r
        @Autowired\r
        protected void setDao(ITaxonDao dao) {\r
                this.dao = dao;\r
@@ -325,6 +336,17 @@ public class TaxonServiceImpl extends IdentifiableServiceBase<TaxonBase,ITaxonDa
                return new DefaultPagerImpl<TaxonBase>(pageNumber, numberOfResults, pageSize, results);\r
        }\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 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
@@ -402,6 +424,9 @@ public class TaxonServiceImpl extends IdentifiableServiceBase<TaxonBase,ITaxonDa
                return heterotypicSynonymyGroups;\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
@@ -412,24 +437,34 @@ public class TaxonServiceImpl extends IdentifiableServiceBase<TaxonBase,ITaxonDa
                long numberTaxaResults = 0L;\r
                \r
                Class<? extends TaxonBase> clazz = null;\r
-               if (configurator.isDoTaxa() && configurator.isDoSynonyms()) {\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
-                       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
+                       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.getNamedAreas());\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.getNamedAreas(), configurator.getPageSize(), \r
-                                       configurator.getPageNumber(), configurator.getTaxonPropertyPath());\r
+                                       configurator.getPageNumber(), propertyPath);\r
                        }\r
                }\r
 \r
@@ -440,15 +475,14 @@ public class TaxonServiceImpl extends IdentifiableServiceBase<TaxonBase,ITaxonDa
                }\r
                \r
                numberOfResults += numberTaxaResults;\r
-               \r
+\r
                // Names without taxa \r
-               \r
                if (configurator.isDoNamesWithoutTaxa()) {\r
             int numberNameResults = 0;\r
-            //FIXME implement search by area\r
+           \r
                        List<? extends TaxonNameBase<?,?>> names = \r
                                nameDao.findByName(configurator.getSearchString(), configurator.getMatchMode(), \r
-                                               configurator.getPageSize(), configurator.getPageNumber(), null, null);\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
@@ -463,39 +497,24 @@ public class TaxonServiceImpl extends IdentifiableServiceBase<TaxonBase,ITaxonDa
                }\r
                \r
                // Taxa from common names\r
-               // FIXME the matching common names also must be returned\r
-               // FIXME implement search by area\r
+               \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
+                       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
+                       }\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
+                       }\r
+                       if(taxa != null){\r
+                               results.addAll(taxa);\r
+                       }\r
+                       numberOfResults += numberTaxaResults;\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
+          return new DefaultPagerImpl<IdentifiableEntity>\r
                        (configurator.getPageNumber(), numberOfResults, configurator.getPageSize(), results);\r
        }\r
        \r
@@ -513,11 +532,140 @@ public class TaxonServiceImpl extends IdentifiableServiceBase<TaxonBase,ITaxonDa
                                for(Media media : descElem.getMedia()){\r
                                                                        \r
                                        //find the best matching representation\r
-                                       medRep.add(media.findBestMatchingRepresentation(size, height, widthOrDuration, mimeTypes));\r
+                                       medRep.add(MediaUtils.findBestMatchingRepresentation(media, size, height, widthOrDuration, mimeTypes));\r
                                        \r
                                }\r
                        }\r
                }\r
                return medRep;\r
        }\r
+\r
+       public List<TaxonBase> findTaxaByID(Set<Integer> listOfIDs) {\r
+               return this.dao.findById(listOfIDs);\r
+       }\r
+\r
+       public int countAllRelationships() {\r
+               return this.dao.countAllRelationships();\r
+       }\r
+\r
+       public List<Synonym> createAllInferredSynonyms(TaxonomicTree 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
+               \r
+               return this.dao.createInferredSynonyms(taxon, tree, type);\r
+       }\r
+\r
+       public List<TaxonNameBase> findIdenticalTaxonNames(List<String> propertyPath) {\r
+               \r
+               return this.dao.findIdenticalTaxonNames(propertyPath);\r
+       }\r
+       \r
+       public List<TaxonNameBase> findIdenticalTaxonNameIds(List<String> propertyPath) {\r
+               \r
+               return this.dao.findIdenticalNamesNew(propertyPath);\r
+       }\r
+       \r
+       public String getPhylumName(TaxonNameBase name){\r
+               return this.dao.getPhylumName(name);\r
+       }\r
+       \r
+       private class TaxonAndNameComparator implements Comparator{\r
+\r
+               public int compare(Object arg0, Object arg1) {\r
+                       IdentifiableEntity castArg0 = (IdentifiableEntity) arg0;\r
+                       IdentifiableEntity castArg1 = (IdentifiableEntity) arg1;\r
+                       return castArg0.compareTo(castArg1);\r
+               }\r
+               \r
+       }\r
+\r
+       public long deleteSynonymRelationships(Synonym syn) {\r
+               \r
+               return dao.deleteSynonymRelationships(syn);\r
+       }\r
+\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#matchToTaxon(eu.etaxonomy.cdm.model.name.NonViralName)\r
+        */\r
+       @Override\r
+       public Taxon findBestMatchingTaxon(String taxonName) {\r
+               \r
+               Taxon matchedTaxon = null;\r
+               try{\r
+                       // 1. search for acceptet taxa\r
+                       List<TaxonBase> taxonList = dao.findByNameTitleCache(Taxon.class, taxonName, null, MatchMode.EXACT, null, 0, null, null);\r
+                       for(IdentifiableEntity taxonBaseCandidate : taxonList){\r
+                               if(taxonBaseCandidate instanceof Taxon){\r
+                                       matchedTaxon = (Taxon)taxonBaseCandidate;\r
+                                       if(taxonList.size() > 1){\r
+                                               logger.info(taxonList.size() + " TaxonBases found, using first accepted Taxon: " + matchedTaxon.getTitleCache());\r
+                                               return matchedTaxon;\r
+                                       } else {\r
+                                               logger.info("using accepted Taxon: " + matchedTaxon.getTitleCache());\r
+                                               return matchedTaxon;\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
+                       // 2. search for synonyms\r
+                       List<TaxonBase> synonymList = dao.findByNameTitleCache(Synonym.class, taxonName, null, MatchMode.EXACT, null, 0, null, null);\r
+                       for(TaxonBase taxonBase : synonymList){\r
+                               if(taxonBase instanceof Synonym){\r
+                                       Set<Taxon> acceptetdCandidates = ((Synonym)taxonBase).getAcceptedTaxa();\r
+                                       if(!acceptetdCandidates.isEmpty()){\r
+                                               matchedTaxon = acceptetdCandidates.iterator().next();\r
+                                               if(acceptetdCandidates.size() == 1){\r
+                                                       logger.info(acceptetdCandidates.size() + " Accepted taxa found for synonym " + taxonBase.getTitleCache() + ", using first one: " + matchedTaxon.getTitleCache());\r
+                                                       return matchedTaxon;\r
+                                               } else {\r
+                                                       logger.info("using accepted Taxon " +  matchedTaxon.getTitleCache() + "for synonym " + taxonBase.getTitleCache());\r
+                                                       return matchedTaxon;\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
+               } catch (Exception e){\r
+                       logger.error(e);\r
+               }\r
+               \r
+               return matchedTaxon;\r
+       }\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
 }\r