Merge branch 'master' of wp5.e-taxonomy.eu:/var/git/cdmlib
[cdmlib.git] / cdmlib-services / src / main / java / eu / etaxonomy / cdm / api / service / DescriptionServiceImpl.java
1 // $Id$
2 /**
3 * Copyright (C) 2007 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
6 *
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.
9 */
10
11 package eu.etaxonomy.cdm.api.service;
12
13 import java.util.ArrayList;
14 import java.util.Collection;
15 import java.util.HashSet;
16 import java.util.List;
17 import java.util.Map;
18 import java.util.Set;
19 import java.util.UUID;
20
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;
26
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.DefinedTerm;
36 import eu.etaxonomy.cdm.model.common.Language;
37 import eu.etaxonomy.cdm.model.common.Marker;
38 import eu.etaxonomy.cdm.model.common.MarkerType;
39 import eu.etaxonomy.cdm.model.common.TermVocabulary;
40 import eu.etaxonomy.cdm.model.description.DescriptionBase;
41 import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
42 import eu.etaxonomy.cdm.model.description.Distribution;
43 import eu.etaxonomy.cdm.model.description.Feature;
44 import eu.etaxonomy.cdm.model.description.FeatureTree;
45 import eu.etaxonomy.cdm.model.description.PresenceAbsenceTerm;
46 import eu.etaxonomy.cdm.model.description.TaxonDescription;
47 import eu.etaxonomy.cdm.model.description.TaxonNameDescription;
48 import eu.etaxonomy.cdm.model.description.TextData;
49 import eu.etaxonomy.cdm.model.location.NamedArea;
50 import eu.etaxonomy.cdm.model.location.NamedAreaLevel;
51 import eu.etaxonomy.cdm.model.media.Media;
52 import eu.etaxonomy.cdm.model.name.TaxonNameBase;
53 import eu.etaxonomy.cdm.model.taxon.Taxon;
54 import eu.etaxonomy.cdm.persistence.dao.common.IDefinedTermDao;
55 import eu.etaxonomy.cdm.persistence.dao.common.ITermVocabularyDao;
56 import eu.etaxonomy.cdm.persistence.dao.description.IDescriptionDao;
57 import eu.etaxonomy.cdm.persistence.dao.description.IDescriptionElementDao;
58 import eu.etaxonomy.cdm.persistence.dao.description.IFeatureDao;
59 import eu.etaxonomy.cdm.persistence.dao.description.IFeatureNodeDao;
60 import eu.etaxonomy.cdm.persistence.dao.description.IFeatureTreeDao;
61 import eu.etaxonomy.cdm.persistence.dao.description.IStatisticalMeasurementValueDao;
62 import eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao;
63 import eu.etaxonomy.cdm.persistence.dto.TermDto;
64 import eu.etaxonomy.cdm.persistence.query.OrderHint;
65 import eu.etaxonomy.cdm.strategy.cache.common.IIdentifiableEntityCacheStrategy;
66
67 /**
68 * @author a.mueller
69 * @created 24.06.2008
70 * @version 1.0
71 */
72 /**
73 * @author a.kohlbecker
74 * @date Dec 5, 2013
75 *
76 */
77 @Service
78 @Transactional(readOnly = true)
79 public class DescriptionServiceImpl extends IdentifiableServiceBase<DescriptionBase,IDescriptionDao> implements IDescriptionService {
80
81 private static final Logger logger = Logger.getLogger(DescriptionServiceImpl.class);
82
83 protected IDescriptionElementDao descriptionElementDao;
84 protected IFeatureTreeDao featureTreeDao;
85 protected IFeatureNodeDao featureNodeDao;
86 protected IFeatureDao featureDao;
87 protected ITermVocabularyDao vocabularyDao;
88 protected IDefinedTermDao definedTermDao;
89 protected IStatisticalMeasurementValueDao statisticalMeasurementValueDao;
90 protected ITaxonDao taxonDao;
91
92 //TODO change to Interface
93 private NaturalLanguageGenerator naturalLanguageGenerator;
94
95 @Autowired
96 protected void setFeatureTreeDao(IFeatureTreeDao featureTreeDao) {
97 this.featureTreeDao = featureTreeDao;
98 }
99
100 @Autowired
101 protected void setFeatureNodeDao(IFeatureNodeDao featureNodeDao) {
102 this.featureNodeDao = featureNodeDao;
103 }
104
105 @Autowired
106 protected void setFeatureDao(IFeatureDao featureDao) {
107 this.featureDao = featureDao;
108 }
109
110 @Autowired
111 protected void setVocabularyDao(ITermVocabularyDao vocabularyDao) {
112 this.vocabularyDao = vocabularyDao;
113 }
114
115 @Autowired
116 protected void setDefinedTermDao(IDefinedTermDao definedTermDao) {
117 this.definedTermDao = definedTermDao;
118 }
119
120 @Autowired
121 protected void statisticalMeasurementValueDao(IStatisticalMeasurementValueDao statisticalMeasurementValueDao) {
122 this.statisticalMeasurementValueDao = statisticalMeasurementValueDao;
123 }
124
125 @Autowired
126 protected void setDescriptionElementDao(IDescriptionElementDao descriptionElementDao) {
127 this.descriptionElementDao = descriptionElementDao;
128 }
129
130 @Autowired
131 protected void setNaturalLanguageGenerator(NaturalLanguageGenerator naturalLanguageGenerator) {
132 this.naturalLanguageGenerator = naturalLanguageGenerator;
133 }
134
135 @Autowired
136 protected void setTaxonDao(ITaxonDao taxonDao) {
137 this.taxonDao = taxonDao;
138 }
139
140 /**
141 *
142 */
143 public DescriptionServiceImpl() {
144 logger.debug("Load DescriptionService Bean");
145 }
146
147
148
149 /* (non-Javadoc)
150 * @see eu.etaxonomy.cdm.api.service.IIdentifiableEntityService#updateTitleCache(java.lang.Integer, eu.etaxonomy.cdm.strategy.cache.common.IIdentifiableEntityCacheStrategy)
151 */
152 @Override
153 @Transactional(readOnly = false)
154 public void updateTitleCache(Class<? extends DescriptionBase> clazz, Integer stepSize, IIdentifiableEntityCacheStrategy<DescriptionBase> cacheStrategy, IProgressMonitor monitor) {
155 if (clazz == null){
156 clazz = DescriptionBase.class;
157 }
158 super.updateTitleCacheImpl(clazz, stepSize, cacheStrategy, monitor);
159 }
160
161
162 @Override
163 public TermVocabulary<Feature> getDefaultFeatureVocabulary(){
164 String uuidFeature = "b187d555-f06f-4d65-9e53-da7c93f8eaa8";
165 UUID featureUuid = UUID.fromString(uuidFeature);
166 return vocabularyDao.findByUuid(featureUuid);
167 }
168
169 @Override
170 @Autowired
171 protected void setDao(IDescriptionDao dao) {
172 this.dao = dao;
173 }
174
175 @Override
176 public int count(Class<? extends DescriptionBase> type, Boolean hasImages, Boolean hasText,Set<Feature> feature) {
177 return dao.countDescriptions(type, hasImages, hasText, feature);
178 }
179
180 @Override
181 public Pager<DescriptionElementBase> pageDescriptionElements(DescriptionBase description, Class<? extends DescriptionBase> descriptionType,
182 Set<Feature> features, Class<? extends DescriptionElementBase> type, Integer pageSize, Integer pageNumber, List<String> propertyPaths) {
183
184 List<DescriptionElementBase> results = listDescriptionElements(description, descriptionType, features, type, pageSize, pageNumber, propertyPaths);
185 return new DefaultPagerImpl<DescriptionElementBase>(pageNumber, results.size(), pageSize, results);
186 }
187
188 /* (non-Javadoc)
189 * @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)
190 */
191 @Override
192 @Deprecated
193 public Pager<DescriptionElementBase> getDescriptionElements(DescriptionBase description,
194 Set<Feature> features, Class<? extends DescriptionElementBase> type, Integer pageSize, Integer pageNumber, List<String> propertyPaths) {
195 return pageDescriptionElements(description, null, features, type, pageSize, pageNumber, propertyPaths);
196 }
197
198 @Override
199 public List<DescriptionElementBase> listDescriptionElements(DescriptionBase description, Class<? extends DescriptionBase> descriptionType,
200 Set<Feature> features, Class<? extends DescriptionElementBase> type, Integer pageSize, Integer pageNumber, List<String> propertyPaths) {
201
202 Integer numberOfResults = dao.countDescriptionElements(description, descriptionType, features, type);
203 List<DescriptionElementBase> results = new ArrayList<DescriptionElementBase>();
204 if(AbstractPagerImpl.hasResultsInRange(numberOfResults.longValue(), pageNumber, pageSize)) {
205 results = dao.getDescriptionElements(description, descriptionType, features, type, pageSize, pageNumber, propertyPaths);
206 }
207 return results;
208 }
209
210 /* (non-Javadoc)
211 * @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)
212 */
213 @Override
214 @Deprecated
215 public List<DescriptionElementBase> listDescriptionElements(DescriptionBase description,
216 Set<Feature> features, Class<? extends DescriptionElementBase> type, Integer pageSize, Integer pageNumber, List<String> propertyPaths) {
217
218 return listDescriptionElements(description, null, features, type, pageSize, pageNumber, propertyPaths);
219 }
220
221 @Override
222 public Pager<Annotation> getDescriptionElementAnnotations(DescriptionElementBase annotatedObj, MarkerType status, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths){
223 Integer numberOfResults = descriptionElementDao.countAnnotations(annotatedObj, status);
224
225 List<Annotation> results = new ArrayList<Annotation>();
226 if(numberOfResults > 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
227 results = descriptionElementDao.getAnnotations(annotatedObj, status, pageSize, pageNumber, orderHints, propertyPaths);
228 }
229
230 return new DefaultPagerImpl<Annotation>(pageNumber, numberOfResults, pageSize, results);
231 }
232
233
234
235 @Override
236 public Pager<Media> getMedia(DescriptionElementBase descriptionElement, Integer pageSize, Integer pageNumber, List<String> propertyPaths) {
237 Integer numberOfResults = descriptionElementDao.countMedia(descriptionElement);
238
239 List<Media> results = new ArrayList<Media>();
240 if(numberOfResults > 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
241 results = descriptionElementDao.getMedia(descriptionElement, pageSize, pageNumber, propertyPaths);
242 }
243
244 return new DefaultPagerImpl<Media>(pageNumber, numberOfResults, pageSize, results);
245 }
246
247 @Override
248 public Pager<TaxonDescription> pageTaxonDescriptions(Taxon taxon, Set<DefinedTerm> scopes, Set<NamedArea> geographicalScope, Integer pageSize, Integer pageNumber, List<String> propertyPaths) {
249 Set<MarkerType> markerTypes = null;
250 return pageTaxonDescriptions(taxon, scopes, geographicalScope, markerTypes, pageSize, pageNumber, propertyPaths);
251 }
252
253 @Override
254 public List<TaxonDescription> listTaxonDescriptions(Taxon taxon, Set<DefinedTerm> scopes, Set<NamedArea> geographicalScope, Integer pageSize, Integer pageNumber, List<String> propertyPaths) {
255 Set<MarkerType> markerTypes = null;
256 return listTaxonDescriptions(taxon, scopes, geographicalScope, markerTypes, pageSize, pageNumber, propertyPaths);
257 }
258
259
260 /* (non-Javadoc)
261 * @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)
262 */
263 @Override
264 public Pager<TaxonDescription> pageTaxonDescriptions(Taxon taxon, Set<DefinedTerm> scopes, Set<NamedArea> geographicalScope, Set<MarkerType> markerTypes, Integer pageSize, Integer pageNumber, List<String> propertyPaths) {
265 Integer numberOfResults = dao.countTaxonDescriptions(taxon, scopes, geographicalScope, markerTypes);
266
267 List<TaxonDescription> results = new ArrayList<TaxonDescription>();
268 if(numberOfResults > 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
269 results = dao.listTaxonDescriptions(taxon, scopes, geographicalScope, markerTypes, pageSize, pageNumber, propertyPaths);
270 }
271
272 return new DefaultPagerImpl<TaxonDescription>(pageNumber, numberOfResults, pageSize, results);
273 }
274
275 @Override
276 public List<TaxonDescription> listTaxonDescriptions(Taxon taxon, Set<DefinedTerm> scopes, Set<NamedArea> geographicalScope, Set<MarkerType> markerTypes, Integer pageSize, Integer pageNumber, List<String> propertyPaths) {
277 List<TaxonDescription> results = dao.listTaxonDescriptions(taxon, scopes, geographicalScope, markerTypes, pageSize, pageNumber, propertyPaths);
278 return results;
279 }
280
281
282 /* (non-Javadoc)
283 * @see eu.etaxonomy.cdm.api.service.IDescriptionService#listTaxonDescriptionMedia(UUID, boolean, Set, Integer, Integer, List)
284 */
285 @Override
286 public List<Media> listTaxonDescriptionMedia(UUID taxonUuid, boolean limitToGalleries, Set<MarkerType> markerTypes, Integer pageSize, Integer pageNumber, List<String> propertyPaths){
287 return this.dao.listTaxonDescriptionMedia(taxonUuid, limitToGalleries, markerTypes, pageSize, pageNumber, propertyPaths);
288 }
289
290 /*
291 * @see IDescriptionService#countTaxonDescriptionMedia(UUID, boolean, Set)
292 */
293 @Override
294 public int countTaxonDescriptionMedia(UUID taxonUuid, boolean limitToGalleries, Set<MarkerType> markerTypes){
295 return this.dao.countTaxonDescriptionMedia(taxonUuid, limitToGalleries, markerTypes);
296 }
297
298
299 /* (non-Javadoc)
300 * @see eu.etaxonomy.cdm.api.service.IDescriptionService#getOrderedDistributions(java.util.Set, boolean, boolean, java.util.Set, java.util.List)
301 */
302 @Override
303 @Deprecated
304 public DistributionTree getOrderedDistributions(
305 Set<TaxonDescription> taxonDescriptions,
306 boolean subAreaPreference,
307 boolean statusOrderPreference,
308 Set<MarkerType> hideMarkedAreas,
309 Set<NamedAreaLevel> omitLevels, List<String> propertyPaths){
310
311 List<Distribution> distList = new ArrayList<Distribution>();
312
313 List<UUID> uuids = new ArrayList<UUID>();
314 for (TaxonDescription taxonDescription : taxonDescriptions) {
315 if (! taxonDescription.isImageGallery()){ //image galleries should not have descriptions, but better filter fully on DTYPE of description element
316 uuids.add(taxonDescription.getUuid());
317 }
318 }
319
320 List<DescriptionBase> desclist = dao.list(uuids, null, null, null, propertyPaths);
321 for (DescriptionBase desc : desclist) {
322 if (desc.isInstanceOf(TaxonDescription.class)){
323 Set<DescriptionElementBase> elements = desc.getElements();
324 for (DescriptionElementBase element : elements) {
325 if (element.isInstanceOf(Distribution.class)) {
326 Distribution distribution = (Distribution) element;
327 if(distribution.getArea() != null){
328 distList.add(distribution);
329 }
330 }
331 }
332 }
333 }
334
335 //old
336 // for (TaxonDescription taxonDescription : taxonDescriptions) {
337 // if (logger.isDebugEnabled()){ logger.debug("load taxon description " + taxonDescription.getUuid());}
338 // //TODO why not loading all description via .list ? This may improve performance
339 // taxonDescription = (TaxonDescription) dao.load(taxonDescription.getUuid(), propertyPaths);
340 // Set<DescriptionElementBase> elements = taxonDescription.getElements();
341 // for (DescriptionElementBase element : elements) {
342 // if (element.isInstanceOf(Distribution.class)) {
343 // Distribution distribution = (Distribution) element;
344 // if(distribution.getArea() != null){
345 // distList.add(distribution);
346 // }
347 // }
348 // }
349 // }
350
351 if (logger.isDebugEnabled()){logger.debug("filter tree for " + distList.size() + " distributions ...");}
352
353 // filter distributions
354 Collection<Distribution> filteredDistributions = DescriptionUtility.filterDistributions(distList, subAreaPreference, statusOrderPreference, hideMarkedAreas);
355 distList.clear();
356 distList.addAll(filteredDistributions);
357
358 return DescriptionUtility.orderDistributions(definedTermDao, omitLevels, distList);
359 }
360
361
362 @Override
363 public Pager<TaxonNameDescription> getTaxonNameDescriptions(TaxonNameBase name, Integer pageSize, Integer pageNumber, List<String> propertyPaths) {
364 Integer numberOfResults = dao.countTaxonNameDescriptions(name);
365
366 List<TaxonNameDescription> results = new ArrayList<TaxonNameDescription>();
367 if(numberOfResults > 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
368 results = dao.getTaxonNameDescriptions(name, pageSize, pageNumber,propertyPaths);
369 }
370
371 return new DefaultPagerImpl<TaxonNameDescription>(pageNumber, numberOfResults, pageSize, results);
372 }
373
374
375 @Override
376 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) {
377 Integer numberOfResults = dao.countDescriptions(type, hasImages, hasText, feature);
378
379 List<DescriptionBase> results = new ArrayList<DescriptionBase>();
380 if(numberOfResults > 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
381 results = dao.listDescriptions(type, hasImages, hasText, feature, pageSize, pageNumber,orderHints,propertyPaths);
382 }
383
384 return new DefaultPagerImpl<DescriptionBase>(pageNumber, numberOfResults, pageSize, results);
385 }
386
387 /**
388 * FIXME Candidate for harmonization
389 * Rename: searchByDistribution
390 */
391 @Override
392 public Pager<TaxonDescription> searchDescriptionByDistribution(Set<NamedArea> namedAreas, PresenceAbsenceTerm presence, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {
393 Integer numberOfResults = dao.countDescriptionByDistribution(namedAreas, presence);
394
395 List<TaxonDescription> results = new ArrayList<TaxonDescription>();
396 if(numberOfResults > 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
397 results = dao.searchDescriptionByDistribution(namedAreas, presence, pageSize, pageNumber,orderHints,propertyPaths);
398 }
399
400 return new DefaultPagerImpl<TaxonDescription>(pageNumber, numberOfResults, pageSize, results);
401 }
402
403 /**
404 * FIXME Candidate for harmonization
405 * move: descriptionElementService.search
406 */
407 @Override
408 public Pager<DescriptionElementBase> searchElements(Class<? extends DescriptionElementBase> clazz, String queryString, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {
409 Integer numberOfResults = descriptionElementDao.count(clazz, queryString);
410
411 List<DescriptionElementBase> results = new ArrayList<DescriptionElementBase>();
412 if(numberOfResults > 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
413 results = descriptionElementDao.search(clazz, queryString, pageSize, pageNumber, orderHints, propertyPaths);
414 }
415
416 return new DefaultPagerImpl<DescriptionElementBase>(pageNumber, numberOfResults, pageSize, results);
417 }
418
419 /**
420 * FIXME Candidate for harmonization
421 * descriptionElementService.find
422 */
423 @Override
424 public DescriptionElementBase getDescriptionElementByUuid(UUID uuid) {
425 return descriptionElementDao.findByUuid(uuid);
426 }
427
428 /**
429 * FIXME Candidate for harmonization
430 * descriptionElementService.load
431 */
432 @Override
433 public DescriptionElementBase loadDescriptionElement(UUID uuid, List<String> propertyPaths) {
434 return descriptionElementDao.load(uuid, propertyPaths);
435 }
436
437 /**
438 * FIXME Candidate for harmonization
439 * descriptionElementService.save
440 */
441 @Override
442 @Transactional(readOnly = false)
443 public UUID saveDescriptionElement(DescriptionElementBase descriptionElement) {
444 return descriptionElementDao.save(descriptionElement);
445 }
446
447 /**
448 * FIXME Candidate for harmonization
449 * descriptionElementService.save
450 */
451 @Override
452 @Transactional(readOnly = false)
453 public Map<UUID, DescriptionElementBase> saveDescriptionElement(Collection<DescriptionElementBase> descriptionElements) {
454 return descriptionElementDao.saveAll(descriptionElements);
455 }
456
457 /**
458 * FIXME Candidate for harmonization
459 * descriptionElementService.delete
460 */
461 @Override
462 public UUID deleteDescriptionElement(DescriptionElementBase descriptionElement) {
463 return descriptionElementDao.delete(descriptionElement);
464 }
465
466
467 /* (non-Javadoc)
468 * @see eu.etaxonomy.cdm.api.service.IDescriptionService#deleteDescriptionElement(java.util.UUID)
469 */
470 @Override
471 public UUID deleteDescriptionElement(UUID descriptionElementUuid) {
472 return deleteDescriptionElement(descriptionElementDao.load(descriptionElementUuid));
473 }
474
475 @Override
476 @Transactional(readOnly = false)
477 public DeleteResult deleteDescription(DescriptionBase description) {
478 DeleteResult deleteResult = new DeleteResult();
479
480 if (description instanceof TaxonDescription){
481 TaxonDescription taxDescription = HibernateProxyHelper.deproxy(description, TaxonDescription.class);
482 Taxon tax = taxDescription.getTaxon();
483 tax.removeDescription(taxDescription, true);
484
485 deleteResult.addUpdatedObject(tax);
486 deleteResult.setCdmEntity(tax);
487 }
488
489
490 return deleteResult;
491 }
492
493
494 /* (non-Javadoc)
495 * @see eu.etaxonomy.cdm.api.service.IDescriptionService#deleteDescription(java.util.UUID)
496 */
497 @Override
498 @Transactional(readOnly = false)
499 public DeleteResult deleteDescription(UUID descriptionUuid) {
500 return deleteDescription(dao.load(descriptionUuid));
501 }
502
503
504 @Override
505 public TermVocabulary<Feature> getFeatureVocabulary(UUID uuid) {
506 return vocabularyDao.findByUuid(uuid);
507 }
508
509 @Override
510 @Deprecated
511 public <T extends DescriptionElementBase> List<T> getDescriptionElementsForTaxon(
512 Taxon taxon, Set<Feature> features,
513 Class<T> type, Integer pageSize,
514 Integer pageNumber, List<String> propertyPaths) {
515 return listDescriptionElementsForTaxon(taxon, features, type, pageSize, pageNumber, propertyPaths);
516 }
517
518 @Override
519 public <T extends DescriptionElementBase> List<T> listDescriptionElementsForTaxon(
520 Taxon taxon, Set<Feature> features,
521 Class<T> type, Integer pageSize,
522 Integer pageNumber, List<String> propertyPaths) {
523 return dao.getDescriptionElementForTaxon(taxon.getUuid(), features, type, pageSize, pageNumber, propertyPaths);
524 }
525
526 @Override
527 public <T extends DescriptionElementBase> Pager<T> pageDescriptionElementsForTaxon(
528 Taxon taxon, Set<Feature> features,
529 Class<T> type, Integer pageSize,
530 Integer pageNumber, List<String> propertyPaths) {
531 if (logger.isDebugEnabled()){logger.debug(" get count ...");}
532 Long count = dao.countDescriptionElementForTaxon(taxon.getUuid(), features, type);
533 List<T> descriptionElements;
534 if(AbstractPagerImpl.hasResultsInRange(count, pageNumber, pageSize)){ // no point checking again
535 if (logger.isDebugEnabled()){logger.debug(" get list ...");}
536 descriptionElements = listDescriptionElementsForTaxon(taxon, features, type, pageSize, pageNumber, propertyPaths);
537 } else {
538 descriptionElements = new ArrayList<T>(0);
539 }
540 if (logger.isDebugEnabled()){logger.debug(" service - DONE ...");}
541 return new DefaultPagerImpl<T>(pageNumber, count.intValue(), pageSize, descriptionElements);
542 }
543
544
545 /* (non-Javadoc)
546 * @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)
547 */
548 @Override
549 public String generateNaturalLanguageDescription(FeatureTree featureTree,
550 TaxonDescription description, List<Language> preferredLanguages, String separator) {
551
552 Language lang = preferredLanguages.size() > 0 ? preferredLanguages.get(0) : Language.DEFAULT();
553
554 description = (TaxonDescription)load(description.getUuid());
555 featureTree = featureTreeDao.load(featureTree.getUuid());
556
557 StringBuilder naturalLanguageDescription = new StringBuilder();
558
559 MarkerType useMarkerType = (MarkerType) definedTermDao.load(UUID.fromString("2e6e42d9-e92a-41f4-899b-03c0ac64f039"));
560 boolean isUseDescription = false;
561 if(!description.getMarkers().isEmpty()) {
562 for (Marker marker: description.getMarkers()) {
563 MarkerType markerType = marker.getMarkerType();
564 if (markerType.equals(useMarkerType)) {
565 isUseDescription = true;
566 }
567
568 }
569 }
570
571 if(description.hasStructuredData() && !isUseDescription){
572
573
574 String lastCategory = null;
575 String categorySeparator = ". ";
576
577 List<TextData> textDataList;
578 TextData naturalLanguageDescriptionText = null;
579
580 boolean useMicroFormatQuantitativeDescriptionBuilder = false;
581
582 if(useMicroFormatQuantitativeDescriptionBuilder){
583
584 MicroFormatQuantitativeDescriptionBuilder micro = new MicroFormatQuantitativeDescriptionBuilder();
585 naturalLanguageGenerator.setQuantitativeDescriptionBuilder(micro);
586 naturalLanguageDescriptionText = naturalLanguageGenerator.generateSingleTextData(featureTree, (description), lang);
587
588 } else {
589
590 naturalLanguageDescriptionText = naturalLanguageGenerator.generateSingleTextData(
591 featureTree,
592 (description),
593 lang);
594 }
595
596 return naturalLanguageDescriptionText.getText(lang);
597
598 //
599 // boolean doItBetter = false;
600 //
601 // for (TextData textData : textDataList.toArray(new TextData[textDataList.size()])){
602 // if(textData.getMultilanguageText().size() > 0){
603 //
604 // if (!textData.getFeature().equals(Feature.UNKNOWN())) {
605 // String featureLabel = textData.getFeature().getLabel(lang);
606 //
607 // if(doItBetter){
608 // /*
609 // * WARNING
610 // * The code lines below are desinged to handle
611 // * a special case where as the feature label contains
612 // * hierarchical information on the features. This code
613 // * exist only as a base for discussion, and is not
614 // * intendet to be used in production.
615 // */
616 // featureLabel = StringUtils.remove(featureLabel, '>');
617 //
618 // String[] labelTokens = StringUtils.split(featureLabel, '<');
619 // if(labelTokens[0].equals(lastCategory) && labelTokens.length > 1){
620 // if(naturalLanguageDescription.length() > 0){
621 // naturalLanguageDescription.append(separator);
622 // }
623 // naturalLanguageDescription.append(labelTokens[1]);
624 // } else {
625 // if(naturalLanguageDescription.length() > 0){
626 // naturalLanguageDescription.append(categorySeparator);
627 // }
628 // naturalLanguageDescription.append(StringUtils.join(labelTokens));
629 // }
630 // lastCategory = labelTokens[0];
631 // // end of demo code
632 // } else {
633 // if(naturalLanguageDescription.length() > 0){
634 // naturalLanguageDescription.append(separator);
635 // }
636 // naturalLanguageDescription.append(textData.getFeature().getLabel(lang));
637 // }
638 // } else {
639 // if(naturalLanguageDescription.length() > 0){
640 // naturalLanguageDescription.append(separator);
641 // }
642 // }
643 // String text = textData.getMultilanguageText().values().iterator().next().getText();
644 // naturalLanguageDescription.append(text);
645 //
646 // }
647 // }
648
649 }
650 else if (isUseDescription) {
651 //AT: Left Blank in case we need to generate a Natural language text string.
652 }
653 return naturalLanguageDescription.toString();
654 }
655
656
657 @Override
658 public boolean hasStructuredData(DescriptionBase<?> description) {
659 return load(description.getUuid()).hasStructuredData();
660 }
661
662
663 @Override
664 public void moveDescriptionElementsToDescription(
665 Collection<DescriptionElementBase> descriptionElements,
666 DescriptionBase targetDescription,
667 boolean isCopy) {
668
669 if (descriptionElements.isEmpty() ){
670 return ;
671 }
672
673 if (! isCopy && descriptionElements == descriptionElements.iterator().next().getInDescription().getElements()){
674 //if the descriptionElements collection is the elements set of a description, put it in a separate set before to avoid concurrent modification exceptions
675 descriptionElements = new HashSet<DescriptionElementBase>(descriptionElements);
676 // descriptionElementsTmp.addAll(descriptionElements);
677 // descriptionElements = descriptionElementsTmp;
678 }
679 for (DescriptionElementBase element : descriptionElements){
680 DescriptionBase<?> description = element.getInDescription();
681 try {
682 DescriptionElementBase newElement = (DescriptionElementBase)element.clone();
683 targetDescription.addElement(newElement);
684 } catch (CloneNotSupportedException e) {
685 throw new RuntimeException ("Clone not yet implemented for class " + element.getClass().getName(), e);
686 }
687 if (! isCopy){
688 description.removeElement(element);
689 }
690
691 }
692 }
693
694 @Override
695 public Pager<TermDto> pageNamedAreasInUse(boolean includeAllParents, Integer pageSize,
696 Integer pageNumber){
697
698 List<TermDto> results = dao.listNamedAreasInUse(includeAllParents, pageSize, pageNumber);
699 return new DefaultPagerImpl<TermDto>(pageNumber, results.size(), pageSize, results);
700 }
701
702
703 @Override
704 @Transactional(readOnly = false)
705 public UpdateResult moveTaxonDescriptions(Taxon sourceTaxon, Taxon targetTaxon) {
706 List<TaxonDescription> descriptions = new ArrayList(sourceTaxon.getDescriptions());
707 UpdateResult result = new UpdateResult();
708 result.addUpdatedObject(sourceTaxon);
709 result.addUpdatedObject(targetTaxon);
710 for(TaxonDescription description : descriptions){
711
712 String moveMessage = String.format("Description moved from %s", sourceTaxon);
713 if(description.isProtectedTitleCache()){
714 String separator = "";
715 if(!StringUtils.isBlank(description.getTitleCache())){
716 separator = " - ";
717 }
718 description.setTitleCache(description.getTitleCache() + separator + moveMessage, true);
719 }
720 Annotation annotation = Annotation.NewInstance(moveMessage, Language.getDefaultLanguage());
721 annotation.setAnnotationType(AnnotationType.TECHNICAL());
722 description.addAnnotation(annotation);
723 targetTaxon.addDescription(description);
724 }
725 return result;
726 }
727
728 @Override
729 @Transactional(readOnly = false)
730 public UpdateResult moveTaxonDescriptions(UUID sourceTaxonUuid, UUID targetTaxonUuid) {
731 Taxon sourceTaxon = HibernateProxyHelper.deproxy(taxonDao.load(sourceTaxonUuid), Taxon.class);
732 Taxon targetTaxon = HibernateProxyHelper.deproxy(taxonDao.load(targetTaxonUuid), Taxon.class);
733 return moveTaxonDescriptions(sourceTaxon, targetTaxon);
734
735 }
736
737
738
739 }