Project

General

Profile

Download (20.1 KB) Statistics
| Branch: | Tag: | Revision:
1 2ce08010 Andreas Kohlbecker
// $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 2cf910bc Andreas Müller
import java.util.HashSet;
16 2ce08010 Andreas Kohlbecker
import java.util.List;
17
import java.util.Map;
18
import java.util.Set;
19
import java.util.UUID;
20
21
import org.apache.log4j.Logger;
22
import org.springframework.beans.factory.annotation.Autowired;
23
import org.springframework.stereotype.Service;
24
import org.springframework.transaction.annotation.Propagation;
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.DefaultPagerImpl;
29 f197a589 Andreas Müller
import eu.etaxonomy.cdm.common.IProgressMonitor;
30 2ce08010 Andreas Kohlbecker
import eu.etaxonomy.cdm.model.common.Annotation;
31
import eu.etaxonomy.cdm.model.common.Language;
32
import eu.etaxonomy.cdm.model.common.MarkerType;
33
import eu.etaxonomy.cdm.model.common.TermVocabulary;
34
import eu.etaxonomy.cdm.model.description.DescriptionBase;
35
import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
36
import eu.etaxonomy.cdm.model.description.Distribution;
37
import eu.etaxonomy.cdm.model.description.Feature;
38
import eu.etaxonomy.cdm.model.description.FeatureTree;
39
import eu.etaxonomy.cdm.model.description.PresenceAbsenceTermBase;
40
import eu.etaxonomy.cdm.model.description.Scope;
41
import eu.etaxonomy.cdm.model.description.TaxonDescription;
42
import eu.etaxonomy.cdm.model.description.TaxonNameDescription;
43
import eu.etaxonomy.cdm.model.description.TextData;
44
import eu.etaxonomy.cdm.model.location.NamedArea;
45
import eu.etaxonomy.cdm.model.location.NamedAreaLevel;
46
import eu.etaxonomy.cdm.model.media.Media;
47
import eu.etaxonomy.cdm.model.name.TaxonNameBase;
48
import eu.etaxonomy.cdm.model.taxon.Taxon;
49
import eu.etaxonomy.cdm.persistence.dao.common.ITermVocabularyDao;
50
import eu.etaxonomy.cdm.persistence.dao.description.IDescriptionDao;
51
import eu.etaxonomy.cdm.persistence.dao.description.IDescriptionElementDao;
52
import eu.etaxonomy.cdm.persistence.dao.description.IFeatureDao;
53
import eu.etaxonomy.cdm.persistence.dao.description.IFeatureNodeDao;
54
import eu.etaxonomy.cdm.persistence.dao.description.IFeatureTreeDao;
55
import eu.etaxonomy.cdm.persistence.dao.description.IStatisticalMeasurementValueDao;
56
import eu.etaxonomy.cdm.persistence.query.OrderHint;
57 f197a589 Andreas Müller
import eu.etaxonomy.cdm.strategy.cache.common.IIdentifiableEntityCacheStrategy;
58 2ce08010 Andreas Kohlbecker
59
/**
60
 * @author a.mueller
61
 * @created 24.06.2008
62
 * @version 1.0
63
 */
64
@Service
65
@Transactional(readOnly = true, propagation = Propagation.SUPPORTS)
66
public class DescriptionServiceImpl extends IdentifiableServiceBase<DescriptionBase,IDescriptionDao> implements IDescriptionService {
67
 	
68
	private static final Logger logger = Logger.getLogger(DescriptionServiceImpl.class);
69
70
	protected IDescriptionElementDao descriptionElementDao;
71
	protected IFeatureTreeDao featureTreeDao;
72
	protected IFeatureNodeDao featureNodeDao;
73
	protected IFeatureDao featureDao;
74
	protected ITermVocabularyDao vocabularyDao;
75
	protected IStatisticalMeasurementValueDao statisticalMeasurementValueDao;
76 76de813f Andreas Kohlbecker
	//TODO change to Interface
77 65c22e25 Andreas Kohlbecker
	private NaturalLanguageGenerator naturalLanguageGenerator;
78 2ce08010 Andreas Kohlbecker
	
79
	@Autowired
80
	protected void setFeatureTreeDao(IFeatureTreeDao featureTreeDao) {
81
		this.featureTreeDao = featureTreeDao;
82
	}
83
	
84
	@Autowired
85
	protected void setFeatureNodeDao(IFeatureNodeDao featureNodeDao) {
86
		this.featureNodeDao = featureNodeDao;
87
	}
88
	
89
	@Autowired
90
	protected void setFeatureDao(IFeatureDao featureDao) {
91
		this.featureDao = featureDao;
92
	}
93
	
94
	@Autowired
95
	protected void setVocabularyDao(ITermVocabularyDao vocabularyDao) {
96
		this.vocabularyDao = vocabularyDao;
97
	}
98
	
99
	@Autowired
100
	protected void statisticalMeasurementValueDao(IStatisticalMeasurementValueDao statisticalMeasurementValueDao) {
101
		this.statisticalMeasurementValueDao = statisticalMeasurementValueDao;
102
	}
103
	
104
	@Autowired
105
	protected void setDescriptionElementDao(IDescriptionElementDao descriptionElementDao) {
106
		this.descriptionElementDao = descriptionElementDao;
107
	}
108
	
109
	@Autowired
110 65c22e25 Andreas Kohlbecker
	protected void setNaturalLanguageGenerator(NaturalLanguageGenerator naturalLanguageGenerator) {
111 2ce08010 Andreas Kohlbecker
		this.naturalLanguageGenerator = naturalLanguageGenerator;
112
	}
113
	
114
	/**
115
	 * 
116
	 */
117
	public DescriptionServiceImpl() {
118
		logger.debug("Load DescriptionService Bean");
119
	}
120
	
121 f197a589 Andreas Müller
	
122
123 2ce08010 Andreas Kohlbecker
	/* (non-Javadoc)
124 f197a589 Andreas Müller
	 * @see eu.etaxonomy.cdm.api.service.IIdentifiableEntityService#updateTitleCache(java.lang.Integer, eu.etaxonomy.cdm.strategy.cache.common.IIdentifiableEntityCacheStrategy)
125 2ce08010 Andreas Kohlbecker
	 */
126 b17d9121 Andreas Müller
	@Override
127 f197a589 Andreas Müller
	public void updateTitleCache(Class<? extends DescriptionBase> clazz, Integer stepSize, IIdentifiableEntityCacheStrategy<DescriptionBase> cacheStrategy, IProgressMonitor monitor) {
128
		if (clazz == null){
129
			clazz = DescriptionBase.class;
130
		}
131
		super.updateTitleCacheImpl(clazz, stepSize, cacheStrategy, monitor);
132 2ce08010 Andreas Kohlbecker
	}
133 f197a589 Andreas Müller
134 b17d9121 Andreas Müller
	
135 2ce08010 Andreas Kohlbecker
	public TermVocabulary<Feature> getDefaultFeatureVocabulary(){
136
		String uuidFeature = "b187d555-f06f-4d65-9e53-da7c93f8eaa8";
137
		UUID featureUuid = UUID.fromString(uuidFeature);
138
		return (TermVocabulary)vocabularyDao.findByUuid(featureUuid);
139
	}
140
141
	@Autowired
142
	protected void setDao(IDescriptionDao dao) {
143
		this.dao = dao;
144
	}
145
146
	public int count(Class<? extends DescriptionBase> type, Boolean hasImages, Boolean hasText,Set<Feature> feature) {
147
		return dao.countDescriptions(type, hasImages, hasText, feature);
148
	}
149
150
	/**
151
	 * FIXME Candidate for harmonization
152
	 * rename -> getElements
153
	 */
154
	public Pager<DescriptionElementBase> getDescriptionElements(DescriptionBase description,
155
			Set<Feature> features, Class<? extends DescriptionElementBase> type, Integer pageSize, Integer pageNumber, List<String> propertyPaths) {
156
157
		List<DescriptionElementBase> results = listDescriptionElements(description, features, type, pageSize, pageNumber, propertyPaths);
158
		return new DefaultPagerImpl<DescriptionElementBase>(pageNumber, results.size(), pageSize, results);
159
	}
160
161
	public List<DescriptionElementBase> listDescriptionElements(DescriptionBase description,
162
			Set<Feature> features, Class<? extends DescriptionElementBase> type, Integer pageSize, Integer pageNumber, List<String> propertyPaths) {
163
		Integer numberOfResults = dao.countDescriptionElements(description, features, type);
164
		
165
		List<DescriptionElementBase> results = new ArrayList<DescriptionElementBase>();
166 76de813f Andreas Kohlbecker
		if(numberOfResults > 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
167 2ce08010 Andreas Kohlbecker
			results = dao.getDescriptionElements(description, features, type, pageSize, pageNumber, propertyPaths);
168
		}
169
		return results;
170
	}
171 242af8f3 Andreas Kohlbecker
	
172 2ce08010 Andreas Kohlbecker
	public Pager<Annotation> getDescriptionElementAnnotations(DescriptionElementBase annotatedObj, MarkerType status, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths){
173
		Integer numberOfResults = descriptionElementDao.countAnnotations(annotatedObj, status);
174
		
175
		List<Annotation> results = new ArrayList<Annotation>();
176 76de813f Andreas Kohlbecker
		if(numberOfResults > 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
177 2ce08010 Andreas Kohlbecker
			results = descriptionElementDao.getAnnotations(annotatedObj, status, pageSize, pageNumber, orderHints, propertyPaths); 
178
		}
179
		
180
		return new DefaultPagerImpl<Annotation>(pageNumber, numberOfResults, pageSize, results);
181
	}
182
	
183
	
184
185
	public Pager<Media> getMedia(DescriptionElementBase descriptionElement,	Integer pageSize, Integer pageNumber, List<String> propertyPaths) {
186
        Integer numberOfResults = descriptionElementDao.countMedia(descriptionElement);
187
		
188
		List<Media> results = new ArrayList<Media>();
189 76de813f Andreas Kohlbecker
		if(numberOfResults > 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
190 2ce08010 Andreas Kohlbecker
			results = descriptionElementDao.getMedia(descriptionElement, pageSize, pageNumber, propertyPaths); 
191
		}
192
		
193
		return new DefaultPagerImpl<Media>(pageNumber, numberOfResults, pageSize, results);
194
	}
195
196
	public Pager<TaxonDescription> getTaxonDescriptions(Taxon taxon, Set<Scope> scopes, Set<NamedArea> geographicalScope, Integer pageSize, Integer pageNumber, List<String> propertyPaths) {
197
        Integer numberOfResults = dao.countTaxonDescriptions(taxon, scopes, geographicalScope);
198
		
199
		List<TaxonDescription> results = new ArrayList<TaxonDescription>();
200 76de813f Andreas Kohlbecker
		if(numberOfResults > 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
201 2ce08010 Andreas Kohlbecker
			results = dao.getTaxonDescriptions(taxon, scopes, geographicalScope, pageSize, pageNumber, propertyPaths); 
202
		}
203
		
204
		return new DefaultPagerImpl<TaxonDescription>(pageNumber, numberOfResults, pageSize, results);
205
	}
206
	
207 ae1f3e69 n.hoffmann
	public List<TaxonDescription> listTaxonDescriptions(Taxon taxon, Set<Scope> scopes, Set<NamedArea> geographicalScope, Integer pageSize, Integer pageNumber, List<String> propertyPaths) {
208
		List<TaxonDescription> results = dao.getTaxonDescriptions(taxon, scopes, geographicalScope, pageSize, pageNumber, propertyPaths);
209
		return results;
210
	}
211
	
212 2c9de4b9 n.hoffmann
	public DistributionTree getOrderedDistributions(
213 2ce08010 Andreas Kohlbecker
			Set<TaxonDescription> taxonDescriptions,
214 5afc1134 f.revilla
			Set<NamedAreaLevel> omitLevels,
215
			List<String> propertyPaths){
216 2ce08010 Andreas Kohlbecker
		
217
		DistributionTree tree = new DistributionTree();
218
		List<Distribution> distList = new ArrayList<Distribution>();
219
		
220
		for (TaxonDescription taxonDescription : taxonDescriptions) {
221 5afc1134 f.revilla
			taxonDescription = (TaxonDescription) dao.load(taxonDescription.getUuid(), propertyPaths);
222 2ce08010 Andreas Kohlbecker
			Set<DescriptionElementBase> elements = taxonDescription.getElements();
223
			for (DescriptionElementBase element : elements) {
224 04b43757 f.revilla
					if (element.isInstanceOf(Distribution.class)) {
225
						Distribution distribution = (Distribution) element;
226
						if(distribution.getArea() != null){
227
							distList.add(distribution);							
228
						}
229
					}
230 2ce08010 Andreas Kohlbecker
			}
231
		}
232
		
233
		//ordering the areas
234
		tree.merge(distList, omitLevels);
235
		tree.sortChildren();
236
		return tree;
237
	}
238
239
	public Pager<TaxonNameDescription> getTaxonNameDescriptions(TaxonNameBase name, Integer pageSize, Integer pageNumber, List<String> propertyPaths) {
240
        Integer numberOfResults = dao.countTaxonNameDescriptions(name);
241
		
242
		List<TaxonNameDescription> results = new ArrayList<TaxonNameDescription>();
243 76de813f Andreas Kohlbecker
		if(numberOfResults > 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
244 2ce08010 Andreas Kohlbecker
			results = dao.getTaxonNameDescriptions(name, pageSize, pageNumber,propertyPaths); 
245
		}
246
		
247
		return new DefaultPagerImpl<TaxonNameDescription>(pageNumber, numberOfResults, pageSize, results);
248
	}
249
250
	
251
	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) {
252
        Integer numberOfResults = dao.countDescriptions(type, hasImages, hasText, feature);
253
		
254
		List<DescriptionBase> results = new ArrayList<DescriptionBase>();
255 76de813f Andreas Kohlbecker
		if(numberOfResults > 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
256 2ce08010 Andreas Kohlbecker
			results = dao.listDescriptions(type, hasImages, hasText, feature, pageSize, pageNumber,orderHints,propertyPaths); 
257
		}
258
		
259
		return new DefaultPagerImpl<DescriptionBase>(pageNumber, numberOfResults, pageSize, results);
260
	}
261
262
	/**
263
	 * FIXME Candidate for harmonization
264
	 * Rename: searchByDistribution
265
	 */
266
	public Pager<TaxonDescription> searchDescriptionByDistribution(Set<NamedArea> namedAreas, PresenceAbsenceTermBase presence,	Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {
267
        Integer numberOfResults = dao.countDescriptionByDistribution(namedAreas, presence);
268
		
269
		List<TaxonDescription> results = new ArrayList<TaxonDescription>();
270 76de813f Andreas Kohlbecker
		if(numberOfResults > 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
271 2ce08010 Andreas Kohlbecker
			results = dao.searchDescriptionByDistribution(namedAreas, presence, pageSize, pageNumber,orderHints,propertyPaths); 
272
		}
273
		
274
		return new DefaultPagerImpl<TaxonDescription>(pageNumber, numberOfResults, pageSize, results);
275
	}
276
277
	/**
278
	 * FIXME Candidate for harmonization
279
	 * move: descriptionElementService.search
280
	 */
281
	public Pager<DescriptionElementBase> searchElements(Class<? extends DescriptionElementBase> clazz, String queryString, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {
282
        Integer numberOfResults = descriptionElementDao.count(clazz,queryString);
283
		
284
		List<DescriptionElementBase> results = new ArrayList<DescriptionElementBase>();
285 76de813f Andreas Kohlbecker
		if(numberOfResults > 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
286 2ce08010 Andreas Kohlbecker
			results = descriptionElementDao.search(clazz, queryString, pageSize, pageNumber, orderHints, propertyPaths); 
287
		}
288
		
289
		return new DefaultPagerImpl<DescriptionElementBase>(pageNumber, numberOfResults, pageSize, results);
290
	}
291
292
	/**
293
	 * FIXME Candidate for harmonization
294
	 * descriptionElementService.find
295
	 */
296
	public DescriptionElementBase getDescriptionElementByUuid(UUID uuid) {
297
		return descriptionElementDao.findByUuid(uuid);
298
	}	
299
	
300
	/**
301
	 * FIXME Candidate for harmonization
302
	 * descriptionElementService.load
303
	 */
304
	public DescriptionElementBase loadDescriptionElement(UUID uuid,	List<String> propertyPaths) {
305
		return descriptionElementDao.load(uuid, propertyPaths);
306
	}
307
308
    /**
309
     * FIXME Candidate for harmonization
310
     * descriptionElementService.save
311
     */
312
	@Transactional(readOnly = false)
313
	public UUID saveDescriptionElement(DescriptionElementBase descriptionElement) {
314
		return descriptionElementDao.save(descriptionElement);
315
	}
316
	
317
    /**
318
     * FIXME Candidate for harmonization
319
     * descriptionElementService.save
320
     */
321
	@Transactional(readOnly = false)
322
	public Map<UUID, DescriptionElementBase> saveDescriptionElement(Collection<DescriptionElementBase> descriptionElements) {
323
		return descriptionElementDao.saveAll(descriptionElements);
324
	}
325
326
    /**
327
     * FIXME Candidate for harmonization
328
     * descriptionElementService.delete
329
     */
330
	public UUID deleteDescriptionElement(DescriptionElementBase descriptionElement) {
331
		return descriptionElementDao.delete(descriptionElement);
332
	}
333
334
	public TermVocabulary<Feature> getFeatureVocabulary(UUID uuid) {
335
		return (TermVocabulary)vocabularyDao.findByUuid(uuid);
336
	}
337
338 2b8ca443 Andreas Müller
	public <T extends DescriptionElementBase> List<T> getDescriptionElementsForTaxon(
339 2ce08010 Andreas Kohlbecker
			Taxon taxon, Set<Feature> features,
340 2b8ca443 Andreas Müller
			Class<? extends T> type, Integer pageSize,
341 2ce08010 Andreas Kohlbecker
			Integer pageNumber, List<String> propertyPaths) {
342 c35c706e Andreas Kohlbecker
		//FIXME remove cast
343 2b8ca443 Andreas Müller
		return (List<T>) dao.getDescriptionElementForTaxon(taxon, features, type, pageSize, pageNumber, propertyPaths);
344 2ce08010 Andreas Kohlbecker
	}
345 ae1f3e69 n.hoffmann
	
346
	public List<DescriptionElementBase> getDescriptionElementsForTaxon(
347
			Taxon taxon, FeatureTree featureTree,
348
			Class<? extends DescriptionElementBase> type, Integer pageSize,
349
			Integer pageNumber, List<String> propertyPaths) {
350 c35c706e Andreas Kohlbecker
		 //FIXME remove cast
351
		 return (List<DescriptionElementBase>) dao.getDescriptionElementForTaxon(taxon, featureTree.getDistinctFeatures(), type, pageSize, pageNumber, propertyPaths);
352 ae1f3e69 n.hoffmann
	}
353 2ce08010 Andreas Kohlbecker
354
	/* (non-Javadoc)
355
	 * @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)
356
	 */
357
	@Override
358
	public String generateNaturalLanguageDescription(FeatureTree featureTree,
359
			TaxonDescription description, List<Language> preferredLanguages, String separator) {
360
		
361
		Language lang = preferredLanguages.size() > 0 ? preferredLanguages.get(0) : Language.DEFAULT();
362
		
363
		description = (TaxonDescription)load(description.getUuid());
364
		featureTree = featureTreeDao.load(featureTree.getUuid());
365
		
366
		StringBuilder naturalLanguageDescription = new StringBuilder();
367
		
368
		if(description.hasStructuredData()){
369
			
370
			
371
			String lastCategory = null;
372 afb3ded4 Andreas Kohlbecker
			String categorySeparator = ". ";
373 2ce08010 Andreas Kohlbecker
			
374 65c22e25 Andreas Kohlbecker
			List<TextData> textDataList;
375 76de813f Andreas Kohlbecker
			TextData naturalLanguageDescriptionText = null;
376 cbe73bd6 Andreas Kohlbecker
			
377 b8740066 Andreas Kohlbecker
			boolean useMicroFormatQuantitativeDescriptionBuilder = false;
378 65c22e25 Andreas Kohlbecker
			
379
			if(useMicroFormatQuantitativeDescriptionBuilder){
380
				
381
				MicroFormatQuantitativeDescriptionBuilder micro = new MicroFormatQuantitativeDescriptionBuilder();
382
				naturalLanguageGenerator.setQuantitativeDescriptionBuilder(micro);
383 76de813f Andreas Kohlbecker
				naturalLanguageDescriptionText = naturalLanguageGenerator.generateSingleTextData(featureTree, ((TaxonDescription)description), lang);
384 65c22e25 Andreas Kohlbecker
					
385
			} else {
386 3cbf3cb7 Andreas Müller
				
387 76de813f Andreas Kohlbecker
				naturalLanguageDescriptionText = naturalLanguageGenerator.generateSingleTextData(
388
						featureTree, 
389
						((TaxonDescription)description),
390
						lang);				
391 65c22e25 Andreas Kohlbecker
			}
392
393 76de813f Andreas Kohlbecker
			return naturalLanguageDescriptionText.getText(lang);
394 b8740066 Andreas Kohlbecker
			
395
//			
396
//			boolean doItBetter = false;
397
//
398
//			for (TextData textData : textDataList.toArray(new TextData[textDataList.size()])){
399
//				if(textData.getMultilanguageText().size() > 0){
400
//					
401
//					if (!textData.getFeature().equals(Feature.UNKNOWN())) {
402
//						String featureLabel = textData.getFeature().getLabel(lang);
403
//
404
//						if(doItBetter){
405
//							/*
406
//							 *  WARNING
407
//							 *  The code lines below are desinged to handle
408
//							 *  a special case where as the feature label contains 
409
//							 *  hierarchical information on the features. This code 
410
//							 *  exist only as a base for discussion, and is not 
411
//							 *  intendet to be used in production.
412
//							 */
413
//							featureLabel = StringUtils.remove(featureLabel, '>');
414
//							
415
//							String[] labelTokens = StringUtils.split(featureLabel, '<');
416
//							if(labelTokens[0].equals(lastCategory) && labelTokens.length > 1){
417
//								if(naturalLanguageDescription.length() > 0){
418
//									naturalLanguageDescription.append(separator);
419
//								}
420
//								naturalLanguageDescription.append(labelTokens[1]);
421
//							} else {
422
//								if(naturalLanguageDescription.length() > 0){
423
//									naturalLanguageDescription.append(categorySeparator);
424
//								}
425
//								naturalLanguageDescription.append(StringUtils.join(labelTokens));
426
//							}
427
//							lastCategory = labelTokens[0];
428
//							// end of demo code
429
//						} else {
430
//							if(naturalLanguageDescription.length() > 0){
431
//								naturalLanguageDescription.append(separator);
432
//							}
433
//							naturalLanguageDescription.append(textData.getFeature().getLabel(lang));							
434
//						}
435
//					} else {
436
//						if(naturalLanguageDescription.length() > 0){
437
//							naturalLanguageDescription.append(separator);
438
//						}
439
//					}
440
//					String text = textData.getMultilanguageText().values().iterator().next().getText();
441
//					naturalLanguageDescription.append(text);		
442
//					
443
//				}
444
//			}
445 2ce08010 Andreas Kohlbecker
		
446
		}
447
		return naturalLanguageDescription.toString();
448
	}
449
450
	/* (non-Javadoc)
451
	 * @see eu.etaxonomy.cdm.api.service.IDescriptionService#hasStructuredData(eu.etaxonomy.cdm.model.description.DescriptionBase)
452
	 */
453
	@Override
454
	public boolean hasStructuredData(DescriptionBase<?> description) {
455
		return load(description.getUuid()).hasStructuredData();
456
	}
457 fcdd5642 n.hoffmann
458 abcb1ed4 Andreas Müller
459 fcdd5642 n.hoffmann
	/* (non-Javadoc)
460 abcb1ed4 Andreas Müller
	 * @see eu.etaxonomy.cdm.api.service.IDescriptionService#moveDescriptionElementsToDescription(java.util.Collection, eu.etaxonomy.cdm.model.description.DescriptionBase, boolean)
461 fcdd5642 n.hoffmann
	 */
462
	@Override
463 a883c19f Andreas Müller
	public void moveDescriptionElementsToDescription(Collection<DescriptionElementBase> descriptionElements,
464 32ffb67d Andreas Müller
													DescriptionBase targetDescription, boolean isCopy) {
465 583c8fcf n.hoffmann
		
466 2cf910bc Andreas Müller
		if (descriptionElements.isEmpty() ){
467
			return ;
468
		}
469
470
		if (! isCopy && descriptionElements == descriptionElements.iterator().next().getInDescription().getElements()){
471
			//if the descriptionElements collection is the elements set of a description, put it in a separate set before to avoid concurrent modification exceptions
472
			descriptionElements = new HashSet<DescriptionElementBase>(descriptionElements);
473
//			descriptionElementsTmp.addAll(descriptionElements);
474
//			descriptionElements = descriptionElementsTmp;
475
		}
476 583c8fcf n.hoffmann
		for (DescriptionElementBase element : descriptionElements){
477
			DescriptionBase description = element.getInDescription();
478
			try {
479
				DescriptionElementBase newElement = (DescriptionElementBase)element.clone();
480
				targetDescription.addElement(newElement);	
481
			} catch (CloneNotSupportedException e) {
482
				new RuntimeException ("Clone not yet implemented for class " + element.getClass().getName(), e);
483
			}
484 32ffb67d Andreas Müller
			if (! isCopy){
485 583c8fcf n.hoffmann
				description.removeElement(element);
486 1071a451 Andreas Müller
			}
487 583c8fcf n.hoffmann
			
488 a883c19f Andreas Müller
		}
489 fcdd5642 n.hoffmann
	}
490
491 2ce08010 Andreas Kohlbecker
}