Project

General

Profile

Download (20.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.persistence.dao.hibernate.term;
10

    
11
import java.util.ArrayList;
12
import java.util.Collection;
13
import java.util.Collections;
14
import java.util.HashSet;
15
import java.util.List;
16
import java.util.Map;
17
import java.util.Set;
18
import java.util.UUID;
19

    
20
import org.hibernate.Criteria;
21
import org.hibernate.Query;
22
import org.hibernate.Session;
23
import org.hibernate.criterion.CriteriaSpecification;
24
import org.hibernate.criterion.Restrictions;
25
import org.hibernate.envers.query.AuditEntity;
26
import org.hibernate.envers.query.AuditQuery;
27
import org.springframework.dao.DataAccessException;
28
import org.springframework.stereotype.Repository;
29

    
30
import eu.etaxonomy.cdm.model.common.CdmClass;
31
import eu.etaxonomy.cdm.model.term.DefinedTermBase;
32
import eu.etaxonomy.cdm.model.term.OrderedTermVocabulary;
33
import eu.etaxonomy.cdm.model.term.TermType;
34
import eu.etaxonomy.cdm.model.term.TermVocabulary;
35
import eu.etaxonomy.cdm.model.view.AuditEvent;
36
import eu.etaxonomy.cdm.persistence.dao.common.Restriction;
37
import eu.etaxonomy.cdm.persistence.dao.hibernate.common.IdentifiableDaoBase;
38
import eu.etaxonomy.cdm.persistence.dao.term.ITermVocabularyDao;
39
import eu.etaxonomy.cdm.persistence.dto.CharacterDto;
40
import eu.etaxonomy.cdm.persistence.dto.FeatureDto;
41
import eu.etaxonomy.cdm.persistence.dto.TermCollectionDto;
42
import eu.etaxonomy.cdm.persistence.dto.TermDto;
43
import eu.etaxonomy.cdm.persistence.dto.TermVocabularyDto;
44
import eu.etaxonomy.cdm.persistence.dto.UuidAndTitleCache;
45
import eu.etaxonomy.cdm.persistence.query.OrderHint;
46

    
47
/**
48
 * @author a.mueller
49
 */
50
@Repository
51
public class TermVocabularyDaoImpl extends IdentifiableDaoBase<TermVocabulary> implements
52
		ITermVocabularyDao {
53

    
54
	@SuppressWarnings("unchecked")
55
    public TermVocabularyDaoImpl() {
56
		super(TermVocabulary.class);
57
		indexedClasses = new Class[2];
58
		indexedClasses[0] = TermVocabulary.class;
59
		indexedClasses[1] = OrderedTermVocabulary.class;
60
	}
61

    
62
	@Override
63
    public long countTerms(TermVocabulary termVocabulary) {
64
		AuditEvent auditEvent = getAuditEventFromContext();
65
		if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
66
		    Query query = getSession().createQuery("select count(term) from DefinedTermBase term where term.vocabulary = :vocabulary");
67
		    query.setParameter("vocabulary", termVocabulary);
68

    
69
		    return (Long)query.uniqueResult();
70
		} else {
71
			AuditQuery query = makeAuditQuery(null, auditEvent);
72
			query.addProjection(AuditEntity.id().count());
73
			query.add(AuditEntity.relatedId("vocabulary").eq(termVocabulary.getId()));
74
			return (Long)query.getSingleResult();
75
		}
76
	}
77

    
78
	@Override
79
    public <T extends DefinedTermBase> List<T> getTerms(TermVocabulary<T> vocabulary,Integer pageSize, Integer pageNumber, List<OrderHint> orderHints,List<String> propertyPaths) {
80
		AuditEvent auditEvent = getAuditEventFromContext();
81
		if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
82
			Criteria criteria = getCriteria(DefinedTermBase.class);
83
			criteria.createCriteria("vocabulary").add(Restrictions.idEq(vocabulary.getId()));
84

    
85
			addPageSizeAndNumber(criteria, pageSize, pageNumber);
86
		    this.addOrder(criteria, orderHints);
87

    
88
		    @SuppressWarnings("unchecked")
89
            List<T> result = DefinedTermDaoImpl.deduplicateResult(criteria.list());
90
		    defaultBeanInitializer.initializeAll(result, propertyPaths);
91
		    return result;
92
		} else {
93
			AuditQuery query = makeAuditQuery(null, auditEvent);
94
			query.add(AuditEntity.relatedId("vocabulary").eq(vocabulary.getId()));
95

    
96
			addPageSizeAndNumber(query, pageSize, pageNumber);
97

    
98
			@SuppressWarnings("unchecked")
99
            List<T> result = DefinedTermDaoImpl.deduplicateResult(query.getResultList());
100
		    defaultBeanInitializer.initializeAll(result, propertyPaths);
101
			return result;
102
		}
103
	}
104

    
105
    @Override
106
    public <T extends DefinedTermBase> TermVocabulary<T> findByUri(String termSourceUri, Class<T> clazz) {
107
		AuditEvent auditEvent = getAuditEventFromContext();
108
		if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
109
		    //TODO use clazz
110
    		Query query = getSession().createQuery("select vocabulary from TermVocabulary vocabulary where vocabulary.termSourceUri= :termSourceUri");
111
	    	query.setParameter("termSourceUri", termSourceUri);
112

    
113
	    	@SuppressWarnings("unchecked")
114
	    	TermVocabulary<T> result = (TermVocabulary<T>)query.uniqueResult();
115
	    	return result;
116
		} else {
117
            AuditQuery query = makeAuditQuery(clazz, auditEvent);
118
			query.add(AuditEntity.property("termSourceUri").eq(termSourceUri));
119

    
120
			@SuppressWarnings("unchecked")
121
            TermVocabulary<T> result = (TermVocabulary<T>)query.getSingleResult();
122
			return result;
123
		}
124
	}
125

    
126
	@Override
127
    public <T extends DefinedTermBase> List<T> getTerms(TermVocabulary<T> termVocabulary, Integer pageSize,	Integer pageNumber) {
128
		return getTerms(termVocabulary, pageSize, pageNumber, null, null);
129
	}
130

    
131
    @Override
132
    public <T extends DefinedTermBase> List<TermVocabulary<T>> findByTermType(TermType termType, List<String> propertyPaths) {
133

    
134
        Criteria criteria = getSession().createCriteria(type);
135
        criteria.add(Restrictions.eq("termType", termType));
136
        criteria.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
137
        //this.addOrder(criteria, orderHints);
138

    
139
        @SuppressWarnings("unchecked")
140
        List<TermVocabulary<T>> result = DefinedTermDaoImpl.deduplicateResult(criteria.list());
141
        defaultBeanInitializer.initializeAll(result, propertyPaths);
142
        return result;
143
    }
144

    
145
	@Override
146
    public List<TermVocabulary> listByTermType(TermType termType, boolean includeSubTypes, Integer limit, Integer start,List<OrderHint> orderHints, List<String> propertyPaths) {
147
        checkNotInPriorView("TermVocabularyDao.listByTermType(TermType termType, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths)");
148

    
149
        Set<TermType> allTermTypes = new HashSet<TermType>();
150
        allTermTypes.add(termType);
151
        if (includeSubTypes){
152
            allTermTypes.addAll(termType.getGeneralizationOf(true));
153
        }
154

    
155
        Criteria criteria = getSession().createCriteria(type);
156
        criteria.add(Restrictions.in("termType", allTermTypes));
157

    
158
        if(limit != null) {
159
            criteria.setMaxResults(limit);
160
            if(start != null) {
161
                criteria.setFirstResult(start);
162
            }
163
        }
164

    
165
        this.addOrder(criteria, orderHints);
166

    
167
        @SuppressWarnings("unchecked")
168
        List<TermVocabulary> result = DefinedTermDaoImpl.deduplicateResult(criteria.list());
169
        defaultBeanInitializer.initializeAll(result, propertyPaths);
170
        return result;
171
    }
172

    
173
	@Override
174
	public void missingTermUuids(
175
			Map<UUID, List<UUID>> uuidsRequested,
176
			Map<UUID, Set<UUID>> uuidMissingTermsRepsonse,
177
			Map<UUID, TermVocabulary<?>> vocabularyResponse){
178

    
179
		Set<UUID> missingTermCandidateUuids = new HashSet<>();
180

    
181
		for (List<UUID> uuidsPerVocSet : uuidsRequested.values()){
182
			missingTermCandidateUuids.addAll(uuidsPerVocSet);
183
		}
184

    
185
 		//search persisted subset of required (usually all)
186
		String hql = " SELECT terms.uuid " +
187
				" FROM TermVocabulary voc join voc.terms terms  " +
188
				" WHERE terms.uuid IN (:uuids) " +
189
				" ORDER BY voc.uuid ";
190
		Query query = getSession().createQuery(hql);
191

    
192
		int splitSize = 2000;
193
		List<Collection<UUID>> missingTermCandidates = splitCollection(missingTermCandidateUuids, splitSize);
194
		List<UUID> persistedUuids = new ArrayList<>();
195

    
196
		for (Collection<UUID> uuids : missingTermCandidates){
197
		    query.setParameterList("uuids", uuids);
198
		    @SuppressWarnings("unchecked")
199
            List<UUID> list = query.list();
200
		    persistedUuids.addAll(list);
201
		}
202

    
203

    
204
 		//fully load and initialize vocabularies if required
205
		if (vocabularyResponse != null){
206
			String hql2 = " SELECT DISTINCT voc " +
207
					" FROM TermVocabulary voc " +
208
						" LEFT JOIN FETCH voc.terms terms " +
209
						" LEFT JOIN FETCH terms.representations representations " +
210
						" LEFT JOIN FETCH voc.representations vocReps " +
211
					" WHERE terms.uuid IN (:termUuids) OR  (  voc.uuid IN (:vocUuids)  ) " +  //was: AND voc.terms is empty, but did not load originally empty vocabularies with user defined terms added
212
//					" WHERE  voc.uuid IN (:vocUuids) AND voc.terms is empty  " +
213
					" ORDER BY voc.uuid ";
214
			query = getSession().createQuery(hql2);
215
			query.setParameterList("termUuids", missingTermCandidateUuids);
216
			query.setParameterList("vocUuids", uuidsRequested.keySet());
217

    
218
			for (Collection<UUID> uuids : missingTermCandidates){
219
			    query.setParameterList("termUuids", uuids);
220
			    @SuppressWarnings("unchecked")
221
	            List<TermVocabulary<?>> o = query.list();
222
	            for (TermVocabulary<?> voc : o){
223
	                vocabularyResponse.put(voc.getUuid(), voc);
224
	            }
225
	        }
226
		}
227

    
228
		//compute missing terms
229
		if (missingTermCandidateUuids.size() == persistedUuids.size()){
230
			missingTermCandidateUuids.clear();
231
		}else{
232
			missingTermCandidateUuids.removeAll(persistedUuids);
233
			//add missing terms to response
234
			for (UUID vocUUID : uuidsRequested.keySet()){
235
				for (UUID termUuid : uuidsRequested.get(vocUUID)){
236
					if (missingTermCandidateUuids.contains(termUuid)){
237
						Set<UUID> r = uuidMissingTermsRepsonse.get(vocUUID);
238
						if (r == null){
239
							r = new HashSet<>();
240
							uuidMissingTermsRepsonse.put(vocUUID, r);
241
						}
242
						r.add(termUuid);
243
					}
244
				}
245
			}
246
		}
247

    
248
		return;
249
	}
250

    
251
	@Override
252
	public Collection<TermDto> getTerms(List<UUID> vocabularyUuids) {
253
	    String queryString = TermDto.getTermDtoSelect()
254
	            + "where v.uuid in :vocabularyUuids "
255
	            + "order by a.titleCache";
256
	    Query query =  getSession().createQuery(queryString);
257
	    query.setParameterList("vocabularyUuids", vocabularyUuids);
258

    
259
	    @SuppressWarnings("unchecked")
260
	    List<Object[]> result = query.list();
261

    
262
	    List<TermDto> list = TermDto.termDtoListFrom(result);
263
	    return list;
264
	}
265

    
266
	@Override
267
	public Collection<TermDto> getTerms(UUID vocabularyUuid) {
268
	    String queryString = TermDto.getTermDtoSelect()
269
	            + "where v.uuid = :vocabularyUuid "
270
	            + "order by a.titleCache";
271
	    Query query =  getSession().createQuery(queryString);
272
	    query.setParameter("vocabularyUuid", vocabularyUuid);
273

    
274
	    @SuppressWarnings("unchecked")
275
	    List<Object[]> result = query.list();
276

    
277
	    List<TermDto> list = TermDto.termDtoListFrom(result);
278
	    return list;
279
	}
280

    
281
	@Override
282
    public Collection<TermDto> getNamedAreaTerms(List<UUID> vocabularyUuids) {
283
        String queryString = TermDto.getTermDtoSelectNamedArea()
284
                + "where v.uuid in :vocabularyUuids "
285
                + "order by a.titleCache";
286
        Query query =  getSession().createQuery(queryString);
287
        query.setParameterList("vocabularyUuids", vocabularyUuids);
288

    
289
        @SuppressWarnings("unchecked")
290
        List<Object[]> result = query.list();
291

    
292
        List<TermDto> list = TermDto.termDtoListFrom(result);
293
        return list;
294
    }
295

    
296
    @Override
297
    public Collection<TermDto> getTopLevelTerms(UUID vocabularyUuid) {
298
        String queryString = TermDto.getTermDtoSelect()
299
                + "where v.uuid = :vocabularyUuid "
300
                + "and a.partOf is null "
301
                + "and a.kindOf is null";
302
        Query query =  getSession().createQuery(queryString);
303
        query.setParameter("vocabularyUuid", vocabularyUuid);
304

    
305
        @SuppressWarnings("unchecked")
306
        List<Object[]> result = query.list();
307

    
308
        List<TermDto> list = TermDto.termDtoListFrom(result);
309
        return list;
310
    }
311

    
312
    @Override
313
    public List<TermDto> getTopLevelTerms(UUID vocabularyUuid, TermType type) {
314
        String queryString;
315
        if (type.equals(TermType.NamedArea)){
316
            queryString = TermDto.getTermDtoSelectNamedArea();
317
        }else if (type.equals(TermType.Feature) || type.isKindOf(TermType.Feature)){
318
            if (type.equals(TermType.Character)){
319
                queryString = CharacterDto.getTermDtoSelect();
320
            }else{
321
                queryString = FeatureDto.getTermDtoSelect();
322
            }
323
        }else{
324
            queryString = TermDto.getTermDtoSelect();
325
        }
326
        queryString = queryString
327
                + " where v.uuid = :vocabularyUuid "
328
                + " and a.partOf is null "
329
                + " and a.kindOf is null";
330
        Query query =  getSession().createQuery(queryString);
331
        query.setParameter("vocabularyUuid", vocabularyUuid);
332

    
333
        @SuppressWarnings("unchecked")
334
        List<Object[]> result = query.list();
335
        List<TermDto> list = null;
336
        if (type.equals(TermType.Feature)|| type.isKindOf(TermType.Feature)){
337
            if (type.equals(TermType.Character)){
338
                list = CharacterDto.termDtoListFrom(result);
339
            }else{
340
                list = FeatureDto.termDtoListFrom(result);
341
            }
342
        }else{
343
            list = TermDto.termDtoListFrom(result);
344
        }
345
        return list;
346
    }
347

    
348
    @Override
349
    public List<TermVocabularyDto> findVocabularyDtoByTermTypes(Set<TermType> termTypes) {
350
        return findVocabularyDtoByTermTypes(termTypes, true);
351
    }
352

    
353
    @Override
354
    public List<TermVocabularyDto> findVocabularyDtoByTermTypes(Set<TermType> termTypes, boolean includeSubtypes) {
355
        return findVocabularyDtoByTermTypes(termTypes, null, includeSubtypes);
356
    }
357

    
358
    @Override
359
    public List<TermVocabularyDto> findVocabularyDtoByAvailableFor(Set<CdmClass> availableForSet) {
360

    
361
        String queryVocWithFittingTerms = "SELECT DISTINCT(v.uuid) FROM DefinedTermBase term JOIN term.vocabulary as v WHERE " ;
362
        for (CdmClass availableFor: availableForSet){
363
            queryVocWithFittingTerms += " term.availableFor like '%"+availableFor.getKey()+"%' AND term.termType = :feature";
364
        }
365

    
366
        String queryString = TermCollectionDto.getTermCollectionDtoSelect()
367
                + " WHERE a.uuid in "
368
                + " (" + queryVocWithFittingTerms + ")";
369

    
370
        Query query =  getSession().createQuery(queryString);
371
        query.setParameter("feature", TermType.Feature);
372

    
373
        @SuppressWarnings("unchecked")
374
        List<Object[]> result = query.list();
375

    
376
        List<TermVocabularyDto>  dtos = TermVocabularyDto.termVocabularyDtoListFrom(result);
377

    
378
        return dtos;
379
    }
380

    
381

    
382
    @Override
383
    public List<TermVocabularyDto> findVocabularyDtoByTermTypes(Set<TermType> termTypes, String pattern, boolean includeSubtypes) {
384
        Set<TermType> termTypeWithSubType = new HashSet<>();
385
        if (! (termTypes.isEmpty() || (termTypes.size() == 1 && termTypes.iterator().next() == null))){
386
            termTypeWithSubType = new HashSet<>(termTypes);
387
        }
388

    
389
        if(includeSubtypes){
390
            if (!termTypes.isEmpty()){
391
                for (TermType termType : termTypes) {
392
                    if (termType != null){
393
                        termTypeWithSubType.addAll(termType.getGeneralizationOf(true));
394
                    }
395
                }
396
            }
397
        }
398
        String queryString = TermVocabularyDto.getTermCollectionDtoSelect();
399

    
400
        if (!termTypeWithSubType.isEmpty()){
401
            queryString += " where a.termType in (:termTypes) ";
402
            if (pattern != null){
403
                queryString += " AND a.titleCache like :pattern";
404
            }
405
        }else{
406
            if (pattern != null){
407
                queryString += " WHERE a.titleCache like :pattern";
408
            }
409
        }
410

    
411
        Query query =  getSession().createQuery(queryString);
412
        if (!termTypeWithSubType.isEmpty()){
413
            query.setParameterList("termTypes", termTypeWithSubType);
414
        }
415
        if (pattern != null){
416
            pattern = pattern.replace("*", "%");
417
            pattern = "%"+pattern+"%";
418
            query.setParameter("pattern", pattern);
419
        }
420
        @SuppressWarnings("unchecked")
421
        List<Object[]> result = query.list();
422
        List<TermVocabularyDto> dtos = TermVocabularyDto.termVocabularyDtoListFrom(result);
423
        return dtos;
424
    }
425

    
426
    @Override
427
    public List<TermVocabularyDto> findVocabularyDtoByTermType(TermType termType) {
428
        return findVocabularyDtoByTermTypes(Collections.singleton(termType));
429
    }
430

    
431
    @Override
432
    public <S extends TermVocabulary> List<UuidAndTitleCache<S>> getUuidAndTitleCache(Class<S> clazz, TermType termType,
433
            Integer limit, String pattern) {
434
        if(termType==null){
435
            return getUuidAndTitleCache(clazz, limit, pattern);
436
        }
437
        Session session = getSession();
438
        Query query = null;
439
        if (pattern != null){
440
            query = session.createQuery(
441
                      " SELECT uuid, id, titleCache "
442
                    + " FROM " + clazz.getSimpleName()
443
                    + " WHERE titleCache LIKE :pattern "
444
                    + " AND termType = :termType");
445
            pattern = pattern.replace("*", "%");
446
            pattern = pattern.replace("?", "_");
447
            pattern = pattern + "%";
448
            query.setParameter("pattern", pattern);
449
        } else {
450
            query = session.createQuery(
451
                      " SELECT uuid, id, titleCache "
452
                    + " FROM  " + clazz.getSimpleName()
453
                    + " WHERE termType = :termType");
454
        }
455
        query.setParameter("termType", termType);
456
        if (limit != null){
457
           query.setMaxResults(limit);
458
        }
459
        return getUuidAndTitleCache(query);
460
    }
461

    
462
    @Override
463
    public TermVocabularyDto findVocabularyDtoByUuid(UUID vocUuid) {
464
        if (vocUuid == null ){
465
            return null;
466
        }
467

    
468
        String queryString = TermCollectionDto.getTermCollectionDtoSelect()
469
                + " where a.uuid like :uuid ";
470
//                + "order by a.titleCache";
471
        Query query =  getSession().createQuery(queryString);
472
        query.setParameter("uuid", vocUuid);
473

    
474
        @SuppressWarnings("unchecked")
475
        List<Object[]> result = query.list();
476
        if (result.size() == 1){
477
            return TermVocabularyDto.termVocabularyDtoListFrom(result).get(0);
478
        }
479
        return null;
480
    }
481

    
482
    @Override
483
    public List<TermVocabularyDto> findVocabularyDtoByUuids(List<UUID> vocUuids) {
484

    
485
        if (vocUuids == null || vocUuids.isEmpty()){
486
            return null;
487
        }
488
        List<TermVocabularyDto> list = new ArrayList<>();
489

    
490
        String queryString = TermCollectionDto.getTermCollectionDtoSelect()
491
                + "where a.uuid in :uuidList ";
492
//                + "order by a.titleCache";
493
        Query query =  getSession().createQuery(queryString);
494
        query.setParameterList("uuidList", vocUuids);
495

    
496
        @SuppressWarnings("unchecked")
497
        List<Object[]> result = query.list();
498

    
499
        list = TermVocabularyDto.termVocabularyDtoListFrom(result);
500
        return list;
501
    }
502

    
503
//***************** Overrides for deduplication *******************************/
504

    
505
    @Override
506
    public List<TermVocabulary> loadList(Collection<Integer> ids, List<OrderHint> orderHints,
507
            List<String> propertyPaths) throws DataAccessException {
508
        return DefinedTermDaoImpl.deduplicateResult(super.loadList(ids, orderHints, propertyPaths));
509
    }
510

    
511
    @Override
512
    public List<TermVocabulary> list(Collection<UUID> uuids, Integer pageSize, Integer pageNumber,
513
            List<OrderHint> orderHints, List<String> propertyPaths) throws DataAccessException {
514
        return DefinedTermDaoImpl.deduplicateResult(super.list(uuids, pageSize, pageNumber, orderHints, propertyPaths));
515
    }
516

    
517
    @Override
518
    public <S extends TermVocabulary> List<S> list(Class<S> clazz, Collection<UUID> uuids, Integer pageSize,
519
            Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) throws DataAccessException {
520
        return DefinedTermDaoImpl.deduplicateResult(super.list(clazz, uuids, pageSize, pageNumber, orderHints, propertyPaths));
521
    }
522

    
523
    @Override
524
    public <S extends TermVocabulary> List<S> list(Class<S> type, List<Restriction<?>> restrictions, Integer limit,
525
            Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {
526
        return DefinedTermDaoImpl.deduplicateResult(super.list(type, restrictions, limit, start, orderHints, propertyPaths));
527
    }
528

    
529
    @Override
530
    public List<TermVocabulary> list(Integer limit, Integer start, List<OrderHint> orderHints) {
531
        return DefinedTermDaoImpl.deduplicateResult(super.list(limit, start, orderHints));
532
    }
533

    
534
    @Override
535
    public List<TermVocabulary> list(Integer limit, Integer start, List<OrderHint> orderHints,
536
            List<String> propertyPaths) {
537
        return DefinedTermDaoImpl.deduplicateResult(super.list(limit, start, orderHints, propertyPaths));
538
    }
539

    
540
    @Override
541
    public <S extends TermVocabulary> List<S> list(Class<S> type, Integer limit, Integer start,
542
            List<OrderHint> orderHints) {
543
        return DefinedTermDaoImpl.deduplicateResult(super.list(type, limit, start, orderHints));
544
    }
545
}
(6-6/6)