Project

General

Profile

Download (18.5 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.stereotype.Repository;
28

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

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

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

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

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

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

    
83
			addPageSizeAndNumber(criteria, pageSize, pageNumber);
84
		    this.addOrder(criteria, orderHints);
85

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

    
94
			addPageSizeAndNumber(query, pageSize, pageNumber);
95

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

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

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

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

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

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

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

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

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

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

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

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

    
163
        this.addOrder(criteria, orderHints);
164

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

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

    
177
		Set<UUID> missingTermCandidateUuids = new HashSet<>();
178

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

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

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

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

    
201

    
202
 		//fully load and initialize vocabularies if required
203
		if (vocabularyResponse != null){
204
			String hql2 = " SELECT DISTINCT voc " +
205
					" FROM TermVocabulary voc " +
206
						" LEFT JOIN FETCH voc.terms terms " +
207
						" LEFT JOIN FETCH terms.representations representations " +
208
						" LEFT JOIN FETCH voc.representations vocReps " +
209
					" 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
210
//					" WHERE  voc.uuid IN (:vocUuids) AND voc.terms is empty  " +
211
					" ORDER BY voc.uuid ";
212
			query = getSession().createQuery(hql2);
213
			query.setParameterList("termUuids", missingTermCandidateUuids);
214
			query.setParameterList("vocUuids", uuidsRequested.keySet());
215

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

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

    
246
		return;
247
	}
248

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
356
    @Override
357
    public List<TermVocabularyDto> findVocabularyDtoByAvailableFor(Set<CdmClass> availableForSet) {
358

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

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

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

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

    
374
        List<TermVocabularyDto>  dtos = TermVocabularyDto.termVocabularyDtoListFrom(result);
375

    
376
        return dtos;
377
    }
378

    
379

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

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

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

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

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

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

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

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

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

    
480
    @Override
481
    public List<TermVocabularyDto> findVocabularyDtoByUuids(List<UUID> vocUuids) {
482

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

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

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

    
497
        list = TermVocabularyDto.termVocabularyDtoListFrom(result);
498
        return list;
499

    
500
    }
501
}
(6-6/6)