742c8b800f1bfb7e0083a309d0a436dbfc8de9a6
[cdmlib.git] / cdmlib-persistence / src / main / java / eu / etaxonomy / cdm / persistence / dao / hibernate / taxon / TaxonDaoHibernateImpl.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 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.ITitledDao;
67 import eu.etaxonomy.cdm.persistence.dao.hibernate.AlternativeSpellingSuggestionParser;
68 import eu.etaxonomy.cdm.persistence.dao.hibernate.common.IdentifiableDaoBase;
69 import eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao;
70 import eu.etaxonomy.cdm.persistence.fetch.CdmFetch;
71
72 /**
73 * @author a.mueller
74 *
75 */
76 /**
77 * @author a.mueller
78 * @created 24.11.2008
79 * @version 1.0
80 */
81 /**
82 * @author a.mueller
83 * @created 24.11.2008
84 * @version 1.0
85 */
86 @Repository
87 @Qualifier("taxonDaoHibernateImpl")
88 public class TaxonDaoHibernateImpl extends IdentifiableDaoBase<TaxonBase> implements ITaxonDao {
89 private AlternativeSpellingSuggestionParser<TaxonBase> alternativeSpellingSuggestionParser;
90
91
92 @SuppressWarnings("unused")
93 private static final Logger logger = Logger.getLogger(TaxonDaoHibernateImpl.class);
94
95 public TaxonDaoHibernateImpl() {
96 super(TaxonBase.class);
97 }
98
99 @Autowired(required = false) //TODO switched of because it caused problems when starting CdmApplicationController
100 public void setAlternativeSpellingSuggestionParser(AlternativeSpellingSuggestionParser<TaxonBase> alternativeSpellingSuggestionParser) {
101 this.alternativeSpellingSuggestionParser = alternativeSpellingSuggestionParser;
102 }
103
104 /* (non-Javadoc)
105 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getRootTaxa(eu.etaxonomy.cdm.model.reference.ReferenceBase)
106 */
107 public List<Taxon> getRootTaxa(ReferenceBase sec) {
108 return getRootTaxa(sec, CdmFetch.FETCH_CHILDTAXA(), true, false);
109 }
110
111 @Override
112 public TaxonBase findByUuid(UUID uuid) {
113 TaxonBase taxonBase = super.findByUuid(uuid);
114 if(taxonBase == null)
115 return taxonBase;
116
117 Hibernate.initialize(taxonBase.getName());
118 Hibernate.initialize(taxonBase.getSec());
119
120 return taxonBase;
121 }
122
123 /* (non-Javadoc)
124 * @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)
125 */
126 public List<Taxon> getRootTaxa(ReferenceBase sec, CdmFetch cdmFetch, Boolean onlyWithChildren, Boolean withMisapplications) {
127 checkNotInPriorView("TaxonDaoHibernateImpl.getRootTaxa(ReferenceBase sec, CdmFetch cdmFetch, Boolean onlyWithChildren, Boolean withMisapplications)");
128 if (onlyWithChildren == null){
129 onlyWithChildren = true;
130 }
131 if (withMisapplications == null){
132 withMisapplications = true;
133 }
134 if (cdmFetch == null){
135 cdmFetch = CdmFetch.NO_FETCH();
136 }
137
138 // String query = "from Taxon root ";
139 // query += " where root.taxonomicParentCache is NULL ";
140 // if (sec != null){
141 // query += " AND root.sec.id = :sec ";
142 // }
143 // Query q = getSession().createQuery(query);
144 // if (sec != null){
145 // q.setInteger("sec", sec.getId());
146 // }
147
148 Criteria crit = getSession().createCriteria(Taxon.class);
149 crit.add(Restrictions.isNull("taxonomicParentCache"));
150 if (sec != null){
151 crit.add(Restrictions.eq("sec", sec) );
152 }
153
154 if (! cdmFetch.includes(CdmFetch.FETCH_CHILDTAXA())){
155 logger.warn("no child taxa fetch");
156 //TODO overwrite LAZY (SELECT) does not work (bug in hibernate?)
157 crit.setFetchMode("relationsToThisTaxon.fromTaxon", FetchMode.LAZY);
158 }
159
160 List<Taxon> results = new ArrayList<Taxon>();
161 for(Taxon taxon : (List<Taxon>) crit.list()){
162 //childTaxa
163 //TODO create restriction instead
164 if (onlyWithChildren == false || taxon.hasTaxonomicChildren()){
165 if (withMisapplications == true || ! taxon.isMisappliedName()){
166 results.add(taxon);
167 }
168 }
169 }
170 return results;
171 }
172
173 public List<TaxonBase> getTaxaByName(String queryString, ReferenceBase sec) {
174
175 return getTaxaByName(queryString, true, sec);
176 }
177
178 public List<TaxonBase> getTaxaByName(String queryString, Boolean accepted, ReferenceBase sec) {
179 checkNotInPriorView("TaxonDaoHibernateImpl.getTaxaByName(String name, ReferenceBase sec)");
180
181 Criteria criteria = null;
182 if (accepted == true) {
183 criteria = getSession().createCriteria(Taxon.class);
184 } else {
185 criteria = getSession().createCriteria(Synonym.class);
186 }
187
188 criteria.setFetchMode( "name", FetchMode.JOIN );
189 criteria.createAlias("name", "name");
190
191 if (sec != null){
192 // FIXME I don't think that we should be saving objects in get methods
193 if(sec.getId() == 0){
194 getSession().save(sec);
195 }
196 criteria.add(Restrictions.eq("sec", sec ) );
197 }
198 if (queryString != null) {
199 criteria.add(Restrictions.ilike("name.nameCache", queryString));
200 }
201
202 return (List<TaxonBase>)criteria.list();
203 }
204
205 public List<TaxonBase> getAllTaxonBases(Integer pagesize, Integer page) {
206 return super.list(pagesize, page);
207 }
208
209 public List<Synonym> getAllSynonyms(Integer limit, Integer start) {
210 return super.list(Synonym.class, limit, start);
211 }
212
213 public List<Taxon> getAllTaxa(Integer limit, Integer start) {
214 return super.list(Taxon.class, limit, start);
215 }
216
217 public List<RelationshipBase> getAllRelationships(Integer limit, Integer start) {
218 AuditEvent auditEvent = getAuditEventFromContext();
219 if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
220 Criteria criteria = getSession().createCriteria(RelationshipBase.class);
221 return (List<RelationshipBase>)criteria.list();
222 } else {
223 AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(RelationshipBase.class,auditEvent.getRevisionNumber());
224 return (List<RelationshipBase>)query.getResultList();
225 }
226 }
227
228 @Override
229 public UUID delete(TaxonBase taxonBase) throws DataAccessException{
230 if (taxonBase == null){
231 logger.warn("TaxonBase was 'null'");
232 return null;
233 }
234
235 // Merge the object in if it is detached
236 //
237 // I think this is preferable to catching lazy initialization errors
238 // as that solution only swallows and hides the exception, but doesn't
239 // actually solve it.
240 getSession().merge(taxonBase);
241
242 for(Iterator<Annotation> iterator = taxonBase.getAnnotations().iterator(); iterator.hasNext();) {
243 Annotation annotation = iterator.next();
244 annotation.setAnnotatedObj(null);
245 iterator.remove();
246 getSession().delete(annotation);
247 }
248
249 for(Iterator<Marker> iterator = taxonBase.getMarkers().iterator(); iterator.hasNext();) {
250 Marker marker = iterator.next();
251 marker.setMarkedObj(null);
252 iterator.remove();
253 getSession().delete(marker);
254 }
255
256 for(Iterator<Extension> iterator = taxonBase.getExtensions().iterator(); iterator.hasNext();) {
257 Extension extension = iterator.next();
258 extension.setExtendedObj(null);
259 iterator.remove();
260 getSession().delete(extension);
261 }
262
263 for(Iterator<OriginalSource> iterator = taxonBase.getSources().iterator(); iterator.hasNext();) {
264 OriginalSource source = iterator.next();
265 source.setSourcedObj(null);
266 iterator.remove();
267 getSession().delete(source);
268 }
269
270 for(Iterator<Rights> iterator = taxonBase.getRights().iterator(); iterator.hasNext();) {
271 Rights rights = iterator.next();
272 iterator.remove();
273 getSession().delete(rights);
274 }
275
276 if (taxonBase instanceof Taxon){ // is Taxon
277 //taxonRelationships
278 Taxon taxon = (Taxon)taxonBase;
279
280 for (Iterator<TaxonRelationship> iterator = taxon.getRelationsFromThisTaxon().iterator(); iterator.hasNext();){
281 TaxonRelationship relationToThisTaxon = iterator.next();
282 iterator.remove();
283 relationToThisTaxon.setFromTaxon(null);
284 relationToThisTaxon.setToTaxon(null);
285 getSession().delete(relationToThisTaxon);
286 }
287
288 for (Iterator<TaxonRelationship> iterator = taxon.getRelationsToThisTaxon().iterator(); iterator.hasNext();){
289 TaxonRelationship relationFromThisTaxon = iterator.next();
290 iterator.remove();
291 relationFromThisTaxon.setToTaxon(null);
292 relationFromThisTaxon.setFromTaxon(null);
293 getSession().delete(relationFromThisTaxon);
294 }
295
296 //SynonymRelationships
297 for (Iterator<SynonymRelationship> iterator = taxon.getSynonymRelations().iterator(); iterator.hasNext();){
298 SynonymRelationship synonymRelation = iterator.next();
299 iterator.remove();
300 synonymRelation.setAcceptedTaxon(null);
301 synonymRelation.setSynonym(null);
302 getSession().delete(synonymRelation);
303 }
304 } else if (taxonBase instanceof Synonym){ //is Synonym
305 Synonym synonym = (Synonym)taxonBase;
306 for (Iterator<SynonymRelationship> iterator = synonym.getSynonymRelations().iterator(); iterator.hasNext();){
307 SynonymRelationship synonymRelation = iterator.next();
308 iterator.remove();
309 synonymRelation.setAcceptedTaxon(null);
310 synonymRelation.setSynonym(null);
311 } ;
312 }
313 return super.delete(taxonBase);
314 }
315
316
317 // TODO add generic return type !!
318 public List findByName(String queryString, ITitledDao.MATCH_MODE matchMode, int page, int pagesize, boolean onlyAcccepted) {
319 ArrayList<Criterion> criteria = new ArrayList<Criterion>();
320 //TODO ... Restrictions.eq(propertyName, value)
321 return super.findByTitle(queryString, matchMode, page, pagesize, criteria);
322
323 }
324
325 public int countMatchesByName(String queryString, ITitledDao.MATCH_MODE matchMode, boolean onlyAcccepted) {
326 checkNotInPriorView("TaxonDaoHibernateImpl.countMatchesByName(String queryString, ITitledDao.MATCH_MODE matchMode, boolean onlyAcccepted)");
327 Criteria crit = getSession().createCriteria(type);
328 crit.add(Restrictions.ilike("titleCache", matchMode.queryStringFrom(queryString)));
329 crit.setProjection(Projections.rowCount());
330 int result = ((Integer)crit.list().get(0)).intValue();
331 return result;
332 }
333
334
335 public int countMatchesByName(String queryString, ITitledDao.MATCH_MODE matchMode, boolean onlyAcccepted, List<Criterion> criteria) {
336 checkNotInPriorView("TaxonDaoHibernateImpl.countMatchesByName(String queryString, ITitledDao.MATCH_MODE matchMode, boolean onlyAcccepted, List<Criterion> criteria)");
337 Criteria crit = getSession().createCriteria(type);
338 crit.add(Restrictions.ilike("titleCache", matchMode.queryStringFrom(queryString)));
339 if(criteria != null){
340 for (Criterion criterion : criteria) {
341 crit.add(criterion);
342 }
343 }
344 crit.setProjection(Projections.rowCount());
345 int result = ((Integer)crit.list().get(0)).intValue();
346 return result;
347 }
348
349 public int countRelatedTaxa(Taxon taxon, TaxonRelationshipType type) {
350 AuditEvent auditEvent = getAuditEventFromContext();
351 if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
352 Query query = null;
353
354 if(type == null) {
355 query = getSession().createQuery("select count(taxonRelationship) from TaxonRelationship taxonRelationship where taxonRelationship.relatedTo = :relatedTo");
356 } else {
357 query = getSession().createQuery("select count(taxonRelationship) from TaxonRelationship taxonRelationship where taxonRelationship.relatedTo = :relatedTo and taxonRelationship.type = :type");
358 query.setParameter("type",type);
359 }
360
361 query.setParameter("relatedTo", taxon);
362
363 return ((Long)query.uniqueResult()).intValue();
364 } else {
365 AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(TaxonRelationship.class,auditEvent.getRevisionNumber());
366 query.add(AuditEntity.relatedId("relatedTo").eq(taxon.getId()));
367 query.addProjection(AuditEntity.id().count("id"));
368
369 if(type != null) {
370 query.add(AuditEntity.relatedId("type").eq(type.getId()));
371 }
372
373 return ((Long)query.getSingleResult()).intValue();
374 }
375 }
376
377 public int countSynonyms(Taxon taxon, SynonymRelationshipType type) {
378 AuditEvent auditEvent = getAuditEventFromContext();
379 if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
380 Query query = null;
381
382 if(type == null) {
383 query = getSession().createQuery("select count(synonymRelationship) from SynonymRelationship synonymRelationship where synonymRelationship.relatedTo = :relatedTo");
384 } else {
385 query = getSession().createQuery("select count(synonymRelationship) from SynonymRelationship synonymRelationship where synonymRelationship.relatedTo = :relatedTo and synonymRelationship.type = :type");
386 query.setParameter("type",type);
387 }
388
389 query.setParameter("relatedTo", taxon);
390
391 return ((Long)query.uniqueResult()).intValue();
392 } else {
393 AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(SynonymRelationship.class,auditEvent.getRevisionNumber());
394 query.add(AuditEntity.relatedId("relatedTo").eq(taxon.getId()));
395 query.addProjection(AuditEntity.id().count("id"));
396
397 if(type != null) {
398 query.add(AuditEntity.relatedId("type").eq(type.getId()));
399 }
400
401 return ((Long)query.getSingleResult()).intValue();
402 }
403 }
404
405 public int countTaxa(String queryString, Boolean accepted) {
406 checkNotInPriorView("TaxonDaoHibernateImpl.countTaxa(String queryString, Boolean accepted)");
407 QueryParser queryParser = new QueryParser("name.titleCache", new SimpleAnalyzer());
408
409 try {
410 org.apache.lucene.search.Query query = queryParser.parse(queryString);
411
412 FullTextSession fullTextSession = Search.createFullTextSession(this.getSession());
413 org.hibernate.search.FullTextQuery fullTextQuery = null;
414
415 if(accepted == null) {
416 fullTextQuery = fullTextSession.createFullTextQuery(query, TaxonBase.class);
417 } else {
418 if(accepted) {
419 fullTextQuery = fullTextSession.createFullTextQuery(query, Taxon.class);
420 } else {
421 fullTextQuery = fullTextSession.createFullTextQuery(query, Synonym.class);
422 }
423 }
424
425 Integer result = fullTextQuery.getResultSize();
426 return result;
427
428 } catch (ParseException e) {
429 throw new QueryParseException(e, queryString);
430 }
431 }
432
433 public int countTaxaByName(String queryString, Boolean accepted, ReferenceBase sec) {
434 checkNotInPriorView("TaxonDaoHibernateImpl.countTaxaByName(String queryString, Boolean accepted, ReferenceBase sec)");
435 Criteria criteria = null;
436
437 if (accepted == true) {
438 criteria = getSession().createCriteria(Taxon.class);
439 } else {
440 criteria = getSession().createCriteria(Synonym.class);
441 }
442
443 criteria.setFetchMode( "name", FetchMode.JOIN );
444 criteria.createAlias("name", "name");
445
446 if (sec != null){
447 if(sec.getId() == 0){
448 getSession().save(sec);
449 }
450 criteria.add(Restrictions.eq("sec", sec ) );
451 }
452 if (queryString != null) {
453 criteria.add(Restrictions.ilike("name.nameCache", queryString));
454 }
455 criteria.setProjection(Projections.projectionList().add(Projections.rowCount()));
456
457 return (Integer)criteria.uniqueResult();
458 }
459
460 public int countTaxaByName(Boolean accepted, String genusOrUninomial, String infraGenericEpithet, String specificEpithet, String infraSpecificEpithet, Rank rank) {
461 checkNotInPriorView("TaxonDaoHibernateImpl.countTaxaByName(Boolean accepted, String genusOrUninomial, String infraGenericEpithet, String specificEpithet, String infraSpecificEpithet, Rank rank)");
462 Criteria criteria = null;
463
464 if(accepted == null) {
465 criteria = getSession().createCriteria(TaxonBase.class);
466 } else {
467 if(accepted) {
468 criteria = getSession().createCriteria(Taxon.class);
469 } else {
470 criteria = getSession().createCriteria(Synonym.class);
471 }
472 }
473
474 criteria.setFetchMode( "name", FetchMode.JOIN );
475 criteria.createAlias("name", "name");
476
477 if(genusOrUninomial != null) {
478 criteria.add(Restrictions.eq("name.genusOrUninomial", genusOrUninomial));
479 }
480
481 if(infraGenericEpithet != null) {
482 criteria.add(Restrictions.eq("name.infraGenericEpithet", infraGenericEpithet));
483 }
484
485 if(specificEpithet != null) {
486 criteria.add(Restrictions.eq("name.specificEpithet", specificEpithet));
487 }
488
489 if(infraSpecificEpithet != null) {
490 criteria.add(Restrictions.eq("name.infraSpecificEpithet", infraSpecificEpithet));
491 }
492
493 if(rank != null) {
494 criteria.add(Restrictions.eq("name.rank", rank));
495 }
496
497 criteria.setProjection(Projections.projectionList().add(Projections.rowCount()));
498
499 return (Integer)criteria.uniqueResult();
500 }
501
502 public List<TaxonBase> findTaxaByName(Boolean accepted, String genusOrUninomial, String infraGenericEpithet, String specificEpithet, String infraSpecificEpithet, Rank rank, Integer pageSize, Integer pageNumber) {
503 checkNotInPriorView("TaxonDaoHibernateImpl.findTaxaByName(Boolean accepted, String genusOrUninomial, String infraGenericEpithet, String specificEpithet, String infraSpecificEpithet, Rank rank, Integer pageSize, Integer pageNumber)");
504 Criteria criteria = null;
505
506 if(accepted == null) {
507 criteria = getSession().createCriteria(TaxonBase.class);
508 } else {
509 if(accepted) {
510 criteria = getSession().createCriteria(Taxon.class);
511 } else {
512 criteria = getSession().createCriteria(Synonym.class);
513 }
514 }
515
516 criteria.setFetchMode( "name", FetchMode.JOIN );
517 criteria.createAlias("name", "name");
518
519 if(genusOrUninomial != null) {
520 criteria.add(Restrictions.eq("name.genusOrUninomial", genusOrUninomial));
521 }
522
523 if(infraGenericEpithet != null) {
524 criteria.add(Restrictions.eq("name.infraGenericEpithet", infraGenericEpithet));
525 } else {
526 criteria.add(Restrictions.isNull("name.infraGenericEpithet"));
527 }
528
529 if(specificEpithet != null) {
530 criteria.add(Restrictions.eq("name.specificEpithet", specificEpithet));
531 }
532
533 if(infraSpecificEpithet != null) {
534 criteria.add(Restrictions.eq("name.infraSpecificEpithet", infraSpecificEpithet));
535 }
536
537 if(rank != null) {
538 criteria.add(Restrictions.eq("name.rank", rank));
539 }
540
541 if(pageSize != null) {
542 criteria.setMaxResults(pageSize);
543 if(pageNumber != null) {
544 criteria.setFirstResult(pageNumber * pageSize);
545 } else {
546 criteria.setFirstResult(0);
547 }
548 }
549
550 return (List<TaxonBase>)criteria.list();
551 }
552
553 public List<TaxonRelationship> getRelatedTaxa(Taxon taxon, TaxonRelationshipType type, Integer pageSize, Integer pageNumber) {
554 AuditEvent auditEvent = getAuditEventFromContext();
555 if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
556 Query query = null;
557
558 if(type == null) {
559 query = getSession().createQuery("select taxonRelationship from TaxonRelationship taxonRelationship join fetch taxonRelationship.relatedFrom where taxonRelationship.relatedTo = :relatedTo");
560 } else {
561 query = getSession().createQuery("select taxonRelationship from TaxonRelationship taxonRelationship join fetch taxonRelationship.relatedFrom where taxonRelationship.relatedTo = :relatedTo and taxonRelationship.type = :type");
562 query.setParameter("type",type);
563 }
564
565 query.setParameter("relatedTo", taxon);
566
567 if(pageSize != null) {
568 query.setMaxResults(pageSize);
569 if(pageNumber != null) {
570 query.setFirstResult(pageNumber * pageSize);
571 } else {
572 query.setFirstResult(0);
573 }
574 }
575
576 return (List<TaxonRelationship>)query.list();
577 } else {
578 AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(TaxonRelationship.class,auditEvent.getRevisionNumber());
579 query.add(AuditEntity.relatedId("relatedTo").eq(taxon.getId()));
580
581 if(type != null) {
582 query.add(AuditEntity.relatedId("type").eq(type.getId()));
583 }
584
585 if(pageSize != null) {
586 query.setMaxResults(pageSize);
587 if(pageNumber != null) {
588 query.setFirstResult(pageNumber * pageSize);
589 } else {
590 query.setFirstResult(0);
591 }
592 }
593
594 List<TaxonRelationship> result = (List<TaxonRelationship>)query.getResultList();
595 for(TaxonRelationship relationship : result) {
596 Hibernate.initialize(relationship.getFromTaxon());
597 }
598
599 return result;
600 }
601 }
602
603 public List<SynonymRelationship> getSynonyms(Taxon taxon, SynonymRelationshipType type, Integer pageSize, Integer pageNumber) {
604 AuditEvent auditEvent = getAuditEventFromContext();
605 if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
606 Query query = null;
607
608 if(type == null) {
609 query = getSession().createQuery("select synonymRelationship from SynonymRelationship synonymRelationship join fetch synonymRelationship.relatedFrom where synonymRelationship.relatedTo = :relatedTo");
610 } else {
611 query = getSession().createQuery("select synonymRelationship from SynonymRelationship synonymRelationship join fetch synonymRelationship.relatedFrom where synonymRelationship.relatedTo = :relatedTo and synonymRelationship.type = :type");
612 query.setParameter("type",type);
613 }
614
615 query.setParameter("relatedTo", taxon);
616
617 if(pageSize != null) {
618 query.setMaxResults(pageSize);
619 if(pageNumber != null) {
620 query.setFirstResult(pageNumber * pageSize);
621 } else {
622 query.setFirstResult(0);
623 }
624 }
625
626 return (List<SynonymRelationship>)query.list();
627 } else {
628 AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(SynonymRelationship.class,auditEvent.getRevisionNumber());
629 query.add(AuditEntity.relatedId("relatedTo").eq(taxon.getId()));
630
631 if(type != null) {
632 query.add(AuditEntity.relatedId("type").eq(type.getId()));
633 }
634
635 if(pageSize != null) {
636 query.setMaxResults(pageSize);
637 if(pageNumber != null) {
638 query.setFirstResult(pageNumber * pageSize);
639 } else {
640 query.setFirstResult(0);
641 }
642 }
643
644 List<SynonymRelationship> result = (List<SynonymRelationship>)query.getResultList();
645 for(SynonymRelationship relationship : result) {
646 Hibernate.initialize(relationship.getSynonym());
647 }
648
649 return result;
650 }
651 }
652
653 public List<TaxonBase> searchTaxa(String queryString, Boolean accepted, Integer pageSize, Integer pageNumber) {
654 checkNotInPriorView("TaxonDaoHibernateImpl.searchTaxa(String queryString, Boolean accepted, Integer pageSize, Integer pageNumber)");
655 QueryParser queryParser = new QueryParser("name.titleCache", new SimpleAnalyzer());
656 List<TaxonBase> results = new ArrayList<TaxonBase>();
657
658 try {
659 org.apache.lucene.search.Query query = queryParser.parse(queryString);
660
661 FullTextSession fullTextSession = Search.createFullTextSession(getSession());
662 org.hibernate.search.FullTextQuery fullTextQuery = null;
663 Criteria criteria = null;
664
665 if(accepted == null) {
666 fullTextQuery = fullTextSession.createFullTextQuery(query, TaxonBase.class);
667 criteria = getSession().createCriteria( TaxonBase.class );
668 } else {
669 if(accepted) {
670 fullTextQuery = fullTextSession.createFullTextQuery(query, Taxon.class);
671 criteria = getSession().createCriteria( Taxon.class );
672 } else {
673 fullTextQuery = fullTextSession.createFullTextQuery(query, Synonym.class);
674 criteria = getSession().createCriteria( Synonym.class );
675 }
676 }
677
678 org.apache.lucene.search.Sort sort = new Sort(new SortField("name.titleCache_forSort"));
679 fullTextQuery.setSort(sort);
680
681 criteria.setFetchMode( "name", FetchMode.JOIN );
682 fullTextQuery.setCriteriaQuery(criteria);
683
684 if(pageSize != null) {
685 fullTextQuery.setMaxResults(pageSize);
686 if(pageNumber != null) {
687 fullTextQuery.setFirstResult(pageNumber * pageSize);
688 } else {
689 fullTextQuery.setFirstResult(0);
690 }
691 }
692
693 return (List<TaxonBase>)fullTextQuery.list();
694
695 } catch (ParseException e) {
696 throw new QueryParseException(e, queryString);
697 }
698 }
699
700 public void purgeIndex() {
701 FullTextSession fullTextSession = Search.createFullTextSession(getSession());
702
703 fullTextSession.purgeAll(type); // remove all taxon base from indexes
704 // fullTextSession.flushToIndexes() not implemented in 3.0.0.GA
705 }
706
707 public void rebuildIndex() {
708 FullTextSession fullTextSession = Search.createFullTextSession(getSession());
709
710 for(TaxonBase taxonBase : list(null,null)) { // re-index all taxon base
711 Hibernate.initialize(taxonBase.getName());
712 fullTextSession.index(taxonBase);
713 }
714 // fullTextSession.flushToIndexes() not implemented in 3.0.0.GA
715 }
716
717 public void optimizeIndex() {
718 FullTextSession fullTextSession = Search.createFullTextSession(getSession());
719 SearchFactory searchFactory = fullTextSession.getSearchFactory();
720 searchFactory.optimize(type); // optimize the indices ()
721 // fullTextSession.flushToIndexes() not implemented in 3.0.0.GA
722 }
723
724 public String suggestQuery(String queryString) {
725 checkNotInPriorView("TaxonDaoHibernateImpl.suggestQuery(String queryString)");
726 String alternativeQueryString = null;
727 if (alternativeSpellingSuggestionParser != null) {
728 try {
729
730 alternativeSpellingSuggestionParser.parse(queryString);
731 org.apache.lucene.search.Query alternativeQuery = alternativeSpellingSuggestionParser
732 .suggest(queryString);
733 if (alternativeQuery != null) {
734 alternativeQueryString = alternativeQuery
735 .toString("name.titleCache");
736 }
737
738 } catch (ParseException e) {
739 throw new QueryParseException(e, queryString);
740 }
741 }
742 return alternativeQueryString;
743 }
744 }