Project

General

Profile

Download (19.1 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.FeatureDto;
38
import eu.etaxonomy.cdm.persistence.dto.TermCollectionDto;
39
import eu.etaxonomy.cdm.persistence.dto.TermDto;
40
import eu.etaxonomy.cdm.persistence.dto.TermVocabularyDto;
41
import eu.etaxonomy.cdm.persistence.dto.UuidAndTitleCache;
42
import eu.etaxonomy.cdm.persistence.query.OrderHint;
43

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

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

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

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

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

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

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

    
93
			addPageSizeAndNumber(query, pageSize, pageNumber);
94

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

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

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

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

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

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

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

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

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

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

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

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

    
162
        this.addOrder(criteria, orderHints);
163

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

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

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

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

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

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

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

    
200

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

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

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

    
245
		return;
246
	}
247

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

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

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

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

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

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

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

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

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

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

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

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

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

    
326
        @SuppressWarnings("unchecked")
327
        List<Object[]> result = query.list();
328
        List<TermDto> list = null;
329
        if (type.equals(TermType.Feature)|| type.isKindOf(TermType.Feature)){
330
            list = FeatureDto.termDtoListFrom(result);
331
        }else{
332
            list = TermDto.termDtoListFrom(result);
333
        }
334
        return list;
335
    }
336

    
337
    @Override
338
    public List<TermVocabularyDto> findVocabularyDtoByTermTypes(Set<TermType> termTypes) {
339
        return findVocabularyDtoByTermTypes(termTypes, true);
340
    }
341

    
342
    @Override
343
    public List<TermVocabularyDto> findVocabularyDtoByTermTypes(Set<TermType> termTypes, boolean includeSubtypes) {
344
        return findVocabularyDtoByTermTypes(termTypes, null, includeSubtypes);
345
    }
346

    
347
    @Override
348
    public List<TermVocabularyDto> findVocabularyDtoByAvailableFor(Set<CdmClass> availableForSet) {
349

    
350
        String queryVocWithFittingTerms = "SELECT DISTINCT(v.uuid) FROM DefinedTermBase term JOIN term.vocabulary as v WHERE " ;
351
        for (CdmClass availableFor: availableForSet){
352
            queryVocWithFittingTerms += " term.availableFor like '%"+availableFor.getKey()+"%' AND term.termType = :feature";
353
        }
354

    
355
        String queryString = TermCollectionDto.getTermCollectionDtoSelect()
356
                + " WHERE a.uuid in "
357
                + " (" + queryVocWithFittingTerms + ")";
358

    
359
        Query query =  getSession().createQuery(queryString);
360
        query.setParameter("feature", TermType.Feature);
361

    
362
        @SuppressWarnings("unchecked")
363
        List<Object[]> result = query.list();
364

    
365
        List<TermVocabularyDto>  dtos = TermVocabularyDto.termVocabularyDtoListFrom(result);
366

    
367
        return dtos;
368
    }
369

    
370

    
371
    @Override
372
    public List<TermVocabularyDto> findVocabularyDtoByTermTypes(Set<TermType> termTypes, String pattern, boolean includeSubtypes) {
373
        Set<TermType> termTypeWithSubType = new HashSet<>();
374
        if (! (termTypes.isEmpty() || (termTypes.size() == 1 && termTypes.iterator().next() == null))){
375
            termTypeWithSubType = new HashSet<>(termTypes);
376
        }
377

    
378
        if(includeSubtypes){
379
            if (!termTypes.isEmpty()){
380
                for (TermType termType : termTypes) {
381
                    if (termType != null){
382
                        termTypeWithSubType.addAll(termType.getGeneralizationOf(true));
383
                    }
384
                }
385
            }
386
        }
387
        String queryString = TermVocabularyDto.getTermCollectionDtoSelect();
388

    
389
        if (!termTypeWithSubType.isEmpty()){
390
            queryString += " where a.termType in (:termTypes) ";
391
            if (pattern != null){
392
                queryString += " AND a.titleCache like :pattern";
393
            }
394
        }else{
395
            if (pattern != null){
396
                queryString += " WHERE a.titleCache like :pattern";
397
            }
398
        }
399

    
400
        Query query =  getSession().createQuery(queryString);
401
        if (!termTypeWithSubType.isEmpty()){
402
            query.setParameterList("termTypes", termTypeWithSubType);
403
        }
404
        if (pattern != null){
405
            pattern = pattern.replace("*", "%");
406
            pattern = "%"+pattern+"%";
407
            query.setParameter("pattern", pattern);
408
        }
409
        @SuppressWarnings("unchecked")
410
        List<Object[]> result = query.list();
411
        List<TermVocabularyDto> dtos = TermVocabularyDto.termVocabularyDtoListFrom(result);
412
        return dtos;
413

    
414
//        Map<UUID, TermVocabularyDto> dtoMap = new HashMap<>(result.size());
415
//        for (Object[] elements : result) {
416
//            UUID uuid = (UUID)elements[0];
417
//            TermType termType = (TermType)elements[1];
418
//            if(dtoMap.containsKey(uuid)){
419
//                dtoMap.get(uuid).addRepresentation((Representation)elements[2]);
420
//            } else {
421
//                Set<Representation> representations = new HashSet<>();
422
//                if(elements[2] instanceof Representation) {
423
//                    representations = new HashSet<Representation>();
424
//                    representations.add((Representation)elements[2]);
425
//                } else {
426
//                    representations = (Set<Representation>)elements[2];
427
//                }
428
//                dtoMap.put(uuid, new TermVocabularyDto(uuid, representations, termType, (String)elements[3]));
429
//            }
430
//        }
431
//        return new ArrayList<>(dtoMap.values());
432
    }
433

    
434
    @Override
435
    public List<TermVocabularyDto> findVocabularyDtoByTermType(TermType termType) {
436
        return findVocabularyDtoByTermTypes(Collections.singleton(termType));
437
    }
438

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

    
470
    @Override
471
    public TermVocabularyDto findVocabularyDtoByUuid(UUID vocUuid) {
472
        if (vocUuid == null ){
473
            return null;
474
        }
475

    
476
        String queryString = TermCollectionDto.getTermCollectionDtoSelect()
477
                + " where a.uuid like :uuid ";
478
//                + "order by a.titleCache";
479
        Query query =  getSession().createQuery(queryString);
480
        query.setParameter("uuid", vocUuid);
481

    
482
        @SuppressWarnings("unchecked")
483
        List<Object[]> result = query.list();
484
        if (result.size() == 1){
485
            return TermVocabularyDto.termVocabularyDtoListFrom(result).get(0);
486
        }
487
        return null;
488
    }
489

    
490
    @Override
491
    public List<TermVocabularyDto> findVocabularyDtoByUuids(List<UUID> vocUuids) {
492

    
493
        if (vocUuids == null || vocUuids.isEmpty()){
494
            return null;
495
        }
496
        List<TermVocabularyDto> list = new ArrayList<>();
497

    
498
        String queryString = TermCollectionDto.getTermCollectionDtoSelect()
499
                + "where a.uuid in :uuidList ";
500
//                + "order by a.titleCache";
501
        Query query =  getSession().createQuery(queryString);
502
        query.setParameterList("uuidList", vocUuids);
503

    
504
        @SuppressWarnings("unchecked")
505
        List<Object[]> result = query.list();
506

    
507
        list = TermVocabularyDto.termVocabularyDtoListFrom(result);
508
        return list;
509

    
510
    }
511
}
(6-6/6)