Project

General

Profile

Download (15 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.net.URI;
14
import java.util.ArrayList;
15
import java.util.Collection;
16
import java.util.Enumeration;
17
import java.util.HashSet;
18
import java.util.List;
19
import java.util.Locale;
20
import java.util.Set;
21
import java.util.UUID;
22

    
23
import org.apache.commons.lang.StringUtils;
24
import org.apache.log4j.Logger;
25
import org.springframework.beans.factory.annotation.Autowired;
26
import org.springframework.beans.factory.annotation.Qualifier;
27
import org.springframework.stereotype.Service;
28
import org.springframework.transaction.annotation.Transactional;
29

    
30
import eu.etaxonomy.cdm.api.service.UpdateResult.Status;
31
import eu.etaxonomy.cdm.api.service.config.TermDeletionConfigurator;
32
import eu.etaxonomy.cdm.api.service.exception.DataChangeNoRollbackException;
33
import eu.etaxonomy.cdm.api.service.pager.Pager;
34
import eu.etaxonomy.cdm.api.service.pager.impl.DefaultPagerImpl;
35
import eu.etaxonomy.cdm.common.monitor.IProgressMonitor;
36
import eu.etaxonomy.cdm.model.common.CdmBase;
37
import eu.etaxonomy.cdm.model.common.DefinedTermBase;
38
import eu.etaxonomy.cdm.model.common.Language;
39
import eu.etaxonomy.cdm.model.common.LanguageString;
40
import eu.etaxonomy.cdm.model.common.LanguageStringBase;
41
import eu.etaxonomy.cdm.model.common.Representation;
42
import eu.etaxonomy.cdm.model.common.TermType;
43
import eu.etaxonomy.cdm.model.common.TermVocabulary;
44
import eu.etaxonomy.cdm.model.location.NamedArea;
45
import eu.etaxonomy.cdm.model.location.NamedAreaLevel;
46
import eu.etaxonomy.cdm.model.location.NamedAreaType;
47
import eu.etaxonomy.cdm.model.media.Media;
48
import eu.etaxonomy.cdm.persistence.dao.common.IDefinedTermDao;
49
import eu.etaxonomy.cdm.persistence.dao.common.ILanguageStringBaseDao;
50
import eu.etaxonomy.cdm.persistence.dao.common.ILanguageStringDao;
51
import eu.etaxonomy.cdm.persistence.dao.common.IRepresentationDao;
52
import eu.etaxonomy.cdm.persistence.query.OrderHint;
53
import eu.etaxonomy.cdm.strategy.cache.common.IIdentifiableEntityCacheStrategy;
54

    
55
@Service
56
@Transactional(readOnly = true)
57
public class TermServiceImpl extends IdentifiableServiceBase<DefinedTermBase,IDefinedTermDao> implements ITermService{
58
	@SuppressWarnings("unused")
59
	private static final Logger logger = Logger.getLogger(TermServiceImpl.class);
60

    
61
	private ILanguageStringDao languageStringDao;
62

    
63
	@Autowired
64
	@Qualifier("langStrBaseDao")
65
	private ILanguageStringBaseDao languageStringBaseDao;
66
	private IRepresentationDao representationDao;
67

    
68
	@Autowired
69
	public void setLanguageStringDao(ILanguageStringDao languageStringDao) {
70
		this.languageStringDao = languageStringDao;
71
	}
72

    
73
	@Autowired
74
	public void setRepresentationDao(IRepresentationDao representationDao) {
75
		this.representationDao = representationDao;
76
	}
77

    
78
	@Override
79
    @Autowired
80
	protected void setDao(IDefinedTermDao dao) {
81
		this.dao = dao;
82
	}
83

    
84
	/* (non-Javadoc)
85
	 * @see eu.etaxonomy.cdm.api.service.ITermService#listByTermType(eu.etaxonomy.cdm.model.common.TermType, java.lang.Integer, java.lang.Integer, java.util.List, java.util.List)
86
	 */
87
	@Override
88
	public List<DefinedTermBase<?>> listByTermType(TermType termType, Integer limit, Integer start,
89
	        List<OrderHint> orderHints, List<String> propertyPaths) {
90
	    return dao.listByTermType(termType, limit, start, orderHints, propertyPaths);
91
	}
92

    
93
	@Override
94
	public DefinedTermBase getByUri(URI uri) {
95
		return dao.findByUri(uri);
96
	}
97

    
98
	@Override
99
	public Language getLanguageByIso(String iso639) {
100
	    return dao.getLanguageByIso(iso639);
101
	}
102

    
103
	@Override
104
	public Language getLanguageByLabel(String label) {
105
	    return Language.getLanguageByLabel(label);
106
	}
107

    
108
	@Override
109
	public List<Language> getLanguagesByLocale(Enumeration<Locale> locales){
110
		return dao.getLanguagesByLocale(locales);
111
	}
112

    
113
	@Override
114
    public <TERM extends DefinedTermBase> TERM findByIdInVocabulary(String id, UUID vocabularyUuid, Class<TERM> clazz) throws IllegalArgumentException {
115
        List<TERM> list = dao.getDefinedTermByIdInVocabulary(id, vocabularyUuid, clazz, null, null);
116
		if (list.isEmpty()){
117
			return null;
118
		}else if (list.size() == 1){
119
			return list.get(0);
120
		}else{
121
			String message = "There is more then 1 (%d) term with the same id in vocabulary. This is forbidden. Check the state of your database.";
122
			throw new IllegalStateException(String.format(message, list.size()));
123
		}
124
	}
125

    
126

    
127
	@Override
128
	public NamedArea getAreaByTdwgAbbreviation(String tdwgAbbreviation) {
129
		if (StringUtils.isBlank(tdwgAbbreviation)){ //TDWG areas should always have a label
130
			return null;
131
		}
132
		List<NamedArea> list = dao.getDefinedTermByIdInVocabulary(tdwgAbbreviation, NamedArea.uuidTdwgAreaVocabulary, NamedArea.class, null, null);
133
		if (list.isEmpty()){
134
			return null;
135
		}else if (list.size() == 1){
136
			return list.get(0);
137
		}else{
138
			String message = "There is more then 1 (%d) TDWG area with the same abbreviated label. This is forbidden. Check the state of your database.";
139
			throw new IllegalStateException(String.format(message, list.size()));
140
		}
141

    
142
	}
143

    
144
	@Override
145
	public <T extends DefinedTermBase> Pager<T> getGeneralizationOf(T definedTerm, Integer pageSize, Integer pageNumber) {
146
        Integer numberOfResults = dao.countGeneralizationOf(definedTerm);
147

    
148
		List<T> results = new ArrayList<T>();
149
		if(numberOfResults > 0) { // no point checking again  //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
150
			results = dao.getGeneralizationOf(definedTerm, pageSize, pageNumber);
151
		}
152

    
153
		return new DefaultPagerImpl<T>(pageNumber, numberOfResults, pageSize, results);
154
	}
155

    
156
	@Override
157
	public <T extends DefinedTermBase> Pager<T> getIncludes(Collection<T> definedTerms, Integer pageSize, Integer pageNumber, List<String> propertyPaths) {
158
        Integer numberOfResults = dao.countIncludes(definedTerms);
159

    
160
		List<T> results = new ArrayList<T>();
161
		if(numberOfResults > 0) { // no point checking again  //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
162
			results = dao.getIncludes(definedTerms, pageSize, pageNumber,propertyPaths);
163
		}
164

    
165
		return new DefaultPagerImpl<T>(pageNumber, numberOfResults, pageSize, results);
166
	}
167

    
168
	@Override
169
	public Pager<Media> getMedia(DefinedTermBase definedTerm, Integer pageSize,	Integer pageNumber) {
170
        Integer numberOfResults = dao.countMedia(definedTerm);
171

    
172
		List<Media> results = new ArrayList<Media>();
173
		if(numberOfResults > 0) { // no point checking again  //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
174
			results = dao.getMedia(definedTerm, pageSize, pageNumber);
175
		}
176

    
177
		return new DefaultPagerImpl<Media>(pageNumber, numberOfResults, pageSize, results);
178
	}
179

    
180
	@Override
181
	public <T extends DefinedTermBase> Pager<T> getPartOf(Set<T> definedTerms,Integer pageSize, Integer pageNumber, List<String> propertyPaths) {
182
        Integer numberOfResults = dao.countPartOf(definedTerms);
183

    
184
		List<T> results = new ArrayList<T>();
185
		if(numberOfResults > 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
186
			results = dao.getPartOf(definedTerms, pageSize, pageNumber, propertyPaths);
187
		}
188

    
189
		return new DefaultPagerImpl<T>(pageNumber, numberOfResults, pageSize, results);
190
	}
191

    
192
	@Override
193
	public Pager<NamedArea> list(NamedAreaLevel level, NamedAreaType type, Integer pageSize, Integer pageNumber,
194
			List<OrderHint> orderHints, List<String> propertyPaths) {
195
		Integer numberOfResults = dao.count(level, type);
196

    
197
		List<NamedArea> results = new ArrayList<NamedArea>();
198
		if (numberOfResults > 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
199
			results = dao.list(level, type, pageSize, pageNumber, orderHints, propertyPaths);
200
		}
201

    
202
		return new DefaultPagerImpl<NamedArea>(pageNumber, numberOfResults, pageSize, results);
203
	}
204

    
205
	@Override
206
	public <T extends DefinedTermBase> Pager<T> findByRepresentationText(String label, Class<T> clazz, Integer pageSize, Integer pageNumber) {
207
        Integer numberOfResults = dao.countDefinedTermByRepresentationText(label,clazz);
208

    
209
		List<T> results = new ArrayList<T>();
210
		if(numberOfResults > 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
211
			results = dao.getDefinedTermByRepresentationText(label, clazz, pageSize, pageNumber);
212
		}
213

    
214
		return new DefaultPagerImpl<T>(pageNumber, numberOfResults, pageSize, results);
215
	}
216

    
217
	@Override
218
	public <T extends DefinedTermBase> Pager<T> findByRepresentationAbbreviation(String abbrev, Class<T> clazz, Integer pageSize, Integer pageNumber) {
219
        Integer numberOfResults = dao.countDefinedTermByRepresentationAbbrev(abbrev,clazz);
220

    
221
		List<T> results = new ArrayList<T>();
222
		if(numberOfResults > 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
223
			results = dao.getDefinedTermByRepresentationAbbrev(abbrev, clazz, pageSize, pageNumber);
224
		}
225

    
226
		return new DefaultPagerImpl<T>(pageNumber, numberOfResults, pageSize, results);
227
	}
228

    
229
	@Override
230
	public List<LanguageString> getAllLanguageStrings(int limit, int start) {
231
		return languageStringDao.list(limit, start);
232
	}
233

    
234
	@Override
235
	public List<Representation> getAllRepresentations(int limit, int start) {
236
		return representationDao.list(limit,start);
237
	}
238

    
239
	@Override
240
	public UUID saveLanguageData(LanguageStringBase languageData) {
241
		return languageStringBaseDao.save(languageData).getUuid();
242
	}
243

    
244
	/* (non-Javadoc)
245
	 * @see eu.etaxonomy.cdm.api.service.ServiceBase#delete(eu.etaxonomy.cdm.model.common.CdmBase)
246
	 */
247
	/** @deprecated use {@link #delete(DefinedTermBase, TermDeletionConfigurator)} instead
248
	 * to allow DeleteResult return type*/
249
	@Override
250
	@Deprecated
251
	public DeleteResult delete(DefinedTermBase term){
252
		DeleteResult result = new DeleteResult();
253

    
254
		TermDeletionConfigurator defaultConfig = new TermDeletionConfigurator();
255
		result = delete(term, defaultConfig);
256
		return result;
257
	}
258

    
259
	@Override
260
	@Deprecated
261
	@Transactional(readOnly = false)
262
	public DeleteResult delete(UUID termUuid){
263
	    DeleteResult result = new DeleteResult();
264

    
265
	    TermDeletionConfigurator defaultConfig = new TermDeletionConfigurator();
266
	    result = delete(dao.load(termUuid), defaultConfig);
267
	    return result;
268
	}
269

    
270
	@Override
271
	public DeleteResult delete(DefinedTermBase term, TermDeletionConfigurator config){
272
		if (config == null){
273
			config = new TermDeletionConfigurator();
274
		}
275
//		boolean isInternal = config.isInternal();
276
		DeleteResult result = new DeleteResult();
277
		Set<DefinedTermBase> termsToSave = new HashSet<DefinedTermBase>();
278
		CdmBase.deproxy(dao.merge(term), DefinedTermBase.class);
279

    
280
		try {
281
			//generalization of
282
			Set<DefinedTermBase> specificTerms = term.getGeneralizationOf();
283
			if (specificTerms.size()>0){
284
				if (config.isDeleteGeneralizationOfRelations()){
285
					DefinedTermBase generalTerm = term.getKindOf();
286
					for (DefinedTermBase specificTerm: specificTerms){
287
						term.removeGeneralization(specificTerm);
288
						if (generalTerm != null){
289
							generalTerm.addGeneralizationOf(specificTerm);
290
							termsToSave.add(generalTerm);
291
						}
292
					}
293
				}else{
294
					//TODO Exception type
295
					String message = "This term has specifing terms. Move or delete specifiing terms prior to delete or change delete configuration.";
296
					result.addRelatedObjects(specificTerms);
297
					result.setAbort();
298
					Exception ex = new DataChangeNoRollbackException(message);
299
					result.addException(ex);
300
				}
301
			}
302

    
303
			//kind of
304
			DefinedTermBase generalTerm = term.getKindOf();
305
			if (generalTerm != null){
306
				if (config.isDeleteKindOfRelations()){
307
					generalTerm.removeGeneralization(term);
308
				}else{
309
					//TODO Exception type
310
					String message = "This term is kind of another term. Move or delete kind of relationship prior to delete or change delete configuration.";
311
					result.addRelatedObject(generalTerm);
312
					result.setAbort();
313
					DataChangeNoRollbackException ex = new DataChangeNoRollbackException(message);
314
					result.addException(ex);
315
					throw ex;
316
				}
317
			}
318

    
319
			//part of
320
			DefinedTermBase parentTerm = term.getPartOf();
321
			if (parentTerm != null){
322
				if (! config.isDeletePartOfRelations()){
323
					//TODO Exception type
324
					String message = "This term is included in another term. Remove from parent term prior to delete or change delete configuration.";
325
					result.addRelatedObject(parentTerm);
326
					result.setAbort();
327
					DataChangeNoRollbackException ex = new DataChangeNoRollbackException(message);
328
					result.addException(ex);
329
				}
330
			}
331

    
332

    
333
			//included in
334
			Set<DefinedTermBase> includedTerms = term.getIncludes();
335
			if (includedTerms.size()> 0){
336
//				if (config.isDeleteIncludedTerms()){
337
//					for (DefinedTermBase includedTerm: includedTerms){
338
//						config.setCheck(true);
339
//						DeleteResult includedResult = this.delete(includedTerm, config);
340
////						config.setCheck(isCheck);
341
//						result.includeResult(includedResult);
342
//					}
343
//				}else
344
					if (config.isDeleteIncludedRelations()){
345
					DefinedTermBase parent = term.getPartOf();
346
					for (DefinedTermBase includedTerm: includedTerms){
347
						term.removeIncludes(includedTerm);
348
						if (parent != null){
349
							parent.addIncludes(includedTerm);
350
							termsToSave.add(parent);
351
						}
352
					}
353
				}else{
354
					//TODO Exception type
355
					String message = "This term includes other terms. Move or delete included terms prior to delete or change delete configuration.";
356
					result.addRelatedObjects(includedTerms);
357
					result.setAbort();
358
					Exception ex = new DataChangeNoRollbackException(message);
359
					result.addException(ex);
360
				}
361
			}
362

    
363
			//part of
364
			if (parentTerm != null){
365
				if (config.isDeletePartOfRelations()){
366
					parentTerm.removeIncludes(term);
367
					termsToSave.add(parentTerm);
368
				}else{
369
					//handelede before "included in"
370
				}
371
			}
372

    
373
//			relatedObjects;
374

    
375

    
376
			if (result.isOk()){
377
				TermVocabulary voc = term.getVocabulary();
378
				if (voc!= null){
379
					voc.removeTerm(term);
380
				}
381
				//TODO save voc
382
				if (true /*!config.isInternal()*/){
383
					dao.delete(term);
384
					dao.saveOrUpdateAll(termsToSave);
385
//					for (DeleteResult.PersistPair persistPair : result.getObjectsToDelete()){
386
//						persistPair.dao.delete(persistPair.objectToPersist);
387
//					}
388
//					for (DeleteResult.PersistPair persistPair : result.getObjectsToSave()){
389
//						persistPair.dao.saveOrUpdate(persistPair.objectToPersist);
390
//					}
391

    
392
				}
393
			}
394
		} catch (DataChangeNoRollbackException e) {
395
			result.setStatus(Status.ERROR);
396
		}
397
		return result;
398
	}
399

    
400
	@Override
401
	@Transactional(readOnly = false)
402
	public DeleteResult delete(UUID termUuid, TermDeletionConfigurator config){
403
	    return delete(dao.load(termUuid), config);
404
	}
405

    
406
	@Override
407
	@Transactional(readOnly = false)
408
    public void updateTitleCache(Class<? extends DefinedTermBase> clazz, Integer stepSize, IIdentifiableEntityCacheStrategy<DefinedTermBase> cacheStrategy, IProgressMonitor monitor) {
409
		//TODO shouldnt this be TermBase instead of DefinedTermBase
410
		if (clazz == null){
411
			clazz = DefinedTermBase.class;
412
		}
413
		super.updateTitleCacheImpl(clazz, stepSize, cacheStrategy, monitor);
414
	}
415

    
416
}
(86-86/92)