Project

General

Profile

Download (15.6 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

    
10
package eu.etaxonomy.cdm.persistence.dao.hibernate.term;
11

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

    
22
import org.hibernate.Criteria;
23
import org.hibernate.Query;
24
import org.hibernate.Session;
25
import org.hibernate.criterion.Disjunction;
26
import org.hibernate.criterion.Order;
27
import org.hibernate.criterion.Restrictions;
28
import org.hibernate.envers.query.AuditEntity;
29
import org.hibernate.envers.query.AuditQuery;
30
import org.springframework.stereotype.Repository;
31

    
32
import eu.etaxonomy.cdm.model.term.DefinedTermBase;
33
import eu.etaxonomy.cdm.model.term.OrderedTermVocabulary;
34
import eu.etaxonomy.cdm.model.term.Representation;
35
import eu.etaxonomy.cdm.model.term.TermType;
36
import eu.etaxonomy.cdm.model.term.TermVocabulary;
37
import eu.etaxonomy.cdm.model.view.AuditEvent;
38
import eu.etaxonomy.cdm.persistence.dao.hibernate.common.IdentifiableDaoBase;
39
import eu.etaxonomy.cdm.persistence.dao.term.ITermVocabularyDao;
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
 */
49
@Repository
50
public class TermVocabularyDaoImpl extends IdentifiableDaoBase<TermVocabulary> implements
51
		ITermVocabularyDao {
52

    
53
	/**
54
	 * @param type
55
	 */
56
	public TermVocabularyDaoImpl() {
57
		super(TermVocabulary.class);
58
		indexedClasses = new Class[2];
59
		indexedClasses[0] = TermVocabulary.class;
60
		indexedClasses[1] = OrderedTermVocabulary.class;
61
	}
62

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

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

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

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

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

    
97
			addPageSizeAndNumber(query, pageSize, pageNumber);
98

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

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

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

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

    
128

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

    
134

    
135
    @Override
136
    public <T extends DefinedTermBase> List<TermVocabulary<T>> findByTermType(TermType termType, List<String> propertyPaths) {
137

    
138
        Criteria criteria = getSession().createCriteria(type);
139
        criteria.add(Restrictions.eq("termType", termType));
140
        criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
141
        //this.addOrder(criteria, orderHints);
142

    
143
        @SuppressWarnings("unchecked")
144
        List<TermVocabulary<T>> result = criteria.list();
145
        defaultBeanInitializer.initializeAll(result, propertyPaths);
146
        return result;
147
    }
148

    
149
	@Override
150
    public List<TermVocabulary> listByTermType(TermType termType, boolean includeSubTypes, Integer limit, Integer start,List<OrderHint> orderHints, List<String> propertyPaths) {
151
        checkNotInPriorView("TermVocabularyDao.listByTermType(TermType termType, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths)");
152

    
153
        Set<TermType> allTermTypes = new HashSet<TermType>();
154
        allTermTypes.add(termType);
155
        if (includeSubTypes){
156
            allTermTypes.addAll(termType.getGeneralizationOf(true));
157
        }
158

    
159
        Criteria criteria = getSession().createCriteria(type);
160
        criteria.add(Restrictions.in("termType", allTermTypes));
161

    
162
        if(limit != null) {
163
            criteria.setMaxResults(limit);
164
            if(start != null) {
165
                criteria.setFirstResult(start);
166
            }
167
        }
168

    
169
        this.addOrder(criteria, orderHints);
170

    
171
        @SuppressWarnings("unchecked")
172
        List<TermVocabulary> result = criteria.list();
173
        defaultBeanInitializer.initializeAll(result, propertyPaths);
174
        return result;
175
    }
176

    
177
	@Override
178
	public void missingTermUuids(
179
			Map<UUID, Set<UUID>> uuidsRequested,
180
			Map<UUID, Set<UUID>> uuidMissingTermsRepsonse,
181
			Map<UUID, TermVocabulary<?>> vocabularyResponse){
182

    
183
		Set<UUID> missingTermCandidateUuids = new HashSet<>();
184

    
185
		for (Set<UUID> uuidsPerVocSet : uuidsRequested.values()){
186
			missingTermCandidateUuids.addAll(uuidsPerVocSet);
187
		}
188

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

    
196
		int splitSize = 2000;
197
		List<Collection<UUID>> missingTermCandidates = splitCollection(missingTermCandidateUuids, splitSize);
198
		List<UUID> persistedUuids = new ArrayList<>();
199

    
200
		for (Collection<UUID> uuids : missingTermCandidates){
201
		    query.setParameterList("uuids", uuids);
202
		    @SuppressWarnings("unchecked")
203
            List<UUID> list = query.list();
204
		    persistedUuids.addAll(list);
205
		}
206

    
207

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

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

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

    
252
		return;
253
	}
254

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

    
263
	    @SuppressWarnings("unchecked")
264
	    List<Object[]> result = query.list();
265

    
266
	    List<TermDto> list = TermDto.termDtoListFrom(result);
267
	    return list;
268
	}
269

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

    
278
	    @SuppressWarnings("unchecked")
279
	    List<Object[]> result = query.list();
280

    
281
	    List<TermDto> list = TermDto.termDtoListFrom(result);
282
	    return list;
283
	}
284

    
285
    @Override
286
    public Collection<TermDto> getTopLevelTerms(UUID vocabularyUuid) {
287
        String queryString = TermDto.getTermDtoSelect()
288
                + "where v.uuid = :vocabularyUuid "
289
                + "and a.partOf is null "
290
                + "and a.kindOf is null";
291
        Query query =  getSession().createQuery(queryString);
292
        query.setParameter("vocabularyUuid", vocabularyUuid);
293

    
294
        @SuppressWarnings("unchecked")
295
        List<Object[]> result = query.list();
296

    
297
        List<TermDto> list = TermDto.termDtoListFrom(result);
298
        return list;
299
    }
300

    
301
    @Override
302
    public List<TermVocabularyDto> findVocabularyDtoByTermTypes(Set<TermType> termTypes) {
303
        return findVocabularyDtoByTermTypes(termTypes, true);
304
    }
305

    
306
    @Override
307
    public List<TermVocabularyDto> findVocabularyDtoByTermTypes(Set<TermType> termTypes, boolean includeSubtypes) {
308
        Set<TermType> termTypeWithSubType = new HashSet<>(termTypes);
309
        if(includeSubtypes){
310
            for (TermType termType : termTypes) {
311
                termTypeWithSubType.addAll(termType.getGeneralizationOf(true));
312
            }
313
        }
314
        String queryString = ""
315
                + "select v.uuid, v.termType, r "
316
                + "from TermVocabulary as v LEFT JOIN v.representations AS r "
317
                + "where v.termType in (:termTypes) "
318
                ;
319
        Query query =  getSession().createQuery(queryString);
320
        query.setParameterList("termTypes", termTypeWithSubType);
321

    
322
        @SuppressWarnings("unchecked")
323
        List<Object[]> result = query.list();
324

    
325
        Map<UUID, TermVocabularyDto> dtoMap = new HashMap<>(result.size());
326
        for (Object[] elements : result) {
327
            UUID uuid = (UUID)elements[0];
328
            TermType termType = (TermType)elements[1];
329
            if(dtoMap.containsKey(uuid)){
330
                dtoMap.get(uuid).addRepresentation((Representation)elements[2]);
331
            } else {
332
                Set<Representation> representations = new HashSet<>();
333
                if(elements[2] instanceof Representation) {
334
                    representations = new HashSet<Representation>();
335
                    representations.add((Representation)elements[2]);
336
                } else {
337
                    representations = (Set<Representation>)elements[2];
338
                }
339
                dtoMap.put(uuid, new TermVocabularyDto(uuid, representations, termType));
340
            }
341
        }
342
        return new ArrayList<>(dtoMap.values());
343
    }
344

    
345
    @Override
346
    public List<TermVocabularyDto> findVocabularyDtoByTermType(TermType termType) {
347
        return findVocabularyDtoByTermTypes(Collections.singleton(termType));
348
    }
349

    
350
    @Override
351
    public <S extends TermVocabulary> List<UuidAndTitleCache<S>> getUuidAndTitleCache(Class<S> clazz, TermType termType,
352
            Integer limit, String pattern) {
353
        if(termType==null){
354
            return getUuidAndTitleCache(clazz, limit, pattern);
355
        }
356
        Session session = getSession();
357
        Query query = null;
358
        if (pattern != null){
359
            query = session.createQuery(
360
                      " SELECT uuid, id, titleCache "
361
                    + " FROM " + clazz.getSimpleName()
362
                    + " WHERE titleCache LIKE :pattern "
363
                    + " AND termType = :termType");
364
            pattern = pattern.replace("*", "%");
365
            pattern = pattern.replace("?", "_");
366
            pattern = pattern + "%";
367
            query.setParameter("pattern", pattern);
368
        } else {
369
            query = session.createQuery(
370
                      " SELECT uuid, id, titleCache "
371
                    + " FROM  " + clazz.getSimpleName()
372
                    + " WHERE termType = :termType");
373
        }
374
        query.setParameter("termType", termType);
375
        if (limit != null){
376
           query.setMaxResults(limit);
377
        }
378
        return getUuidAndTitleCache(query);
379
    }
380

    
381
    @Override
382
    public TermVocabularyDto findVocabularyDtoByUuid(UUID vocUuid) {
383
        Session session = getSession();
384
        Criteria crit = session.createCriteria(type);
385
        crit.add(Restrictions.eq("uuid", vocUuid));
386
        crit.addOrder(Order.desc("created"));
387
        List<TermVocabulary> result = crit.list();
388

    
389
        if (result.size() == 0){
390
            return null;
391
        }
392

    
393
        TermVocabulary resultVoc = result.get(0);
394
        TermVocabularyDto dto = new TermVocabularyDto(resultVoc.getUuid(), resultVoc.getRepresentations(), resultVoc.getTermType());
395
        for (Object o: resultVoc.getTerms()){
396
            DefinedTermBase term = (DefinedTermBase)o;
397
            dto.addTerm(TermDto.fromTerm(term));
398
        }
399

    
400
        return dto;
401
    }
402

    
403
    @Override
404
    public List<TermVocabularyDto> findVocabularyDtoByUuids(List<UUID> vocUuids) {
405
        Session session = getSession();
406
        Criteria crit = session.createCriteria(type);
407
        Disjunction or = Restrictions.disjunction();
408
        for (UUID uuid: vocUuids){
409
            or.add(Restrictions.or(Restrictions.eq("uuid", uuid)));
410
        }
411
        crit.add(or);
412
        crit.addOrder(Order.desc("created"));
413
        List<TermVocabulary> result = crit.list();
414

    
415
        if (result.size() == 0){
416
            return null;
417
        }
418
        List<TermVocabularyDto> dtos = new ArrayList<>();
419
        for (TermVocabulary voc: result){
420
            TermVocabularyDto dto = new TermVocabularyDto(voc.getUuid(), voc.getRepresentations(), voc.getTermType());
421
            for (Object o: voc.getTerms()){
422
                DefinedTermBase term = (DefinedTermBase)o;
423
                dto.addTerm(TermDto.fromTerm(term));
424
            }
425
            dtos.add(dto);
426

    
427
        }
428
        return dtos;
429
    }
430

    
431
}
(6-6/6)