Project

General

Profile

« Previous | Next » 

Revision 367973e0

Added by Andreas Müller over 8 years ago

Add vocabulary list method by term types #3843

View differences:

cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/common/ITermVocabularyDao.java
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.common;
11

  
12

  
13
import java.util.List;
14
import java.util.Map;
15
import java.util.Set;
16
import java.util.UUID;
17

  
18
import eu.etaxonomy.cdm.model.common.DefinedTermBase;
19
import eu.etaxonomy.cdm.model.common.TermType;
20
import eu.etaxonomy.cdm.model.common.TermVocabulary;
21
import eu.etaxonomy.cdm.persistence.query.OrderHint;
22

  
23

  
24
/**
25
 * @author a.mueller
26
 *
27
 */
28
public interface ITermVocabularyDao extends IIdentifiableDao<TermVocabulary> {
29
	
30
	/**
31
	 * Return a count of terms that belong to the termVocabulary supplied
32
	 * 
33
	 * @param termVocabulary The term vocabulary which 'owns' the terms of interest
34
	 * @return a count of terms
35
	 */
36
	public int countTerms(TermVocabulary termVocabulary);
37
	
38
	/**
39
	 * Return a List of terms that belong to the termVocabulary supplied
40
	 * 
41
	 * @param termVocabulary The term vocabulary which 'owns' the terms of interest
42
	 * @param pageSize The maximum number of terms returned (can be null for all terms)
43
	 * @param pageNumber The offset (in pageSize chunks) from the start of the result set (0 - based)
44
	 * @return a List of terms
45
	 */
46
	public <T extends DefinedTermBase> List<T> getTerms(TermVocabulary<T> termVocabulary, Integer pageSize, Integer pageNumber);
47
	
48
	public <T extends DefinedTermBase> TermVocabulary<T> findByUri(String termSourceUri, Class<T> clazz);
49
	
50
	/**
51
	 * Return a List of vocabularies that belong to the term type supplied
52
	 * 
53
	 * @param termType The term type corresoponding to the vocabularies of interest
54
	 * @return a List of vocabularies
55
	 */
56
	
57
	public <T extends DefinedTermBase> List<TermVocabulary<T>> findByTermType(TermType termType);
58

  
59
	/**
60
	 * Return a List of terms that belong to the termVocabulary supplied
61
	 * 
62
	 * @param termVocabulary The term vocabulary which 'owns' the terms of interest
63
	 * @param pageSize The maximum number of terms returned (can be null for all terms)
64
	 * @param pageNumber The offset (in pageSize chunks) from the start of the result set (0 - based)
65
	 * @param orderHints
66
	 *            Supports path like <code>orderHints.propertyNames</code> which
67
	 *            include *-to-one properties like createdBy.username or
68
	 *            authorTeam.persistentTitleCache
69
	 * @param propertyPaths properties to be initialized
70
	 * @return a List of terms
71
	 */
72
	public <T extends DefinedTermBase> List<T> getTerms(TermVocabulary<T> vocabulary,Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths);
73
	
74
	/**
75
     * Returns term vocabularies that contain terms of a certain class e.g. Feature, Modifier, State.
76
     * 
77
     * @param <TERMTYPE>
78
     * @param clazz the term class of the terms in the vocabulary
79
     * @param includeSubclasses if <code>true</code> all subclasses of clazz will be included for computation of the result
80
     * @param includeEmptyVocs if <code>true</code> all vocabularies that do not contain any term will be included in the result
81
     * @param limit The maximum number of vocabularies returned (can be null for all vocabularies)
82
     * @param start The offset from the start of the result set (0 - based, can be null - equivalent of starting at the beginning of the recordset)
83
     * @param orderHints 
84
     *            Supports path like <code>orderHints.propertyNames</code> which
85
	 *            include *-to-one properties like createdBy.username or
86
	 *            authorTeam.persistentTitleCache
87
     * @param propertyPaths properties to be initialized
88
     * @return a list of term vocabularies
89
     */
90
	public <TERMTYPE extends DefinedTermBase> List<TermVocabulary<? extends TERMTYPE>> listByTermClass(Class<TERMTYPE> clazz, boolean includeSubclasses, boolean includeEmptyVocs, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths);
91

  
92
	
93
	public List<TermVocabulary> listEmpty(Integer limit, Integer start,List<OrderHint> orderHints, List<String> propertyPaths);
94

  
95
	/**
96
	 * Fills the response map with those term uuids which do exist in the requested map
97
	 * but not in the repository (missing terms). The map key is the vocabulary uuid in both cases.
98
	 * If parameter vocabularyRepsonse is not <code>null</code> the vocabularies will be fully loaded
99
	 * and returned within the map. The later is for using this method together with fast termloading.
100
	 * @param uuidsRequested
101
	 * @param uuidsRepsonse
102
	 * @param vocabularyResponse
103
	 */
104
	public void missingTermUuids(Map<UUID, Set<UUID>> uuidsRequested,
105
			Map<UUID, Set<UUID>> uuidsRepsonse,
106
			Map<UUID, TermVocabulary<?>> vocabularyResponse);
107

  
108

  
109
}
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.common;
11

  
12

  
13
import java.util.List;
14
import java.util.Map;
15
import java.util.Set;
16
import java.util.UUID;
17

  
18
import eu.etaxonomy.cdm.model.common.DefinedTermBase;
19
import eu.etaxonomy.cdm.model.common.TermType;
20
import eu.etaxonomy.cdm.model.common.TermVocabulary;
21
import eu.etaxonomy.cdm.persistence.query.OrderHint;
22

  
23

  
24
/**
25
 * @author a.mueller
26
 *
27
 */
28
public interface ITermVocabularyDao extends IIdentifiableDao<TermVocabulary> {
29

  
30
	/**
31
	 * Return a count of terms that belong to the termVocabulary supplied
32
	 *
33
	 * @param termVocabulary The term vocabulary which 'owns' the terms of interest
34
	 * @return a count of terms
35
	 */
36
	public int countTerms(TermVocabulary termVocabulary);
37

  
38
	/**
39
	 * Return a List of terms that belong to the termVocabulary supplied
40
	 *
41
	 * @param termVocabulary The term vocabulary which 'owns' the terms of interest
42
	 * @param pageSize The maximum number of terms returned (can be null for all terms)
43
	 * @param pageNumber The offset (in pageSize chunks) from the start of the result set (0 - based)
44
	 * @return a List of terms
45
	 */
46
	public <T extends DefinedTermBase> List<T> getTerms(TermVocabulary<T> termVocabulary, Integer pageSize, Integer pageNumber);
47

  
48
	public <T extends DefinedTermBase> TermVocabulary<T> findByUri(String termSourceUri, Class<T> clazz);
49

  
50
	/**
51
	 * Return a List of terms that belong to the termVocabulary supplied
52
	 *
53
	 * @param termVocabulary The term vocabulary which 'owns' the terms of interest
54
	 * @param pageSize The maximum number of terms returned (can be null for all terms)
55
	 * @param pageNumber The offset (in pageSize chunks) from the start of the result set (0 - based)
56
	 * @param orderHints
57
	 *            Supports path like <code>orderHints.propertyNames</code> which
58
	 *            include *-to-one properties like createdBy.username or
59
	 *            authorTeam.persistentTitleCache
60
	 * @param propertyPaths properties to be initialized
61
	 * @return a List of terms
62
	 */
63
	public <T extends DefinedTermBase> List<T> getTerms(TermVocabulary<T> vocabulary,Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths);
64

  
65
	/**
66
     * Returns term vocabularies that contain terms of a certain class e.g. Feature, Modifier, State.
67
     *
68
     * @param <TERMCLASS>
69
     * @param clazz the term class of the terms in the vocabulary
70
     * @param includeSubclasses if <code>true</code> all subclasses of clazz will be included for computation of the result
71
     * @param includeEmptyVocs if <code>true</code> all vocabularies that do not contain any term will be included in the result
72
     * @param limit The maximum number of vocabularies returned (can be null for all vocabularies)
73
     * @param start The offset from the start of the result set (0 - based, can be null - equivalent of starting at the beginning of the recordset)
74
     * @param orderHints
75
     *            Supports path like <code>orderHints.propertyNames</code> which
76
	 *            include *-to-one properties like createdBy.username or
77
	 *            authorTeam.persistentTitleCache
78
     * @param propertyPaths properties to be initialized
79
     * @return a list of term vocabularies
80
     */
81
	/**
82
     * @deprecated This method is deprecated as we are using {@link TermType} now.
83
     * It may be removed in a future version.
84
     */
85
	@Deprecated
86
	public <TERMCLASS extends DefinedTermBase> List<TermVocabulary<? extends TERMCLASS>> listByTermClass(Class<TERMCLASS> clazz, boolean includeSubclasses, boolean includeEmptyVocs, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths);
87

  
88

  
89
    /**
90
     * Return a List of vocabularies that belong to the term type supplied
91
     *
92
     * @param termType The term type corresponding to the vocabularies of interest
93
     * @return a List of vocabularies
94
     */
95
    public <T extends DefinedTermBase> List<TermVocabulary<T>> findByTermType(TermType termType);
96

  
97

  
98
	/**
99
     * Returns term vocabularies that contain terms of a certain {@link TermType} e.g. Feature, Modifier, State.
100
     *
101
     * @param <TERMTYPE>
102
     * @param termType the {@link TermType} of the terms in the vocabulary and of the vocabulary
103
     * @param includeSubtypes if <code>true</code> all subtypes will be included for computation of the result
104
     * @param limit The maximum number of vocabularies returned (can be null for all vocabularies)
105
     * @param start The offset from the start of the result set (0 - based, can be null - equivalent of starting at the beginning of the recordset)
106
     * @param orderHints
107
     *            Supports path like <code>orderHints.propertyNames</code> which
108
     *            include *-to-one properties like createdBy.username or
109
     *            authorTeam.persistentTitleCache
110
     * @param propertyPaths properties to be initialized
111
     * @return a list of term vocabularies
112
     */
113
	public List<TermVocabulary> listByTermType(TermType termType, boolean includeSubtypes, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths);
114

  
115
	/**
116
	 * Returns all empty vocabularies.
117
	 * @param limit
118
	 * @param start
119
	 * @param orderHints
120
	 * @param propertyPaths
121
	 * @return
122
	 */
123
	public List<TermVocabulary> listEmpty(Integer limit, Integer start,List<OrderHint> orderHints, List<String> propertyPaths);
124

  
125
	/**
126
	 * Fills the response map with those term uuids which do exist in the requested map
127
	 * but not in the repository (missing terms). The map key is the vocabulary uuid in both cases.
128
	 * If parameter vocabularyRepsonse is not <code>null</code> the vocabularies will be fully loaded
129
	 * and returned within the map. The later is for using this method together with fast termloading.
130
	 * @param uuidsRequested
131
	 * @param uuidsRepsonse
132
	 * @param vocabularyResponse
133
	 */
134
	public void missingTermUuids(Map<UUID, Set<UUID>> uuidsRequested,
135
			Map<UUID, Set<UUID>> uuidsRepsonse,
136
			Map<UUID, TermVocabulary<?>> vocabularyResponse);
137

  
138
}
cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/hibernate/common/TermVocabularyDaoImpl.java
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.common;
11

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

  
19
import org.hibernate.Criteria;
20
import org.hibernate.Query;
21
import org.hibernate.criterion.Projections;
22
import org.hibernate.criterion.Restrictions;
23
import org.hibernate.envers.query.AuditEntity;
24
import org.hibernate.envers.query.AuditQuery;
25
import org.springframework.stereotype.Repository;
26

  
27
import eu.etaxonomy.cdm.model.common.DefinedTermBase;
28
import eu.etaxonomy.cdm.model.common.OrderedTermVocabulary;
29
import eu.etaxonomy.cdm.model.common.TermType;
30
import eu.etaxonomy.cdm.model.common.TermVocabulary;
31
import eu.etaxonomy.cdm.model.view.AuditEvent;
32
import eu.etaxonomy.cdm.persistence.dao.common.ITermVocabularyDao;
33
import eu.etaxonomy.cdm.persistence.query.OrderHint;
34

  
35
/**
36
 * @author a.mueller
37
 *
38
 */
39
@Repository
40
public class TermVocabularyDaoImpl extends IdentifiableDaoBase<TermVocabulary> implements
41
		ITermVocabularyDao {
42
	/**
43
	 * @param type
44
	 */
45
	public TermVocabularyDaoImpl() {
46
		super(TermVocabulary.class);
47
		indexedClasses = new Class[2];
48
		indexedClasses[0] = TermVocabulary.class;
49
		indexedClasses[1] = OrderedTermVocabulary.class;
50
	}
51

  
52
	public int countTerms(TermVocabulary termVocabulary) {
53
		AuditEvent auditEvent = getAuditEventFromContext();
54
		if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
55
		    Query query = getSession().createQuery("select count(term) from DefinedTermBase term where term.vocabulary = :vocabulary");
56
		    query.setParameter("vocabulary", termVocabulary);
57
		
58
		    return ((Long)query.uniqueResult()).intValue();
59
		} else {
60
			AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(type,auditEvent.getRevisionNumber());
61
			query.addProjection(AuditEntity.id().count("id"));
62
			query.add(AuditEntity.relatedId("vocabulary").eq(termVocabulary.getId()));
63
			return ((Number)query.getSingleResult()).intValue();
64
		}
65
	}
66

  
67
	public <T extends DefinedTermBase> List<T> getTerms(TermVocabulary<T> vocabulary,Integer pageSize, Integer pageNumber, List<OrderHint> orderHints,List<String> propertyPaths) {
68
		AuditEvent auditEvent = getAuditEventFromContext();
69
		if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
70
			Criteria criteria = getSession().createCriteria(DefinedTermBase.class);
71
			criteria.createCriteria("vocabulary").add(Restrictions.idEq(vocabulary.getId()));
72
		
73
		    if(pageSize != null) {
74
		    	criteria.setMaxResults(pageSize);
75
		        if(pageNumber != null) {
76
		        	criteria.setFirstResult(pageNumber * pageSize);
77
		        }
78
		    }
79
		    
80
		    this.addOrder(criteria, orderHints);
81
		    List<T> result = (List<T>)criteria.list();
82
		    defaultBeanInitializer.initializeAll(result, propertyPaths);
83
		    return result;
84
		} else {
85
			AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(type,auditEvent.getRevisionNumber());
86
			query.add(AuditEntity.relatedId("vocabulary").eq(vocabulary.getId()));
87
			
88
			if(pageSize != null) {
89
			    query.setMaxResults(pageSize);
90
		        if(pageNumber != null) {
91
		    	    query.setFirstResult(pageNumber * pageSize);
92
		        }
93
			}
94
			
95
			List<T> result = (List<T>)query.getResultList();
96
		    defaultBeanInitializer.initializeAll(result, propertyPaths);
97
			return result;
98
		}
99
	}
100

  
101
	public <T extends DefinedTermBase> TermVocabulary<T> findByUri(String termSourceUri, Class<T> clazz) {
102
		AuditEvent auditEvent = getAuditEventFromContext();
103
		if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
104
    		Query query = getSession().createQuery("select vocabulary from TermVocabulary vocabulary where vocabulary.termSourceUri= :termSourceUri");
105
	    	query.setParameter("termSourceUri", termSourceUri);
106
		 
107
		    return (TermVocabulary<T>)query.uniqueResult();
108
		} else {
109
			AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(type,auditEvent.getRevisionNumber());
110
			query.add(AuditEntity.property("termSourceUri").eq(termSourceUri));
111
			
112
			return (TermVocabulary<T>)query.getSingleResult();
113
		}
114
	}
115

  
116
//	public <T extends DefinedTermBase> List<TermVocabulary<T>> findByTermType(TermType termType) {
117
//
118
//		Query query = getSession().createQuery("select vocabulary from TermVocabulary vocabulary where vocabulary.termType= :termType");
119
//		query.setParameter("termType", termType);
120
//
121
//		return (List<TermVocabulary<T>>)query.list();
122
//
123
//	}
124
	
125
	public <T extends DefinedTermBase> List<TermVocabulary<T>> findByTermType(TermType termType) {
126
		
127
		Criteria criteria = getSession().createCriteria(type);
128
		criteria.add(Restrictions.eq("termType", termType));		
129
				
130
		//this.addOrder(criteria, orderHints);
131
		
132
		List<TermVocabulary<T>> result = (List<TermVocabulary<T>>)criteria.list();
133
	    defaultBeanInitializer.initializeAll(result, null);
134
		return result;
135
	}
136

  
137
	public <T extends DefinedTermBase> List<T> getTerms(TermVocabulary<T> termVocabulary, Integer pageSize,	Integer pageNumber) {
138
		return getTerms(termVocabulary, pageSize, pageNumber, null, null);
139
	}
140

  
141
	public <TERM extends DefinedTermBase> List<TermVocabulary<TERM>> listByTermClass(Class<TERM> clazz, Integer limit, Integer start,List<OrderHint> orderHints, List<String> propertyPaths) {
142
		checkNotInPriorView("TermVocabularyDao.listByTermClass(Class<TERM> clazz, Integer limit, Integer start,	List<OrderHint> orderHints, List<String> propertyPaths)");
143
		Criteria criteria = getSession().createCriteria(type);
144
		criteria.createAlias("terms", "trms").add(Restrictions.eq("trms.class", clazz.getSimpleName()));		
145
		criteria.setProjection(Projections.id());
146
		List<Integer> intermediateResults = criteria.list();
147
		
148
		if(intermediateResults.size() == 0) {
149
			return new ArrayList<TermVocabulary<TERM>>();
150
		}
151
		
152
		criteria = getSession().createCriteria(type);
153
		criteria.add(Restrictions.in("id", intermediateResults));
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
		List<TermVocabulary<TERM>> result = (List<TermVocabulary<TERM>>)criteria.list();
165
	    defaultBeanInitializer.initializeAll(result, propertyPaths);
166
		return result;
167
	}
168
	
169
	public <TERM extends DefinedTermBase> List<TermVocabulary<? extends TERM>> listByTermClass(Class<TERM> clazz, boolean includeSubclasses, boolean includeEmptyVocs, Integer limit, Integer start,List<OrderHint> orderHints, List<String> propertyPaths) {
170
		checkNotInPriorView("TermVocabularyDao.listByTermClass2(Class<TERM> clazz, Integer limit, Integer start,	List<OrderHint> orderHints, List<String> propertyPaths)");
171
		List<Integer> intermediateResults;
172
		
173
		if (includeSubclasses){
174
			String hql = " SELECT DISTINCT trm.vocabulary.id " +
175
					" FROM %s trm " +
176
					" GROUP BY trm.vocabulary ";
177
			hql = String.format(hql, clazz.getSimpleName());
178
			Query query = getSession().createQuery(hql);
179
			intermediateResults = query.list();
180
		}else{
181
			Criteria criteria = getSession().createCriteria(type);
182
			criteria.createAlias("terms", "trms").add(Restrictions.eq("trms.class", clazz.getSimpleName()));		
183
			criteria.setProjection(Projections.id());
184
			intermediateResults = criteria.list();
185
		}
186
		if (includeEmptyVocs){
187
			intermediateResults.addAll(getEmptyVocIds());
188
		}
189
			
190
		if(intermediateResults.size() == 0) {
191
			return new ArrayList<TermVocabulary<? extends TERM>>();
192
		}
193
		
194
		Criteria criteria = getSession().createCriteria(type);
195
		criteria.add(Restrictions.in("id", intermediateResults));
196
		
197
		if(limit != null) {
198
		    criteria.setMaxResults(limit);
199
	        if(start != null) {
200
	    	    criteria.setFirstResult(start);
201
	        }
202
		}
203
		
204
		this.addOrder(criteria, orderHints);
205
		
206
		List<TermVocabulary<? extends TERM>> result = (List<TermVocabulary<? extends TERM>>)criteria.list();
207
	    defaultBeanInitializer.initializeAll(result, propertyPaths);
208
		return result;
209
	}
210
	
211
	public List<TermVocabulary> listEmpty(Integer limit, Integer start,List<OrderHint> orderHints, List<String> propertyPaths) {
212
		checkNotInPriorView("TermVocabularyDao.listByTermClass2(Class<TERM> clazz, Integer limit, Integer start,	List<OrderHint> orderHints, List<String> propertyPaths)");
213
		List<Integer> intermediateResults;
214
		
215
		intermediateResults = getEmptyVocIds();
216
		
217
		Criteria criteria = getSession().createCriteria(type);
218
		criteria.add(Restrictions.in("id", intermediateResults));
219
		
220
		if(limit != null) {
221
		    criteria.setMaxResults(limit);
222
	        if(start != null) {
223
	    	    criteria.setFirstResult(start);
224
	        }
225
		}
226
		
227
		this.addOrder(criteria, orderHints);
228
		
229
		List<TermVocabulary> result = (List<TermVocabulary>)criteria.list();
230
	    defaultBeanInitializer.initializeAll(result, propertyPaths);
231
		return result;
232
	}
233
	
234
	@Override
235
	public void missingTermUuids(
236
			Map<UUID, Set<UUID>> uuidsRequested, 
237
			Map<UUID, Set<UUID>> uuidMissingTermsRepsonse, 
238
			Map<UUID, TermVocabulary<?>> vocabularyResponse){
239
		
240
		Set<UUID> missingTermCandidateUuids = new HashSet<UUID>();
241
		
242
		for (Set<UUID> uuidsPerVocSet : uuidsRequested.values()){
243
			missingTermCandidateUuids.addAll(uuidsPerVocSet);
244
		}
245
		
246
 		//search persisted subset of required (usually all) 
247
		String hql = " SELECT terms.uuid " +
248
				" FROM TermVocabulary voc join voc.terms terms  " +
249
				" WHERE terms.uuid IN (:uuids) " +
250
				" ORDER BY voc.uuid ";
251
		Query query = getSession().createQuery(hql);
252
		query.setParameterList("uuids", missingTermCandidateUuids);
253
		List<?> persistedUuids = query.list();
254

  
255
		
256
 		//fully load and initialize vocabularies if required
257
		if (vocabularyResponse != null){
258
			String hql2 = " SELECT DISTINCT voc " +
259
					" FROM TermVocabulary voc " +
260
						" LEFT JOIN FETCH voc.terms terms " +
261
						" LEFT JOIN FETCH terms.representations representations " +
262
						" LEFT JOIN FETCH voc.representations vocReps " +
263
					" 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
264
//					" WHERE  voc.uuid IN (:vocUuids) AND voc.terms is empty  " +
265
					" ORDER BY voc.uuid ";
266
			query = getSession().createQuery(hql2);
267
			query.setParameterList("termUuids",missingTermCandidateUuids);
268
			query.setParameterList("vocUuids",uuidsRequested.keySet());
269
			List<TermVocabulary> o = query.list();
270
			for (TermVocabulary<?> voc : o){
271
				vocabularyResponse.put(voc.getUuid(), voc);
272
			}
273
		}
274
		
275
		//compute missing terms
276
		if (missingTermCandidateUuids.size() == persistedUuids.size()){
277
			missingTermCandidateUuids.clear();
278
		}else{
279
			missingTermCandidateUuids.removeAll(persistedUuids);
280
			//add missing terms to response
281
			for (UUID vocUUID : uuidsRequested.keySet()){
282
				for (UUID termUuid : uuidsRequested.get(vocUUID)){
283
					if (missingTermCandidateUuids.contains(termUuid)){
284
						Set<UUID> r = uuidMissingTermsRepsonse.get(vocUUID);
285
						if (r == null){
286
							r = new HashSet<UUID>();
287
							uuidMissingTermsRepsonse.put(vocUUID, r);
288
						}
289
						r.add(termUuid);
290
					}
291
				}
292
			}
293
		}
294

  
295
		return;
296
	}
297

  
298
	/**
299
	 * @return
300
	 */
301
	private List<Integer> getEmptyVocIds() {
302
		List<Integer> intermediateResults;
303
		String hql = " SELECT voc.id " +
304
				" FROM TermVocabulary voc " +
305
				" WHERE voc.terms.size = 0 ";
306
		Query query = getSession().createQuery(hql);
307
		intermediateResults = query.list();
308
		return intermediateResults;
309
	}
310
}
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.common;
11

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

  
19
import org.hibernate.Criteria;
20
import org.hibernate.Query;
21
import org.hibernate.criterion.Projections;
22
import org.hibernate.criterion.Restrictions;
23
import org.hibernate.envers.query.AuditEntity;
24
import org.hibernate.envers.query.AuditQuery;
25
import org.springframework.stereotype.Repository;
26

  
27
import eu.etaxonomy.cdm.model.common.DefinedTermBase;
28
import eu.etaxonomy.cdm.model.common.OrderedTermVocabulary;
29
import eu.etaxonomy.cdm.model.common.TermType;
30
import eu.etaxonomy.cdm.model.common.TermVocabulary;
31
import eu.etaxonomy.cdm.model.view.AuditEvent;
32
import eu.etaxonomy.cdm.persistence.dao.common.ITermVocabularyDao;
33
import eu.etaxonomy.cdm.persistence.query.OrderHint;
34

  
35
/**
36
 * @author a.mueller
37
 *
38
 */
39
@Repository
40
public class TermVocabularyDaoImpl extends IdentifiableDaoBase<TermVocabulary> implements
41
		ITermVocabularyDao {
42
	/**
43
	 * @param type
44
	 */
45
	public TermVocabularyDaoImpl() {
46
		super(TermVocabulary.class);
47
		indexedClasses = new Class[2];
48
		indexedClasses[0] = TermVocabulary.class;
49
		indexedClasses[1] = OrderedTermVocabulary.class;
50
	}
51

  
52
	@Override
53
    public int countTerms(TermVocabulary termVocabulary) {
54
		AuditEvent auditEvent = getAuditEventFromContext();
55
		if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
56
		    Query query = getSession().createQuery("select count(term) from DefinedTermBase term where term.vocabulary = :vocabulary");
57
		    query.setParameter("vocabulary", termVocabulary);
58

  
59
		    return ((Long)query.uniqueResult()).intValue();
60
		} else {
61
			AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(type,auditEvent.getRevisionNumber());
62
			query.addProjection(AuditEntity.id().count("id"));
63
			query.add(AuditEntity.relatedId("vocabulary").eq(termVocabulary.getId()));
64
			return ((Number)query.getSingleResult()).intValue();
65
		}
66
	}
67

  
68
	@Override
69
    public <T extends DefinedTermBase> List<T> getTerms(TermVocabulary<T> vocabulary,Integer pageSize, Integer pageNumber, List<OrderHint> orderHints,List<String> propertyPaths) {
70
		AuditEvent auditEvent = getAuditEventFromContext();
71
		if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
72
			Criteria criteria = getSession().createCriteria(DefinedTermBase.class);
73
			criteria.createCriteria("vocabulary").add(Restrictions.idEq(vocabulary.getId()));
74

  
75
		    if(pageSize != null) {
76
		    	criteria.setMaxResults(pageSize);
77
		        if(pageNumber != null) {
78
		        	criteria.setFirstResult(pageNumber * pageSize);
79
		        }
80
		    }
81

  
82
		    this.addOrder(criteria, orderHints);
83
		    List<T> result = criteria.list();
84
		    defaultBeanInitializer.initializeAll(result, propertyPaths);
85
		    return result;
86
		} else {
87
			AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(type,auditEvent.getRevisionNumber());
88
			query.add(AuditEntity.relatedId("vocabulary").eq(vocabulary.getId()));
89

  
90
			if(pageSize != null) {
91
			    query.setMaxResults(pageSize);
92
		        if(pageNumber != null) {
93
		    	    query.setFirstResult(pageNumber * pageSize);
94
		        }
95
			}
96

  
97
			List<T> result = 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
    		Query query = getSession().createQuery("select vocabulary from TermVocabulary vocabulary where vocabulary.termSourceUri= :termSourceUri");
108
	    	query.setParameter("termSourceUri", termSourceUri);
109

  
110
		    return (TermVocabulary<T>)query.uniqueResult();
111
		} else {
112
			AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(type,auditEvent.getRevisionNumber());
113
			query.add(AuditEntity.property("termSourceUri").eq(termSourceUri));
114

  
115
			return (TermVocabulary<T>)query.getSingleResult();
116
		}
117
	}
118

  
119

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

  
125
	@Override
126
    @Deprecated
127
	public <TERM extends DefinedTermBase> List<TermVocabulary<? extends TERM>> listByTermClass(Class<TERM> clazz, boolean includeSubclasses, boolean includeEmptyVocs, Integer limit, Integer start,List<OrderHint> orderHints, List<String> propertyPaths) {
128
		checkNotInPriorView("TermVocabularyDao.listByTermClass2(Class<TERM> clazz, Integer limit, Integer start,	List<OrderHint> orderHints, List<String> propertyPaths)");
129
		List<Integer> intermediateResults;
130

  
131
		if (includeSubclasses){
132
			String hql = " SELECT DISTINCT trm.vocabulary.id " +
133
					" FROM %s trm " +
134
					" GROUP BY trm.vocabulary ";
135
			hql = String.format(hql, clazz.getSimpleName());
136
			Query query = getSession().createQuery(hql);
137
			intermediateResults = query.list();
138
		}else{
139
			Criteria criteria = getSession().createCriteria(type);
140
			criteria.createAlias("terms", "trms").add(Restrictions.eq("trms.class", clazz.getSimpleName()));
141
			criteria.setProjection(Projections.id());
142
			intermediateResults = criteria.list();
143
		}
144
		if (includeEmptyVocs){
145
			intermediateResults.addAll(getEmptyVocIds());
146
		}
147

  
148
		if(intermediateResults.size() == 0) {
149
			return new ArrayList<TermVocabulary<? extends TERM>>();
150
		}
151

  
152
		Criteria criteria = getSession().createCriteria(type);
153
		criteria.add(Restrictions.in("id", intermediateResults));
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
		List<TermVocabulary<? extends TERM>> result = criteria.list();
165
	    defaultBeanInitializer.initializeAll(result, propertyPaths);
166
		return result;
167
	}
168

  
169

  
170
//  public <T extends DefinedTermBase> List<TermVocabulary<T>> findByTermType(TermType termType) {
171
//
172
//      Query query = getSession().createQuery("select vocabulary from TermVocabulary vocabulary where vocabulary.termType= :termType");
173
//      query.setParameter("termType", termType);
174
//
175
//      return (List<TermVocabulary<T>>)query.list();
176
//
177
//  }
178

  
179
    @Override
180
    public <T extends DefinedTermBase> List<TermVocabulary<T>> findByTermType(TermType termType) {
181

  
182
        Criteria criteria = getSession().createCriteria(type);
183
        criteria.add(Restrictions.eq("termType", termType));
184

  
185
        //this.addOrder(criteria, orderHints);
186

  
187
        List<TermVocabulary<T>> result = criteria.list();
188
        defaultBeanInitializer.initializeAll(result, null);
189
        return result;
190
    }
191

  
192
	@Override
193
    public List<TermVocabulary> listByTermType(TermType termType, boolean includeSubTypes, Integer limit, Integer start,List<OrderHint> orderHints, List<String> propertyPaths) {
194
        checkNotInPriorView("TermVocabularyDao.listByTermType(TermType termType, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths)");
195

  
196
        Set<TermType> allTermTypes = new HashSet<TermType>();
197
        allTermTypes.add(termType);
198
        if (includeSubTypes){
199
            allTermTypes.addAll(termType.getGeneralizationOf(true));
200
        }
201

  
202
        Criteria criteria = getSession().createCriteria(type);
203
        criteria.add(Restrictions.in("termType", allTermTypes));
204

  
205
        if(limit != null) {
206
            criteria.setMaxResults(limit);
207
            if(start != null) {
208
                criteria.setFirstResult(start);
209
            }
210
        }
211

  
212
        this.addOrder(criteria, orderHints);
213

  
214
        List<TermVocabulary> result = criteria.list();
215
        defaultBeanInitializer.initializeAll(result, propertyPaths);
216
        return result;
217
    }
218

  
219

  
220
	@Override
221
    public List<TermVocabulary> listEmpty(Integer limit, Integer start,List<OrderHint> orderHints, List<String> propertyPaths) {
222
		checkNotInPriorView("TermVocabularyDao.listEmpty(Integer limit, Integer start,	List<OrderHint> orderHints, List<String> propertyPaths)");
223
		List<Integer> intermediateResults;
224

  
225
		intermediateResults = getEmptyVocIds();
226

  
227
		Criteria criteria = getSession().createCriteria(type);
228
		criteria.add(Restrictions.in("id", intermediateResults));
229

  
230
		if(limit != null) {
231
		    criteria.setMaxResults(limit);
232
	        if(start != null) {
233
	    	    criteria.setFirstResult(start);
234
	        }
235
		}
236

  
237
		this.addOrder(criteria, orderHints);
238

  
239
		List<TermVocabulary> result = criteria.list();
240
	    defaultBeanInitializer.initializeAll(result, propertyPaths);
241
		return result;
242
	}
243

  
244
	@Override
245
	public void missingTermUuids(
246
			Map<UUID, Set<UUID>> uuidsRequested,
247
			Map<UUID, Set<UUID>> uuidMissingTermsRepsonse,
248
			Map<UUID, TermVocabulary<?>> vocabularyResponse){
249

  
250
		Set<UUID> missingTermCandidateUuids = new HashSet<UUID>();
251

  
252
		for (Set<UUID> uuidsPerVocSet : uuidsRequested.values()){
253
			missingTermCandidateUuids.addAll(uuidsPerVocSet);
254
		}
255

  
256
 		//search persisted subset of required (usually all)
257
		String hql = " SELECT terms.uuid " +
258
				" FROM TermVocabulary voc join voc.terms terms  " +
259
				" WHERE terms.uuid IN (:uuids) " +
260
				" ORDER BY voc.uuid ";
261
		Query query = getSession().createQuery(hql);
262
		query.setParameterList("uuids", missingTermCandidateUuids);
263
		List<?> persistedUuids = query.list();
264

  
265

  
266
 		//fully load and initialize vocabularies if required
267
		if (vocabularyResponse != null){
268
			String hql2 = " SELECT DISTINCT voc " +
269
					" FROM TermVocabulary voc " +
270
						" LEFT JOIN FETCH voc.terms terms " +
271
						" LEFT JOIN FETCH terms.representations representations " +
272
						" LEFT JOIN FETCH voc.representations vocReps " +
273
					" 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
274
//					" WHERE  voc.uuid IN (:vocUuids) AND voc.terms is empty  " +
275
					" ORDER BY voc.uuid ";
276
			query = getSession().createQuery(hql2);
277
			query.setParameterList("termUuids",missingTermCandidateUuids);
278
			query.setParameterList("vocUuids",uuidsRequested.keySet());
279
			List<TermVocabulary> o = query.list();
280
			for (TermVocabulary<?> voc : o){
281
				vocabularyResponse.put(voc.getUuid(), voc);
282
			}
283
		}
284

  
285
		//compute missing terms
286
		if (missingTermCandidateUuids.size() == persistedUuids.size()){
287
			missingTermCandidateUuids.clear();
288
		}else{
289
			missingTermCandidateUuids.removeAll(persistedUuids);
290
			//add missing terms to response
291
			for (UUID vocUUID : uuidsRequested.keySet()){
292
				for (UUID termUuid : uuidsRequested.get(vocUUID)){
293
					if (missingTermCandidateUuids.contains(termUuid)){
294
						Set<UUID> r = uuidMissingTermsRepsonse.get(vocUUID);
295
						if (r == null){
296
							r = new HashSet<UUID>();
297
							uuidMissingTermsRepsonse.put(vocUUID, r);
298
						}
299
						r.add(termUuid);
300
					}
301
				}
302
			}
303
		}
304

  
305
		return;
306
	}
307

  
308
	/**
309
	 * @return
310
	 */
311
	private List<Integer> getEmptyVocIds() {
312
		List<Integer> intermediateResults;
313
		String hql = " SELECT voc.id " +
314
				" FROM TermVocabulary voc " +
315
				" WHERE voc.terms.size = 0 ";
316
		Query query = getSession().createQuery(hql);
317
		intermediateResults = query.list();
318
		return intermediateResults;
319
	}
320
}
cdmlib-persistence/src/test/java/eu/etaxonomy/cdm/persistence/dao/hibernate/common/TermVocabularyDaoImplTest.java
1
/**
2
* Copyright (C) 2009 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.common;
11

  
12
import static org.junit.Assert.assertEquals;
13
import static org.junit.Assert.assertFalse;
14

  
15
import java.io.FileNotFoundException;
16
import java.util.HashMap;
17
import java.util.HashSet;
18
import java.util.List;
19
import java.util.Map;
20
import java.util.Set;
21
import java.util.UUID;
22

  
23
import org.apache.log4j.Logger;
24
import org.junit.Assert;
25
import org.junit.Before;
26
import org.junit.Test;
27
import org.unitils.dbunit.annotation.DataSet;
28
import org.unitils.spring.annotation.SpringBeanByType;
29

  
30
import eu.etaxonomy.cdm.model.common.Language;
31
import eu.etaxonomy.cdm.model.common.Representation;
32
import eu.etaxonomy.cdm.model.common.TermType;
33
import eu.etaxonomy.cdm.model.common.TermVocabulary;
34
import eu.etaxonomy.cdm.model.location.Country;
35
import eu.etaxonomy.cdm.model.location.NamedArea;
36
import eu.etaxonomy.cdm.model.name.Rank;
37
import eu.etaxonomy.cdm.persistence.dao.common.ITermVocabularyDao;
38
import eu.etaxonomy.cdm.test.integration.CdmIntegrationTest;
39

  
40
/**
41
 * @author a.babadshanjan
42
 * @created 10.02.2009
43
 */
44
public class TermVocabularyDaoImplTest extends CdmIntegrationTest {
45
	@SuppressWarnings("unused")
46
	private static Logger logger = Logger.getLogger(TermVocabularyDaoImplTest.class);
47

  
48
	@SpringBeanByType
49
	private ITermVocabularyDao dao;
50

  
51
	@Before
52
	public void setUp() {
53
	}
54

  
55
	@Test
56
	public void testListVocabularyByClass() {
57
		//test class with no subclasses
58
		List<TermVocabulary<? extends Rank>> rankVocabularies = dao.listByTermClass(Rank.class, false, false, null, null, null, null);
59
		assertFalse("There should be at least one vocabulary containing terms of class Rank",rankVocabularies.isEmpty());
60
		assertEquals("There should be only one vocabulary containing terms of class Rank",1,rankVocabularies.size());
61

  
62

  
63
		rankVocabularies = dao.listByTermClass(Rank.class, true, false, null, null, null, null);
64
		assertFalse("There should be at least one vocabulary containing terms of class Rank",rankVocabularies.isEmpty());
65
		assertEquals("There should be only one vocabulary containing terms of class Rank",1,rankVocabularies.size());
66

  
67
		//with subclasses
68
		List<TermVocabulary<? extends NamedArea>> namedAreaVocabularies = dao.listByTermClass(NamedArea.class, true, false, null, null, null, null);
69
		int subclassedSize = namedAreaVocabularies.size();
70
		assertEquals("There should be 3 vocabularies (TdwgAreas, Continents, WaterbodyOrCountries)", 4, subclassedSize);
71

  
72
		List<TermVocabulary<? extends NamedArea>> namedAreaOnlyVocabularies = dao.listByTermClass(NamedArea.class, false, false, null, null, null, null);
73
		List<TermVocabulary<? extends Country>> countryVocabularies = dao.listByTermClass(Country.class, false, false, null, null, null, null);
74
		int sumOfSingleSizes = namedAreaOnlyVocabularies.size() + countryVocabularies.size();
75
		assertEquals("number of NamedArea and subclasses should be same as sum of all single vocabularies", subclassedSize, sumOfSingleSizes);
76

  
77
	}
78

  
79
	@Test
80
	@DataSet("TermVocabularyDaoImplTest.testListVocabularyEmpty.xml")
81
	public void testListVocabularyByClassEmpty() {
82
		//test include empty
83
		List<TermVocabulary<? extends NamedArea>> namedAreaVocabulariesAndEmpty = dao.listByTermClass(NamedArea.class, true, true, null, null, null, null);
84
		assertEquals("There should be 1 vocabulary (the empty one)", 1, namedAreaVocabulariesAndEmpty.size());
85

  
86
		List<TermVocabulary<? extends Language>> languageVocabulariesAndEmpty = dao.listByTermClass(Language.class, true, true, null, null, null, null);
87
		assertEquals("There should be 2 vocabularies, the empty one and the one that has a language term in", 2, languageVocabulariesAndEmpty.size());
88
	}
89

  
90
	@Test
91
	@DataSet("TermVocabularyDaoImplTest.testListVocabularyEmpty.xml")
92
	public void testListVocabularyEmpty() {
93
		//test class with no subclasses
94
		List<TermVocabulary> emptyVocs = dao.listEmpty(null, null, null, null);
95
		assertFalse("There should be at least one vocabulary containing no terms",emptyVocs.isEmpty());
96
		assertEquals("There should be only one vocabulary containing terms of class Rank",1,emptyVocs.size());
97
		UUID uuidEmptyVoc = UUID.fromString("f253962f-d787-4b16-b2d2-e645da73ae4f");
98
		assertEquals("The empty vocabulary should be the one defined", uuidEmptyVoc, emptyVocs.get(0).getUuid());
99
	}
100

  
101
	@Test
102
	public void testMissingTermUuids() {
103
		Set<UUID> uuidSet = new HashSet<UUID>();
104
		uuidSet.add(Language.uuidEnglish);
105
		uuidSet.add(Language.uuidFrench);
106
		UUID uuidNotExisting = UUID.fromString("e93e8c10-d9d2-4ad6-9907-952da6d139c4");
107
		uuidSet.add(uuidNotExisting);
108
		Map<UUID, Set<UUID>> uuidVocs = new HashMap<UUID, Set<UUID>>();
109
		uuidVocs.put( Language.uuidLanguageVocabulary, uuidSet);
110
		Map<UUID, Set<UUID>> notExisting = new HashMap<UUID, Set<UUID>>();
111
		Map<UUID, TermVocabulary<?>> vocabularyMap = new HashMap<UUID, TermVocabulary<?>>();
112

  
113
		dao.missingTermUuids(uuidVocs, notExisting, vocabularyMap);
114

  
115
		//assert missing terms
116
		assertEquals(Integer.valueOf(1), Integer.valueOf(notExisting.keySet().size()));
117
		assertEquals(Language.uuidLanguageVocabulary, notExisting.keySet().iterator().next());
118
		Set<UUID> missingLanguageTerms = notExisting.get(Language.uuidLanguageVocabulary );
119
		assertEquals(Integer.valueOf(1), Integer.valueOf(missingLanguageTerms.size()));
120
		assertEquals(uuidNotExisting, missingLanguageTerms.iterator().next());
121
	}
122

  
123
	@Test
124
    public void testTitleCacheCreation() {
125

  
126
	    //prepare
127
	    UUID vocUuid = UUID.fromString("a7a2fbe4-3a35-4ec0-b2b2-2298c3ebdf57");
128
	    TermVocabulary<?> newVoc = TermVocabulary.NewInstance(TermType.Modifier);
129
	    newVoc.setUuid(vocUuid);
130

  
131
	    //default titleCache
132
	    dao.save(newVoc);
133
	    newVoc.setProtectedTitleCache(true);  //make sure we use the title cache created during save by listeners
134
	    String emptyLabel = newVoc.getTitleCache();
135
	    //this value may need to be changed when the default cache generation changes
136
	    Assert.assertEquals("TitleCache should use default title generation", "TermVocabulary<a7a2fbe4-3a35-4ec0-b2b2-2298c3ebdf57>", emptyLabel);
137

  
138
	    //only German
139
	    newVoc.setProtectedTitleCache(false);
140
	    Representation newRepresentation = Representation.NewInstance("Beschreibung", "Deutsches Label", "Abk.", Language.GERMAN());
141
	    newVoc.addRepresentation(newRepresentation);
142
	    dao.saveOrUpdate(newVoc);
143
	    newVoc.setProtectedTitleCache(true);
144
	    Assert.assertEquals("German Label should be new title cache", "Deutsches Label", newVoc.getTitleCache());
145

  
146
	    //German and English
147
	    newVoc.setProtectedTitleCache(false);
148
        Representation englishRepresentation = Representation.NewInstance("Description", "English label", "Abbrev.", Language.DEFAULT());
149
        newVoc.addRepresentation(englishRepresentation);
150
        dao.saveOrUpdate(newVoc);
151
        newVoc.setProtectedTitleCache(true);
152
        Assert.assertEquals("English Label should be new title cache", "English label", newVoc.getTitleCache());
153

  
154
        //Change English label
155
        newVoc.setProtectedTitleCache(false);
156
        newVoc.setLabel("New English label");
157
        dao.saveOrUpdate(newVoc);
158
        newVoc.setProtectedTitleCache(true);
159
        Assert.assertEquals("English (default language) label should be new English label", "New English label", newVoc.getTitleCache());
160

  
161
        //Remove English
162
        newVoc.setProtectedTitleCache(false);
163
        newVoc.removeRepresentation(englishRepresentation);
164
        dao.saveOrUpdate(newVoc);
165
        newVoc.setProtectedTitleCache(true);
166
        Assert.assertEquals("German Label should be new title cache again as English representation is not there anymore", "Deutsches Label", newVoc.getTitleCache());
167

  
168
	}
169

  
170
    @Override
171
    public void createTestDataSet() throws FileNotFoundException {}
1
/**
2
* Copyright (C) 2009 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.common;
11

  
12
import static org.junit.Assert.assertEquals;
13
import static org.junit.Assert.assertFalse;
14

  
15
import java.io.FileNotFoundException;
16
import java.util.HashMap;
17
import java.util.HashSet;
18
import java.util.List;
19
import java.util.Map;
20
import java.util.Set;
21
import java.util.UUID;
22

  
23
import org.apache.log4j.Logger;
24
import org.junit.Assert;
25
import org.junit.Before;
26
import org.junit.Test;
27
import org.unitils.dbunit.annotation.DataSet;
28
import org.unitils.spring.annotation.SpringBeanByType;
29

  
30
import eu.etaxonomy.cdm.model.common.Language;
31
import eu.etaxonomy.cdm.model.common.Representation;
32
import eu.etaxonomy.cdm.model.common.TermType;
33
import eu.etaxonomy.cdm.model.common.TermVocabulary;
34
import eu.etaxonomy.cdm.model.location.Country;
35
import eu.etaxonomy.cdm.model.location.NamedArea;
36
import eu.etaxonomy.cdm.model.name.Rank;
37
import eu.etaxonomy.cdm.persistence.dao.common.ITermVocabularyDao;
38
import eu.etaxonomy.cdm.test.integration.CdmIntegrationTest;
39

  
40
/**
41
 * @author a.babadshanjan
42
 * @created 10.02.2009
43
 */
44
public class TermVocabularyDaoImplTest extends CdmIntegrationTest {
45
	@SuppressWarnings("unused")
46
	private static Logger logger = Logger.getLogger(TermVocabularyDaoImplTest.class);
47

  
48
	@SpringBeanByType
49
	private ITermVocabularyDao dao;
50

  
51
	@Before
52
	public void setUp() {}
53

  
54
   @Test
55
    public void testListVocabularyByType() {
56
        //test class with no subclasses
57
        List<TermVocabulary> rankVocabularies = dao.listByTermType(TermType.Rank, false, null, null, null, null);
58
        assertFalse("There should be at least one vocabulary containing terms of type Rank", rankVocabularies.isEmpty());
59
        assertEquals("There should be only one vocabulary containing terms of type Rank", 1, rankVocabularies.size());
60

  
61
        //include subtype, but termtype has no subtype
62
        rankVocabularies = dao.listByTermType(TermType.Rank, true, null, null, null, null);
63
        assertFalse("There should be at least one vocabulary containing terms of type Rank", rankVocabularies.isEmpty());
64
        assertEquals("There should be only one vocabulary containing terms of type Rank", 1, rankVocabularies.size());
65

  
66
        //with different classes
67
        List<TermVocabulary> namedAreaVocabularies = dao.listByTermType(TermType.NamedArea, true, null, null, null, null);
68
        int subclassedSize = namedAreaVocabularies.size();
69
        assertEquals("There should be 4 vocabularies (TdwgAreas, Continents, Waterbody, Countries)", 4, subclassedSize);
70

  
71
        //with sub types
72
        List<TermVocabulary> scopeVocabularies = dao.listByTermType(TermType.Scope, true, null, null, null, null);
73
        int subtypeSize = scopeVocabularies.size();
74
        assertEquals("There should be 6 vocabularies (Scope, Sex, Stage, 3 x KindOfUnit)", 6, subtypeSize);
75

  
76
        List<TermVocabulary> scopeOnlyVocabularies = dao.listByTermType(TermType.Scope, false, null, null, null, null);
77
        assertEquals("Scope only vocabularies w/o subtypes should be 1", 1, scopeOnlyVocabularies.size());
78
        List<TermVocabulary> stageVocabularies = dao.listByTermType(TermType.Stage, false, null, null, null, null);
79
        assertEquals("Stage only vocabularies should be 1", 1, stageVocabularies.size());
80
    }
81

  
82

  
83
    @Test
84
    @DataSet("TermVocabularyDaoImplTest.testListVocabularyEmpty.xml")
85
    public void testListVocabularyByTypeEmpty() {
86
        List<TermVocabulary> emptyNamedAreas = dao.listByTermType(TermType.NamedArea, true, null, null, null, null);
87
        assertEquals("There should be no vocabulary, as we do not return ALL empty vocabularies of ANY type anymore", 0, emptyNamedAreas.size());
88

  
89
        List<TermVocabulary> languageVocabulariesAndEmpty = dao.listByTermType(TermType.Language, true, null, null, null, null);
90
        assertEquals("There should be 2 vocabularies, the empty one and the one that has a language term in", 2, languageVocabulariesAndEmpty.size());
91
    }
92

  
93

  
94
	@Test
95
	public void testListVocabularyByClass() {
96
		//test class with no subclasses
97
		List<TermVocabulary<? extends Rank>> rankVocabularies = dao.listByTermClass(Rank.class, false, false, null, null, null, null);
98
		assertFalse("There should be at least one vocabulary containing terms of class Rank",rankVocabularies.isEmpty());
99
		assertEquals("There should be only one vocabulary containing terms of class Rank",1,rankVocabularies.size());
100

  
101
		rankVocabularies = dao.listByTermClass(Rank.class, true, false, null, null, null, null);
102
		assertFalse("There should be at least one vocabulary containing terms of class Rank",rankVocabularies.isEmpty());
103
		assertEquals("There should be only one vocabulary containing terms of class Rank",1,rankVocabularies.size());
104

  
105
		//with subclasses
106
		List<TermVocabulary<? extends NamedArea>> namedAreaVocabularies = dao.listByTermClass(NamedArea.class, true, false, null, null, null, null);
107
		int subclassedSize = namedAreaVocabularies.size();
108
		assertEquals("There should be 3 vocabularies (TdwgAreas, Continents, WaterbodyOrCountries)", 4, subclassedSize);
109

  
110
		List<TermVocabulary<? extends NamedArea>> namedAreaOnlyVocabularies = dao.listByTermClass(NamedArea.class, false, false, null, null, null, null);
111
		List<TermVocabulary<? extends Country>> countryVocabularies = dao.listByTermClass(Country.class, false, false, null, null, null, null);
112
		int sumOfSingleSizes = namedAreaOnlyVocabularies.size() + countryVocabularies.size();
113
		assertEquals("number of NamedArea and subclasses should be same as sum of all single vocabularies", subclassedSize, sumOfSingleSizes);
114
	}
115

  
116
	@Test
117
	@DataSet("TermVocabularyDaoImplTest.testListVocabularyEmpty.xml")
118
	public void testListVocabularyByClassEmpty() {
119
		//test include empty
120
		List<TermVocabulary<? extends NamedArea>> namedAreaVocabulariesAndEmpty = dao.listByTermClass(NamedArea.class, true, true, null, null, null, null);
121
		assertEquals("There should be 1 vocabulary (the empty one)", 1, namedAreaVocabulariesAndEmpty.size());
122

  
123
		List<TermVocabulary<? extends Language>> languageVocabulariesAndEmpty = dao.listByTermClass(Language.class, true, true, null, null, null, null);
124
		assertEquals("There should be 2 vocabularies, the empty one and the one that has a language term in", 2, languageVocabulariesAndEmpty.size());
125
	}
126

  
127
	@Test
128
	@DataSet("TermVocabularyDaoImplTest.testListVocabularyEmpty.xml")
129
	public void testListVocabularyEmpty() {
130
		//test class with no subclasses
131
		List<TermVocabulary> emptyVocs = dao.listEmpty(null, null, null, null);
132
		assertFalse("There should be at least one vocabulary containing no terms",emptyVocs.isEmpty());
133
		assertEquals("There should be only one vocabulary containing terms of class Rank",1,emptyVocs.size());
134
		UUID uuidEmptyVoc = UUID.fromString("f253962f-d787-4b16-b2d2-e645da73ae4f");
135
		assertEquals("The empty vocabulary should be the one defined", uuidEmptyVoc, emptyVocs.get(0).getUuid());
136
	}
137

  
138
	@Test
139
	public void testMissingTermUuids() {
140
		Set<UUID> uuidSet = new HashSet<UUID>();
141
		uuidSet.add(Language.uuidEnglish);
142
		uuidSet.add(Language.uuidFrench);
143
		UUID uuidNotExisting = UUID.fromString("e93e8c10-d9d2-4ad6-9907-952da6d139c4");
144
		uuidSet.add(uuidNotExisting);
145
		Map<UUID, Set<UUID>> uuidVocs = new HashMap<UUID, Set<UUID>>();
146
		uuidVocs.put( Language.uuidLanguageVocabulary, uuidSet);
147
		Map<UUID, Set<UUID>> notExisting = new HashMap<UUID, Set<UUID>>();
148
		Map<UUID, TermVocabulary<?>> vocabularyMap = new HashMap<UUID, TermVocabulary<?>>();
149

  
150
		dao.missingTermUuids(uuidVocs, notExisting, vocabularyMap);
151

  
152
		//assert missing terms
153
		assertEquals(Integer.valueOf(1), Integer.valueOf(notExisting.keySet().size()));
154
		assertEquals(Language.uuidLanguageVocabulary, notExisting.keySet().iterator().next());
155
		Set<UUID> missingLanguageTerms = notExisting.get(Language.uuidLanguageVocabulary );
156
		assertEquals(Integer.valueOf(1), Integer.valueOf(missingLanguageTerms.size()));
157
		assertEquals(uuidNotExisting, missingLanguageTerms.iterator().next());
158
	}
159

  
160
	@Test
161
    public void testTitleCacheCreation() {
162

  
163
	    //prepare
164
	    UUID vocUuid = UUID.fromString("a7a2fbe4-3a35-4ec0-b2b2-2298c3ebdf57");
165
	    TermVocabulary<?> newVoc = TermVocabulary.NewInstance(TermType.Modifier);
166
	    newVoc.setUuid(vocUuid);
167

  
168
	    //default titleCache
169
	    dao.save(newVoc);
170
	    newVoc.setProtectedTitleCache(true);  //make sure we use the title cache created during save by listeners
171
	    String emptyLabel = newVoc.getTitleCache();
172
	    //this value may need to be changed when the default cache generation changes
173
	    Assert.assertEquals("TitleCache should use default title generation", "TermVocabulary<a7a2fbe4-3a35-4ec0-b2b2-2298c3ebdf57>", emptyLabel);
174

  
175
	    //only German
176
	    newVoc.setProtectedTitleCache(false);
177
	    Representation newRepresentation = Representation.NewInstance("Beschreibung", "Deutsches Label", "Abk.", Language.GERMAN());
178
	    newVoc.addRepresentation(newRepresentation);
179
	    dao.saveOrUpdate(newVoc);
180
	    newVoc.setProtectedTitleCache(true);
181
	    Assert.assertEquals("German Label should be new title cache", "Deutsches Label", newVoc.getTitleCache());
182

  
183
	    //German and English
184
	    newVoc.setProtectedTitleCache(false);
185
        Representation englishRepresentation = Representation.NewInstance("Description", "English label", "Abbrev.", Language.DEFAULT());
186
        newVoc.addRepresentation(englishRepresentation);
187
        dao.saveOrUpdate(newVoc);
188
        newVoc.setProtectedTitleCache(true);
189
        Assert.assertEquals("English Label should be new title cache", "English label", newVoc.getTitleCache());
190

  
191
        //Change English label
192
        newVoc.setProtectedTitleCache(false);
193
        newVoc.setLabel("New English label");
194
        dao.saveOrUpdate(newVoc);
195
        newVoc.setProtectedTitleCache(true);
196
        Assert.assertEquals("English (default language) label should be new English label", "New English label", newVoc.getTitleCache());
197

  
198
        //Remove English
199
        newVoc.setProtectedTitleCache(false);
200
        newVoc.removeRepresentation(englishRepresentation);
201
        dao.saveOrUpdate(newVoc);
202
        newVoc.setProtectedTitleCache(true);
203
        Assert.assertEquals("German Label should be new title cache again as English representation is not there anymore", "Deutsches Label", newVoc.getTitleCache());
204

  
205
	}
206

  
207
    @Override
208
    public void createTestDataSet() throws FileNotFoundException {}
172 209
}
cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/IVocabularyService.java
1
/**
2
* Copyright (C) 2009 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.api.service;
11

  
12
import java.util.List;
13

  
14
import eu.etaxonomy.cdm.api.service.pager.Pager;
15
import eu.etaxonomy.cdm.model.common.DefinedTermBase;
16
import eu.etaxonomy.cdm.model.common.Language;
17
import eu.etaxonomy.cdm.model.common.TermType;
18
import eu.etaxonomy.cdm.model.common.TermVocabulary;
19
import eu.etaxonomy.cdm.persistence.query.OrderHint;
20

  
21
public interface IVocabularyService extends IIdentifiableEntityService<TermVocabulary> {
22

  
23
    /**
24
     * Returns term vocabularies that contain terms of a certain class e.g. Feature, Modifier, State.
25
     *
26
     * @param <TERM>
27
     * @param clazz the term class of the terms in the vocabulary
28
     * @param limit The maximum number of vocabularies returned (can be null for all vocabularies)
29
     * @param start The offset from the start of the result set (0 - based, can be null - equivalent of starting at the beginning of the recordset)
30
     * @param orderHints
31
     *            Supports path like <code>orderHints.propertyNames</code> which
32
	 *            include *-to-one properties like createdBy.username or
33
	 *            authorTeam.persistentTitleCache
34
     * @param propertyPaths properties to be initialized
35
     * @return a list of term vocabularies
36
     * @see #listByTermClass(Class, boolean, Integer, Integer, List, List)
37
     */
38
	public <TERM extends DefinedTermBase> List<TermVocabulary<TERM>> listByTermClass(Class<TERM> clazz, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths);
39

  
40
	   /**
41
     * Returns term vocabularies that contain terms of a certain class e.g. Feature, Modifier, State.
42
     *
43
     * @param <TERM>
44
     * @param clazz the term class of the terms in the vocabulary
45
     * @param includeSubclasses if <code>true</code> all subclasses of clazz will be included for computation of the result
46
     * @param includeEmptyVocs if <code>true</code> all vocabularies that do not contain any term will be included in the result
47
     * @param limit The maximum number of vocabularies returned (can be null for all vocabularies)
48
     * @param start The offset from the start of the result set (0 - based, can be null - equivalent of starting at the beginning of the recordset)
49
     * @param orderHints
50
     *            Supports path like <code>orderHints.propertyNames</code> which
51
	 *            include *-to-one properties like createdBy.username or
52
	 *            authorTeam.persistentTitleCache
53
     * @param propertyPaths properties to be initialized
54
     * @return a list of term vocabularies
55
     * @see #listByTermClass(Class, Integer, Integer, List, List)
56
     */
57
	public <TERM extends DefinedTermBase> List<TermVocabulary<? extends TERM>> listByTermClass(Class<TERM> clazz, boolean includeSubclasses, boolean includeEmptyVocs, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths);
58

  
59

  
60
	/**
61
	 * Returns Language Vocabulary
62
	 * @return
63
	 */
64
	//TODO candidate for harmonization: rename to loadLanguageVocabulary(...
65
	public TermVocabulary<Language> getLanguageVocabulary();
66

  
67
	/**
68
	 * Returns a list of terms belonging to the vocabulary passed as an argument
69
	 *
70
	 * @param vocabulary The vocabulary for which the list of terms is desired
71
	 * @param limit The maximum number of terms returned (can be null for all terms in the vocabulary)
72
	 * @param start The offset from the start of the result set (0 - based, can be null - equivalent of starting at the beginning of the recordset)
73
	 * @param orderHints
74
	 *            Supports path like <code>orderHints.propertyNames</code> which
75
	 *            include *-to-one properties like createdBy.username or
76
	 *            authorTeam.persistentTitleCache
77
	 * @param propertyPaths properties to be initialized
78
	 * @return a paged list of terms
79
	 */
80
	//TODO candidate for harmonization: rename to getTerms(...
81
	public Pager<DefinedTermBase> getTerms(TermVocabulary vocabulary, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths);
82
	
83
	/**
84
	 * Returns a list of term vocabularies corresponding to a term type
85
	 *
86
	 * @param termType The term type for which the list of vocabularies is desired
87
	 * @return a list of vocabularies
88
	 */
89
	public <T extends DefinedTermBase> List<TermVocabulary<T>> findByTermType(TermType termType);
90

  
91
}
1
/**
2
* Copyright (C) 2009 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.api.service;
11

  
12
import java.util.List;
13

  
14
import eu.etaxonomy.cdm.api.service.pager.Pager;
15
import eu.etaxonomy.cdm.model.common.DefinedTermBase;
16
import eu.etaxonomy.cdm.model.common.Language;
17
import eu.etaxonomy.cdm.model.common.TermType;
18
import eu.etaxonomy.cdm.model.common.TermVocabulary;
19
import eu.etaxonomy.cdm.persistence.query.OrderHint;
20

  
21
public interface IVocabularyService extends IIdentifiableEntityService<TermVocabulary> {
22

  
23
    /**
24
     * Returns term vocabularies that contain terms of a certain class e.g. Feature, Modifier, State.
25
     *
26
     * @param <TERM>
27
     * @param clazz the term class of the terms in the vocabulary
28
     * @param limit The maximum number of vocabularies returned (can be null for all vocabularies)
29
     * @param start The offset from the start of the result set (0 - based, can be null - equivalent of starting at the beginning of the recordset)
30
     * @param orderHints
31
     *            Supports path like <code>orderHints.propertyNames</code> which
32
	 *            include *-to-one properties like createdBy.username or
33
	 *            authorTeam.persistentTitleCache
34
     * @param propertyPaths properties to be initialized
35
     * @return a list of term vocabularies
36
     * @see #listByTermClass(Class, boolean, Integer, Integer, List, List)
37
     * @deprecated use {@link #listByTermType(TermType, boolean, boolean, Integer, Integer, List, List)} instead.
38
     * May be removed in future versions.
39
     */
40
    @Deprecated
41
	public <TERM extends DefinedTermBase> List<TermVocabulary<TERM>> listByTermClass(Class<TERM> clazz, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths);
42

  
43
	/**
44
     * Returns term vocabularies that contain terms of a certain class e.g. Feature, Modifier, State.
45
     *
46
     * @param <TERM>
47
     * @param clazz the term class of the terms in the vocabulary
48
     * @param includeSubclasses if <code>true</code> all subclasses of clazz will be included for computation of the result
49
     * @param includeEmptyVocs if <code>true</code> all vocabularies that do not contain any term will be included in the result
50
     * @param limit The maximum number of vocabularies returned (can be null for all vocabularies)
51
     * @param start The offset from the start of the result set (0 - based, can be null - equivalent of starting at the beginning of the recordset)
52
     * @param orderHints
53
     *            Supports path like <code>orderHints.propertyNames</code> which
54
	 *            include *-to-one properties like createdBy.username or
55
	 *            authorTeam.persistentTitleCache
56
     * @param propertyPaths properties to be initialized
57
     * @return a list of term vocabularies
58
     * @see #listByTermClass(Class, Integer, Integer, List, List)
59
     * @deprecated use {@link #listByTermType(TermType, boolean, boolean, Integer, Integer, List, List)} instead.
60
     * May be removed in future versions.
61
     */
62
	@Deprecated
63
	public <TERM extends DefinedTermBase> List<TermVocabulary<? extends TERM>> listByTermClass(Class<TERM> clazz, boolean includeSubclasses, boolean includeEmptyVocs, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths);
64

  
65
//	/**
66
//     * Returns term vocabularies that contain terms of a certain {@link TermType} e.g. Feature, Modifier, State.
67
//     *
68
//     * @param <TERMTYPE>
69
//     * @param termType the {@link TermType} of the terms in the vocabulary and of the vocabulary
70
//     * @param includeSubtypes if <code>true</code> all subtypes will be included for computation of the result
71
//     * @param includeEmptyVocs if <code>true</code> all vocabularies that do not contain any term will be included in the result
72
//     * @param limit The maximum number of vocabularies returned (can be null for all vocabularies)
73
//     * @param start The offset from the start of the result set (0 - based, can be null - equivalent of starting at the beginning of the recordset)
74
//     * @param orderHints
75
//     *            Supports path like <code>orderHints.propertyNames</code> which
76
//     *            include *-to-one properties like createdBy.username or
77
//     *            authorTeam.persistentTitleCache
78
//     * @param propertyPaths properties to be initialized
79
//     * @return a list of term vocabularies
80
//     */
81
//    public List<TermVocabulary> listByTermType(TermType termType, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths);
82
//
83

  
84
    /**
85
     * Returns term vocabularies that contain terms of a certain {@link TermType} e.g. Feature, Modifier, State.
86
     *
87
     * @param <TERMTYPE>
88
     * @param termType the {@link TermType} of the terms in the vocabulary and of the vocabulary
89
     * @param includeSubTypes if <code>true</code> all subtypes will be included for computation of the result
90
     * @param limit The maximum number of vocabularies returned (can be null for all vocabularies)
91
     * @param start The offset from the start of the result set (0 - based, can be null - equivalent of starting at the beginning of the recordset)
92
     * @param orderHints
93
     *            Supports path like <code>orderHints.propertyNames</code> which
94
     *            include *-to-one properties like createdBy.username or
95
     *            authorTeam.persistentTitleCache
96
     * @param propertyPaths properties to be initialized
97
     * @return a list of term vocabularies
98
     */
99
    public List<TermVocabulary> listByTermType(TermType termType, boolean includeSubTypes, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths);
100

  
101
	/**
102
	 * Returns Language Vocabulary
103
	 * @return
104
	 */
105
	//TODO candidate for harmonization: rename to loadLanguageVocabulary(...
106
	public TermVocabulary<Language> getLanguageVocabulary();
107

  
108
	/**
109
	 * Returns a list of terms belonging to the vocabulary passed as an argument
110
	 *
111
	 * @param vocabulary The vocabulary for which the list of terms is desired
112
	 * @param limit The maximum number of terms returned (can be null for all terms in the vocabulary)
113
	 * @param start The offset from the start of the result set (0 - based, can be null - equivalent of starting at the beginning of the recordset)
114
	 * @param orderHints
115
	 *            Supports path like <code>orderHints.propertyNames</code> which
116
	 *            include *-to-one properties like createdBy.username or
117
	 *            authorTeam.persistentTitleCache
118
	 * @param propertyPaths properties to be initialized
119
	 * @return a paged list of terms
120
	 */
121
	//TODO candidate for harmonization: rename to getTerms(...
122
	public Pager<DefinedTermBase> getTerms(TermVocabulary vocabulary, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths);
123

  
124
	/**
125
	 * Returns a list of term vocabularies corresponding to a term type
126
	 *
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff