X-Git-Url: https://dev.e-taxonomy.eu/gitweb/cdmlib.git/blobdiff_plain/27bed44b3320a4a9b21fb105604a5b19f2d7abdc..b0f33c74dc700b1d772380e8a737406689fa9c6e:/cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/TaxonServiceImpl.java diff --git a/cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/TaxonServiceImpl.java b/cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/TaxonServiceImpl.java index e71243b5e4..8162c1fbf3 100644 --- a/cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/TaxonServiceImpl.java +++ b/cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/TaxonServiceImpl.java @@ -11,6 +11,7 @@ package eu.etaxonomy.cdm.api.service; import java.io.IOException; import java.util.ArrayList; +import java.util.Collections; import java.util.EnumSet; import java.util.HashMap; import java.util.HashSet; @@ -33,6 +34,7 @@ import org.apache.lucene.search.SortField; import org.apache.lucene.search.grouping.TopGroups; import org.apache.lucene.search.join.ScoreMode; import org.apache.lucene.util.BytesRef; +import org.hibernate.criterion.Criterion; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -52,6 +54,7 @@ import eu.etaxonomy.cdm.api.service.exception.DataChangeNoRollbackException; import eu.etaxonomy.cdm.api.service.exception.HomotypicalGroupChangeException; import eu.etaxonomy.cdm.api.service.exception.ReferencedObjectUndeletableException; import eu.etaxonomy.cdm.api.service.pager.Pager; +import eu.etaxonomy.cdm.api.service.pager.impl.AbstractPagerImpl; import eu.etaxonomy.cdm.api.service.pager.impl.DefaultPagerImpl; import eu.etaxonomy.cdm.api.service.search.ILuceneIndexToolProvider; import eu.etaxonomy.cdm.api.service.search.ISearchResultBuilder; @@ -64,6 +67,8 @@ import eu.etaxonomy.cdm.api.service.search.SearchResult; import eu.etaxonomy.cdm.api.service.search.SearchResultBuilder; import eu.etaxonomy.cdm.api.service.util.TaxonRelationshipEdge; import eu.etaxonomy.cdm.common.monitor.IProgressMonitor; +import eu.etaxonomy.cdm.compare.taxon.HomotypicGroupTaxonComparator; +import eu.etaxonomy.cdm.compare.taxon.TaxonComparator; import eu.etaxonomy.cdm.exception.UnpublishedException; import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper; import eu.etaxonomy.cdm.hibernate.search.AcceptedTaxonBridge; @@ -72,16 +77,15 @@ import eu.etaxonomy.cdm.model.CdmBaseType; import eu.etaxonomy.cdm.model.common.Annotation; import eu.etaxonomy.cdm.model.common.AnnotationType; import eu.etaxonomy.cdm.model.common.CdmBase; -import eu.etaxonomy.cdm.model.common.DefinedTerm; import eu.etaxonomy.cdm.model.common.IdentifiableEntity; import eu.etaxonomy.cdm.model.common.IdentifiableSource; import eu.etaxonomy.cdm.model.common.Language; import eu.etaxonomy.cdm.model.common.MarkerType; -import eu.etaxonomy.cdm.model.common.OriginalSourceType; import eu.etaxonomy.cdm.model.common.RelationshipBase.Direction; import eu.etaxonomy.cdm.model.description.CommonTaxonName; import eu.etaxonomy.cdm.model.description.DescriptionBase; import eu.etaxonomy.cdm.model.description.DescriptionElementBase; +import eu.etaxonomy.cdm.model.description.DescriptionElementSource; import eu.etaxonomy.cdm.model.description.Distribution; import eu.etaxonomy.cdm.model.description.Feature; import eu.etaxonomy.cdm.model.description.IIdentificationKey; @@ -93,6 +97,7 @@ import eu.etaxonomy.cdm.model.description.TaxonInteraction; import eu.etaxonomy.cdm.model.description.TaxonNameDescription; import eu.etaxonomy.cdm.model.location.NamedArea; import eu.etaxonomy.cdm.model.media.Media; +import eu.etaxonomy.cdm.model.metadata.SecReferenceHandlingEnum; import eu.etaxonomy.cdm.model.name.HomotypicalGroup; import eu.etaxonomy.cdm.model.name.IZoologicalName; import eu.etaxonomy.cdm.model.name.Rank; @@ -101,9 +106,9 @@ import eu.etaxonomy.cdm.model.name.TaxonNameFactory; import eu.etaxonomy.cdm.model.occurrence.DerivedUnit; import eu.etaxonomy.cdm.model.occurrence.DeterminationEvent; import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase; +import eu.etaxonomy.cdm.model.reference.OriginalSourceType; import eu.etaxonomy.cdm.model.reference.Reference; import eu.etaxonomy.cdm.model.taxon.Classification; -import eu.etaxonomy.cdm.model.taxon.HomotypicGroupTaxonComparator; import eu.etaxonomy.cdm.model.taxon.ITaxonTreeNode; import eu.etaxonomy.cdm.model.taxon.Synonym; import eu.etaxonomy.cdm.model.taxon.SynonymType; @@ -112,6 +117,8 @@ import eu.etaxonomy.cdm.model.taxon.TaxonBase; import eu.etaxonomy.cdm.model.taxon.TaxonNode; import eu.etaxonomy.cdm.model.taxon.TaxonRelationship; import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType; +import eu.etaxonomy.cdm.model.term.DefinedTerm; +import eu.etaxonomy.cdm.persistence.dao.common.Restriction; import eu.etaxonomy.cdm.persistence.dao.initializer.AbstractBeanInitializer; import eu.etaxonomy.cdm.persistence.dao.name.ITaxonNameDao; import eu.etaxonomy.cdm.persistence.dao.occurrence.IOccurrenceDao; @@ -161,6 +168,9 @@ public class TaxonServiceImpl @Autowired private IDescriptionService descriptionService; + + @Autowired + private IReferenceService referenceService; // // @Autowired // private IOrderedTermVocabularyDao orderedVocabularyDao; @@ -184,10 +194,6 @@ public class TaxonServiceImpl // ****************************** METHODS ********************************/ - - /** - * {@inheritDoc} - */ @Override public TaxonBase load(UUID uuid, boolean includeUnpublished, List propertyPaths) { return dao.load(uuid, includeUnpublished, propertyPaths); @@ -200,34 +206,131 @@ public class TaxonServiceImpl @Override @Transactional(readOnly = false) - public UpdateResult swapSynonymAndAcceptedTaxon(Synonym synonym, Taxon acceptedTaxon){ - UpdateResult result = new UpdateResult(); - TaxonName synonymName = synonym.getName(); + public UpdateResult swapSynonymAndAcceptedTaxon(Synonym synonym, Taxon acceptedTaxon, boolean setNameInSource){ + UpdateResult result = new UpdateResult(); + acceptedTaxon.removeSynonym(synonym); + TaxonName synonymName = synonym.getName(); + TaxonName taxonName = HibernateProxyHelper.deproxy(acceptedTaxon.getName()); + + boolean sameHomotypicGroup = synonymName.getHomotypicalGroup().equals(taxonName.getHomotypicalGroup()); + synonymName.removeTaxonBase(synonym); - TaxonName taxonName = acceptedTaxon.getName(); - taxonName.removeTaxonBase(acceptedTaxon); - - synonym.setName(taxonName); - synonym.setTitleCache(null, false); - synonym.getTitleCache(); - acceptedTaxon.setName(synonymName); - acceptedTaxon.setTitleCache(null, false); - acceptedTaxon.getTitleCache(); - saveOrUpdate(synonym); - saveOrUpdate(acceptedTaxon); - result.addUpdatedObject(acceptedTaxon); - result.addUpdatedObject(synonym); - return result; - // the accepted taxon needs a new uuid because the concept has changed - // FIXME this leads to an error "HibernateException: immutable natural identifier of an instance of eu.etaxonomy.cdm.model.taxon.Taxon was altered" - //acceptedTaxon.setUuid(UUID.randomUUID()); - } + //taxonName.removeTaxonBase(acceptedTaxon); + + List synonyms = new ArrayList<>(); + for (Synonym syn: acceptedTaxon.getSynonyms()){ + syn = HibernateProxyHelper.deproxy(syn, Synonym.class); + synonyms.add(syn); + } + for (Synonym syn: synonyms){ + acceptedTaxon.removeSynonym(syn); + } + Taxon newTaxon = acceptedTaxon.clone(); + newTaxon.getDescriptions().clear(); + Set descriptionsToCopy = new HashSet<>(); + for (TaxonDescription desc: acceptedTaxon.getDescriptions()){ + descriptionsToCopy.add(desc); + } + for (TaxonDescription description: descriptionsToCopy){ + newTaxon.addDescription(description); + } + newTaxon.setName(synonymName); + newTaxon.setSec(synonym.getSec()); + newTaxon.setPublish(synonym.isPublish()); + for (Synonym syn: synonyms){ + if (!syn.getName().equals(newTaxon.getName())){ + newTaxon.addSynonym(syn, syn.getType()); + } + } + + //move all data to new taxon + //Move Taxon RelationShips to new Taxon + for(TaxonRelationship taxonRelationship : newTaxon.getTaxonRelations()){ + newTaxon.removeTaxonRelation(taxonRelationship); + } + + for(TaxonRelationship taxonRelationship : acceptedTaxon.getTaxonRelations()){ + Taxon fromTaxon = HibernateProxyHelper.deproxy(taxonRelationship.getFromTaxon()); + Taxon toTaxon = HibernateProxyHelper.deproxy(taxonRelationship.getToTaxon()); + if (fromTaxon == acceptedTaxon){ + newTaxon.addTaxonRelation(taxonRelationship.getToTaxon(), taxonRelationship.getType(), + taxonRelationship.getCitation(), taxonRelationship.getCitationMicroReference()); + }else if(toTaxon == acceptedTaxon){ + fromTaxon.addTaxonRelation(newTaxon, taxonRelationship.getType(), + taxonRelationship.getCitation(), taxonRelationship.getCitationMicroReference()); + saveOrUpdate(fromTaxon); + + }else{ + logger.warn("Taxon is not part of its own Taxonrelationship"); + } + // Remove old relationships + + fromTaxon.removeTaxonRelation(taxonRelationship); + toTaxon.removeTaxonRelation(taxonRelationship); + taxonRelationship.setToTaxon(null); + taxonRelationship.setFromTaxon(null); + } + + //Move descriptions to new taxon + List descriptions = new ArrayList( newTaxon.getDescriptions()); //to avoid concurrent modification errors (newAcceptedTaxon.addDescription() modifies also oldtaxon.descritpions()) + for(TaxonDescription description : descriptions){ + String message = "Description copied from former accepted taxon: %s (Old title: %s)"; + message = String.format(message, acceptedTaxon.getTitleCache(), description.getTitleCache()); + description.setTitleCache(message, true); + if(setNameInSource){ + for (DescriptionElementBase element: description.getElements()){ + for (DescriptionElementSource source: element.getSources()){ + if (source.getNameUsedInSource() == null){ + source.setNameUsedInSource(taxonName); + } + } + } + } +// //oldTaxon.removeDescription(description, false); + // newTaxon.addDescription(description); + } + List nodes = new ArrayList<>(acceptedTaxon.getTaxonNodes()); + for (TaxonNode node: nodes){ + node = HibernateProxyHelper.deproxy(node, TaxonNode.class); + TaxonNode parent = node.getParent(); + acceptedTaxon.removeTaxonNode(node); + node.setTaxon(newTaxon); + if (parent != null){ + parent.addChildNode(node, null, null); + } + + } + Synonym newSynonym = synonym.clone(); + newSynonym.setName(taxonName); + newSynonym.setSec(acceptedTaxon.getSec()); + newSynonym.setPublish(acceptedTaxon.isPublish()); + if (sameHomotypicGroup){ + newTaxon.addSynonym(newSynonym, SynonymType.HOMOTYPIC_SYNONYM_OF()); + }else{ + newTaxon.addSynonym(newSynonym, SynonymType.HETEROTYPIC_SYNONYM_OF()); + } + + saveOrUpdate(newSynonym); + saveOrUpdate(newTaxon); + TaxonDeletionConfigurator conf = new TaxonDeletionConfigurator(); + conf.setDeleteNameIfPossible(false); + SynonymDeletionConfigurator confSyn = new SynonymDeletionConfigurator(); + confSyn.setDeleteNameIfPossible(false); + result.setCdmEntity(newTaxon); + + DeleteResult deleteResult = deleteTaxon(acceptedTaxon.getUuid(), conf, null); + if (synonym.isPersited()){ + deleteResult.includeResult(deleteSynonym(synonym, confSyn)); + } + result.includeResult(deleteResult); + return result; + } @Override @Transactional(readOnly = false) - public UpdateResult changeSynonymToAcceptedTaxon(Synonym synonym, Taxon acceptedTaxon, boolean deleteSynonym) { + public UpdateResult changeSynonymToAcceptedTaxon(Synonym synonym, Taxon acceptedTaxon, Reference newSecRef, String microRef, boolean deleteSynonym) { UpdateResult result = new UpdateResult(); TaxonName acceptedName = acceptedTaxon.getName(); TaxonName synonymName = synonym.getName(); @@ -240,8 +343,8 @@ public class TaxonServiceImpl result.setAbort(); return result; } - - Taxon newAcceptedTaxon = Taxon.NewInstance(synonymName, acceptedTaxon.getSec()); + Taxon newAcceptedTaxon = Taxon.NewInstance(synonymName, newSecRef, microRef); + newAcceptedTaxon.setPublish(synonym.isPublish()); dao.save(newAcceptedTaxon); result.setCdmEntity(newAcceptedTaxon); SynonymType relTypeForGroup = SynonymType.HOMOTYPIC_SYNONYM_OF(); @@ -278,23 +381,52 @@ public class TaxonServiceImpl public UpdateResult changeSynonymToAcceptedTaxon(UUID synonymUuid, UUID acceptedTaxonUuid, UUID newParentNodeUuid, + UUID newSec, + String microReference, + SecReferenceHandlingEnum secHandling, boolean deleteSynonym) { UpdateResult result = new UpdateResult(); Synonym synonym = CdmBase.deproxy(dao.load(synonymUuid), Synonym.class); Taxon acceptedTaxon = CdmBase.deproxy(dao.load(acceptedTaxonUuid), Taxon.class); - result = changeSynonymToAcceptedTaxon(synonym, acceptedTaxon, deleteSynonym); - Taxon newTaxon = (Taxon)result.getCdmEntity(); TaxonNode newParentNode = taxonNodeDao.load(newParentNodeUuid); + Reference newSecRef = null; + switch (secHandling){ + case AlwaysDelete: + newSecRef = null; + break; + case KeepAlways: + newSecRef = synonym.getSec(); + break; + case UseNewParentSec: + newSecRef = newParentNode.getTaxon() != null? newParentNode.getTaxon().getSec(): null; + break; + case KeepWhenSame: + Reference parentSec = newParentNode.getTaxon() != null? newParentNode.getTaxon().getSec(): null; + Reference synSec = synonym.getSec(); + if (parentSec != null && synSec != null && parentSec.equals(synSec)){ + newSecRef = synonym.getSec(); + }else{ + newSecRef = CdmBase.deproxy(referenceService.load(newSec)); + } + case WarningSelect: + newSecRef = CdmBase.deproxy(referenceService.load(newSec)); + + default: + break; + } + + + result = changeSynonymToAcceptedTaxon(synonym, acceptedTaxon, newSecRef, microReference, deleteSynonym); + Taxon newTaxon = (Taxon)result.getCdmEntity(); + TaxonNode newNode = newParentNode.addChildTaxon(newTaxon, null, null); taxonNodeDao.save(newNode); result.addUpdatedObject(newTaxon); result.addUpdatedObject(acceptedTaxon); result.setCdmEntity(newNode); return result; - } - - + } @Override @Transactional(readOnly = false) @@ -332,6 +464,7 @@ public class TaxonServiceImpl */ // Create a taxon with synonym name Taxon fromTaxon = Taxon.NewInstance(synonymName, null); + fromTaxon.setPublish(synonym.isPublish()); save(fromTaxon); fromTaxon.setAppendedPhrase(synonym.getAppendedPhrase()); @@ -391,16 +524,15 @@ public class TaxonServiceImpl SynonymType relType = isHomotypicToTaxon? SynonymType.HOMOTYPIC_SYNONYM_OF() : SynonymType.HETEROTYPIC_SYNONYM_OF(); targetTaxon.addSynonym(synonym, relType); } - } @Override @Transactional(readOnly = false) - public void updateCaches(Class clazz, Integer stepSize, IIdentifiableEntityCacheStrategy cacheStrategy, IProgressMonitor monitor) { + public UpdateResult updateCaches(Class clazz, Integer stepSize, IIdentifiableEntityCacheStrategy cacheStrategy, IProgressMonitor monitor) { if (clazz == null){ clazz = TaxonBase.class; } - super.updateCachesImpl(clazz, stepSize, cacheStrategy, monitor); + return super.updateCachesImpl(clazz, stepSize, cacheStrategy, monitor); } @Override @@ -410,27 +542,25 @@ public class TaxonServiceImpl } @Override - public Pager findTaxaByName(Class clazz, String uninomial, String infragenericEpithet, String specificEpithet, String infraspecificEpithet, String authorship, Rank rank, Integer pageSize,Integer pageNumber) { - long numberOfResults = dao.countTaxaByName(clazz, uninomial, infragenericEpithet, specificEpithet, infraspecificEpithet, rank); + public Pager findTaxaByName(Class clazz, String uninomial, String infragenericEpithet, String specificEpithet, + String infraspecificEpithet, String authorshipCache, Rank rank, Integer pageSize,Integer pageNumber, List propertyPaths) { + long numberOfResults = dao.countTaxaByName(clazz, uninomial, infragenericEpithet, specificEpithet, infraspecificEpithet, authorshipCache, rank); - List results = new ArrayList<>(); + List results = new ArrayList<>(); if(numberOfResults > 0) { // no point checking again - results = dao.findTaxaByName(clazz, uninomial, infragenericEpithet, specificEpithet, infraspecificEpithet, authorship, rank, pageSize, pageNumber); + results = dao.findTaxaByName(clazz, uninomial, infragenericEpithet, specificEpithet, infraspecificEpithet, authorshipCache, rank, + pageSize, pageNumber, propertyPaths); } return new DefaultPagerImpl<>(pageNumber, numberOfResults, pageSize, results); } @Override - public List listTaxaByName(Class clazz, String uninomial, String infragenericEpithet, String specificEpithet, String infraspecificEpithet, String authorship, Rank rank, Integer pageSize,Integer pageNumber) { - long numberOfResults = dao.countTaxaByName(clazz, uninomial, infragenericEpithet, specificEpithet, infraspecificEpithet, rank); + public List listTaxaByName(Class clazz, String uninomial, String infragenericEpithet, String specificEpithet, + String infraspecificEpithet, String authorshipCache, Rank rank, Integer pageSize,Integer pageNumber, List propertyPaths) { - List results = new ArrayList<>(); - if(numberOfResults > 0) { // no point checking again - results = dao.findTaxaByName(clazz, uninomial, infragenericEpithet, specificEpithet, infraspecificEpithet, authorship, rank, pageSize, pageNumber); - } - - return results; + return findTaxaByName(clazz, uninomial, infragenericEpithet, specificEpithet, infragenericEpithet, authorshipCache, rank, + pageSize, pageNumber, propertyPaths).getRecords(); } @Override @@ -483,16 +613,37 @@ public class TaxonServiceImpl @Override public List listTaxonRelationships(Set types, - Integer pageSize, Integer pageStart, List orderHints, List propertyPaths) { - Long numberOfResults = dao.countTaxonRelationships(types); + Integer pageSize, Integer pageNumber, List orderHints, List propertyPaths) { + Long numberOfResults = dao.countTaxonRelationships(types); List results = new ArrayList<>(); if(numberOfResults > 0) { - results = dao.getTaxonRelationships(types, pageSize, pageStart, orderHints, propertyPaths); + results = dao.getTaxonRelationships(types, pageSize, pageNumber, orderHints, propertyPaths); } return results; } + @Override + public Pager page(Class clazz, List> restrictions, Integer pageSize, + Integer pageIndex, List orderHints, List propertyPaths) { + return page(clazz, restrictions, pageSize, pageIndex, orderHints, propertyPaths, INCLUDE_UNPUBLISHED); + } + + @Override + public Pager page(Class clazz, List> restrictions, Integer pageSize, + Integer pageIndex, List orderHints, List propertyPaths, boolean includeUnpublished) { + + List records; + long resultSize = dao.count(clazz, restrictions); + if(AbstractPagerImpl.hasResultsInRange(resultSize, pageIndex, pageSize)){ + records = dao.list(clazz, restrictions, pageSize, pageIndex, orderHints, propertyPaths, includeUnpublished); + } else { + records = new ArrayList<>(); + } + Pager pager = new DefaultPagerImpl<>(pageIndex, resultSize, pageSize, records); + return pager; + } + @Override public Taxon findAcceptedTaxonFor(UUID synonymUuid, UUID classificationUuid, boolean includeUnpublished, List propertyPaths) throws UnpublishedException{ @@ -541,7 +692,6 @@ public class TaxonServiceImpl return relatedTaxa; } - /** * Recursively collect related taxa for the given taxon . The returned list will also include the * taxon supplied as parameter. @@ -622,7 +772,6 @@ public class TaxonServiceImpl taxon = (Taxon)dao.load(taxon.getUuid(), propertyPaths); HomotypicGroupTaxonComparator comparator = new HomotypicGroupTaxonComparator(taxon); - //homotypic result.add(taxon.getHomotypicSynonymsByHomotypicGroup(comparator)); @@ -633,7 +782,6 @@ public class TaxonServiceImpl } return result; - } @Override @@ -671,6 +819,7 @@ public class TaxonServiceImpl @Override public Pager findTaxaAndNames(IFindTaxaAndNamesConfigurator configurator) { + @SuppressWarnings("rawtypes") List results = new ArrayList<>(); long numberOfResults = 0; // overall number of results (as opposed to number of results per page) List taxa = null; @@ -699,7 +848,7 @@ public class TaxonServiceImpl configurator.getMatchMode(), configurator.getNamedAreas(), configurator.isIncludeUnpublished(), configurator.getOrder(), configurator.getPageSize(), configurator.getPageNumber(), propertyPath); } - } + } if (logger.isDebugEnabled()) { logger.debug(numberTaxaResults + " matching taxa counted"); } @@ -798,6 +947,7 @@ public class TaxonServiceImpl if(includeOccurrences != null && includeOccurrences) { logger.trace("listMedia() - includeOccurrences"); + @SuppressWarnings("rawtypes") Set specimensOrObservations = new HashSet<>(); // --- Specimens for (Taxon t : taxa) { @@ -853,7 +1003,6 @@ public class TaxonServiceImpl } } - logger.trace("listMedia() - initialize"); beanInitializer.initializeAll(taxonMedia, propertyPath); @@ -864,7 +1013,7 @@ public class TaxonServiceImpl @Override public List findTaxaByID(Set listOfIDs) { - return this.dao.loadList(listOfIDs, null); + return this.dao.loadList(listOfIDs, null, null); } @Override @@ -877,11 +1026,6 @@ public class TaxonServiceImpl return this.dao.countSynonyms(onlyAttachedToTaxon); } - @Override - public List findIdenticalTaxonNames(List propertyPath) { - return this.dao.findIdenticalTaxonNames(propertyPath); - } - @Override @Transactional(readOnly=false) public DeleteResult deleteTaxon(UUID taxonUUID, TaxonDeletionConfigurator config, UUID classificationUuid) { @@ -898,6 +1042,7 @@ public class TaxonServiceImpl } taxon = HibernateProxyHelper.deproxy(taxon); Classification classification = HibernateProxyHelper.deproxy(classificationDao.load(classificationUuid), Classification.class); + config.setClassificationUuid(classificationUuid); result = isDeletable(taxonUUID, config); if (result.isOk()){ @@ -933,8 +1078,8 @@ public class TaxonServiceImpl configRelTaxon.setDeleteConceptRelationships(true); for (TaxonRelationship taxRel: taxon.getTaxonRelations()){ - if (config.isDeleteMisappliedNamesAndInvalidDesignations() - && taxRel.getType().isMisappliedNameOrInvalidDesignation() + if (config.isDeleteMisappliedNames() + && taxRel.getType().isMisappliedName() && taxon.equals(taxRel.getToTaxon())){ this.deleteTaxon(taxRel.getFromTaxon().getUuid(), config, classificationUuid); } else if (config.isDeleteConceptRelationships() && taxRel.getType().isConceptRelationship()){ @@ -963,8 +1108,6 @@ public class TaxonServiceImpl break; } removeDescriptions.add(desc); - - } if (result.isOk()){ for (TaxonDescription desc: removeDescriptions){ @@ -976,101 +1119,99 @@ public class TaxonServiceImpl } } - - if (! config.isDeleteTaxonNodes() || (!config.isDeleteInAllClassifications() && classification == null && taxon.getTaxonNodes().size() > 1)){ - result.addException(new Exception( "Taxon can't be deleted as it is used in more than one classification.")); - }else{ - if (taxon.getTaxonNodes().size() != 0){ - Set nodes = taxon.getTaxonNodes(); - Iterator iterator = nodes.iterator(); - TaxonNode node = null; - boolean deleteChildren; - if (config.getTaxonNodeConfig().getChildHandling().equals(ChildHandling.DELETE)){ - deleteChildren = true; - }else { - deleteChildren = false; - } - boolean success = true; - if (!config.isDeleteInAllClassifications() && !(classification == null)){ - while (iterator.hasNext()){ - node = iterator.next(); - if (node.getClassification().equals(classification)){ - break; - } - node = null; - } - if (node != null){ - HibernateProxyHelper.deproxy(node, TaxonNode.class); - success =taxon.removeTaxonNode(node, deleteChildren); - nodeService.delete(node); - result.addDeletedObject(node); - } else { - result.setError(); - result.addException(new Exception("The taxon can not be deleted because it is not used in defined classification.")); + if (! config.isDeleteTaxonNodes() || (!config.isDeleteInAllClassifications() && classification == null && taxon.getTaxonNodes().size() > 1)){ + result.addException(new Exception( "Taxon can't be deleted as it is used in more than one classification.")); + }else{ + if (taxon.getTaxonNodes().size() != 0){ + Set nodes = taxon.getTaxonNodes(); + Iterator iterator = nodes.iterator(); + TaxonNode node = null; + boolean deleteChildren; + if (config.getTaxonNodeConfig().getChildHandling().equals(ChildHandling.DELETE)){ + deleteChildren = true; + }else { + deleteChildren = false; } - } else if (config.isDeleteInAllClassifications()){ - List nodesList = new ArrayList<>(); - nodesList.addAll(taxon.getTaxonNodes()); - for (ITaxonTreeNode treeNode: nodesList){ - TaxonNode taxonNode = (TaxonNode) treeNode; - if(!deleteChildren){ - Object[] childNodes = taxonNode.getChildNodes().toArray(); - for (Object childNode: childNodes){ - TaxonNode childNodeCast = (TaxonNode) childNode; - taxonNode.getParent().addChildNode(childNodeCast, childNodeCast.getReference(), childNodeCast.getMicroReference()); + boolean success = true; + if (!config.isDeleteInAllClassifications() && !(classification == null)){ + while (iterator.hasNext()){ + node = iterator.next(); + if (node.getClassification().equals(classification)){ + break; + } + node = null; + } + if (node != null){ + HibernateProxyHelper.deproxy(node, TaxonNode.class); + success =taxon.removeTaxonNode(node, deleteChildren); + nodeService.delete(node); + result.addDeletedObject(node); + } else { + result.setError(); + result.addException(new Exception("The taxon can not be deleted because it is not used in defined classification.")); + } + } else if (config.isDeleteInAllClassifications()){ + List nodesList = new ArrayList<>(); + nodesList.addAll(taxon.getTaxonNodes()); + for (ITaxonTreeNode treeNode: nodesList){ + TaxonNode taxonNode = (TaxonNode) treeNode; + if(!deleteChildren){ + Object[] childNodes = taxonNode.getChildNodes().toArray(); + for (Object childNode: childNodes){ + TaxonNode childNodeCast = (TaxonNode) childNode; + taxonNode.getParent().addChildNode(childNodeCast, childNodeCast.getReference(), childNodeCast.getMicroReference()); + } } } + config.getTaxonNodeConfig().setDeleteElement(false); + DeleteResult resultNodes = nodeService.deleteTaxonNodes(nodesList, config); + if (!resultNodes.isOk()){ + result.addExceptions(resultNodes.getExceptions()); + result.setStatus(resultNodes.getStatus()); + } else { + result.addUpdatedObjects(resultNodes.getUpdatedObjects()); + } } - config.getTaxonNodeConfig().setDeleteElement(false); - DeleteResult resultNodes = nodeService.deleteTaxonNodes(nodesList, config); - if (!resultNodes.isOk()){ - result.addExceptions(resultNodes.getExceptions()); - result.setStatus(resultNodes.getStatus()); - } else { - result.addUpdatedObjects(resultNodes.getUpdatedObjects()); + if (!success){ + result.setError(); + result.addException(new Exception("The taxon can not be deleted because the taxon node can not be removed.")); } } - if (!success){ - result.setError(); - result.addException(new Exception("The taxon can not be deleted because the taxon node can not be removed.")); - } - } - } - TaxonName name = taxon.getName(); - taxon.setName(null); - this.saveOrUpdate(taxon); - - if ((taxon.getTaxonNodes() == null || taxon.getTaxonNodes().size()== 0) && result.isOk()){ - try{ - dao.delete(taxon); - result.addDeletedObject(taxon); - }catch(Exception e){ - result.addException(e); - result.setError(); } - } else { - result.setError(); - result.addException(new Exception("The Taxon can't be deleted because it is used in a classification.")); + TaxonName name = taxon.getName(); + taxon.setName(null); + this.saveOrUpdate(taxon); + + if ((taxon.getTaxonNodes() == null || taxon.getTaxonNodes().size()== 0) && result.isOk()){ + try{ + dao.delete(taxon); + result.addDeletedObject(taxon); + }catch(Exception e){ + result.addException(e); + result.setError(); + } + } else { + result.setError(); + result.addException(new Exception("The Taxon can't be deleted because it is used in a classification.")); - } - //TaxonName - if (config.isDeleteNameIfPossible() && result.isOk()){ - DeleteResult nameResult = new DeleteResult(); - //remove name if possible (and required) - if (name != null ){ - nameResult = nameService.delete(name.getUuid(), config.getNameDeletionConfig()); - } - if (nameResult.isError() || nameResult.isAbort()){ - result.addRelatedObject(name); - result.addExceptions(nameResult.getExceptions()); - }else{ - result.includeResult(nameResult); - } - } + } + //TaxonName + if (config.isDeleteNameIfPossible() && result.isOk()){ + DeleteResult nameResult = new DeleteResult(); + //remove name if possible (and required) + if (name != null ){ + nameResult = nameService.delete(name.getUuid(), config.getNameDeletionConfig()); + } + if (nameResult.isError() || nameResult.isAbort()){ + result.addRelatedObject(name); + result.addExceptions(nameResult.getExceptions()); + }else{ + result.includeResult(nameResult); + } + } } return result; - } @Override @@ -1084,10 +1225,8 @@ public class TaxonServiceImpl @Transactional(readOnly = false) public DeleteResult deleteSynonym(UUID synonymUuid, SynonymDeletionConfigurator config) { return deleteSynonym((Synonym)dao.load(synonymUuid), config); - } - @Override @Transactional(readOnly = false) public DeleteResult deleteSynonym(Synonym synonym, SynonymDeletionConfigurator config) { @@ -1138,18 +1277,15 @@ public class TaxonServiceImpl result.addDeletedObject(name); } } - } return result; } @Override - public List findIdenticalTaxonNameIds(List propertyPath) { - - return this.dao.findIdenticalNamesNew(propertyPath); + public Map>> findIdenticalTaxonNames(List sourceRefUuids, List propertyPaths) { + return this.dao.findIdenticalNames(sourceRefUuids, propertyPaths); } - @Override public Taxon findBestMatchingTaxon(String taxonName) { MatchingTaxonConfigurator config = MatchingTaxonConfigurator.NewInstance(); @@ -1195,7 +1331,6 @@ public class TaxonServiceImpl countEqualCandidates = 1; continue; } - }else{ //not Taxon.class continue; } @@ -1212,7 +1347,6 @@ public class TaxonServiceImpl } } - // 2. search for synonyms if (config.isIncludeSynonyms()){ List synonymList = dao.findByNameTitleCache(false, true, config.isIncludeUnpublished(), @@ -1365,7 +1499,8 @@ public class TaxonServiceImpl } @Override - public List> getUuidAndTitleCache(Class clazz, Integer limit, String pattern) { + public List> getUuidAndTitleCache(Class clazz, Integer limit, String pattern) { + return dao.getUuidAndTitleCache(clazz, limit, pattern); } @@ -1394,6 +1529,7 @@ public class TaxonServiceImpl // --- initialize taxa, thighlight matches .... ISearchResultBuilder searchResultBuilder = new SearchResultBuilder(luceneSearch, luceneSearch.getQuery()); + @SuppressWarnings("rawtypes") List> searchResults = searchResultBuilder.createResultSet( topDocsResultSet, luceneSearch.getHighlightFields(), dao, idFieldMap, propertyPaths); @@ -1401,6 +1537,43 @@ public class TaxonServiceImpl return new DefaultPagerImpl<>(pageNumber, totalHits, pageSize, searchResults); } + @Transactional(readOnly = true) + @Override + public Pager findByTitleWithRestrictions(Class clazz, String queryString, MatchMode matchmode, List> restrictions, Integer pageSize, Integer pageNumber, List orderHints, List propertyPaths) { + long numberOfResults = dao.countByTitleWithRestrictions(clazz, queryString, matchmode, restrictions); + + long numberOfResults_doubtful = dao.countByTitleWithRestrictions(clazz, "?".concat(queryString), matchmode, restrictions); + List results = new ArrayList<>(); + if(numberOfResults > 0 || numberOfResults_doubtful > 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize) + + results = dao.findByTitleWithRestrictions(clazz, queryString, matchmode, restrictions, pageSize, pageNumber, orderHints, propertyPaths); + results.addAll(dao.findByTitleWithRestrictions(clazz, "?".concat(queryString), matchmode, restrictions, pageSize, pageNumber, orderHints, propertyPaths)); + } + Collections.sort(results, new TaxonComparator()); + return new DefaultPagerImpl<>(pageNumber, numberOfResults, pageSize, results); + } + + @Transactional(readOnly = true) + @Override + public Pager findByTitle(Class clazz, String queryString,MatchMode matchmode, List criteria, Integer pageSize, Integer pageNumber, List orderHints, List propertyPaths) { + long numberOfResults = dao.countByTitle(clazz, queryString, matchmode, criteria); + //check whether there are doubtful taxa matching + long numberOfResults_doubtful = dao.countByTitle(clazz, "?".concat(queryString), matchmode, criteria); + List results = new ArrayList<>(); + if(numberOfResults > 0 || numberOfResults_doubtful > 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize) + if (numberOfResults > 0){ + results = dao.findByTitle(clazz, queryString, matchmode, criteria, pageSize, pageNumber, orderHints, propertyPaths); + }else{ + results = new ArrayList<>(); + } + if (numberOfResults_doubtful > 0){ + results.addAll(dao.findByTitle(clazz, "?".concat(queryString), matchmode, criteria, pageSize, pageNumber, orderHints, propertyPaths)); + } + } + Collections.sort(results, new TaxonComparator()); + return new DefaultPagerImpl<>(pageNumber, numberOfResults, pageSize, results); + } + @Override public Pager> findByDistribution(List areaFilter, List statusFilter, Classification classification, TaxonNode subtree, @@ -1627,7 +1800,6 @@ public class TaxonServiceImpl // SortField[] sortFields = new SortField[]{SortField.FIELD_SCORE, new SortField("id", SortField.STRING, false)}; // SortField[] sortFields = new SortField[]{new SortField(NomenclaturalSortOrderBrigde.NAME_SORT_FIELD_NAME, SortField.STRING, false)}; - boolean addDistributionFilter = namedAreas != null && namedAreas.size() > 0; List luceneSearches = new ArrayList<>(); @@ -1831,7 +2003,6 @@ public class TaxonServiceImpl } } - // search by pro parte synonyms if(searchModes.contains(TaxaAndNamesSearchMode.doSynonyms)) { //TODO merge with misapplied name search once #7487 is fixed @@ -1853,12 +2024,9 @@ public class TaxonServiceImpl } }//end pro parte synonyms - - LuceneMultiSearch multiSearch = new LuceneMultiSearch(luceneIndexToolProvider, luceneSearches.toArray(new LuceneSearch[luceneSearches.size()])); - if(addDistributionFilter){ // B) @@ -2000,7 +2168,6 @@ public class TaxonServiceImpl Classification classification, TaxonNode subtree, List features, List languages, boolean highlightFragments, Integer pageSize, Integer pageNumber, List orderHints, List propertyPaths) throws IOException, LuceneParseException { - LuceneSearch luceneSearch = prepareByDescriptionElementFullTextSearch(clazz, queryString, classification, subtree, features, languages, highlightFragments); // --- execute search @@ -2024,10 +2191,8 @@ public class TaxonServiceImpl int totalHits = topDocsResultSet != null ? topDocsResultSet.totalGroupCount : 0; return new DefaultPagerImpl<>(pageNumber, Long.valueOf(totalHits), pageSize, searchResults); - } - @Override public Pager> findByEverythingFullText(String queryString, Classification classification, TaxonNode subtree, boolean includeUnpublished, List languages, boolean highlightFragments, @@ -2063,10 +2228,8 @@ public class TaxonServiceImpl int totalHits = topDocsResultSet != null ? topDocsResultSet.totalGroupCount : 0; return new DefaultPagerImpl<>(pageNumber, Long.valueOf(totalHits), pageSize, searchResults); - } - /** * @param clazz * @param queryString @@ -2178,7 +2341,6 @@ public class TaxonServiceImpl @Override public List createInferredSynonyms(Taxon taxon, Classification classification, SynonymType type, boolean doWithMisappliedNames){ - List inferredSynonyms = new ArrayList<>(); List inferredSynonymsToBeRemoved = new ArrayList<>(); @@ -2275,140 +2437,87 @@ public class TaxonServiceImpl } if (!taxonNames.isEmpty()){ - List synNotInCDM = dao.taxaByNameNotInDB(taxonNames); - IZoologicalName name; - if (!synNotInCDM.isEmpty()){ - inferredSynonymsToBeRemoved.clear(); - - for (Synonym syn :inferredSynonyms){ - name = getZoologicalName(syn.getName().getUuid(), zooHashMap); - if (!synNotInCDM.contains(name.getNameCache())){ - inferredSynonymsToBeRemoved.add(syn); + List synNotInCDM = dao.taxaByNameNotInDB(taxonNames); + if (!synNotInCDM.isEmpty()){ + inferredSynonymsToBeRemoved.clear(); + + for (Synonym syn :inferredSynonyms){ + IZoologicalName name = getZoologicalName(syn.getName().getUuid(), zooHashMap); + if (!synNotInCDM.contains(name.getNameCache())){ + inferredSynonymsToBeRemoved.add(syn); + } } - } - // Remove identified Synonyms from inferredSynonyms - for (Synonym synonym : inferredSynonymsToBeRemoved) { - inferredSynonyms.remove(synonym); + // Remove identified Synonyms from inferredSynonyms + for (Synonym synonym : inferredSynonymsToBeRemoved) { + inferredSynonyms.remove(synonym); + } } } - } - - }else if (type.equals(SynonymType.INFERRED_GENUS_OF())){ - - for (Synonym synonymRelationOfTaxon:synonymsOfTaxon){ - inferredGenus = createInferredGenus(taxon, - zooHashMap, taxonName, epithetOfTaxon, - genusOfTaxon, taxonNames, zooParentName, synonymRelationOfTaxon); + }else if (type.equals(SynonymType.INFERRED_GENUS_OF())){ - inferredSynonyms.add(inferredGenus); - zooHashMap.put(inferredGenus.getName().getUuid(), inferredGenus.getName()); - taxonNames.add(inferredGenus.getName().getNameCache()); - } - - if (doWithMisappliedNames){ + for (Synonym synonymRelationOfTaxon:synonymsOfTaxon){ - for (TaxonRelationship taxonRelationship: taxonRelListTaxon){ - Taxon misappliedName = taxonRelationship.getFromTaxon(); - inferredGenus = createInferredGenus(taxon, zooHashMap, taxonName, infraspecificEpithetOfTaxon, genusOfTaxon, taxonNames, zooParentName, misappliedName); + inferredGenus = createInferredGenus(taxon, + zooHashMap, taxonName, epithetOfTaxon, + genusOfTaxon, taxonNames, zooParentName, synonymRelationOfTaxon); inferredSynonyms.add(inferredGenus); zooHashMap.put(inferredGenus.getName().getUuid(), inferredGenus.getName()); - taxonNames.add(inferredGenus.getName().getNameCache()); + taxonNames.add(inferredGenus.getName().getNameCache()); } - } + if (doWithMisappliedNames){ - if (!taxonNames.isEmpty()){ - List synNotInCDM = dao.taxaByNameNotInDB(taxonNames); - IZoologicalName name; - if (!synNotInCDM.isEmpty()){ - inferredSynonymsToBeRemoved.clear(); - - for (Synonym syn :inferredSynonyms){ - name = getZoologicalName(syn.getName().getUuid(), zooHashMap); - if (!synNotInCDM.contains(name.getNameCache())){ - inferredSynonymsToBeRemoved.add(syn); - } - } + for (TaxonRelationship taxonRelationship: taxonRelListTaxon){ + Taxon misappliedName = taxonRelationship.getFromTaxon(); + inferredGenus = createInferredGenus(taxon, zooHashMap, taxonName, infraspecificEpithetOfTaxon, genusOfTaxon, taxonNames, zooParentName, misappliedName); - // Remove identified Synonyms from inferredSynonyms - for (Synonym synonym : inferredSynonymsToBeRemoved) { - inferredSynonyms.remove(synonym); + inferredSynonyms.add(inferredGenus); + zooHashMap.put(inferredGenus.getName().getUuid(), inferredGenus.getName()); + taxonNames.add(inferredGenus.getName().getNameCache()); } } - } - - }else if (type.equals(SynonymType.POTENTIAL_COMBINATION_OF())){ - - Reference sourceReference = null; // TODO: Determination of sourceReference is redundant - //for all synonyms of the parent... - for (Synonym synonymRelationOfParent:synonyMsOfParent){ - TaxonName synName; - HibernateProxyHelper.deproxy(synonymRelationOfParent); - synName = synonymRelationOfParent.getName(); - // Set the sourceReference - sourceReference = synonymRelationOfParent.getSec(); - - // Determine the idInSource - String idInSourceParent = getIdInSource(synonymRelationOfParent); - - IZoologicalName parentSynZooName = getZoologicalName(synName.getUuid(), zooHashMap); - String synParentGenus = parentSynZooName.getGenusOrUninomial(); - String synParentInfragenericName = null; - String synParentSpecificEpithet = null; - - if (parentSynZooName.isInfraGeneric()){ - synParentInfragenericName = parentSynZooName.getInfraGenericEpithet(); - } - if (parentSynZooName.isSpecies()){ - synParentSpecificEpithet = parentSynZooName.getSpecificEpithet(); - } - - /* if (synGenusName != null && !synonymsGenus.containsKey(synGenusName)){ - synonymsGenus.put(synGenusName, idInSource); - }*/ - - //for all synonyms of the taxon - - for (Synonym synonymRelationOfTaxon:synonymsOfTaxon){ - - IZoologicalName zooSynName = getZoologicalName(synonymRelationOfTaxon.getName().getUuid(), zooHashMap); - potentialCombination = createPotentialCombination(idInSourceParent, parentSynZooName, zooSynName, - synParentGenus, - synParentInfragenericName, - synParentSpecificEpithet, synonymRelationOfTaxon, zooHashMap); + if (!taxonNames.isEmpty()){ + List synNotInCDM = dao.taxaByNameNotInDB(taxonNames); + IZoologicalName name; + if (!synNotInCDM.isEmpty()){ + inferredSynonymsToBeRemoved.clear(); - taxon.addSynonym(potentialCombination, SynonymType.POTENTIAL_COMBINATION_OF()); - inferredSynonyms.add(potentialCombination); - zooHashMap.put(potentialCombination.getName().getUuid(), potentialCombination.getName()); - taxonNames.add(potentialCombination.getName().getNameCache()); + for (Synonym syn :inferredSynonyms){ + name = getZoologicalName(syn.getName().getUuid(), zooHashMap); + if (!synNotInCDM.contains(name.getNameCache())){ + inferredSynonymsToBeRemoved.add(syn); + } + } + // Remove identified Synonyms from inferredSynonyms + for (Synonym synonym : inferredSynonymsToBeRemoved) { + inferredSynonyms.remove(synonym); + } + } } - } - - if (doWithMisappliedNames){ - - for (TaxonRelationship parentRelationship: taxonRelListParent){ - - TaxonName misappliedParentName; + }else if (type.equals(SynonymType.POTENTIAL_COMBINATION_OF())){ - Taxon misappliedParent = parentRelationship.getFromTaxon(); - misappliedParentName = misappliedParent.getName(); + Reference sourceReference = null; // TODO: Determination of sourceReference is redundant + //for all synonyms of the parent... + for (Synonym synonymRelationOfParent:synonyMsOfParent){ + TaxonName synName; + HibernateProxyHelper.deproxy(synonymRelationOfParent); - HibernateProxyHelper.deproxy(misappliedParent); + synName = synonymRelationOfParent.getName(); // Set the sourceReference - sourceReference = misappliedParent.getSec(); + sourceReference = synonymRelationOfParent.getSec(); // Determine the idInSource - String idInSourceParent = getIdInSource(misappliedParent); + String idInSourceParent = getIdInSource(synonymRelationOfParent); - IZoologicalName parentSynZooName = getZoologicalName(misappliedParentName.getUuid(), zooHashMap); + IZoologicalName parentSynZooName = getZoologicalName(synName.getUuid(), zooHashMap); String synParentGenus = parentSynZooName.getGenusOrUninomial(); String synParentInfragenericName = null; String synParentSpecificEpithet = null; @@ -2420,16 +2529,19 @@ public class TaxonServiceImpl synParentSpecificEpithet = parentSynZooName.getSpecificEpithet(); } + /* if (synGenusName != null && !synonymsGenus.containsKey(synGenusName)){ + synonymsGenus.put(synGenusName, idInSource); + }*/ - for (TaxonRelationship taxonRelationship: taxonRelListTaxon){ - Taxon misappliedName = taxonRelationship.getFromTaxon(); - IZoologicalName zooMisappliedName = getZoologicalName(misappliedName.getName().getUuid(), zooHashMap); - potentialCombination = createPotentialCombination( - idInSourceParent, parentSynZooName, zooMisappliedName, + //for all synonyms of the taxon + + for (Synonym synonymRelationOfTaxon:synonymsOfTaxon){ + + IZoologicalName zooSynName = getZoologicalName(synonymRelationOfTaxon.getName().getUuid(), zooHashMap); + potentialCombination = createPotentialCombination(idInSourceParent, parentSynZooName, zooSynName, synParentGenus, synParentInfragenericName, - synParentSpecificEpithet, misappliedName, zooHashMap); - + synParentSpecificEpithet, synonymRelationOfTaxon, zooHashMap); taxon.addSynonym(potentialCombination, SynonymType.POTENTIAL_COMBINATION_OF()); inferredSynonyms.add(potentialCombination); @@ -2437,29 +2549,74 @@ public class TaxonServiceImpl taxonNames.add(potentialCombination.getName().getNameCache()); } } - } - if (!taxonNames.isEmpty()){ - List synNotInCDM = dao.taxaByNameNotInDB(taxonNames); - IZoologicalName name; - if (!synNotInCDM.isEmpty()){ - inferredSynonymsToBeRemoved.clear(); - for (Synonym syn :inferredSynonyms){ - try{ - name = syn.getName(); - }catch (ClassCastException e){ - name = getZoologicalName(syn.getName().getUuid(), zooHashMap); + if (doWithMisappliedNames){ + + for (TaxonRelationship parentRelationship: taxonRelListParent){ + + TaxonName misappliedParentName; + + Taxon misappliedParent = parentRelationship.getFromTaxon(); + misappliedParentName = misappliedParent.getName(); + + HibernateProxyHelper.deproxy(misappliedParent); + + // Set the sourceReference + sourceReference = misappliedParent.getSec(); + + // Determine the idInSource + String idInSourceParent = getIdInSource(misappliedParent); + + IZoologicalName parentSynZooName = getZoologicalName(misappliedParentName.getUuid(), zooHashMap); + String synParentGenus = parentSynZooName.getGenusOrUninomial(); + String synParentInfragenericName = null; + String synParentSpecificEpithet = null; + + if (parentSynZooName.isInfraGeneric()){ + synParentInfragenericName = parentSynZooName.getInfraGenericEpithet(); + } + if (parentSynZooName.isSpecies()){ + synParentSpecificEpithet = parentSynZooName.getSpecificEpithet(); + } + + for (TaxonRelationship taxonRelationship: taxonRelListTaxon){ + Taxon misappliedName = taxonRelationship.getFromTaxon(); + IZoologicalName zooMisappliedName = getZoologicalName(misappliedName.getName().getUuid(), zooHashMap); + potentialCombination = createPotentialCombination( + idInSourceParent, parentSynZooName, zooMisappliedName, + synParentGenus, + synParentInfragenericName, + synParentSpecificEpithet, misappliedName, zooHashMap); + + taxon.addSynonym(potentialCombination, SynonymType.POTENTIAL_COMBINATION_OF()); + inferredSynonyms.add(potentialCombination); + zooHashMap.put(potentialCombination.getName().getUuid(), potentialCombination.getName()); + taxonNames.add(potentialCombination.getName().getNameCache()); } - if (!synNotInCDM.contains(name.getNameCache())){ - inferredSynonymsToBeRemoved.add(syn); + } + } + + if (!taxonNames.isEmpty()){ + List synNotInCDM = dao.taxaByNameNotInDB(taxonNames); + IZoologicalName name; + if (!synNotInCDM.isEmpty()){ + inferredSynonymsToBeRemoved.clear(); + for (Synonym syn :inferredSynonyms){ + try{ + name = syn.getName(); + }catch (ClassCastException e){ + name = getZoologicalName(syn.getName().getUuid(), zooHashMap); + } + if (!synNotInCDM.contains(name.getNameCache())){ + inferredSynonymsToBeRemoved.add(syn); + } + } + // Remove identified Synonyms from inferredSynonyms + for (Synonym synonym : inferredSynonymsToBeRemoved) { + inferredSynonyms.remove(synonym); } - } - // Remove identified Synonyms from inferredSynonyms - for (Synonym synonym : inferredSynonymsToBeRemoved) { - inferredSynonyms.remove(synonym); } } - } } }else { logger.info("The synonym type is not defined."); @@ -2467,7 +2624,6 @@ public class TaxonServiceImpl } } } - } return inferredSynonyms; @@ -2523,7 +2679,6 @@ public class TaxonServiceImpl inferredSynName.setInfraGenericEpithet(synParentInfragenericName); } - potentialCombination = Synonym.NewInstance(inferredSynName, null); // Set the sourceReference @@ -2566,14 +2721,13 @@ public class TaxonServiceImpl synName = syn.getName(); IZoologicalName synZooName = getZoologicalName(synName.getUuid(), zooHashMap); String synSpeciesEpithetName = synZooName.getSpecificEpithet(); - /* if (synonymsEpithet != null && !synonymsEpithet.contains(synSpeciesEpithetName)){ + /* if (synonymsEpithet != null && !synonymsEpithet.contains(synSpeciesEpithetName)){ synonymsEpithet.add(synSpeciesEpithetName); }*/ inferredSynName = TaxonNameFactory.NewZoologicalInstance(taxon.getName().getRank()); //TODO:differ between parent is genus and taxon is species, parent is subgenus and taxon is species, parent is species and taxon is subspecies and parent is genus and taxon is subgenus... - inferredSynName.setGenusOrUninomial(genusOfTaxon); if (zooParentName.isInfraGeneric()){ inferredSynName.setInfraGenericEpithet(zooParentName.getInfraGenericEpithet()); @@ -2587,7 +2741,6 @@ public class TaxonServiceImpl inferredSynName.setInfraSpecificEpithet(synZooName.getInfraGenericEpithet()); } - inferredGenus = Synonym.NewInstance(inferredSynName, null); // Set the sourceReference @@ -2657,7 +2810,7 @@ public class TaxonServiceImpl synSpecificEpithet = zooSynName.getSpecificEpithet(); } - /* if (synGenusName != null && !synonymsGenus.containsKey(synGenusName)){ + /* if (synGenusName != null && !synonymsGenus.containsKey(synGenusName)){ synonymsGenus.put(synGenusName, idInSource); }*/ @@ -2708,8 +2861,6 @@ public class TaxonServiceImpl inferredSynName.addSource(originalSource); - - taxon.addSynonym(inferredEpithet, SynonymType.INFERRED_EPITHET_OF()); return inferredEpithet; @@ -2756,11 +2907,9 @@ public class TaxonServiceImpl logger.warn("No idInSource for TaxonBase " + taxonBase.getUuid() + " - " + taxonBase.getTitleCache()); } - return idInSource; } - /** * Returns the citation for a given Synonym. * @param syn @@ -2878,11 +3027,32 @@ public class TaxonServiceImpl Set references = commonService.getReferencingObjectsForDeletion(taxonBase); if (taxonBase instanceof Taxon){ TaxonDeletionConfigurator taxonConfig = (TaxonDeletionConfigurator) config; - result = isDeletableForTaxon(references, taxonConfig); + List propertyPaths = new ArrayList<>(); + propertyPaths.add("taxonNodes"); + Taxon taxon = (Taxon)load(taxonBaseUuid, propertyPaths); + + result = isDeletableForTaxon(references, taxonConfig ); + + if (taxonConfig.isDeleteNameIfPossible()){ + if (taxonBase.getName() != null){ + DeleteResult nameResult = nameService.isDeletable(taxonBase.getName().getUuid(), taxonConfig.getNameDeletionConfig(), taxon.getUuid()); + if (!nameResult.isOk()){ + result.addExceptions(nameResult.getExceptions()); + } + } + + } }else{ SynonymDeletionConfigurator synonymConfig = (SynonymDeletionConfigurator) config; result = isDeletableForSynonym(references, synonymConfig); + if (synonymConfig.isDeleteNameIfPossible()){ + DeleteResult nameResult = nameService.isDeletable(taxonBase.getName().getUuid(), synonymConfig.getNameDeletionConfig(), taxonBase.getUuid()); + if (!nameResult.isOk()){ + result.addExceptions(nameResult.getExceptions()); + } + } } + return result; } @@ -2896,6 +3066,7 @@ public class TaxonServiceImpl result.addRelatedObject(ref); result.setAbort(); } + } return result; @@ -2915,11 +3086,16 @@ public class TaxonServiceImpl } if (!config.isDeleteTaxonNodes() && (ref instanceof TaxonNode)){ + message = "The taxon can't be deleted as long as it belongs to a taxon node."; } + if (ref instanceof TaxonNode && config.getClassificationUuid() != null && !config.isDeleteInAllClassifications() && !((TaxonNode)ref).getClassification().getUuid().equals(config.getClassificationUuid())){ + message = "The taxon can't be deleted as long as it is used in more than one classification"; + + } if (!config.isDeleteTaxonRelationships() && (ref instanceof TaxonRelationship)){ - if (!config.isDeleteMisappliedNamesAndInvalidDesignations() && - (((TaxonRelationship)ref).getType().isMisappliedNameOrInvalidDesignation())){ + if (!config.isDeleteMisappliedNames() && + (((TaxonRelationship)ref).getType().isMisappliedName())){ message = "The taxon can't be deleted as long as it has misapplied names or invalid designations."; } else{ message = "The taxon can't be deleted as long as it belongs to taxon relationship."; @@ -2933,7 +3109,6 @@ public class TaxonServiceImpl message = "Taxon can't be deleted as it is used in an identification key. Remove from identification key prior to deleting this taxon"; } - /* //PolytomousKeyNode if (referencingObject.isInstanceOf(PolytomousKeyNode.class)){ String message = "Taxon" + taxon.getTitleCache() + " can't be deleted as it is used in polytomous key node"; @@ -3092,6 +3267,7 @@ public class TaxonServiceImpl @Override public List findTaxaByName(MatchingTaxonConfigurator config){ + @SuppressWarnings("rawtypes") List taxonList = dao.getTaxaByName(true, config.isIncludeSynonyms(), false, false, false, config.getTaxonNameTitle(), null, null, MatchMode.EXACT, null, config.isIncludeSynonyms(), null, 0, 0, config.getPropertyPath()); return taxonList; @@ -3167,7 +3343,7 @@ public class TaxonServiceImpl return result; } - @Override + @Override public UpdateResult moveFactualDateToAnotherTaxon(UUID fromTaxonUuid, UUID toTaxonUuid){ UpdateResult result = new UpdateResult(); @@ -3202,18 +3378,15 @@ public class TaxonServiceImpl @Override @Transactional(readOnly = false) public UpdateResult swapSynonymAndAcceptedTaxon(UUID synonymUUid, - UUID acceptedTaxonUuid) { + UUID acceptedTaxonUuid, boolean setNameInSource) { TaxonBase base = this.load(synonymUUid); Synonym syn = HibernateProxyHelper.deproxy(base, Synonym.class); base = this.load(acceptedTaxonUuid); Taxon taxon = HibernateProxyHelper.deproxy(base, Taxon.class); - return this.swapSynonymAndAcceptedTaxon(syn, taxon); + return this.swapSynonymAndAcceptedTaxon(syn, taxon, setNameInSource); } - /** - * {@inheritDoc} - */ @Override public TaxonRelationshipsDTO listTaxonRelationships(UUID taxonUuid, Set directTypes, Set inversTypes, @@ -3266,5 +3439,4 @@ public class TaxonServiceImpl return dto; } } - }