Project

General

Profile

Download (25.7 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2007 EDIT
3
* European Distributed Institute of Taxonomy
4
* http://www.e-taxonomy.eu
5
*
6
* The contents of this file are subject to the Mozilla Public License Version 1.1
7
* See LICENSE.TXT at the top of this package for the full license terms.
8
*/
9
package eu.etaxonomy.cdm.api.service;
10

    
11
import java.util.ArrayList;
12
import java.util.Collection;
13
import java.util.Enumeration;
14
import java.util.HashMap;
15
import java.util.HashSet;
16
import java.util.List;
17
import java.util.Locale;
18
import java.util.Map;
19
import java.util.Set;
20
import java.util.UUID;
21

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

    
29
import eu.etaxonomy.cdm.api.service.UpdateResult.Status;
30
import eu.etaxonomy.cdm.api.service.config.DeleteConfiguratorBase;
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.exception.ReferencedObjectUndeletableException;
34
import eu.etaxonomy.cdm.api.service.pager.Pager;
35
import eu.etaxonomy.cdm.api.service.pager.impl.DefaultPagerImpl;
36
import eu.etaxonomy.cdm.common.URI;
37
import eu.etaxonomy.cdm.common.monitor.IProgressMonitor;
38
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
39
import eu.etaxonomy.cdm.model.common.CdmBase;
40
import eu.etaxonomy.cdm.model.common.Language;
41
import eu.etaxonomy.cdm.model.common.LanguageString;
42
import eu.etaxonomy.cdm.model.common.LanguageStringBase;
43
import eu.etaxonomy.cdm.model.location.Country;
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.model.metadata.TermSearchField;
49
import eu.etaxonomy.cdm.model.term.DefinedTermBase;
50
import eu.etaxonomy.cdm.model.term.OrderedTermBase;
51
import eu.etaxonomy.cdm.model.term.OrderedTermVocabulary;
52
import eu.etaxonomy.cdm.model.term.Representation;
53
import eu.etaxonomy.cdm.model.term.TermType;
54
import eu.etaxonomy.cdm.model.term.TermVocabulary;
55
import eu.etaxonomy.cdm.persistence.dao.common.ILanguageStringBaseDao;
56
import eu.etaxonomy.cdm.persistence.dao.common.ILanguageStringDao;
57
import eu.etaxonomy.cdm.persistence.dao.term.IDefinedTermDao;
58
import eu.etaxonomy.cdm.persistence.dao.term.IRepresentationDao;
59
import eu.etaxonomy.cdm.persistence.dto.TermDto;
60
import eu.etaxonomy.cdm.persistence.dto.UuidAndTitleCache;
61
import eu.etaxonomy.cdm.persistence.query.OrderHint;
62
import eu.etaxonomy.cdm.strategy.cache.common.IIdentifiableEntityCacheStrategy;
63

    
64
@Service
65
@Transactional(readOnly = true)
66
public class TermServiceImpl
67
            extends IdentifiableServiceBase<DefinedTermBase,IDefinedTermDao>
68
            implements ITermService{
69

    
70
    @SuppressWarnings("unused")
71
	private static final Logger logger = LogManager.getLogger(TermServiceImpl.class);
72

    
73
	private ILanguageStringDao languageStringDao;
74

    
75
	@Autowired
76
	private IVocabularyService vocabularyService;
77

    
78
	@Autowired
79
	@Qualifier("langStrBaseDao")
80
	private ILanguageStringBaseDao languageStringBaseDao;
81
	private IRepresentationDao representationDao;
82

    
83
	@Autowired
84
	public void setLanguageStringDao(ILanguageStringDao languageStringDao) {
85
		this.languageStringDao = languageStringDao;
86
	}
87

    
88
	@Autowired
89
	public void setRepresentationDao(IRepresentationDao representationDao) {
90
		this.representationDao = representationDao;
91
	}
92

    
93
	@Override
94
    @Autowired
95
	protected void setDao(IDefinedTermDao dao) {
96
		this.dao = dao;
97
	}
98

    
99
	@Override
100
	public <T extends DefinedTermBase> List<T> listByTermType(TermType termType, Integer limit, Integer start,
101
	        List<OrderHint> orderHints, List<String> propertyPaths) {
102
	    return dao.listByTermType(termType, limit, start, orderHints, propertyPaths);
103
	}
104

    
105
	@Override
106
	public DefinedTermBase getByUri(URI uri) {
107
		return dao.findByUri(uri);
108
	}
109

    
110
	@Override
111
	public Language getLanguageByIso(String iso639) {
112
	    return dao.getLanguageByIso(iso639);
113
	}
114

    
115
	@Override
116
	public Language getLanguageByLabel(String label) {
117
	    return Language.getLanguageByLabel(label);
118
	}
119

    
120
	@Override
121
	public List<Language> getLanguagesByLocale(Enumeration<Locale> locales){
122
		return dao.getLanguagesByLocale(locales);
123
	}
124

    
125
	@Override
126
    public <TERM extends DefinedTermBase> TERM findByIdInVocabulary(String id, UUID vocabularyUuid, Class<TERM> clazz) throws IllegalArgumentException {
127
        List<TERM> list = dao.getDefinedTermByIdInVocabulary(id, vocabularyUuid, clazz, 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) term with the same id in vocabulary. 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 NamedArea getAreaByTdwgAbbreviation(String tdwgAbbreviation) {
141
		if (StringUtils.isBlank(tdwgAbbreviation)){ //TDWG areas should always have a label
142
			return null;
143
		}
144
		List<NamedArea> list = dao.getDefinedTermByIdInVocabulary(tdwgAbbreviation, NamedArea.uuidTdwgAreaVocabulary, NamedArea.class, null, null);
145
		if (list.isEmpty()){
146
			return null;
147
		}else if (list.size() == 1){
148
			return list.get(0);
149
		}else{
150
			String message = "There is more then 1 (%d) TDWG area with the same abbreviated label. This is forbidden. Check the state of your database.";
151
			throw new IllegalStateException(String.format(message, list.size()));
152
		}
153
	}
154

    
155
	@Override
156
	public <T extends DefinedTermBase> Pager<T> getGeneralizationOf(T definedTerm, Integer pageSize, Integer pageNumber) {
157
        long numberOfResults = dao.countGeneralizationOf(definedTerm);
158

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

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

    
167
	@Override
168
	public <T extends DefinedTermBase> Pager<T> getIncludes(Collection<T> definedTerms, Integer pageSize, Integer pageNumber, List<String> propertyPaths) {
169
        long numberOfResults = dao.countIncludes(definedTerms);
170

    
171
		List<T> results = new ArrayList<>();
172
		if(numberOfResults > 0) { // no point checking again  //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
173
			results = dao.getIncludes(definedTerms, pageSize, pageNumber,propertyPaths);
174
		}
175

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

    
179
	@Override
180
	public Pager<Media> getMedia(DefinedTermBase definedTerm, Integer pageSize,	Integer pageNumber) {
181
        long numberOfResults = dao.countMedia(definedTerm);
182

    
183
		List<Media> results = new ArrayList<>();
184
		if(numberOfResults > 0) { // no point checking again  //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
185
			results = dao.getMedia(definedTerm, pageSize, pageNumber);
186
		}
187

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

    
191
	@Override
192
	public <T extends DefinedTermBase> Pager<T> getPartOf(Set<T> definedTerms,Integer pageSize, Integer pageNumber, List<String> propertyPaths) {
193
        long numberOfResults = dao.countPartOf(definedTerms);
194

    
195
		List<T> results = new ArrayList<>();
196
		if(numberOfResults > 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
197
			results = dao.getPartOf(definedTerms, pageSize, pageNumber, propertyPaths);
198
		}
199

    
200
		return new DefaultPagerImpl<>(pageNumber, numberOfResults, pageSize, results);
201
	}
202

    
203
	@Override
204
	public Pager<NamedArea> list(NamedAreaLevel level, NamedAreaType type, Integer pageSize, Integer pageNumber,
205
			List<OrderHint> orderHints, List<String> propertyPaths) {
206
		long numberOfResults = dao.count(level, type);
207

    
208
		List<NamedArea> results = new ArrayList<>();
209
		if (numberOfResults > 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
210
			results = dao.list(level, type, pageSize, pageNumber, orderHints, propertyPaths);
211
		}
212

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

    
216
	@Override
217
	public <T extends DefinedTermBase> Pager<T> findByRepresentationText(String label, Class<T> clazz, Integer pageSize, Integer pageNumber) {
218
        long numberOfResults = dao.countDefinedTermByRepresentationText(label,clazz);
219

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

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

    
228
	@Override
229
	public <T extends DefinedTermBase> Pager<T> findByRepresentationAbbreviation(String abbrev, Class<T> clazz, Integer pageSize, Integer pageNumber) {
230
        long numberOfResults = dao.countDefinedTermByRepresentationAbbrev(abbrev,clazz);
231

    
232
		List<T> results = new ArrayList<>();
233
		if(numberOfResults > 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
234
			results = dao.getDefinedTermByRepresentationAbbrev(abbrev, clazz, pageSize, pageNumber);
235
		}
236

    
237
		return new DefaultPagerImpl<T>(pageNumber, numberOfResults, pageSize, results);
238
	}
239

    
240
	@Override
241
	public List<LanguageString> getAllLanguageStrings(int limit, int start) {
242
		return languageStringDao.list(limit, start);
243
	}
244

    
245
	@Override
246
	public List<Representation> getAllRepresentations(int limit, int start) {
247
		return representationDao.list(limit,start);
248
	}
249

    
250
	@Override
251
	public UUID saveLanguageData(LanguageStringBase languageData) {
252
		return languageStringBaseDao.save(languageData).getUuid();
253
	}
254

    
255

    
256
	/** @deprecated use {@link #delete(DefinedTermBase, TermDeletionConfigurator)} instead
257
	 * to allow DeleteResult return type*/
258
	@Override
259
	@Deprecated
260
	public DeleteResult delete(DefinedTermBase term){
261
		DeleteResult result = new DeleteResult();
262

    
263
		TermDeletionConfigurator defaultConfig = new TermDeletionConfigurator();
264
		result = delete(term, defaultConfig);
265
		return result;
266
	}
267

    
268
	@Override
269
	@Deprecated
270
	@Transactional(readOnly = false)
271
	public DeleteResult delete(UUID termUuid){
272
	    DeleteResult result = new DeleteResult();
273

    
274
	    TermDeletionConfigurator defaultConfig = new TermDeletionConfigurator();
275
	    result = delete(dao.load(termUuid), defaultConfig);
276
	    return result;
277
	}
278

    
279
	@Override
280
	public DeleteResult delete(DefinedTermBase term, TermDeletionConfigurator config){
281
		if (config == null){
282
			config = new TermDeletionConfigurator();
283
		}
284
		Set<DefinedTermBase> termsToSave = new HashSet<>();
285

    
286
		DeleteResult result = isDeletable(term.getUuid(), config);
287
		if (result.isAbort()) {
288
            return result;
289
        }
290
		//CdmBase.deproxy(dao.merge(term), DefinedTermBase.class);
291

    
292
		try {
293
			//generalization of
294
			Set<DefinedTermBase> specificTerms = term.getGeneralizationOf();
295
			if (specificTerms.size()>0){
296
				if (config.isDeleteGeneralizationOfRelations()){
297
					DefinedTermBase generalTerm = term.getKindOf();
298
					for (DefinedTermBase specificTerm: specificTerms){
299
						term.removeGeneralization(specificTerm);
300
						if (generalTerm != null){
301
							generalTerm.addGeneralizationOf(specificTerm);
302
							termsToSave.add(generalTerm);
303
						}
304
					}
305
				}else{
306
					//TODO Exception type
307
					String message = "This term has specifing terms. Move or delete specifiing terms prior to delete or change delete configuration.";
308
					result.addRelatedObjects(specificTerms);
309
					result.setAbort();
310
					Exception ex = new DataChangeNoRollbackException(message);
311
					result.addException(ex);
312
				}
313
			}
314

    
315
			//kind of
316
			DefinedTermBase generalTerm = term.getKindOf();
317
			if (generalTerm != null){
318
				if (config.isDeleteKindOfRelations()){
319
					generalTerm.removeGeneralization(term);
320
				}else{
321
					//TODO Exception type
322
					String message = "This term is kind of another term. Move or delete kind of relationship prior to delete or change delete configuration.";
323
					result.addRelatedObject(generalTerm);
324
					result.setAbort();
325
					DataChangeNoRollbackException ex = new DataChangeNoRollbackException(message);
326
					result.addException(ex);
327
					throw ex;
328
				}
329
			}
330

    
331
			//part of
332
			DefinedTermBase parentTerm = term.getPartOf();
333
			if (parentTerm != null){
334
				if (! config.isDeletePartOfRelations()){
335
					//TODO Exception type
336
					String message = "This term is included in another term. Remove from parent term prior to delete or change delete configuration.";
337
					result.addRelatedObject(parentTerm);
338
					result.setAbort();
339
					DataChangeNoRollbackException ex = new DataChangeNoRollbackException(message);
340
					result.addException(ex);
341
				}
342
			}
343

    
344

    
345
			//included in
346
			Set<DefinedTermBase> includedTerms = term.getIncludes();
347
			if (includedTerms.size()> 0){
348
			    if (config.isDeleteIncludedRelations()){
349
			        DefinedTermBase parent = term.getPartOf();
350
			        for (DefinedTermBase includedTerm: includedTerms){
351
			            term.removeIncludes(includedTerm);
352
			            if (parent != null){
353
			                parent.addIncludes(includedTerm);
354
			                termsToSave.add(parent);
355
			            }
356
			        }
357
			    }else{
358
			        //TODO Exception type
359
			        String message = "This term includes other terms. Move or delete included terms prior to delete or change delete configuration.";
360
			        result.addRelatedObjects(includedTerms);
361
			        result.setAbort();
362
			        Exception ex = new DataChangeNoRollbackException(message);
363
			        result.addException(ex);
364
			    }
365
			}
366

    
367
			//part of
368
			if (parentTerm != null){
369
			    if (config.isDeletePartOfRelations()){
370
			        parentTerm.removeIncludes(term);
371
			        termsToSave.add(parentTerm);
372
			    }else{
373
			        //handled before "included in"
374
			    }
375
			}
376

    
377
			if (result.isOk()){
378
				TermVocabulary voc = term.getVocabulary();
379
				if (voc!= null){
380
					voc.removeTerm(term);
381
				}
382
				//TODO save voc
383
				if (true){
384
					dao.delete(term);
385
					result.addDeletedObject(term);
386
					dao.saveOrUpdateAll(termsToSave);
387
				}
388
			}
389
		} catch (DataChangeNoRollbackException e) {
390
			result.setStatus(Status.ERROR);
391
		}
392
		return result;
393
	}
394

    
395
	@Override
396
	@Transactional(readOnly = false)
397
	public DeleteResult delete(UUID termUuid, TermDeletionConfigurator config){
398
	    return delete(dao.load(termUuid), config);
399
	}
400

    
401
	@Override
402
	@Transactional(readOnly = false)
403
    public UpdateResult updateCaches(Class<? extends DefinedTermBase> clazz, Integer stepSize, IIdentifiableEntityCacheStrategy<DefinedTermBase> cacheStrategy, IProgressMonitor monitor) {
404
		//TODO shouldn't this be TermBase instead of DefinedTermBase
405
		if (clazz == null){
406
			clazz = DefinedTermBase.class;
407
		}
408
		return super.updateCachesImpl(clazz, stepSize, cacheStrategy, monitor);
409
	}
410

    
411
	@Override
412
    public DeleteResult isDeletable(UUID termUuid, DeleteConfiguratorBase config){
413
	    TermDeletionConfigurator termConfig = null;
414
	    if(config instanceof TermDeletionConfigurator){
415
	        termConfig = (TermDeletionConfigurator) config;
416
	    }
417
	    DeleteResult result = new DeleteResult();
418
	    DefinedTermBase term = load(termUuid);
419
        Set<CdmBase> references = commonService.getReferencingObjectsForDeletion(term);
420

    
421
	    if(termConfig!=null){
422
	        //generalization of
423
	        Set<DefinedTermBase> specificTerms = term.getGeneralizationOf();
424
	        if (!specificTerms.isEmpty() && termConfig.isDeleteGeneralizationOfRelations()){
425
	            references.removeAll(specificTerms);
426
	        }
427
	        //kind of
428
	        DefinedTermBase generalTerm = term.getKindOf();
429
	        if (generalTerm != null && termConfig.isDeleteKindOfRelations()){
430
	            references.remove(generalTerm);
431
	        }
432
	        //part of
433
	        DefinedTermBase parentTerm = term.getPartOf();
434
	        if (parentTerm != null && termConfig.isDeletePartOfRelations()){
435
	            references.remove(parentTerm);
436
	        }
437
	        //included in
438
	        Set<DefinedTermBase> includedTerms = term.getIncludes();
439
	        if (!includedTerms.isEmpty() && termConfig.isDeleteIncludedRelations()){
440
	            references.removeAll(includedTerms);
441
	        }
442
	    }
443

    
444
	    //gather remaining referenced objects
445
        for (CdmBase relatedObject : references) {
446
            if(relatedObject instanceof TermVocabulary){
447
                continue;
448
            }
449
            result.getRelatedObjects().add(relatedObject);
450
            String message = "An object of " + relatedObject.getClass().getName() + " with ID " + relatedObject.getId() + " is referencing the object" ;
451
            result.addException(new ReferencedObjectUndeletableException(message));
452
            result.setAbort();
453
        }
454
        return result;
455
    }
456

    
457
    @Override
458
    @Transactional(readOnly = false)
459
    public Map<UUID, Representation> saveOrUpdateRepresentations(Collection<Representation> representations){
460
        return representationDao.saveOrUpdateAll(representations);
461
    }
462

    
463
    @Override
464
    @Transactional(readOnly = true)
465
    public List<UuidAndTitleCache<NamedArea>> getUuidAndTitleCacheNamedArea(List<TermVocabulary> vocs, Integer limit, String pattern, Language lang) {
466
        List<NamedArea> areas = dao.list(NamedArea.class, vocs, limit, pattern);
467

    
468
        List<UuidAndTitleCache<NamedArea>> result = new ArrayList<>();
469
        UuidAndTitleCache<NamedArea> uuidAndTitleCache;
470
        for (NamedArea area: areas){
471
            uuidAndTitleCache = new UuidAndTitleCache<>(area.getUuid(), area.getId(), NamedArea.labelWithLevel(area, lang));
472
            result.add(uuidAndTitleCache);
473
        }
474

    
475
        return result;
476
    }
477

    
478
    @Override
479
    @Transactional(readOnly = true)
480
    public List<UuidAndTitleCache<NamedArea>> getUuidAndTitleCacheNamedAreaByAbbrev(List<TermVocabulary> vocs, Integer limit, String pattern, Language lang, TermSearchField type) {
481
        List<NamedArea> areas = dao.listByAbbrev(NamedArea.class, vocs, limit, pattern, type);
482

    
483
        List<UuidAndTitleCache<NamedArea>> result = new ArrayList<>();
484
        UuidAndTitleCache<NamedArea> uuidAndTitleCache;
485
        for (NamedArea area: areas){
486
            if (type.equals(TermSearchField.NoAbbrev)){
487
                uuidAndTitleCache = new UuidAndTitleCache<>(area.getUuid(), area.getId(), area.labelWithLevel(area, lang));
488
            }else{
489
                String display = area.labelWithLevel(area, lang);
490
                if (type.equals(TermSearchField.IDInVocabulary)){
491
                    display += " - " + area.getIdInVocabulary();
492
                }else if (type.equals(TermSearchField.Symbol1)){
493
                    display += " - " + area.getSymbol();
494
                }else if (type.equals(TermSearchField.Symbol2)){
495
                    display += " - " + area.getSymbol2();
496
                }
497
                uuidAndTitleCache = new UuidAndTitleCache<>(area.getUuid(), area.getId(), display);
498
            }
499
            result.add(uuidAndTitleCache);
500
        }
501

    
502
        return result;
503
    }
504

    
505
    @Override
506
    public Collection<TermDto> getIncludesAsDto(
507
            TermDto parentTerm) {
508
        return dao.getIncludesAsDto(parentTerm);
509
    }
510

    
511
    @Override
512
    public Collection<TermDto> getKindOfsAsDto(
513
            TermDto parentTerm) {
514
        return dao.getKindOfsAsDto(parentTerm);
515
    }
516

    
517
    @Transactional(readOnly = false)
518
    @Override
519
    public UpdateResult moveTerm(TermDto termDto, UUID parentUUID) {
520
        return moveTerm(termDto, parentUUID, TermMovePosition.ON);
521
    }
522

    
523
    @SuppressWarnings({ "rawtypes", "unchecked" })
524
    @Transactional(readOnly = false)
525
    @Override
526
    public UpdateResult moveTerm(TermDto termDto, UUID parentUuid, TermMovePosition termMovePosition) {
527
        boolean isKindOf = termDto.getKindOfUuid()!=null && termDto.getKindOfUuid().equals(parentUuid);
528
        TermVocabulary vocabulary = HibernateProxyHelper.deproxy(vocabularyService.load(termDto.getVocabularyUuid()));
529
        DefinedTermBase parent = HibernateProxyHelper.deproxy(dao.load(parentUuid));
530
        UpdateResult result = new UpdateResult();
531
        if(parent==null){
532
            //new parent is a vocabulary
533
            TermVocabulary parentVocabulary = HibernateProxyHelper.deproxy(vocabularyService.load(parentUuid));
534
            DefinedTermBase term = HibernateProxyHelper.deproxy(dao.load(termDto.getUuid()));
535
            if(parentVocabulary!=null){
536
                term.setKindOf(null);
537
                term.setPartOf(null);
538

    
539
                vocabulary.removeTerm(term);
540
                parentVocabulary.addTerm(term);
541
                result.addUpdatedObject(term);
542
                result.addUpdatedObject(vocabulary);
543
                result.addUpdatedObject(parentVocabulary);
544

    
545
            }
546
            vocabularyService.saveOrUpdate(parentVocabulary);
547

    
548
        }
549
        else {
550
            DefinedTermBase term = HibernateProxyHelper.deproxy(dao.load(termDto.getUuid()));
551
            //new parent is a term
552
            if(parent.isInstanceOf(OrderedTermBase.class)
553
                    && term.isInstanceOf(OrderedTermBase.class)
554
                    && termMovePosition!=null
555
                    && HibernateProxyHelper.deproxy(parent, OrderedTermBase.class).getVocabulary().isInstanceOf(OrderedTermVocabulary.class)) {
556
                //new parent is an ordered term
557
                OrderedTermBase orderedTerm = HibernateProxyHelper.deproxy(term, OrderedTermBase.class);
558
                OrderedTermBase targetOrderedDefinedTerm = HibernateProxyHelper.deproxy(parent, OrderedTermBase.class);
559
                OrderedTermVocabulary otVoc = HibernateProxyHelper.deproxy(targetOrderedDefinedTerm.getVocabulary(), OrderedTermVocabulary.class);
560
                if(termMovePosition.equals(TermMovePosition.BEFORE)) {
561
                    orderedTerm.getVocabulary().removeTerm(orderedTerm);
562
                    otVoc.addTermAbove(orderedTerm, targetOrderedDefinedTerm);
563
                    if (targetOrderedDefinedTerm.getPartOf() != null){
564
                        targetOrderedDefinedTerm.getPartOf().addIncludes(orderedTerm);
565
                    }
566
                }
567
                else if(termMovePosition.equals(TermMovePosition.AFTER)) {
568
                    orderedTerm.getVocabulary().removeTerm(orderedTerm);
569
                    otVoc.addTermBelow(orderedTerm, targetOrderedDefinedTerm);
570
                    if (targetOrderedDefinedTerm.getPartOf() != null){
571
                        targetOrderedDefinedTerm.getPartOf().addIncludes(orderedTerm);
572
                    }
573
                }
574
                else if(termMovePosition.equals(TermMovePosition.ON)) {
575
                    orderedTerm.getVocabulary().removeTerm(orderedTerm);
576
                    targetOrderedDefinedTerm.addIncludes(orderedTerm);
577
                    targetOrderedDefinedTerm.getVocabulary().addTerm(orderedTerm);
578
                }
579
            }
580
            else{
581
                vocabulary.removeTerm(term);
582
                if(isKindOf){
583
                    parent.addGeneralizationOf(term);
584
                }
585
                else{
586
                    parent.addIncludes(term);
587
                }
588
                parent.getVocabulary().addTerm(term);
589
            }
590
            result.addUpdatedObject(term);
591
            result.addUpdatedObject(parent);
592
            result.addUpdatedObject(vocabulary);
593
            vocabularyService.saveOrUpdate(parent.getVocabulary());
594
        }
595
        return result;
596
    }
597

    
598
    @SuppressWarnings({ "rawtypes", "unchecked" })
599
    @Transactional(readOnly = false)
600
    @Override
601
    public TermDto addNewTerm(TermType termType, UUID parentUUID, boolean isKindOf, Language lang) {
602
        DefinedTermBase term = termType.getEmptyDefinedTermBase(lang);
603
        dao.save(term);
604
        DefinedTermBase parent = dao.load(parentUUID);
605
        if(isKindOf){
606
            parent.addGeneralizationOf(term);
607
        }
608
        else{
609
            parent.addIncludes(term);
610
        }
611
        parent.getVocabulary().addTerm(term);
612
        dao.saveOrUpdate(parent);
613
        return TermDto.fromTerm(term, true);
614
    }
615

    
616
    @Override
617
    public Collection<TermDto> findByTitleAsDtoWithVocDto(String title, TermType termType){
618
        return dao.findByTitleAsDtoWithVocDto(title, termType);
619
    }
620

    
621
    @Override
622
    public Collection<TermDto> findByUriAsDto(URI uri, String termLabel, TermType termType){
623
        return dao.findByUriAsDto(uri, termLabel, termType);
624
    }
625

    
626
    @Override
627
    public Collection<TermDto> findByUUIDsAsDto(List<UUID> uuidList){
628
        return dao.findByUUIDsAsDto(uuidList);
629
    }
630

    
631
    @Override
632
    public Collection<TermDto> findFeatureByUUIDsAsDto(List<UUID> uuidList){
633
        return dao.findFeatureByUUIDsAsDto(uuidList);
634
    }
635

    
636
    @Override
637
    public Map<UUID, TermDto> findFeatureByUUIDsAsDtos(List<UUID> uuidList){
638
        if (uuidList == null || uuidList.isEmpty()){
639
            return null;
640
        }
641
        Collection<TermDto> col = dao.findFeatureByUUIDsAsDto(uuidList);
642
        Map<UUID, TermDto> result = new HashMap<>();
643
        if (col != null){
644
            for (TermDto dto: col){
645
                result.put(dto.getUuid(), dto);
646
            }
647
        }
648
        return result;
649
    }
650

    
651

    
652
    @Override
653
    public Collection<TermDto> findFeatureByTitleAsDto(String title){
654
        return dao.findFeatureByTitleAsDto(title);
655
    }
656

    
657
    @Override
658
    public Country getCountryByIso(String iso639) {
659
        return this.dao.getCountryByIso(iso639);
660
    }
661

    
662
    @Override
663
    public List<Country> getCountryByName(String name) {
664
        List<? extends DefinedTermBase> terms = this.dao.findByTitleWithRestrictions(Country.class, name, null, null, null, null, null, null);
665
        List<Country> countries = new ArrayList<>();
666
        for (int i = 0; i < terms.size(); i++) {
667
            countries.add((Country) terms.get(i));
668
        }
669
        return countries;
670
    }
671

    
672

    
673
    public enum TermMovePosition{
674
        BEFORE,
675
        AFTER,
676
        ON
677
    }
678

    
679
}
(89-89/95)