2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
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.
9 package eu
.etaxonomy
.cdm
.persistence
.dao
.hibernate
.taxon
;
11 import java
.util
.ArrayList
;
12 import java
.util
.Collection
;
13 import java
.util
.Collections
;
14 import java
.util
.Comparator
;
15 import java
.util
.HashSet
;
16 import java
.util
.Iterator
;
17 import java
.util
.List
;
19 import java
.util
.SortedSet
;
20 import java
.util
.TreeSet
;
21 import java
.util
.UUID
;
23 import org
.apache
.log4j
.Logger
;
24 import org
.apache
.lucene
.queryParser
.ParseException
;
25 import org
.hibernate
.Criteria
;
26 import org
.hibernate
.FetchMode
;
27 import org
.hibernate
.Hibernate
;
28 import org
.hibernate
.Query
;
29 import org
.hibernate
.Session
;
30 import org
.hibernate
.criterion
.Criterion
;
31 import org
.hibernate
.criterion
.Order
;
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
.FullTextSession
;
37 import org
.hibernate
.search
.Search
;
38 import org
.springframework
.beans
.factory
.annotation
.Autowired
;
39 import org
.springframework
.beans
.factory
.annotation
.Qualifier
;
40 import org
.springframework
.dao
.DataAccessException
;
41 import org
.springframework
.stereotype
.Repository
;
43 import eu
.etaxonomy
.cdm
.model
.common
.CdmBase
;
44 import eu
.etaxonomy
.cdm
.model
.common
.LSID
;
45 import eu
.etaxonomy
.cdm
.model
.common
.OriginalSourceBase
;
46 import eu
.etaxonomy
.cdm
.model
.common
.RelationshipBase
;
47 import eu
.etaxonomy
.cdm
.model
.common
.RelationshipBase
.Direction
;
48 import eu
.etaxonomy
.cdm
.model
.common
.UuidAndTitleCache
;
49 import eu
.etaxonomy
.cdm
.model
.location
.NamedArea
;
50 import eu
.etaxonomy
.cdm
.model
.name
.NonViralName
;
51 import eu
.etaxonomy
.cdm
.model
.name
.Rank
;
52 import eu
.etaxonomy
.cdm
.model
.name
.TaxonNameBase
;
53 import eu
.etaxonomy
.cdm
.model
.name
.TaxonNameComparator
;
54 import eu
.etaxonomy
.cdm
.model
.reference
.Reference
;
55 import eu
.etaxonomy
.cdm
.model
.taxon
.Classification
;
56 import eu
.etaxonomy
.cdm
.model
.taxon
.Synonym
;
57 import eu
.etaxonomy
.cdm
.model
.taxon
.SynonymRelationship
;
58 import eu
.etaxonomy
.cdm
.model
.taxon
.SynonymRelationshipType
;
59 import eu
.etaxonomy
.cdm
.model
.taxon
.Taxon
;
60 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonBase
;
61 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonNode
;
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
.hibernate
.AlternativeSpellingSuggestionParser
;
67 import eu
.etaxonomy
.cdm
.persistence
.dao
.hibernate
.common
.IdentifiableDaoBase
;
68 import eu
.etaxonomy
.cdm
.persistence
.dao
.name
.ITaxonNameDao
;
69 import eu
.etaxonomy
.cdm
.persistence
.dao
.taxon
.ITaxonDao
;
70 import eu
.etaxonomy
.cdm
.persistence
.fetch
.CdmFetch
;
71 import eu
.etaxonomy
.cdm
.persistence
.query
.MatchMode
;
72 import eu
.etaxonomy
.cdm
.persistence
.query
.OrderHint
;
81 @Qualifier("taxonDaoHibernateImpl")
82 public class TaxonDaoHibernateImpl
extends IdentifiableDaoBase
<TaxonBase
> implements ITaxonDao
{
83 private AlternativeSpellingSuggestionParser
<TaxonBase
> alternativeSpellingSuggestionParser
;
84 private static final Logger logger
= Logger
.getLogger(TaxonDaoHibernateImpl
.class);
86 public TaxonDaoHibernateImpl() {
87 super(TaxonBase
.class);
88 indexedClasses
= new Class
[2];
89 indexedClasses
[0] = Taxon
.class;
90 indexedClasses
[1] = Synonym
.class;
91 super.defaultField
= "name.titleCache_tokenized";
95 private ITaxonNameDao taxonNameDao
;
97 // spelling support currently disabled in appcontext, see spelling.xml ... "
98 // @Autowired(required = false) //TODO switched of because it caused problems when starting CdmApplicationController
99 public void setAlternativeSpellingSuggestionParser(AlternativeSpellingSuggestionParser
<TaxonBase
> alternativeSpellingSuggestionParser
) {
100 this.alternativeSpellingSuggestionParser
= alternativeSpellingSuggestionParser
;
105 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getRootTaxa(eu.etaxonomy.cdm.model.reference.Reference)
107 public List
<Taxon
> getRootTaxa(Reference sec
) {
108 return getRootTaxa(sec
, CdmFetch
.FETCH_CHILDTAXA(), true, false);
112 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getRootTaxa(eu.etaxonomy.cdm.model.name.Rank, eu.etaxonomy.cdm.model.reference.Reference, eu.etaxonomy.cdm.persistence.fetch.CdmFetch, java.lang.Boolean, java.lang.Boolean)
114 public List
<Taxon
> getRootTaxa(Rank rank
, Reference sec
, CdmFetch cdmFetch
, Boolean onlyWithChildren
, Boolean withMisapplications
, List
<String
> propertyPaths
) {
115 checkNotInPriorView("TaxonDaoHibernateImpl.getRootTaxa(Rank rank, Reference sec, CdmFetch cdmFetch, Boolean onlyWithChildren, Boolean withMisapplications)");
116 if (onlyWithChildren
== null){
117 onlyWithChildren
= true;
119 if (withMisapplications
== null){
120 withMisapplications
= true;
122 if (cdmFetch
== null){
123 cdmFetch
= CdmFetch
.NO_FETCH();
126 Criteria crit
= getSession().createCriteria(Taxon
.class);
128 crit
.setFetchMode("name", FetchMode
.JOIN
);
129 crit
.createAlias("name", "name");
132 crit
.add(Restrictions
.eq("name.rank", rank
));
134 crit
.add(Restrictions
.isNull("taxonomicParentCache"));
138 crit
.add(Restrictions
.eq("sec", sec
) );
141 if (! cdmFetch
.includes(CdmFetch
.FETCH_CHILDTAXA())){
142 logger
.info("Not fetching child taxa");
143 //TODO overwrite LAZY (SELECT) does not work (bug in hibernate?)
144 crit
.setFetchMode("relationsToThisTaxon.fromTaxon", FetchMode
.LAZY
);
147 List
<Taxon
> results
= new ArrayList
<Taxon
>();
148 List
<Taxon
> taxa
= crit
.list();
149 for(Taxon taxon
: taxa
){
153 //TODO create restriction instead
154 // (a) not using cache fields
155 /*Hibernate.initialize(taxon.getRelationsFromThisTaxon());
156 if (onlyWithChildren == false || taxon.getRelationsFromThisTaxon().size() > 0){
157 if (withMisapplications == true || ! taxon.isMisappliedName()){
158 defaultBeanInitializer.initialize(taxon, propertyPaths);
162 // (b) using cache fields
163 if (onlyWithChildren
== false || taxon
.hasTaxonomicChildren()){
164 if (withMisapplications
== true || ! taxon
.isMisapplication()){
165 defaultBeanInitializer
.initialize(taxon
, propertyPaths
);
174 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getRootTaxa(eu.etaxonomy.cdm.model.reference.Reference, eu.etaxonomy.cdm.persistence.fetch.CdmFetch, java.lang.Boolean, java.lang.Boolean)
176 public List
<Taxon
> getRootTaxa(Reference sec
, CdmFetch cdmFetch
, Boolean onlyWithChildren
, Boolean withMisapplications
) {
177 return getRootTaxa(null, sec
, cdmFetch
, onlyWithChildren
, withMisapplications
, null);
182 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getTaxaByName(java.lang.String, eu.etaxonomy.cdm.model.reference.Reference)
184 public List
<TaxonBase
> getTaxaByName(String queryString
, Reference sec
) {
186 return getTaxaByName(queryString
, true, sec
);
191 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getTaxaByName(java.lang.String, java.lang.Boolean, eu.etaxonomy.cdm.model.reference.Reference)
193 public List
<TaxonBase
> getTaxaByName(String queryString
, Boolean accepted
, Reference sec
) {
194 checkNotInPriorView("TaxonDaoHibernateImpl.getTaxaByName(String name, Reference sec)");
196 Criteria criteria
= null;
197 if (accepted
== true) {
198 criteria
= getSession().createCriteria(Taxon
.class);
200 criteria
= getSession().createCriteria(Synonym
.class);
203 criteria
.setFetchMode( "name", FetchMode
.JOIN
);
204 criteria
.createAlias("name", "name");
206 if (sec
!= null && sec
.getId() != 0) {
207 criteria
.add(Restrictions
.eq("sec", sec
) );
210 if (queryString
!= null) {
211 criteria
.add(Restrictions
.ilike("name.nameCache", queryString
));
214 return (List
<TaxonBase
>)criteria
.list();
217 public List
<TaxonBase
> getTaxaByName(boolean doTaxa
, boolean doSynonyms
, String queryString
, MatchMode matchMode
,
218 Integer pageSize
, Integer pageNumber
) {
220 return getTaxaByName(doTaxa
, doSynonyms
, false, queryString
, null, matchMode
, null, pageSize
, pageNumber
, null);
225 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getTaxaByName(java.lang.String, eu.etaxonomy.cdm.persistence.query.MatchMode, java.lang.Boolean, java.lang.Integer, java.lang.Integer)
227 public List
<TaxonBase
> getTaxaByName(String queryString
, MatchMode matchMode
,
228 Boolean accepted
, Integer pageSize
, Integer pageNumber
) {
230 boolean doTaxa
= true;
231 boolean doSynonyms
= true;
233 if (accepted
== true) {
238 return getTaxaByName(doTaxa
, doSynonyms
, queryString
, matchMode
, pageSize
, pageNumber
);
243 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getTaxaByName(java.lang.Class, java.lang.String, eu.etaxonomy.cdm.model.taxon.Classification, eu.etaxonomy.cdm.persistence.query.MatchMode, java.util.Set, java.lang.Integer, java.lang.Integer, java.util.List)
245 public List
<TaxonBase
> getTaxaByName(boolean doTaxa
, boolean doSynonyms
, boolean doMisappliedNames
,String queryString
, Classification classification
,
246 MatchMode matchMode
, Set
<NamedArea
> namedAreas
, Integer pageSize
,
247 Integer pageNumber
, List
<String
> propertyPaths
) {
249 boolean doCount
= false;
251 Query query
= prepareTaxaByName(doTaxa
, doSynonyms
, doMisappliedNames
, "nameCache", queryString
, classification
, matchMode
, namedAreas
, pageSize
, pageNumber
, doCount
);
254 List
<TaxonBase
> results
= query
.list();
256 defaultBeanInitializer
.initializeAll(results
, propertyPaths
);
257 //TaxonComparatorSearch comp = new TaxonComparatorSearch();
258 //Collections.sort(results, comp);
262 return new ArrayList
<TaxonBase
>();
269 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getTaxaByName(java.lang.Class, java.lang.String, eu.etaxonomy.cdm.model.taxon.Classification, eu.etaxonomy.cdm.persistence.query.MatchMode, java.util.Set, java.lang.Integer, java.lang.Integer, java.util.List)
271 //new search for the editor, for performance issues the return values are only uuid and titleCache, to avoid the initialisation of all objects
272 @SuppressWarnings("unchecked")
273 public List
<UuidAndTitleCache
<TaxonBase
>> getTaxaByNameForEditor(boolean doTaxa
, boolean doSynonyms
, String queryString
, Classification classification
,
274 MatchMode matchMode
, Set
<NamedArea
> namedAreas
) {
278 boolean doCount
= false;
279 Query query
= prepareTaxaByNameForEditor(doTaxa
, doSynonyms
, "nameCache", queryString
, classification
, matchMode
, namedAreas
, doCount
);
283 List
<Object
[]> results
= query
.list();
285 List
<UuidAndTitleCache
<TaxonBase
>> resultObjects
= new ArrayList
<UuidAndTitleCache
<TaxonBase
>>();
287 for(int i
= 0; i
<results
.size();i
++){
288 result
= results
.get(i
);
290 //differentiate taxa and synonyms
291 if (doTaxa
&& doSynonyms
){
292 if (result
[2].equals("synonym")) {
293 resultObjects
.add( new UuidAndTitleCache(Synonym
.class, (UUID
) result
[0], (String
)result
[1], (Boolean
)result
[3]));
296 resultObjects
.add( new UuidAndTitleCache(Taxon
.class, (UUID
) result
[0], (String
)result
[1], (Boolean
)result
[3]));
299 resultObjects
.add( new UuidAndTitleCache(Taxon
.class, (UUID
) result
[0], (String
)result
[1], (Boolean
)result
[3]));
300 }else if (doSynonyms
){
301 resultObjects
.add( new UuidAndTitleCache(Synonym
.class, (UUID
) result
[0], (String
)result
[1], (Boolean
)result
[3]));
305 return resultObjects
;
308 return new ArrayList
<UuidAndTitleCache
<TaxonBase
>>();
314 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getTaxaByCommonName(java.lang.String, eu.etaxonomy.cdm.model.taxon.Classification, eu.etaxonomy.cdm.persistence.query.MatchMode, java.util.Set, java.lang.Integer, java.lang.Integer, java.util.List)
316 public List
<Object
[]> getTaxaByCommonName(String queryString
, Classification classification
,
317 MatchMode matchMode
, Set
<NamedArea
> namedAreas
, Integer pageSize
,
318 Integer pageNumber
, List
<String
> propertyPaths
) {
319 boolean doCount
= false;
320 Query query
= prepareTaxaByCommonName(queryString
, classification
, matchMode
, namedAreas
, pageSize
, pageNumber
, doCount
);
322 List
<Object
[]> results
= query
.list();
323 defaultBeanInitializer
.initializeAll(results
, propertyPaths
);
326 return new ArrayList
<Object
[]>();
332 * @param searchField the field in TaxonNameBase to be searched through usually either <code>nameCache</code> or <code>titleCache</code>
334 * @param classification TODO
344 private Query
prepareTaxaByNameForEditor(boolean doTaxa
, boolean doSynonyms
, String searchField
, String queryString
, Classification classification
,
345 MatchMode matchMode
, Set
<NamedArea
> namedAreas
, boolean doCount
) {
346 return prepareQuery(doTaxa
, doSynonyms
, false, searchField
, queryString
,
347 classification
, matchMode
, namedAreas
, doCount
, true);
353 * @param classification
357 * @param doNotReturnFullEntities
358 * if set true the seach method will not return synonym and taxon
359 * entities but an array containing the uuid, titleCache, and the
360 * DTYPE in lowercase letters.
364 private Query
prepareQuery(boolean doTaxa
, boolean doSynonyms
, boolean doIncludeMisappliedNames
, String searchField
, String queryString
,
365 Classification classification
, MatchMode matchMode
, Set
<NamedArea
> namedAreas
, boolean doCount
, boolean doNotReturnFullEntities
){
367 String hqlQueryString
= matchMode
.queryStringFrom(queryString
);
369 if (doNotReturnFullEntities
){
370 selectWhat
= "t.uuid, t.titleCache ";
372 selectWhat
= (doCount ?
"count(t)": "t");
376 Set
<NamedArea
> areasExpanded
= new HashSet
<NamedArea
>();
377 if(namedAreas
!= null && namedAreas
.size() > 0){
378 // expand areas and restrict by distribution area
379 Query areaQuery
= getSession().createQuery("select childArea from NamedArea as childArea left join childArea.partOf as parentArea where parentArea = :area");
380 expandNamedAreas(namedAreas
, areasExpanded
, areaQuery
);
382 boolean doAreaRestriction
= areasExpanded
.size() > 0;
384 Set
<UUID
> namedAreasUuids
= new HashSet
<UUID
>();
385 for (NamedArea area
:areasExpanded
){
386 namedAreasUuids
.add(area
.getUuid());
390 String
[] subSelects
= createHQLString(doTaxa
, doSynonyms
, doIncludeMisappliedNames
, classification
, areasExpanded
, matchMode
, searchField
);
391 String taxonSubselect
= subSelects
[1];
392 String synonymSubselect
= subSelects
[2];
393 String misappliedSelect
= subSelects
[0];
396 /*if(classification != null ){
397 if (!doIncludeMisappliedNames){
398 if(doAreaRestriction){
400 taxonSubselect = "select t.id from" +
402 " join e.inDescription d" +
405 " join t.taxonNodes as tn "+
407 " e.area.uuid in (:namedAreasUuids) AND" +
408 " tn.classification = :classification" +
409 " AND n." + searchField + " " + matchMode.getMatchOperator() + " :queryString";
413 synonymSubselect = "select s.id from" +
415 " join e.inDescription d" +
416 " join d.taxon t" + // the taxa
417 " join t.taxonNodes as tn "+
418 " join t.synonymRelations sr" +
419 " join sr.relatedFrom s" + // the synonyms
422 " e.area.uuid in (:namedAreasUuids) AND" +
423 " tn.classification = :classification" +
424 " AND sn." + searchField + " " + matchMode.getMatchOperator() + " :queryString";
428 taxonSubselect = "select t.id from" +
431 " join t.taxonNodes as tn "+
433 " tn.classification = :classification" +
434 " AND n." + searchField + " " + matchMode.getMatchOperator() + " :queryString";
436 synonymSubselect = "select s.id from" +
437 " Taxon t" + // the taxa
438 " join t.taxonNodes as tn "+
439 " join t.synonymRelations sr" +
440 " join sr.relatedFrom s" + // the synonyms
443 " tn.classification = :classification" +
444 " AND sn." + searchField + " " + matchMode.getMatchOperator() + " :queryString";
447 if(doAreaRestriction){
448 if (!doTaxa && !doSynonyms ){
449 misappliedSelect = "select t.id from" +
451 " join e.inDescription d" +
454 " join t.taxonNodes as tn "+
455 " left join t.relationsFromThisTaxon as rft" +
456 " left join rft.relatedTo as rt" +
457 " left join rt.taxonNodes as tn2" +
458 " left join rt.name as n2" +
459 " left join rft.type as rtype"+
461 " e.area.uuid in (:namedAreasUuids) AND" +
462 " (tn.classification != :classification" +
463 " AND n." + searchField + " " + matchMode.getMatchOperator() + " :queryString" +
464 " AND tn2.classification = :classification" +
465 " AND rtype = :rType )";
468 taxonSubselect = "select t.id from" +
470 " join e.inDescription d" +
473 " join t.taxonNodes as tn "+
474 " left join t.relationsFromThisTaxon as rft" +
475 " left join rft.relatedTo as rt" +
476 " left join rt.taxonNodes as tn2" +
477 " left join rt.name as n2" +
478 " left join rft.type as rtype"+
480 " e.area.uuid in (:namedAreasUuids) AND" +
481 " (tn.classification = :classification" +
482 " AND n." + searchField + " " + matchMode.getMatchOperator() + " :queryString )" +
484 " (tn.classification != :classification" +
485 " AND n." + searchField + " " + matchMode.getMatchOperator() + " :queryString" +
486 " AND tn2.classification = :classification" +
487 " AND rtype = :rType )";
490 synonymSubselect = "select s.id from" +
492 " join e.inDescription d" +
493 " join d.taxon t" + // the taxa
494 " join t.taxonNodes as tn "+
495 " join t.synonymRelations sr" +
496 " join sr.relatedFrom s" + // the synonyms
499 " e.area.uuid in (:namedAreasUuids) AND" +
500 " tn.classification != :classification" +
501 " AND sn." + searchField + " " + matchMode.getMatchOperator() + " :queryString";
504 if (!doTaxa && !doSynonyms ){
505 misappliedSelect = "select t.id from" +
507 " join e.inDescription d" +
510 " join t.taxonNodes as tn "+
511 " left join t.relationsFromThisTaxon as rft" +
512 " left join rft.relatedTo as rt" +
513 " left join rt.taxonNodes as tn2" +
514 " left join rt.name as n2" +
515 " left join rft.type as rtype"+
517 " (tn.classification != :classification" +
518 " AND n." + searchField + " " + matchMode.getMatchOperator() + " :queryString" +
519 " AND tn2.classification = :classification" +
520 " AND rtype = :rType )";
523 taxonSubselect = "select t.id from" +
526 " join t.taxonNodes as tn "+
527 " left join t.relationsFromThisTaxon as rft" +
528 " left join rft.relatedTo as rt" +
529 " left join rt.taxonNodes as tn2" +
530 " left join rt.name as n2" +
531 " left join rft.type as rtype"+
533 " (tn.classification = :classification" +
534 " AND n." + searchField + " " + matchMode.getMatchOperator() + " :queryString )" +
536 " (tn.classification != :classification" +
537 " AND n." + searchField + " " + matchMode.getMatchOperator() + " :queryString" +
538 " AND tn2.classification = :classification" +
539 " AND rtype = :rType )";
541 synonymSubselect = "select s.id from" +
542 " Taxon t" + // the taxa
543 " join t.taxonNodes as tn "+
544 " join t.synonymRelations sr" +
545 " join sr.relatedFrom s" + // the synonyms
548 " tn.classification != :classification" +
549 " AND sn." + searchField + " " + matchMode.getMatchOperator() + " :queryString";
555 if (!doIncludeMisappliedNames){
556 if(doAreaRestriction){
557 taxonSubselect = "select t.id from " +
559 " join e.inDescription d" +
563 (doAreaRestriction ? " e.area.uuid in (:namedAreasUuids) AND" : "") +
564 " n." + searchField + " " + matchMode.getMatchOperator() + " :queryString";
566 synonymSubselect = "select s.id from" +
568 " join e.inDescription d" +
569 " join d.taxon t" + // the taxa
570 " join t.synonymRelations sr" +
571 " join sr.relatedFrom s" + // the synonyms
574 (doAreaRestriction ? " e.area.uuid in (:namedAreasUuids) AND" : "") +
575 " sn." + searchField + " " + matchMode.getMatchOperator() + " :queryString";
579 taxonSubselect = "select t.id from " +
583 " n." + searchField + " " + matchMode.getMatchOperator() + " :queryString";
585 synonymSubselect = "select s.id from" +
586 " Taxon t" + // the taxa
587 " join t.synonymRelations sr" +
588 " join sr.relatedFrom s" + // the synonyms
591 " sn." + searchField + " " + matchMode.getMatchOperator() + " :queryString";
599 logger
.debug("taxonSubselect: " + taxonSubselect
!= null ? taxonSubselect
: "NULL");
600 logger
.debug("synonymSubselect: " + synonymSubselect
!= null ? synonymSubselect
: "NULL");
602 Query subTaxon
= null;
603 Query subSynonym
= null;
604 Query subMisappliedNames
= null;
607 subTaxon
= getSession().createQuery(taxonSubselect
).setParameter("queryString", hqlQueryString
);
609 if(doAreaRestriction
){
610 subTaxon
.setParameterList("namedAreasUuids", namedAreasUuids
);
612 if(classification
!= null){
613 subTaxon
.setParameter("classification", classification
);
622 subSynonym
= getSession().createQuery(synonymSubselect
).setParameter("queryString", hqlQueryString
);
624 if(doAreaRestriction
){
625 subSynonym
.setParameterList("namedAreasUuids", namedAreasUuids
);
627 if(classification
!= null){
628 subSynonym
.setParameter("classification", classification
);
631 if (doIncludeMisappliedNames
){
632 subMisappliedNames
= getSession().createQuery(misappliedSelect
).setParameter("queryString", hqlQueryString
);
633 subMisappliedNames
.setParameter("rType", TaxonRelationshipType
.MISAPPLIED_NAME_FOR());
634 if(doAreaRestriction
){
635 subMisappliedNames
.setParameterList("namedAreasUuids", namedAreasUuids
);
637 if(classification
!= null){
638 subMisappliedNames
.setParameter("classification", classification
);
642 List
<Integer
> taxa
= new ArrayList
<Integer
>();
643 List
<Integer
> synonyms
= new ArrayList
<Integer
>();
645 synonyms
= subSynonym
.list();
648 taxa
= subTaxon
.list();
650 if (doIncludeMisappliedNames
){
651 taxa
.addAll(subMisappliedNames
.list());
654 if (doTaxa
&& doSynonyms
){
655 if(synonyms
.size()>0 && taxa
.size()>0){
656 hql
= "select " + selectWhat
;
657 // in doNotReturnFullEntities mode it is nesscary to also return the type of the matching entities:
658 // also return the computed isOrphaned flag
659 if (doNotReturnFullEntities
&& !doCount
){
660 hql
+= ", case when t.id in (:taxa) then 'taxon' else 'synonym' end, " +
661 " case when t.id in (:taxa) and t.taxonNodes is empty and t.relationsFromThisTaxon is empty and t.relationsToThisTaxon is empty then true else false end ";
663 hql
+= " from %s t " +
664 " where (t.id in (:taxa) OR t.id in (:synonyms)) ";
665 }else if (synonyms
.size()>0 ){
666 hql
= "select " + selectWhat
;
667 // in doNotReturnFullEntities mode it is nesscary to also return the type of the matching entities:
668 // also return the computed isOrphaned flag
669 if (doNotReturnFullEntities
&& !doCount
){
670 hql
+= ", 'synonym', " +
673 hql
+= " from %s t " +
674 " where t.id in (:synonyms) ";
676 } else if (taxa
.size()>0 ){
677 hql
= "select " + selectWhat
;
678 // in doNotReturnFullEntities mode it is nesscary to also return the type of the matching entities:
679 // also return the computed isOrphaned flag
680 if (doNotReturnFullEntities
&& !doCount
){
681 hql
+= ", 'taxon', " +
682 " case when t.taxonNodes is empty and t.relationsFromThisTaxon is empty and t.relationsToThisTaxon is empty then true else false end ";
684 hql
+= " from %s t " +
685 " where t.id in (:taxa) ";
688 hql
= "select " + selectWhat
+ " from %s t";
692 hql
= "select " + selectWhat
;
693 // in doNotReturnFullEntities mode it is nesscary to also return the type of the matching entities:
694 // also return the computed isOrphaned flag
695 if (doNotReturnFullEntities
){
696 hql
+= ", 'taxon', " +
697 " case when t.taxonNodes is empty and t.relationsFromThisTaxon is empty and t.relationsToThisTaxon is empty then true else false end ";
699 hql
+= " from %s t " +
700 " where t.id in (:taxa) ";
703 hql
= "select " + selectWhat
+ " from %s t";
705 } else if(doSynonyms
){
706 if (synonyms
.size()>0){
708 hql
= "select " + selectWhat
;
709 // in doNotReturnFullEntities mode it is nesscary to also return the type of the matching entities:
710 // also return the computed isOrphaned flag
711 if (doNotReturnFullEntities
){
712 hql
+= ", 'synonym', " +
715 hql
+= " from %s t " +
716 " where t.id in (:synonyms) ";
718 hql
= "select " + selectWhat
+ " from %s t";
720 } else if (doIncludeMisappliedNames
){
721 hql
= "select " + selectWhat
;
722 // in doNotReturnFullEntities mode it is nesscary to also return the type of the matching entities:
723 // also return the computed isOrphaned flag
724 if (doNotReturnFullEntities
){
725 hql
+= ", 'taxon', " +
726 " case when t.taxonNodes is empty and t.relationsFromThisTaxon is empty and t.relationsToThisTaxon is empty then true else false end ";
728 hql
+= " from %s t " +
729 " where t.id in (:taxa) ";
734 if (doTaxa
&& doSynonyms
){
735 classString
= "TaxonBase";
737 classString
= "Taxon";
738 } else if (doSynonyms
){
739 classString
= "Synonym";
740 } else{//only misappliedNames
741 classString
= "Taxon";
744 hql
= String
.format(hql
, classString
);
747 if (hql
== "") return null;
749 hql
+= " order by t.name.genusOrUninomial, case when t.name.specificEpithet like '\"%\"' then 1 else 0 end, t.name.specificEpithet, t.name.rank desc, t.name.nameCache";
752 logger
.debug("hql: " + hql
);
753 Query query
= getSession().createQuery(hql
);
756 if (doTaxa
&& doSynonyms
){
757 // find taxa and synonyms
759 query
.setParameterList("taxa", taxa
);
761 if (synonyms
.size()>0){
762 query
.setParameterList("synonyms",synonyms
);
764 if (taxa
.size()== 0 && synonyms
.size() == 0){
770 query
.setParameterList("taxa", taxa
);
774 } else if(doSynonyms
){
776 if (synonyms
.size()>0){
777 query
.setParameterList("synonyms", synonyms
);
782 //only misappliedNames
784 query
.setParameterList("taxa", taxa
);
798 * @param searchField the field in TaxonNameBase to be searched through usually either <code>nameCache</code> or <code>titleCache</code>
800 * @param classification TODO
809 * FIXME implement classification restriction & implement test: see {@link TaxonDaoHibernateImplTest#testCountTaxaByName()}
811 private Query
prepareTaxaByName(boolean doTaxa
, boolean doSynonyms
, boolean doMisappliedNames
, String searchField
, String queryString
,
812 Classification classification
, MatchMode matchMode
, Set
<NamedArea
> namedAreas
, Integer pageSize
, Integer pageNumber
, boolean doCount
) {
814 Query query
= prepareQuery(doTaxa
, doSynonyms
, doMisappliedNames
, searchField
, queryString
, classification
, matchMode
, namedAreas
, doCount
, false);
816 if(pageSize
!= null && !doCount
) {
817 query
.setMaxResults(pageSize
);
818 if(pageNumber
!= null) {
819 query
.setFirstResult(pageNumber
* pageSize
);
826 private Query
prepareTaxaByCommonName(String queryString
, Classification classification
,
827 MatchMode matchMode
, Set
<NamedArea
> namedAreas
, Integer pageSize
, Integer pageNumber
, boolean doCount
){
829 String hql
= "from Taxon t " +
830 "join t.descriptions d "+
831 "join d.descriptionElements e " +
832 "join e.feature f " +
833 "where f.supportsCommonTaxonName = true and e.name "+matchMode
.getMatchOperator()+" :queryString";//and ls.text like 'common%'";
835 Query query
= getSession().createQuery(hql
);
837 query
.setParameter("queryString", queryString
);
839 if(pageSize
!= null && !doCount
) {
840 query
.setMaxResults(pageSize
);
841 if(pageNumber
!= null) {
842 query
.setFirstResult(pageNumber
* pageSize
);
849 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#countTaxaByName(java.lang.String, eu.etaxonomy.cdm.persistence.query.MatchMode, eu.etaxonomy.cdm.persistence.query.SelectMode, eu.etaxonomy.cdm.model.reference.Reference, java.util.Set)
851 public long countTaxaByName(boolean doTaxa
, boolean doSynonyms
, boolean doMisappliedNames
, String queryString
, Classification classification
,
852 MatchMode matchMode
, Set
<NamedArea
> namedAreas
) {
854 boolean doCount
= true;
856 boolean doTaxa = true;
857 boolean doSynonyms = true;
858 if (clazz.equals(Taxon.class)){
860 } else if (clazz.equals(Synonym.class)){
866 Query query
= prepareTaxaByName(doTaxa
, doSynonyms
, doMisappliedNames
, "nameCache", queryString
, classification
, matchMode
, namedAreas
, null, null, doCount
);
868 return (Long
)query
.uniqueResult();
876 * @param areasExpanded
879 private void expandNamedAreas(Collection
<NamedArea
> namedAreas
, Set
<NamedArea
> areasExpanded
, Query areaQuery
) {
880 List
<NamedArea
> childAreas
;
881 for(NamedArea a
: namedAreas
){
882 areasExpanded
.add(a
);
883 areaQuery
.setParameter("area", a
);
884 childAreas
= areaQuery
.list();
885 if(childAreas
.size() > 0){
886 areasExpanded
.addAll(childAreas
);
887 expandNamedAreas(childAreas
, areasExpanded
, areaQuery
);
893 // * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#countTaxaByName(java.lang.String, eu.etaxonomy.cdm.persistence.query.MatchMode, eu.etaxonomy.cdm.persistence.query.SelectMode)
895 // public Integer countTaxaByName(String queryString, MatchMode matchMode, SelectMode selectMode) {
896 // return countTaxaByName(queryString, matchMode, selectMode, null);
900 // * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#countTaxaByName(java.lang.String, eu.etaxonomy.cdm.persistence.query.MatchMode, eu.etaxonomy.cdm.persistence.query.SelectMode, eu.etaxonomy.cdm.model.reference.Reference)
902 // public Integer countTaxaByName(String queryString,
903 // MatchMode matchMode, SelectMode selectMode, Reference sec) {
905 // Long count = countTaxaByName(queryString, matchMode, selectMode, sec, null);
906 // return count.intValue();
910 // public Integer countTaxaByName(String queryString, MatchMode matchMode, Boolean accepted) {
912 // SelectMode selectMode = (accepted ? SelectMode.TAXA : SelectMode.SYNONYMS);
913 // Long count = countTaxaByName(queryString, matchMode, selectMode, null, null);
914 // return count.intValue();
917 public List
<TaxonBase
> getAllTaxonBases(Integer pagesize
, Integer page
) {
918 return super.list(pagesize
, page
);
923 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getAllSynonyms(java.lang.Integer, java.lang.Integer)
925 public List
<Synonym
> getAllSynonyms(Integer limit
, Integer start
) {
926 Criteria criteria
= getSession().createCriteria(Synonym
.class);
929 criteria
.setFirstResult(start
);
930 criteria
.setMaxResults(limit
);
933 return criteria
.list();
938 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getAllTaxa(java.lang.Integer, java.lang.Integer)
940 public List
<Taxon
> getAllTaxa(Integer limit
, Integer start
) {
941 Criteria criteria
= getSession().createCriteria(Taxon
.class);
944 criteria
.setFirstResult(start
);
945 criteria
.setMaxResults(limit
);
948 return criteria
.list();
953 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getAllRelationships(java.lang.Integer, java.lang.Integer)
956 public List
<RelationshipBase
> getAllRelationships(/*Class<? extends RelationshipBase> clazz,*/ Integer limit
, Integer start
) {
957 Class
<?
extends RelationshipBase
> clazz
= RelationshipBase
.class; //preliminary, see #2653
958 AuditEvent auditEvent
= getAuditEventFromContext();
959 if(auditEvent
.equals(AuditEvent
.CURRENT_VIEW
)) {
960 // for some reason the HQL .class discriminator didn't work here so I created this preliminary
961 // implementation for now. Should be cleaned in future.
963 List
<RelationshipBase
> result
= new ArrayList
<RelationshipBase
>();
965 int taxRelSize
= countAllRelationships(TaxonRelationship
.class);
967 if (taxRelSize
> start
){
969 String hql
= " FROM TaxonRelationship as rb ORDER BY rb.id ";
970 Query query
= getSession().createQuery(hql
);
971 query
.setFirstResult(start
);
973 query
.setMaxResults(limit
);
975 result
= query
.list();
977 limit
= limit
- result
.size();
979 String hql
= " FROM SynonymRelationship as rb ORDER BY rb.id ";
980 Query query
= getSession().createQuery(hql
);
981 start
= (taxRelSize
> start
) ?
0 : (start
- taxRelSize
);
982 query
.setFirstResult(start
);
984 query
.setMaxResults(limit
);
986 result
.addAll(query
.list());
991 AuditQuery query
= getAuditReader().createQuery().forEntitiesAtRevision(clazz
,auditEvent
.getRevisionNumber());
992 return (List
<RelationshipBase
>)query
.getResultList();
996 /** Sets the taxonomic parent to null. Does not handle taxonomic relationships. */
997 // private boolean nullifyTaxonomicParent(Taxon taxon) {
1000 // Method nullifyTaxonomicParent = taxon.getClass().getMethod("nullifyTaxonomicParent");
1001 // nullifyTaxonomicParent.invoke(taxon);
1002 // } catch (NoSuchMethodException ex) {
1003 // logger.error("NoSuchMethod: " + ex.getMessage());
1005 // } catch (IllegalArgumentException ex) {
1006 // logger.error("IllegalArgumentException: " + ex.getMessage());
1008 // } catch (IllegalAccessException ex) {
1009 // logger.error("IllegalAccessException: " + ex.getMessage());
1011 // } catch (InvocationTargetException ex) {
1012 // logger.error("IllegalAccessException: " + ex.getMessage());
1019 public UUID
delete(TaxonBase taxonBase
) throws DataAccessException
{
1020 if (taxonBase
== null){
1021 logger
.warn("TaxonBase was 'null'");
1025 // Merge the object in if it is detached
1027 // I think this is preferable to catching lazy initialization errors
1028 // as that solution only swallows and hides the exception, but doesn't
1029 // actually solve it.
1030 getSession().merge(taxonBase
);
1032 if (taxonBase
instanceof Taxon
){ // is Taxon
1033 for (Iterator
<TaxonRelationship
> iterator
= ((Taxon
)taxonBase
).getRelationsFromThisTaxon().iterator(); iterator
.hasNext();){
1034 TaxonRelationship relationFromThisTaxon
= iterator
.next();
1036 // decrease children count of taxonomic parent by one
1037 if (relationFromThisTaxon
.getType().equals(TaxonRelationshipType
.TAXONOMICALLY_INCLUDED_IN())) {
1038 Taxon toTaxon
= relationFromThisTaxon
.getToTaxon(); // parent
1039 if (toTaxon
!= null) {
1040 toTaxon
.setTaxonomicChildrenCount(toTaxon
.getTaxonomicChildrenCount() - 1);
1046 return super.delete(taxonBase
);
1051 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#findByName(java.lang.String, eu.etaxonomy.cdm.persistence.query.MatchMode, int, int, boolean)
1053 public List
<TaxonBase
> findByNameTitleCache(boolean doTaxa
, boolean doSynonyms
, String queryString
, Classification classification
, MatchMode matchMode
, Set
<NamedArea
> namedAreas
, Integer pageNumber
, Integer pageSize
, List
<String
> propertyPaths
) {
1055 boolean doCount
= false;
1056 Query query
= prepareTaxaByName(doTaxa
, doSynonyms
, false, "titleCache", queryString
, classification
, matchMode
, namedAreas
, pageSize
, pageNumber
, doCount
);
1058 List
<TaxonBase
> results
= query
.list();
1059 defaultBeanInitializer
.initializeAll(results
, propertyPaths
);
1062 return new ArrayList
<TaxonBase
>();
1067 < * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#findByUuid(java.util.UUID, java.util.List<org.hibernate.criterion.Criterion>, java.util.List<java.lang.String>)
1069 public TaxonBase
findByUuid(UUID uuid
, List
<Criterion
> criteria
, List
<String
> propertyPaths
) {
1071 Criteria crit
= getSession().createCriteria(type
);
1074 crit
.add(Restrictions
.eq("uuid", uuid
));
1076 logger
.warn("UUID is NULL");
1079 if(criteria
!= null){
1080 for (Criterion criterion
: criteria
) {
1081 crit
.add(criterion
);
1084 crit
.addOrder(Order
.asc("uuid"));
1086 List
<?
extends TaxonBase
> results
= crit
.list();
1087 if (results
.size() == 1) {
1088 defaultBeanInitializer
.initializeAll(results
, propertyPaths
);
1089 TaxonBase taxon
= results
.iterator().next();
1091 } else if (results
.size() > 1) {
1092 logger
.error("Multiple results for UUID: " + uuid
);
1093 } else if (results
.size() == 0) {
1094 logger
.info("No results for UUID: " + uuid
);
1100 public List
<?
extends TaxonBase
> findByUuids(List
<UUID
> uuids
, List
<Criterion
> criteria
, List
<String
> propertyPaths
) {
1102 Criteria crit
= getSession().createCriteria(type
);
1104 if (uuids
!= null) {
1105 crit
.add(Restrictions
.in("uuid", uuids
));
1107 logger
.warn("List<UUID> uuids is NULL");
1110 if(criteria
!= null){
1111 for (Criterion criterion
: criteria
) {
1112 crit
.add(criterion
);
1115 crit
.addOrder(Order
.asc("uuid"));
1117 List
<?
extends TaxonBase
> results
= crit
.list();
1119 defaultBeanInitializer
.initializeAll(results
, propertyPaths
);
1125 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#countMatchesByName(java.lang.String, eu.etaxonomy.cdm.persistence.query.MatchMode, boolean)
1127 public int countMatchesByName(String queryString
, MatchMode matchMode
, boolean onlyAcccepted
) {
1128 checkNotInPriorView("TaxonDaoHibernateImpl.countMatchesByName(String queryString, ITitledDao.MATCH_MODE matchMode, boolean onlyAcccepted)");
1129 Criteria crit
= getSession().createCriteria(type
);
1130 crit
.add(Restrictions
.ilike("titleCache", matchMode
.queryStringFrom(queryString
)));
1131 crit
.setProjection(Projections
.rowCount());
1132 int result
= ((Number
)crit
.list().get(0)).intValue();
1138 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#countMatchesByName(java.lang.String, eu.etaxonomy.cdm.persistence.query.MatchMode, boolean, java.util.List)
1140 public int countMatchesByName(String queryString
, MatchMode matchMode
, boolean onlyAcccepted
, List
<Criterion
> criteria
) {
1141 checkNotInPriorView("TaxonDaoHibernateImpl.countMatchesByName(String queryString, ITitledDao.MATCH_MODE matchMode, boolean onlyAcccepted, List<Criterion> criteria)");
1142 Criteria crit
= getSession().createCriteria(type
);
1143 crit
.add(Restrictions
.ilike("titleCache", matchMode
.queryStringFrom(queryString
)));
1144 if(criteria
!= null){
1145 for (Criterion criterion
: criteria
) {
1146 crit
.add(criterion
);
1149 crit
.setProjection(Projections
.rowCount());
1150 int result
= ((Number
)crit
.list().get(0)).intValue();
1156 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#countTaxonRelationships(eu.etaxonomy.cdm.model.taxon.Taxon, eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType, eu.etaxonomy.cdm.model.common.RelationshipBase.Direction)
1158 public int countTaxonRelationships(Taxon taxon
, TaxonRelationshipType type
, Direction direction
) {
1159 AuditEvent auditEvent
= getAuditEventFromContext();
1160 if(auditEvent
.equals(AuditEvent
.CURRENT_VIEW
)) {
1164 query
= getSession().createQuery("select count(taxonRelationship) from TaxonRelationship taxonRelationship where taxonRelationship."+direction
+" = :relatedTaxon");
1166 query
= getSession().createQuery("select count(taxonRelationship) from TaxonRelationship taxonRelationship where taxonRelationship."+direction
+" = :relatedTaxon and taxonRelationship.type = :type");
1167 query
.setParameter("type",type
);
1169 query
.setParameter("relatedTaxon", taxon
);
1171 return ((Long
)query
.uniqueResult()).intValue();
1173 AuditQuery query
= getAuditReader().createQuery().forEntitiesAtRevision(TaxonRelationship
.class,auditEvent
.getRevisionNumber());
1174 query
.add(AuditEntity
.relatedId(direction
.toString()).eq(taxon
.getId()));
1175 query
.addProjection(AuditEntity
.id().count("id"));
1178 query
.add(AuditEntity
.relatedId("type").eq(type
.getId()));
1181 return ((Long
)query
.getSingleResult()).intValue();
1187 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#countSynonyms(eu.etaxonomy.cdm.model.taxon.Taxon, eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType)
1189 public int countSynonyms(Taxon taxon
, SynonymRelationshipType type
) {
1190 AuditEvent auditEvent
= getAuditEventFromContext();
1191 if(auditEvent
.equals(AuditEvent
.CURRENT_VIEW
)) {
1192 Criteria criteria
= getSession().createCriteria(SynonymRelationship
.class);
1194 criteria
.add(Restrictions
.eq("relatedTo", taxon
));
1196 criteria
.add(Restrictions
.eq("type", type
));
1198 criteria
.setProjection(Projections
.rowCount());
1199 return ((Number
)criteria
.uniqueResult()).intValue();
1201 AuditQuery query
= getAuditReader().createQuery().forEntitiesAtRevision(SynonymRelationship
.class,auditEvent
.getRevisionNumber());
1202 query
.add(AuditEntity
.relatedId("relatedTo").eq(taxon
.getId()));
1203 query
.addProjection(AuditEntity
.id().count("id"));
1206 query
.add(AuditEntity
.relatedId("type").eq(type
.getId()));
1209 return ((Long
)query
.getSingleResult()).intValue();
1215 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#countSynonyms(eu.etaxonomy.cdm.model.taxon.Synonym, eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType)
1217 public int countSynonyms(Synonym synonym
, SynonymRelationshipType type
) {
1218 AuditEvent auditEvent
= getAuditEventFromContext();
1219 if(auditEvent
.equals(AuditEvent
.CURRENT_VIEW
)) {
1220 Criteria criteria
= getSession().createCriteria(SynonymRelationship
.class);
1222 criteria
.add(Restrictions
.eq("relatedFrom", synonym
));
1224 criteria
.add(Restrictions
.eq("type", type
));
1227 criteria
.setProjection(Projections
.rowCount());
1228 return ((Number
)criteria
.uniqueResult()).intValue();
1230 AuditQuery query
= getAuditReader().createQuery().forEntitiesAtRevision(SynonymRelationship
.class,auditEvent
.getRevisionNumber());
1231 query
.add(AuditEntity
.relatedId("relatedFrom").eq(synonym
.getId()));
1232 query
.addProjection(AuditEntity
.id().count("id"));
1235 query
.add(AuditEntity
.relatedId("type").eq(type
.getId()));
1238 return ((Long
)query
.getSingleResult()).intValue();
1244 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#countTaxaByName(java.lang.Class, java.lang.String, java.lang.String, java.lang.String, java.lang.String, eu.etaxonomy.cdm.model.name.Rank)
1246 public int countTaxaByName(Class
<?
extends TaxonBase
> clazz
, String genusOrUninomial
, String infraGenericEpithet
, String specificEpithet
, String infraSpecificEpithet
, Rank rank
) {
1247 checkNotInPriorView("TaxonDaoHibernateImpl.countTaxaByName(Boolean accepted, String genusOrUninomial, String infraGenericEpithet, String specificEpithet, String infraSpecificEpithet, Rank rank)");
1248 Criteria criteria
= null;
1250 criteria
= getSession().createCriteria(clazz
);
1252 criteria
.setFetchMode( "name", FetchMode
.JOIN
);
1253 criteria
.createAlias("name", "name");
1255 if(genusOrUninomial
== null) {
1256 criteria
.add(Restrictions
.isNull("name.genusOrUninomial"));
1257 } else if(!genusOrUninomial
.equals("*")) {
1258 criteria
.add(Restrictions
.eq("name.genusOrUninomial", genusOrUninomial
));
1261 if(infraGenericEpithet
== null) {
1262 criteria
.add(Restrictions
.isNull("name.infraGenericEpithet"));
1263 } else if(!infraGenericEpithet
.equals("*")) {
1264 criteria
.add(Restrictions
.eq("name.infraGenericEpithet", infraGenericEpithet
));
1267 if(specificEpithet
== null) {
1268 criteria
.add(Restrictions
.isNull("name.specificEpithet"));
1269 } else if(!specificEpithet
.equals("*")) {
1270 criteria
.add(Restrictions
.eq("name.specificEpithet", specificEpithet
));
1274 if(infraSpecificEpithet
== null) {
1275 criteria
.add(Restrictions
.isNull("name.infraSpecificEpithet"));
1276 } else if(!infraSpecificEpithet
.equals("*")) {
1277 criteria
.add(Restrictions
.eq("name.infraSpecificEpithet", infraSpecificEpithet
));
1281 criteria
.add(Restrictions
.eq("name.rank", rank
));
1284 criteria
.setProjection(Projections
.projectionList().add(Projections
.rowCount()));
1286 return ((Number
)criteria
.uniqueResult()).intValue();
1291 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#findTaxaByName(java.lang.Class, java.lang.String, java.lang.String, java.lang.String, java.lang.String, eu.etaxonomy.cdm.model.name.Rank, java.lang.Integer, java.lang.Integer)
1293 public List
<TaxonBase
> findTaxaByName(Class
<?
extends TaxonBase
> clazz
, String genusOrUninomial
, String infraGenericEpithet
, String specificEpithet
, String infraSpecificEpithet
, Rank rank
, Integer pageSize
, Integer pageNumber
) {
1294 checkNotInPriorView("TaxonDaoHibernateImpl.findTaxaByName(Boolean accepted, String genusOrUninomial, String infraGenericEpithet, String specificEpithet, String infraSpecificEpithet, Rank rank, Integer pageSize, Integer pageNumber)");
1295 Criteria criteria
= null;
1297 criteria
= getSession().createCriteria(TaxonBase
.class);
1299 criteria
= getSession().createCriteria(clazz
);
1301 criteria
.setFetchMode( "name", FetchMode
.JOIN
);
1302 criteria
.createAlias("name", "name");
1304 if(genusOrUninomial
== null) {
1305 criteria
.add(Restrictions
.isNull("name.genusOrUninomial"));
1306 } else if(!genusOrUninomial
.equals("*")) {
1307 criteria
.add(Restrictions
.eq("name.genusOrUninomial", genusOrUninomial
));
1310 if(infraGenericEpithet
== null) {
1311 criteria
.add(Restrictions
.isNull("name.infraGenericEpithet"));
1312 } else if(!infraGenericEpithet
.equals("*")) {
1313 criteria
.add(Restrictions
.eq("name.infraGenericEpithet", infraGenericEpithet
));
1316 if(specificEpithet
== null) {
1317 criteria
.add(Restrictions
.isNull("name.specificEpithet"));
1318 } else if(!specificEpithet
.equals("*")) {
1319 criteria
.add(Restrictions
.eq("name.specificEpithet", specificEpithet
));
1323 if(infraSpecificEpithet
== null) {
1324 criteria
.add(Restrictions
.isNull("name.infraSpecificEpithet"));
1325 } else if(!infraSpecificEpithet
.equals("*")) {
1326 criteria
.add(Restrictions
.eq("name.infraSpecificEpithet", infraSpecificEpithet
));
1330 criteria
.add(Restrictions
.eq("name.rank", rank
));
1333 if(pageSize
!= null) {
1334 criteria
.setMaxResults(pageSize
);
1335 if(pageNumber
!= null) {
1336 criteria
.setFirstResult(pageNumber
* pageSize
);
1338 criteria
.setFirstResult(0);
1342 return (List
<TaxonBase
>)criteria
.list();
1347 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getTaxonRelationships(eu.etaxonomy.cdm.model.taxon.Taxon, eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType, java.lang.Integer, java.lang.Integer, java.util.List, java.util.List, eu.etaxonomy.cdm.model.common.RelationshipBase.Direction)
1349 public List
<TaxonRelationship
> getTaxonRelationships(Taxon taxon
, TaxonRelationshipType type
,
1350 Integer pageSize
, Integer pageNumber
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
, Direction direction
) {
1352 AuditEvent auditEvent
= getAuditEventFromContext();
1353 if(auditEvent
.equals(AuditEvent
.CURRENT_VIEW
)) {
1355 Criteria criteria
= getSession().createCriteria(TaxonRelationship
.class);
1357 if(direction
!= null) {
1358 criteria
.add(Restrictions
.eq(direction
.name(), taxon
));
1360 criteria
.add(Restrictions
.or(
1361 Restrictions
.eq(Direction
.relatedFrom
.name(), taxon
),
1362 Restrictions
.eq(Direction
.relatedTo
.name(), taxon
))
1367 criteria
.add(Restrictions
.eq("type", type
));
1370 addOrder(criteria
,orderHints
);
1372 if(pageSize
!= null) {
1373 criteria
.setMaxResults(pageSize
);
1374 if(pageNumber
!= null) {
1375 criteria
.setFirstResult(pageNumber
* pageSize
);
1377 criteria
.setFirstResult(0);
1381 List
<TaxonRelationship
> result
= (List
<TaxonRelationship
>)criteria
.list();
1382 defaultBeanInitializer
.initializeAll(result
, propertyPaths
);
1386 AuditQuery query
= getAuditReader().createQuery().forEntitiesAtRevision(TaxonRelationship
.class,auditEvent
.getRevisionNumber());
1387 query
.add(AuditEntity
.relatedId("relatedTo").eq(taxon
.getId()));
1390 query
.add(AuditEntity
.relatedId("type").eq(type
.getId()));
1393 if(pageSize
!= null) {
1394 query
.setMaxResults(pageSize
);
1395 if(pageNumber
!= null) {
1396 query
.setFirstResult(pageNumber
* pageSize
);
1398 query
.setFirstResult(0);
1402 List
<TaxonRelationship
> result
= (List
<TaxonRelationship
>)query
.getResultList();
1403 defaultBeanInitializer
.initializeAll(result
, propertyPaths
);
1405 // Ugly, but for now, there is no way to sort on a related entity property in Envers,
1406 // and we can't live without this functionality in CATE as it screws up the whole
1408 if(orderHints
!= null && !orderHints
.isEmpty()) {
1409 SortedSet
<TaxonRelationship
> sortedList
= new TreeSet
<TaxonRelationship
>(new TaxonRelationshipFromTaxonComparator());
1410 sortedList
.addAll(result
);
1411 return new ArrayList
<TaxonRelationship
>(sortedList
);
1418 class TaxonRelationshipFromTaxonComparator
implements Comparator
<TaxonRelationship
> {
1420 public int compare(TaxonRelationship o1
, TaxonRelationship o2
) {
1421 return o1
.getFromTaxon().getTitleCache().compareTo(o2
.getFromTaxon().getTitleCache());
1426 class SynonymRelationshipFromTaxonComparator
implements Comparator
<SynonymRelationship
> {
1428 public int compare(SynonymRelationship o1
, SynonymRelationship o2
) {
1429 return o1
.getSynonym().getTitleCache().compareTo(o2
.getSynonym().getTitleCache());
1436 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getSynonyms(eu.etaxonomy.cdm.model.taxon.Taxon, eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType, java.lang.Integer, java.lang.Integer, java.util.List, java.util.List)
1438 public List
<SynonymRelationship
> getSynonyms(Taxon taxon
, SynonymRelationshipType type
, Integer pageSize
, Integer pageNumber
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
1439 AuditEvent auditEvent
= getAuditEventFromContext();
1440 if(auditEvent
.equals(AuditEvent
.CURRENT_VIEW
)) {
1441 Criteria criteria
= getSession().createCriteria(SynonymRelationship
.class);
1443 criteria
.add(Restrictions
.eq("relatedTo", taxon
));
1445 criteria
.add(Restrictions
.eq("type", type
));
1448 addOrder(criteria
,orderHints
);
1450 if(pageSize
!= null) {
1451 criteria
.setMaxResults(pageSize
);
1452 if(pageNumber
!= null) {
1453 criteria
.setFirstResult(pageNumber
* pageSize
);
1455 criteria
.setFirstResult(0);
1459 List
<SynonymRelationship
> result
= (List
<SynonymRelationship
>)criteria
.list();
1460 defaultBeanInitializer
.initializeAll(result
, propertyPaths
);
1464 AuditQuery query
= getAuditReader().createQuery().forEntitiesAtRevision(SynonymRelationship
.class,auditEvent
.getRevisionNumber());
1465 query
.add(AuditEntity
.relatedId("relatedTo").eq(taxon
.getId()));
1468 query
.add(AuditEntity
.relatedId("type").eq(type
.getId()));
1471 if(pageSize
!= null) {
1472 query
.setMaxResults(pageSize
);
1473 if(pageNumber
!= null) {
1474 query
.setFirstResult(pageNumber
* pageSize
);
1476 query
.setFirstResult(0);
1480 List
<SynonymRelationship
> result
= (List
<SynonymRelationship
>)query
.getResultList();
1481 defaultBeanInitializer
.initializeAll(result
, propertyPaths
);
1489 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getSynonyms(eu.etaxonomy.cdm.model.taxon.Synonym, eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType, java.lang.Integer, java.lang.Integer, java.util.List, java.util.List)
1491 public List
<SynonymRelationship
> getSynonyms(Synonym synonym
, SynonymRelationshipType type
, Integer pageSize
, Integer pageNumber
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
1492 AuditEvent auditEvent
= getAuditEventFromContext();
1493 if(auditEvent
.equals(AuditEvent
.CURRENT_VIEW
)) {
1494 Criteria criteria
= getSession().createCriteria(SynonymRelationship
.class);
1496 criteria
.add(Restrictions
.eq("relatedFrom", synonym
));
1498 criteria
.add(Restrictions
.eq("type", type
));
1501 addOrder(criteria
,orderHints
);
1503 if(pageSize
!= null) {
1504 criteria
.setMaxResults(pageSize
);
1505 if(pageNumber
!= null) {
1506 criteria
.setFirstResult(pageNumber
* pageSize
);
1508 criteria
.setFirstResult(0);
1512 List
<SynonymRelationship
> result
= (List
<SynonymRelationship
>)criteria
.list();
1513 defaultBeanInitializer
.initializeAll(result
, propertyPaths
);
1517 AuditQuery query
= getAuditReader().createQuery().forEntitiesAtRevision(SynonymRelationship
.class,auditEvent
.getRevisionNumber());
1518 query
.add(AuditEntity
.relatedId("relatedFrom").eq(synonym
.getId()));
1521 query
.add(AuditEntity
.relatedId("type").eq(type
.getId()));
1524 if(pageSize
!= null) {
1525 query
.setMaxResults(pageSize
);
1526 if(pageNumber
!= null) {
1527 query
.setFirstResult(pageNumber
* pageSize
);
1529 query
.setFirstResult(0);
1533 List
<SynonymRelationship
> result
= (List
<SynonymRelationship
>)query
.getResultList();
1534 defaultBeanInitializer
.initializeAll(result
, propertyPaths
);
1541 public void rebuildIndex() {
1542 FullTextSession fullTextSession
= Search
.getFullTextSession(getSession());
1544 for(TaxonBase taxonBase
: list(null,null)) { // re-index all taxon base
1545 Hibernate
.initialize(taxonBase
.getName());
1546 fullTextSession
.index(taxonBase
);
1548 fullTextSession
.flushToIndexes();
1552 public String
suggestQuery(String queryString
) {
1553 checkNotInPriorView("TaxonDaoHibernateImpl.suggestQuery(String queryString)");
1554 String alternativeQueryString
= null;
1555 if (alternativeSpellingSuggestionParser
!= null) {
1558 alternativeSpellingSuggestionParser
.parse(queryString
);
1559 org
.apache
.lucene
.search
.Query alternativeQuery
= alternativeSpellingSuggestionParser
.suggest(queryString
);
1560 if (alternativeQuery
!= null) {
1561 alternativeQueryString
= alternativeQuery
1562 .toString("name.titleCache");
1565 } catch (ParseException e
) {
1566 throw new QueryParseException(e
, queryString
);
1569 return alternativeQueryString
;
1574 * @see eu.etaxonomy.cdm.api.service.ITaxonService#getUuidAndTitleCacheOfAcceptedTaxa(eu.etaxonomy.cdm.model.taxon.Classification)
1576 public List
<UuidAndTitleCache
<TaxonNode
>> getTaxonNodeUuidAndTitleCacheOfAcceptedTaxaByClassification(Classification classification
) {
1578 int classificationId
= classification
.getId();
1580 String queryString
= "SELECT nodes.uuid, taxa.titleCache FROM TaxonNode AS nodes LEFT JOIN TaxonBase AS taxa ON nodes.taxon_id = taxa.id WHERE taxa.DTYPE = 'Taxon' AND nodes.classification_id = " + classificationId
;
1582 List
<Object
[]> result
= getSession().createSQLQuery(queryString
).list();
1584 if(result
.size() == 0){
1587 List
<UuidAndTitleCache
<TaxonNode
>> list
= new ArrayList
<UuidAndTitleCache
<TaxonNode
>>(result
.size());
1589 for (Object object
: result
){
1591 Object
[] objectArray
= (Object
[]) object
;
1593 UUID uuid
= UUID
.fromString((String
) objectArray
[0]);
1594 String titleCache
= (String
) objectArray
[1];
1596 list
.add(new UuidAndTitleCache(TaxonNode
.class, uuid
, titleCache
));
1604 public class UuidAndTitleCacheOfAcceptedTaxon
{
1609 public UuidAndTitleCacheOfAcceptedTaxon(UUID uuid
, String titleCache
){
1611 this.titleCache
= titleCache
;
1614 public UUID
getUuid() {
1618 public void setUuid(UUID uuid
) {
1622 public String
getTitleCache() {
1626 public void setTitleCache(String titleCache
) {
1627 this.titleCache
= titleCache
;
1632 public TaxonBase
find(LSID lsid
) {
1633 TaxonBase
<?
> taxonBase
= super.find(lsid
);
1634 if(taxonBase
!= null) {
1635 List
<String
> propertyPaths
= new ArrayList
<String
>();
1636 propertyPaths
.add("createdBy");
1637 propertyPaths
.add("updatedBy");
1638 propertyPaths
.add("name");
1639 propertyPaths
.add("sec");
1640 propertyPaths
.add("relationsToThisTaxon");
1641 propertyPaths
.add("relationsToThisTaxon.fromTaxon");
1642 propertyPaths
.add("relationsToThisTaxon.toTaxon");
1643 propertyPaths
.add("relationsFromThisTaxon");
1644 propertyPaths
.add("relationsFromThisTaxon.toTaxon");
1645 propertyPaths
.add("relationsToThisTaxon.type");
1646 propertyPaths
.add("synonymRelations");
1647 propertyPaths
.add("synonymRelations.synonym");
1648 propertyPaths
.add("synonymRelations.type");
1649 propertyPaths
.add("descriptions");
1651 defaultBeanInitializer
.initialize(taxonBase
, propertyPaths
);
1656 public List
<TaxonBase
> getTaxaByCommonName(String queryString
,
1657 Classification classification
, MatchMode matchMode
,
1658 Set
<NamedArea
> namedAreas
, Integer pageSize
, Integer pageNumber
) {
1659 logger
.warn("getTaxaByCommonName not yet implemented.");
1671 /* private void xxx(List<SynonymRelationship> synonymRelationships, HashMap <UUID, ZoologicalName> zooHashMap, SynonymRelationshipType type, String addString){
1673 for (SynonymRelationship synonymRelation:synonymRelationships){
1674 TaxonNameBase synName;
1675 NonViralName inferredSynName;
1676 Synonym syn = synonymRelation.getSynonym();
1677 HibernateProxyHelper.deproxy(syn);
1679 synName = syn.getName();
1680 ZoologicalName zooName = zooHashMap.get(synName.getUuid());
1681 String synGenusName = zooName.getGenusOrUninomial();
1683 switch(type.getId()){
1684 case SynonymRelationshipType.INFERRED_EPITHET_OF().getId():
1685 inferredSynName.setSpecificEpithet(addString);
1687 case SynonymRelationshipType.INFERRED_GENUS_OF().getId():
1689 case SynonymRelationshipType.POTENTIAL_COMBINATION_OF().getId():
1693 if (!synonymsGenus.contains(synGenusName)){
1694 synonymsGenus.add(synGenusName);
1696 inferredSynName = NonViralName.NewInstance(Rank.SPECIES());
1697 inferredSynName.setSpecificEpithet(epithetOfTaxon);
1698 inferredSynName.setGenusOrUninomial(synGenusName);
1699 inferredEpithet = Synonym.NewInstance(inferredSynName, null);
1700 taxon.addSynonym(inferredEpithet, SynonymRelationshipType.INFERRED_GENUS_OF());
1701 inferredSynonyms.add(inferredEpithet);
1702 inferredSynName.generateTitle();
1703 taxonNames.add(inferredSynName.getNameCache());
1707 if (!taxonNames.isEmpty()){
1708 List<String> synNotInCDM = this.taxaByNameNotInDB(taxonNames);
1709 ZoologicalName name;
1710 if (!synNotInCDM.isEmpty()){
1711 for (Synonym syn :inferredSynonyms){
1712 name =zooHashMap.get(syn.getName().getUuid());
1713 if (!synNotInCDM.contains(name.getNameCache())){
1714 inferredSynonyms.remove(syn);
1723 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#countAllRelationships()
1725 public int countAllRelationships() {
1726 return countAllRelationships(null);
1731 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#countAllRelationships()
1733 public int countAllRelationships(Class
<?
extends RelationshipBase
> clazz
) {
1734 if (clazz
!= null && ! TaxonRelationship
.class.isAssignableFrom(clazz
) && ! SynonymRelationship
.class.isAssignableFrom(clazz
) ){
1735 throw new RuntimeException("Class must be assignable by a taxon or snonym relation");
1739 if (clazz
== null || TaxonRelationship
.class.isAssignableFrom(clazz
)){
1740 String hql
= " SELECT count(rel) FROM TaxonRelationship rel";
1741 size
+= (Long
)getSession().createQuery(hql
).list().get(0);
1743 if (clazz
== null || SynonymRelationship
.class.isAssignableFrom(clazz
)){
1744 String hql
= " SELECT count(rel) FROM SynonymRelationship rel";
1745 size
+= (Long
)getSession().createQuery(hql
).list().get(0);
1751 public List
<String
> taxaByNameNotInDB(List
<String
> taxonNames
){
1752 List
<TaxonBase
> notInDB
= new ArrayList
<TaxonBase
>();
1753 //get all taxa, already in db
1754 Query query
= getSession().createQuery("from TaxonNameBase t where t.nameCache IN (:taxonList)");
1755 query
.setParameterList("taxonList", taxonNames
);
1756 List
<TaxonNameBase
> taxaInDB
= query
.list();
1757 //compare the original list with the result of the query
1758 for (TaxonNameBase taxonName
: taxaInDB
){
1759 if (taxonName
.isInstanceOf(NonViralName
.class)) {
1760 NonViralName nonViralName
= CdmBase
.deproxy(taxonName
, NonViralName
.class);
1761 String nameCache
= nonViralName
.getNameCache();
1762 if (taxonNames
.contains(nameCache
)){
1763 taxonNames
.remove(nameCache
);
1771 //TODO: mal nur mit UUID probieren (ohne fetch all properties), vielleicht geht das schneller?
1772 public List
<UUID
> findIdenticalTaxonNameIds(List
<String
> propertyPaths
){
1773 Query query
=getSession().createQuery("select tmb2 from ZoologicalName tmb, ZoologicalName tmb2 fetch all properties where tmb.id != tmb2.id and tmb.nameCache = tmb2.nameCache");
1774 List
<UUID
> zooNames
= query
.list();
1780 public List
<TaxonNameBase
> findIdenticalTaxonNames(List
<String
> propertyPaths
) {
1782 Query query
=getSession().createQuery("select tmb2 from ZoologicalName tmb, ZoologicalName tmb2 fetch all properties where tmb.id != tmb2.id and tmb.nameCache = tmb2.nameCache");
1784 List
<TaxonNameBase
> zooNames
= query
.list();
1786 TaxonNameComparator taxComp
= new TaxonNameComparator();
1787 Collections
.sort(zooNames
, taxComp
);
1789 for (TaxonNameBase taxonNameBase
: zooNames
){
1790 defaultBeanInitializer
.initialize(taxonNameBase
, propertyPaths
);
1796 public List
<TaxonNameBase
> findIdenticalNamesNew(List
<String
> propertyPaths
){
1798 //Hole die beiden Source_ids von "Fauna Europaea" und "Erms" und in sources der names darf jeweils nur das entgegengesetzte auftreten (i member of tmb.taxonBases)
1799 Query query
= getSession().createQuery("Select id from Reference where titleCache like 'Fauna Europaea database'");
1800 List
<String
> secRefFauna
= query
.list();
1801 query
= getSession().createQuery("Select id from Reference where titleCache like 'ERMS'");
1802 List
<String
> secRefErms
= query
.list();
1803 //Query query = getSession().createQuery("select tmb2.nameCache from ZoologicalName tmb, TaxonBase tb1, ZoologicalName tmb2, TaxonBase tb2 where tmb.id != tmb2.id and tb1.name = tmb and tb2.name = tmb2 and tmb.nameCache = tmb2.nameCache and tb1.sec != tb2.sec");
1804 //Get all names of fauna europaea
1805 query
= getSession().createQuery("select zn.nameCache from ZoologicalName zn, TaxonBase tb where tb.name = zn and tb.sec.id = :secRefFauna");
1806 query
.setParameter("secRefFauna", secRefFauna
.get(0));
1807 List
<String
> namesFauna
= query
.list();
1809 //Get all names of erms
1811 query
= getSession().createQuery("select zn.nameCache from ZoologicalName zn, TaxonBase tb where tb.name = zn and tb.sec.id = :secRefErms");
1812 query
.setParameter("secRefErms", secRefErms
.get(0));
1814 List
<String
> namesErms
= query
.list();
1815 /*TaxonNameComparator comp = new TaxonNameComparator();
1816 Collections.sort(namesFauna);
1817 Collections.sort(namesErms);
1819 List
<String
> identicalNames
= new ArrayList
<String
>();
1820 String predecessor
= "";
1822 for (String nameFauna
: namesFauna
){
1823 if (namesErms
.contains(nameFauna
)){
1824 identicalNames
.add(nameFauna
);
1829 query
= getSession().createQuery("from ZoologicalName zn where zn.nameCache IN (:identicalNames)");
1830 query
.setParameterList("identicalNames", identicalNames
);
1831 List
<TaxonNameBase
> result
= query
.list();
1832 TaxonNameBase temp
= result
.get(0);
1834 Iterator
<OriginalSourceBase
> sources
= temp
.getSources().iterator();
1836 TaxonNameComparator taxComp
= new TaxonNameComparator();
1837 Collections
.sort(result
, taxComp
);
1838 defaultBeanInitializer
.initializeAll(result
, propertyPaths
);
1845 public String
getPhylumName(TaxonNameBase name
){
1846 List results
= new ArrayList();
1848 Query query
= getSession().createSQLQuery("select getPhylum("+ name
.getId()+");");
1849 results
= query
.list();
1850 }catch(Exception e
){
1851 System
.err
.println(name
.getUuid());
1854 System
.err
.println("phylum of "+ name
.getTitleCache() );
1855 return (String
)results
.get(0);
1859 public long countTaxaByCommonName(String searchString
,
1860 Classification classification
, MatchMode matchMode
,
1861 Set
<NamedArea
> namedAreas
) {
1862 boolean doCount
= true;
1863 Query query
= prepareTaxaByCommonName(searchString
, classification
, matchMode
, namedAreas
, null, null, doCount
);
1864 if (query
!= null && !query
.list().isEmpty()) {
1865 Object o
= query
.uniqueResult();
1875 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#deleteSynonymRelationships(eu.etaxonomy.cdm.model.taxon.Synonym, eu.etaxonomy.cdm.model.taxon.Taxon)
1877 public long deleteSynonymRelationships(Synonym synonym
, Taxon taxon
) {
1879 String hql
= "delete SynonymRelationship sr where sr.relatedFrom = :syn ";
1881 hql
+= " and sr.relatedTo = :taxon";
1883 Session session
= this.getSession();
1884 Query q
= session
.createQuery(hql
);
1886 q
.setParameter("syn", synonym
);
1888 q
.setParameter("taxon", taxon
);
1890 long result
= q
.executeUpdate();
1897 public Integer
countSynonymRelationships(TaxonBase taxonBase
,
1898 SynonymRelationshipType type
, Direction relatedfrom
) {
1899 AuditEvent auditEvent
= getAuditEventFromContext();
1900 if(auditEvent
.equals(AuditEvent
.CURRENT_VIEW
)) {
1904 query
= getSession().createQuery("select count(synonymRelationship) from SynonymRelationship synonymRelationship where synonymRelationship."+relatedfrom
+" = :relatedSynonym");
1906 query
= getSession().createQuery("select count(synonymRelationship) from SynonymRelationship synonymRelationship where synonymRelationship."+relatedfrom
+" = :relatedSynonym and synonymRelationship.type = :type");
1907 query
.setParameter("type",type
);
1909 query
.setParameter("relatedTaxon", taxonBase
);
1911 return ((Long
)query
.uniqueResult()).intValue();
1913 AuditQuery query
= getAuditReader().createQuery().forEntitiesAtRevision(TaxonRelationship
.class,auditEvent
.getRevisionNumber());
1914 query
.add(AuditEntity
.relatedId(relatedfrom
.toString()).eq(taxonBase
.getId()));
1915 query
.addProjection(AuditEntity
.id().count("id"));
1918 query
.add(AuditEntity
.relatedId("type").eq(type
.getId()));
1921 return ((Long
)query
.getSingleResult()).intValue();
1927 public List
<SynonymRelationship
> getSynonymRelationships(TaxonBase taxonBase
,
1928 SynonymRelationshipType type
, Integer pageSize
, Integer pageNumber
,
1929 List
<OrderHint
> orderHints
, List
<String
> propertyPaths
,
1930 Direction direction
) {
1932 AuditEvent auditEvent
= getAuditEventFromContext();
1933 if(auditEvent
.equals(AuditEvent
.CURRENT_VIEW
)) {
1934 Criteria criteria
= getSession().createCriteria(SynonymRelationship
.class);
1936 if (direction
.equals(Direction
.relatedTo
)){
1937 criteria
.add(Restrictions
.eq("relatedTo", taxonBase
));
1939 criteria
.add(Restrictions
.eq("relatedFrom", taxonBase
));
1942 criteria
.add(Restrictions
.eq("type", type
));
1945 addOrder(criteria
,orderHints
);
1947 if(pageSize
!= null) {
1948 criteria
.setMaxResults(pageSize
);
1949 if(pageNumber
!= null) {
1950 criteria
.setFirstResult(pageNumber
* pageSize
);
1952 criteria
.setFirstResult(0);
1956 List
<SynonymRelationship
> result
= (List
<SynonymRelationship
>)criteria
.list();
1957 defaultBeanInitializer
.initializeAll(result
, propertyPaths
);
1961 AuditQuery query
= getAuditReader().createQuery().forEntitiesAtRevision(TaxonRelationship
.class,auditEvent
.getRevisionNumber());
1963 if (direction
.equals(Direction
.relatedTo
)){
1964 query
.add(AuditEntity
.relatedId("relatedTo").eq(taxonBase
.getId()));
1966 query
.add(AuditEntity
.relatedId("relatedFrom").eq(taxonBase
.getId()));
1970 query
.add(AuditEntity
.relatedId("type").eq(type
.getId()));
1973 if(pageSize
!= null) {
1974 query
.setMaxResults(pageSize
);
1975 if(pageNumber
!= null) {
1976 query
.setFirstResult(pageNumber
* pageSize
);
1978 query
.setFirstResult(0);
1982 List
<SynonymRelationship
> result
= (List
<SynonymRelationship
>)query
.getResultList();
1983 defaultBeanInitializer
.initializeAll(result
, propertyPaths
);
1985 // Ugly, but for now, there is no way to sort on a related entity property in Envers,
1986 // and we can't live without this functionality in CATE as it screws up the whole
1988 if(orderHints
!= null && !orderHints
.isEmpty()) {
1989 SortedSet
<SynonymRelationship
> sortedList
= new TreeSet
<SynonymRelationship
>(new SynonymRelationshipFromTaxonComparator());
1990 sortedList
.addAll(result
);
1991 return new ArrayList
<SynonymRelationship
>(sortedList
);
2000 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getUuidAndTitleCacheTaxon()
2003 public List
<UuidAndTitleCache
<TaxonBase
>> getUuidAndTitleCacheTaxon() {
2004 String queryString
= String
.format("select uuid, titleCache from %s where DTYPE = '%s'", type
.getSimpleName(), Taxon
.class.getSimpleName());
2005 Query query
= getSession().createQuery(queryString
);
2007 List
<UuidAndTitleCache
<TaxonBase
>> result
= getUuidAndTitleCache(query
);
2014 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getUuidAndTitleCacheSynonym()
2017 public List
<UuidAndTitleCache
<TaxonBase
>> getUuidAndTitleCacheSynonym() {
2018 String queryString
= String
.format("select uuid, titleCache from %s where DTYPE = '%s'", type
.getSimpleName(), Synonym
.class.getSimpleName());
2019 Query query
= getSession().createQuery(queryString
);
2021 List
<UuidAndTitleCache
<TaxonBase
>> result
= getUuidAndTitleCache(query
);
2027 private String
[] createHQLString(boolean doTaxa
, boolean doSynonyms
, boolean doIncludeMisappliedNames
, Classification classification
, Set
<NamedArea
> areasExpanded
, MatchMode matchMode
, String searchField
){
2029 boolean doAreaRestriction
= areasExpanded
.size() > 0;
2030 String doAreaRestrictionSubSelect
= "select %s.id from" +
2032 " join e.inDescription d" +
2034 (classification
!= null ?
" join t.taxonNodes as tn " : " ");
2036 String doAreaRestrictionMisappliedNameSubSelect
= "select %s.id from" +
2038 " join e.inDescription d" +
2041 String doTaxonSubSelect
= "select %s.id from Taxon t " + (classification
!= null ?
" join t.taxonNodes as tn " : " ");
2042 String doTaxonMisappliedNameSubSelect
= "select %s.id from Taxon t ";
2044 String doTaxonNameJoin
= " join t.name n ";
2046 String doSynonymNameJoin
= " join t.synonymRelations sr join sr.relatedFrom s join s.name sn";
2048 String doMisappliedNamesJoin
= " left join t.relationsFromThisTaxon as rft" +
2049 " left join rft.relatedTo as rt" +
2050 (classification
!= null ?
" left join rt.taxonNodes as tn2" : " ") +
2051 " left join rt.name as n2" +
2052 " left join rft.type as rtype";
2054 String doClassificationWhere
= " tn.classification = :classification";
2055 String doClassificationForMisappliedNamesWhere
= " tn2 .classification = :classification";
2057 String doAreaRestrictionWhere
= " e.area.uuid in (:namedAreasUuids)";
2059 String doSearchFieldWhere
= "%s." + searchField
+ " " + matchMode
.getMatchOperator() + " :queryString";
2061 String doRelationshipTypeComparison
= " rtype = :rType ";
2063 String taxonSubselect
= null;
2064 String synonymSubselect
= null;
2065 String misappliedSelect
= null;
2067 if(classification
!= null ){
2068 if (!doIncludeMisappliedNames
){
2069 if(doAreaRestriction
){
2070 taxonSubselect
= String
.format(doAreaRestrictionSubSelect
, "t") + doTaxonNameJoin
+
2071 " WHERE " + doAreaRestrictionWhere
+
2072 " AND " + doClassificationWhere
+
2073 " AND " + String
.format(doSearchFieldWhere
, "n");
2074 synonymSubselect
= String
.format(doAreaRestrictionSubSelect
, "s") + doSynonymNameJoin
+
2075 " WHERE " + doAreaRestrictionWhere
+
2076 " AND " + doClassificationWhere
+
2077 " AND " + String
.format(doSearchFieldWhere
, "sn");
2079 taxonSubselect
= String
.format(doTaxonSubSelect
, "t" )+ doTaxonNameJoin
+
2080 " WHERE " + doClassificationWhere
+
2081 " AND " + String
.format(doSearchFieldWhere
, "n");
2082 synonymSubselect
= String
.format(doTaxonSubSelect
, "s" ) + doSynonymNameJoin
+
2083 " WHERE " + doClassificationWhere
+
2084 " AND " + String
.format(doSearchFieldWhere
, "sn");
2086 }else{ //misappliedNames included
2087 if(doAreaRestriction
){
2088 misappliedSelect
= String
.format(doAreaRestrictionMisappliedNameSubSelect
, "t") + doTaxonNameJoin
+ doMisappliedNamesJoin
+
2089 " WHERE " + doAreaRestrictionWhere
+
2090 " AND " + String
.format(doSearchFieldWhere
, "n") +
2091 " AND " + doClassificationForMisappliedNamesWhere
+
2092 " AND " + doRelationshipTypeComparison
;
2094 taxonSubselect
= String
.format(doAreaRestrictionSubSelect
, "t") + doTaxonNameJoin
+
2095 " WHERE " + doAreaRestrictionWhere
+
2096 " AND "+ String
.format(doSearchFieldWhere
, "n") + " AND "+ doClassificationWhere
;
2098 synonymSubselect
= String
.format(doAreaRestrictionSubSelect
, "s") + doSynonymNameJoin
+
2099 " WHERE " + doAreaRestrictionWhere
+
2100 " AND " + doClassificationWhere
+ " AND " + String
.format(doSearchFieldWhere
, "sn");;
2103 misappliedSelect
= String
.format(doTaxonMisappliedNameSubSelect
, "t" ) + doTaxonNameJoin
+ doMisappliedNamesJoin
+
2104 " WHERE " + String
.format(doSearchFieldWhere
, "n") +
2105 " AND " + doClassificationForMisappliedNamesWhere
+
2106 " AND " + doRelationshipTypeComparison
;
2108 taxonSubselect
= String
.format(doTaxonSubSelect
, "t" ) + doTaxonNameJoin
+
2109 " WHERE " + String
.format(doSearchFieldWhere
, "n") +
2110 " AND "+ doClassificationWhere
;
2112 synonymSubselect
= String
.format(doTaxonSubSelect
, "s" ) + doSynonymNameJoin
+
2113 " WHERE " + doClassificationWhere
+
2114 " AND " + String
.format(doSearchFieldWhere
, "sn");
2119 if(doAreaRestriction
){
2120 misappliedSelect
= String
.format(doAreaRestrictionMisappliedNameSubSelect
, "t") + doTaxonNameJoin
+ doMisappliedNamesJoin
+
2121 " WHERE " + doAreaRestrictionWhere
+
2122 " AND " + String
.format(doSearchFieldWhere
, "n")+
2123 " AND " + doRelationshipTypeComparison
;
2125 taxonSubselect
= String
.format(doAreaRestrictionSubSelect
, "t") + doTaxonNameJoin
+
2126 " WHERE " + doAreaRestrictionWhere
+
2127 " AND " + String
.format(doSearchFieldWhere
, "n");
2129 synonymSubselect
= String
.format(doAreaRestrictionSubSelect
, "s") + doSynonymNameJoin
+
2130 " WHERE " + doAreaRestrictionWhere
+
2131 " AND " + String
.format(doSearchFieldWhere
, "sn");
2135 misappliedSelect
= String
.format(doTaxonMisappliedNameSubSelect
, "t" ) + doTaxonNameJoin
+ doMisappliedNamesJoin
+ " WHERE " + String
.format(doSearchFieldWhere
, "n") + " AND " + doRelationshipTypeComparison
;
2136 taxonSubselect
= String
.format(doTaxonSubSelect
, "t" ) + doTaxonNameJoin
+ " WHERE " + String
.format(doSearchFieldWhere
, "n");
2137 synonymSubselect
= String
.format(doTaxonSubSelect
, "s" ) + doSynonymNameJoin
+ " WHERE " + String
.format(doSearchFieldWhere
, "sn");
2141 String
[] result
= {misappliedSelect
, taxonSubselect
, synonymSubselect
};