Project

General

Profile

Download (25.2 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.HashSet;
15
import java.util.List;
16
import java.util.Locale;
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.beans.factory.annotation.Qualifier;
25
import org.springframework.stereotype.Service;
26
import org.springframework.transaction.annotation.Transactional;
27

    
28
import eu.etaxonomy.cdm.api.service.UpdateResult.Status;
29
import eu.etaxonomy.cdm.api.service.config.DeleteConfiguratorBase;
30
import eu.etaxonomy.cdm.api.service.config.TermDeletionConfigurator;
31
import eu.etaxonomy.cdm.api.service.exception.DataChangeNoRollbackException;
32
import eu.etaxonomy.cdm.api.service.exception.ReferencedObjectUndeletableException;
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.URI;
36
import eu.etaxonomy.cdm.common.monitor.IProgressMonitor;
37
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
38
import eu.etaxonomy.cdm.model.common.CdmBase;
39
import eu.etaxonomy.cdm.model.common.Language;
40
import eu.etaxonomy.cdm.model.common.LanguageString;
41
import eu.etaxonomy.cdm.model.common.LanguageStringBase;
42
import eu.etaxonomy.cdm.model.location.Country;
43
import eu.etaxonomy.cdm.model.location.NamedArea;
44
import eu.etaxonomy.cdm.model.location.NamedAreaLevel;
45
import eu.etaxonomy.cdm.model.location.NamedAreaType;
46
import eu.etaxonomy.cdm.model.media.Media;
47
import eu.etaxonomy.cdm.model.metadata.TermSearchField;
48
import eu.etaxonomy.cdm.model.term.DefinedTermBase;
49
import eu.etaxonomy.cdm.model.term.OrderedTermBase;
50
import eu.etaxonomy.cdm.model.term.OrderedTermVocabulary;
51
import eu.etaxonomy.cdm.model.term.Representation;
52
import eu.etaxonomy.cdm.model.term.TermType;
53
import eu.etaxonomy.cdm.model.term.TermVocabulary;
54
import eu.etaxonomy.cdm.persistence.dao.common.ILanguageStringBaseDao;
55
import eu.etaxonomy.cdm.persistence.dao.common.ILanguageStringDao;
56
import eu.etaxonomy.cdm.persistence.dao.term.IDefinedTermDao;
57
import eu.etaxonomy.cdm.persistence.dao.term.IRepresentationDao;
58
import eu.etaxonomy.cdm.persistence.dto.TermDto;
59
import eu.etaxonomy.cdm.persistence.dto.UuidAndTitleCache;
60
import eu.etaxonomy.cdm.persistence.query.OrderHint;
61
import eu.etaxonomy.cdm.strategy.cache.common.IIdentifiableEntityCacheStrategy;
62

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

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

    
72
	private ILanguageStringDao languageStringDao;
73

    
74
	@Autowired
75
	private IVocabularyService vocabularyService;
76

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

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

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

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

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

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

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

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

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

    
124
	@Override
125
    public <TERM extends DefinedTermBase> TERM findByIdInVocabulary(String id, UUID vocabularyUuid, Class<TERM> clazz) throws IllegalArgumentException {
126
        List<TERM> list = dao.getDefinedTermByIdInVocabulary(id, vocabularyUuid, clazz, null, null);
127
		if (list.isEmpty()){
128
			return null;
129
		}else if (list.size() == 1){
130
			return list.get(0);
131
		}else{
132
			String message = "There is more then 1 (%d) term with the same id in vocabulary. This is forbidden. Check the state of your database.";
133
			throw new IllegalStateException(String.format(message, list.size()));
134
		}
135
	}
136

    
137

    
138
	@Override
139
	public NamedArea getAreaByTdwgAbbreviation(String tdwgAbbreviation) {
140
		if (StringUtils.isBlank(tdwgAbbreviation)){ //TDWG areas should always have a label
141
			return null;
142
		}
143
		List<NamedArea> list = dao.getDefinedTermByIdInVocabulary(tdwgAbbreviation, NamedArea.uuidTdwgAreaVocabulary, NamedArea.class, null, null);
144
		if (list.isEmpty()){
145
			return null;
146
		}else if (list.size() == 1){
147
			return list.get(0);
148
		}else{
149
			String message = "There is more then 1 (%d) TDWG area with the same abbreviated label. This is forbidden. Check the state of your database.";
150
			throw new IllegalStateException(String.format(message, list.size()));
151
		}
152
	}
153

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
254

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

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

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

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

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

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

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

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

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

    
343

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

    
366
			//part of
367
			if (parentTerm != null){
368
			    if (config.isDeletePartOfRelations()){
369
			        parentTerm.removeIncludes(term);
370
			        termsToSave.add(parentTerm);
371
			    }else{
372
			        //handled before "included in"
373
			    }
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){
383
					dao.delete(term);
384
					result.addDeletedObject(term);
385
					dao.saveOrUpdateAll(termsToSave);
386
				}
387
			}
388
		} catch (DataChangeNoRollbackException e) {
389
			result.setStatus(Status.ERROR);
390
		}
391
		return result;
392
	}
393

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

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

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

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

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

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

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

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

    
474
        return result;
475
    }
476

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

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

    
501
        return result;
502
    }
503

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

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

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

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

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

    
544
            }
545
            vocabularyService.saveOrUpdate(parentVocabulary);
546

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

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

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

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

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

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

    
635
    @Override
636
    public Collection<TermDto> findFeatureByTitleAsDto(String title){
637
        return dao.findFeatureByTitleAsDto(title);
638
    }
639

    
640
    @Override
641
    public Country getCountryByIso(String iso639) {
642
        return this.dao.getCountryByIso(iso639);
643
    }
644

    
645
    @Override
646
    public List<Country> getCountryByName(String name) {
647
        List<? extends DefinedTermBase> terms = this.dao.findByTitleWithRestrictions(Country.class, name, null, null, null, null, null, null);
648
        List<Country> countries = new ArrayList<>();
649
        for (int i = 0; i < terms.size(); i++) {
650
            countries.add((Country) terms.get(i));
651
        }
652
        return countries;
653
    }
654

    
655

    
656
    public enum TermMovePosition{
657
        BEFORE,
658
        AFTER,
659
        ON
660
    }
661

    
662
}
(91-91/97)