X-Git-Url: https://dev.e-taxonomy.eu/gitweb/cdmlib.git/blobdiff_plain/1d54cd17de6f310b117e09da584341e8afe31399..b3efd136d482e66d851a80d9cce57583bf7cb1f6:/cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/ClassificationServiceImpl.java diff --git a/cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/ClassificationServiceImpl.java b/cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/ClassificationServiceImpl.java old mode 100755 new mode 100644 index f3a6acf66f..9de05cfb17 --- a/cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/ClassificationServiceImpl.java +++ b/cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/ClassificationServiceImpl.java @@ -1,4 +1,3 @@ -// $Id$ /** * Copyright (C) 2007 EDIT * European Distributed Institute of Taxonomy @@ -16,12 +15,17 @@ import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.TreeMap; import java.util.UUID; +import javax.persistence.EntityNotFoundException; + import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -39,18 +43,22 @@ import eu.etaxonomy.cdm.api.service.pager.PagerUtils; import eu.etaxonomy.cdm.api.service.pager.impl.AbstractPagerImpl; import eu.etaxonomy.cdm.api.service.pager.impl.DefaultPagerImpl; import eu.etaxonomy.cdm.common.monitor.IProgressMonitor; +import eu.etaxonomy.cdm.hibernate.HHH_9751_Util; +import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper; import eu.etaxonomy.cdm.model.common.CdmBase; import eu.etaxonomy.cdm.model.common.DefinedTermBase; import eu.etaxonomy.cdm.model.common.ITreeNode; import eu.etaxonomy.cdm.model.common.MarkerType; +import eu.etaxonomy.cdm.model.common.TreeIndex; import eu.etaxonomy.cdm.model.description.DescriptionElementBase; import eu.etaxonomy.cdm.model.description.TaxonDescription; import eu.etaxonomy.cdm.model.media.Media; import eu.etaxonomy.cdm.model.media.MediaRepresentation; import eu.etaxonomy.cdm.model.media.MediaUtils; -import eu.etaxonomy.cdm.model.name.NonViralName; +import eu.etaxonomy.cdm.model.name.INonViralName; import eu.etaxonomy.cdm.model.name.Rank; -import eu.etaxonomy.cdm.model.name.TaxonNameBase; +import eu.etaxonomy.cdm.model.name.TaxonName; +import eu.etaxonomy.cdm.model.reference.Reference; import eu.etaxonomy.cdm.model.taxon.Classification; import eu.etaxonomy.cdm.model.taxon.ITaxonNodeComparator; import eu.etaxonomy.cdm.model.taxon.ITaxonTreeNode; @@ -58,6 +66,7 @@ import eu.etaxonomy.cdm.model.taxon.Synonym; import eu.etaxonomy.cdm.model.taxon.Taxon; import eu.etaxonomy.cdm.model.taxon.TaxonBase; import eu.etaxonomy.cdm.model.taxon.TaxonNode; +import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType; import eu.etaxonomy.cdm.persistence.dao.common.IDefinedTermDao; import eu.etaxonomy.cdm.persistence.dao.initializer.IBeanInitializer; import eu.etaxonomy.cdm.persistence.dao.taxon.IClassificationDao; @@ -65,7 +74,7 @@ import eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao; import eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonNodeDao; import eu.etaxonomy.cdm.persistence.dto.ClassificationLookupDTO; import eu.etaxonomy.cdm.persistence.dto.TaxonNodeDto; -import eu.etaxonomy.cdm.persistence.dto.TaxonNodeDto.TaxonStatus; +import eu.etaxonomy.cdm.persistence.dto.TaxonStatus; import eu.etaxonomy.cdm.persistence.dto.UuidAndTitleCache; import eu.etaxonomy.cdm.persistence.query.OrderHint; import eu.etaxonomy.cdm.strategy.cache.common.IIdentifiableEntityCacheStrategy; @@ -127,6 +136,53 @@ public class ClassificationServiceImpl extends IdentifiableServiceBase childNodes = classification.getRootNode().getChildNodes(); + for (TaxonNode taxonNode : childNodes) { + addChildTaxa(taxonNode, null, clone, relationshipType); + } + dao.saveOrUpdate(clone); + result.setCdmEntity(clone); + return result; + } + + private void addChildTaxa(TaxonNode originalParentNode, TaxonNode cloneParentNode, Classification classification, TaxonRelationshipType relationshipType){ + Reference reference = classification.getReference(); + Taxon cloneTaxon = (Taxon) HibernateProxyHelper.deproxy(originalParentNode.getTaxon(), Taxon.class).clone(); + cloneTaxon.setSec(reference); + String microReference = null; + List originalChildNodes = originalParentNode.getChildNodes(); + HHH_9751_Util.removeAllNull(originalChildNodes); + + //add relation between taxa + if (relationshipType != null){ + cloneTaxon.addTaxonRelation(originalParentNode.getTaxon(), relationshipType, reference, microReference); + } + + TaxonNode cloneChildNode = null; + //add taxon node to either parent node or classification (no parent node) + if(cloneParentNode==null){ + cloneChildNode = classification.addChildTaxon(cloneTaxon, reference, microReference); + } + else{ + cloneChildNode = cloneParentNode.addChildTaxon(cloneTaxon, reference, microReference); + } + taxonNodeDao.saveOrUpdate(cloneChildNode); + //add children + for (TaxonNode originalChildNode : originalChildNodes) { + addChildTaxa(originalChildNode, cloneChildNode, classification, relationshipType); + } + } + @Override public List listRankSpecificRootNodes(Classification classification, Rank rank, Integer pageSize, Integer pageIndex, List propertyPaths) { @@ -185,6 +241,9 @@ public class ClassificationServiceImpl extends IdentifiableServiceBase loadTreeBranch(TaxonNode taxonNode, Rank baseRank, List propertyPaths){ TaxonNode thisNode = taxonNodeDao.load(taxonNode.getUuid(), propertyPaths); + if(baseRank != null){ + baseRank = (Rank) termDao.load(baseRank.getUuid()); + } List pathToRoot = new ArrayList(); pathToRoot.add(thisNode); @@ -333,6 +392,14 @@ public class ClassificationServiceImpl extends IdentifiableServiceBase> getAllMediaForChildNodes(Taxon taxon, Classification taxTree, List propertyPaths, int size, int height, int widthOrDuration, String[] mimeTypes){ - TaxonNode node = taxTree.getNode(taxon); - - return getAllMediaForChildNodes(node, propertyPaths, size, height, widthOrDuration, mimeTypes); - } @Override @Transactional(readOnly = false) @@ -442,11 +503,11 @@ public class ClassificationServiceImpl extends IdentifiableServiceBase> sortedGenusMap = new HashMap>(); + Map> sortedGenusMap = new HashMap<>(); for(TaxonNode node:allNodesOfClassification){ final TaxonNode tn = node; Taxon taxon = node.getTaxon(); - NonViralName name = CdmBase.deproxy(taxon.getName(), NonViralName.class); + INonViralName name = taxon.getName(); String genusOrUninomial = name.getGenusOrUninomial(); //if rank unknown split string and take first word if(genusOrUninomial == null){ @@ -484,7 +545,7 @@ public class ClassificationServiceImpl extends IdentifiableServiceBase> map = getSortedGenusList(classification.getAllNodes()); final String APPENDIX = "repaired"; - String titleCache = org.apache.commons.lang.StringUtils.isBlank(classification.getTitleCache()) ? " " : classification.getTitleCache() ; + String titleCache = StringUtils.isBlank(classification.getTitleCache()) ? " " : classification.getTitleCache() ; //TODO classification clone??? Classification newClassification = Classification.NewInstance(titleCache +" "+ APPENDIX); newClassification.setReference(classification.getReference()); @@ -506,9 +567,8 @@ public class ClassificationServiceImpl extends IdentifiableServiceBase result = new ArrayList<>(); //get treeindex for each taxonUUID - Map taxonIdTreeIndexMap = dao.treeIndexForTaxonUuids(classificationUuid, originalTaxonUuids); + Map taxonIdTreeIndexMap = dao.treeIndexForTaxonUuids(classificationUuid, originalTaxonUuids); //build treeindex list (or tree) - List treeIndexClosure = new ArrayList<>(); - for (String treeIndex : taxonIdTreeIndexMap.values()){ - String[] splits = treeIndex.substring(1).split(ITreeNode.separator); + //TODO make it work with TreeIndex or move there + List treeIndexClosureStr = new ArrayList<>(); + for (TreeIndex treeIndex : taxonIdTreeIndexMap.values()){ + String[] splits = treeIndex.toString().substring(1).split(ITreeNode.separator); String currentIndex = ITreeNode.separator; for (String split : splits){ if (split.equals("")){ continue; } currentIndex += split + ITreeNode.separator; - if (!treeIndexClosure.contains(currentIndex) && !split.startsWith(ITreeNode.treePrefix)){ - treeIndexClosure.add(currentIndex); + if (!treeIndexClosureStr.contains(currentIndex) && !split.startsWith(ITreeNode.treePrefix)){ + treeIndexClosureStr.add(currentIndex); } } } @@ -661,15 +726,17 @@ public class ClassificationServiceImpl extends IdentifiableServiceBase= maxRank (if available) Integer minRankOrderIndex = minRank == null ? null : minRank.getOrderIndex(); Integer maxRankOrderIndex = maxRank == null ? null : maxRank.getOrderIndex(); - Map treeIndexSortIndexMapTmp = taxonNodeDao.rankOrderIndexForTreeIndex(treeIndexClosure, minRankOrderIndex, maxRankOrderIndex); + List treeIndexClosure = TreeIndex.NewListInstance(treeIndexClosureStr); + + Map treeIndexSortIndexMapTmp = taxonNodeDao.rankOrderIndexForTreeIndex(treeIndexClosure, minRankOrderIndex, maxRankOrderIndex); //remove all treeindex with "exists child in above map(and child.sortindex > xxx) - List treeIndexList = new ArrayList<>(treeIndexSortIndexMapTmp.keySet()); - Collections.sort(treeIndexList, new TreeIndexComparator()); - Map treeIndexSortIndexMap = new HashMap<>(); - String lastTreeIndex = null; - for (String treeIndex : treeIndexList){ - if (lastTreeIndex != null && treeIndex.startsWith(lastTreeIndex)){ + List treeIndexList = TreeIndex.sort(treeIndexSortIndexMapTmp.keySet()); + + Map treeIndexSortIndexMap = new HashMap<>(); + TreeIndex lastTreeIndex = null; + for (TreeIndex treeIndex : treeIndexList){ + if (lastTreeIndex != null && lastTreeIndex.hasChild(treeIndex)){ treeIndexSortIndexMap.remove(lastTreeIndex); } treeIndexSortIndexMap.put(treeIndex, treeIndexSortIndexMapTmp.get(treeIndex)); @@ -677,23 +744,25 @@ public class ClassificationServiceImpl extends IdentifiableServiceBase> treeIndexTaxonIdMap = taxonNodeDao.taxonUuidsForTreeIndexes(treeIndexSortIndexMap.keySet()); + Map> treeIndexTaxonIdMap = taxonNodeDao.taxonUuidsForTreeIndexes(treeIndexSortIndexMap.keySet()); //fill result list for (UUID originalTaxonUuid : originalTaxonUuids){ GroupedTaxonDTO item = new GroupedTaxonDTO(); result.add(item); item.setTaxonUuid(originalTaxonUuid); - String groupIndex = taxonIdTreeIndexMap.get(originalTaxonUuid); - while (groupIndex != null){ - if (treeIndexTaxonIdMap.get(groupIndex) != null){ - UuidAndTitleCache uuidAndLabel = treeIndexTaxonIdMap.get(groupIndex); + TreeIndex groupTreeIndex = taxonIdTreeIndexMap.get(originalTaxonUuid); + String groupIndexX = TreeIndex.toString(groupTreeIndex); + while (groupTreeIndex != null){ + if (treeIndexTaxonIdMap.get(groupTreeIndex) != null){ + UuidAndTitleCache uuidAndLabel = treeIndexTaxonIdMap.get(groupTreeIndex); item.setGroupTaxonUuid(uuidAndLabel.getUuid()); item.setGroupTaxonName(uuidAndLabel.getTitleCache()); break; }else{ - int index = groupIndex.substring(0, groupIndex.length()-1).lastIndexOf(ITreeNode.separator); - groupIndex = index<0 ? null : groupIndex.substring(0, index+1); + groupTreeIndex = groupTreeIndex.parent(); +// int index = groupIndex.substring(0, groupIndex.length()-1).lastIndexOf(ITreeNode.separator); +// groupIndex = index < 0 ? null : groupIndex.substring(0, index+1); } } } @@ -701,6 +770,47 @@ public class ClassificationServiceImpl extends IdentifiableServiceBase groupTaxaByMarkedParents(List originalTaxonUuids, UUID classificationUuid, + MarkerType markerType, Boolean flag) { + + List result = new ArrayList<>(); + + //get treeindex for each taxonUUID + Map taxonIdTreeIndexMap = dao.treeIndexForTaxonUuids(classificationUuid, originalTaxonUuids); + + //get all marked tree indexes + Set markedTreeIndexes = dao.getMarkedTreeIndexes(markerType, flag); + + + Map groupedMap = TreeIndex.group(markedTreeIndexes, taxonIdTreeIndexMap.values()); + Set notNullGroups = new HashSet<>(groupedMap.values()); + notNullGroups.remove(null); + + //get taxonInfo for treeIndexes + Map> treeIndexTaxonIdMap = taxonNodeDao.taxonUuidsForTreeIndexes(notNullGroups); + + //fill result list + for (UUID originalTaxonUuid : originalTaxonUuids){ + GroupedTaxonDTO item = new GroupedTaxonDTO(); + result.add(item); + item.setTaxonUuid(originalTaxonUuid); + + TreeIndex toBeGroupedTreeIndex = taxonIdTreeIndexMap.get(originalTaxonUuid); + TreeIndex groupTreeIndex = groupedMap.get(toBeGroupedTreeIndex); + UuidAndTitleCache uuidAndLabel = treeIndexTaxonIdMap.get(groupTreeIndex); + if (uuidAndLabel != null){ + item.setGroupTaxonUuid(uuidAndLabel.getUuid()); + item.setGroupTaxonName(uuidAndLabel.getTitleCache()); + } + } + + return result; + } + /** * {@inheritDoc} */ @@ -715,38 +825,82 @@ public class ClassificationServiceImpl extends IdentifiableServiceBase ancestorMarkers, NodeSortMode sortMode) { TaxonInContextDTO result = new TaxonInContextDTO(); - TaxonBase taxonBase = taxonDao.load(taxonUuid); + + TaxonBase taxonBase = taxonDao.load(taxonBaseUuid); if (taxonBase == null){ - return result; //TODO + throw new EntityNotFoundException("Taxon with uuid " + taxonBaseUuid + " not found in datasource"); } + boolean isSynonym = false; + Taxon acceptedTaxon; + if (taxonBase.isInstanceOf(Synonym.class)){ + isSynonym = true; + Synonym synonym = CdmBase.deproxy(taxonBase, Synonym.class); + acceptedTaxon = synonym.getAcceptedTaxon(); + if (acceptedTaxon == null) { + throw new EntityNotFoundException("Accepted taxon not found for synonym" ); + } + TaxonStatus taxonStatus = TaxonStatus.Synonym; + if (synonym.getName()!= null && acceptedTaxon.getName() != null + && synonym.getName().getHomotypicalGroup().equals(acceptedTaxon.getName().getHomotypicalGroup())){ + taxonStatus = TaxonStatus.SynonymObjective; + } + result.setTaxonStatus(taxonStatus); - TaxonNameBase name = taxonBase.getName(); - result.setNameUuid(name.getUuid()); - result.setNameLabel(name.getTitleCache()); - if (name.isInstanceOf(NonViralName.class)){ - NonViralName nvn = CdmBase.deproxy(name, NonViralName.class); - - result.setNameWithoutAuthor(nvn.getNameCache()); - result.setGenusOrUninomial(nvn.getGenusOrUninomial()); - result.setInfraGenericEpithet(nvn.getInfraGenericEpithet()); - result.setSpeciesEpithet(nvn.getSpecificEpithet()); - result.setInfraSpecificEpithet(nvn.getInfraSpecificEpithet()); + }else{ + acceptedTaxon = CdmBase.deproxy(taxonBase, Taxon.class); + result.setTaxonStatus(TaxonStatus.Accepted); + } + UUID acceptedTaxonUuid = acceptedTaxon.getUuid(); - result.setAuthorship(nvn.getAuthorshipCache()); + UUID taxonNodeUuid = getTaxonNodeUuidByTaxonUuid(classificationUuid, acceptedTaxonUuid); + if (taxonNodeUuid == null) { + throw new EntityNotFoundException("Taxon not found in classficiation with uuid " + classificationUuid + ". Either classification does not exist or does not contain taxon/synonym with uuid " + taxonBaseUuid ); + } + result.setTaxonNodeUuid(taxonNodeUuid); - Rank rank = name.getRank(); - if (rank != null){ - result.setRankUuid(rank.getUuid()); - result.setRankLabel(rank.getTitleCache()); + //TODO make it a dao call + Taxon parentTaxon = getParentTaxon(classificationUuid, acceptedTaxon); + if (parentTaxon != null){ + result.setParentTaxonUuid(parentTaxon.getUuid()); + result.setParentTaxonLabel(parentTaxon.getTitleCache()); + if (parentTaxon.getName() != null){ + result.setParentNameLabel(parentTaxon.getName().getTitleCache()); } } - UUID taxonNodeUuid = getTaxonNodeUuidByTaxonUuid(classificationUuid, taxonUuid); - result.setTaxonNodeUuid(taxonNodeUuid); + + result.setTaxonUuid(taxonBaseUuid); + result.setClassificationUuid(classificationUuid); + if (taxonBase.getSec() != null){ + result.setSecundumUuid(taxonBase.getSec().getUuid()); + result.setSecundumLabel(taxonBase.getSec().getTitleCache()); + } + result.setTaxonLabel(taxonBase.getTitleCache()); + + TaxonName name = taxonBase.getName(); + result.setNameUuid(name.getUuid()); + result.setNameLabel(name.getTitleCache()); + result.setNameWithoutAuthor(name.getNameCache()); + result.setGenusOrUninomial(name.getGenusOrUninomial()); + result.setInfraGenericEpithet(name.getInfraGenericEpithet()); + result.setSpeciesEpithet(name.getSpecificEpithet()); + result.setInfraSpecificEpithet(name.getInfraSpecificEpithet()); + + result.setAuthorship(name.getAuthorshipCache()); + + Rank rank = name.getRank(); + if (rank != null){ + result.setRankUuid(rank.getUuid()); + String rankLabel = rank.getAbbreviation(); + if (StringUtils.isBlank(rankLabel)){ + rankLabel = rank.getLabel(); + } + result.setRankLabel(rankLabel); + } boolean recursive = false; Integer pageSize = null; @@ -754,14 +908,21 @@ public class ClassificationServiceImpl extends IdentifiableServiceBase children = taxonNodeService.pageChildNodesDTOs(taxonNodeUuid, recursive, doSynonyms, sortMode, pageSize, pageIndex); //children - for (TaxonNodeDto childDto : children.getRecords()){ - if (doChildren && childDto.getStatus().equals(TaxonStatus.Accepted)){ - EntityDTO child = new EntityDTO(childDto.getTaxonUuid(), childDto.getTitleCache()); - result.addChild(child); - }else if (doSynonyms && childDto.getStatus().isSynonym()){ - EntityDTO child = new EntityDTO(childDto.getTaxonUuid(), childDto.getTitleCache()); - result.addSynonym(child); + if(! isSynonym) { + for (TaxonNodeDto childDto : children.getRecords()){ + if (doChildren && childDto.getStatus().equals(TaxonStatus.Accepted)){ + EntityDTO child = new EntityDTO(childDto.getTaxonUuid(), childDto.getTitleCache()); + result.addChild(child); + }else if (doSynonyms && childDto.getStatus().isSynonym()){ + EntityDTO child = new EntityDTO(childDto.getTaxonUuid(), childDto.getTitleCache()); + result.addSynonym(child); + } } + }else{ + result.setAcceptedTaxonUuid(acceptedTaxonUuid); + String nameTitel = acceptedTaxon.getName() == null ? null : acceptedTaxon.getName().getTitleCache(); + result.setAcceptedTaxonLabel(acceptedTaxon.getTitleCache()); + result.setAcceptedNameLabel(nameTitel); } //marked ancestors @@ -782,6 +943,27 @@ public class ClassificationServiceImpl extends IdentifiableServiceBase dto = new MarkedEntityDTO<>(type, true, taxon.getUuid(), taxon.getTitleCache()); + String label = taxon.getName() == null? taxon.getTitleCache() : taxon.getName().getTitleCache(); + MarkedEntityDTO dto = new MarkedEntityDTO<>(type, true, taxon.getUuid(), label); result.addMarkedAncestor(dto); } } @@ -801,4 +984,5 @@ public class ClassificationServiceImpl extends IdentifiableServiceBase