Project

General

Profile

Download (32.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.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> hiddenAreaMarkerTypes,
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, hiddenAreaMarkerTypes, true, statusOrderPreference, false);
355
        distList.clear();
356
        distList.addAll(filteredDistributions);
357

    
358
        return DescriptionUtility.orderDistributions(definedTermDao, omitLevels, distList, hiddenAreaMarkerTypes);
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).getUuid();
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
    		dao.delete(description);
485

    
486
            deleteResult.addUpdatedObject(tax);
487
            deleteResult.setCdmEntity(tax);
488
    	}
489

    
490

    
491
        return deleteResult;
492
    }
493

    
494

    
495
    /* (non-Javadoc)
496
     * @see eu.etaxonomy.cdm.api.service.IDescriptionService#deleteDescription(java.util.UUID)
497
     */
498
    @Override
499
    @Transactional(readOnly = false)
500
    public DeleteResult deleteDescription(UUID descriptionUuid) {
501
        return deleteDescription(dao.load(descriptionUuid));
502
    }
503

    
504

    
505
    @Override
506
    public TermVocabulary<Feature> getFeatureVocabulary(UUID uuid) {
507
        return vocabularyDao.findByUuid(uuid);
508
    }
509

    
510
    @Override
511
    @Deprecated
512
    public <T extends DescriptionElementBase> List<T> getDescriptionElementsForTaxon(
513
            Taxon taxon, Set<Feature> features,
514
            Class<T> type, Integer pageSize,
515
            Integer pageNumber, List<String> propertyPaths) {
516
        return listDescriptionElementsForTaxon(taxon, features, type, pageSize, pageNumber, propertyPaths);
517
    }
518

    
519
    @Override
520
    public <T extends DescriptionElementBase> List<T> listDescriptionElementsForTaxon(
521
            Taxon taxon, Set<Feature> features,
522
            Class<T> type, Integer pageSize,
523
            Integer pageNumber, List<String> propertyPaths) {
524
        return dao.getDescriptionElementForTaxon(taxon.getUuid(), features, type, pageSize, pageNumber, propertyPaths);
525
    }
526

    
527
    @Override
528
    public <T extends DescriptionElementBase> Pager<T> pageDescriptionElementsForTaxon(
529
            Taxon taxon, Set<Feature> features,
530
            Class<T> type, Integer pageSize,
531
            Integer pageNumber, List<String> propertyPaths) {
532
        if (logger.isDebugEnabled()){logger.debug(" get count ...");}
533
        Long count = dao.countDescriptionElementForTaxon(taxon.getUuid(), features, type);
534
        List<T> descriptionElements;
535
        if(AbstractPagerImpl.hasResultsInRange(count, pageNumber, pageSize)){ // no point checking again
536
            if (logger.isDebugEnabled()){logger.debug(" get list ...");}
537
            descriptionElements = listDescriptionElementsForTaxon(taxon, features, type, pageSize, pageNumber, propertyPaths);
538
        } else {
539
            descriptionElements = new ArrayList<T>(0);
540
        }
541
        if (logger.isDebugEnabled()){logger.debug(" service - DONE ...");}
542
        return new DefaultPagerImpl<T>(pageNumber, count.intValue(), pageSize, descriptionElements);
543
    }
544

    
545

    
546
    /* (non-Javadoc)
547
     * @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)
548
     */
549
    @Override
550
    public String generateNaturalLanguageDescription(FeatureTree featureTree,
551
            TaxonDescription description, List<Language> preferredLanguages, String separator) {
552

    
553
        Language lang = preferredLanguages.size() > 0 ? preferredLanguages.get(0) : Language.DEFAULT();
554

    
555
        description = (TaxonDescription)load(description.getUuid());
556
        featureTree = featureTreeDao.load(featureTree.getUuid());
557

    
558
        StringBuilder naturalLanguageDescription = new StringBuilder();
559

    
560
        MarkerType useMarkerType = (MarkerType) definedTermDao.load(UUID.fromString("2e6e42d9-e92a-41f4-899b-03c0ac64f039"));
561
        boolean isUseDescription = false;
562
        if(!description.getMarkers().isEmpty()) {
563
            for (Marker marker: description.getMarkers()) {
564
                MarkerType markerType = marker.getMarkerType();
565
                if (markerType.equals(useMarkerType)) {
566
                    isUseDescription = true;
567
                }
568

    
569
            }
570
        }
571

    
572
        if(description.hasStructuredData() && !isUseDescription){
573

    
574

    
575
            String lastCategory = null;
576
            String categorySeparator = ". ";
577

    
578
            List<TextData> textDataList;
579
            TextData naturalLanguageDescriptionText = null;
580

    
581
            boolean useMicroFormatQuantitativeDescriptionBuilder = false;
582

    
583
            if(useMicroFormatQuantitativeDescriptionBuilder){
584

    
585
                MicroFormatQuantitativeDescriptionBuilder micro = new MicroFormatQuantitativeDescriptionBuilder();
586
                naturalLanguageGenerator.setQuantitativeDescriptionBuilder(micro);
587
                naturalLanguageDescriptionText = naturalLanguageGenerator.generateSingleTextData(featureTree, (description), lang);
588

    
589
            } else {
590

    
591
                naturalLanguageDescriptionText = naturalLanguageGenerator.generateSingleTextData(
592
                        featureTree,
593
                        (description),
594
                        lang);
595
            }
596

    
597
            return naturalLanguageDescriptionText.getText(lang);
598

    
599
//
600
//			boolean doItBetter = false;
601
//
602
//			for (TextData textData : textDataList.toArray(new TextData[textDataList.size()])){
603
//				if(textData.getMultilanguageText().size() > 0){
604
//
605
//					if (!textData.getFeature().equals(Feature.UNKNOWN())) {
606
//						String featureLabel = textData.getFeature().getLabel(lang);
607
//
608
//						if(doItBetter){
609
//							/*
610
//							 *  WARNING
611
//							 *  The code lines below are desinged to handle
612
//							 *  a special case where as the feature label contains
613
//							 *  hierarchical information on the features. This code
614
//							 *  exist only as a base for discussion, and is not
615
//							 *  intendet to be used in production.
616
//							 */
617
//							featureLabel = StringUtils.remove(featureLabel, '>');
618
//
619
//							String[] labelTokens = StringUtils.split(featureLabel, '<');
620
//							if(labelTokens[0].equals(lastCategory) && labelTokens.length > 1){
621
//								if(naturalLanguageDescription.length() > 0){
622
//									naturalLanguageDescription.append(separator);
623
//								}
624
//								naturalLanguageDescription.append(labelTokens[1]);
625
//							} else {
626
//								if(naturalLanguageDescription.length() > 0){
627
//									naturalLanguageDescription.append(categorySeparator);
628
//								}
629
//								naturalLanguageDescription.append(StringUtils.join(labelTokens));
630
//							}
631
//							lastCategory = labelTokens[0];
632
//							// end of demo code
633
//						} else {
634
//							if(naturalLanguageDescription.length() > 0){
635
//								naturalLanguageDescription.append(separator);
636
//							}
637
//							naturalLanguageDescription.append(textData.getFeature().getLabel(lang));
638
//						}
639
//					} else {
640
//						if(naturalLanguageDescription.length() > 0){
641
//							naturalLanguageDescription.append(separator);
642
//						}
643
//					}
644
//					String text = textData.getMultilanguageText().values().iterator().next().getText();
645
//					naturalLanguageDescription.append(text);
646
//
647
//				}
648
//			}
649

    
650
        }
651
        else if (isUseDescription) {
652
            //AT: Left Blank in case we need to generate a Natural language text string.
653
        }
654
        return naturalLanguageDescription.toString();
655
    }
656

    
657

    
658
    @Override
659
    public boolean hasStructuredData(DescriptionBase<?> description) {
660
        return load(description.getUuid()).hasStructuredData();
661
    }
662

    
663

    
664
    @Override
665
    public void moveDescriptionElementsToDescription(
666
            Collection<DescriptionElementBase> descriptionElements,
667
            DescriptionBase targetDescription,
668
            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
                throw new RuntimeException ("Clone not yet implemented for class " + element.getClass().getName(), e);
687
            }
688
            if (! isCopy){
689
                description.removeElement(element);
690
                dao.saveOrUpdate(description);
691
            }
692

    
693
        }
694
        dao.saveOrUpdate(targetDescription);
695

    
696
    }
697

    
698
    @Override
699
    public Pager<TermDto> pageNamedAreasInUse(boolean includeAllParents, Integer pageSize,
700
            Integer pageNumber){
701
        List<TermDto> results = dao.listNamedAreasInUse(includeAllParents, null, null);
702
        int startIndex= pageNumber * pageSize;
703
        int toIndex = Math.min(startIndex + pageSize, results.size());
704
        List<TermDto> page = results.subList(startIndex, toIndex);
705
        return new DefaultPagerImpl<TermDto>(pageNumber, results.size(), pageSize, page);
706
    }
707

    
708

    
709
    @Override
710
    @Transactional(readOnly = false)
711
    public UpdateResult moveTaxonDescriptions(Taxon sourceTaxon, Taxon targetTaxon) {
712
        List<TaxonDescription> descriptions = new ArrayList(sourceTaxon.getDescriptions());
713
        UpdateResult result = new UpdateResult();
714
        result.addUpdatedObject(sourceTaxon);
715
        result.addUpdatedObject(targetTaxon);
716
        for(TaxonDescription description : descriptions){
717

    
718
            String moveMessage = String.format("Description moved from %s", sourceTaxon);
719
            if(description.isProtectedTitleCache()){
720
                String separator = "";
721
                if(!StringUtils.isBlank(description.getTitleCache())){
722
                    separator = " - ";
723
                }
724
                description.setTitleCache(description.getTitleCache() + separator + moveMessage, true);
725
            }
726
            Annotation annotation = Annotation.NewInstance(moveMessage, Language.getDefaultLanguage());
727
            annotation.setAnnotationType(AnnotationType.TECHNICAL());
728
            description.addAnnotation(annotation);
729
            targetTaxon.addDescription(description);
730
        }
731
        return result;
732
    }
733

    
734
    @Override
735
    @Transactional(readOnly = false)
736
    public UpdateResult moveTaxonDescriptions(UUID sourceTaxonUuid, UUID targetTaxonUuid) {
737
        Taxon sourceTaxon = HibernateProxyHelper.deproxy(taxonDao.load(sourceTaxonUuid), Taxon.class);
738
        Taxon targetTaxon = HibernateProxyHelper.deproxy(taxonDao.load(targetTaxonUuid), Taxon.class);
739
        return moveTaxonDescriptions(sourceTaxon, targetTaxon);
740

    
741
    }
742

    
743

    
744

    
745
}
(16-16/92)