import java.io.IOException;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
+import java.util.stream.Collectors;
import javax.persistence.EntityNotFoundException;
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;
import eu.etaxonomy.cdm.api.service.search.QueryFactory;
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.api.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;
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;
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.ExternalLink;
+import eu.etaxonomy.cdm.model.media.ExternalLinkType;
import eu.etaxonomy.cdm.model.media.Media;
+import eu.etaxonomy.cdm.model.metadata.SecReferenceHandlingEnum;
+import eu.etaxonomy.cdm.model.metadata.SecReferenceHandlingSwapEnum;
import eu.etaxonomy.cdm.model.name.HomotypicalGroup;
import eu.etaxonomy.cdm.model.name.IZoologicalName;
import eu.etaxonomy.cdm.model.name.Rank;
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.SecundumSource;
import eu.etaxonomy.cdm.model.taxon.Synonym;
import eu.etaxonomy.cdm.model.taxon.SynonymType;
import eu.etaxonomy.cdm.model.taxon.Taxon;
import eu.etaxonomy.cdm.persistence.dao.taxon.IClassificationDao;
import eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao;
import eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonNodeDao;
+import eu.etaxonomy.cdm.persistence.dto.MergeResult;
import eu.etaxonomy.cdm.persistence.dto.UuidAndTitleCache;
import eu.etaxonomy.cdm.persistence.query.MatchMode;
import eu.etaxonomy.cdm.persistence.query.OrderHint;
@Autowired
private IDescriptionService descriptionService;
+
+ @Autowired
+ private IReferenceService referenceService;
//
// @Autowired
// private IOrderedTermVocabularyDao orderedVocabularyDao;
// ****************************** METHODS ********************************/
-
- /**
- * {@inheritDoc}
- */
@Override
public TaxonBase load(UUID uuid, boolean includeUnpublished, List<String> propertyPaths) {
return dao.load(uuid, includeUnpublished, propertyPaths);
@Override
@Transactional(readOnly = false)
- public UpdateResult swapSynonymAndAcceptedTaxon(Synonym synonym, Taxon acceptedTaxon){
- UpdateResult result = new UpdateResult();
- TaxonName synonymName = synonym.getName();
- 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);
+ public UpdateResult swapSynonymAndAcceptedTaxon(Synonym synonym, Taxon acceptedTaxon, boolean setNameInSource, boolean newUuidForAcceptedTaxon, SecReferenceHandlingSwapEnum secHandling, Reference newSecAcc, Reference newSecSyn){
+ if (newUuidForAcceptedTaxon){
+ return swapSynonymAndAcceptedTaxonNewUuid(synonym, acceptedTaxon, setNameInSource, secHandling, newSecAcc, newSecSyn);
+ }else{
+ return swapSynonymAndAcceptedTaxon(synonym, acceptedTaxon, setNameInSource, secHandling, newSecAcc, newSecSyn);
+ }
+ }
+
+ private UpdateResult swapSynonymAndAcceptedTaxon(Synonym synonym, Taxon acceptedTaxon, boolean setNameInSource, SecReferenceHandlingSwapEnum secHandling, Reference newSecAcc, Reference newSecSyn){
+ UpdateResult result = new UpdateResult();
+ String oldTaxonTitleCache = acceptedTaxon.getTitleCache();
+
+ TaxonName synonymName = synonym.getName();
+ TaxonName taxonName = HibernateProxyHelper.deproxy(acceptedTaxon.getName());
+ Reference secAccepted = acceptedTaxon.getSec();
+ String microRefSecAccepted = acceptedTaxon.getSecMicroReference();
+ Reference secSynonym = synonym.getSec();
+ String microRefSecSynonym = synonym.getSecMicroReference();
+
+// if (secHandling.equals(SecReferenceHandlingSwapEnum.AlwaysDelete) || (secAccepted != null && secSynonym != null && !secAccepted.getUuid().equals(secSynonym.getUuid()) && (secHandling.equals(SecReferenceHandlingSwapEnum.AlwaysSelect) || secHandling.equals(SecReferenceHandlingSwapEnum.KeepOrSelect)))){
+// secAccepted = null;
+// microRefSecAccepted = null;
+// secSynonym = null;
+// microRefSecSynonym = null;
+// }
+
+
+ Set<ExternalLink> accLinks = new HashSet<>();
+ if (acceptedTaxon.getSecSource() != null){
+ for (ExternalLink link: acceptedTaxon.getSecSource().getLinks()){
+ accLinks.add(ExternalLink.NewInstance(ExternalLinkType.Unknown, link.getUri()));
+ }
+ }
+ acceptedTaxon.setName(synonymName);
+ acceptedTaxon.setSec(newSecAcc);
+// acceptedTaxon.setSecMicroReference(synonym.getSecMicroReference());
+
+// if (synonym.getSecSource()!= null && synonym.getSecSource().getLinks() != null){
+// acceptedTaxon.getSecSource().getLinks().clear();
+// for (ExternalLink link: synonym.getSecSource().getLinks()){
+// acceptedTaxon.getSecSource().addLink(ExternalLink.NewInstance(ExternalLinkType.Unknown, link.getUri()));
+// }
+// }
+
+ synonym.setName(taxonName);
+ synonym.setSec(newSecSyn);
+// synonym.setSecMicroReference(microRefSecAccepted);
+// if (synonym.getSecSource() != null){
+// synonym.getSecSource().getLinks().clear();
+// for (ExternalLink link: accLinks){
+// synonym.getSecSource().addLink(link);
+// }
+// }
+
+ //nameUsedInSource
+ handleNameUsedInSourceForSwap(setNameInSource, taxonName, oldTaxonTitleCache, acceptedTaxon.getDescriptions());
+
+ acceptedTaxon.resetTitleCache();
+ synonym.resetTitleCache();
+
+ MergeResult mergeTaxon = merge(acceptedTaxon, true);
+ MergeResult mergeSynonym = merge(synonym, true);
+ result.setCdmEntity((CdmBase) mergeTaxon.getMergedEntity());
+ result.addUpdatedObject((CdmBase) mergeSynonym.getMergedEntity());
+
return result;
+ }
+
+ private UpdateResult swapSynonymAndAcceptedTaxonNewUuid(Synonym oldSynonym, Taxon oldAcceptedTaxon, boolean setNameInSource, SecReferenceHandlingSwapEnum secHandling, Reference newSecAcc, Reference newSecSyn){
+ UpdateResult result = new UpdateResult();
+ oldAcceptedTaxon.removeSynonym(oldSynonym);
+ TaxonName synonymName = oldSynonym.getName();
+ TaxonName taxonName = HibernateProxyHelper.deproxy(oldAcceptedTaxon.getName());
+ String oldTaxonTitleCache = oldAcceptedTaxon.getTitleCache();
+
+ boolean sameHomotypicGroup = synonymName.getHomotypicalGroup().equals(taxonName.getHomotypicalGroup());
+ synonymName.removeTaxonBase(oldSynonym);
+
+ List<Synonym> synonyms = new ArrayList<>();
+ for (Synonym syn: oldAcceptedTaxon.getSynonyms()){
+ syn = HibernateProxyHelper.deproxy(syn, Synonym.class);
+ synonyms.add(syn);
+ }
+ for (Synonym syn: synonyms){
+ oldAcceptedTaxon.removeSynonym(syn);
+ }
+ Taxon newTaxon = oldAcceptedTaxon.clone(true, true, false, true);
+ newTaxon.setSec(newSecAcc);
+
+ //move descriptions
+ Set<TaxonDescription> descriptionsToCopy = new HashSet<>(oldAcceptedTaxon.getDescriptions());
+ for (TaxonDescription description: descriptionsToCopy){
+ newTaxon.addDescription(description);
+ }
+ //nameUsedInSource
+ handleNameUsedInSourceForSwap(setNameInSource, taxonName, oldTaxonTitleCache, newTaxon.getDescriptions());
+
+ newTaxon.setName(synonymName);
+
+ newTaxon.setPublish(oldSynonym.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 : oldAcceptedTaxon.getTaxonRelations()){
+ Taxon fromTaxon = HibernateProxyHelper.deproxy(taxonRelationship.getFromTaxon());
+ Taxon toTaxon = HibernateProxyHelper.deproxy(taxonRelationship.getToTaxon());
+ if (fromTaxon == oldAcceptedTaxon){
+ newTaxon.addTaxonRelation(taxonRelationship.getToTaxon(), taxonRelationship.getType(),
+ taxonRelationship.getCitation(), taxonRelationship.getCitationMicroReference());
+
+ }else if(toTaxon == oldAcceptedTaxon){
+ fromTaxon.addTaxonRelation(newTaxon, taxonRelationship.getType(),
+ taxonRelationship.getCitation(), taxonRelationship.getCitationMicroReference());
+ saveOrUpdate(fromTaxon);
- // 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());
+ }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);
+ }
+
+ //taxon nodes
+ List<TaxonNode> nodes = new ArrayList<>(oldAcceptedTaxon.getTaxonNodes());
+ for (TaxonNode node: nodes){
+ node = HibernateProxyHelper.deproxy(node);
+ TaxonNode parent = node.getParent();
+ oldAcceptedTaxon.removeTaxonNode(node);
+ node.setTaxon(newTaxon);
+ if (parent != null){
+ parent.addChildNode(node, null, null);
+ }
+ }
+
+ //synonym
+ Synonym newSynonym = oldSynonym.clone();
+ newSynonym.setName(taxonName);
+ newSynonym.setPublish(oldAcceptedTaxon.isPublish());
+ newSynonym.setSec(newSecSyn);
+ if (sameHomotypicGroup){
+ newTaxon.addSynonym(newSynonym, SynonymType.HOMOTYPIC_SYNONYM_OF());
+ }else{
+ newTaxon.addSynonym(newSynonym, SynonymType.HETEROTYPIC_SYNONYM_OF());
+ }
+
+ //deletes
+ TaxonDeletionConfigurator conf = new TaxonDeletionConfigurator();
+ conf.setDeleteNameIfPossible(false);
+ SynonymDeletionConfigurator confSyn = new SynonymDeletionConfigurator();
+ confSyn.setDeleteNameIfPossible(false);
+ result.setCdmEntity(newTaxon);
+
+ DeleteResult deleteResult = deleteTaxon(oldAcceptedTaxon.getUuid(), conf, null);
+ if (oldSynonym.isPersited()){
+ oldSynonym.setSecSource(null);
+ deleteResult.includeResult(deleteSynonym(oldSynonym.getUuid(), confSyn));
+ }
+ result.includeResult(deleteResult);
+
+ return result;
}
+ private void handleNameUsedInSourceForSwap(boolean setNameInSource, TaxonName taxonName, String oldTaxonTitleCache,
+ Set<TaxonDescription> descriptions) {
+ for(TaxonDescription description : descriptions){
+ String message = "Description copied from former accepted taxon: %s (Old title: %s)";
+ message = String.format(message, oldTaxonTitleCache, 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);
+ }
+ }
+ }
+ }
+ }
+ }
@Override
@Transactional(readOnly = false)
- public UpdateResult changeSynonymToAcceptedTaxon(Synonym synonym, Taxon acceptedTaxon, boolean deleteSynonym) {
+ public UpdateResult changeSynonymToAcceptedTaxon(Synonym synonym, Taxon acceptedTaxon, Reference newSecRef, String microRef, SecReferenceHandlingEnum secHandling, boolean deleteSynonym) {
UpdateResult result = new UpdateResult();
TaxonName acceptedName = acceptedTaxon.getName();
TaxonName synonymName = synonym.getName();
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();
List<Synonym> heteroSynonyms = acceptedTaxon.getSynonymsInGroup(synonymHomotypicGroup);
for (Synonym heteroSynonym : heteroSynonyms){
+ if (secHandling == null){
+ heteroSynonym.setSec(newSecRef);
+ }
if (synonym.equals(heteroSynonym)){
acceptedTaxon.removeSynonym(heteroSynonym, false);
}else{
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 UseNewParentSec:
+ newSecRef = newParentNode.getTaxon() != null? newParentNode.getTaxon().getSec(): null;
+ break;
+ case KeepOrWarn:
+ Reference parentSec = newParentNode.getTaxon() != null? newParentNode.getTaxon().getSec(): null;
+ Reference synSec = synonym.getSec();
+ if (synSec != null ){
+ newSecRef = CdmBase.deproxy(synSec);
+ }else{
+ newSecRef = CdmBase.deproxy(referenceService.load(newSec));
+ }
+ break;
+ case KeepOrSelect:
+ newSecRef = CdmBase.deproxy(referenceService.load(newSec));
+ break;
+ default:
+ break;
+ }
+
+ result = changeSynonymToAcceptedTaxon(synonym, acceptedTaxon, newSecRef, microReference, secHandling, deleteSynonym);
+ Taxon newTaxon = (Taxon)result.getCdmEntity();
+
TaxonNode newNode = newParentNode.addChildTaxon(newTaxon, null, null);
taxonNodeDao.save(newNode);
result.addUpdatedObject(newTaxon);
return result;
}
-
-
-
@Override
@Transactional(readOnly = false)
public UpdateResult changeSynonymToRelatedTaxon(UUID synonymUuid,
*/
// Create a taxon with synonym name
Taxon fromTaxon = Taxon.NewInstance(synonymName, null);
+ fromTaxon.setPublish(synonym.isPublish());
save(fromTaxon);
fromTaxon.setAppendedPhrase(synonym.getAppendedPhrase());
SynonymType relType = isHomotypicToTaxon? SynonymType.HOMOTYPIC_SYNONYM_OF() : SynonymType.HETEROTYPIC_SYNONYM_OF();
targetTaxon.addSynonym(synonym, relType);
}
-
}
@Override
this.dao = dao;
}
-
@Override
- public Pager<TaxonBase> findTaxaByName(Class<? extends TaxonBase> 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 <T extends TaxonBase> Pager<T> findTaxaByName(Class<T> clazz, String uninomial, String infragenericEpithet, String specificEpithet,
+ String infraspecificEpithet, String authorshipCache, Rank rank, Integer pageSize,Integer pageNumber, List<String> propertyPaths) {
+ long numberOfResults = dao.countTaxaByName(clazz, uninomial, infragenericEpithet, specificEpithet, infraspecificEpithet, authorshipCache, rank);
- List<TaxonBase> results = new ArrayList<>();
+ List<T> 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<TaxonBase> listTaxaByName(Class<? extends TaxonBase> 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);
-
- List<TaxonBase> results = new ArrayList<>();
- if(numberOfResults > 0) { // no point checking again
- results = dao.findTaxaByName(clazz, uninomial, infragenericEpithet, specificEpithet, infraspecificEpithet, authorship, rank, pageSize, pageNumber);
- }
+ public <T extends TaxonBase> List<T> listTaxaByName(Class<T> clazz, String uninomial, String infragenericEpithet, String specificEpithet,
+ String infraspecificEpithet, String authorshipCache, Rank rank, Integer pageSize,Integer pageNumber, List<String> propertyPaths) {
- return results;
+ return findTaxaByName(clazz, uninomial, infragenericEpithet, specificEpithet, infragenericEpithet, authorshipCache, rank,
+ pageSize, pageNumber, propertyPaths).getRecords();
}
@Override
@Override
public List<TaxonRelationship> listTaxonRelationships(Set<TaxonRelationshipType> types,
- Integer pageSize, Integer pageStart, List<OrderHint> orderHints, List<String> propertyPaths) {
- Long numberOfResults = dao.countTaxonRelationships(types);
+ Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {
+ Long numberOfResults = dao.countTaxonRelationships(types);
List<TaxonRelationship> results = new ArrayList<>();
if(numberOfResults > 0) {
- results = dao.getTaxonRelationships(types, pageSize, pageStart, orderHints, propertyPaths);
+ results = dao.getTaxonRelationships(types, pageSize, pageNumber, orderHints, propertyPaths);
}
return results;
}
return relatedTaxa;
}
-
/**
* Recursively collect related taxa for the given <code>taxon</code> . The returned list will also include the
* <code>taxon</code> supplied as parameter.
taxon = (Taxon)dao.load(taxon.getUuid(), propertyPaths);
HomotypicGroupTaxonComparator comparator = new HomotypicGroupTaxonComparator(taxon);
-
//homotypic
result.add(taxon.getHomotypicSynonymsByHomotypicGroup(comparator));
}
return result;
-
}
@Override
if (config.isDoSynonyms() || config.isDoTaxa() || config.isDoNamesWithoutTaxa() || config.isDoTaxaByCommonNames()){
return dao.getTaxaByNameForEditor(config.isDoTaxa(), config.isDoSynonyms(), config.isDoNamesWithoutTaxa(),
- config.isDoMisappliedNames(), config.isDoTaxaByCommonNames(), config.isIncludeUnpublished(),
+ config.isDoMisappliedNames(), config.isDoTaxaByCommonNames(), config.isIncludeUnpublished(), config.isDoIncludeAuthors(),
config.getTitleSearchStringSqlized(), config.getClassification(), config.getSubtree(),
config.getMatchMode(), config.getNamedAreas(), config.getOrder());
}else{
@Override
public Pager<IdentifiableEntity> findTaxaAndNames(IFindTaxaAndNamesConfigurator configurator) {
+ @SuppressWarnings("rawtypes")
List<IdentifiableEntity> results = new ArrayList<>();
long numberOfResults = 0; // overall number of results (as opposed to number of results per page)
List<TaxonBase> taxa = null;
configurator.getMatchMode(), configurator.getNamedAreas(), configurator.isIncludeUnpublished(),
configurator.getOrder(), configurator.getPageSize(), configurator.getPageNumber(), propertyPath);
}
- }
+ }
if (logger.isDebugEnabled()) { logger.debug(numberTaxaResults + " matching taxa counted"); }
// logger.setLevel(Level.TRACE);
// Logger.getLogger("org.hibernate.SQL").setLevel(Level.TRACE);
- logger.trace("listMedia() - START");
+ if (logger.isTraceEnabled()){logger.trace("listMedia() - START");}
Set<Taxon> taxa = new HashSet<>();
List<Media> taxonMedia = new ArrayList<>();
// --- resolve related taxa
if (includeRelationships != null && ! includeRelationships.isEmpty()) {
- logger.trace("listMedia() - resolve related taxa");
+ if (logger.isTraceEnabled()){logger.trace("listMedia() - resolve related taxa");}
taxa = listRelatedTaxa(taxon, includeRelationships, null, includeUnpublished, null, null, null);
}
taxa.add((Taxon) dao.load(taxon.getUuid()));
if(includeTaxonDescriptions != null && includeTaxonDescriptions){
- logger.trace("listMedia() - includeTaxonDescriptions");
+ if (logger.isTraceEnabled()){logger.trace("listMedia() - includeTaxonDescriptions");}
List<TaxonDescription> taxonDescriptions = new ArrayList<>();
// --- TaxonDescriptions
for (Taxon t : taxa) {
if(includeOccurrences != null && includeOccurrences) {
- logger.trace("listMedia() - includeOccurrences");
+ if (logger.isTraceEnabled()){logger.trace("listMedia() - includeOccurrences");}
+ @SuppressWarnings("rawtypes")
Set<SpecimenOrObservationBase> specimensOrObservations = new HashSet<>();
// --- Specimens
for (Taxon t : taxa) {
}
}
//media in hierarchy
- taxonMedia.addAll(occurrenceService.getMediainHierarchy(occurrence, null, null, propertyPath).getRecords());
+ taxonMedia.addAll(occurrenceService.getMediaInHierarchy(occurrence, null, null, propertyPath).getRecords());
}
}
if(includeTaxonNameDescriptions != null && includeTaxonNameDescriptions) {
- logger.trace("listMedia() - includeTaxonNameDescriptions");
+ if (logger.isTraceEnabled()){logger.trace("listMedia() - includeTaxonNameDescriptions");}
// --- TaxonNameDescription
Set<TaxonNameDescription> nameDescriptions = new HashSet<>();
for (Taxon t : taxa) {
- nameDescriptions .addAll(t.getName().getDescriptions());
+ nameDescriptions.addAll(t.getName().getDescriptions());
}
for(TaxonNameDescription nameDescription: nameDescriptions){
if (!limitToGalleries || nameDescription.isImageGallery()) {
}
}
+ taxonMedia = deduplicateMedia(taxonMedia);
- logger.trace("listMedia() - initialize");
+ if (logger.isTraceEnabled()){logger.trace("listMedia() - initialize");}
beanInitializer.initializeAll(taxonMedia, propertyPath);
- logger.trace("listMedia() - END");
+ if (logger.isTraceEnabled()){logger.trace("listMedia() - END");}
return taxonMedia;
}
+ private List<Media> deduplicateMedia(List<Media> taxonMedia) {
+ return taxonMedia.stream().distinct().collect(Collectors.toList());
+ }
+
@Override
public List<TaxonBase> findTaxaByID(Set<Integer> listOfIDs) {
- return this.dao.loadList(listOfIDs, null);
+ return this.dao.loadList(listOfIDs, null, null);
}
@Override
return this.dao.countSynonyms(onlyAttachedToTaxon);
}
- @Override
- public List<TaxonName> findIdenticalTaxonNames(List<String> propertyPath) {
- return this.dao.findIdenticalTaxonNames(propertyPath);
- }
-
@Override
@Transactional(readOnly=false)
public DeleteResult deleteTaxon(UUID taxonUUID, TaxonDeletionConfigurator config, UUID classificationUuid) {
}
taxon = HibernateProxyHelper.deproxy(taxon);
Classification classification = HibernateProxyHelper.deproxy(classificationDao.load(classificationUuid), Classification.class);
+ config.setClassificationUuid(classificationUuid);
result = isDeletable(taxonUUID, config);
if (result.isOk()){
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()){
break;
}
removeDescriptions.add(desc);
-
-
}
if (result.isOk()){
for (TaxonDescription desc: removeDescriptions){
}
}
-
- 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<TaxonNode> nodes = taxon.getTaxonNodes();
- Iterator<TaxonNode> 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<TaxonNode> nodes = taxon.getTaxonNodes();
+ Iterator<TaxonNode> 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<TaxonNode> 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<TaxonNode> 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
@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) {
//remove name if possible (and required)
if (name != null && config.isDeleteNameIfPossible()){
- DeleteResult nameDeleteResult = nameService.delete(name, config.getNameDeletionConfig());
- if (nameDeleteResult.isAbort() || nameDeleteResult.isError()){
- result.addExceptions(nameDeleteResult.getExceptions());
- result.addRelatedObject(name);
- }else{
- result.addDeletedObject(name);
- }
+ DeleteResult nameDeleteResult = nameService.delete(name, config.getNameDeletionConfig());
+ if (nameDeleteResult.isAbort() || nameDeleteResult.isError()){
+ result.addExceptions(nameDeleteResult.getExceptions());
+ result.addRelatedObject(name);
+ result.addUpdatedObject(name);
+ }else{
+ result.addDeletedObject(name);
+ }
}
-
}
return result;
}
@Override
- public List<TaxonName> findIdenticalTaxonNameIds(List<String> propertyPath) {
-
- return this.dao.findIdenticalNamesNew(propertyPath);
+ public Map<String, Map<UUID,Set<TaxonName>>> findIdenticalTaxonNames(List<UUID> sourceRefUuids, List<String> propertyPaths) {
+ return this.dao.findIdenticalNames(sourceRefUuids, propertyPaths);
}
-
@Override
public Taxon findBestMatchingTaxon(String taxonName) {
MatchingTaxonConfigurator config = MatchingTaxonConfigurator.NewInstance();
countEqualCandidates = 1;
continue;
}
-
}else{ //not Taxon.class
continue;
}
}
}
-
// 2. search for synonyms
if (config.isIncludeSynonyms()){
List<TaxonBase> synonymList = dao.findByNameTitleCache(false, true, config.isIncludeUnpublished(),
return null;
}
+ @Override
+ @Transactional(readOnly = false)
+ public UpdateResult moveSynonymToAnotherTaxon(Synonym oldSynonym, UUID newTaxonUUID, boolean moveHomotypicGroup,
+ SynonymType newSynonymType, UUID newSecundumUuid, String newSecundumDetail,
+ boolean keepSecundumIfUndefined) throws HomotypicalGroupChangeException {
+
+ UpdateResult result = new UpdateResult();
+ Taxon newTaxon = CdmBase.deproxy(dao.load(newTaxonUUID), Taxon.class);
+ result = moveSynonymToAnotherTaxon(oldSynonym, newTaxon, moveHomotypicGroup, newSynonymType,
+ newSecundumUuid, newSecundumDetail, keepSecundumIfUndefined);
+
+ return result;
+ }
+
@Override
@Transactional(readOnly = false)
public UpdateResult moveSynonymToAnotherTaxon(Synonym oldSynonym,
SynonymType newSynonymType) throws HomotypicalGroupChangeException {
return moveSynonymToAnotherTaxon(oldSynonym, newTaxon, moveHomotypicGroup,
newSynonymType,
- oldSynonym.getSec(),
+ oldSynonym.getSec()!= null? oldSynonym.getSec().getUuid(): null,
oldSynonym.getSecMicroReference(),
true);
}
Taxon newTaxon,
boolean moveHomotypicGroup,
SynonymType newSynonymType,
- Reference newSecundum,
+ UUID newSecundumUuid,
String newSecundumDetail,
boolean keepSecundumIfUndefined) throws HomotypicalGroupChangeException {
UpdateResult result = new UpdateResult();
//move all synonyms to new taxon
List<Synonym> homotypicSynonyms = oldTaxon.getSynonymsInGroup(homotypicGroup);
+ Reference newSecundum = referenceService.load(newSecundumUuid);
for (Synonym synRelation: homotypicSynonyms){
newTaxon = HibernateProxyHelper.deproxy(newTaxon, Taxon.class);
result.addUpdatedObject(oldTaxon);
result.addUpdatedObject(newTaxon);
+ result.addUpdatedObject(homotypicGroup);
+ result.addUpdatedObject(synonym);
saveOrUpdate(oldTaxon);
saveOrUpdate(newTaxon);
}
@Override
- public <T extends TaxonBase> List<UuidAndTitleCache<T>> getUuidAndTitleCache(Class<T> clazz, Integer limit, String pattern) {
+ public <T extends TaxonBase>List<UuidAndTitleCache<T>> getUuidAndTitleCache(Class<T> clazz, Integer limit, String pattern) {
+
return dao.getUuidAndTitleCache(clazz, limit, pattern);
}
}
Map<CdmBaseType, String> idFieldMap = new HashMap<>();
- idFieldMap.put(CdmBaseType.TAXON, "id");
+ idFieldMap.put(CdmBaseType.TAXON_BASE, "id");
// --- initialize taxa, thighlight matches ....
ISearchResultBuilder searchResultBuilder = new SearchResultBuilder(luceneSearch, luceneSearch.getQuery());
+ @SuppressWarnings("rawtypes")
List<SearchResult<TaxonBase>> searchResults = searchResultBuilder.createResultSet(
topDocsResultSet, luceneSearch.getHighlightFields(), dao, idFieldMap, propertyPaths);
return new DefaultPagerImpl<>(pageNumber, totalHits, pageSize, searchResults);
}
+ @Transactional(readOnly = true)
+ @Override
+ public <S extends TaxonBase> Pager<S> findByTitleWithRestrictions(Class<S> clazz, String queryString, MatchMode matchmode, List<Restriction<?>> restrictions, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {
+ long numberOfResults = dao.countByTitleWithRestrictions(clazz, queryString, matchmode, restrictions);
+
+ long numberOfResults_doubtful = dao.countByTitleWithRestrictions(clazz, "?".concat(queryString), matchmode, restrictions);
+ List<S> 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 <S extends TaxonBase> Pager<S> findByTitle(Class<S> clazz, String queryString,MatchMode matchmode, List<Criterion> criteria, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> 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<S> 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<SearchResult<TaxonBase>> findByDistribution(List<NamedArea> areaFilter, List<PresenceAbsenceTerm> statusFilter,
Classification classification, TaxonNode subtree,
}
Map<CdmBaseType, String> idFieldMap = new HashMap<>();
- idFieldMap.put(CdmBaseType.TAXON, "id");
+ idFieldMap.put(CdmBaseType.TAXON_BASE, "id");
// --- initialize taxa, thighlight matches ....
ISearchResultBuilder searchResultBuilder = new SearchResultBuilder(luceneSearch, luceneSearch.getQuery());
* Uses org.apache.lucene.search.join.JoinUtil for query time joining, alternatively
* the BlockJoinQuery could be used. The latter might be more memory save but has the
* drawback of requiring to do the join an indexing time.
- * see http://dev.e-taxonomy.eu/trac/wiki/LuceneNotes#JoinsinLucene for more information on this.
+ * see https://dev.e-taxonomy.eu/redmine/projects/edit/wiki/LuceneNotes#JoinsinLucene for more information on this.
*
* Joins TaxonRelationShip with Taxon depending on the direction of the given edge:
* <ul>
Set<NamedArea> namedAreas, Set<PresenceAbsenceTerm> distributionStatus, List<Language> languages,
boolean highlightFragments, Integer pageSize,
Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths)
- throws IOException, LuceneParseException, LuceneMultiSearchException {
+ throws IOException, LuceneParseException, LuceneMultiSearchException {
// FIXME: allow taxonomic ordering
- // hql equivalent: order by t.name.genusOrUninomial, case when t.name.specificEpithet like '\"%\"' then 1 else 0 end, t.name.specificEpithet, t.name.rank desc, t.name.nameCache";
- // this require building a special sort column by a special classBridge
+ // hql equivalent: order by t.name.genusOrUninomial, case when t.name.specificEpithet
+ // like '\"%\"' then 1 else 0 end, t.name.specificEpithet, t.name.rank desc, t.name.nameCache";
+ // this requires building a special sort column by a special classBridge
if(highlightFragments){
logger.warn("findTaxaAndNamesByFullText() : fragment highlighting is " +
"currently not fully supported by this method and thus " +
// 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<LuceneSearch> luceneSearches = new ArrayList<>();
luceneSearches.add(prepareFindByFullTextSearch(taxonBaseSubclass,
queryString, classification, subtree, className,
includeUnpublished, languages, highlightFragments, sortFields));
- idFieldMap.put(CdmBaseType.TAXON, "id");
+ idFieldMap.put(CdmBaseType.TAXON_BASE, "id");
/* A) does not work!!!!
if(addDistributionFilter){
// in this case we need a filter which uses a join query
byCommonNameSearch.setQuery(builder.build());
byCommonNameSearch.setSortFields(sortFields);
- idFieldMap.put(CdmBaseType.TAXON, "id");
+ idFieldMap.put(CdmBaseType.TAXON_BASE, "id");
luceneSearches.add(byCommonNameSearch);
luceneSearches.add(prepareFindByTaxonRelationFullTextSearch(
new TaxonRelationshipEdge(relTypes, Direction.relatedTo),
queryString, classification, subtree, includeUnpublished, languages, highlightFragments, sortFields));
- idFieldMap.put(CdmBaseType.TAXON, "id");
+ idFieldMap.put(CdmBaseType.TAXON_BASE, "id");
if(addDistributionFilter){
String fromField = "inDescription.taxon.id"; // in DescriptionElementBase index
}
}
-
// search by pro parte synonyms
if(searchModes.contains(TaxaAndNamesSearchMode.doSynonyms)) {
//TODO merge with misapplied name search once #7487 is fixed
luceneSearches.add(prepareFindByTaxonRelationFullTextSearch(
new TaxonRelationshipEdge(relTypes, Direction.relatedTo),
queryString, classification, subtree, includeUnpublished, languages, highlightFragments, sortFields));
- idFieldMap.put(CdmBaseType.TAXON, "id");
+ idFieldMap.put(CdmBaseType.TAXON_BASE, "id");
if(addDistributionFilter){
String fromField = "inDescription.taxon.id"; // in DescriptionElementBase index
}
}//end pro parte synonyms
-
-
LuceneMultiSearch multiSearch = new LuceneMultiSearch(luceneIndexToolProvider,
luceneSearches.toArray(new LuceneSearch[luceneSearches.size()]));
-
if(addDistributionFilter){
// B)
Classification classification, TaxonNode subtree, List<Feature> features, List<Language> languages,
boolean highlightFragments, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) throws IOException, LuceneParseException {
-
LuceneSearch luceneSearch = prepareByDescriptionElementFullTextSearch(clazz, queryString, classification, subtree, features, languages, highlightFragments);
// --- execute search
int totalHits = topDocsResultSet != null ? topDocsResultSet.totalGroupCount : 0;
return new DefaultPagerImpl<>(pageNumber, Long.valueOf(totalHits), pageSize, searchResults);
-
}
-
@Override
public Pager<SearchResult<TaxonBase>> findByEverythingFullText(String queryString,
Classification classification, TaxonNode subtree, boolean includeUnpublished, List<Language> languages, boolean highlightFragments,
ISearchResultBuilder searchResultBuilder = new SearchResultBuilder(multiSearch, multiSearch.getQuery());
Map<CdmBaseType, String> idFieldMap = new HashMap<>();
- idFieldMap.put(CdmBaseType.TAXON, "id");
+ idFieldMap.put(CdmBaseType.TAXON_BASE, "id");
idFieldMap.put(CdmBaseType.DESCRIPTION_ELEMENT, "inDescription.taxon.id");
List<SearchResult<TaxonBase>> searchResults = searchResultBuilder.createResultSet(
int totalHits = topDocsResultSet != null ? topDocsResultSet.totalGroupCount : 0;
return new DefaultPagerImpl<>(pageNumber, Long.valueOf(totalHits), pageSize, searchResults);
-
}
-
/**
* @param clazz
* @param queryString
@Override
public List<Synonym> createInferredSynonyms(Taxon taxon, Classification classification, SynonymType type, boolean doWithMisappliedNames){
-
List <Synonym> inferredSynonyms = new ArrayList<>();
List<Synonym> inferredSynonymsToBeRemoved = new ArrayList<>();
}
if (!taxonNames.isEmpty()){
- List<String> 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<String> 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){
+ }else if (type.equals(SynonymType.INFERRED_GENUS_OF())){
- 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());
- }
-
- 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 (!taxonNames.isEmpty()){
- List<String> synNotInCDM = dao.taxaByNameNotInDB(taxonNames);
- IZoologicalName name;
- if (!synNotInCDM.isEmpty()){
- inferredSynonymsToBeRemoved.clear();
+ if (doWithMisappliedNames){
- 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<String> 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){
+ }else if (type.equals(SynonymType.POTENTIAL_COMBINATION_OF())){
- TaxonName misappliedParentName;
-
- 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;
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);
taxonNames.add(potentialCombination.getName().getNameCache());
}
}
- }
- if (!taxonNames.isEmpty()){
- List<String> 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<String> 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.");
}
}
}
-
}
return inferredSynonyms;
inferredSynName.setInfraGenericEpithet(synParentInfragenericName);
}
-
potentialCombination = Synonym.NewInstance(inferredSynName, null);
// Set the sourceReference
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());
inferredSynName.setInfraSpecificEpithet(synZooName.getInfraGenericEpithet());
}
-
inferredGenus = Synonym.NewInstance(inferredSynName, null);
// Set the sourceReference
synSpecificEpithet = zooSynName.getSpecificEpithet();
}
- /* if (synGenusName != null && !synonymsGenus.containsKey(synGenusName)){
+ /* if (synGenusName != null && !synonymsGenus.containsKey(synGenusName)){
synonymsGenus.put(synGenusName, idInSource);
}*/
inferredSynName.addSource(originalSource);
-
-
taxon.addSynonym(inferredEpithet, SynonymType.INFERRED_EPITHET_OF());
return inferredEpithet;
logger.warn("No idInSource for TaxonBase " + taxonBase.getUuid() + " - " + taxonBase.getTitleCache());
}
-
return idInSource;
}
-
/**
* Returns the citation for a given Synonym.
* @param syn
Taxon toTaxon = (Taxon) dao.load(toTaxonUuid);
result = changeRelatedTaxonToSynonym(fromTaxon, toTaxon, oldRelationshipType, synonymType);
- result.addUpdatedObject(fromTaxon);
result.addUpdatedObject(toTaxon);
result.addUpdatedObject(result.getCdmEntity());
} else{
synonym = toTaxon.addHeterotypicSynonymName(synonymName);
}
-
+ //keep the publish flag
+ synonym.setPublish(fromTaxon.isPublish());
this.saveOrUpdate(toTaxon);
//TODO: configurator and classification
TaxonDeletionConfigurator config = new TaxonDeletionConfigurator();
Set<CdmBase> references = commonService.getReferencingObjectsForDeletion(taxonBase);
if (taxonBase instanceof Taxon){
TaxonDeletionConfigurator taxonConfig = (TaxonDeletionConfigurator) config;
- result = isDeletableForTaxon(references, taxonConfig);
+ List<String> 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() && taxonBase.getName() != null){
+ DeleteResult nameResult = nameService.isDeletable(taxonBase.getName().getUuid(), synonymConfig.getNameDeletionConfig(), taxonBase.getUuid());
+ if (!nameResult.isOk()){
+ result.addExceptions(nameResult.getExceptions());
+
+ }
+ }
}
+
return result;
}
private DeleteResult isDeletableForSynonym(Set<CdmBase> references, SynonymDeletionConfigurator config){
- String message;
+
DeleteResult result = new DeleteResult();
for (CdmBase ref: references){
- if (!(ref instanceof Taxon || ref instanceof TaxonName )){
- message = "The Synonym can't be deleted as long as it is referenced by " + ref.getClass().getSimpleName() + " with id "+ ref.getId();
+ if (!(ref instanceof Taxon || ref instanceof TaxonName || ref instanceof SecundumSource)){
+ String message = "The Synonym can't be deleted as long as it is referenced by " + ref.getClass().getSimpleName() + " with id "+ ref.getId();
result.addException(new ReferencedObjectUndeletableException(message));
result.addRelatedObject(ref);
result.setAbort();
String message = null;
DeleteResult result = new DeleteResult();
for (CdmBase ref: references){
- if (!(ref instanceof TaxonName)){
+ if (!(ref instanceof TaxonName || ref instanceof SecundumSource)){
message = null;
if (!config.isDeleteSynonymRelations() && (ref instanceof Synonym)){
message = "The taxon can't be deleted as long as it has synonyms.";
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.";
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";
@Override
public List<TaxonBase> findTaxaByName(MatchingTaxonConfigurator config){
+ @SuppressWarnings("rawtypes")
List<TaxonBase> 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;
}
@Override
- @Transactional(readOnly = false)
- public UpdateResult moveSynonymToAnotherTaxon(Synonym oldSynonym, UUID newTaxonUUID, boolean moveHomotypicGroup,
- SynonymType newSynonymType, Reference newSecundum, String newSecundumDetail,
- boolean keepSecundumIfUndefined) throws HomotypicalGroupChangeException {
-
- UpdateResult result = new UpdateResult();
- Taxon newTaxon = CdmBase.deproxy(dao.load(newTaxonUUID),Taxon.class);
- result = moveSynonymToAnotherTaxon(oldSynonym, newTaxon, moveHomotypicGroup, newSynonymType,
- newSecundum, newSecundumDetail, keepSecundumIfUndefined);
-
- return result;
- }
-
- @Override
public UpdateResult moveFactualDateToAnotherTaxon(UUID fromTaxonUuid, UUID toTaxonUuid){
UpdateResult result = new UpdateResult();
@Override
@Transactional(readOnly = false)
public UpdateResult swapSynonymAndAcceptedTaxon(UUID synonymUUid,
- UUID acceptedTaxonUuid) {
+ UUID acceptedTaxonUuid, boolean setNameInSource, boolean newUuidForAcceptedTaxon, SecReferenceHandlingSwapEnum secHandling, UUID newSecAcc, UUID newSecSyn) {
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);
+ Reference refAcc = referenceService.load(newSecAcc);
+ Reference refSyn = referenceService.load(newSecSyn);
+
+ return this.swapSynonymAndAcceptedTaxon(syn, taxon, setNameInSource, newUuidForAcceptedTaxon, secHandling, refAcc, refSyn);
}
- /**
- * {@inheritDoc}
- */
@Override
public TaxonRelationshipsDTO listTaxonRelationships(UUID taxonUuid, Set<TaxonRelationshipType> directTypes,
Set<TaxonRelationshipType> inversTypes,
return dto;
}
}
-
}