Project

General

Profile

Download (15.5 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2007 EDIT
3
* European Distributed Institute of Taxonomy 
4
* http://www.e-taxonomy.eu
5
* 
6
* The contents of this file are subject to the Mozilla Public License Version 1.1
7
* See LICENSE.TXT at the top of this package for the full license terms.
8
*/
9

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

    
12
import java.util.ArrayList;
13
import java.util.List;
14
import java.util.UUID;
15

    
16
import org.apache.log4j.Logger;
17
import org.apache.lucene.analysis.standard.StandardAnalyzer;
18
import org.apache.lucene.queryParser.ParseException;
19
import org.apache.lucene.queryParser.QueryParser;
20
import org.hibernate.Criteria;
21
import org.hibernate.Query;
22
import org.hibernate.Session;
23
import org.hibernate.criterion.Criterion;
24
import org.hibernate.criterion.Order;
25
import org.hibernate.criterion.Projections;
26
import org.hibernate.criterion.Restrictions;
27
import org.hibernate.envers.query.AuditEntity;
28
import org.hibernate.envers.query.AuditQuery;
29
import org.hibernate.search.FullTextSession;
30
import org.hibernate.search.Search;
31
import org.hibernate.search.SearchFactory;
32

    
33
import eu.etaxonomy.cdm.model.common.CdmBase;
34
import eu.etaxonomy.cdm.model.common.Credit;
35
import eu.etaxonomy.cdm.model.common.IIdentifiableEntity;
36
import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
37
import eu.etaxonomy.cdm.model.common.IdentifiableSource;
38
import eu.etaxonomy.cdm.model.common.LSID;
39
import eu.etaxonomy.cdm.model.common.UuidAndTitleCache;
40
import eu.etaxonomy.cdm.model.media.Rights;
41
import eu.etaxonomy.cdm.persistence.dao.QueryParseException;
42
import eu.etaxonomy.cdm.persistence.dao.common.IIdentifiableDao;
43
import eu.etaxonomy.cdm.persistence.query.MatchMode;
44
import eu.etaxonomy.cdm.persistence.query.OrderHint;
45

    
46

    
47
public class IdentifiableDaoBase<T extends IdentifiableEntity> extends AnnotatableDaoImpl<T> implements IIdentifiableDao<T>{
48
	@SuppressWarnings("unused")
49
	private static final Logger logger = Logger.getLogger(IdentifiableDaoBase.class);
50
	protected String defaultField = "titleCache_tokenized";
51
	protected Class<? extends T> indexedClasses[]; 
52

    
53
	public IdentifiableDaoBase(Class<T> type) {
54
		super(type);
55
	}
56

    
57
	/* (non-Javadoc)
58
	 * @see eu.etaxonomy.cdm.persistence.dao.common.ITitledDao#findByTitle(java.lang.String)
59
	 */
60
	public List<T> findByTitle(String queryString) {
61
		return findByTitle(queryString, null);
62
	}
63
	
64
	/* (non-Javadoc)
65
	 * @see eu.etaxonomy.cdm.persistence.dao.common.ITitledDao#findByTitle(java.lang.String)
66
	 */
67
	public List<T> findByTitle(String queryString, CdmBase sessionObject) {
68
		/**
69
		 *  FIXME why do we need to call update in a find* method? I don't know for sure 
70
		 *  that this is a good idea . . . 
71
		 */
72
		Session session = getSession();
73
		if ( sessionObject != null ) {
74
			session.update(sessionObject);
75
		}
76
		checkNotInPriorView("IdentifiableDaoBase.findByTitle(String queryString, CdmBase sessionObject)");
77
		Criteria crit = session.createCriteria(type);
78
		crit.add(Restrictions.ilike("titleCache", queryString));
79
		List<T> results = crit.list();
80
		List<String> propertyPaths = null;
81
		defaultBeanInitializer.initializeAll(results, propertyPaths);
82
		return results;
83
	}
84
	
85
	public List<T> findByTitleAndClass(String queryString, Class<T> clazz) {
86
		checkNotInPriorView("IdentifiableDaoBase.findByTitleAndClass(String queryString, Class<T> clazz)");
87
		Criteria crit = getSession().createCriteria(clazz);
88
		crit.add(Restrictions.ilike("titleCache", queryString));
89
		List<T> results = crit.list();
90
		return results;
91
	}
92
	
93

    
94
	
95
	public List<T> findByTitle(Class<? extends T> clazz, String queryString, MatchMode matchmode, List<Criterion> criterion, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {
96
		return findByParam(clazz, "titleCache", queryString, matchmode, criterion, pageSize, pageNumber, orderHints, propertyPaths);
97
	}
98
	
99
	public List<T> findByReferenceTitle(Class<? extends T> clazz, String queryString, MatchMode matchmode, List<Criterion> criterion, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {
100
		return findByParam(clazz, "title", queryString, matchmode, criterion, pageSize, pageNumber, orderHints, propertyPaths);
101
	}
102
	
103
	/* (non-Javadoc)
104
	 * @see eu.etaxonomy.cdm.persistence.dao.common.ITitledDao#findByTitle(java.lang.String, boolean, int, int, java.util.List)
105
	 */
106
	public List<T> findByTitle(String queryString, MatchMode matchmode, int page, int pagesize, List<Criterion> criteria) {
107
		checkNotInPriorView("IdentifiableDaoBase.findByTitle(String queryString, MATCH_MODE matchmode, int page, int pagesize, List<Criterion> criteria)");
108
		Criteria crit = getSession().createCriteria(type);
109
		if (matchmode == MatchMode.EXACT) {
110
			crit.add(Restrictions.eq("titleCache", matchmode.queryStringFrom(queryString)));
111
		} else {
112
//			crit.add(Restrictions.ilike("titleCache", matchmode.queryStringFrom(queryString)));
113
			crit.add(Restrictions.like("titleCache", matchmode.queryStringFrom(queryString)));
114
		}
115
		if (pagesize >= 0) {
116
			crit.setMaxResults(pagesize);
117
		}
118
		if(criteria != null){
119
			for (Criterion criterion : criteria) {
120
				crit.add(criterion);
121
			}
122
		}
123
		crit.addOrder(Order.asc("titleCache"));
124
		int firstItem = (page - 1) * pagesize;
125
		crit.setFirstResult(firstItem);
126
		List<T> results = crit.list();
127
		return results;
128
	}
129

    
130
	public int countRights(T identifiableEntity) {
131
		checkNotInPriorView("IdentifiableDaoBase.countRights(T identifiableEntity)");
132
		Query query = getSession().createQuery("select count(rights) from " + type.getSimpleName() + " identifiableEntity join identifiableEntity.rights rights where identifiableEntity = :identifiableEntity");
133
		query.setParameter("identifiableEntity",identifiableEntity);
134
		return ((Long)query.uniqueResult()).intValue();
135
	}
136

    
137
	public int countSources(T identifiableEntity) {
138
		checkNotInPriorView("IdentifiableDaoBase.countSources(T identifiableEntity)");
139
		Query query = getSession().createQuery("select count(source) from OriginalSourceBase source where source.sourcedObj = :identifiableEntity");
140
		query.setParameter("identifiableEntity",identifiableEntity);
141
		return ((Long)query.uniqueResult()).intValue();
142
	}
143

    
144
	public List<Rights> getRights(T identifiableEntity, Integer pageSize, Integer pageNumber, List<String> propertyPaths) {
145
		checkNotInPriorView("IdentifiableDaoBase.getRights(T identifiableEntity, Integer pageSize, Integer pageNumber, List<String> propertyPaths)");
146
		Query query = getSession().createQuery("select rights from " + type.getSimpleName() + " identifiableEntity join identifiableEntity.rights rights where identifiableEntity = :identifiableEntity");
147
		query.setParameter("identifiableEntity",identifiableEntity);
148
		setPagingParameter(query, pageSize, pageNumber);
149
		List<Rights> results = (List<Rights>)query.list();
150
		defaultBeanInitializer.initializeAll(results, propertyPaths);
151
		return results;
152
	}
153
	
154
	public List<Credit> getCredits(T identifiableEntity, Integer pageSize, Integer pageNumber) {
155
		checkNotInPriorView("IdentifiableDaoBase.getCredits(T identifiableEntity, Integer pageSize, Integer pageNumber)");
156
		Query query = getSession().createQuery("select credits from " + type.getSimpleName() + " identifiableEntity join identifiableEntity.credits credits where identifiableEntity = :identifiableEntity");
157
		query.setParameter("identifiableEntity",identifiableEntity);
158
		setPagingParameter(query, pageSize, pageNumber);
159
		return (List<Credit>)query.list();
160
	}
161

    
162
	public List<IdentifiableSource> getSources(T identifiableEntity, Integer pageSize, Integer pageNumber, List<String> propertyPaths) {
163
		checkNotInPriorView("IdentifiableDaoBase.getSources(T identifiableEntity, Integer pageSize, Integer pageNumber)");
164
		Query query = getSession().createQuery("select source from OriginalSourceBase source where source.sourcedObj.id = :id and source.sourcedObj.class = :class");
165
		query.setParameter("id",identifiableEntity.getId());
166
		query.setParameter("class",identifiableEntity.getClass().getName());
167
		setPagingParameter(query, pageSize, pageNumber);
168
		List<IdentifiableSource> results = (List<IdentifiableSource>)query.list();
169
		defaultBeanInitializer.initializeAll(results, propertyPaths);
170
		return results;
171
	}
172

    
173
	public List<T> findOriginalSourceByIdInSource(String idInSource, String idNamespace) {
174
		checkNotInPriorView("IdentifiableDaoBase.findOriginalSourceByIdInSource(String idInSource, String idNamespace)");
175
		Query query = getSession().createQuery(
176
                "Select c from " + type.getSimpleName() + " as c " +
177
                "inner join c.sources as source " +
178
                "where source.idInSource = :idInSource " + 
179
                	" AND source.idNamespace = :idNamespace"
180
            );
181
		query.setString("idInSource", idInSource);
182
		query.setString("idNamespace", idNamespace);
183
		//TODO integrate reference in where		
184
		return (List<T>)query.list();
185
	}
186

    
187
	public T find(LSID lsid) {
188
		checkNotInPriorView("IdentifiableDaoBase.find(LSID lsid)");
189
		Criteria criteria = getSession().createCriteria(type);
190
		criteria.add(Restrictions.eq("lsid.authority", lsid.getAuthority()));
191
		criteria.add(Restrictions.eq("lsid.namespace", lsid.getNamespace()));
192
		criteria.add(Restrictions.eq("lsid.object", lsid.getObject()));
193
		
194
		if(lsid.getRevision() != null) {
195
			criteria.add(Restrictions.eq("lsid.revision", lsid.getRevision()));
196
		}
197
		
198
		T object = (T)criteria.uniqueResult();
199
		if(object != null) {
200
			return object;
201
		} else {
202
			AuditQuery query = getAuditReader().createQuery().forRevisionsOfEntity(type, false, true);
203
			query.add(AuditEntity.property("lsid_authority").eq(lsid.getAuthority()));
204
			query.add(AuditEntity.property("lsid_namespace").eq(lsid.getNamespace()));
205
			query.add(AuditEntity.property("lsid_object").eq(lsid.getObject()));
206
			
207
			if(lsid.getRevision() != null) {
208
				query.add(AuditEntity.property("lsid_revision").eq(lsid.getRevision()));
209
			}
210
			
211
			query.addOrder(AuditEntity.revisionNumber().asc());
212
			query.setMaxResults(1);
213
			query.setFirstResult(0);
214
			List<Object[]> objs = (List<Object[]>)query.getResultList();
215
			if(objs.isEmpty()) {
216
				return null;
217
			} else {
218
				return (T)objs.get(0)[0];
219
			}
220
		}
221
	}
222
	
223
	public List<UuidAndTitleCache<T>> getUuidAndTitleCache(){
224
		Session session = getSession();
225
		Query query = session.createQuery("select uuid, titleCache from " + type.getSimpleName());
226
		return getUuidAndTitleCache(query);
227
	}
228
	
229
	protected <E extends IIdentifiableEntity> List<UuidAndTitleCache<E>> getUuidAndTitleCache(Query query){
230
		List<UuidAndTitleCache<E>> list = new ArrayList<UuidAndTitleCache<E>>();
231
		
232
		List<Object[]> result = query.list();
233
		
234
		for(Object[] object : result){
235
			list.add(new UuidAndTitleCache<E>((UUID) object[0], (String) object[1]));
236
		}
237
		
238
		return list;
239
	}
240
	
241

    
242
	public int countByTitle(Class<? extends T> clazz, String queryString,	MatchMode matchmode, List<Criterion> criterion) {
243
		return countByParam(clazz, "titleCache",queryString,matchmode,criterion);
244
	}
245
	
246
	public int countByReferenceTitle(Class<? extends T> clazz, String queryString,	MatchMode matchmode, List<Criterion> criterion) {
247
		return countByParam(clazz, "title",queryString,matchmode,criterion);
248
	}
249

    
250
	public int count(Class<? extends T> clazz, String queryString) {
251
		checkNotInPriorView("IdentifiableDaoBase.count(Class<? extends T> clazz, String queryString)");
252
        QueryParser queryParser = new QueryParser(defaultField , new StandardAnalyzer());
253
		
254
		try {
255
			org.apache.lucene.search.Query query = queryParser.parse(queryString);
256
			
257
			FullTextSession fullTextSession = Search.getFullTextSession(this.getSession());
258
			org.hibernate.search.FullTextQuery fullTextQuery = null;
259
			
260
			if(clazz == null) {
261
				fullTextQuery = fullTextSession.createFullTextQuery(query, type);
262
			} else {
263
				fullTextQuery = fullTextSession.createFullTextQuery(query, clazz);
264
			}
265
			
266
		    Integer  result = fullTextQuery.getResultSize();
267
		    return result;
268

    
269
		} catch (ParseException e) {
270
			throw new QueryParseException(e, queryString);
271
		}
272
	}
273

    
274
	public void optimizeIndex() {
275
		FullTextSession fullTextSession = Search.getFullTextSession(getSession());
276
		SearchFactory searchFactory = fullTextSession.getSearchFactory();
277
		for(Class clazz : indexedClasses) {
278
	        searchFactory.optimize(clazz); // optimize the indices ()
279
		}
280
	    fullTextSession.flushToIndexes();
281
	}
282

    
283
	public void purgeIndex() {
284
		FullTextSession fullTextSession = Search.getFullTextSession(getSession());
285
		for(Class clazz : indexedClasses) {
286
		    fullTextSession.purgeAll(clazz); // remove all objects of type t from indexes
287
		}
288
		fullTextSession.flushToIndexes();
289
	}
290

    
291
	public void rebuildIndex() {
292
        FullTextSession fullTextSession = Search.getFullTextSession(getSession());
293
		
294
		for(T t : list(null,null)) { // re-index all objects
295
			fullTextSession.index(t);
296
		}
297
		fullTextSession.flushToIndexes();
298
	}
299

    
300
	public List<T> search(Class<? extends T> clazz, String queryString,	Integer pageSize, Integer pageNumber, List<OrderHint> orderHints,List<String> propertyPaths) {
301
		checkNotInPriorView("IdentifiableDaoBase.search(Class<? extends T> clazz, String queryString, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints,List<String> propertyPaths)");
302
		QueryParser queryParser = new QueryParser(defaultField, new StandardAnalyzer());
303
		List<T> results = new ArrayList<T>();
304
		 
305
		try {
306
			org.apache.lucene.search.Query query = queryParser.parse(queryString);
307
			
308
			FullTextSession fullTextSession = Search.getFullTextSession(getSession());
309
			org.hibernate.search.FullTextQuery fullTextQuery = null;
310
			
311
			if(clazz == null) {
312
				fullTextQuery = fullTextSession.createFullTextQuery(query, type);
313
			} else {
314
				fullTextQuery = fullTextSession.createFullTextQuery(query, clazz);
315
			}
316
			
317
			addOrder(fullTextQuery,orderHints);
318
			
319
		    if(pageSize != null) {
320
		    	fullTextQuery.setMaxResults(pageSize);
321
			    if(pageNumber != null) {
322
			    	fullTextQuery.setFirstResult(pageNumber * pageSize);
323
			    } else {
324
			    	fullTextQuery.setFirstResult(0);
325
			    }
326
			}
327
		    
328
		    List<T> result = (List<T>)fullTextQuery.list();
329
		    defaultBeanInitializer.initializeAll(result, propertyPaths);
330
		    return result;
331

    
332
		} catch (ParseException e) {
333
			throw new QueryParseException(e, queryString);
334
		}
335
	}
336

    
337
	public String suggestQuery(String string) {
338
		throw new UnsupportedOperationException("suggestQuery is not supported for objects of class " + type.getName());
339
	}
340

    
341
	@Override
342
	public Integer countByTitle(String queryString) {
343
		return countByTitle(queryString, null);
344
	}
345

    
346
	@Override
347
	public Integer countByTitle(String queryString, CdmBase sessionObject) {
348
		Session session = getSession();
349
		if ( sessionObject != null ) {
350
			session.update(sessionObject);
351
		}
352
		checkNotInPriorView("IdentifiableDaoBase.countByTitle(String queryString, CdmBase sessionObject)");
353
		Criteria crit = session.createCriteria(type);
354
		crit.add(Restrictions.ilike("titleCache", queryString));
355
		Integer result =  (Integer)crit.setProjection(Projections.rowCount()).uniqueResult();
356
		return result;
357
	}
358

    
359
	@Override
360
	public Integer countByTitle(String queryString, MatchMode matchMode, List<Criterion> criteria) {
361
		checkNotInPriorView("IdentifiableDaoBase.findByTitle(String queryString, MATCH_MODE matchmode, int page, int pagesize, List<Criterion> criteria)");
362
		Criteria crit = getSession().createCriteria(type);
363
		if (matchMode == MatchMode.EXACT) {
364
			crit.add(Restrictions.eq("titleCache", matchMode.queryStringFrom(queryString)));
365
		} else {
366
//			crit.add(Restrictions.ilike("titleCache", matchmode.queryStringFrom(queryString)));
367
			crit.add(Restrictions.like("titleCache", matchMode.queryStringFrom(queryString)));
368
		}
369
		
370
		if(criteria != null){
371
			for (Criterion criterion : criteria) {
372
				crit.add(criterion);
373
			}
374
		}
375
				
376
		
377
		Integer result = (Integer)crit.setProjection(Projections.rowCount()).uniqueResult();
378
		return result;
379
	}
380

    
381
	
382

    
383
}
(9-9/20)