X-Git-Url: https://dev.e-taxonomy.eu/gitweb/cdmlib.git/blobdiff_plain/199ed72a78b464290b2470e7f5dc823a1373d6aa..e8302290d4e34ecf7526c3dfb389805e3b36a1d5:/cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/DescriptionServiceImpl.java diff --git a/cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/DescriptionServiceImpl.java b/cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/DescriptionServiceImpl.java index 6920476481..e813dcdc46 100644 --- a/cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/DescriptionServiceImpl.java +++ b/cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/DescriptionServiceImpl.java @@ -18,16 +18,21 @@ import java.util.Map; import java.util.Set; import java.util.UUID; +import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import eu.etaxonomy.cdm.api.service.pager.Pager; +import eu.etaxonomy.cdm.api.service.pager.impl.AbstractPagerImpl; import eu.etaxonomy.cdm.api.service.pager.impl.DefaultPagerImpl; import eu.etaxonomy.cdm.api.utility.DescriptionUtility; import eu.etaxonomy.cdm.common.monitor.IProgressMonitor; +import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper; import eu.etaxonomy.cdm.model.common.Annotation; +import eu.etaxonomy.cdm.model.common.AnnotationType; +import eu.etaxonomy.cdm.model.common.CdmBase; import eu.etaxonomy.cdm.model.common.DefinedTerm; import eu.etaxonomy.cdm.model.common.Language; import eu.etaxonomy.cdm.model.common.Marker; @@ -38,14 +43,13 @@ import eu.etaxonomy.cdm.model.description.DescriptionElementBase; import eu.etaxonomy.cdm.model.description.Distribution; import eu.etaxonomy.cdm.model.description.Feature; import eu.etaxonomy.cdm.model.description.FeatureTree; -import eu.etaxonomy.cdm.model.description.PresenceAbsenceTermBase; +import eu.etaxonomy.cdm.model.description.PresenceAbsenceTerm; import eu.etaxonomy.cdm.model.description.TaxonDescription; import eu.etaxonomy.cdm.model.description.TaxonNameDescription; import eu.etaxonomy.cdm.model.description.TextData; import eu.etaxonomy.cdm.model.location.NamedArea; import eu.etaxonomy.cdm.model.location.NamedAreaLevel; import eu.etaxonomy.cdm.model.media.Media; -import eu.etaxonomy.cdm.model.name.Rank; import eu.etaxonomy.cdm.model.name.TaxonNameBase; import eu.etaxonomy.cdm.model.taxon.Taxon; import eu.etaxonomy.cdm.persistence.dao.common.IDefinedTermDao; @@ -56,6 +60,8 @@ import eu.etaxonomy.cdm.persistence.dao.description.IFeatureDao; import eu.etaxonomy.cdm.persistence.dao.description.IFeatureNodeDao; import eu.etaxonomy.cdm.persistence.dao.description.IFeatureTreeDao; import eu.etaxonomy.cdm.persistence.dao.description.IStatisticalMeasurementValueDao; +import eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao; +import eu.etaxonomy.cdm.persistence.dto.TermDto; import eu.etaxonomy.cdm.persistence.query.OrderHint; import eu.etaxonomy.cdm.strategy.cache.common.IIdentifiableEntityCacheStrategy; @@ -64,6 +70,11 @@ import eu.etaxonomy.cdm.strategy.cache.common.IIdentifiableEntityCacheStrategy; * @created 24.06.2008 * @version 1.0 */ +/** + * @author a.kohlbecker + * @date Dec 5, 2013 + * + */ @Service @Transactional(readOnly = true) public class DescriptionServiceImpl extends IdentifiableServiceBase implements IDescriptionService { @@ -77,6 +88,8 @@ public class DescriptionServiceImpl extends IdentifiableServiceBase clazz, Integer stepSize, IIdentifiableEntityCacheStrategy cacheStrategy, IProgressMonitor monitor) { @@ -161,42 +175,41 @@ public class DescriptionServiceImpl extends IdentifiableServiceBase pageDescriptionElements(DescriptionBase description, Class descriptionType, - Set features, Class type, Integer pageSize, Integer pageNumber, List propertyPaths) { + public Pager pageDescriptionElements(DescriptionBase description, Class descriptionType, + Set features, Class type, Integer pageSize, Integer pageNumber, List propertyPaths) { - List results = listDescriptionElements(description, descriptionType, features, type, pageSize, pageNumber, propertyPaths); - return new DefaultPagerImpl(pageNumber, results.size(), pageSize, results); + List results = listDescriptionElements(description, descriptionType, features, type, pageSize, pageNumber, propertyPaths); + return new DefaultPagerImpl(pageNumber, results.size(), pageSize, results); } - /* (non-Javadoc) - * @see eu.etaxonomy.cdm.api.service.IDescriptionService#getDescriptionElements(eu.etaxonomy.cdm.model.description.DescriptionBase, java.util.Set, java.lang.Class, java.lang.Integer, java.lang.Integer, java.util.List) - */ @Override @Deprecated - public Pager getDescriptionElements(DescriptionBase description, - Set features, Class type, Integer pageSize, Integer pageNumber, List propertyPaths) { + public Pager getDescriptionElements(DescriptionBase description, + Set features, Class type, Integer pageSize, Integer pageNumber, List propertyPaths) { return pageDescriptionElements(description, null, features, type, pageSize, pageNumber, propertyPaths); } + + @Override - public List listDescriptionElements(DescriptionBase description, Class descriptionType, - Set features, Class type, Integer pageSize, Integer pageNumber, List propertyPaths) { + public List listDescriptionElements(DescriptionBase description, + Class descriptionType, Set features, Class type, Integer pageSize, Integer pageNumber, + List propertyPaths) { Integer numberOfResults = dao.countDescriptionElements(description, descriptionType, features, type); - List results = new ArrayList(); - if(numberOfResults > 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize) + List results = new ArrayList(); + if(AbstractPagerImpl.hasResultsInRange(numberOfResults.longValue(), pageNumber, pageSize)) { results = dao.getDescriptionElements(description, descriptionType, features, type, pageSize, pageNumber, propertyPaths); } return results; + } - /* (non-Javadoc) - * @see eu.etaxonomy.cdm.api.service.IDescriptionService#listDescriptionElements(eu.etaxonomy.cdm.model.description.DescriptionBase, java.util.Set, java.lang.Class, java.lang.Integer, java.lang.Integer, java.util.List) - */ + @Override @Deprecated - public List listDescriptionElements(DescriptionBase description, - Set features, Class type, Integer pageSize, Integer pageNumber, List propertyPaths) { + public List listDescriptionElements(DescriptionBase description, + Set features, Class type, Integer pageSize, Integer pageNumber, List propertyPaths) { return listDescriptionElements(description, null, features, type, pageSize, pageNumber, propertyPaths); } @@ -214,7 +227,6 @@ public class DescriptionServiceImpl extends IdentifiableServiceBase getMedia(DescriptionElementBase descriptionElement, Integer pageSize, Integer pageNumber, List propertyPaths) { Integer numberOfResults = descriptionElementDao.countMedia(descriptionElement); @@ -239,10 +251,6 @@ public class DescriptionServiceImpl extends IdentifiableServiceBase pageTaxonDescriptions(Taxon taxon, Set scopes, Set geographicalScope, Set markerTypes, Integer pageSize, Integer pageNumber, List propertyPaths) { Integer numberOfResults = dao.countTaxonDescriptions(taxon, scopes, geographicalScope, markerTypes); @@ -262,58 +270,76 @@ public class DescriptionServiceImpl extends IdentifiableServiceBase listTaxonDescriptionMedia(UUID taxonUuid, boolean limitToGalleries, Set markerTypes, Integer pageSize, Integer pageNumber, List propertyPaths){ return this.dao.listTaxonDescriptionMedia(taxonUuid, limitToGalleries, markerTypes, pageSize, pageNumber, propertyPaths); } - /* - * @see IDescriptionService#countTaxonDescriptionMedia(UUID, boolean, Set) - */ @Override public int countTaxonDescriptionMedia(UUID taxonUuid, boolean limitToGalleries, Set markerTypes){ return this.dao.countTaxonDescriptionMedia(taxonUuid, limitToGalleries, markerTypes); } - - - @Override + @Deprecated public DistributionTree getOrderedDistributions( Set taxonDescriptions, - Set omitLevels, - List propertyPaths){ + boolean subAreaPreference, + boolean statusOrderPreference, + Set hiddenAreaMarkerTypes, + Set omitLevels, List propertyPaths){ - DistributionTree tree = new DistributionTree(); List distList = new ArrayList(); + List uuids = new ArrayList(); for (TaxonDescription taxonDescription : taxonDescriptions) { - taxonDescription = (TaxonDescription) dao.load(taxonDescription.getUuid(), propertyPaths); - Set elements = taxonDescription.getElements(); - for (DescriptionElementBase element : elements) { - if (element.isInstanceOf(Distribution.class)) { - Distribution distribution = (Distribution) element; - if(distribution.getArea() != null){ - distList.add(distribution); + if (! taxonDescription.isImageGallery()){ //image galleries should not have descriptions, but better filter fully on DTYPE of description element + uuids.add(taxonDescription.getUuid()); + } + } + + List desclist = dao.list(uuids, null, null, null, propertyPaths); + for (DescriptionBase desc : desclist) { + if (desc.isInstanceOf(TaxonDescription.class)){ + Set elements = desc.getElements(); + for (DescriptionElementBase element : elements) { + if (element.isInstanceOf(Distribution.class)) { + Distribution distribution = (Distribution) element; + if(distribution.getArea() != null){ + distList.add(distribution); + } } - } + } } } + //old +// for (TaxonDescription taxonDescription : taxonDescriptions) { +// if (logger.isDebugEnabled()){ logger.debug("load taxon description " + taxonDescription.getUuid());} +// //TODO why not loading all description via .list ? This may improve performance +// taxonDescription = (TaxonDescription) dao.load(taxonDescription.getUuid(), propertyPaths); +// Set elements = taxonDescription.getElements(); +// for (DescriptionElementBase element : elements) { +// if (element.isInstanceOf(Distribution.class)) { +// Distribution distribution = (Distribution) element; +// if(distribution.getArea() != null){ +// distList.add(distribution); +// } +// } +// } +// } + + if (logger.isDebugEnabled()){logger.debug("filter tree for " + distList.size() + " distributions ...");} + // filter distributions - Collection filteredDistributions = DescriptionUtility.filterDistributions(distList); + Collection filteredDistributions = DescriptionUtility.filterDistributions(distList, hiddenAreaMarkerTypes, true, statusOrderPreference, false); distList.clear(); distList.addAll(filteredDistributions); - //order by areas - tree.orderAsTree(distList, omitLevels); - tree.sortChildren(); - return tree; + return DescriptionUtility.orderDistributions(definedTermDao, omitLevels, distList, hiddenAreaMarkerTypes, null); } + @Override public Pager getTaxonNameDescriptions(TaxonNameBase name, Integer pageSize, Integer pageNumber, List propertyPaths) { Integer numberOfResults = dao.countTaxonNameDescriptions(name); @@ -344,7 +370,7 @@ public class DescriptionServiceImpl extends IdentifiableServiceBase searchDescriptionByDistribution(Set namedAreas, PresenceAbsenceTermBase presence, Integer pageSize, Integer pageNumber, List orderHints, List propertyPaths) { + public Pager searchDescriptionByDistribution(Set namedAreas, PresenceAbsenceTerm presence, Integer pageSize, Integer pageNumber, List orderHints, List propertyPaths) { Integer numberOfResults = dao.countDescriptionByDistribution(namedAreas, presence); List results = new ArrayList(); @@ -396,7 +422,7 @@ public class DescriptionServiceImpl extends IdentifiableServiceBase getFeatureVocabulary(UUID uuid) { return vocabularyDao.findByUuid(uuid); @@ -437,7 +502,7 @@ public class DescriptionServiceImpl extends IdentifiableServiceBase features, Class type, Integer pageSize, Integer pageNumber, List propertyPaths) { - return dao.getDescriptionElementForTaxon(taxon, features, type, pageSize, pageNumber, propertyPaths); + return dao.getDescriptionElementForTaxon(taxon.getUuid(), features, type, pageSize, pageNumber, propertyPaths); } @Override @@ -445,13 +510,16 @@ public class DescriptionServiceImpl extends IdentifiableServiceBase features, Class type, Integer pageSize, Integer pageNumber, List propertyPaths) { - Long count = dao.countDescriptionElementForTaxon(taxon, features, type); + if (logger.isDebugEnabled()){logger.debug(" get count ...");} + Long count = dao.countDescriptionElementForTaxon(taxon.getUuid(), features, type); List descriptionElements; - if(count > (pageSize * pageNumber + 1)){ // no point checking again + if(AbstractPagerImpl.hasResultsInRange(count, pageNumber, pageSize)){ // no point checking again + if (logger.isDebugEnabled()){logger.debug(" get list ...");} descriptionElements = listDescriptionElementsForTaxon(taxon, features, type, pageSize, pageNumber, propertyPaths); } else { descriptionElements = new ArrayList(0); } + if (logger.isDebugEnabled()){logger.debug(" service - DONE ...");} return new DefaultPagerImpl(pageNumber, count.intValue(), pageSize, descriptionElements); } @@ -567,24 +635,23 @@ public class DescriptionServiceImpl extends IdentifiableServiceBase description) { return load(description.getUuid()).hasStructuredData(); } - /* (non-Javadoc) - * @see eu.etaxonomy.cdm.api.service.IDescriptionService#moveDescriptionElementsToDescription(java.util.Collection, eu.etaxonomy.cdm.model.description.DescriptionBase, boolean) - */ @Override - public void moveDescriptionElementsToDescription(Collection descriptionElements, - DescriptionBase targetDescription, boolean isCopy) { + @Transactional(readOnly = false) + public UpdateResult moveDescriptionElementsToDescription( + Collection descriptionElements, + DescriptionBase targetDescription, + boolean isCopy) { + UpdateResult result = new UpdateResult(); if (descriptionElements.isEmpty() ){ - return ; + return result; } if (! isCopy && descriptionElements == descriptionElements.iterator().next().getInDescription().getElements()){ @@ -594,23 +661,146 @@ public class DescriptionServiceImpl extends IdentifiableServiceBase description = element.getInDescription(); try { DescriptionElementBase newElement = (DescriptionElementBase)element.clone(); targetDescription.addElement(newElement); } catch (CloneNotSupportedException e) { - new RuntimeException ("Clone not yet implemented for class " + element.getClass().getName(), e); + throw new RuntimeException ("Clone not yet implemented for class " + element.getClass().getName(), e); } if (! isCopy){ description.removeElement(element); + if (description.getElements().isEmpty()){ + if (description instanceof TaxonDescription){ + TaxonDescription taxDescription = HibernateProxyHelper.deproxy(description, TaxonDescription.class); + if (taxDescription.getTaxon() != null){ + taxDescription.getTaxon().removeDescription((TaxonDescription)description); + } + } + dao.delete(description); + }else{ + dao.saveOrUpdate(description); + result.addUpdatedObject(description); + } } + + } + dao.saveOrUpdate(targetDescription); + result.addUpdatedObject(targetDescription); + if (targetDescription instanceof TaxonDescription){ + result.addUpdatedObject(((TaxonDescription)targetDescription).getTaxon()); } + return result; } - public void aggregateDistributions(List superAreas, Rank lowerRank, Rank upperRank) { + @Override + @Transactional(readOnly = false) + public UpdateResult moveDescriptionElementsToDescription( + Set descriptionElementUUIDs, + UUID targetDescriptionUuid, + boolean isCopy) { + Set descriptionElements = new HashSet(); + for(UUID deUuid : descriptionElementUUIDs) { + descriptionElements.add(descriptionElementDao.load(deUuid)); + } + DescriptionBase targetDescription = dao.load(targetDescriptionUuid); + + return moveDescriptionElementsToDescription(descriptionElements, targetDescription, isCopy); + } -// transmissionEngineDistribution engine = new transmissionEngineDistribution(superAreas, lowerRank, upperRank); + @Override + @Transactional(readOnly = false) + public UpdateResult moveDescriptionElementsToDescription( + Set descriptionElementUUIDs, + UUID targetTaxonUuid, + String moveMessage, + boolean isCopy) { + Taxon targetTaxon = CdmBase.deproxy(taxonDao.load(targetTaxonUuid), Taxon.class); + DescriptionBase targetDescription = TaxonDescription.NewInstance(targetTaxon); + targetDescription.setTitleCache(moveMessage, true); + Annotation annotation = Annotation.NewInstance(moveMessage, Language.getDefaultLanguage()); + annotation.setAnnotationType(AnnotationType.TECHNICAL()); + targetDescription.addAnnotation(annotation); + + targetDescription = dao.save(targetDescription); + Set descriptionElements = new HashSet(); + for(UUID deUuid : descriptionElementUUIDs) { + descriptionElements.add(descriptionElementDao.load(deUuid)); + } + + return moveDescriptionElementsToDescription(descriptionElements, targetDescription, isCopy); + } + + @Override + public Pager pageNamedAreasInUse(boolean includeAllParents, Integer pageSize, + Integer pageNumber){ + List results = dao.listNamedAreasInUse(includeAllParents, null, null); + int startIndex= pageNumber * pageSize; + int toIndex = Math.min(startIndex + pageSize, results.size()); + List page = results.subList(startIndex, toIndex); + return new DefaultPagerImpl(pageNumber, results.size(), pageSize, page); + } + + + @Override + @Transactional(readOnly = false) + public UpdateResult moveTaxonDescriptions(Taxon sourceTaxon, Taxon targetTaxon) { + List descriptions = new ArrayList(sourceTaxon.getDescriptions()); + UpdateResult result = new UpdateResult(); + result.addUpdatedObject(sourceTaxon); + result.addUpdatedObject(targetTaxon); + for(TaxonDescription description : descriptions){ + + String moveMessage = String.format("Description moved from %s", sourceTaxon); + if(description.isProtectedTitleCache()){ + String separator = ""; + if(!StringUtils.isBlank(description.getTitleCache())){ + separator = " - "; + } + description.setTitleCache(description.getTitleCache() + separator + moveMessage, true); + } + Annotation annotation = Annotation.NewInstance(moveMessage, Language.getDefaultLanguage()); + annotation.setAnnotationType(AnnotationType.TECHNICAL()); + description.addAnnotation(annotation); + targetTaxon.addDescription(description); + } + return result; + } + + @Override + @Transactional(readOnly = false) + public UpdateResult moveTaxonDescriptions(UUID sourceTaxonUuid, UUID targetTaxonUuid) { + Taxon sourceTaxon = HibernateProxyHelper.deproxy(taxonDao.load(sourceTaxonUuid), Taxon.class); + Taxon targetTaxon = HibernateProxyHelper.deproxy(taxonDao.load(targetTaxonUuid), Taxon.class); + return moveTaxonDescriptions(sourceTaxon, targetTaxon); + + } + + @Override + @Transactional(readOnly = false) + public UpdateResult moveTaxonDescription(UUID descriptionUuid, UUID targetTaxonUuid){ + UpdateResult result = new UpdateResult(); + TaxonDescription description = HibernateProxyHelper.deproxy(dao.load(descriptionUuid), TaxonDescription.class); + + Taxon sourceTaxon = description.getTaxon(); + String moveMessage = String.format("Description moved from %s", sourceTaxon); + if(description.isProtectedTitleCache()){ + String separator = ""; + if(!StringUtils.isBlank(description.getTitleCache())){ + separator = " - "; + } + description.setTitleCache(description.getTitleCache() + separator + moveMessage, true); + } + Annotation annotation = Annotation.NewInstance(moveMessage, Language.getDefaultLanguage()); + annotation.setAnnotationType(AnnotationType.TECHNICAL()); + description.addAnnotation(annotation); + Taxon targetTaxon = HibernateProxyHelper.deproxy(taxonDao.load(targetTaxonUuid), Taxon.class); + targetTaxon.addDescription(description); + result.addUpdatedObject(targetTaxon); + result.addUpdatedObject(sourceTaxon); + // dao.merge(description); + return result; }