Project

General

Profile

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

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

    
19
import org.apache.log4j.Logger;
20
import org.apache.lucene.analysis.SimpleAnalyzer;
21
import org.apache.lucene.queryParser.ParseException;
22
import org.apache.lucene.queryParser.QueryParser;
23
import org.apache.lucene.search.Sort;
24
import org.apache.lucene.search.SortField;
25
import org.hibernate.Criteria;
26
import org.hibernate.FetchMode;
27
import org.hibernate.Hibernate;
28
import org.hibernate.LazyInitializationException;
29
import org.hibernate.Query;
30
import org.hibernate.Transaction;
31
import org.hibernate.criterion.Criterion;
32
import org.hibernate.criterion.Projections;
33
import org.hibernate.criterion.Restrictions;
34
import org.hibernate.envers.query.AuditEntity;
35
import org.hibernate.envers.query.AuditQuery;
36
import org.hibernate.search.FullTextQuery;
37
import org.hibernate.search.FullTextSession;
38
import org.hibernate.search.Search;
39
import org.hibernate.search.SearchFactory;
40
import org.springframework.beans.factory.annotation.Autowired;
41
import org.springframework.beans.factory.annotation.Qualifier;
42
import org.springframework.dao.DataAccessException;
43
import org.springframework.stereotype.Repository;
44

    
45
import eu.etaxonomy.cdm.model.common.Annotation;
46
import eu.etaxonomy.cdm.model.common.Extension;
47
import eu.etaxonomy.cdm.model.common.Marker;
48
import eu.etaxonomy.cdm.model.common.OriginalSource;
49
import eu.etaxonomy.cdm.model.common.RelationshipBase;
50
import eu.etaxonomy.cdm.model.location.WaterbodyOrCountry;
51
import eu.etaxonomy.cdm.model.media.Rights;
52
import eu.etaxonomy.cdm.model.name.Rank;
53
import eu.etaxonomy.cdm.model.name.TaxonNameBase;
54
import eu.etaxonomy.cdm.model.occurrence.Collection;
55
import eu.etaxonomy.cdm.model.occurrence.DeterminationEvent;
56
import eu.etaxonomy.cdm.model.reference.ReferenceBase;
57
import eu.etaxonomy.cdm.model.taxon.Synonym;
58
import eu.etaxonomy.cdm.model.taxon.SynonymRelationship;
59
import eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType;
60
import eu.etaxonomy.cdm.model.taxon.Taxon;
61
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
62
import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;
63
import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;
64
import eu.etaxonomy.cdm.model.view.AuditEvent;
65
import eu.etaxonomy.cdm.persistence.dao.QueryParseException;
66
import eu.etaxonomy.cdm.persistence.dao.common.ISearchableDao;
67
import eu.etaxonomy.cdm.persistence.dao.common.ITitledDao;
68
import eu.etaxonomy.cdm.persistence.dao.hibernate.AlternativeSpellingSuggestionParser;
69
import eu.etaxonomy.cdm.persistence.dao.hibernate.common.IdentifiableDaoBase;
70
import eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao;
71
import eu.etaxonomy.cdm.persistence.fetch.CdmFetch;
72

    
73
/**
74
 * @author a.mueller
75
 *
76
 */
77
/**
78
 * @author a.mueller
79
 * @created 24.11.2008
80
 * @version 1.0
81
 */
82
/**
83
 * @author a.mueller
84
 * @created 24.11.2008
85
 * @version 1.0
86
 */
87
@Repository
88
@Qualifier("taxonDaoHibernateImpl")
89
public class TaxonDaoHibernateImpl extends IdentifiableDaoBase<TaxonBase> implements ITaxonDao {	
90
	private AlternativeSpellingSuggestionParser<TaxonBase> alternativeSpellingSuggestionParser;
91
	
92
	
93
	@SuppressWarnings("unused")
94
	private static final Logger logger = Logger.getLogger(TaxonDaoHibernateImpl.class);
95
	
96
	private String defaultField = "name.titleCache";
97
	private String defaultSort = "name.titleCache_forSort";
98
	private Class<? extends TaxonBase> indexedClasses[]; 
99

    
100
	public TaxonDaoHibernateImpl() {
101
		super(TaxonBase.class);
102
		indexedClasses = new Class[2];
103
		indexedClasses[0] = Taxon.class;
104
		indexedClasses[1] = Synonym.class;
105
	}
106
	
107
	@Autowired(required = false)   //TODO switched of because it caused problems when starting CdmApplicationController
108
	public void setAlternativeSpellingSuggestionParser(AlternativeSpellingSuggestionParser<TaxonBase> alternativeSpellingSuggestionParser) {
109
		this.alternativeSpellingSuggestionParser = alternativeSpellingSuggestionParser;
110
	}
111

    
112
	/* (non-Javadoc)
113
	 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getRootTaxa(eu.etaxonomy.cdm.model.reference.ReferenceBase)
114
	 */
115
	public List<Taxon> getRootTaxa(ReferenceBase sec) {
116
		return getRootTaxa(sec, CdmFetch.FETCH_CHILDTAXA(), true, false);
117
	}
118
	
119
	@Override
120
	public TaxonBase findByUuid(UUID uuid) {
121
		TaxonBase taxonBase = super.findByUuid(uuid);
122
		if(taxonBase == null) 
123
			return taxonBase;
124
		
125
		Hibernate.initialize(taxonBase.getName());
126
		Hibernate.initialize(taxonBase.getSec());
127
		
128
		return taxonBase; 
129
	}
130
	
131
	/* (non-Javadoc)
132
	 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getRootTaxa(eu.etaxonomy.cdm.model.reference.ReferenceBase, eu.etaxonomy.cdm.persistence.fetch.CdmFetch, java.lang.Boolean, java.lang.Boolean)
133
	 */
134
	public List<Taxon> getRootTaxa(ReferenceBase sec, CdmFetch cdmFetch, Boolean onlyWithChildren, Boolean withMisapplications) {
135
		checkNotInPriorView("TaxonDaoHibernateImpl.getRootTaxa(ReferenceBase sec, CdmFetch cdmFetch, Boolean onlyWithChildren, Boolean withMisapplications)");
136
		if (onlyWithChildren == null){
137
			onlyWithChildren = true;
138
		}
139
		if (withMisapplications == null){
140
			withMisapplications = true;
141
		}
142
		if (cdmFetch == null){
143
			cdmFetch = CdmFetch.NO_FETCH();
144
		}
145

    
146
//		String query = "from Taxon root ";
147
//		query += " where root.taxonomicParentCache is NULL ";
148
//		if (sec != null){
149
//		query += " AND root.sec.id = :sec "; 
150
//		}		
151
//		Query q = getSession().createQuery(query);
152
//		if (sec != null){
153
//		q.setInteger("sec", sec.getId());
154
//		}
155

    
156
		Criteria crit = getSession().createCriteria(Taxon.class);
157
		crit.add(Restrictions.isNull("taxonomicParentCache"));
158
		if (sec != null){
159
			crit.add(Restrictions.eq("sec", sec) );
160
		}
161

    
162
		if (! cdmFetch.includes(CdmFetch.FETCH_CHILDTAXA())){
163
			logger.warn("no child taxa fetch");
164
			//TODO overwrite LAZY (SELECT) does not work (bug in hibernate?)
165
			crit.setFetchMode("relationsToThisTaxon.fromTaxon", FetchMode.LAZY);
166
		}
167

    
168
		List<Taxon> results = new ArrayList<Taxon>();
169
		for(Taxon taxon : (List<Taxon>) crit.list()){
170
			//childTaxa
171
			//TODO create restriction instead
172
			if (onlyWithChildren == false || taxon.hasTaxonomicChildren()){
173
				if (withMisapplications == true || ! taxon.isMisappliedName()){
174
					results.add(taxon);
175
				}
176
			}
177
		}
178
		return results;
179
	}
180
	
181
	public List<TaxonBase> getTaxaByName(String queryString, ReferenceBase sec) {
182
		
183
		return getTaxaByName(queryString, true, sec);
184
	}
185

    
186
	public List<TaxonBase> getTaxaByName(String queryString, Boolean accepted, ReferenceBase sec) {
187
		checkNotInPriorView("TaxonDaoHibernateImpl.getTaxaByName(String name, ReferenceBase sec)");
188
		
189
        Criteria criteria = null;
190
		if (accepted == true) {
191
			criteria = getSession().createCriteria(Taxon.class);
192
		} else {
193
			criteria = getSession().createCriteria(Synonym.class);
194
		}
195
		
196
		criteria.setFetchMode( "name", FetchMode.JOIN );
197
		criteria.createAlias("name", "name");
198
		
199
		if (sec != null){
200
			// FIXME I don't think that we should be saving objects in get methods
201
			if(sec.getId() == 0){
202
				getSession().save(sec);
203
			}
204
			criteria.add(Restrictions.eq("sec", sec ) );
205
		}
206
		if (queryString != null) {
207
			criteria.add(Restrictions.ilike("name.nameCache", queryString));
208
		}
209

    
210
		return (List<TaxonBase>)criteria.list();
211
	}
212

    
213
	public List<TaxonBase> getAllTaxonBases(Integer pagesize, Integer page) {
214
		return super.list(pagesize, page);
215
	}
216

    
217
	public List<Synonym> getAllSynonyms(Integer limit, Integer start) {
218
		return super.list(Synonym.class, limit, start);
219
	}
220

    
221
	public List<Taxon> getAllTaxa(Integer limit, Integer start) {
222
		return super.list(Taxon.class, limit, start);
223
	}
224

    
225
	public List<RelationshipBase> getAllRelationships(Integer limit, Integer start) {
226
		AuditEvent auditEvent = getAuditEventFromContext();
227
		if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
228
		    Criteria criteria = getSession().createCriteria(RelationshipBase.class);
229
		    return (List<RelationshipBase>)criteria.list();
230
		} else {
231
			AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(RelationshipBase.class,auditEvent.getRevisionNumber());
232
			return (List<RelationshipBase>)query.getResultList();
233
		}
234
	}
235

    
236
	@Override
237
	public UUID delete(TaxonBase taxonBase) throws DataAccessException{
238
		if (taxonBase == null){
239
			logger.warn("TaxonBase was 'null'");
240
			return null;
241
		}
242
		
243
		// Merge the object in if it is detached
244
		//
245
		// I think this is preferable to catching lazy initialization errors 
246
		// as that solution only swallows and hides the exception, but doesn't 
247
		// actually solve it.
248
		getSession().merge(taxonBase);
249
		
250
		for(Iterator<Annotation> iterator = taxonBase.getAnnotations().iterator(); iterator.hasNext();) {
251
			Annotation annotation = iterator.next();
252
		    annotation.setAnnotatedObj(null);
253
		    iterator.remove();
254
		    getSession().delete(annotation);
255
	    }
256
		
257
		for(Iterator<Marker> iterator = taxonBase.getMarkers().iterator(); iterator.hasNext();) {
258
			Marker marker = iterator.next();
259
		    marker.setMarkedObj(null);
260
		    iterator.remove();
261
		    getSession().delete(marker);
262
	    }
263
		
264
		for(Iterator<Extension> iterator = taxonBase.getExtensions().iterator(); iterator.hasNext();) {
265
			Extension extension = iterator.next();
266
		    extension.setExtendedObj(null);
267
		    iterator.remove();
268
		    getSession().delete(extension);
269
	    }
270
		
271
		for(Iterator<OriginalSource> iterator = taxonBase.getSources().iterator(); iterator.hasNext();) {
272
			OriginalSource source = iterator.next();
273
		    source.setSourcedObj(null);
274
		    iterator.remove();
275
		    getSession().delete(source);
276
	    }
277

    
278
		for(Iterator<Rights> iterator = taxonBase.getRights().iterator(); iterator.hasNext();) {
279
			Rights rights = iterator.next();
280
		    iterator.remove();
281
		    getSession().delete(rights);
282
	    }
283
		
284
		if (taxonBase instanceof Taxon){ //	is Taxon
285
			//taxonRelationships
286
			Taxon taxon = (Taxon)taxonBase;
287
						
288
			for (Iterator<TaxonRelationship> iterator = taxon.getRelationsFromThisTaxon().iterator(); iterator.hasNext();){
289
				TaxonRelationship relationToThisTaxon = iterator.next();
290
				iterator.remove();
291
				relationToThisTaxon.setFromTaxon(null);
292
				relationToThisTaxon.setToTaxon(null);
293
				getSession().delete(relationToThisTaxon);
294
			}
295
			
296
			for (Iterator<TaxonRelationship> iterator = taxon.getRelationsToThisTaxon().iterator(); iterator.hasNext();){
297
				TaxonRelationship relationFromThisTaxon = iterator.next();
298
				iterator.remove();
299
				relationFromThisTaxon.setToTaxon(null);
300
				relationFromThisTaxon.setFromTaxon(null);
301
				getSession().delete(relationFromThisTaxon);
302
			}
303
			
304
			//SynonymRelationships
305
			for (Iterator<SynonymRelationship> iterator = taxon.getSynonymRelations().iterator(); iterator.hasNext();){
306
				SynonymRelationship synonymRelation = iterator.next();
307
				iterator.remove();
308
				synonymRelation.setAcceptedTaxon(null);
309
				synonymRelation.setSynonym(null);
310
				getSession().delete(synonymRelation);
311
			} 
312
		} else if (taxonBase instanceof Synonym){ //is Synonym
313
			Synonym synonym = (Synonym)taxonBase;
314
			for (Iterator<SynonymRelationship> iterator = synonym.getSynonymRelations().iterator(); iterator.hasNext();){
315
				SynonymRelationship synonymRelation = iterator.next();
316
				iterator.remove();
317
				synonymRelation.setAcceptedTaxon(null);
318
				synonymRelation.setSynonym(null);
319
			} ;
320
		}
321
		return super.delete(taxonBase);
322
	}
323

    
324

    
325
	// TODO add generic return type !!
326
	public List findByName(String queryString, ITitledDao.MATCH_MODE matchMode, int page, int pagesize, boolean onlyAcccepted) {
327
		ArrayList<Criterion> criteria = new ArrayList<Criterion>();
328
		//TODO ... Restrictions.eq(propertyName, value)
329
		return super.findByTitle(queryString, matchMode, page, pagesize, criteria);
330

    
331
	}
332

    
333
	public int countMatchesByName(String queryString, ITitledDao.MATCH_MODE matchMode, boolean onlyAcccepted) {
334
		checkNotInPriorView("TaxonDaoHibernateImpl.countMatchesByName(String queryString, ITitledDao.MATCH_MODE matchMode, boolean onlyAcccepted)");
335
		Criteria crit = getSession().createCriteria(type);
336
		crit.add(Restrictions.ilike("titleCache", matchMode.queryStringFrom(queryString)));
337
		crit.setProjection(Projections.rowCount());
338
		int result = ((Integer)crit.list().get(0)).intValue();
339
		return result;
340
	}
341

    
342

    
343
	public int countMatchesByName(String queryString, ITitledDao.MATCH_MODE matchMode, boolean onlyAcccepted, List<Criterion> criteria) {
344
		checkNotInPriorView("TaxonDaoHibernateImpl.countMatchesByName(String queryString, ITitledDao.MATCH_MODE matchMode, boolean onlyAcccepted, List<Criterion> criteria)");
345
		Criteria crit = getSession().createCriteria(type);
346
		crit.add(Restrictions.ilike("titleCache", matchMode.queryStringFrom(queryString)));
347
		if(criteria != null){
348
			for (Criterion criterion : criteria) {
349
				crit.add(criterion);
350
			}
351
		}
352
		crit.setProjection(Projections.rowCount());
353
		int result = ((Integer)crit.list().get(0)).intValue();
354
		return result;
355
	}
356

    
357
	public int countRelatedTaxa(Taxon taxon, TaxonRelationshipType type) {
358
		AuditEvent auditEvent = getAuditEventFromContext();
359
		if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
360
		    Query query = null;
361
		
362
		    if(type == null) {
363
			    query = getSession().createQuery("select count(taxonRelationship) from TaxonRelationship taxonRelationship where taxonRelationship.relatedTo = :relatedTo");
364
		    } else {
365
			    query = getSession().createQuery("select count(taxonRelationship) from TaxonRelationship taxonRelationship where taxonRelationship.relatedTo = :relatedTo and taxonRelationship.type = :type");
366
			    query.setParameter("type",type);
367
		    }
368
		
369
		    query.setParameter("relatedTo", taxon);
370
		
371
		    return ((Long)query.uniqueResult()).intValue();
372
		} else {
373
			AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(TaxonRelationship.class,auditEvent.getRevisionNumber());
374
			query.add(AuditEntity.relatedId("relatedTo").eq(taxon.getId()));
375
			query.addProjection(AuditEntity.id().count("id"));
376
			
377
			if(type != null) {
378
				query.add(AuditEntity.relatedId("type").eq(type.getId()));
379
		    }
380
			
381
			return ((Long)query.getSingleResult()).intValue();
382
		}
383
	}
384

    
385
	public int countSynonyms(Taxon taxon, SynonymRelationshipType type) {
386
		AuditEvent auditEvent = getAuditEventFromContext();
387
		if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
388
			Query query = null;
389

    
390
			if(type == null) {
391
				query = getSession().createQuery("select count(synonymRelationship) from SynonymRelationship synonymRelationship where synonymRelationship.relatedTo = :relatedTo");
392
			} else {
393
				query = getSession().createQuery("select count(synonymRelationship) from SynonymRelationship synonymRelationship where synonymRelationship.relatedTo = :relatedTo and synonymRelationship.type = :type");
394
				query.setParameter("type",type);
395
			}
396

    
397
			query.setParameter("relatedTo", taxon);
398

    
399
			return ((Long)query.uniqueResult()).intValue();
400
		} else {
401
			AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(SynonymRelationship.class,auditEvent.getRevisionNumber());
402
			query.add(AuditEntity.relatedId("relatedTo").eq(taxon.getId()));
403
			query.addProjection(AuditEntity.id().count("id"));
404
			
405
			if(type != null) {
406
				query.add(AuditEntity.relatedId("type").eq(type.getId()));
407
		    }
408
			
409
			return ((Long)query.getSingleResult()).intValue();
410
		}
411
	}
412

    
413
	public int countTaxa(String queryString, Boolean accepted) {
414
		checkNotInPriorView("TaxonDaoHibernateImpl.countTaxa(String queryString, Boolean accepted)");
415
        QueryParser queryParser = new QueryParser("name.titleCache", new SimpleAnalyzer());
416
		
417
		try {
418
			org.apache.lucene.search.Query query = queryParser.parse(queryString);
419
			
420
			FullTextSession fullTextSession = Search.getFullTextSession(this.getSession());
421
			org.hibernate.search.FullTextQuery fullTextQuery = null;
422
			
423
			if(accepted == null) {
424
				fullTextQuery = fullTextSession.createFullTextQuery(query, TaxonBase.class);
425
			} else {
426
				if(accepted) {
427
					fullTextQuery = fullTextSession.createFullTextQuery(query, Taxon.class);
428
				} else {
429
					fullTextQuery = fullTextSession.createFullTextQuery(query, Synonym.class);
430
				}
431
			}
432
			
433
		    Integer  result = fullTextQuery.getResultSize();
434
		    return result;
435

    
436
		} catch (ParseException e) {
437
			throw new QueryParseException(e, queryString);
438
		}
439
	}
440
	
441
	public int countTaxaByName(String queryString, Boolean accepted, ReferenceBase sec) {
442
		checkNotInPriorView("TaxonDaoHibernateImpl.countTaxaByName(String queryString, Boolean accepted, ReferenceBase sec)");
443
		Criteria criteria = null;
444
		
445
		if (accepted == true) {
446
			criteria = getSession().createCriteria(Taxon.class);
447
		} else {
448
			criteria = getSession().createCriteria(Synonym.class);
449
		}
450
		
451
		criteria.setFetchMode( "name", FetchMode.JOIN );
452
		criteria.createAlias("name", "name");
453

    
454
		if (sec != null){
455
			if(sec.getId() == 0){
456
				getSession().save(sec);
457
			}
458
			criteria.add(Restrictions.eq("sec", sec ) );
459
		}
460
		if (queryString != null) {
461
			criteria.add(Restrictions.ilike("name.nameCache", queryString));
462
		}
463
		criteria.setProjection(Projections.projectionList().add(Projections.rowCount()));
464
		
465
		return (Integer)criteria.uniqueResult();
466
	}
467

    
468
	public int countTaxaByName(Boolean accepted, String genusOrUninomial,	String infraGenericEpithet, String specificEpithet,	String infraSpecificEpithet, Rank rank) {
469
		checkNotInPriorView("TaxonDaoHibernateImpl.countTaxaByName(Boolean accepted, String genusOrUninomial,	String infraGenericEpithet, String specificEpithet,	String infraSpecificEpithet, Rank rank)");
470
        Criteria criteria = null;
471
		
472
		if(accepted == null) {
473
			criteria = getSession().createCriteria(TaxonBase.class);
474
		} else {
475
			if(accepted) {
476
				criteria = getSession().createCriteria(Taxon.class);
477
			} else {
478
				criteria = getSession().createCriteria(Synonym.class);
479
			}
480
		}
481
		
482
		criteria.setFetchMode( "name", FetchMode.JOIN );
483
		criteria.createAlias("name", "name");
484
		
485
		if(genusOrUninomial != null) {
486
			criteria.add(Restrictions.eq("name.genusOrUninomial", genusOrUninomial));
487
		}
488
		
489
		if(infraGenericEpithet != null) {
490
			criteria.add(Restrictions.eq("name.infraGenericEpithet", infraGenericEpithet));
491
		}
492
		
493
		if(specificEpithet != null) {
494
			criteria.add(Restrictions.eq("name.specificEpithet", specificEpithet));
495
		}
496
		
497
		if(infraSpecificEpithet != null) {
498
			criteria.add(Restrictions.eq("name.infraSpecificEpithet", infraSpecificEpithet));
499
		}
500
		
501
		if(rank != null) {
502
			criteria.add(Restrictions.eq("name.rank", rank));
503
		}
504
		
505
		criteria.setProjection(Projections.projectionList().add(Projections.rowCount()));
506
	
507
		return (Integer)criteria.uniqueResult();
508
	}
509

    
510
	public List<TaxonBase> findTaxaByName(Boolean accepted, String genusOrUninomial, String infraGenericEpithet, String specificEpithet, String infraSpecificEpithet, Rank rank, Integer pageSize,	Integer pageNumber) {
511
		checkNotInPriorView("TaxonDaoHibernateImpl.findTaxaByName(Boolean accepted, String genusOrUninomial, String infraGenericEpithet, String specificEpithet, String infraSpecificEpithet, Rank rank, Integer pageSize,	Integer pageNumber)");
512
		Criteria criteria = null;
513
		
514
		if(accepted == null) {
515
			criteria = getSession().createCriteria(TaxonBase.class);
516
		} else {
517
			if(accepted) {
518
				criteria = getSession().createCriteria(Taxon.class);
519
			} else {
520
				criteria = getSession().createCriteria(Synonym.class);
521
			}
522
		}
523
		
524
		criteria.setFetchMode( "name", FetchMode.JOIN );
525
		criteria.createAlias("name", "name");
526
		
527
		if(genusOrUninomial != null) {
528
			criteria.add(Restrictions.eq("name.genusOrUninomial", genusOrUninomial));
529
		}
530
		
531
		if(infraGenericEpithet != null) {
532
			criteria.add(Restrictions.eq("name.infraGenericEpithet", infraGenericEpithet));
533
		} else {
534
			criteria.add(Restrictions.isNull("name.infraGenericEpithet"));
535
		}
536
		
537
		if(specificEpithet != null) {
538
			criteria.add(Restrictions.eq("name.specificEpithet", specificEpithet));
539
		}
540
		
541
		if(infraSpecificEpithet != null) {
542
			criteria.add(Restrictions.eq("name.infraSpecificEpithet", infraSpecificEpithet));
543
		}
544
		
545
		if(rank != null) {
546
			criteria.add(Restrictions.eq("name.rank", rank));
547
		}
548
		
549
		if(pageSize != null) {
550
	    	criteria.setMaxResults(pageSize);
551
		    if(pageNumber != null) {
552
		    	criteria.setFirstResult(pageNumber * pageSize);
553
		    } else {
554
		    	criteria.setFirstResult(0);
555
		    }
556
		}
557
	
558
		return (List<TaxonBase>)criteria.list();
559
	}
560

    
561
	public List<TaxonRelationship> getRelatedTaxa(Taxon taxon,	TaxonRelationshipType type, Integer pageSize, Integer pageNumber) {
562
		AuditEvent auditEvent = getAuditEventFromContext();
563
		if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
564
            Query query = null;
565
            
566
		    if(type == null) {
567
			    query = getSession().createQuery("select taxonRelationship from TaxonRelationship taxonRelationship join fetch taxonRelationship.relatedFrom where taxonRelationship.relatedTo = :relatedTo");
568
		    } else {
569
			    query = getSession().createQuery("select taxonRelationship from TaxonRelationship taxonRelationship join fetch taxonRelationship.relatedFrom where taxonRelationship.relatedTo = :relatedTo and taxonRelationship.type = :type");
570
			    query.setParameter("type",type);
571
		    }
572
		
573
		    query.setParameter("relatedTo", taxon);
574
		
575
		    if(pageSize != null) {
576
		        query.setMaxResults(pageSize);
577
		        if(pageNumber != null) {
578
		            query.setFirstResult(pageNumber * pageSize);
579
		        } else {
580
		    	    query.setFirstResult(0);
581
		        }
582
		    }
583
		
584
		    return (List<TaxonRelationship>)query.list();
585
		} else {
586
			AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(TaxonRelationship.class,auditEvent.getRevisionNumber());
587
			query.add(AuditEntity.relatedId("relatedTo").eq(taxon.getId()));
588
			
589
			if(type != null) {
590
				query.add(AuditEntity.relatedId("type").eq(type.getId()));
591
		    }
592
			
593
			if(pageSize != null) {
594
		        query.setMaxResults(pageSize);
595
		        if(pageNumber != null) {
596
		            query.setFirstResult(pageNumber * pageSize);
597
		        } else {
598
		    	    query.setFirstResult(0);
599
		        }
600
		    }
601
			
602
			List<TaxonRelationship> result = (List<TaxonRelationship>)query.getResultList();
603
			for(TaxonRelationship relationship : result) {
604
				Hibernate.initialize(relationship.getFromTaxon());
605
			}
606
			
607
			return result;
608
		}
609
	}
610

    
611
	public List<SynonymRelationship> getSynonyms(Taxon taxon, SynonymRelationshipType type, Integer pageSize, Integer pageNumber) {
612
		AuditEvent auditEvent = getAuditEventFromContext();
613
		if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
614
			Query query = null;
615

    
616
			if(type == null) {
617
				query = getSession().createQuery("select synonymRelationship from SynonymRelationship synonymRelationship join fetch synonymRelationship.relatedFrom where synonymRelationship.relatedTo = :relatedTo");
618
			} else {
619
				query = getSession().createQuery("select synonymRelationship from SynonymRelationship synonymRelationship join fetch synonymRelationship.relatedFrom where synonymRelationship.relatedTo = :relatedTo and synonymRelationship.type = :type");
620
				query.setParameter("type",type);
621
			}
622

    
623
			query.setParameter("relatedTo", taxon);
624

    
625
			if(pageSize != null) {
626
				query.setMaxResults(pageSize);
627
				if(pageNumber != null) {
628
					query.setFirstResult(pageNumber * pageSize);
629
				} else {
630
					query.setFirstResult(0);
631
				}
632
			}
633

    
634
			return (List<SynonymRelationship>)query.list();
635
		} else {
636
			AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(SynonymRelationship.class,auditEvent.getRevisionNumber());
637
			query.add(AuditEntity.relatedId("relatedTo").eq(taxon.getId()));
638
			
639
			if(type != null) {
640
				query.add(AuditEntity.relatedId("type").eq(type.getId()));
641
		    }
642
			
643
			if(pageSize != null) {
644
		        query.setMaxResults(pageSize);
645
		        if(pageNumber != null) {
646
		            query.setFirstResult(pageNumber * pageSize);
647
		        } else {
648
		    	    query.setFirstResult(0);
649
		        }
650
		    }
651
			
652
			List<SynonymRelationship> result = (List<SynonymRelationship>)query.getResultList();
653
			for(SynonymRelationship relationship : result) {
654
				Hibernate.initialize(relationship.getSynonym());
655
			}
656
			
657
			return result;
658
		}
659
	}
660

    
661
	public List<TaxonBase> searchTaxa(String queryString, Boolean accepted,	Integer pageSize, Integer pageNumber) {
662
		checkNotInPriorView("TaxonDaoHibernateImpl.searchTaxa(String queryString, Boolean accepted,	Integer pageSize, Integer pageNumber)");
663
		QueryParser queryParser = new QueryParser(defaultField, new SimpleAnalyzer());
664
		List<TaxonBase> results = new ArrayList<TaxonBase>();
665
		 
666
		try {
667
			org.apache.lucene.search.Query query = queryParser.parse(queryString);
668
			
669
			FullTextSession fullTextSession = Search.getFullTextSession(getSession());
670
			org.hibernate.search.FullTextQuery fullTextQuery = null;
671
			
672
			if(accepted == null) {
673
				fullTextQuery = fullTextSession.createFullTextQuery(query, TaxonBase.class);
674
			} else {
675
				if(accepted) {
676
					fullTextQuery = fullTextSession.createFullTextQuery(query, Taxon.class);
677
				} else {
678
					fullTextQuery = fullTextSession.createFullTextQuery(query, Synonym.class);
679
				}
680
			}
681
			
682
			org.apache.lucene.search.Sort sort = new Sort(new SortField(defaultSort));
683
			fullTextQuery.setSort(sort);
684
			
685
		    if(pageSize != null) {
686
		    	fullTextQuery.setMaxResults(pageSize);
687
			    if(pageNumber != null) {
688
			    	fullTextQuery.setFirstResult(pageNumber * pageSize);
689
			    } else {
690
			    	fullTextQuery.setFirstResult(0);
691
			    }
692
			}
693
		    
694
		    List<TaxonBase> result = (List<TaxonBase>)fullTextQuery.list();
695
		    for(TaxonBase taxonBase : result) {
696
		    	Hibernate.initialize(taxonBase.getName());
697
		    }
698
		    return result;
699

    
700
		} catch (ParseException e) {
701
			throw new QueryParseException(e, queryString);
702
		}
703
	}
704
	
705
	public void purgeIndex() {
706
		FullTextSession fullTextSession = Search.getFullTextSession(getSession());
707
		for(Class clazz : indexedClasses) {
708
		    fullTextSession.purgeAll(clazz); // remove all taxon base from indexes
709
		}
710
		fullTextSession.flushToIndexes();
711
	}
712

    
713
	public void rebuildIndex() {
714
		FullTextSession fullTextSession = Search.getFullTextSession(getSession());
715
		
716
		for(TaxonBase taxonBase : list(null,null)) { // re-index all taxon base
717
			Hibernate.initialize(taxonBase.getName());
718
			fullTextSession.index(taxonBase);
719
		}
720
		fullTextSession.flushToIndexes();
721
	}
722
	
723
	public void optimizeIndex() {
724
		FullTextSession fullTextSession = Search.getFullTextSession(getSession());
725
		SearchFactory searchFactory = fullTextSession.getSearchFactory();
726
		for(Class clazz : indexedClasses) {
727
	        searchFactory.optimize(clazz); // optimize the indices ()
728
		}
729
	    fullTextSession.flushToIndexes();
730
	}
731

    
732
	public String suggestQuery(String queryString) {
733
		checkNotInPriorView("TaxonDaoHibernateImpl.suggestQuery(String queryString)");
734
		String alternativeQueryString = null;
735
		if (alternativeSpellingSuggestionParser != null) {
736
			try {
737

    
738
				alternativeSpellingSuggestionParser.parse(queryString);
739
				org.apache.lucene.search.Query alternativeQuery = alternativeSpellingSuggestionParser.suggest(queryString);
740
				if (alternativeQuery != null) {
741
					alternativeQueryString = alternativeQuery
742
							.toString("name.titleCache");
743
				}
744

    
745
			} catch (ParseException e) {
746
				throw new QueryParseException(e, queryString);
747
			}
748
		}
749
		return alternativeQueryString;
750
	}
751

    
752
	public int count(String queryString) {
753
		checkNotInPriorView("TaxonDaoHibernateImpl.count(String queryString)");
754
        QueryParser queryParser = new QueryParser(defaultField, new SimpleAnalyzer());
755
		
756
		try {
757
			org.apache.lucene.search.Query query = queryParser.parse(queryString);
758
		
759
			FullTextSession fullTextSession = Search.getFullTextSession(this.getSession());
760
			org.hibernate.search.FullTextQuery fullTextQuery = fullTextSession.createFullTextQuery(query, type);
761
				
762
		    return fullTextQuery.getResultSize();
763

    
764
		} catch (ParseException e) {
765
			throw new QueryParseException(e, queryString);
766
		}
767
	}
768

    
769
	public List<TaxonBase> search(String queryString, Integer pageSize,	Integer pageNumber) {
770
		checkNotInPriorView("TaxonDaoHibernateImpl.search(String queryString, Integer pageSize,	Integer pageNumber)");
771
		QueryParser queryParser = new QueryParser(defaultField, new SimpleAnalyzer());
772
		List<TaxonBase> results = new ArrayList<TaxonBase>();
773
		 
774
		try {
775
			org.apache.lucene.search.Query query = queryParser.parse(queryString);
776
			
777
			FullTextSession fullTextSession = Search.getFullTextSession(getSession());
778
			
779
			org.hibernate.search.FullTextQuery fullTextQuery = fullTextSession.createFullTextQuery(query, type);
780
			
781
			org.apache.lucene.search.Sort sort = new Sort(new SortField(defaultSort));
782
			fullTextQuery.setSort(sort);
783
		    
784
		    if(pageSize != null) {
785
		    	fullTextQuery.setMaxResults(pageSize);
786
			    if(pageNumber != null) {
787
			    	fullTextQuery.setFirstResult(pageNumber * pageSize);
788
			    } else {
789
			    	fullTextQuery.setFirstResult(0);
790
			    }
791
			}
792
		    
793
		    List<TaxonBase> result = (List<TaxonBase>)fullTextQuery.list();
794
		    for(TaxonBase taxonBase : result) {
795
		    	Hibernate.initialize(taxonBase.getName());
796
		    }
797
		    return result;
798

    
799
		} catch (ParseException e) {
800
			throw new QueryParseException(e, queryString);
801
		}
802
	}
803
}
(2-2/2)