Add sec restriction back in getTaxaByName
[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.lang.reflect.Field;
12 import java.util.ArrayList;
13 import java.util.Collections;
14 import java.util.HashSet;
15 import java.util.Iterator;
16 import java.util.List;
17 import java.util.Set;
18 import java.util.UUID;
19
20 import org.apache.log4j.Logger;
21 import org.apache.lucene.analysis.SimpleAnalyzer;
22 import org.apache.lucene.queryParser.ParseException;
23 import org.apache.lucene.queryParser.QueryParser;
24 import org.apache.lucene.search.Sort;
25 import org.apache.lucene.search.SortField;
26 import org.hibernate.Criteria;
27 import org.hibernate.FetchMode;
28 import org.hibernate.Hibernate;
29 import org.hibernate.LazyInitializationException;
30 import org.hibernate.Query;
31 import org.hibernate.Transaction;
32 import org.hibernate.criterion.Criterion;
33 import org.hibernate.criterion.Projections;
34 import org.hibernate.criterion.Restrictions;
35 import org.hibernate.envers.query.AuditEntity;
36 import org.hibernate.envers.query.AuditQuery;
37 import org.hibernate.search.FullTextQuery;
38 import org.hibernate.search.FullTextSession;
39 import org.hibernate.search.Search;
40 import org.hibernate.search.SearchFactory;
41 import org.springframework.beans.factory.annotation.Autowired;
42 import org.springframework.beans.factory.annotation.Qualifier;
43 import org.springframework.dao.DataAccessException;
44 import org.springframework.stereotype.Repository;
45 import org.springframework.util.ReflectionUtils;
46
47 import eu.etaxonomy.cdm.model.common.Annotation;
48 import eu.etaxonomy.cdm.model.common.Extension;
49 import eu.etaxonomy.cdm.model.common.Marker;
50 import eu.etaxonomy.cdm.model.common.OriginalSource;
51 import eu.etaxonomy.cdm.model.common.RelationshipBase;
52 import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
53 import eu.etaxonomy.cdm.model.description.TaxonDescription;
54 import eu.etaxonomy.cdm.model.media.Rights;
55 import eu.etaxonomy.cdm.model.location.WaterbodyOrCountry;
56 import eu.etaxonomy.cdm.model.name.Rank;
57 import eu.etaxonomy.cdm.model.name.TaxonNameBase;
58 import eu.etaxonomy.cdm.model.occurrence.Collection;
59 import eu.etaxonomy.cdm.model.occurrence.DeterminationEvent;
60 import eu.etaxonomy.cdm.model.reference.ReferenceBase;
61 import eu.etaxonomy.cdm.model.taxon.Synonym;
62 import eu.etaxonomy.cdm.model.taxon.SynonymRelationship;
63 import eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType;
64 import eu.etaxonomy.cdm.model.taxon.Taxon;
65 import eu.etaxonomy.cdm.model.taxon.TaxonBase;
66 import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;
67 import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;
68 import eu.etaxonomy.cdm.model.view.AuditEvent;
69 import eu.etaxonomy.cdm.persistence.dao.BeanInitializer;
70 import eu.etaxonomy.cdm.persistence.dao.QueryParseException;
71 import eu.etaxonomy.cdm.persistence.dao.common.ISearchableDao;
72 import eu.etaxonomy.cdm.persistence.dao.common.ITitledDao;
73 import eu.etaxonomy.cdm.persistence.dao.hibernate.AlternativeSpellingSuggestionParser;
74 import eu.etaxonomy.cdm.persistence.dao.hibernate.HibernateBeanInitializer;
75 import eu.etaxonomy.cdm.persistence.dao.hibernate.common.IdentifiableDaoBase;
76 import eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao;
77 import eu.etaxonomy.cdm.persistence.fetch.CdmFetch;
78 import eu.etaxonomy.cdm.persistence.query.MatchMode;
79
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 private String defaultField = "name.titleCache";
96 private String defaultSort = "name.titleCache_forSort";
97 private Class<? extends TaxonBase> indexedClasses[];
98
99 public TaxonDaoHibernateImpl() {
100 super(TaxonBase.class);
101 indexedClasses = new Class[2];
102 indexedClasses[0] = Taxon.class;
103 indexedClasses[1] = Synonym.class;
104 }
105
106 @Autowired(required = false) //TODO switched of because it caused problems when starting CdmApplicationController
107 public void setAlternativeSpellingSuggestionParser(AlternativeSpellingSuggestionParser<TaxonBase> alternativeSpellingSuggestionParser) {
108 this.alternativeSpellingSuggestionParser = alternativeSpellingSuggestionParser;
109 }
110
111 /* (non-Javadoc)
112 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getRootTaxa(eu.etaxonomy.cdm.model.reference.ReferenceBase)
113 */
114 public List<Taxon> getRootTaxa(ReferenceBase sec) {
115 return getRootTaxa(sec, CdmFetch.FETCH_CHILDTAXA(), true, false);
116 }
117
118 @Override
119 public TaxonBase findByUuid(UUID uuid) {
120 TaxonBase taxonBase = super.findByUuid(uuid);
121 if(taxonBase == null)
122 return taxonBase;
123
124 Hibernate.initialize(taxonBase.getName());
125 Hibernate.initialize(taxonBase.getSec());
126 return taxonBase;
127 }
128
129
130 /* (non-Javadoc)
131 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getRootTaxa(eu.etaxonomy.cdm.model.name.Rank, eu.etaxonomy.cdm.model.reference.ReferenceBase, eu.etaxonomy.cdm.persistence.fetch.CdmFetch, java.lang.Boolean, java.lang.Boolean)
132 */
133 public List<Taxon> getRootTaxa(Rank rank, ReferenceBase sec, CdmFetch cdmFetch, Boolean onlyWithChildren, Boolean withMisapplications) {
134 checkNotInPriorView("TaxonDaoHibernateImpl.getRootTaxa(Rank rank, ReferenceBase sec, CdmFetch cdmFetch, Boolean onlyWithChildren, Boolean withMisapplications)");
135 if (onlyWithChildren == null){
136 onlyWithChildren = true;
137 }
138 if (withMisapplications == null){
139 withMisapplications = true;
140 }
141 if (cdmFetch == null){
142 cdmFetch = CdmFetch.NO_FETCH();
143 }
144
145 Criteria crit = getSession().createCriteria(Taxon.class);
146
147 crit.setFetchMode("name", FetchMode.JOIN);
148 crit.createAlias("name", "name");
149
150 if (rank != null) {
151 crit.add(Restrictions.eq("name.rank", rank));
152 }else{
153 crit.add(Restrictions.isNull("taxonomicParentCache"));
154 }
155
156 if (sec != null){
157 crit.add(Restrictions.eq("sec", sec) );
158 }
159
160 if (! cdmFetch.includes(CdmFetch.FETCH_CHILDTAXA())){
161 logger.info("Not fetching child taxa");
162 //TODO overwrite LAZY (SELECT) does not work (bug in hibernate?)
163 crit.setFetchMode("relationsToThisTaxon.fromTaxon", FetchMode.LAZY);
164 }
165
166 List<Taxon> results = new ArrayList<Taxon>();
167 List<Taxon> taxa = crit.list();
168 for(Taxon taxon : taxa){
169 //childTaxa
170 //TODO create restriction instead
171 //Hibernate.initialize(taxon.getName());
172 Hibernate.initialize(taxon.getSec());
173
174 // (a) not using cache fields
175 /*Hibernate.initialize(taxon.getRelationsFromThisTaxon());
176 if (onlyWithChildren == false || taxon.getRelationsFromThisTaxon().size() > 0){
177 if (withMisapplications == true || ! taxon.isMisappliedName()){
178 results.add(taxon);
179 }
180 }*/
181 // (b) using cache fields
182 if (onlyWithChildren == false || taxon.hasTaxonomicChildren()){
183 if (withMisapplications == true || ! taxon.isMisappliedName()){
184 results.add(taxon);
185 }
186 }
187 }
188 return results;
189 }
190
191 /* (non-Javadoc)
192 * @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)
193 */
194 public List<Taxon> getRootTaxa(ReferenceBase sec, CdmFetch cdmFetch, Boolean onlyWithChildren, Boolean withMisapplications) {
195 return getRootTaxa(null, sec, cdmFetch, onlyWithChildren, withMisapplications);
196 }
197
198
199 public List<TaxonBase> getTaxaByName(String queryString, ReferenceBase sec) {
200
201 return getTaxaByName(queryString, true, sec);
202 }
203
204 public List<TaxonBase> getTaxaByName(String queryString, Boolean accepted, ReferenceBase sec) {
205 checkNotInPriorView("TaxonDaoHibernateImpl.getTaxaByName(String name, ReferenceBase sec)");
206
207 Criteria criteria = null;
208 if (accepted == true) {
209 criteria = getSession().createCriteria(Taxon.class);
210 } else {
211 criteria = getSession().createCriteria(Synonym.class);
212 }
213
214 criteria.setFetchMode( "name", FetchMode.JOIN );
215 criteria.createAlias("name", "name");
216
217 if (sec != null && sec.getId() != 0) {
218 criteria.add(Restrictions.eq("sec", sec ) );
219 }
220
221 // FIXME: sec restriction caused problems in cich image import: results was empty
222
223 if (queryString != null) {
224 criteria.add(Restrictions.ilike("name.nameCache", queryString));
225 }
226
227 return (List<TaxonBase>)criteria.list();
228 }
229
230 public List<TaxonBase> getTaxaByName(String queryString, MatchMode matchMode,
231 Boolean accepted, Integer pageSize, Integer pageNumber) {
232
233 Criteria criteria = null;
234 if (accepted == true) {
235 criteria = getSession().createCriteria(Taxon.class);
236 } else {
237 criteria = getSession().createCriteria(Synonym.class);
238 }
239
240 criteria.setFetchMode( "name", FetchMode.JOIN );
241 criteria.createAlias("name", "name");
242
243 if (matchMode == MatchMode.EXACT) {
244 criteria.add(Restrictions.eq("name.nameCache", matchMode.queryStringFrom(queryString)));
245 } else {
246 criteria.add(Restrictions.ilike("name.nameCache", matchMode.queryStringFrom(queryString)));
247 }
248
249
250 // if (queryString != null) {
251 // criteria.add(Restrictions.ilike("name.nameCache", queryString));
252 // }
253 //
254 if(pageSize != null) {
255 criteria.setMaxResults(pageSize);
256 if(pageNumber != null) {
257 criteria.setFirstResult(pageNumber * pageSize);
258 }
259 }
260
261 List<TaxonBase> results = criteria.list();
262 return results;
263 }
264
265 public List<TaxonBase> getAllTaxonBases(Integer pagesize, Integer page) {
266 return super.list(pagesize, page);
267 }
268
269 public List<Synonym> getAllSynonyms(Integer limit, Integer start) {
270 return super.list(Synonym.class, limit, start);
271 }
272
273 public List<Taxon> getAllTaxa(Integer limit, Integer start) {
274 return super.list(Taxon.class, limit, start);
275 }
276
277 public List<RelationshipBase> getAllRelationships(Integer limit, Integer start) {
278 AuditEvent auditEvent = getAuditEventFromContext();
279 if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
280 Criteria criteria = getSession().createCriteria(RelationshipBase.class);
281 return (List<RelationshipBase>)criteria.list();
282 } else {
283 AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(RelationshipBase.class,auditEvent.getRevisionNumber());
284 return (List<RelationshipBase>)query.getResultList();
285 }
286 }
287
288 @Override
289 public UUID delete(TaxonBase taxonBase) throws DataAccessException{
290 if (taxonBase == null){
291 logger.warn("TaxonBase was 'null'");
292 return null;
293 }
294
295 // Merge the object in if it is detached
296 //
297 // I think this is preferable to catching lazy initialization errors
298 // as that solution only swallows and hides the exception, but doesn't
299 // actually solve it.
300 getSession().merge(taxonBase);
301
302 for(Iterator<Annotation> iterator = taxonBase.getAnnotations().iterator(); iterator.hasNext();) {
303 Annotation annotation = iterator.next();
304 annotation.setAnnotatedObj(null);
305 iterator.remove();
306 getSession().delete(annotation);
307 }
308
309 for(Iterator<Marker> iterator = taxonBase.getMarkers().iterator(); iterator.hasNext();) {
310 Marker marker = iterator.next();
311 marker.setMarkedObj(null);
312 iterator.remove();
313 getSession().delete(marker);
314 }
315
316 for(Iterator<Extension> iterator = taxonBase.getExtensions().iterator(); iterator.hasNext();) {
317 Extension extension = iterator.next();
318 extension.setExtendedObj(null);
319 iterator.remove();
320 getSession().delete(extension);
321 }
322
323 for(Iterator<OriginalSource> iterator = taxonBase.getSources().iterator(); iterator.hasNext();) {
324 OriginalSource source = iterator.next();
325 source.setSourcedObj(null);
326 iterator.remove();
327 getSession().delete(source);
328 }
329
330 for(Iterator<Rights> iterator = taxonBase.getRights().iterator(); iterator.hasNext();) {
331 Rights rights = iterator.next();
332 iterator.remove();
333 getSession().delete(rights);
334 }
335
336 if (taxonBase instanceof Taxon){ // is Taxon
337 //taxonRelationships
338 Taxon taxon = (Taxon)taxonBase;
339
340 for (Iterator<TaxonRelationship> iterator = taxon.getRelationsFromThisTaxon().iterator(); iterator.hasNext();){
341 TaxonRelationship relationToThisTaxon = iterator.next();
342 iterator.remove();
343 relationToThisTaxon.setFromTaxon(null);
344 relationToThisTaxon.setToTaxon(null);
345 getSession().delete(relationToThisTaxon);
346 }
347
348 for (Iterator<TaxonRelationship> iterator = taxon.getRelationsToThisTaxon().iterator(); iterator.hasNext();){
349 TaxonRelationship relationFromThisTaxon = iterator.next();
350 iterator.remove();
351 relationFromThisTaxon.setToTaxon(null);
352 relationFromThisTaxon.setFromTaxon(null);
353 getSession().delete(relationFromThisTaxon);
354 }
355
356 //SynonymRelationships
357 for (Iterator<SynonymRelationship> iterator = taxon.getSynonymRelations().iterator(); iterator.hasNext();){
358 SynonymRelationship synonymRelation = iterator.next();
359 iterator.remove();
360 synonymRelation.setAcceptedTaxon(null);
361 synonymRelation.setSynonym(null);
362 getSession().delete(synonymRelation);
363 }
364
365 // Descriptions
366 for (Iterator<TaxonDescription> iterDesc = taxon.getDescriptions().iterator(); iterDesc.hasNext();) {
367 TaxonDescription taxonDescription = iterDesc.next();
368 iterDesc.remove();
369 //taxonDescription.setTaxon(null);
370 Field field = ReflectionUtils.findField(TaxonDescription.class, "taxon", Taxon.class);
371 ReflectionUtils.makeAccessible(field);
372 ReflectionUtils.setField(field, taxonDescription, null);
373 for (Iterator<DescriptionElementBase> iterDescElem =
374 taxonDescription.getElements().iterator(); iterDescElem.hasNext();) {
375 DescriptionElementBase descriptionElement = iterDescElem.next();
376 iterDescElem.remove();
377 getSession().delete(descriptionElement);
378 }
379 getSession().delete(taxonDescription);
380 }
381
382 } else { //is Synonym
383 Synonym synonym = (Synonym)taxonBase;
384 for (Iterator<SynonymRelationship> iterator = synonym.getSynonymRelations().iterator(); iterator.hasNext();){
385 SynonymRelationship synonymRelation = iterator.next();
386 iterator.remove();
387 synonymRelation.setAcceptedTaxon(null);
388 synonymRelation.setSynonym(null);
389 } ;
390 }
391 return super.delete(taxonBase);
392 }
393
394
395 // TODO add generic return type !!
396 public List findByName(String queryString, MatchMode matchMode, int page, int pagesize, boolean onlyAcccepted) {
397 ArrayList<Criterion> criteria = new ArrayList<Criterion>();
398 //TODO ... Restrictions.eq(propertyName, value)
399 return super.findByTitle(queryString, matchMode, page, pagesize, criteria);
400
401 }
402
403 public int countMatchesByName(String queryString, MatchMode matchMode, boolean onlyAcccepted) {
404 checkNotInPriorView("TaxonDaoHibernateImpl.countMatchesByName(String queryString, ITitledDao.MATCH_MODE matchMode, boolean onlyAcccepted)");
405 Criteria crit = getSession().createCriteria(type);
406 crit.add(Restrictions.ilike("titleCache", matchMode.queryStringFrom(queryString)));
407 crit.setProjection(Projections.rowCount());
408 int result = ((Integer)crit.list().get(0)).intValue();
409 return result;
410 }
411
412
413 public int countMatchesByName(String queryString, MatchMode matchMode, boolean onlyAcccepted, List<Criterion> criteria) {
414 checkNotInPriorView("TaxonDaoHibernateImpl.countMatchesByName(String queryString, ITitledDao.MATCH_MODE matchMode, boolean onlyAcccepted, List<Criterion> criteria)");
415 Criteria crit = getSession().createCriteria(type);
416 crit.add(Restrictions.ilike("titleCache", matchMode.queryStringFrom(queryString)));
417 if(criteria != null){
418 for (Criterion criterion : criteria) {
419 crit.add(criterion);
420 }
421 }
422 crit.setProjection(Projections.rowCount());
423 int result = ((Integer)crit.list().get(0)).intValue();
424 return result;
425 }
426
427 public int countRelatedTaxa(Taxon taxon, TaxonRelationshipType type) {
428 AuditEvent auditEvent = getAuditEventFromContext();
429 if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
430 Query query = null;
431
432 if(type == null) {
433 query = getSession().createQuery("select count(taxonRelationship) from TaxonRelationship taxonRelationship where taxonRelationship.relatedTo = :relatedTo");
434 } else {
435 query = getSession().createQuery("select count(taxonRelationship) from TaxonRelationship taxonRelationship where taxonRelationship.relatedTo = :relatedTo and taxonRelationship.type = :type");
436 query.setParameter("type",type);
437 }
438
439 query.setParameter("relatedTo", taxon);
440
441 return ((Long)query.uniqueResult()).intValue();
442 } else {
443 AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(TaxonRelationship.class,auditEvent.getRevisionNumber());
444 query.add(AuditEntity.relatedId("relatedTo").eq(taxon.getId()));
445 query.addProjection(AuditEntity.id().count("id"));
446
447 if(type != null) {
448 query.add(AuditEntity.relatedId("type").eq(type.getId()));
449 }
450
451 return ((Long)query.getSingleResult()).intValue();
452 }
453 }
454
455 public int countSynonyms(Taxon taxon, SynonymRelationshipType type) {
456 AuditEvent auditEvent = getAuditEventFromContext();
457 if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
458 Query query = null;
459
460 if(type == null) {
461 query = getSession().createQuery("select count(synonymRelationship) from SynonymRelationship synonymRelationship where synonymRelationship.relatedTo = :relatedTo");
462 } else {
463 query = getSession().createQuery("select count(synonymRelationship) from SynonymRelationship synonymRelationship where synonymRelationship.relatedTo = :relatedTo and synonymRelationship.type = :type");
464 query.setParameter("type",type);
465 }
466
467 query.setParameter("relatedTo", taxon);
468
469 return ((Long)query.uniqueResult()).intValue();
470 } else {
471 AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(SynonymRelationship.class,auditEvent.getRevisionNumber());
472 query.add(AuditEntity.relatedId("relatedTo").eq(taxon.getId()));
473 query.addProjection(AuditEntity.id().count("id"));
474
475 if(type != null) {
476 query.add(AuditEntity.relatedId("type").eq(type.getId()));
477 }
478
479 return ((Long)query.getSingleResult()).intValue();
480 }
481 }
482
483 public int countTaxa(String queryString, Boolean accepted) {
484 checkNotInPriorView("TaxonDaoHibernateImpl.countTaxa(String queryString, Boolean accepted)");
485 QueryParser queryParser = new QueryParser("name.titleCache", new SimpleAnalyzer());
486
487 try {
488 org.apache.lucene.search.Query query = queryParser.parse(queryString);
489
490 FullTextSession fullTextSession = Search.getFullTextSession(this.getSession());
491 org.hibernate.search.FullTextQuery fullTextQuery = null;
492
493 if(accepted == null) {
494 fullTextQuery = fullTextSession.createFullTextQuery(query, TaxonBase.class);
495 } else {
496 if(accepted) {
497 fullTextQuery = fullTextSession.createFullTextQuery(query, Taxon.class);
498 } else {
499 fullTextQuery = fullTextSession.createFullTextQuery(query, Synonym.class);
500 }
501 }
502
503 Integer result = fullTextQuery.getResultSize();
504 return result;
505
506 } catch (ParseException e) {
507 throw new QueryParseException(e, queryString);
508 }
509 }
510
511 public int countTaxaByName(String queryString, Boolean accepted, ReferenceBase sec) {
512 checkNotInPriorView("TaxonDaoHibernateImpl.countTaxaByName(String queryString, Boolean accepted, ReferenceBase sec)");
513 Criteria criteria = null;
514
515 if (accepted == true) {
516 criteria = getSession().createCriteria(Taxon.class);
517 } else {
518 criteria = getSession().createCriteria(Synonym.class);
519 }
520
521 criteria.setFetchMode( "name", FetchMode.JOIN );
522 criteria.createAlias("name", "name");
523
524 if (sec != null){
525 if(sec.getId() == 0){
526 getSession().save(sec);
527 }
528 criteria.add(Restrictions.eq("sec", sec ) );
529 }
530 if (queryString != null) {
531 criteria.add(Restrictions.ilike("name.nameCache", queryString));
532 }
533 criteria.setProjection(Projections.projectionList().add(Projections.rowCount()));
534
535 return (Integer)criteria.uniqueResult();
536 }
537
538 public int countTaxaByName(Boolean accepted, String genusOrUninomial, String infraGenericEpithet, String specificEpithet, String infraSpecificEpithet, Rank rank) {
539 checkNotInPriorView("TaxonDaoHibernateImpl.countTaxaByName(Boolean accepted, String genusOrUninomial, String infraGenericEpithet, String specificEpithet, String infraSpecificEpithet, Rank rank)");
540 Criteria criteria = null;
541
542 if(accepted == null) {
543 criteria = getSession().createCriteria(TaxonBase.class);
544 } else {
545 if(accepted) {
546 criteria = getSession().createCriteria(Taxon.class);
547 } else {
548 criteria = getSession().createCriteria(Synonym.class);
549 }
550 }
551
552 criteria.setFetchMode( "name", FetchMode.JOIN );
553 criteria.createAlias("name", "name");
554
555 if(genusOrUninomial != null) {
556 criteria.add(Restrictions.eq("name.genusOrUninomial", genusOrUninomial));
557 }
558
559 if(infraGenericEpithet != null) {
560 criteria.add(Restrictions.eq("name.infraGenericEpithet", infraGenericEpithet));
561 }
562
563 if(specificEpithet != null) {
564 criteria.add(Restrictions.eq("name.specificEpithet", specificEpithet));
565 }
566
567 if(infraSpecificEpithet != null) {
568 criteria.add(Restrictions.eq("name.infraSpecificEpithet", infraSpecificEpithet));
569 }
570
571 if(rank != null) {
572 criteria.add(Restrictions.eq("name.rank", rank));
573 }
574
575 criteria.setProjection(Projections.projectionList().add(Projections.rowCount()));
576
577 return (Integer)criteria.uniqueResult();
578 }
579
580 public List<TaxonBase> findTaxaByName(Boolean accepted, String genusOrUninomial, String infraGenericEpithet, String specificEpithet, String infraSpecificEpithet, Rank rank, Integer pageSize, Integer pageNumber) {
581 checkNotInPriorView("TaxonDaoHibernateImpl.findTaxaByName(Boolean accepted, String genusOrUninomial, String infraGenericEpithet, String specificEpithet, String infraSpecificEpithet, Rank rank, Integer pageSize, Integer pageNumber)");
582 Criteria criteria = null;
583
584 if(accepted == null) {
585 criteria = getSession().createCriteria(TaxonBase.class);
586 } else {
587 if(accepted) {
588 criteria = getSession().createCriteria(Taxon.class);
589 } else {
590 criteria = getSession().createCriteria(Synonym.class);
591 }
592 }
593
594 criteria.setFetchMode( "name", FetchMode.JOIN );
595 criteria.createAlias("name", "name");
596
597 if(genusOrUninomial != null) {
598 criteria.add(Restrictions.eq("name.genusOrUninomial", genusOrUninomial));
599 }
600
601 if(infraGenericEpithet != null) {
602 criteria.add(Restrictions.eq("name.infraGenericEpithet", infraGenericEpithet));
603 } else {
604 criteria.add(Restrictions.isNull("name.infraGenericEpithet"));
605 }
606
607 if(specificEpithet != null) {
608 criteria.add(Restrictions.eq("name.specificEpithet", specificEpithet));
609 }
610
611 if(infraSpecificEpithet != null) {
612 criteria.add(Restrictions.eq("name.infraSpecificEpithet", infraSpecificEpithet));
613 }
614
615 if(rank != null) {
616 criteria.add(Restrictions.eq("name.rank", rank));
617 }
618
619 if(pageSize != null) {
620 criteria.setMaxResults(pageSize);
621 if(pageNumber != null) {
622 criteria.setFirstResult(pageNumber * pageSize);
623 } else {
624 criteria.setFirstResult(0);
625 }
626 }
627
628 return (List<TaxonBase>)criteria.list();
629 }
630
631 public List<TaxonRelationship> getRelatedTaxa(Taxon taxon, TaxonRelationshipType type, Integer pageSize, Integer pageNumber) {
632 AuditEvent auditEvent = getAuditEventFromContext();
633 if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
634 Query query = null;
635
636 if(type == null) {
637 query = getSession().createQuery("select taxonRelationship from TaxonRelationship taxonRelationship join fetch taxonRelationship.relatedFrom where taxonRelationship.relatedTo = :relatedTo");
638 } else {
639 query = getSession().createQuery("select taxonRelationship from TaxonRelationship taxonRelationship join fetch taxonRelationship.relatedFrom where taxonRelationship.relatedTo = :relatedTo and taxonRelationship.type = :type");
640 query.setParameter("type",type);
641 }
642
643 query.setParameter("relatedTo", taxon);
644
645 if(pageSize != null) {
646 query.setMaxResults(pageSize);
647 if(pageNumber != null) {
648 query.setFirstResult(pageNumber * pageSize);
649 } else {
650 query.setFirstResult(0);
651 }
652 }
653
654 return (List<TaxonRelationship>)query.list();
655 } else {
656 AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(TaxonRelationship.class,auditEvent.getRevisionNumber());
657 query.add(AuditEntity.relatedId("relatedTo").eq(taxon.getId()));
658
659 if(type != null) {
660 query.add(AuditEntity.relatedId("type").eq(type.getId()));
661 }
662
663 if(pageSize != null) {
664 query.setMaxResults(pageSize);
665 if(pageNumber != null) {
666 query.setFirstResult(pageNumber * pageSize);
667 } else {
668 query.setFirstResult(0);
669 }
670 }
671
672 List<TaxonRelationship> result = (List<TaxonRelationship>)query.getResultList();
673 for(TaxonRelationship relationship : result) {
674 Hibernate.initialize(relationship.getFromTaxon());
675 }
676
677 return result;
678 }
679 }
680
681 public List<SynonymRelationship> getSynonyms(Taxon taxon, SynonymRelationshipType type, Integer pageSize, Integer pageNumber) {
682 AuditEvent auditEvent = getAuditEventFromContext();
683 if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
684 Query query = null;
685
686 if(type == null) {
687 query = getSession().createQuery("select synonymRelationship from SynonymRelationship synonymRelationship join fetch synonymRelationship.relatedFrom where synonymRelationship.relatedTo = :relatedTo");
688 } else {
689 query = getSession().createQuery("select synonymRelationship from SynonymRelationship synonymRelationship join fetch synonymRelationship.relatedFrom where synonymRelationship.relatedTo = :relatedTo and synonymRelationship.type = :type");
690 query.setParameter("type",type);
691 }
692
693 query.setParameter("relatedTo", taxon);
694
695 if(pageSize != null) {
696 query.setMaxResults(pageSize);
697 if(pageNumber != null) {
698 query.setFirstResult(pageNumber * pageSize);
699 } else {
700 query.setFirstResult(0);
701 }
702 }
703
704 return (List<SynonymRelationship>)query.list();
705 } else {
706 AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(SynonymRelationship.class,auditEvent.getRevisionNumber());
707 query.add(AuditEntity.relatedId("relatedTo").eq(taxon.getId()));
708
709 if(type != null) {
710 query.add(AuditEntity.relatedId("type").eq(type.getId()));
711 }
712
713 if(pageSize != null) {
714 query.setMaxResults(pageSize);
715 if(pageNumber != null) {
716 query.setFirstResult(pageNumber * pageSize);
717 } else {
718 query.setFirstResult(0);
719 }
720 }
721
722 List<SynonymRelationship> result = (List<SynonymRelationship>)query.getResultList();
723 for(SynonymRelationship relationship : result) {
724 Hibernate.initialize(relationship.getSynonym());
725 }
726
727 return result;
728 }
729 }
730
731 public List<TaxonBase> searchTaxa(String queryString, Boolean accepted, Integer pageSize, Integer pageNumber) {
732 checkNotInPriorView("TaxonDaoHibernateImpl.searchTaxa(String queryString, Boolean accepted, Integer pageSize, Integer pageNumber)");
733 QueryParser queryParser = new QueryParser(defaultField, new SimpleAnalyzer());
734 List<TaxonBase> results = new ArrayList<TaxonBase>();
735
736 try {
737 org.apache.lucene.search.Query query = queryParser.parse(queryString);
738
739 FullTextSession fullTextSession = Search.getFullTextSession(getSession());
740 org.hibernate.search.FullTextQuery fullTextQuery = null;
741
742 if(accepted == null) {
743 fullTextQuery = fullTextSession.createFullTextQuery(query, TaxonBase.class);
744 } else {
745 if(accepted) {
746 fullTextQuery = fullTextSession.createFullTextQuery(query, Taxon.class);
747 } else {
748 fullTextQuery = fullTextSession.createFullTextQuery(query, Synonym.class);
749 }
750 }
751
752 org.apache.lucene.search.Sort sort = new Sort(new SortField(defaultSort));
753 fullTextQuery.setSort(sort);
754
755 if(pageSize != null) {
756 fullTextQuery.setMaxResults(pageSize);
757 if(pageNumber != null) {
758 fullTextQuery.setFirstResult(pageNumber * pageSize);
759 } else {
760 fullTextQuery.setFirstResult(0);
761 }
762 }
763
764 List<TaxonBase> result = (List<TaxonBase>)fullTextQuery.list();
765 for(TaxonBase taxonBase : result) {
766 Hibernate.initialize(taxonBase.getName());
767 }
768 return result;
769
770 } catch (ParseException e) {
771 throw new QueryParseException(e, queryString);
772 }
773 }
774
775 public void purgeIndex() {
776 FullTextSession fullTextSession = Search.getFullTextSession(getSession());
777 for(Class clazz : indexedClasses) {
778 fullTextSession.purgeAll(clazz); // remove all taxon base from indexes
779 }
780 fullTextSession.flushToIndexes();
781 }
782
783 public void rebuildIndex() {
784 FullTextSession fullTextSession = Search.getFullTextSession(getSession());
785
786 for(TaxonBase taxonBase : list(null,null)) { // re-index all taxon base
787 Hibernate.initialize(taxonBase.getName());
788 fullTextSession.index(taxonBase);
789 }
790 fullTextSession.flushToIndexes();
791 }
792
793 public void optimizeIndex() {
794 FullTextSession fullTextSession = Search.getFullTextSession(getSession());
795 SearchFactory searchFactory = fullTextSession.getSearchFactory();
796 for(Class clazz : indexedClasses) {
797 searchFactory.optimize(clazz); // optimize the indices ()
798 }
799 fullTextSession.flushToIndexes();
800 }
801
802 public String suggestQuery(String queryString) {
803 checkNotInPriorView("TaxonDaoHibernateImpl.suggestQuery(String queryString)");
804 String alternativeQueryString = null;
805 if (alternativeSpellingSuggestionParser != null) {
806 try {
807
808 alternativeSpellingSuggestionParser.parse(queryString);
809 org.apache.lucene.search.Query alternativeQuery = alternativeSpellingSuggestionParser.suggest(queryString);
810 if (alternativeQuery != null) {
811 alternativeQueryString = alternativeQuery
812 .toString("name.titleCache");
813 }
814
815 } catch (ParseException e) {
816 throw new QueryParseException(e, queryString);
817 }
818 }
819 return alternativeQueryString;
820 }
821
822 public int count(String queryString) {
823 checkNotInPriorView("TaxonDaoHibernateImpl.count(String queryString)");
824 QueryParser queryParser = new QueryParser(defaultField, new SimpleAnalyzer());
825
826 try {
827 org.apache.lucene.search.Query query = queryParser.parse(queryString);
828
829 FullTextSession fullTextSession = Search.getFullTextSession(this.getSession());
830 org.hibernate.search.FullTextQuery fullTextQuery = fullTextSession.createFullTextQuery(query, type);
831
832 return fullTextQuery.getResultSize();
833
834 } catch (ParseException e) {
835 throw new QueryParseException(e, queryString);
836 }
837 }
838
839 public List<TaxonBase> search(String queryString, Integer pageSize, Integer pageNumber) {
840 checkNotInPriorView("TaxonDaoHibernateImpl.search(String queryString, Integer pageSize, Integer pageNumber)");
841 QueryParser queryParser = new QueryParser(defaultField, new SimpleAnalyzer());
842 List<TaxonBase> results = new ArrayList<TaxonBase>();
843
844 try {
845 org.apache.lucene.search.Query query = queryParser.parse(queryString);
846
847 FullTextSession fullTextSession = Search.getFullTextSession(getSession());
848
849 org.hibernate.search.FullTextQuery fullTextQuery = fullTextSession.createFullTextQuery(query, type);
850
851 org.apache.lucene.search.Sort sort = new Sort(new SortField(defaultSort));
852 fullTextQuery.setSort(sort);
853
854 if(pageSize != null) {
855 fullTextQuery.setMaxResults(pageSize);
856 if(pageNumber != null) {
857 fullTextQuery.setFirstResult(pageNumber * pageSize);
858 } else {
859 fullTextQuery.setFirstResult(0);
860 }
861 }
862
863 List<TaxonBase> result = (List<TaxonBase>)fullTextQuery.list();
864 for(TaxonBase taxonBase : result) {
865 Hibernate.initialize(taxonBase.getName());
866 }
867 return result;
868
869 } catch (ParseException e) {
870 throw new QueryParseException(e, queryString);
871 }
872 }
873 }