Project

General

Profile

Download (31.1 KB) Statistics
| Branch: | Tag: | Revision:
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
    @Override
466
    public UUID deleteDescription(DescriptionBase description) {
467
    	if (description instanceof TaxonDescription){
468
    		TaxonDescription taxDescription = HibernateProxyHelper.deproxy(description, TaxonDescription.class);
469
    		Taxon tax = taxDescription.getTaxon();
470
    		tax.removeDescription(taxDescription, true);
471
    	}
472

    
473
        return dao.delete(description);
474
    }
475
    @Override
476
    public TermVocabulary<Feature> getFeatureVocabulary(UUID uuid) {
477
        return vocabularyDao.findByUuid(uuid);
478
    }
479

    
480
    @Override
481
    @Deprecated
482
    public <T extends DescriptionElementBase> List<T> getDescriptionElementsForTaxon(
483
            Taxon taxon, Set<Feature> features,
484
            Class<T> type, Integer pageSize,
485
            Integer pageNumber, List<String> propertyPaths) {
486
        return listDescriptionElementsForTaxon(taxon, features, type, pageSize, pageNumber, propertyPaths);
487
    }
488

    
489
    @Override
490
    public <T extends DescriptionElementBase> List<T> listDescriptionElementsForTaxon(
491
            Taxon taxon, Set<Feature> features,
492
            Class<T> type, Integer pageSize,
493
            Integer pageNumber, List<String> propertyPaths) {
494
        return dao.getDescriptionElementForTaxon(taxon.getUuid(), features, type, pageSize, pageNumber, propertyPaths);
495
    }
496

    
497
    @Override
498
    public <T extends DescriptionElementBase> Pager<T> pageDescriptionElementsForTaxon(
499
            Taxon taxon, Set<Feature> features,
500
            Class<T> type, Integer pageSize,
501
            Integer pageNumber, List<String> propertyPaths) {
502
        if (logger.isDebugEnabled()){logger.debug(" get count ...");}
503
        Long count = dao.countDescriptionElementForTaxon(taxon.getUuid(), features, type);
504
        List<T> descriptionElements;
505
        if(AbstractPagerImpl.hasResultsInRange(count, pageNumber, pageSize)){ // no point checking again
506
            if (logger.isDebugEnabled()){logger.debug(" get list ...");}
507
            descriptionElements = listDescriptionElementsForTaxon(taxon, features, type, pageSize, pageNumber, propertyPaths);
508
        } else {
509
            descriptionElements = new ArrayList<T>(0);
510
        }
511
        if (logger.isDebugEnabled()){logger.debug(" service - DONE ...");}
512
        return new DefaultPagerImpl<T>(pageNumber, count.intValue(), pageSize, descriptionElements);
513
    }
514

    
515

    
516
    /* (non-Javadoc)
517
     * @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)
518
     */
519
    @Override
520
    public String generateNaturalLanguageDescription(FeatureTree featureTree,
521
            TaxonDescription description, List<Language> preferredLanguages, String separator) {
522

    
523
        Language lang = preferredLanguages.size() > 0 ? preferredLanguages.get(0) : Language.DEFAULT();
524

    
525
        description = (TaxonDescription)load(description.getUuid());
526
        featureTree = featureTreeDao.load(featureTree.getUuid());
527

    
528
        StringBuilder naturalLanguageDescription = new StringBuilder();
529

    
530
        MarkerType useMarkerType = (MarkerType) definedTermDao.load(UUID.fromString("2e6e42d9-e92a-41f4-899b-03c0ac64f039"));
531
        boolean isUseDescription = false;
532
        if(!description.getMarkers().isEmpty()) {
533
            for (Marker marker: description.getMarkers()) {
534
                MarkerType markerType = marker.getMarkerType();
535
                if (markerType.equals(useMarkerType)) {
536
                    isUseDescription = true;
537
                }
538

    
539
            }
540
        }
541

    
542
        if(description.hasStructuredData() && !isUseDescription){
543

    
544

    
545
            String lastCategory = null;
546
            String categorySeparator = ". ";
547

    
548
            List<TextData> textDataList;
549
            TextData naturalLanguageDescriptionText = null;
550

    
551
            boolean useMicroFormatQuantitativeDescriptionBuilder = false;
552

    
553
            if(useMicroFormatQuantitativeDescriptionBuilder){
554

    
555
                MicroFormatQuantitativeDescriptionBuilder micro = new MicroFormatQuantitativeDescriptionBuilder();
556
                naturalLanguageGenerator.setQuantitativeDescriptionBuilder(micro);
557
                naturalLanguageDescriptionText = naturalLanguageGenerator.generateSingleTextData(featureTree, (description), lang);
558

    
559
            } else {
560

    
561
                naturalLanguageDescriptionText = naturalLanguageGenerator.generateSingleTextData(
562
                        featureTree,
563
                        (description),
564
                        lang);
565
            }
566

    
567
            return naturalLanguageDescriptionText.getText(lang);
568

    
569
//
570
//			boolean doItBetter = false;
571
//
572
//			for (TextData textData : textDataList.toArray(new TextData[textDataList.size()])){
573
//				if(textData.getMultilanguageText().size() > 0){
574
//
575
//					if (!textData.getFeature().equals(Feature.UNKNOWN())) {
576
//						String featureLabel = textData.getFeature().getLabel(lang);
577
//
578
//						if(doItBetter){
579
//							/*
580
//							 *  WARNING
581
//							 *  The code lines below are desinged to handle
582
//							 *  a special case where as the feature label contains
583
//							 *  hierarchical information on the features. This code
584
//							 *  exist only as a base for discussion, and is not
585
//							 *  intendet to be used in production.
586
//							 */
587
//							featureLabel = StringUtils.remove(featureLabel, '>');
588
//
589
//							String[] labelTokens = StringUtils.split(featureLabel, '<');
590
//							if(labelTokens[0].equals(lastCategory) && labelTokens.length > 1){
591
//								if(naturalLanguageDescription.length() > 0){
592
//									naturalLanguageDescription.append(separator);
593
//								}
594
//								naturalLanguageDescription.append(labelTokens[1]);
595
//							} else {
596
//								if(naturalLanguageDescription.length() > 0){
597
//									naturalLanguageDescription.append(categorySeparator);
598
//								}
599
//								naturalLanguageDescription.append(StringUtils.join(labelTokens));
600
//							}
601
//							lastCategory = labelTokens[0];
602
//							// end of demo code
603
//						} else {
604
//							if(naturalLanguageDescription.length() > 0){
605
//								naturalLanguageDescription.append(separator);
606
//							}
607
//							naturalLanguageDescription.append(textData.getFeature().getLabel(lang));
608
//						}
609
//					} else {
610
//						if(naturalLanguageDescription.length() > 0){
611
//							naturalLanguageDescription.append(separator);
612
//						}
613
//					}
614
//					String text = textData.getMultilanguageText().values().iterator().next().getText();
615
//					naturalLanguageDescription.append(text);
616
//
617
//				}
618
//			}
619

    
620
        }
621
        else if (isUseDescription) {
622
            //AT: Left Blank in case we need to generate a Natural language text string.
623
        }
624
        return naturalLanguageDescription.toString();
625
    }
626

    
627
    /* (non-Javadoc)
628
     * @see eu.etaxonomy.cdm.api.service.IDescriptionService#hasStructuredData(eu.etaxonomy.cdm.model.description.DescriptionBase)
629
     */
630
    @Override
631
    public boolean hasStructuredData(DescriptionBase<?> description) {
632
        return load(description.getUuid()).hasStructuredData();
633
    }
634

    
635

    
636
    /* (non-Javadoc)
637
     * @see eu.etaxonomy.cdm.api.service.IDescriptionService#moveDescriptionElementsToDescription(java.util.Collection, eu.etaxonomy.cdm.model.description.DescriptionBase, boolean)
638
     */
639
    @Override
640
    public void moveDescriptionElementsToDescription(Collection<DescriptionElementBase> descriptionElements,
641
                                                    DescriptionBase targetDescription, boolean isCopy) {
642

    
643
        if (descriptionElements.isEmpty() ){
644
            return ;
645
        }
646

    
647
        if (! isCopy && descriptionElements == descriptionElements.iterator().next().getInDescription().getElements()){
648
            //if the descriptionElements collection is the elements set of a description, put it in a separate set before to avoid concurrent modification exceptions
649
            descriptionElements = new HashSet<DescriptionElementBase>(descriptionElements);
650
//			descriptionElementsTmp.addAll(descriptionElements);
651
//			descriptionElements = descriptionElementsTmp;
652
        }
653
        for (DescriptionElementBase element : descriptionElements){
654
            DescriptionBase description = element.getInDescription();
655
            try {
656
                DescriptionElementBase newElement = (DescriptionElementBase)element.clone();
657
                targetDescription.addElement(newElement);
658
            } catch (CloneNotSupportedException e) {
659
                new RuntimeException ("Clone not yet implemented for class " + element.getClass().getName(), e);
660
            }
661
            if (! isCopy){
662
                description.removeElement(element);
663
            }
664

    
665
        }
666
    }
667

    
668
    @Override
669
    public Pager<NamedArea> pageNamedAreasInUse(Integer pageSize,
670
            Integer pageNumber, List<String> propertyPaths){
671

    
672
        List<NamedArea> results = dao.listNamedAreasInUse(pageSize, pageNumber, propertyPaths);
673
        return new DefaultPagerImpl<NamedArea>(pageNumber, results.size(), pageSize, results);
674
    }
675

    
676

    
677
    @Override
678
    @Transactional(readOnly = false)
679
    public void moveTaxonDescriptions(Taxon sourceTaxon, Taxon targetTaxon) {
680
        List<TaxonDescription> descriptions = new ArrayList(sourceTaxon.getDescriptions());
681
        for(TaxonDescription description : descriptions){
682

    
683
            String moveMessage = String.format("Description moved from %s", sourceTaxon);
684
            if(description.isProtectedTitleCache()){
685
                String separator = "";
686
                if(!StringUtils.isBlank(description.getTitleCache())){
687
                    separator = " - ";
688
                }
689
                description.setTitleCache(description.getTitleCache() + separator + moveMessage, true);
690
            }
691
            Annotation annotation = Annotation.NewInstance(moveMessage, Language.getDefaultLanguage());
692
            annotation.setAnnotationType(AnnotationType.TECHNICAL());
693
            description.addAnnotation(annotation);
694
            targetTaxon.addDescription(description);
695
        }
696
    }
697

    
698
    @Override
699
    @Transactional(readOnly = false)
700
    public void moveTaxonDescriptions(UUID sourceTaxonUuid, UUID targetTaxonUuid) {
701
        Taxon sourceTaxon = HibernateProxyHelper.deproxy(taxonDao.load(sourceTaxonUuid), Taxon.class);
702
        Taxon targetTaxon = HibernateProxyHelper.deproxy(taxonDao.load(targetTaxonUuid), Taxon.class);
703
        moveTaxonDescriptions(sourceTaxon, targetTaxon);
704

    
705
    }
706

    
707
}
(16-16/88)