Project

General

Profile

Download (26 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.NamedAreaSearchField;
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.listNamedArea(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(), area.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, NamedAreaSearchField type) {
480
        List<NamedArea> areas = dao.listNamedAreaByAbbrev(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(NamedAreaSearchField.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(NamedAreaSearchField.IDInVocabulary)){
490
                    display += " - " + area.getIdInVocabulary();
491
                }else if (type.equals(NamedAreaSearchField.Symbol1)){
492
                    display += " - " + area.getSymbol();
493
                }else if (type.equals(NamedAreaSearchField.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
//    @Transactional(readOnly = true)
506
//    public List<UuidAndTitleCache<NamedArea>> getUuidAndTitleCache(List<TermVocabulary> vocs, Integer pageNumber, Integer limit, String pattern, Language lang, MatchMode matchMode) {
507
//        List<NamedArea> areas = dao.getUuidAndTitleCache(vocs, pageNumber, limit, pattern, matchMode);
508
//
509
//        List<UuidAndTitleCache<NamedArea>> result = new ArrayList();
510
//        UuidAndTitleCache<NamedArea> uuidAndTitleCache;
511
//        for (NamedArea area: areas){
512
//            uuidAndTitleCache = new UuidAndTitleCache<>(area.getUuid(), area.getId(), area.labelWithLevel(area, lang));
513
//            result.add(uuidAndTitleCache);
514
//        }
515
//
516
//        return result;
517
//    }
518
//
519
//    @Override
520
//    public long count(List<TermVocabulary> vocs, String pattern, Language lang) {
521
//        long count = dao.count(vocs, pattern);
522
//        return count;
523
//    }
524

    
525
    @Override
526
    public Collection<TermDto> getIncludesAsDto(
527
            TermDto parentTerm) {
528
        return dao.getIncludesAsDto(parentTerm);
529
    }
530

    
531
    @Override
532
    public Collection<TermDto> getKindOfsAsDto(
533
            TermDto parentTerm) {
534
        return dao.getKindOfsAsDto(parentTerm);
535
    }
536

    
537
    @Transactional(readOnly = false)
538
    @Override
539
    public UpdateResult moveTerm(TermDto termDto, UUID parentUUID) {
540
        return moveTerm(termDto, parentUUID, TermMovePosition.ON);
541
    }
542

    
543
    @SuppressWarnings({ "rawtypes", "unchecked" })
544
    @Transactional(readOnly = false)
545
    @Override
546
    public UpdateResult moveTerm(TermDto termDto, UUID parentUuid, TermMovePosition termMovePosition) {
547
        boolean isKindOf = termDto.getKindOfUuid()!=null && termDto.getKindOfUuid().equals(parentUuid);
548
        TermVocabulary vocabulary = HibernateProxyHelper.deproxy(vocabularyService.load(termDto.getVocabularyUuid()));
549
        DefinedTermBase parent = HibernateProxyHelper.deproxy(dao.load(parentUuid));
550
        UpdateResult result = new UpdateResult();
551
        if(parent==null){
552
            //new parent is a vocabulary
553
            TermVocabulary parentVocabulary = HibernateProxyHelper.deproxy(vocabularyService.load(parentUuid));
554
            DefinedTermBase term = HibernateProxyHelper.deproxy(dao.load(termDto.getUuid()));
555
            if(parentVocabulary!=null){
556
                term.setKindOf(null);
557
                term.setPartOf(null);
558

    
559
                vocabulary.removeTerm(term);
560
                parentVocabulary.addTerm(term);
561
                result.addUpdatedObject(term);
562
                result.addUpdatedObject(vocabulary);
563
                result.addUpdatedObject(parentVocabulary);
564

    
565
            }
566
            vocabularyService.saveOrUpdate(parentVocabulary);
567

    
568
        }
569
        else {
570
            DefinedTermBase term = HibernateProxyHelper.deproxy(dao.load(termDto.getUuid()));
571
            //new parent is a term
572
            if(parent.isInstanceOf(OrderedTermBase.class)
573
                    && term.isInstanceOf(OrderedTermBase.class)
574
                    && termMovePosition!=null
575
                    && HibernateProxyHelper.deproxy(parent, OrderedTermBase.class).getVocabulary().isInstanceOf(OrderedTermVocabulary.class)) {
576
                //new parent is an ordered term
577
                OrderedTermBase orderedTerm = HibernateProxyHelper.deproxy(term, OrderedTermBase.class);
578
                OrderedTermBase targetOrderedDefinedTerm = HibernateProxyHelper.deproxy(parent, OrderedTermBase.class);
579
                OrderedTermVocabulary otVoc = HibernateProxyHelper.deproxy(targetOrderedDefinedTerm.getVocabulary(), OrderedTermVocabulary.class);
580
                if(termMovePosition.equals(TermMovePosition.BEFORE)) {
581
                    orderedTerm.getVocabulary().removeTerm(orderedTerm);
582
                    otVoc.addTermAbove(orderedTerm, targetOrderedDefinedTerm);
583
                    if (targetOrderedDefinedTerm.getPartOf() != null){
584
                        targetOrderedDefinedTerm.getPartOf().addIncludes(orderedTerm);
585
                    }
586
                }
587
                else if(termMovePosition.equals(TermMovePosition.AFTER)) {
588
                    orderedTerm.getVocabulary().removeTerm(orderedTerm);
589
                    otVoc.addTermBelow(orderedTerm, targetOrderedDefinedTerm);
590
                    if (targetOrderedDefinedTerm.getPartOf() != null){
591
                        targetOrderedDefinedTerm.getPartOf().addIncludes(orderedTerm);
592
                    }
593
                }
594
                else if(termMovePosition.equals(TermMovePosition.ON)) {
595
                    orderedTerm.getVocabulary().removeTerm(orderedTerm);
596
                    targetOrderedDefinedTerm.addIncludes(orderedTerm);
597
                    targetOrderedDefinedTerm.getVocabulary().addTerm(orderedTerm);
598
                }
599
            }
600
            else{
601
                vocabulary.removeTerm(term);
602
                if(isKindOf){
603
                    parent.addGeneralizationOf(term);
604
                }
605
                else{
606
                    parent.addIncludes(term);
607
                }
608
                parent.getVocabulary().addTerm(term);
609
            }
610
            result.addUpdatedObject(term);
611
            result.addUpdatedObject(parent);
612
            result.addUpdatedObject(vocabulary);
613
            vocabularyService.saveOrUpdate(parent.getVocabulary());
614
        }
615
        return result;
616
    }
617

    
618
    @SuppressWarnings({ "rawtypes", "unchecked" })
619
    @Transactional(readOnly = false)
620
    @Override
621
    public TermDto addNewTerm(TermType termType, UUID parentUUID, boolean isKindOf) {
622
        DefinedTermBase term = termType.getEmptyDefinedTermBase();
623
        dao.save(term);
624
        DefinedTermBase parent = dao.load(parentUUID);
625
        if(isKindOf){
626
            parent.addGeneralizationOf(term);
627
        }
628
        else{
629
            parent.addIncludes(term);
630
        }
631
        parent.getVocabulary().addTerm(term);
632
        dao.saveOrUpdate(parent);
633
        return TermDto.fromTerm(term, true);
634
    }
635

    
636
    @Override
637
    public Collection<TermDto> findByTitleAsDto(String title, TermType termType){
638
        return dao.findByTitleAsDto(title, termType);
639
    }
640

    
641
    @Override
642
    public Collection<TermDto> findByUriAsDto(URI uri, String termLabel, TermType termType){
643
        return dao.findByUriAsDto(uri, termLabel, termType);
644
    }
645

    
646
    @Override
647
    public Collection<TermDto> findByUUIDsAsDto(List<UUID> uuidList){
648
        return dao.findByUUIDsAsDto(uuidList);
649
    }
650

    
651
    @Override
652
    public Collection<TermDto> findFeatureByUUIDsAsDto(List<UUID> uuidList){
653
        return dao.findFeatureByUUIDsAsDto(uuidList);
654
    }
655

    
656
    @Override
657
    public Collection<TermDto> findFeatureByTitleAsDto(String title){
658
        return dao.findFeatureByTitleAsDto(title);
659
    }
660

    
661
    @Override
662
    public Country getCountryByIso(String iso639) {
663
        return this.dao.getCountryByIso(iso639);
664
    }
665

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

    
676

    
677
    public enum TermMovePosition{
678
        BEFORE,
679
        AFTER,
680
        ON
681
    }
682

    
683
}
(94-94/100)