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