Project

General

Profile

Download (14.4 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.DeleteResult.DeleteStatus;
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 List<Language> getLanguagesByLocale(Enumeration<Locale> locales){
105
		return dao.getLanguagesByLocale(locales);
106
	}
107

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

    
121

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

    
137
	}
138

    
139
	@Override
140
	public <T extends DefinedTermBase> Pager<T> getGeneralizationOf(T definedTerm, Integer pageSize, Integer pageNumber) {
141
        Integer numberOfResults = dao.countGeneralizationOf(definedTerm);
142

    
143
		List<T> results = new ArrayList<T>();
144
		if(numberOfResults > 0) { // no point checking again  //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
145
			results = dao.getGeneralizationOf(definedTerm, pageSize, pageNumber);
146
		}
147

    
148
		return new DefaultPagerImpl<T>(pageNumber, numberOfResults, pageSize, results);
149
	}
150

    
151
	@Override
152
	public <T extends DefinedTermBase> Pager<T> getIncludes(Collection<T> definedTerms, Integer pageSize, Integer pageNumber, List<String> propertyPaths) {
153
        Integer numberOfResults = dao.countIncludes(definedTerms);
154

    
155
		List<T> results = new ArrayList<T>();
156
		if(numberOfResults > 0) { // no point checking again  //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
157
			results = dao.getIncludes(definedTerms, pageSize, pageNumber,propertyPaths);
158
		}
159

    
160
		return new DefaultPagerImpl<T>(pageNumber, numberOfResults, pageSize, results);
161
	}
162

    
163
	@Override
164
	public Pager<Media> getMedia(DefinedTermBase definedTerm, Integer pageSize,	Integer pageNumber) {
165
        Integer numberOfResults = dao.countMedia(definedTerm);
166

    
167
		List<Media> results = new ArrayList<Media>();
168
		if(numberOfResults > 0) { // no point checking again  //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
169
			results = dao.getMedia(definedTerm, pageSize, pageNumber);
170
		}
171

    
172
		return new DefaultPagerImpl<Media>(pageNumber, numberOfResults, pageSize, results);
173
	}
174

    
175
	@Override
176
	public <T extends DefinedTermBase> Pager<T> getPartOf(Set<T> definedTerms,Integer pageSize, Integer pageNumber, List<String> propertyPaths) {
177
        Integer numberOfResults = dao.countPartOf(definedTerms);
178

    
179
		List<T> results = new ArrayList<T>();
180
		if(numberOfResults > 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
181
			results = dao.getPartOf(definedTerms, pageSize, pageNumber, propertyPaths);
182
		}
183

    
184
		return new DefaultPagerImpl<T>(pageNumber, numberOfResults, pageSize, results);
185
	}
186

    
187
	@Override
188
	public Pager<NamedArea> list(NamedAreaLevel level, NamedAreaType type, Integer pageSize, Integer pageNumber,
189
			List<OrderHint> orderHints, List<String> propertyPaths) {
190
		Integer numberOfResults = dao.count(level, type);
191

    
192
		List<NamedArea> results = new ArrayList<NamedArea>();
193
		if (numberOfResults > 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
194
			results = dao.list(level, type, pageSize, pageNumber, orderHints, propertyPaths);
195
		}
196

    
197
		return new DefaultPagerImpl<NamedArea>(pageNumber, numberOfResults, pageSize, results);
198
	}
199

    
200
	@Override
201
	public <T extends DefinedTermBase> Pager<T> findByRepresentationText(String label, Class<T> clazz, Integer pageSize, Integer pageNumber) {
202
        Integer numberOfResults = dao.countDefinedTermByRepresentationText(label,clazz);
203

    
204
		List<T> results = new ArrayList<T>();
205
		if(numberOfResults > 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
206
			results = dao.getDefinedTermByRepresentationText(label, clazz, pageSize, pageNumber);
207
		}
208

    
209
		return new DefaultPagerImpl<T>(pageNumber, numberOfResults, pageSize, results);
210
	}
211

    
212
	@Override
213
	public <T extends DefinedTermBase> Pager<T> findByRepresentationAbbreviation(String abbrev, Class<T> clazz, Integer pageSize, Integer pageNumber) {
214
        Integer numberOfResults = dao.countDefinedTermByRepresentationAbbrev(abbrev,clazz);
215

    
216
		List<T> results = new ArrayList<T>();
217
		if(numberOfResults > 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
218
			results = dao.getDefinedTermByRepresentationAbbrev(abbrev, clazz, pageSize, pageNumber);
219
		}
220

    
221
		return new DefaultPagerImpl<T>(pageNumber, numberOfResults, pageSize, results);
222
	}
223

    
224
	@Override
225
	public List<LanguageString> getAllLanguageStrings(int limit, int start) {
226
		return languageStringDao.list(limit, start);
227
	}
228

    
229
	@Override
230
	public List<Representation> getAllRepresentations(int limit, int start) {
231
		return representationDao.list(limit,start);
232
	}
233

    
234
	@Override
235
	public UUID saveLanguageData(LanguageStringBase languageData) {
236
		return languageStringBaseDao.save(languageData);
237
	}
238

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

    
249
		TermDeletionConfigurator defaultConfig = new TermDeletionConfigurator();
250
		result = delete(term, defaultConfig);
251
		return result;
252
	}
253

    
254
	@Override
255
	public DeleteResult delete(DefinedTermBase term, TermDeletionConfigurator config){
256
		if (config == null){
257
			config = new TermDeletionConfigurator();
258
		}
259
//		boolean isInternal = config.isInternal();
260
		DeleteResult result = new DeleteResult();
261
		Set<DefinedTermBase> termsToSave = new HashSet<DefinedTermBase>();
262
		CdmBase.deproxy(dao.merge(term), DefinedTermBase.class);
263

    
264
		try {
265
			//generalization of
266
			Set<DefinedTermBase> specificTerms = term.getGeneralizationOf();
267
			if (specificTerms.size()>0){
268
				if (config.isDeleteGeneralizationOfRelations()){
269
					DefinedTermBase generalTerm = term.getKindOf();
270
					for (DefinedTermBase specificTerm: specificTerms){
271
						term.removeGeneralization(specificTerm);
272
						if (generalTerm != null){
273
							generalTerm.addGeneralizationOf(specificTerm);
274
							termsToSave.add(generalTerm);
275
						}
276
					}
277
				}else{
278
					//TODO Exception type
279
					String message = "This term has specifing terms. Move or delete specifiing terms prior to delete or change delete configuration.";
280
					result.addRelatedObjects(specificTerms);
281
					result.setAbort();
282
					Exception ex = new DataChangeNoRollbackException(message);
283
					result.addException(ex);
284
				}
285
			}
286

    
287
			//kind of
288
			DefinedTermBase generalTerm = term.getKindOf();
289
			if (generalTerm != null){
290
				if (config.isDeleteKindOfRelations()){
291
					generalTerm.removeGeneralization(term);
292
				}else{
293
					//TODO Exception type
294
					String message = "This term is kind of another term. Move or delete kind of relationship prior to delete or change delete configuration.";
295
					result.addRelatedObject(generalTerm);
296
					result.setAbort();
297
					DataChangeNoRollbackException ex = new DataChangeNoRollbackException(message);
298
					result.addException(ex);
299
					throw ex;
300
				}
301
			}
302

    
303
			//part of
304
			DefinedTermBase parentTerm = term.getPartOf();
305
			if (parentTerm != null){
306
				if (! config.isDeletePartOfRelations()){
307
					//TODO Exception type
308
					String message = "This term is included in another term. Remove from parent term prior to delete or change delete configuration.";
309
					result.addRelatedObject(parentTerm);
310
					result.setAbort();
311
					DataChangeNoRollbackException ex = new DataChangeNoRollbackException(message);
312
					result.addException(ex);
313
				}
314
			}
315

    
316

    
317
			//included in
318
			Set<DefinedTermBase> includedTerms = term.getIncludes();
319
			if (includedTerms.size()> 0){
320
//				if (config.isDeleteIncludedTerms()){
321
//					for (DefinedTermBase includedTerm: includedTerms){
322
//						config.setCheck(true);
323
//						DeleteResult includedResult = this.delete(includedTerm, config);
324
////						config.setCheck(isCheck);
325
//						result.includeResult(includedResult);
326
//					}
327
//				}else
328
					if (config.isDeleteIncludedRelations()){
329
					DefinedTermBase parent = term.getPartOf();
330
					for (DefinedTermBase includedTerm: includedTerms){
331
						term.removeIncludes(includedTerm);
332
						if (parent != null){
333
							parent.addIncludes(includedTerm);
334
							termsToSave.add(parent);
335
						}
336
					}
337
				}else{
338
					//TODO Exception type
339
					String message = "This term includes other terms. Move or delete included terms prior to delete or change delete configuration.";
340
					result.addRelatedObjects(includedTerms);
341
					result.setAbort();
342
					Exception ex = new DataChangeNoRollbackException(message);
343
					result.addException(ex);
344
				}
345
			}
346

    
347
			//part of
348
			if (parentTerm != null){
349
				if (config.isDeletePartOfRelations()){
350
					parentTerm.removeIncludes(term);
351
					termsToSave.add(parentTerm);
352
				}else{
353
					//handelede before "included in"
354
				}
355
			}
356

    
357
//			relatedObjects;
358

    
359

    
360
			if (result.isOk()){
361
				TermVocabulary voc = term.getVocabulary();
362
				if (voc!= null){
363
					voc.removeTerm(term);
364
				}
365
				//TODO save voc
366
				if (true /*!config.isInternal()*/){
367
					dao.delete(term);
368
					dao.saveOrUpdateAll(termsToSave);
369
//					for (DeleteResult.PersistPair persistPair : result.getObjectsToDelete()){
370
//						persistPair.dao.delete(persistPair.objectToPersist);
371
//					}
372
//					for (DeleteResult.PersistPair persistPair : result.getObjectsToSave()){
373
//						persistPair.dao.saveOrUpdate(persistPair.objectToPersist);
374
//					}
375

    
376
				}
377
			}
378
		} catch (DataChangeNoRollbackException e) {
379
			result.setStatus(DeleteStatus.ERROR);
380
		}
381
		return result;
382
	}
383

    
384
	@Override
385
	@Transactional(readOnly = false)
386
    public void updateTitleCache(Class<? extends DefinedTermBase> clazz, Integer stepSize, IIdentifiableEntityCacheStrategy<DefinedTermBase> cacheStrategy, IProgressMonitor monitor) {
387
		//TODO shouldnt this be TermBase instead of DefinedTermBase
388
		if (clazz == null){
389
			clazz = DefinedTermBase.class;
390
		}
391
		super.updateTitleCacheImpl(clazz, stepSize, cacheStrategy, monitor);
392
	}
393

    
394
}
(80-80/84)