3 * Copyright (C) 2007 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
7 * The contents of this file are subject to the Mozilla Public License Version 1.1
8 * See LICENSE.TXT at the top of this package for the full license terms.
11 package eu
.etaxonomy
.cdm
.api
.service
;
13 import java
.util
.ArrayList
;
14 import java
.util
.Collection
;
15 import java
.util
.HashSet
;
16 import java
.util
.List
;
19 import java
.util
.UUID
;
21 import org
.apache
.commons
.lang
.StringUtils
;
22 import org
.apache
.log4j
.Logger
;
23 import org
.springframework
.beans
.factory
.annotation
.Autowired
;
24 import org
.springframework
.stereotype
.Service
;
25 import org
.springframework
.transaction
.annotation
.Transactional
;
27 import eu
.etaxonomy
.cdm
.api
.service
.pager
.Pager
;
28 import eu
.etaxonomy
.cdm
.api
.service
.pager
.impl
.AbstractPagerImpl
;
29 import eu
.etaxonomy
.cdm
.api
.service
.pager
.impl
.DefaultPagerImpl
;
30 import eu
.etaxonomy
.cdm
.api
.utility
.DescriptionUtility
;
31 import eu
.etaxonomy
.cdm
.common
.monitor
.IProgressMonitor
;
32 import eu
.etaxonomy
.cdm
.hibernate
.HibernateProxyHelper
;
33 import eu
.etaxonomy
.cdm
.model
.common
.Annotation
;
34 import eu
.etaxonomy
.cdm
.model
.common
.AnnotationType
;
35 import eu
.etaxonomy
.cdm
.model
.common
.CdmBase
;
36 import eu
.etaxonomy
.cdm
.model
.common
.DefinedTerm
;
37 import eu
.etaxonomy
.cdm
.model
.common
.Language
;
38 import eu
.etaxonomy
.cdm
.model
.common
.Marker
;
39 import eu
.etaxonomy
.cdm
.model
.common
.MarkerType
;
40 import eu
.etaxonomy
.cdm
.model
.common
.TermVocabulary
;
41 import eu
.etaxonomy
.cdm
.model
.description
.DescriptionBase
;
42 import eu
.etaxonomy
.cdm
.model
.description
.DescriptionElementBase
;
43 import eu
.etaxonomy
.cdm
.model
.description
.Distribution
;
44 import eu
.etaxonomy
.cdm
.model
.description
.Feature
;
45 import eu
.etaxonomy
.cdm
.model
.description
.FeatureTree
;
46 import eu
.etaxonomy
.cdm
.model
.description
.PresenceAbsenceTerm
;
47 import eu
.etaxonomy
.cdm
.model
.description
.TaxonDescription
;
48 import eu
.etaxonomy
.cdm
.model
.description
.TaxonNameDescription
;
49 import eu
.etaxonomy
.cdm
.model
.description
.TextData
;
50 import eu
.etaxonomy
.cdm
.model
.location
.NamedArea
;
51 import eu
.etaxonomy
.cdm
.model
.location
.NamedAreaLevel
;
52 import eu
.etaxonomy
.cdm
.model
.media
.Media
;
53 import eu
.etaxonomy
.cdm
.model
.name
.TaxonNameBase
;
54 import eu
.etaxonomy
.cdm
.model
.taxon
.Taxon
;
55 import eu
.etaxonomy
.cdm
.persistence
.dao
.common
.IDefinedTermDao
;
56 import eu
.etaxonomy
.cdm
.persistence
.dao
.common
.ITermVocabularyDao
;
57 import eu
.etaxonomy
.cdm
.persistence
.dao
.description
.IDescriptionDao
;
58 import eu
.etaxonomy
.cdm
.persistence
.dao
.description
.IDescriptionElementDao
;
59 import eu
.etaxonomy
.cdm
.persistence
.dao
.description
.IFeatureDao
;
60 import eu
.etaxonomy
.cdm
.persistence
.dao
.description
.IFeatureNodeDao
;
61 import eu
.etaxonomy
.cdm
.persistence
.dao
.description
.IFeatureTreeDao
;
62 import eu
.etaxonomy
.cdm
.persistence
.dao
.description
.IStatisticalMeasurementValueDao
;
63 import eu
.etaxonomy
.cdm
.persistence
.dao
.taxon
.ITaxonDao
;
64 import eu
.etaxonomy
.cdm
.persistence
.dto
.TermDto
;
65 import eu
.etaxonomy
.cdm
.persistence
.query
.OrderHint
;
66 import eu
.etaxonomy
.cdm
.strategy
.cache
.common
.IIdentifiableEntityCacheStrategy
;
74 * @author a.kohlbecker
79 @Transactional(readOnly
= true)
80 public class DescriptionServiceImpl
extends IdentifiableServiceBase
<DescriptionBase
,IDescriptionDao
> implements IDescriptionService
{
82 private static final Logger logger
= Logger
.getLogger(DescriptionServiceImpl
.class);
84 protected IDescriptionElementDao descriptionElementDao
;
85 protected IFeatureTreeDao featureTreeDao
;
86 protected IFeatureNodeDao featureNodeDao
;
87 protected IFeatureDao featureDao
;
88 protected ITermVocabularyDao vocabularyDao
;
89 protected IDefinedTermDao definedTermDao
;
90 protected IStatisticalMeasurementValueDao statisticalMeasurementValueDao
;
91 protected ITaxonDao taxonDao
;
93 //TODO change to Interface
94 private NaturalLanguageGenerator naturalLanguageGenerator
;
97 protected void setFeatureTreeDao(IFeatureTreeDao featureTreeDao
) {
98 this.featureTreeDao
= featureTreeDao
;
102 protected void setFeatureNodeDao(IFeatureNodeDao featureNodeDao
) {
103 this.featureNodeDao
= featureNodeDao
;
107 protected void setFeatureDao(IFeatureDao featureDao
) {
108 this.featureDao
= featureDao
;
112 protected void setVocabularyDao(ITermVocabularyDao vocabularyDao
) {
113 this.vocabularyDao
= vocabularyDao
;
117 protected void setDefinedTermDao(IDefinedTermDao definedTermDao
) {
118 this.definedTermDao
= definedTermDao
;
122 protected void statisticalMeasurementValueDao(IStatisticalMeasurementValueDao statisticalMeasurementValueDao
) {
123 this.statisticalMeasurementValueDao
= statisticalMeasurementValueDao
;
127 protected void setDescriptionElementDao(IDescriptionElementDao descriptionElementDao
) {
128 this.descriptionElementDao
= descriptionElementDao
;
132 protected void setNaturalLanguageGenerator(NaturalLanguageGenerator naturalLanguageGenerator
) {
133 this.naturalLanguageGenerator
= naturalLanguageGenerator
;
137 protected void setTaxonDao(ITaxonDao taxonDao
) {
138 this.taxonDao
= taxonDao
;
144 public DescriptionServiceImpl() {
145 logger
.debug("Load DescriptionService Bean");
151 * @see eu.etaxonomy.cdm.api.service.IIdentifiableEntityService#updateTitleCache(java.lang.Integer, eu.etaxonomy.cdm.strategy.cache.common.IIdentifiableEntityCacheStrategy)
154 @Transactional(readOnly
= false)
155 public void updateTitleCache(Class
<?
extends DescriptionBase
> clazz
, Integer stepSize
, IIdentifiableEntityCacheStrategy
<DescriptionBase
> cacheStrategy
, IProgressMonitor monitor
) {
157 clazz
= DescriptionBase
.class;
159 super.updateTitleCacheImpl(clazz
, stepSize
, cacheStrategy
, monitor
);
164 public TermVocabulary
<Feature
> getDefaultFeatureVocabulary(){
165 String uuidFeature
= "b187d555-f06f-4d65-9e53-da7c93f8eaa8";
166 UUID featureUuid
= UUID
.fromString(uuidFeature
);
167 return vocabularyDao
.findByUuid(featureUuid
);
172 protected void setDao(IDescriptionDao dao
) {
177 public int count(Class
<?
extends DescriptionBase
> type
, Boolean hasImages
, Boolean hasText
,Set
<Feature
> feature
) {
178 return dao
.countDescriptions(type
, hasImages
, hasText
, feature
);
182 public Pager
<DescriptionElementBase
> pageDescriptionElements(DescriptionBase description
, Class
<?
extends DescriptionBase
> descriptionType
,
183 Set
<Feature
> features
, Class
<?
extends DescriptionElementBase
> type
, Integer pageSize
, Integer pageNumber
, List
<String
> propertyPaths
) {
185 List
<DescriptionElementBase
> results
= listDescriptionElements(description
, descriptionType
, features
, type
, pageSize
, pageNumber
, propertyPaths
);
186 return new DefaultPagerImpl
<DescriptionElementBase
>(pageNumber
, results
.size(), pageSize
, results
);
190 * @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)
194 public Pager
<DescriptionElementBase
> getDescriptionElements(DescriptionBase description
,
195 Set
<Feature
> features
, Class
<?
extends DescriptionElementBase
> type
, Integer pageSize
, Integer pageNumber
, List
<String
> propertyPaths
) {
196 return pageDescriptionElements(description
, null, features
, type
, pageSize
, pageNumber
, propertyPaths
);
200 public List
<DescriptionElementBase
> listDescriptionElements(DescriptionBase description
, Class
<?
extends DescriptionBase
> descriptionType
,
201 Set
<Feature
> features
, Class
<?
extends DescriptionElementBase
> type
, Integer pageSize
, Integer pageNumber
, List
<String
> propertyPaths
) {
203 Integer numberOfResults
= dao
.countDescriptionElements(description
, descriptionType
, features
, type
);
204 List
<DescriptionElementBase
> results
= new ArrayList
<DescriptionElementBase
>();
205 if(AbstractPagerImpl
.hasResultsInRange(numberOfResults
.longValue(), pageNumber
, pageSize
)) {
206 results
= dao
.getDescriptionElements(description
, descriptionType
, features
, type
, pageSize
, pageNumber
, propertyPaths
);
212 * @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)
216 public List
<DescriptionElementBase
> listDescriptionElements(DescriptionBase description
,
217 Set
<Feature
> features
, Class
<?
extends DescriptionElementBase
> type
, Integer pageSize
, Integer pageNumber
, List
<String
> propertyPaths
) {
219 return listDescriptionElements(description
, null, features
, type
, pageSize
, pageNumber
, propertyPaths
);
223 public Pager
<Annotation
> getDescriptionElementAnnotations(DescriptionElementBase annotatedObj
, MarkerType status
, Integer pageSize
, Integer pageNumber
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
){
224 Integer numberOfResults
= descriptionElementDao
.countAnnotations(annotatedObj
, status
);
226 List
<Annotation
> results
= new ArrayList
<Annotation
>();
227 if(numberOfResults
> 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
228 results
= descriptionElementDao
.getAnnotations(annotatedObj
, status
, pageSize
, pageNumber
, orderHints
, propertyPaths
);
231 return new DefaultPagerImpl
<Annotation
>(pageNumber
, numberOfResults
, pageSize
, results
);
237 public Pager
<Media
> getMedia(DescriptionElementBase descriptionElement
, Integer pageSize
, Integer pageNumber
, List
<String
> propertyPaths
) {
238 Integer numberOfResults
= descriptionElementDao
.countMedia(descriptionElement
);
240 List
<Media
> results
= new ArrayList
<Media
>();
241 if(numberOfResults
> 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
242 results
= descriptionElementDao
.getMedia(descriptionElement
, pageSize
, pageNumber
, propertyPaths
);
245 return new DefaultPagerImpl
<Media
>(pageNumber
, numberOfResults
, pageSize
, results
);
249 public Pager
<TaxonDescription
> pageTaxonDescriptions(Taxon taxon
, Set
<DefinedTerm
> scopes
, Set
<NamedArea
> geographicalScope
, Integer pageSize
, Integer pageNumber
, List
<String
> propertyPaths
) {
250 Set
<MarkerType
> markerTypes
= null;
251 return pageTaxonDescriptions(taxon
, scopes
, geographicalScope
, markerTypes
, pageSize
, pageNumber
, propertyPaths
);
255 public List
<TaxonDescription
> listTaxonDescriptions(Taxon taxon
, Set
<DefinedTerm
> scopes
, Set
<NamedArea
> geographicalScope
, Integer pageSize
, Integer pageNumber
, List
<String
> propertyPaths
) {
256 Set
<MarkerType
> markerTypes
= null;
257 return listTaxonDescriptions(taxon
, scopes
, geographicalScope
, markerTypes
, pageSize
, pageNumber
, propertyPaths
);
262 * @see eu.etaxonomy.cdm.api.service.IDescriptionService#pageMarkedTaxonDescriptions(eu.etaxonomy.cdm.model.taxon.Taxon, java.util.Set, java.util.Set, java.util.Set, java.lang.Integer, java.lang.Integer, java.util.List)
265 public Pager
<TaxonDescription
> pageTaxonDescriptions(Taxon taxon
, Set
<DefinedTerm
> scopes
, Set
<NamedArea
> geographicalScope
, Set
<MarkerType
> markerTypes
, Integer pageSize
, Integer pageNumber
, List
<String
> propertyPaths
) {
266 Integer numberOfResults
= dao
.countTaxonDescriptions(taxon
, scopes
, geographicalScope
, markerTypes
);
268 List
<TaxonDescription
> results
= new ArrayList
<TaxonDescription
>();
269 if(numberOfResults
> 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
270 results
= dao
.listTaxonDescriptions(taxon
, scopes
, geographicalScope
, markerTypes
, pageSize
, pageNumber
, propertyPaths
);
273 return new DefaultPagerImpl
<TaxonDescription
>(pageNumber
, numberOfResults
, pageSize
, results
);
277 public List
<TaxonDescription
> listTaxonDescriptions(Taxon taxon
, Set
<DefinedTerm
> scopes
, Set
<NamedArea
> geographicalScope
, Set
<MarkerType
> markerTypes
, Integer pageSize
, Integer pageNumber
, List
<String
> propertyPaths
) {
278 List
<TaxonDescription
> results
= dao
.listTaxonDescriptions(taxon
, scopes
, geographicalScope
, markerTypes
, pageSize
, pageNumber
, propertyPaths
);
284 * @see eu.etaxonomy.cdm.api.service.IDescriptionService#listTaxonDescriptionMedia(UUID, boolean, Set, Integer, Integer, List)
287 public List
<Media
> listTaxonDescriptionMedia(UUID taxonUuid
, boolean limitToGalleries
, Set
<MarkerType
> markerTypes
, Integer pageSize
, Integer pageNumber
, List
<String
> propertyPaths
){
288 return this.dao
.listTaxonDescriptionMedia(taxonUuid
, limitToGalleries
, markerTypes
, pageSize
, pageNumber
, propertyPaths
);
292 * @see IDescriptionService#countTaxonDescriptionMedia(UUID, boolean, Set)
295 public int countTaxonDescriptionMedia(UUID taxonUuid
, boolean limitToGalleries
, Set
<MarkerType
> markerTypes
){
296 return this.dao
.countTaxonDescriptionMedia(taxonUuid
, limitToGalleries
, markerTypes
);
301 * @see eu.etaxonomy.cdm.api.service.IDescriptionService#getOrderedDistributions(java.util.Set, boolean, boolean, java.util.Set, java.util.List)
305 public DistributionTree
getOrderedDistributions(
306 Set
<TaxonDescription
> taxonDescriptions
,
307 boolean subAreaPreference
,
308 boolean statusOrderPreference
,
309 Set
<MarkerType
> hiddenAreaMarkerTypes
,
310 Set
<NamedAreaLevel
> omitLevels
, List
<String
> propertyPaths
){
312 List
<Distribution
> distList
= new ArrayList
<Distribution
>();
314 List
<UUID
> uuids
= new ArrayList
<UUID
>();
315 for (TaxonDescription taxonDescription
: taxonDescriptions
) {
316 if (! taxonDescription
.isImageGallery()){ //image galleries should not have descriptions, but better filter fully on DTYPE of description element
317 uuids
.add(taxonDescription
.getUuid());
321 List
<DescriptionBase
> desclist
= dao
.list(uuids
, null, null, null, propertyPaths
);
322 for (DescriptionBase desc
: desclist
) {
323 if (desc
.isInstanceOf(TaxonDescription
.class)){
324 Set
<DescriptionElementBase
> elements
= desc
.getElements();
325 for (DescriptionElementBase element
: elements
) {
326 if (element
.isInstanceOf(Distribution
.class)) {
327 Distribution distribution
= (Distribution
) element
;
328 if(distribution
.getArea() != null){
329 distList
.add(distribution
);
337 // for (TaxonDescription taxonDescription : taxonDescriptions) {
338 // if (logger.isDebugEnabled()){ logger.debug("load taxon description " + taxonDescription.getUuid());}
339 // //TODO why not loading all description via .list ? This may improve performance
340 // taxonDescription = (TaxonDescription) dao.load(taxonDescription.getUuid(), propertyPaths);
341 // Set<DescriptionElementBase> elements = taxonDescription.getElements();
342 // for (DescriptionElementBase element : elements) {
343 // if (element.isInstanceOf(Distribution.class)) {
344 // Distribution distribution = (Distribution) element;
345 // if(distribution.getArea() != null){
346 // distList.add(distribution);
352 if (logger
.isDebugEnabled()){logger
.debug("filter tree for " + distList
.size() + " distributions ...");}
354 // filter distributions
355 Collection
<Distribution
> filteredDistributions
= DescriptionUtility
.filterDistributions(distList
, hiddenAreaMarkerTypes
, true, statusOrderPreference
, false);
357 distList
.addAll(filteredDistributions
);
359 return DescriptionUtility
.orderDistributions(definedTermDao
, omitLevels
, distList
, hiddenAreaMarkerTypes
);
364 public Pager
<TaxonNameDescription
> getTaxonNameDescriptions(TaxonNameBase name
, Integer pageSize
, Integer pageNumber
, List
<String
> propertyPaths
) {
365 Integer numberOfResults
= dao
.countTaxonNameDescriptions(name
);
367 List
<TaxonNameDescription
> results
= new ArrayList
<TaxonNameDescription
>();
368 if(numberOfResults
> 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
369 results
= dao
.getTaxonNameDescriptions(name
, pageSize
, pageNumber
,propertyPaths
);
372 return new DefaultPagerImpl
<TaxonNameDescription
>(pageNumber
, numberOfResults
, pageSize
, results
);
377 public Pager
<DescriptionBase
> page(Class
<?
extends DescriptionBase
> type
, Boolean hasImages
, Boolean hasText
, Set
<Feature
> feature
, Integer pageSize
, Integer pageNumber
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
378 Integer numberOfResults
= dao
.countDescriptions(type
, hasImages
, hasText
, feature
);
380 List
<DescriptionBase
> results
= new ArrayList
<DescriptionBase
>();
381 if(numberOfResults
> 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
382 results
= dao
.listDescriptions(type
, hasImages
, hasText
, feature
, pageSize
, pageNumber
,orderHints
,propertyPaths
);
385 return new DefaultPagerImpl
<DescriptionBase
>(pageNumber
, numberOfResults
, pageSize
, results
);
389 * FIXME Candidate for harmonization
390 * Rename: searchByDistribution
393 public Pager
<TaxonDescription
> searchDescriptionByDistribution(Set
<NamedArea
> namedAreas
, PresenceAbsenceTerm presence
, Integer pageSize
, Integer pageNumber
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
394 Integer numberOfResults
= dao
.countDescriptionByDistribution(namedAreas
, presence
);
396 List
<TaxonDescription
> results
= new ArrayList
<TaxonDescription
>();
397 if(numberOfResults
> 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
398 results
= dao
.searchDescriptionByDistribution(namedAreas
, presence
, pageSize
, pageNumber
,orderHints
,propertyPaths
);
401 return new DefaultPagerImpl
<TaxonDescription
>(pageNumber
, numberOfResults
, pageSize
, results
);
405 * FIXME Candidate for harmonization
406 * move: descriptionElementService.search
409 public Pager
<DescriptionElementBase
> searchElements(Class
<?
extends DescriptionElementBase
> clazz
, String queryString
, Integer pageSize
, Integer pageNumber
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
410 Integer numberOfResults
= descriptionElementDao
.count(clazz
, queryString
);
412 List
<DescriptionElementBase
> results
= new ArrayList
<DescriptionElementBase
>();
413 if(numberOfResults
> 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
414 results
= descriptionElementDao
.search(clazz
, queryString
, pageSize
, pageNumber
, orderHints
, propertyPaths
);
417 return new DefaultPagerImpl
<DescriptionElementBase
>(pageNumber
, numberOfResults
, pageSize
, results
);
421 * FIXME Candidate for harmonization
422 * descriptionElementService.find
425 public DescriptionElementBase
getDescriptionElementByUuid(UUID uuid
) {
426 return descriptionElementDao
.findByUuid(uuid
);
430 * FIXME Candidate for harmonization
431 * descriptionElementService.load
434 public DescriptionElementBase
loadDescriptionElement(UUID uuid
, List
<String
> propertyPaths
) {
435 return descriptionElementDao
.load(uuid
, propertyPaths
);
439 * FIXME Candidate for harmonization
440 * descriptionElementService.save
443 @Transactional(readOnly
= false)
444 public UUID
saveDescriptionElement(DescriptionElementBase descriptionElement
) {
445 return descriptionElementDao
.save(descriptionElement
).getUuid();
449 * FIXME Candidate for harmonization
450 * descriptionElementService.save
453 @Transactional(readOnly
= false)
454 public Map
<UUID
, DescriptionElementBase
> saveDescriptionElement(Collection
<DescriptionElementBase
> descriptionElements
) {
455 return descriptionElementDao
.saveAll(descriptionElements
);
459 * FIXME Candidate for harmonization
460 * descriptionElementService.delete
463 public UUID
deleteDescriptionElement(DescriptionElementBase descriptionElement
) {
464 return descriptionElementDao
.delete(descriptionElement
);
469 * @see eu.etaxonomy.cdm.api.service.IDescriptionService#deleteDescriptionElement(java.util.UUID)
472 public UUID
deleteDescriptionElement(UUID descriptionElementUuid
) {
473 return deleteDescriptionElement(descriptionElementDao
.load(descriptionElementUuid
));
477 @Transactional(readOnly
= false)
478 public DeleteResult
deleteDescription(DescriptionBase description
) {
479 DeleteResult deleteResult
= new DeleteResult();
481 if (description
instanceof TaxonDescription
){
482 TaxonDescription taxDescription
= HibernateProxyHelper
.deproxy(description
, TaxonDescription
.class);
483 Taxon tax
= taxDescription
.getTaxon();
484 tax
.removeDescription(taxDescription
, true);
485 dao
.delete(description
);
487 deleteResult
.addUpdatedObject(tax
);
488 deleteResult
.setCdmEntity(tax
);
497 * @see eu.etaxonomy.cdm.api.service.IDescriptionService#deleteDescription(java.util.UUID)
500 @Transactional(readOnly
= false)
501 public DeleteResult
deleteDescription(UUID descriptionUuid
) {
502 return deleteDescription(dao
.load(descriptionUuid
));
507 public TermVocabulary
<Feature
> getFeatureVocabulary(UUID uuid
) {
508 return vocabularyDao
.findByUuid(uuid
);
513 public <T
extends DescriptionElementBase
> List
<T
> getDescriptionElementsForTaxon(
514 Taxon taxon
, Set
<Feature
> features
,
515 Class
<T
> type
, Integer pageSize
,
516 Integer pageNumber
, List
<String
> propertyPaths
) {
517 return listDescriptionElementsForTaxon(taxon
, features
, type
, pageSize
, pageNumber
, propertyPaths
);
521 public <T
extends DescriptionElementBase
> List
<T
> listDescriptionElementsForTaxon(
522 Taxon taxon
, Set
<Feature
> features
,
523 Class
<T
> type
, Integer pageSize
,
524 Integer pageNumber
, List
<String
> propertyPaths
) {
525 return dao
.getDescriptionElementForTaxon(taxon
.getUuid(), features
, type
, pageSize
, pageNumber
, propertyPaths
);
529 public <T
extends DescriptionElementBase
> Pager
<T
> pageDescriptionElementsForTaxon(
530 Taxon taxon
, Set
<Feature
> features
,
531 Class
<T
> type
, Integer pageSize
,
532 Integer pageNumber
, List
<String
> propertyPaths
) {
533 if (logger
.isDebugEnabled()){logger
.debug(" get count ...");}
534 Long count
= dao
.countDescriptionElementForTaxon(taxon
.getUuid(), features
, type
);
535 List
<T
> descriptionElements
;
536 if(AbstractPagerImpl
.hasResultsInRange(count
, pageNumber
, pageSize
)){ // no point checking again
537 if (logger
.isDebugEnabled()){logger
.debug(" get list ...");}
538 descriptionElements
= listDescriptionElementsForTaxon(taxon
, features
, type
, pageSize
, pageNumber
, propertyPaths
);
540 descriptionElements
= new ArrayList
<T
>(0);
542 if (logger
.isDebugEnabled()){logger
.debug(" service - DONE ...");}
543 return new DefaultPagerImpl
<T
>(pageNumber
, count
.intValue(), pageSize
, descriptionElements
);
548 * @see eu.etaxonomy.cdm.api.service.IDescriptionService#generateNaturalLanguageDescription(eu.etaxonomy.cdm.model.description.FeatureTree, eu.etaxonomy.cdm.model.description.TaxonDescription, eu.etaxonomy.cdm.model.common.Language, java.util.List)
551 public String
generateNaturalLanguageDescription(FeatureTree featureTree
,
552 TaxonDescription description
, List
<Language
> preferredLanguages
, String separator
) {
554 Language lang
= preferredLanguages
.size() > 0 ? preferredLanguages
.get(0) : Language
.DEFAULT();
556 description
= (TaxonDescription
)load(description
.getUuid());
557 featureTree
= featureTreeDao
.load(featureTree
.getUuid());
559 StringBuilder naturalLanguageDescription
= new StringBuilder();
561 MarkerType useMarkerType
= (MarkerType
) definedTermDao
.load(UUID
.fromString("2e6e42d9-e92a-41f4-899b-03c0ac64f039"));
562 boolean isUseDescription
= false;
563 if(!description
.getMarkers().isEmpty()) {
564 for (Marker marker
: description
.getMarkers()) {
565 MarkerType markerType
= marker
.getMarkerType();
566 if (markerType
.equals(useMarkerType
)) {
567 isUseDescription
= true;
573 if(description
.hasStructuredData() && !isUseDescription
){
576 String lastCategory
= null;
577 String categorySeparator
= ". ";
579 List
<TextData
> textDataList
;
580 TextData naturalLanguageDescriptionText
= null;
582 boolean useMicroFormatQuantitativeDescriptionBuilder
= false;
584 if(useMicroFormatQuantitativeDescriptionBuilder
){
586 MicroFormatQuantitativeDescriptionBuilder micro
= new MicroFormatQuantitativeDescriptionBuilder();
587 naturalLanguageGenerator
.setQuantitativeDescriptionBuilder(micro
);
588 naturalLanguageDescriptionText
= naturalLanguageGenerator
.generateSingleTextData(featureTree
, (description
), lang
);
592 naturalLanguageDescriptionText
= naturalLanguageGenerator
.generateSingleTextData(
598 return naturalLanguageDescriptionText
.getText(lang
);
601 // boolean doItBetter = false;
603 // for (TextData textData : textDataList.toArray(new TextData[textDataList.size()])){
604 // if(textData.getMultilanguageText().size() > 0){
606 // if (!textData.getFeature().equals(Feature.UNKNOWN())) {
607 // String featureLabel = textData.getFeature().getLabel(lang);
612 // * The code lines below are desinged to handle
613 // * a special case where as the feature label contains
614 // * hierarchical information on the features. This code
615 // * exist only as a base for discussion, and is not
616 // * intendet to be used in production.
618 // featureLabel = StringUtils.remove(featureLabel, '>');
620 // String[] labelTokens = StringUtils.split(featureLabel, '<');
621 // if(labelTokens[0].equals(lastCategory) && labelTokens.length > 1){
622 // if(naturalLanguageDescription.length() > 0){
623 // naturalLanguageDescription.append(separator);
625 // naturalLanguageDescription.append(labelTokens[1]);
627 // if(naturalLanguageDescription.length() > 0){
628 // naturalLanguageDescription.append(categorySeparator);
630 // naturalLanguageDescription.append(StringUtils.join(labelTokens));
632 // lastCategory = labelTokens[0];
633 // // end of demo code
635 // if(naturalLanguageDescription.length() > 0){
636 // naturalLanguageDescription.append(separator);
638 // naturalLanguageDescription.append(textData.getFeature().getLabel(lang));
641 // if(naturalLanguageDescription.length() > 0){
642 // naturalLanguageDescription.append(separator);
645 // String text = textData.getMultilanguageText().values().iterator().next().getText();
646 // naturalLanguageDescription.append(text);
652 else if (isUseDescription
) {
653 //AT: Left Blank in case we need to generate a Natural language text string.
655 return naturalLanguageDescription
.toString();
660 public boolean hasStructuredData(DescriptionBase
<?
> description
) {
661 return load(description
.getUuid()).hasStructuredData();
666 @Transactional(readOnly
= false)
667 public UpdateResult
moveDescriptionElementsToDescription(
668 Collection
<DescriptionElementBase
> descriptionElements
,
669 DescriptionBase targetDescription
,
672 UpdateResult result
= new UpdateResult();
673 if (descriptionElements
.isEmpty() ){
677 if (! isCopy
&& descriptionElements
== descriptionElements
.iterator().next().getInDescription().getElements()){
678 //if the descriptionElements collection is the elements set of a description, put it in a separate set before to avoid concurrent modification exceptions
679 descriptionElements
= new HashSet
<DescriptionElementBase
>(descriptionElements
);
680 // descriptionElementsTmp.addAll(descriptionElements);
681 // descriptionElements = descriptionElementsTmp;
683 for (DescriptionElementBase element
: descriptionElements
){
684 DescriptionBase
<?
> description
= element
.getInDescription();
686 DescriptionElementBase newElement
= (DescriptionElementBase
)element
.clone();
687 targetDescription
.addElement(newElement
);
688 } catch (CloneNotSupportedException e
) {
689 throw new RuntimeException ("Clone not yet implemented for class " + element
.getClass().getName(), e
);
692 description
.removeElement(element
);
693 if (description
.getElements().isEmpty()){
694 if (description
instanceof TaxonDescription
){
695 TaxonDescription taxDescription
= HibernateProxyHelper
.deproxy(description
, TaxonDescription
.class);
696 if (taxDescription
.getTaxon() != null){
697 taxDescription
.getTaxon().removeDescription((TaxonDescription
)description
);
700 dao
.delete(description
);
702 dao
.saveOrUpdate(description
);
703 result
.addUpdatedObject(description
);
709 dao
.saveOrUpdate(targetDescription
);
710 result
.addUpdatedObject(targetDescription
);
711 if (targetDescription
instanceof TaxonDescription
){
712 result
.addUpdatedObject(((TaxonDescription
)targetDescription
).getTaxon());
718 @Transactional(readOnly
= false)
719 public UpdateResult
moveDescriptionElementsToDescription(
720 Set
<UUID
> descriptionElementUUIDs
,
721 UUID targetDescriptionUuid
,
723 Set
<DescriptionElementBase
> descriptionElements
= new HashSet
<DescriptionElementBase
>();
724 for(UUID deUuid
: descriptionElementUUIDs
) {
725 descriptionElements
.add(descriptionElementDao
.load(deUuid
));
727 DescriptionBase targetDescription
= dao
.load(targetDescriptionUuid
);
729 return moveDescriptionElementsToDescription(descriptionElements
, targetDescription
, isCopy
);
733 @Transactional(readOnly
= false)
734 public UpdateResult
moveDescriptionElementsToDescription(
735 Set
<UUID
> descriptionElementUUIDs
,
736 UUID targetTaxonUuid
,
739 Taxon targetTaxon
= CdmBase
.deproxy(taxonDao
.load(targetTaxonUuid
), Taxon
.class);
740 DescriptionBase targetDescription
= TaxonDescription
.NewInstance(targetTaxon
);
741 targetDescription
.setTitleCache(moveMessage
, true);
742 Annotation annotation
= Annotation
.NewInstance(moveMessage
, Language
.getDefaultLanguage());
743 annotation
.setAnnotationType(AnnotationType
.TECHNICAL());
744 targetDescription
.addAnnotation(annotation
);
746 targetDescription
= dao
.save(targetDescription
);
747 Set
<DescriptionElementBase
> descriptionElements
= new HashSet
<DescriptionElementBase
>();
748 for(UUID deUuid
: descriptionElementUUIDs
) {
749 descriptionElements
.add(descriptionElementDao
.load(deUuid
));
752 return moveDescriptionElementsToDescription(descriptionElements
, targetDescription
, isCopy
);
756 public Pager
<TermDto
> pageNamedAreasInUse(boolean includeAllParents
, Integer pageSize
,
758 List
<TermDto
> results
= dao
.listNamedAreasInUse(includeAllParents
, null, null);
759 int startIndex
= pageNumber
* pageSize
;
760 int toIndex
= Math
.min(startIndex
+ pageSize
, results
.size());
761 List
<TermDto
> page
= results
.subList(startIndex
, toIndex
);
762 return new DefaultPagerImpl
<TermDto
>(pageNumber
, results
.size(), pageSize
, page
);
767 @Transactional(readOnly
= false)
768 public UpdateResult
moveTaxonDescriptions(Taxon sourceTaxon
, Taxon targetTaxon
) {
769 List
<TaxonDescription
> descriptions
= new ArrayList(sourceTaxon
.getDescriptions());
770 UpdateResult result
= new UpdateResult();
771 result
.addUpdatedObject(sourceTaxon
);
772 result
.addUpdatedObject(targetTaxon
);
773 for(TaxonDescription description
: descriptions
){
775 String moveMessage
= String
.format("Description moved from %s", sourceTaxon
);
776 if(description
.isProtectedTitleCache()){
777 String separator
= "";
778 if(!StringUtils
.isBlank(description
.getTitleCache())){
781 description
.setTitleCache(description
.getTitleCache() + separator
+ moveMessage
, true);
783 Annotation annotation
= Annotation
.NewInstance(moveMessage
, Language
.getDefaultLanguage());
784 annotation
.setAnnotationType(AnnotationType
.TECHNICAL());
785 description
.addAnnotation(annotation
);
786 targetTaxon
.addDescription(description
);
792 @Transactional(readOnly
= false)
793 public UpdateResult
moveTaxonDescriptions(UUID sourceTaxonUuid
, UUID targetTaxonUuid
) {
794 Taxon sourceTaxon
= HibernateProxyHelper
.deproxy(taxonDao
.load(sourceTaxonUuid
), Taxon
.class);
795 Taxon targetTaxon
= HibernateProxyHelper
.deproxy(taxonDao
.load(targetTaxonUuid
), Taxon
.class);
796 return moveTaxonDescriptions(sourceTaxon
, targetTaxon
);
801 @Transactional(readOnly
= false)
802 public UpdateResult
moveTaxonDescription(UUID descriptionUuid
, UUID targetTaxonUuid
){
803 UpdateResult result
= new UpdateResult();
804 TaxonDescription description
= HibernateProxyHelper
.deproxy(dao
.load(descriptionUuid
), TaxonDescription
.class);
806 Taxon sourceTaxon
= description
.getTaxon();
807 String moveMessage
= String
.format("Description moved from %s", sourceTaxon
);
808 if(description
.isProtectedTitleCache()){
809 String separator
= "";
810 if(!StringUtils
.isBlank(description
.getTitleCache())){
813 description
.setTitleCache(description
.getTitleCache() + separator
+ moveMessage
, true);
815 Annotation annotation
= Annotation
.NewInstance(moveMessage
, Language
.getDefaultLanguage());
816 annotation
.setAnnotationType(AnnotationType
.TECHNICAL());
817 description
.addAnnotation(annotation
);
818 Taxon targetTaxon
= HibernateProxyHelper
.deproxy(taxonDao
.load(targetTaxonUuid
), Taxon
.class);
819 targetTaxon
.addDescription(description
);
820 result
.addUpdatedObject(targetTaxon
);
821 result
.addUpdatedObject(sourceTaxon
);
822 // dao.merge(description);