import java.util.Map;
import java.util.Set;
import java.util.UUID;
+import java.util.stream.Collectors;
import javax.persistence.EntityNotFoundException;
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.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;
@Override
@Transactional(readOnly = false)
- public UpdateResult swapSynonymAndAcceptedTaxon(Synonym synonym, Taxon acceptedTaxon, boolean setNameInSource, boolean newUuidForAcceptedTaxon){
+ public UpdateResult swapSynonymAndAcceptedTaxon(Synonym synonym, Taxon acceptedTaxon, boolean setNameInSource, boolean newUuidForAcceptedTaxon, SecReferenceHandlingSwapEnum secHandling, Reference newSecAcc, Reference newSecSyn){
if (newUuidForAcceptedTaxon){
- return swapSynonymAndAcceptedTaxonNewUuid(synonym, acceptedTaxon, setNameInSource);
+ return swapSynonymAndAcceptedTaxonNewUuid(synonym, acceptedTaxon, setNameInSource, secHandling, newSecAcc, newSecSyn);
}else{
- return swapSynonymAndAcceptedTaxon(synonym, acceptedTaxon, setNameInSource);
+ return swapSynonymAndAcceptedTaxon(synonym, acceptedTaxon, setNameInSource, secHandling, newSecAcc, newSecSyn);
}
}
- private UpdateResult swapSynonymAndAcceptedTaxon(Synonym synonym, Taxon acceptedTaxon, boolean setNameInSource){
+ 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;
+// }
- boolean sameHomotypicGroup = synonymName.getHomotypicalGroup().equals(taxonName.getHomotypicalGroup());
+ 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());
- saveOrUpdate(acceptedTaxon);
- saveOrUpdate(synonym);
- result.setCdmEntity(acceptedTaxon);
- result.addUpdatedObject(synonym);
+ 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 synonym, Taxon acceptedTaxon, boolean setNameInSource){
+ private UpdateResult swapSynonymAndAcceptedTaxonNewUuid(Synonym oldSynonym, Taxon oldAcceptedTaxon, boolean setNameInSource, SecReferenceHandlingSwapEnum secHandling, Reference newSecAcc, Reference newSecSyn){
UpdateResult result = new UpdateResult();
- acceptedTaxon.removeSynonym(synonym);
- TaxonName synonymName = synonym.getName();
- TaxonName taxonName = HibernateProxyHelper.deproxy(acceptedTaxon.getName());
- String oldTaxonTitleCache = acceptedTaxon.getTitleCache();
+ 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(synonym);
+ synonymName.removeTaxonBase(oldSynonym);
List<Synonym> synonyms = new ArrayList<>();
- for (Synonym syn: acceptedTaxon.getSynonyms()){
+ for (Synonym syn: oldAcceptedTaxon.getSynonyms()){
syn = HibernateProxyHelper.deproxy(syn, Synonym.class);
synonyms.add(syn);
}
for (Synonym syn: synonyms){
- acceptedTaxon.removeSynonym(syn);
+ oldAcceptedTaxon.removeSynonym(syn);
}
- Taxon newTaxon = acceptedTaxon.clone(true, true, false, true);
+ Taxon newTaxon = oldAcceptedTaxon.clone(true, true, false, true);
+ newTaxon.setSec(newSecAcc);
//move descriptions
- Set<TaxonDescription> descriptionsToCopy = new HashSet<>(acceptedTaxon.getDescriptions());
+ Set<TaxonDescription> descriptionsToCopy = new HashSet<>(oldAcceptedTaxon.getDescriptions());
for (TaxonDescription description: descriptionsToCopy){
newTaxon.addDescription(description);
}
newTaxon.setName(synonymName);
- newTaxon.setPublish(synonym.isPublish());
+ newTaxon.setPublish(oldSynonym.isPublish());
for (Synonym syn: synonyms){
if (!syn.getName().equals(newTaxon.getName())){
newTaxon.addSynonym(syn, syn.getType());
newTaxon.removeTaxonRelation(taxonRelationship);
}
- for(TaxonRelationship taxonRelationship : acceptedTaxon.getTaxonRelations()){
+ for(TaxonRelationship taxonRelationship : oldAcceptedTaxon.getTaxonRelations()){
Taxon fromTaxon = HibernateProxyHelper.deproxy(taxonRelationship.getFromTaxon());
Taxon toTaxon = HibernateProxyHelper.deproxy(taxonRelationship.getToTaxon());
- if (fromTaxon == acceptedTaxon){
+ if (fromTaxon == oldAcceptedTaxon){
newTaxon.addTaxonRelation(taxonRelationship.getToTaxon(), taxonRelationship.getType(),
taxonRelationship.getCitation(), taxonRelationship.getCitationMicroReference());
- }else if(toTaxon == acceptedTaxon){
+ }else if(toTaxon == oldAcceptedTaxon){
fromTaxon.addTaxonRelation(newTaxon, taxonRelationship.getType(),
taxonRelationship.getCitation(), taxonRelationship.getCitationMicroReference());
saveOrUpdate(fromTaxon);
}
//taxon nodes
- List<TaxonNode> nodes = new ArrayList<>(acceptedTaxon.getTaxonNodes());
+ List<TaxonNode> nodes = new ArrayList<>(oldAcceptedTaxon.getTaxonNodes());
for (TaxonNode node: nodes){
node = HibernateProxyHelper.deproxy(node);
TaxonNode parent = node.getParent();
- acceptedTaxon.removeTaxonNode(node);
+ oldAcceptedTaxon.removeTaxonNode(node);
node.setTaxon(newTaxon);
if (parent != null){
parent.addChildNode(node, null, null);
}
//synonym
- Synonym newSynonym = synonym.clone();
+ Synonym newSynonym = oldSynonym.clone();
newSynonym.setName(taxonName);
- newSynonym.setPublish(acceptedTaxon.isPublish());
+ newSynonym.setPublish(oldAcceptedTaxon.isPublish());
+ newSynonym.setSec(newSecSyn);
if (sameHomotypicGroup){
newTaxon.addSynonym(newSynonym, SynonymType.HOMOTYPIC_SYNONYM_OF());
}else{
confSyn.setDeleteNameIfPossible(false);
result.setCdmEntity(newTaxon);
- DeleteResult deleteResult = deleteTaxon(acceptedTaxon.getUuid(), conf, null);
- if (synonym.isPersited()){
- synonym.setSecSource(null);
- deleteResult.includeResult(deleteSynonym(synonym.getUuid(), confSyn));
+ DeleteResult deleteResult = deleteTaxon(oldAcceptedTaxon.getUuid(), conf, null);
+ if (oldSynonym.isPersited()){
+ oldSynonym.setSecSource(null);
+ deleteResult.includeResult(deleteSynonym(oldSynonym.getUuid(), confSyn));
}
result.includeResult(deleteResult);
result.setAbort();
return result;
}
- if (secHandling != null && secHandling.equals(SecReferenceHandlingEnum.KeepAlways)){
- newSecRef = synonym.getSec();
- }
+
Taxon newAcceptedTaxon = Taxon.NewInstance(synonymName, newSecRef, microRef);
newAcceptedTaxon.setPublish(synonym.isPublish());
dao.save(newAcceptedTaxon);
List<Synonym> heteroSynonyms = acceptedTaxon.getSynonymsInGroup(synonymHomotypicGroup);
for (Synonym heteroSynonym : heteroSynonyms){
- if (secHandling == null || !secHandling.equals(SecReferenceHandlingEnum.KeepAlways)){
+ if (secHandling == null){
heteroSynonym.setSec(newSecRef);
}
if (synonym.equals(heteroSynonym)){
case AlwaysDelete:
newSecRef = null;
break;
- case KeepAlways:
- break;
case UseNewParentSec:
newSecRef = newParentNode.getTaxon() != null? newParentNode.getTaxon().getSec(): null;
break;
- case KeepWhenSame:
+ case KeepOrWarn:
Reference parentSec = newParentNode.getTaxon() != null? newParentNode.getTaxon().getSec(): null;
Reference synSec = synonym.getSec();
- if (parentSec != null && synSec != null && parentSec.equals(synSec)){
- newSecRef = synonym.getSec();
+ if (synSec != null ){
+ newSecRef = CdmBase.deproxy(synSec);
}else{
newSecRef = CdmBase.deproxy(referenceService.load(newSec));
}
break;
- case WarningSelect:
+ case KeepOrSelect:
newSecRef = CdmBase.deproxy(referenceService.load(newSec));
break;
default:
// 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
}
}
//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()) {
}
}
- logger.trace("listMedia() - initialize");
+ taxonMedia = deduplicateMedia(taxonMedia);
+
+ 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, null);
//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;
result.addUpdatedObject(oldTaxon);
result.addUpdatedObject(newTaxon);
+ result.addUpdatedObject(homotypicGroup);
+ result.addUpdatedObject(synonym);
saveOrUpdate(oldTaxon);
saveOrUpdate(newTaxon);
}
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());
}
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 " +
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
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
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(
Taxon toTaxon = (Taxon) dao.load(toTaxonUuid);
result = changeRelatedTaxonToSynonym(fromTaxon, toTaxon, oldRelationshipType, synonymType);
-// result.addUpdatedObject(fromTaxon);
result.addUpdatedObject(toTaxon);
result.addUpdatedObject(result.getCdmEntity());
}else{
SynonymDeletionConfigurator synonymConfig = (SynonymDeletionConfigurator) config;
result = isDeletableForSynonym(references, synonymConfig);
- if (synonymConfig.isDeleteNameIfPossible()){
+ if (synonymConfig.isDeleteNameIfPossible() && taxonBase.getName() != null){
DeleteResult nameResult = nameService.isDeletable(taxonBase.getName().getUuid(), synonymConfig.getNameDeletionConfig(), taxonBase.getUuid());
if (!nameResult.isOk()){
result.addExceptions(nameResult.getExceptions());
+
}
}
}
@Override
@Transactional(readOnly = false)
public UpdateResult swapSynonymAndAcceptedTaxon(UUID synonymUUid,
- UUID acceptedTaxonUuid, boolean setNameInSource, boolean newUuidForAcceptedTaxon) {
+ 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, setNameInSource, newUuidForAcceptedTaxon);
+ Reference refAcc = referenceService.load(newSecAcc);
+ Reference refSyn = referenceService.load(newSecSyn);
+
+ return this.swapSynonymAndAcceptedTaxon(syn, taxon, setNameInSource, newUuidForAcceptedTaxon, secHandling, refAcc, refSyn);
}
@Override