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
.hibernate
.Criteria
;
25 import org
.hibernate
.FetchMode
;
26 import org
.hibernate
.Hibernate
;
27 import org
.hibernate
.Query
;
28 import org
.hibernate
.Session
;
29 import org
.hibernate
.criterion
.Criterion
;
30 import org
.hibernate
.criterion
.Order
;
31 import org
.hibernate
.criterion
.Projections
;
32 import org
.hibernate
.criterion
.Restrictions
;
33 import org
.hibernate
.envers
.query
.AuditEntity
;
34 import org
.hibernate
.envers
.query
.AuditQuery
;
35 import org
.hibernate
.search
.FullTextSession
;
36 import org
.hibernate
.search
.Search
;
37 import org
.springframework
.beans
.factory
.annotation
.Autowired
;
38 import org
.springframework
.beans
.factory
.annotation
.Qualifier
;
39 import org
.springframework
.dao
.DataAccessException
;
40 import org
.springframework
.stereotype
.Repository
;
42 import eu
.etaxonomy
.cdm
.model
.common
.CdmBase
;
43 import eu
.etaxonomy
.cdm
.model
.common
.DefinedTerm
;
44 import eu
.etaxonomy
.cdm
.model
.common
.IdentifiableEntity
;
45 import eu
.etaxonomy
.cdm
.model
.common
.LSID
;
46 import eu
.etaxonomy
.cdm
.model
.common
.OriginalSourceBase
;
47 import eu
.etaxonomy
.cdm
.model
.common
.RelationshipBase
;
48 import eu
.etaxonomy
.cdm
.model
.common
.RelationshipBase
.Direction
;
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
.hibernate
.common
.IdentifiableDaoBase
;
66 import eu
.etaxonomy
.cdm
.persistence
.dao
.name
.ITaxonNameDao
;
67 import eu
.etaxonomy
.cdm
.persistence
.dao
.taxon
.ITaxonDao
;
68 import eu
.etaxonomy
.cdm
.persistence
.dto
.UuidAndTitleCache
;
69 import eu
.etaxonomy
.cdm
.persistence
.fetch
.CdmFetch
;
70 import eu
.etaxonomy
.cdm
.persistence
.query
.MatchMode
;
71 import eu
.etaxonomy
.cdm
.persistence
.query
.OrderHint
;
79 @Qualifier("taxonDaoHibernateImpl")
80 public class TaxonDaoHibernateImpl
extends IdentifiableDaoBase
<TaxonBase
> implements ITaxonDao
{
81 // private AlternativeSpellingSuggestionParser<TaxonBase> alternativeSpellingSuggestionParser;
82 private static final Logger logger
= Logger
.getLogger(TaxonDaoHibernateImpl
.class);
84 public TaxonDaoHibernateImpl() {
85 super(TaxonBase
.class);
86 indexedClasses
= new Class
[2];
87 indexedClasses
[0] = Taxon
.class;
88 indexedClasses
[1] = Synonym
.class;
89 super.defaultField
= "name.titleCache_tokenized";
93 private ITaxonNameDao taxonNameDao
;
95 //// spelling support currently disabled in appcontext, see spelling.xml ... "
96 //// @Autowired(required = false) //TODO switched of because it caused problems when starting CdmApplicationController
97 // public void setAlternativeSpellingSuggestionParser(AlternativeSpellingSuggestionParser<TaxonBase> alternativeSpellingSuggestionParser) {
98 // this.alternativeSpellingSuggestionParser = alternativeSpellingSuggestionParser;
102 public List
<Taxon
> getRootTaxa(Reference sec
) {
103 return getRootTaxa(sec
, CdmFetch
.FETCH_CHILDTAXA(), true, false);
107 public List
<Taxon
> getRootTaxa(Rank rank
, Reference sec
, CdmFetch cdmFetch
, Boolean onlyWithChildren
, Boolean withMisapplications
, List
<String
> propertyPaths
) {
108 checkNotInPriorView("TaxonDaoHibernateImpl.getRootTaxa(Rank rank, Reference sec, CdmFetch cdmFetch, Boolean onlyWithChildren, Boolean withMisapplications)");
109 if (onlyWithChildren
== null){
110 onlyWithChildren
= true;
112 if (withMisapplications
== null){
113 withMisapplications
= true;
115 if (cdmFetch
== null){
116 cdmFetch
= CdmFetch
.NO_FETCH();
119 Criteria crit
= getSession().createCriteria(Taxon
.class);
121 crit
.setFetchMode("name", FetchMode
.JOIN
);
122 crit
.createAlias("name", "name");
125 crit
.add(Restrictions
.eq("name.rank", rank
));
127 crit
.add(Restrictions
.isNull("taxonomicParentCache"));
131 crit
.add(Restrictions
.eq("sec", sec
) );
134 if (! cdmFetch
.includes(CdmFetch
.FETCH_CHILDTAXA())){
135 logger
.info("Not fetching child taxa");
136 //TODO overwrite LAZY (SELECT) does not work (bug in hibernate?)
137 crit
.setFetchMode("relationsToThisTaxon.fromTaxon", FetchMode
.LAZY
);
140 List
<Taxon
> results
= new ArrayList
<Taxon
>();
141 @SuppressWarnings("unchecked")
142 List
<Taxon
> taxa
= crit
.list();
143 for(Taxon taxon
: taxa
){
147 //TODO create restriction instead
148 // (a) not using cache fields
149 /*Hibernate.initialize(taxon.getRelationsFromThisTaxon());
150 if (onlyWithChildren == false || taxon.getRelationsFromThisTaxon().size() > 0){
151 if (withMisapplications == true || ! taxon.isMisappliedName()){
152 defaultBeanInitializer.initialize(taxon, propertyPaths);
156 // (b) using cache fields
157 if (onlyWithChildren
== false || taxon
.hasTaxonomicChildren()){
158 if (withMisapplications
== true || ! taxon
.isMisapplication()){
159 defaultBeanInitializer
.initialize(taxon
, propertyPaths
);
168 public List
<Taxon
> getRootTaxa(Reference sec
, CdmFetch cdmFetch
, Boolean onlyWithChildren
, Boolean withMisapplications
) {
169 return getRootTaxa(null, sec
, cdmFetch
, onlyWithChildren
, withMisapplications
, null);
173 public List
<TaxonBase
> getTaxaByName(String queryString
, Reference sec
) {
175 return getTaxaByName(queryString
, true, sec
);
179 public List
<TaxonBase
> getTaxaByName(String queryString
, Boolean accepted
, Reference sec
) {
180 checkNotInPriorView("TaxonDaoHibernateImpl.getTaxaByName(String name, Reference sec)");
182 Criteria criteria
= null;
183 if (accepted
== true) {
184 criteria
= getSession().createCriteria(Taxon
.class);
186 criteria
= getSession().createCriteria(Synonym
.class);
189 criteria
.setFetchMode( "name", FetchMode
.JOIN
);
190 criteria
.createAlias("name", "name");
192 if (sec
!= null && sec
.getId() != 0) {
193 criteria
.add(Restrictions
.eq("sec", sec
) );
196 if (queryString
!= null) {
197 criteria
.add(Restrictions
.ilike("name.nameCache", queryString
));
200 return criteria
.list();
203 public List
<TaxonBase
> getTaxaByName(boolean doTaxa
, boolean doSynonyms
, String queryString
, MatchMode matchMode
,
204 Integer pageSize
, Integer pageNumber
) {
206 return getTaxaByName(doTaxa
, doSynonyms
, false, queryString
, null, matchMode
, null, pageSize
, pageNumber
, null);
210 public List
<TaxonBase
> getTaxaByName(String queryString
, MatchMode matchMode
,
211 Boolean accepted
, Integer pageSize
, Integer pageNumber
) {
213 boolean doTaxa
= true;
214 boolean doSynonyms
= true;
216 if (accepted
== true) {
221 return getTaxaByName(doTaxa
, doSynonyms
, queryString
, matchMode
, pageSize
, pageNumber
);
225 public List
<TaxonBase
> getTaxaByName(boolean doTaxa
, boolean doSynonyms
, boolean doMisappliedNames
,String queryString
, Classification classification
,
226 MatchMode matchMode
, Set
<NamedArea
> namedAreas
, Integer pageSize
,
227 Integer pageNumber
, List
<String
> propertyPaths
) {
229 boolean doCount
= false;
231 Query query
= prepareTaxaByName(doTaxa
, doSynonyms
, doMisappliedNames
, "nameCache", queryString
, classification
, matchMode
, namedAreas
, pageSize
, pageNumber
, doCount
);
234 @SuppressWarnings("unchecked")
235 List
<TaxonBase
> results
= query
.list();
237 defaultBeanInitializer
.initializeAll(results
, propertyPaths
);
238 //TaxonComparatorSearch comp = new TaxonComparatorSearch();
239 //Collections.sort(results, comp);
243 return new ArrayList
<TaxonBase
>();
248 //new search for the editor, for performance issues the return values are only uuid and titleCache, to avoid the initialisation of all objects
250 @SuppressWarnings("unchecked")
251 public List
<UuidAndTitleCache
<IdentifiableEntity
>> getTaxaByNameForEditor(boolean doTaxa
, boolean doSynonyms
, boolean doNamesWithoutTaxa
, boolean doMisappliedNames
, String queryString
, Classification classification
,
252 MatchMode matchMode
, Set
<NamedArea
> namedAreas
) {
256 boolean doCount
= false;
257 List
<UuidAndTitleCache
<IdentifiableEntity
>> resultObjects
= new ArrayList
<UuidAndTitleCache
<IdentifiableEntity
>>();
258 if (doNamesWithoutTaxa
){
259 List
<?
extends TaxonNameBase
<?
,?
>> nameResult
= taxonNameDao
.findByName(queryString
,matchMode
, null, null, null, null);
261 for (TaxonNameBase name
: nameResult
){
262 if (name
.getTaxonBases().size() == 0){
263 resultObjects
.add(new UuidAndTitleCache(TaxonNameBase
.class, name
.getUuid(), name
.getId(), name
.getTitleCache()));
266 if (!doSynonyms
&& !doTaxa
){
267 return resultObjects
;
270 Query query
= prepareTaxaByNameForEditor(doTaxa
, doSynonyms
, doMisappliedNames
, "nameCache", queryString
, classification
, matchMode
, namedAreas
, doCount
);
274 List
<Object
[]> results
= query
.list();
277 for(int i
= 0; i
<results
.size();i
++){
278 result
= results
.get(i
);
280 //differentiate taxa and synonyms
281 // new Boolean(result[3].toString()) is due to the fact that result[3] could be a Boolean ora String
282 // see FIXME in 'prepareQuery' for more details
283 if (doTaxa
&& doSynonyms
){
284 if (result
[3].equals("synonym")) {
285 resultObjects
.add( new UuidAndTitleCache(Synonym
.class, (UUID
) result
[0], (Integer
) result
[1], (String
)result
[2], new Boolean(result
[4].toString())));
288 resultObjects
.add( new UuidAndTitleCache(Taxon
.class, (UUID
) result
[0], (Integer
) result
[1], (String
)result
[2], new Boolean(result
[4].toString())));
291 resultObjects
.add( new UuidAndTitleCache(Taxon
.class, (UUID
) result
[0], (Integer
) result
[1], (String
)result
[2], new Boolean(result
[4].toString())));
292 }else if (doSynonyms
){
293 resultObjects
.add( new UuidAndTitleCache(Synonym
.class, (UUID
) result
[0], (Integer
) result
[1], (String
)result
[2], new Boolean(result
[4].toString())));
301 return resultObjects
;
306 public List
<Taxon
> getTaxaByCommonName(String queryString
, Classification classification
,
307 MatchMode matchMode
, Set
<NamedArea
> namedAreas
, Integer pageSize
,
308 Integer pageNumber
, List
<String
> propertyPaths
) {
309 boolean doCount
= false;
310 Query query
= prepareTaxaByCommonName(queryString
, classification
, matchMode
, namedAreas
, pageSize
, pageNumber
, doCount
, false);
312 List
<Taxon
> results
= query
.list();
313 defaultBeanInitializer
.initializeAll(results
, propertyPaths
);
316 return new ArrayList
<Taxon
>();
322 * @param searchField the field in TaxonNameBase to be searched through usually either <code>nameCache</code> or <code>titleCache</code>
324 * @param classification TODO
334 private Query
prepareTaxaByNameForEditor(boolean doTaxa
, boolean doSynonyms
, boolean doMisappliedNames
, String searchField
, String queryString
, Classification classification
,
335 MatchMode matchMode
, Set
<NamedArea
> namedAreas
, boolean doCount
) {
336 return prepareQuery(doTaxa
, doSynonyms
, doMisappliedNames
, searchField
, queryString
,
337 classification
, matchMode
, namedAreas
, doCount
, true);
343 * @param classification
347 * @param doNotReturnFullEntities
348 * if set true the seach method will not return synonym and taxon
349 * entities but an array containing the uuid, titleCache, and the
350 * DTYPE in lowercase letters.
354 private Query
prepareQuery(boolean doTaxa
, boolean doSynonyms
, boolean doIncludeMisappliedNames
, String searchField
, String queryString
,
355 Classification classification
, MatchMode matchMode
, Set
<NamedArea
> namedAreas
, boolean doCount
, boolean doNotReturnFullEntities
){
357 String hqlQueryString
= matchMode
.queryStringFrom(queryString
);
359 if (doNotReturnFullEntities
){
360 selectWhat
= "t.uuid, t.id, t.titleCache ";
362 selectWhat
= (doCount ?
"count(t)": "t");
366 Set
<NamedArea
> areasExpanded
= new HashSet
<NamedArea
>();
367 if(namedAreas
!= null && namedAreas
.size() > 0){
368 // expand areas and restrict by distribution area
369 Query areaQuery
= getSession().createQuery("select childArea from NamedArea as childArea left join childArea.partOf as parentArea where parentArea = :area");
370 expandNamedAreas(namedAreas
, areasExpanded
, areaQuery
);
372 boolean doAreaRestriction
= areasExpanded
.size() > 0;
374 Set
<UUID
> namedAreasUuids
= new HashSet
<UUID
>();
375 for (NamedArea area
:areasExpanded
){
376 namedAreasUuids
.add(area
.getUuid());
380 String
[] subSelects
= createHQLString(doTaxa
, doSynonyms
, doIncludeMisappliedNames
, classification
, areasExpanded
, matchMode
, searchField
);
381 String taxonSubselect
= subSelects
[1];
382 String synonymSubselect
= subSelects
[2];
383 String misappliedSelect
= subSelects
[0];
386 /*if(classification != null ){
387 if (!doIncludeMisappliedNames){
388 if(doAreaRestriction){
390 taxonSubselect = "select t.id from" +
392 " join e.inDescription d" +
395 " join t.taxonNodes as tn "+
397 " e.area.uuid in (:namedAreasUuids) AND" +
398 " tn.classification = :classification" +
399 " AND n." + searchField + " " + matchMode.getMatchOperator() + " :queryString";
403 synonymSubselect = "select s.id from" +
405 " join e.inDescription d" +
406 " join d.taxon t" + // the taxa
407 " join t.taxonNodes as tn "+
408 " join t.synonymRelations sr" +
409 " join sr.relatedFrom s" + // the synonyms
412 " e.area.uuid in (:namedAreasUuids) AND" +
413 " tn.classification = :classification" +
414 " AND sn." + searchField + " " + matchMode.getMatchOperator() + " :queryString";
418 taxonSubselect = "select t.id from" +
421 " join t.taxonNodes as tn "+
423 " tn.classification = :classification" +
424 " AND n." + searchField + " " + matchMode.getMatchOperator() + " :queryString";
426 synonymSubselect = "select s.id from" +
427 " Taxon t" + // the taxa
428 " join t.taxonNodes as tn "+
429 " join t.synonymRelations sr" +
430 " join sr.relatedFrom s" + // the synonyms
433 " tn.classification = :classification" +
434 " AND sn." + searchField + " " + matchMode.getMatchOperator() + " :queryString";
437 if(doAreaRestriction){
438 if (!doTaxa && !doSynonyms ){
439 misappliedSelect = "select t.id from" +
441 " join e.inDescription d" +
444 " join t.taxonNodes as tn "+
445 " left join t.relationsFromThisTaxon as rft" +
446 " left join rft.relatedTo as rt" +
447 " left join rt.taxonNodes as tn2" +
448 " left join rt.name as n2" +
449 " left join rft.type as rtype"+
451 " e.area.uuid in (:namedAreasUuids) AND" +
452 " (tn.classification != :classification" +
453 " AND n." + searchField + " " + matchMode.getMatchOperator() + " :queryString" +
454 " AND tn2.classification = :classification" +
455 " AND rtype = :rType )";
458 taxonSubselect = "select t.id from" +
460 " join e.inDescription d" +
463 " join t.taxonNodes as tn "+
464 " left join t.relationsFromThisTaxon as rft" +
465 " left join rft.relatedTo as rt" +
466 " left join rt.taxonNodes as tn2" +
467 " left join rt.name as n2" +
468 " left join rft.type as rtype"+
470 " e.area.uuid in (:namedAreasUuids) AND" +
471 " (tn.classification = :classification" +
472 " AND n." + searchField + " " + matchMode.getMatchOperator() + " :queryString )" +
474 " (tn.classification != :classification" +
475 " AND n." + searchField + " " + matchMode.getMatchOperator() + " :queryString" +
476 " AND tn2.classification = :classification" +
477 " AND rtype = :rType )";
480 synonymSubselect = "select s.id from" +
482 " join e.inDescription d" +
483 " join d.taxon t" + // the taxa
484 " join t.taxonNodes as tn "+
485 " join t.synonymRelations sr" +
486 " join sr.relatedFrom s" + // the synonyms
489 " e.area.uuid in (:namedAreasUuids) AND" +
490 " tn.classification != :classification" +
491 " AND sn." + searchField + " " + matchMode.getMatchOperator() + " :queryString";
494 if (!doTaxa && !doSynonyms ){
495 misappliedSelect = "select t.id from" +
497 " join e.inDescription d" +
500 " join t.taxonNodes as tn "+
501 " left join t.relationsFromThisTaxon as rft" +
502 " left join rft.relatedTo as rt" +
503 " left join rt.taxonNodes as tn2" +
504 " left join rt.name as n2" +
505 " left join rft.type as rtype"+
507 " (tn.classification != :classification" +
508 " AND n." + searchField + " " + matchMode.getMatchOperator() + " :queryString" +
509 " AND tn2.classification = :classification" +
510 " AND rtype = :rType )";
513 taxonSubselect = "select t.id from" +
516 " join t.taxonNodes as tn "+
517 " left join t.relationsFromThisTaxon as rft" +
518 " left join rft.relatedTo as rt" +
519 " left join rt.taxonNodes as tn2" +
520 " left join rt.name as n2" +
521 " left join rft.type as rtype"+
523 " (tn.classification = :classification" +
524 " AND n." + searchField + " " + matchMode.getMatchOperator() + " :queryString )" +
526 " (tn.classification != :classification" +
527 " AND n." + searchField + " " + matchMode.getMatchOperator() + " :queryString" +
528 " AND tn2.classification = :classification" +
529 " AND rtype = :rType )";
531 synonymSubselect = "select s.id from" +
532 " Taxon t" + // the taxa
533 " join t.taxonNodes as tn "+
534 " join t.synonymRelations sr" +
535 " join sr.relatedFrom s" + // the synonyms
538 " tn.classification != :classification" +
539 " AND sn." + searchField + " " + matchMode.getMatchOperator() + " :queryString";
545 if (!doIncludeMisappliedNames){
546 if(doAreaRestriction){
547 taxonSubselect = "select t.id from " +
549 " join e.inDescription d" +
553 (doAreaRestriction ? " e.area.uuid in (:namedAreasUuids) AND" : "") +
554 " n." + searchField + " " + matchMode.getMatchOperator() + " :queryString";
556 synonymSubselect = "select s.id from" +
558 " join e.inDescription d" +
559 " join d.taxon t" + // the taxa
560 " join t.synonymRelations sr" +
561 " join sr.relatedFrom s" + // the synonyms
564 (doAreaRestriction ? " e.area.uuid in (:namedAreasUuids) AND" : "") +
565 " sn." + searchField + " " + matchMode.getMatchOperator() + " :queryString";
569 taxonSubselect = "select t.id from " +
573 " n." + searchField + " " + matchMode.getMatchOperator() + " :queryString";
575 synonymSubselect = "select s.id from" +
576 " Taxon t" + // the taxa
577 " join t.synonymRelations sr" +
578 " join sr.relatedFrom s" + // the synonyms
581 " sn." + searchField + " " + matchMode.getMatchOperator() + " :queryString";
589 logger
.debug("taxonSubselect: " + taxonSubselect
!= null ? taxonSubselect
: "NULL");
590 logger
.debug("synonymSubselect: " + synonymSubselect
!= null ? synonymSubselect
: "NULL");
592 Query subTaxon
= null;
593 Query subSynonym
= null;
594 Query subMisappliedNames
= null;
597 subTaxon
= getSession().createQuery(taxonSubselect
).setParameter("queryString", hqlQueryString
);
599 if(doAreaRestriction
){
600 subTaxon
.setParameterList("namedAreasUuids", namedAreasUuids
);
602 if(classification
!= null){
603 subTaxon
.setParameter("classification", classification
);
612 subSynonym
= getSession().createQuery(synonymSubselect
).setParameter("queryString", hqlQueryString
);
614 if(doAreaRestriction
){
615 subSynonym
.setParameterList("namedAreasUuids", namedAreasUuids
);
617 if(classification
!= null){
618 subSynonym
.setParameter("classification", classification
);
621 if (doIncludeMisappliedNames
){
622 subMisappliedNames
= getSession().createQuery(misappliedSelect
).setParameter("queryString", hqlQueryString
);
623 subMisappliedNames
.setParameter("rType", TaxonRelationshipType
.MISAPPLIED_NAME_FOR());
624 if(doAreaRestriction
){
625 subMisappliedNames
.setParameterList("namedAreasUuids", namedAreasUuids
);
627 if(classification
!= null){
628 subMisappliedNames
.setParameter("classification", classification
);
632 List
<Integer
> taxa
= new ArrayList
<Integer
>();
633 List
<Integer
> synonyms
= new ArrayList
<Integer
>();
635 synonyms
= subSynonym
.list();
638 taxa
= subTaxon
.list();
640 if (doIncludeMisappliedNames
){
641 taxa
.addAll(subMisappliedNames
.list());
644 //FIXME : the fourth element of the result should be a boolean, but in the case of a synonym
645 // (which does require a check) a constant boolean (false) value needs to set. It seems that
646 // hql cannot parse a constant boolean value in the select list clause. This implies that the
647 // resulting object could be a Boolean or a String. The workaround for this is to convert the
648 // resutling object into a String (using toString) and then create a new Boolean object from
650 if (doTaxa
&& doSynonyms
){
651 if(synonyms
.size()>0 && taxa
.size()>0){
652 hql
= "select " + selectWhat
;
653 // in doNotReturnFullEntities mode it is nesscary to also return the type of the matching entities:
654 // also return the computed isOrphaned flag
655 if (doNotReturnFullEntities
&& !doCount
){
656 hql
+= ", case when t.id in (:taxa) then 'taxon' else 'synonym' end, " +
657 " 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 ";
659 hql
+= " from %s t " +
660 " where (t.id in (:taxa) OR t.id in (:synonyms)) ";
661 }else if (synonyms
.size()>0 ){
662 hql
= "select " + selectWhat
;
663 // in doNotReturnFullEntities mode it is nesscary to also return the type of the matching entities:
664 // also return the computed isOrphaned flag
665 if (doNotReturnFullEntities
&& !doCount
){
666 hql
+= ", 'synonym', 'false' ";
669 hql
+= " from %s t " +
670 " where t.id in (:synonyms) ";
672 } else if (taxa
.size()>0 ){
673 hql
= "select " + selectWhat
;
674 // in doNotReturnFullEntities mode it is nesscary to also return the type of the matching entities:
675 // also return the computed isOrphaned flag
676 if (doNotReturnFullEntities
&& !doCount
){
677 hql
+= ", 'taxon', " +
678 " case when t.taxonNodes is empty and t.relationsFromThisTaxon is empty and t.relationsToThisTaxon is empty then true else false end ";
680 hql
+= " from %s t " +
681 " where t.id in (:taxa) ";
684 hql
= "select " + selectWhat
+ " from %s t";
688 hql
= "select " + selectWhat
;
689 // in doNotReturnFullEntities mode it is nesscary to also return the type of the matching entities:
690 // also return the computed isOrphaned flag
691 if (doNotReturnFullEntities
){
692 hql
+= ", 'taxon', " +
693 " case when t.taxonNodes is empty and t.relationsFromThisTaxon is empty and t.relationsToThisTaxon is empty then true else false end ";
695 hql
+= " from %s t " +
696 " where t.id in (:taxa) ";
699 hql
= "select " + selectWhat
+ " from %s t";
701 } else if(doSynonyms
){
702 if (synonyms
.size()>0){
704 hql
= "select " + selectWhat
;
705 // in doNotReturnFullEntities mode it is nesscary to also return the type of the matching entities:
706 // also return the computed isOrphaned flag
707 if (doNotReturnFullEntities
){
708 hql
+= ", 'synonym', 'false' ";
710 hql
+= " from %s t " +
711 " where t.id in (:synonyms) ";
713 hql
= "select " + selectWhat
+ " from %s t";
715 } else if (doIncludeMisappliedNames
){
716 hql
= "select " + selectWhat
;
717 // in doNotReturnFullEntities mode it is nesscary to also return the type of the matching entities:
718 // also return the computed isOrphaned flag
719 if (doNotReturnFullEntities
){
720 hql
+= ", 'taxon', " +
721 " case when t.taxonNodes is empty and t.relationsFromThisTaxon is empty and t.relationsToThisTaxon is empty then true else false end ";
723 hql
+= " from %s t " +
724 " where t.id in (:taxa) ";
729 if (doTaxa
&& doSynonyms
){
730 classString
= "TaxonBase";
732 classString
= "Taxon";
733 } else if (doSynonyms
){
734 classString
= "Synonym";
735 } else{//only misappliedNames
736 classString
= "Taxon";
739 hql
= String
.format(hql
, classString
);
746 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";
749 logger
.debug("hql: " + hql
);
750 Query query
= getSession().createQuery(hql
);
753 if (doTaxa
&& doSynonyms
){
754 // find taxa and synonyms
756 query
.setParameterList("taxa", taxa
);
758 if (synonyms
.size()>0){
759 query
.setParameterList("synonyms",synonyms
);
761 if (taxa
.size()== 0 && synonyms
.size() == 0){
767 query
.setParameterList("taxa", taxa
);
769 logger
.warn("there are no taxa for the query: " + queryString
);
772 } else if(doSynonyms
){
774 if (synonyms
.size()>0){
775 query
.setParameterList("synonyms", synonyms
);
780 //only misappliedNames
782 query
.setParameterList("taxa", taxa
);
793 * @param searchField the field in TaxonNameBase to be searched through usually either <code>nameCache</code> or <code>titleCache</code>
795 * @param classification TODO
804 * FIXME implement classification restriction & implement test: see {@link TaxonDaoHibernateImplTest#testCountTaxaByName()}
806 private Query
prepareTaxaByName(boolean doTaxa
, boolean doSynonyms
, boolean doMisappliedNames
, String searchField
, String queryString
,
807 Classification classification
, MatchMode matchMode
, Set
<NamedArea
> namedAreas
, Integer pageSize
, Integer pageNumber
, boolean doCount
) {
809 Query query
= prepareQuery(doTaxa
, doSynonyms
, doMisappliedNames
, searchField
, queryString
, classification
, matchMode
, namedAreas
, doCount
, false);
811 if(pageSize
!= null && !doCount
&& query
!= null) {
812 query
.setMaxResults(pageSize
);
813 if(pageNumber
!= null) {
814 query
.setFirstResult(pageNumber
* pageSize
);
821 private Query
prepareTaxaByCommonName(String queryString
, Classification classification
,
822 MatchMode matchMode
, Set
<NamedArea
> namedAreas
, Integer pageSize
, Integer pageNumber
, boolean doCount
, boolean doNotReturnFullEntities
){
824 String what
= "select";
825 if (doNotReturnFullEntities
){
826 what
+= " t.uuid, t.id, t.titleCache, \'taxon\', case when t.taxonNodes is empty and t.relationsFromThisTaxon is empty and t.relationsToThisTaxon is empty then true else false end ";
828 what
+= (doCount ?
" count(t)": " t");
830 String hql
= what
+ " from Taxon t " +
831 "join t.descriptions d "+
832 "join d.descriptionElements e " +
833 "join e.feature f " +
834 "where f.supportsCommonTaxonName = true and e.name "+matchMode
.getMatchOperator()+" :queryString";//and ls.text like 'common%'";
836 Query query
= getSession().createQuery(hql
);
838 query
.setParameter("queryString", matchMode
.queryStringFrom(queryString
));
840 if(pageSize
!= null && !doCount
) {
841 query
.setMaxResults(pageSize
);
842 if(pageNumber
!= null) {
843 query
.setFirstResult(pageNumber
* pageSize
);
850 public long countTaxaByName(boolean doTaxa
, boolean doSynonyms
, boolean doMisappliedNames
, String queryString
, Classification classification
,
851 MatchMode matchMode
, Set
<NamedArea
> namedAreas
) {
853 boolean doCount
= true;
855 boolean doTaxa = true;
856 boolean doSynonyms = true;
857 if (clazz.equals(Taxon.class)){
859 } else if (clazz.equals(Synonym.class)){
865 Query query
= prepareTaxaByName(doTaxa
, doSynonyms
, doMisappliedNames
, "nameCache", queryString
, classification
, matchMode
, namedAreas
, null, null, doCount
);
867 return (Long
)query
.uniqueResult();
875 * @param areasExpanded
878 private void expandNamedAreas(Collection
<NamedArea
> namedAreas
, Set
<NamedArea
> areasExpanded
, Query areaQuery
) {
879 List
<NamedArea
> childAreas
;
880 for(NamedArea a
: namedAreas
){
881 areasExpanded
.add(a
);
882 areaQuery
.setParameter("area", a
);
883 childAreas
= areaQuery
.list();
884 if(childAreas
.size() > 0){
885 areasExpanded
.addAll(childAreas
);
886 expandNamedAreas(childAreas
, areasExpanded
, areaQuery
);
893 public List
<TaxonBase
> getAllTaxonBases(Integer pagesize
, Integer page
) {
894 return super.list(pagesize
, page
);
898 public List
<Synonym
> getAllSynonyms(Integer limit
, Integer start
) {
899 Criteria criteria
= getSession().createCriteria(Synonym
.class);
902 criteria
.setFirstResult(start
);
903 criteria
.setMaxResults(limit
);
906 return criteria
.list();
910 public List
<Taxon
> getAllTaxa(Integer limit
, Integer start
) {
911 Criteria criteria
= getSession().createCriteria(Taxon
.class);
914 criteria
.setFirstResult(start
);
915 criteria
.setMaxResults(limit
);
918 return criteria
.list();
922 public List
<RelationshipBase
> getAllRelationships(/*Class<? extends RelationshipBase> clazz,*/ Integer limit
, Integer start
) {
923 Class
<?
extends RelationshipBase
> clazz
= RelationshipBase
.class; //preliminary, see #2653
924 AuditEvent auditEvent
= getAuditEventFromContext();
925 if(auditEvent
.equals(AuditEvent
.CURRENT_VIEW
)) {
926 // for some reason the HQL .class discriminator didn't work here so I created this preliminary
927 // implementation for now. Should be cleaned in future.
929 List
<RelationshipBase
> result
= new ArrayList
<RelationshipBase
>();
931 int taxRelSize
= countAllRelationships(TaxonRelationship
.class);
933 if (taxRelSize
> start
){
935 String hql
= " FROM TaxonRelationship as rb ORDER BY rb.id ";
936 Query query
= getSession().createQuery(hql
);
937 query
.setFirstResult(start
);
939 query
.setMaxResults(limit
);
941 result
= query
.list();
943 limit
= limit
- result
.size();
945 String hql
= " FROM SynonymRelationship as rb ORDER BY rb.id ";
946 Query query
= getSession().createQuery(hql
);
947 start
= (taxRelSize
> start
) ?
0 : (start
- taxRelSize
);
948 query
.setFirstResult(start
);
950 query
.setMaxResults(limit
);
952 result
.addAll(query
.list());
957 AuditQuery query
= getAuditReader().createQuery().forEntitiesAtRevision(clazz
,auditEvent
.getRevisionNumber());
958 return query
.getResultList();
963 public UUID
delete(TaxonBase taxonBase
) throws DataAccessException
{
964 if (taxonBase
== null){
965 logger
.warn("TaxonBase was 'null'");
969 // Merge the object in if it is detached
971 // I think this is preferable to catching lazy initialization errors
972 // as that solution only swallows and hides the exception, but doesn't
973 // actually solve it.
974 getSession().merge(taxonBase
);
976 taxonBase
.removeSources();
978 if (taxonBase
instanceof Taxon
){ // is Taxon
979 for (Iterator
<TaxonRelationship
> iterator
= ((Taxon
)taxonBase
).getRelationsFromThisTaxon().iterator(); iterator
.hasNext();){
980 TaxonRelationship relationFromThisTaxon
= iterator
.next();
982 // decrease children count of taxonomic parent by one
983 if (relationFromThisTaxon
.getType().equals(TaxonRelationshipType
.TAXONOMICALLY_INCLUDED_IN())) {
984 Taxon toTaxon
= relationFromThisTaxon
.getToTaxon(); // parent
985 if (toTaxon
!= null) {
986 toTaxon
.setTaxonomicChildrenCount(toTaxon
.getTaxonomicChildrenCount() - 1);
992 return super.delete(taxonBase
);
997 public List
<TaxonBase
> findByNameTitleCache(boolean doTaxa
, boolean doSynonyms
, String queryString
, Classification classification
, MatchMode matchMode
, Set
<NamedArea
> namedAreas
, Integer pageNumber
, Integer pageSize
, List
<String
> propertyPaths
) {
999 boolean doCount
= false;
1000 Query query
= prepareTaxaByName(doTaxa
, doSynonyms
, false, "titleCache", queryString
, classification
, matchMode
, namedAreas
, pageSize
, pageNumber
, doCount
);
1002 List
<TaxonBase
> results
= query
.list();
1003 defaultBeanInitializer
.initializeAll(results
, propertyPaths
);
1006 return new ArrayList
<TaxonBase
>();
1011 public TaxonBase
findByUuid(UUID uuid
, List
<Criterion
> criteria
, List
<String
> propertyPaths
) {
1013 Criteria crit
= getSession().createCriteria(type
);
1016 crit
.add(Restrictions
.eq("uuid", uuid
));
1018 logger
.warn("UUID is NULL");
1021 if(criteria
!= null){
1022 for (Criterion criterion
: criteria
) {
1023 crit
.add(criterion
);
1026 crit
.addOrder(Order
.asc("uuid"));
1028 List
<?
extends TaxonBase
> results
= crit
.list();
1029 if (results
.size() == 1) {
1030 defaultBeanInitializer
.initializeAll(results
, propertyPaths
);
1031 TaxonBase taxon
= results
.iterator().next();
1033 } else if (results
.size() > 1) {
1034 logger
.error("Multiple results for UUID: " + uuid
);
1035 } else if (results
.size() == 0) {
1036 logger
.info("No results for UUID: " + uuid
);
1043 public List
<?
extends TaxonBase
> findByUuids(List
<UUID
> uuids
, List
<Criterion
> criteria
, List
<String
> propertyPaths
) {
1045 Criteria crit
= getSession().createCriteria(type
);
1047 if (uuids
!= null) {
1048 crit
.add(Restrictions
.in("uuid", uuids
));
1050 logger
.warn("List<UUID> uuids is NULL");
1053 if(criteria
!= null){
1054 for (Criterion criterion
: criteria
) {
1055 crit
.add(criterion
);
1058 crit
.addOrder(Order
.asc("uuid"));
1060 List
<?
extends TaxonBase
> results
= crit
.list();
1062 defaultBeanInitializer
.initializeAll(results
, propertyPaths
);
1067 public int countMatchesByName(String queryString
, MatchMode matchMode
, boolean onlyAcccepted
) {
1068 checkNotInPriorView("TaxonDaoHibernateImpl.countMatchesByName(String queryString, ITitledDao.MATCH_MODE matchMode, boolean onlyAcccepted)");
1069 Criteria crit
= getSession().createCriteria(type
);
1070 crit
.add(Restrictions
.ilike("titleCache", matchMode
.queryStringFrom(queryString
)));
1071 crit
.setProjection(Projections
.rowCount());
1072 int result
= ((Number
)crit
.list().get(0)).intValue();
1078 public int countMatchesByName(String queryString
, MatchMode matchMode
, boolean onlyAcccepted
, List
<Criterion
> criteria
) {
1079 checkNotInPriorView("TaxonDaoHibernateImpl.countMatchesByName(String queryString, ITitledDao.MATCH_MODE matchMode, boolean onlyAcccepted, List<Criterion> criteria)");
1080 Criteria crit
= getSession().createCriteria(type
);
1081 crit
.add(Restrictions
.ilike("titleCache", matchMode
.queryStringFrom(queryString
)));
1082 if(criteria
!= null){
1083 for (Criterion criterion
: criteria
) {
1084 crit
.add(criterion
);
1087 crit
.setProjection(Projections
.rowCount());
1088 int result
= ((Number
)crit
.list().get(0)).intValue();
1093 public int countTaxonRelationships(Taxon taxon
, TaxonRelationshipType type
, Direction direction
) {
1094 AuditEvent auditEvent
= getAuditEventFromContext();
1095 if(auditEvent
.equals(AuditEvent
.CURRENT_VIEW
)) {
1099 query
= getSession().createQuery("select count(taxonRelationship) from TaxonRelationship taxonRelationship where taxonRelationship."+direction
+" = :relatedTaxon");
1101 query
= getSession().createQuery("select count(taxonRelationship) from TaxonRelationship taxonRelationship where taxonRelationship."+direction
+" = :relatedTaxon and taxonRelationship.type = :type");
1102 query
.setParameter("type",type
);
1104 query
.setParameter("relatedTaxon", taxon
);
1106 return ((Long
)query
.uniqueResult()).intValue();
1108 AuditQuery query
= getAuditReader().createQuery().forEntitiesAtRevision(TaxonRelationship
.class,auditEvent
.getRevisionNumber());
1109 query
.add(AuditEntity
.relatedId(direction
.toString()).eq(taxon
.getId()));
1110 query
.addProjection(AuditEntity
.id().count());
1113 query
.add(AuditEntity
.relatedId("type").eq(type
.getId()));
1116 return ((Long
)query
.getSingleResult()).intValue();
1121 public int countSynonyms(Taxon taxon
, SynonymRelationshipType type
) {
1122 AuditEvent auditEvent
= getAuditEventFromContext();
1123 if(auditEvent
.equals(AuditEvent
.CURRENT_VIEW
)) {
1124 Criteria criteria
= getSession().createCriteria(SynonymRelationship
.class);
1126 criteria
.add(Restrictions
.eq("relatedTo", taxon
));
1128 criteria
.add(Restrictions
.eq("type", type
));
1130 criteria
.setProjection(Projections
.rowCount());
1131 return ((Number
)criteria
.uniqueResult()).intValue();
1133 AuditQuery query
= getAuditReader().createQuery().forEntitiesAtRevision(SynonymRelationship
.class,auditEvent
.getRevisionNumber());
1134 query
.add(AuditEntity
.relatedId("relatedTo").eq(taxon
.getId()));
1135 query
.addProjection(AuditEntity
.id().count());
1138 query
.add(AuditEntity
.relatedId("type").eq(type
.getId()));
1141 return ((Long
)query
.getSingleResult()).intValue();
1146 public int countSynonyms(Synonym synonym
, SynonymRelationshipType type
) {
1147 AuditEvent auditEvent
= getAuditEventFromContext();
1148 if(auditEvent
.equals(AuditEvent
.CURRENT_VIEW
)) {
1149 Criteria criteria
= getSession().createCriteria(SynonymRelationship
.class);
1151 criteria
.add(Restrictions
.eq("relatedFrom", synonym
));
1153 criteria
.add(Restrictions
.eq("type", type
));
1156 criteria
.setProjection(Projections
.rowCount());
1157 return ((Number
)criteria
.uniqueResult()).intValue();
1159 AuditQuery query
= getAuditReader().createQuery().forEntitiesAtRevision(SynonymRelationship
.class,auditEvent
.getRevisionNumber());
1160 query
.add(AuditEntity
.relatedId("relatedFrom").eq(synonym
.getId()));
1161 query
.addProjection(AuditEntity
.id().count());
1164 query
.add(AuditEntity
.relatedId("type").eq(type
.getId()));
1167 return ((Long
)query
.getSingleResult()).intValue();
1172 public int countTaxaByName(Class
<?
extends TaxonBase
> clazz
, String genusOrUninomial
, String infraGenericEpithet
, String specificEpithet
, String infraSpecificEpithet
, Rank rank
) {
1173 checkNotInPriorView("TaxonDaoHibernateImpl.countTaxaByName(Boolean accepted, String genusOrUninomial, String infraGenericEpithet, String specificEpithet, String infraSpecificEpithet, Rank rank)");
1174 Criteria criteria
= null;
1176 criteria
= getSession().createCriteria(clazz
);
1178 criteria
.setFetchMode( "name", FetchMode
.JOIN
);
1179 criteria
.createAlias("name", "name");
1181 if(genusOrUninomial
== null) {
1182 criteria
.add(Restrictions
.isNull("name.genusOrUninomial"));
1183 } else if(!genusOrUninomial
.equals("*")) {
1184 criteria
.add(Restrictions
.eq("name.genusOrUninomial", genusOrUninomial
));
1187 if(infraGenericEpithet
== null) {
1188 criteria
.add(Restrictions
.isNull("name.infraGenericEpithet"));
1189 } else if(!infraGenericEpithet
.equals("*")) {
1190 criteria
.add(Restrictions
.eq("name.infraGenericEpithet", infraGenericEpithet
));
1193 if(specificEpithet
== null) {
1194 criteria
.add(Restrictions
.isNull("name.specificEpithet"));
1195 } else if(!specificEpithet
.equals("*")) {
1196 criteria
.add(Restrictions
.eq("name.specificEpithet", specificEpithet
));
1200 if(infraSpecificEpithet
== null) {
1201 criteria
.add(Restrictions
.isNull("name.infraSpecificEpithet"));
1202 } else if(!infraSpecificEpithet
.equals("*")) {
1203 criteria
.add(Restrictions
.eq("name.infraSpecificEpithet", infraSpecificEpithet
));
1207 criteria
.add(Restrictions
.eq("name.rank", rank
));
1210 criteria
.setProjection(Projections
.projectionList().add(Projections
.rowCount()));
1212 return ((Number
)criteria
.uniqueResult()).intValue();
1216 public List
<TaxonBase
> findTaxaByName(Class
<?
extends TaxonBase
> clazz
, String genusOrUninomial
, String infraGenericEpithet
, String specificEpithet
, String infraSpecificEpithet
, String authorship
, Rank rank
, Integer pageSize
, Integer pageNumber
) {
1217 checkNotInPriorView("TaxonDaoHibernateImpl.findTaxaByName(Boolean accepted, String genusOrUninomial, String infraGenericEpithet, String specificEpithet, String infraSpecificEpithet, String authorship, Rank rank, Integer pageSize, Integer pageNumber)");
1218 Criteria criteria
= null;
1220 criteria
= getSession().createCriteria(TaxonBase
.class);
1222 criteria
= getSession().createCriteria(clazz
);
1224 criteria
.setFetchMode( "name", FetchMode
.JOIN
);
1225 criteria
.createAlias("name", "name");
1227 if(genusOrUninomial
== null) {
1228 criteria
.add(Restrictions
.isNull("name.genusOrUninomial"));
1229 } else if(!genusOrUninomial
.equals("*")) {
1230 criteria
.add(Restrictions
.eq("name.genusOrUninomial", genusOrUninomial
));
1233 if(infraGenericEpithet
== null) {
1234 criteria
.add(Restrictions
.isNull("name.infraGenericEpithet"));
1235 } else if(!infraGenericEpithet
.equals("*")) {
1236 criteria
.add(Restrictions
.eq("name.infraGenericEpithet", infraGenericEpithet
));
1239 if(specificEpithet
== null) {
1240 criteria
.add(Restrictions
.isNull("name.specificEpithet"));
1241 } else if(!specificEpithet
.equals("*")) {
1242 criteria
.add(Restrictions
.eq("name.specificEpithet", specificEpithet
));
1246 if(infraSpecificEpithet
== null) {
1247 criteria
.add(Restrictions
.isNull("name.infraSpecificEpithet"));
1248 } else if(!infraSpecificEpithet
.equals("*")) {
1249 criteria
.add(Restrictions
.eq("name.infraSpecificEpithet", infraSpecificEpithet
));
1252 if(authorship
== null) {
1253 criteria
.add(Restrictions
.eq("name.authorshipCache", ""));
1254 } else if(!authorship
.equals("*")) {
1255 criteria
.add(Restrictions
.eq("name.authorshipCache", authorship
));
1259 criteria
.add(Restrictions
.eq("name.rank", rank
));
1262 if(pageSize
!= null) {
1263 criteria
.setMaxResults(pageSize
);
1264 if(pageNumber
!= null) {
1265 criteria
.setFirstResult(pageNumber
* pageSize
);
1267 criteria
.setFirstResult(0);
1271 return criteria
.list();
1275 public List
<TaxonRelationship
> getTaxonRelationships(Taxon taxon
, TaxonRelationshipType type
,
1276 Integer pageSize
, Integer pageNumber
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
, Direction direction
) {
1278 AuditEvent auditEvent
= getAuditEventFromContext();
1279 if(auditEvent
.equals(AuditEvent
.CURRENT_VIEW
)) {
1281 Criteria criteria
= getSession().createCriteria(TaxonRelationship
.class);
1283 if(direction
!= null) {
1284 criteria
.add(Restrictions
.eq(direction
.name(), taxon
));
1286 criteria
.add(Restrictions
.or(
1287 Restrictions
.eq(Direction
.relatedFrom
.name(), taxon
),
1288 Restrictions
.eq(Direction
.relatedTo
.name(), taxon
))
1293 criteria
.add(Restrictions
.eq("type", type
));
1296 addOrder(criteria
,orderHints
);
1298 if(pageSize
!= null) {
1299 criteria
.setMaxResults(pageSize
);
1300 if(pageNumber
!= null) {
1301 criteria
.setFirstResult(pageNumber
* pageSize
);
1303 criteria
.setFirstResult(0);
1307 List
<TaxonRelationship
> result
= criteria
.list();
1308 defaultBeanInitializer
.initializeAll(result
, propertyPaths
);
1312 AuditQuery query
= getAuditReader().createQuery().forEntitiesAtRevision(TaxonRelationship
.class,auditEvent
.getRevisionNumber());
1313 query
.add(AuditEntity
.relatedId("relatedTo").eq(taxon
.getId()));
1316 query
.add(AuditEntity
.relatedId("type").eq(type
.getId()));
1319 if(pageSize
!= null) {
1320 query
.setMaxResults(pageSize
);
1321 if(pageNumber
!= null) {
1322 query
.setFirstResult(pageNumber
* pageSize
);
1324 query
.setFirstResult(0);
1328 List
<TaxonRelationship
> result
= query
.getResultList();
1329 defaultBeanInitializer
.initializeAll(result
, propertyPaths
);
1331 // Ugly, but for now, there is no way to sort on a related entity property in Envers,
1332 // and we can't live without this functionality in CATE as it screws up the whole
1334 if(orderHints
!= null && !orderHints
.isEmpty()) {
1335 SortedSet
<TaxonRelationship
> sortedList
= new TreeSet
<TaxonRelationship
>(new TaxonRelationshipFromTaxonComparator());
1336 sortedList
.addAll(result
);
1337 return new ArrayList
<TaxonRelationship
>(sortedList
);
1344 class TaxonRelationshipFromTaxonComparator
implements Comparator
<TaxonRelationship
> {
1347 public int compare(TaxonRelationship o1
, TaxonRelationship o2
) {
1348 return o1
.getFromTaxon().getTitleCache().compareTo(o2
.getFromTaxon().getTitleCache());
1353 class SynonymRelationshipFromTaxonComparator
implements Comparator
<SynonymRelationship
> {
1356 public int compare(SynonymRelationship o1
, SynonymRelationship o2
) {
1357 return o1
.getSynonym().getTitleCache().compareTo(o2
.getSynonym().getTitleCache());
1363 public List
<SynonymRelationship
> getSynonyms(Taxon taxon
, SynonymRelationshipType type
, Integer pageSize
, Integer pageNumber
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
1364 AuditEvent auditEvent
= getAuditEventFromContext();
1365 if(auditEvent
.equals(AuditEvent
.CURRENT_VIEW
)) {
1366 Criteria criteria
= getSession().createCriteria(SynonymRelationship
.class);
1368 criteria
.add(Restrictions
.eq("relatedTo", taxon
));
1370 criteria
.add(Restrictions
.eq("type", type
));
1373 addOrder(criteria
,orderHints
);
1375 if(pageSize
!= null) {
1376 criteria
.setMaxResults(pageSize
);
1377 if(pageNumber
!= null) {
1378 criteria
.setFirstResult(pageNumber
* pageSize
);
1380 criteria
.setFirstResult(0);
1384 List
<SynonymRelationship
> result
= criteria
.list();
1385 defaultBeanInitializer
.initializeAll(result
, propertyPaths
);
1389 AuditQuery query
= getAuditReader().createQuery().forEntitiesAtRevision(SynonymRelationship
.class,auditEvent
.getRevisionNumber());
1390 query
.add(AuditEntity
.relatedId("relatedTo").eq(taxon
.getId()));
1393 query
.add(AuditEntity
.relatedId("type").eq(type
.getId()));
1396 if(pageSize
!= null) {
1397 query
.setMaxResults(pageSize
);
1398 if(pageNumber
!= null) {
1399 query
.setFirstResult(pageNumber
* pageSize
);
1401 query
.setFirstResult(0);
1405 List
<SynonymRelationship
> result
= query
.getResultList();
1406 defaultBeanInitializer
.initializeAll(result
, propertyPaths
);
1413 public List
<SynonymRelationship
> getSynonyms(Synonym synonym
, SynonymRelationshipType type
, Integer pageSize
, Integer pageNumber
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
1414 AuditEvent auditEvent
= getAuditEventFromContext();
1415 if(auditEvent
.equals(AuditEvent
.CURRENT_VIEW
)) {
1416 Criteria criteria
= getSession().createCriteria(SynonymRelationship
.class);
1418 criteria
.add(Restrictions
.eq("relatedFrom", synonym
));
1420 criteria
.add(Restrictions
.eq("type", type
));
1423 addOrder(criteria
,orderHints
);
1425 if(pageSize
!= null) {
1426 criteria
.setMaxResults(pageSize
);
1427 if(pageNumber
!= null) {
1428 criteria
.setFirstResult(pageNumber
* pageSize
);
1430 criteria
.setFirstResult(0);
1434 List
<SynonymRelationship
> result
= criteria
.list();
1435 defaultBeanInitializer
.initializeAll(result
, propertyPaths
);
1439 AuditQuery query
= getAuditReader().createQuery().forEntitiesAtRevision(SynonymRelationship
.class,auditEvent
.getRevisionNumber());
1440 query
.add(AuditEntity
.relatedId("relatedFrom").eq(synonym
.getId()));
1443 query
.add(AuditEntity
.relatedId("type").eq(type
.getId()));
1446 if(pageSize
!= null) {
1447 query
.setMaxResults(pageSize
);
1448 if(pageNumber
!= null) {
1449 query
.setFirstResult(pageNumber
* pageSize
);
1451 query
.setFirstResult(0);
1455 List
<SynonymRelationship
> result
= query
.getResultList();
1456 defaultBeanInitializer
.initializeAll(result
, propertyPaths
);
1463 public void rebuildIndex() {
1464 FullTextSession fullTextSession
= Search
.getFullTextSession(getSession());
1466 for(TaxonBase taxonBase
: list(null,null)) { // re-index all taxon base
1467 Hibernate
.initialize(taxonBase
.getName());
1468 fullTextSession
.index(taxonBase
);
1470 fullTextSession
.flushToIndexes();
1474 public String
suggestQuery(String queryString
) {
1475 throw new RuntimeException("Query suggestion currently not implemented in TaxonDaoHibernateImpl");
1476 // checkNotInPriorView("TaxonDaoHibernateImpl.suggestQuery(String queryString)");
1477 // String alternativeQueryString = null;
1478 // if (alternativeSpellingSuggestionParser != null) {
1481 // alternativeSpellingSuggestionParser.parse(queryString);
1482 // org.apache.lucene.search.Query alternativeQuery = alternativeSpellingSuggestionParser.suggest(queryString);
1483 // if (alternativeQuery != null) {
1484 // alternativeQueryString = alternativeQuery
1485 // .toString("name.titleCache");
1488 // } catch (ParseException e) {
1489 // throw new QueryParseException(e, queryString);
1492 // return alternativeQueryString;
1496 public List
<Taxon
> listAcceptedTaxaFor(Synonym synonym
, Classification classificationFilter
, Integer pageSize
, Integer pageNumber
,
1497 List
<OrderHint
> orderHints
, List
<String
> propertyPaths
){
1499 String hql
= prepareListAcceptedTaxaFor(classificationFilter
, orderHints
, false);
1501 Query query
= getSession().createQuery(hql
);
1503 query
.setParameter("synonym", synonym
);
1505 if(classificationFilter
!= null){
1506 query
.setParameter("classificationFilter", classificationFilter
);
1510 if(pageSize
!= null) {
1511 query
.setMaxResults(pageSize
);
1512 if(pageNumber
!= null) {
1513 query
.setFirstResult(pageNumber
* pageSize
);
1517 @SuppressWarnings("unchecked")
1518 List
<Taxon
> result
= query
.list();
1520 defaultBeanInitializer
.initializeAll(result
, propertyPaths
);
1527 public long countAcceptedTaxaFor(Synonym synonym
, Classification classificationFilter
){
1529 String hql
= prepareListAcceptedTaxaFor(classificationFilter
, null, true);
1531 Query query
= getSession().createQuery(hql
);
1533 query
.setParameter("synonym", synonym
);
1535 if(classificationFilter
!= null){
1536 query
.setParameter("classificationFilter", classificationFilter
);
1539 Long count
= Long
.parseLong(query
.uniqueResult().toString());
1547 * @param classificationFilter
1551 private String
prepareListAcceptedTaxaFor(Classification classificationFilter
, List
<OrderHint
> orderHints
, boolean doCount
) {
1554 String hqlSelect
= "select " + (doCount?
"count(taxon)" : "taxon") + " from Taxon as taxon left join taxon.synonymRelations as synRel ";
1555 String hqlWhere
= " where synRel.relatedFrom = :synonym";
1557 if(classificationFilter
!= null){
1558 hqlSelect
+= " left join taxon.taxonNodes AS taxonNode";
1559 hqlWhere
+= " and taxonNode.classification = :classificationFilter";
1561 hql
= hqlSelect
+ hqlWhere
+ orderByClause(orderHints
, "taxon");
1565 public List
<UuidAndTitleCache
<TaxonNode
>> getTaxonNodeUuidAndTitleCacheOfAcceptedTaxaByClassification(Classification classification
, Integer limit
, String pattern
) {
1566 int classificationId
= classification
.getId();
1567 // StringBuffer excludeUuids = new StringBuffer();
1569 String queryString
= "SELECT nodes.uuid, nodes.id, taxon.titleCache FROM TaxonNode AS nodes JOIN nodes.taxon as taxon WHERE nodes.classification.id = " + classificationId
;
1571 if (pattern
!= null){
1572 pattern
= pattern
.replace("*", "%");
1573 queryString
= queryString
+ " AND taxon.titleCache like (:pattern)" ;
1576 Query query
= getSession().createQuery(queryString
);
1580 query
.setMaxResults(limit
);
1583 if (pattern
!= null){
1584 query
.setParameter("pattern", pattern
);
1586 @SuppressWarnings("unchecked")
1587 List
<Object
[]> result
= query
.list();
1589 if(result
.size() == 0){
1592 List
<UuidAndTitleCache
<TaxonNode
>> list
= new ArrayList
<UuidAndTitleCache
<TaxonNode
>>(result
.size());
1594 for (Object object
: result
){
1596 Object
[] objectArray
= (Object
[]) object
;
1598 UUID uuid
= (UUID
)objectArray
[0];
1599 Integer id
= (Integer
) objectArray
[1];
1600 String titleCache
= (String
) objectArray
[2];
1602 list
.add(new UuidAndTitleCache
<TaxonNode
>(TaxonNode
.class, uuid
, id
, titleCache
));
1611 public TaxonBase
find(LSID lsid
) {
1612 TaxonBase
<?
> taxonBase
= super.find(lsid
);
1613 if(taxonBase
!= null) {
1614 List
<String
> propertyPaths
= new ArrayList
<String
>();
1615 propertyPaths
.add("createdBy");
1616 propertyPaths
.add("updatedBy");
1617 propertyPaths
.add("name");
1618 propertyPaths
.add("sec");
1619 propertyPaths
.add("relationsToThisTaxon");
1620 propertyPaths
.add("relationsToThisTaxon.fromTaxon");
1621 propertyPaths
.add("relationsToThisTaxon.toTaxon");
1622 propertyPaths
.add("relationsFromThisTaxon");
1623 propertyPaths
.add("relationsFromThisTaxon.toTaxon");
1624 propertyPaths
.add("relationsToThisTaxon.type");
1625 propertyPaths
.add("synonymRelations");
1626 propertyPaths
.add("synonymRelations.synonym");
1627 propertyPaths
.add("synonymRelations.type");
1628 propertyPaths
.add("descriptions");
1630 defaultBeanInitializer
.initialize(taxonBase
, propertyPaths
);
1635 public List
<TaxonBase
> getTaxaByCommonName(String queryString
,
1636 Classification classification
, MatchMode matchMode
,
1637 Set
<NamedArea
> namedAreas
, Integer pageSize
, Integer pageNumber
) {
1638 logger
.warn("getTaxaByCommonName not yet implemented.");
1645 /* private void xxx(List<SynonymRelationship> synonymRelationships, HashMap <UUID, ZoologicalName> zooHashMap, SynonymRelationshipType type, String addString){
1647 for (SynonymRelationship synonymRelation:synonymRelationships){
1648 TaxonNameBase synName;
1649 NonViralName inferredSynName;
1650 Synonym syn = synonymRelation.getSynonym();
1651 HibernateProxyHelper.deproxy(syn);
1653 synName = syn.getName();
1654 ZoologicalName zooName = zooHashMap.get(synName.getUuid());
1655 String synGenusName = zooName.getGenusOrUninomial();
1657 switch(type.getId()){
1658 case SynonymRelationshipType.INFERRED_EPITHET_OF().getId():
1659 inferredSynName.setSpecificEpithet(addString);
1661 case SynonymRelationshipType.INFERRED_GENUS_OF().getId():
1663 case SynonymRelationshipType.POTENTIAL_COMBINATION_OF().getId():
1667 if (!synonymsGenus.contains(synGenusName)){
1668 synonymsGenus.add(synGenusName);
1670 inferredSynName = NonViralName.NewInstance(Rank.SPECIES());
1671 inferredSynName.setSpecificEpithet(epithetOfTaxon);
1672 inferredSynName.setGenusOrUninomial(synGenusName);
1673 inferredEpithet = Synonym.NewInstance(inferredSynName, null);
1674 taxon.addSynonym(inferredEpithet, SynonymRelationshipType.INFERRED_GENUS_OF());
1675 inferredSynonyms.add(inferredEpithet);
1676 inferredSynName.generateTitle();
1677 taxonNames.add(inferredSynName.getNameCache());
1681 if (!taxonNames.isEmpty()){
1682 List<String> synNotInCDM = this.taxaByNameNotInDB(taxonNames);
1683 ZoologicalName name;
1684 if (!synNotInCDM.isEmpty()){
1685 for (Synonym syn :inferredSynonyms){
1686 name =zooHashMap.get(syn.getName().getUuid());
1687 if (!synNotInCDM.contains(name.getNameCache())){
1688 inferredSynonyms.remove(syn);
1696 public int countAllRelationships() {
1697 return countAllRelationships(null);
1701 //FIXME add to interface or make private
1702 public int countAllRelationships(Class
<?
extends RelationshipBase
> clazz
) {
1703 if (clazz
!= null && ! TaxonRelationship
.class.isAssignableFrom(clazz
) && ! SynonymRelationship
.class.isAssignableFrom(clazz
) ){
1704 throw new RuntimeException("Class must be assignable by a taxon or snonym relation");
1708 if (clazz
== null || TaxonRelationship
.class.isAssignableFrom(clazz
)){
1709 String hql
= " SELECT count(rel) FROM TaxonRelationship rel";
1710 size
+= (Long
)getSession().createQuery(hql
).list().get(0);
1712 if (clazz
== null || SynonymRelationship
.class.isAssignableFrom(clazz
)){
1713 String hql
= " SELECT count(rel) FROM SynonymRelationship rel";
1714 size
+= (Long
)getSession().createQuery(hql
).list().get(0);
1720 public List
<String
> taxaByNameNotInDB(List
<String
> taxonNames
){
1721 List
<TaxonBase
> notInDB
= new ArrayList
<TaxonBase
>();
1722 //get all taxa, already in db
1723 Query query
= getSession().createQuery("from TaxonNameBase t where t.nameCache IN (:taxonList)");
1724 query
.setParameterList("taxonList", taxonNames
);
1725 List
<TaxonNameBase
> taxaInDB
= query
.list();
1726 //compare the original list with the result of the query
1727 for (TaxonNameBase taxonName
: taxaInDB
){
1728 if (taxonName
.isInstanceOf(NonViralName
.class)) {
1729 NonViralName nonViralName
= CdmBase
.deproxy(taxonName
, NonViralName
.class);
1730 String nameCache
= nonViralName
.getNameCache();
1731 if (taxonNames
.contains(nameCache
)){
1732 taxonNames
.remove(nameCache
);
1740 //TODO: mal nur mit UUID probieren (ohne fetch all properties), vielleicht geht das schneller?
1742 public List
<UUID
> findIdenticalTaxonNameIds(List
<String
> propertyPaths
){
1743 Query query
=getSession().createQuery("select tmb2 from ZoologicalName tmb, ZoologicalName tmb2 fetch all properties where tmb.id != tmb2.id and tmb.nameCache = tmb2.nameCache");
1744 List
<UUID
> zooNames
= query
.list();
1751 public List
<TaxonNameBase
> findIdenticalTaxonNames(List
<String
> propertyPaths
) {
1753 Query query
=getSession().createQuery("select tmb2 from ZoologicalName tmb, ZoologicalName tmb2 fetch all properties where tmb.id != tmb2.id and tmb.nameCache = tmb2.nameCache");
1755 List
<TaxonNameBase
> zooNames
= query
.list();
1757 TaxonNameComparator taxComp
= new TaxonNameComparator();
1758 Collections
.sort(zooNames
, taxComp
);
1760 for (TaxonNameBase taxonNameBase
: zooNames
){
1761 defaultBeanInitializer
.initialize(taxonNameBase
, propertyPaths
);
1768 public List
<TaxonNameBase
> findIdenticalNamesNew(List
<String
> propertyPaths
){
1770 //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)
1771 Query query
= getSession().createQuery("Select id from Reference where titleCache like 'Fauna Europaea database'");
1772 List
<String
> secRefFauna
= query
.list();
1773 query
= getSession().createQuery("Select id from Reference where titleCache like 'ERMS'");
1774 List
<String
> secRefErms
= query
.list();
1775 //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");
1776 //Get all names of fauna europaea
1777 query
= getSession().createQuery("select zn.nameCache from ZoologicalName zn, TaxonBase tb where tb.name = zn and tb.sec.id = :secRefFauna");
1778 query
.setParameter("secRefFauna", secRefFauna
.get(0));
1779 List
<String
> namesFauna
= query
.list();
1781 //Get all names of erms
1783 query
= getSession().createQuery("select zn.nameCache from ZoologicalName zn, TaxonBase tb where tb.name = zn and tb.sec.id = :secRefErms");
1784 query
.setParameter("secRefErms", secRefErms
.get(0));
1786 List
<String
> namesErms
= query
.list();
1787 /*TaxonNameComparator comp = new TaxonNameComparator();
1788 Collections.sort(namesFauna);
1789 Collections.sort(namesErms);
1791 List
<String
> identicalNames
= new ArrayList
<String
>();
1792 String predecessor
= "";
1794 for (String nameFauna
: namesFauna
){
1795 if (namesErms
.contains(nameFauna
)){
1796 identicalNames
.add(nameFauna
);
1801 query
= getSession().createQuery("from ZoologicalName zn where zn.nameCache IN (:identicalNames)");
1802 query
.setParameterList("identicalNames", identicalNames
);
1803 List
<TaxonNameBase
> result
= query
.list();
1804 TaxonNameBase temp
= result
.get(0);
1806 Iterator
<OriginalSourceBase
> sources
= temp
.getSources().iterator();
1808 TaxonNameComparator taxComp
= new TaxonNameComparator();
1809 Collections
.sort(result
, taxComp
);
1810 defaultBeanInitializer
.initializeAll(result
, propertyPaths
);
1818 public String
getPhylumName(TaxonNameBase name
){
1819 List results
= new ArrayList();
1821 Query query
= getSession().createSQLQuery("select getPhylum("+ name
.getId()+");");
1822 results
= query
.list();
1823 }catch(Exception e
){
1824 System
.err
.println(name
.getUuid());
1827 System
.err
.println("phylum of "+ name
.getTitleCache() );
1828 return (String
)results
.get(0);
1833 public long countTaxaByCommonName(String searchString
,
1834 Classification classification
, MatchMode matchMode
,
1835 Set
<NamedArea
> namedAreas
) {
1836 boolean doCount
= true;
1837 Query query
= prepareTaxaByCommonName(searchString
, classification
, matchMode
, namedAreas
, null, null, doCount
, false);
1838 if (query
!= null && !query
.list().isEmpty()) {
1839 Object o
= query
.uniqueResult();
1848 public long deleteSynonymRelationships(Synonym synonym
, Taxon taxon
) {
1850 String hql
= "delete SynonymRelationship sr where sr.relatedFrom = :syn ";
1852 hql
+= " and sr.relatedTo = :taxon";
1854 Session session
= this.getSession();
1855 Query q
= session
.createQuery(hql
);
1857 q
.setParameter("syn", synonym
);
1859 q
.setParameter("taxon", taxon
);
1861 long result
= q
.executeUpdate();
1868 public Integer
countSynonymRelationships(TaxonBase taxonBase
,
1869 SynonymRelationshipType type
, Direction relatedfrom
) {
1870 AuditEvent auditEvent
= getAuditEventFromContext();
1871 if(auditEvent
.equals(AuditEvent
.CURRENT_VIEW
)) {
1875 query
= getSession().createQuery("select count(synonymRelationship) from SynonymRelationship synonymRelationship where synonymRelationship."+relatedfrom
+" = :relatedSynonym");
1877 query
= getSession().createQuery("select count(synonymRelationship) from SynonymRelationship synonymRelationship where synonymRelationship."+relatedfrom
+" = :relatedSynonym and synonymRelationship.type = :type");
1878 query
.setParameter("type",type
);
1880 query
.setParameter("relatedTaxon", taxonBase
);
1882 return ((Long
)query
.uniqueResult()).intValue();
1884 AuditQuery query
= getAuditReader().createQuery().forEntitiesAtRevision(TaxonRelationship
.class,auditEvent
.getRevisionNumber());
1885 query
.add(AuditEntity
.relatedId(relatedfrom
.toString()).eq(taxonBase
.getId()));
1886 query
.addProjection(AuditEntity
.id().count());
1889 query
.add(AuditEntity
.relatedId("type").eq(type
.getId()));
1892 return ((Long
)query
.getSingleResult()).intValue();
1898 public List
<SynonymRelationship
> getSynonymRelationships(TaxonBase taxonBase
,
1899 SynonymRelationshipType type
, Integer pageSize
, Integer pageNumber
,
1900 List
<OrderHint
> orderHints
, List
<String
> propertyPaths
,
1901 Direction direction
) {
1903 AuditEvent auditEvent
= getAuditEventFromContext();
1904 if(auditEvent
.equals(AuditEvent
.CURRENT_VIEW
)) {
1905 Criteria criteria
= getSession().createCriteria(SynonymRelationship
.class);
1907 if (direction
.equals(Direction
.relatedTo
)){
1908 criteria
.add(Restrictions
.eq("relatedTo", taxonBase
));
1910 criteria
.add(Restrictions
.eq("relatedFrom", taxonBase
));
1913 criteria
.add(Restrictions
.eq("type", type
));
1916 addOrder(criteria
,orderHints
);
1918 if(pageSize
!= null) {
1919 criteria
.setMaxResults(pageSize
);
1920 if(pageNumber
!= null) {
1921 criteria
.setFirstResult(pageNumber
* pageSize
);
1923 criteria
.setFirstResult(0);
1927 List
<SynonymRelationship
> result
= criteria
.list();
1928 defaultBeanInitializer
.initializeAll(result
, propertyPaths
);
1932 AuditQuery query
= getAuditReader().createQuery().forEntitiesAtRevision(TaxonRelationship
.class,auditEvent
.getRevisionNumber());
1934 if (direction
.equals(Direction
.relatedTo
)){
1935 query
.add(AuditEntity
.relatedId("relatedTo").eq(taxonBase
.getId()));
1937 query
.add(AuditEntity
.relatedId("relatedFrom").eq(taxonBase
.getId()));
1941 query
.add(AuditEntity
.relatedId("type").eq(type
.getId()));
1944 if(pageSize
!= null) {
1945 query
.setMaxResults(pageSize
);
1946 if(pageNumber
!= null) {
1947 query
.setFirstResult(pageNumber
* pageSize
);
1949 query
.setFirstResult(0);
1953 List
<SynonymRelationship
> result
= query
.getResultList();
1954 defaultBeanInitializer
.initializeAll(result
, propertyPaths
);
1956 // Ugly, but for now, there is no way to sort on a related entity property in Envers,
1957 // and we can't live without this functionality in CATE as it screws up the whole
1959 if(orderHints
!= null && !orderHints
.isEmpty()) {
1960 SortedSet
<SynonymRelationship
> sortedList
= new TreeSet
<SynonymRelationship
>(new SynonymRelationshipFromTaxonComparator());
1961 sortedList
.addAll(result
);
1962 return new ArrayList
<SynonymRelationship
>(sortedList
);
1970 public List
<UuidAndTitleCache
<TaxonBase
>> getUuidAndTitleCache(Integer limit
, String pattern
, boolean isTaxon
) {
1973 className
= Taxon
.class.getSimpleName();
1975 className
= Synonym
.class.getSimpleName();
1979 if(pattern
== null){
1980 queryString
= String
.format("select uuid, id, titleCache from %s where DTYPE = '%s' ", type
.getSimpleName(), className
);
1982 queryString
= String
.format("select uuid, id, titleCache from %s where DTYPE = '%s' and titleCache like :pattern", type
.getSimpleName(), className
);
1984 Query query
= getSession().createQuery(queryString
);
1985 if (pattern
!= null){
1986 pattern
= pattern
.replace("*", "%");
1987 pattern
= pattern
.replace("?", "_");
1988 pattern
= pattern
+ "%";
1989 pattern
= pattern
.replace("?", "_");
1990 query
.setParameter("pattern", pattern
);
1993 query
.setMaxResults(limit
);
1996 List
<UuidAndTitleCache
<TaxonBase
>> result
= getUuidAndTitleCache(query
);
2001 public List
<UuidAndTitleCache
<TaxonBase
>> getUuidAndTitleCacheSynonym(Integer limit
, String pattern
){
2003 return getUuidAndTitleCache(limit
, pattern
, false);
2007 public List
<UuidAndTitleCache
<TaxonBase
>> getUuidAndTitleCacheTaxon(Integer limit
, String pattern
){
2009 return getUuidAndTitleCache(limit
, pattern
, true);
2012 private String
[] createHQLString(boolean doTaxa
, boolean doSynonyms
, boolean doIncludeMisappliedNames
, Classification classification
, Set
<NamedArea
> areasExpanded
, MatchMode matchMode
, String searchField
){
2014 boolean doAreaRestriction
= areasExpanded
.size() > 0;
2015 String doAreaRestrictionSubSelect
= "select %s.id from" +
2017 " join e.inDescription d" +
2019 (classification
!= null ?
" join t.taxonNodes as tn " : " ");
2021 String doAreaRestrictionMisappliedNameSubSelect
= "select %s.id from" +
2023 " join e.inDescription d" +
2026 String doTaxonSubSelect
= "select %s.id from Taxon t " + (classification
!= null ?
" join t.taxonNodes as tn " : " ");
2027 String doTaxonMisappliedNameSubSelect
= "select %s.id from Taxon t ";
2029 String doTaxonNameJoin
= " join t.name n ";
2031 String doSynonymNameJoin
= " join t.synonymRelations sr join sr.relatedFrom s join s.name sn";
2033 String doMisappliedNamesJoin
= " left join t.relationsFromThisTaxon as rft" +
2034 " left join rft.relatedTo as rt" +
2035 (classification
!= null ?
" left join rt.taxonNodes as tn2" : " ") +
2036 " left join rt.name as n2" +
2037 " left join rft.type as rtype";
2039 String doClassificationWhere
= " tn.classification = :classification";
2040 String doClassificationForMisappliedNamesWhere
= " tn2 .classification = :classification";
2042 String doAreaRestrictionWhere
= " e.area.uuid in (:namedAreasUuids)";
2044 String doSearchFieldWhere
= "%s." + searchField
+ " " + matchMode
.getMatchOperator() + " :queryString";
2046 String doRelationshipTypeComparison
= " rtype = :rType ";
2048 String taxonSubselect
= null;
2049 String synonymSubselect
= null;
2050 String misappliedSelect
= null;
2052 if(classification
!= null ){
2053 if (!doIncludeMisappliedNames
){
2054 if(doAreaRestriction
){
2055 taxonSubselect
= String
.format(doAreaRestrictionSubSelect
, "t") + doTaxonNameJoin
+
2056 " WHERE " + doAreaRestrictionWhere
+
2057 " AND " + doClassificationWhere
+
2058 " AND " + String
.format(doSearchFieldWhere
, "n");
2059 synonymSubselect
= String
.format(doAreaRestrictionSubSelect
, "s") + doSynonymNameJoin
+
2060 " WHERE " + doAreaRestrictionWhere
+
2061 " AND " + doClassificationWhere
+
2062 " AND " + String
.format(doSearchFieldWhere
, "sn");
2064 taxonSubselect
= String
.format(doTaxonSubSelect
, "t" )+ doTaxonNameJoin
+
2065 " WHERE " + doClassificationWhere
+
2066 " AND " + String
.format(doSearchFieldWhere
, "n");
2067 synonymSubselect
= String
.format(doTaxonSubSelect
, "s" ) + doSynonymNameJoin
+
2068 " WHERE " + doClassificationWhere
+
2069 " AND " + String
.format(doSearchFieldWhere
, "sn");
2071 }else{ //misappliedNames included
2072 if(doAreaRestriction
){
2073 misappliedSelect
= String
.format(doAreaRestrictionMisappliedNameSubSelect
, "t") + doTaxonNameJoin
+ doMisappliedNamesJoin
+
2074 " WHERE " + doAreaRestrictionWhere
+
2075 " AND " + String
.format(doSearchFieldWhere
, "n") +
2076 " AND " + doClassificationForMisappliedNamesWhere
+
2077 " AND " + doRelationshipTypeComparison
;
2079 taxonSubselect
= String
.format(doAreaRestrictionSubSelect
, "t") + doTaxonNameJoin
+
2080 " WHERE " + doAreaRestrictionWhere
+
2081 " AND "+ String
.format(doSearchFieldWhere
, "n") + " AND "+ doClassificationWhere
;
2083 synonymSubselect
= String
.format(doAreaRestrictionSubSelect
, "s") + doSynonymNameJoin
+
2084 " WHERE " + doAreaRestrictionWhere
+
2085 " AND " + doClassificationWhere
+ " AND " + String
.format(doSearchFieldWhere
, "sn");;
2088 misappliedSelect
= String
.format(doTaxonMisappliedNameSubSelect
, "t" ) + doTaxonNameJoin
+ doMisappliedNamesJoin
+
2089 " WHERE " + String
.format(doSearchFieldWhere
, "n") +
2090 " AND " + doClassificationForMisappliedNamesWhere
+
2091 " AND " + doRelationshipTypeComparison
;
2093 taxonSubselect
= String
.format(doTaxonSubSelect
, "t" ) + doTaxonNameJoin
+
2094 " WHERE " + String
.format(doSearchFieldWhere
, "n") +
2095 " AND "+ doClassificationWhere
;
2097 synonymSubselect
= String
.format(doTaxonSubSelect
, "s" ) + doSynonymNameJoin
+
2098 " WHERE " + doClassificationWhere
+
2099 " AND " + String
.format(doSearchFieldWhere
, "sn");
2104 if(doAreaRestriction
){
2105 misappliedSelect
= String
.format(doAreaRestrictionMisappliedNameSubSelect
, "t") + doTaxonNameJoin
+ doMisappliedNamesJoin
+
2106 " WHERE " + doAreaRestrictionWhere
+
2107 " AND " + String
.format(doSearchFieldWhere
, "n")+
2108 " AND " + doRelationshipTypeComparison
;
2110 taxonSubselect
= String
.format(doAreaRestrictionSubSelect
, "t") + doTaxonNameJoin
+
2111 " WHERE " + doAreaRestrictionWhere
+
2112 " AND " + String
.format(doSearchFieldWhere
, "n");
2114 synonymSubselect
= String
.format(doAreaRestrictionSubSelect
, "s") + doSynonymNameJoin
+
2115 " WHERE " + doAreaRestrictionWhere
+
2116 " AND " + String
.format(doSearchFieldWhere
, "sn");
2120 misappliedSelect
= String
.format(doTaxonMisappliedNameSubSelect
, "t" ) + doTaxonNameJoin
+ doMisappliedNamesJoin
+ " WHERE " + String
.format(doSearchFieldWhere
, "n") + " AND " + doRelationshipTypeComparison
;
2121 taxonSubselect
= String
.format(doTaxonSubSelect
, "t" ) + doTaxonNameJoin
+ " WHERE " + String
.format(doSearchFieldWhere
, "n");
2122 synonymSubselect
= String
.format(doTaxonSubSelect
, "s" ) + doSynonymNameJoin
+ " WHERE " + String
.format(doSearchFieldWhere
, "sn");
2126 String
[] result
= {misappliedSelect
, taxonSubselect
, synonymSubselect
};
2132 public List
<UuidAndTitleCache
<IdentifiableEntity
>> getTaxaByCommonNameForEditor(
2133 String titleSearchStringSqlized
, Classification classification
,
2134 MatchMode matchMode
, Set namedAreas
) {
2135 List
<Object
> resultArray
= new ArrayList
<Object
>();
2136 Query query
= prepareTaxaByCommonName(titleSearchStringSqlized
, classification
, matchMode
, namedAreas
, null, null, false, true);
2138 resultArray
= query
.list();
2139 List
<UuidAndTitleCache
<IdentifiableEntity
>> returnResult
= new ArrayList
<UuidAndTitleCache
<IdentifiableEntity
>>() ;
2141 for(int i
= 0; i
<resultArray
.size();i
++){
2142 result
= (Object
[]) resultArray
.get(i
);
2143 returnResult
.add(new UuidAndTitleCache(Taxon
.class, (UUID
) result
[0],(Integer
)result
[1], (String
)result
[2], new Boolean(result
[4].toString())));
2145 return returnResult
;
2154 * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#countByIdentifier(java.lang.Class, java.lang.String, eu.etaxonomy.cdm.model.common.DefinedTerm, eu.etaxonomy.cdm.model.taxon.TaxonNode, eu.etaxonomy.cdm.persistence.query.MatchMode)
2157 public <S
extends TaxonBase
> int countByIdentifier(Class
<S
> clazz
,
2158 String identifier
, DefinedTerm identifierType
, TaxonNode subtreeFilter
, MatchMode matchmode
) {
2159 if (subtreeFilter
== null){
2160 return countByIdentifier(clazz
, identifier
, identifierType
, matchmode
);
2163 Class
<?
> clazzParam
= clazz
== null ? type
: clazz
;
2164 checkNotInPriorView("IdentifiableDaoBase.countByIdentifier(T clazz, String identifier, DefinedTerm identifierType, TaxonNode subMatchMode matchmode)");
2166 boolean isTaxon
= clazzParam
== Taxon
.class || clazzParam
== TaxonBase
.class;
2167 boolean isSynonym
= clazzParam
== Synonym
.class || clazzParam
== TaxonBase
.class;
2169 getSession().update(subtreeFilter
); //to avoid LIE when retrieving treeindex
2170 String filterStr
= "'" + subtreeFilter
.treeIndex() + "%%'";
2171 String accTreeJoin
= isTaxon?
" LEFT JOIN c.taxonNodes tn " : "";
2172 String synTreeJoin
= isSynonym ?
" LEFT JOIN c.synonymRelations sr LEFT JOIN sr.relatedTo as acc LEFT JOIN acc.taxonNodes synTn " : "";
2173 String accWhere
= isTaxon ?
"tn.treeIndex like " + filterStr
: "(1=0)";
2174 String synWhere
= isSynonym ?
"synTn.treeIndex like " + filterStr
: "(1=0)";
2176 String queryString
= "SELECT count(*) FROM %s as c " +
2177 " INNER JOIN c.identifiers as ids " +
2181 " AND ( " + accWhere
+ " OR " + synWhere
+ ")";
2182 queryString
= String
.format(queryString
, clazzParam
.getSimpleName());
2184 if (identifier
!= null){
2185 if (matchmode
== null || matchmode
== MatchMode
.EXACT
){
2186 queryString
+= " AND ids.identifier = '" + identifier
+ "'";
2188 queryString
+= " AND ids.identifier LIKE '" + matchmode
.queryStringFrom(identifier
) + "'";
2191 if (identifierType
!= null){
2192 queryString
+= " AND ids.type = :type";
2195 Query query
= getSession().createQuery(queryString
);
2196 if (identifierType
!= null){
2197 query
.setEntity("type", identifierType
);
2200 Long c
= (Long
)query
.uniqueResult();
2201 return c
.intValue();
2205 public <S
extends TaxonBase
> List
<Object
[]> findByIdentifier(
2206 Class
<S
> clazz
, String identifier
, DefinedTerm identifierType
, TaxonNode subtreeFilter
,
2207 MatchMode matchmode
, boolean includeEntity
,
2208 Integer pageSize
, Integer pageNumber
, List
<String
> propertyPaths
) {
2210 checkNotInPriorView("IdentifiableDaoBase.findByIdentifier(T clazz, String identifier, DefinedTerm identifierType, MatchMode matchmode, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths)");
2211 Class
<?
> clazzParam
= clazz
== null ? type
: clazz
;
2213 boolean isTaxon
= clazzParam
== Taxon
.class || clazzParam
== TaxonBase
.class;
2214 boolean isSynonym
= clazzParam
== Synonym
.class || clazzParam
== TaxonBase
.class;
2215 getSession().update(subtreeFilter
); //to avoid LIE when retrieving treeindex
2216 String filterStr
= "'" + subtreeFilter
.treeIndex() + "%%'";
2217 String accTreeJoin
= isTaxon?
" LEFT JOIN c.taxonNodes tn " : "";
2218 String synTreeJoin
= isSynonym ?
" LEFT JOIN c.synonymRelations sr LEFT JOIN sr.relatedTo as acc LEFT JOIN acc.taxonNodes synTn " : "";
2219 String accWhere
= isTaxon ?
"tn.treeIndex like " + filterStr
: "(1=0)";
2220 String synWhere
= isSynonym ?
"synTn.treeIndex like " + filterStr
: "(1=0)";
2222 String queryString
= "SELECT ids.type, ids.identifier, %s " +
2224 " INNER JOIN c.identifiers as ids " +
2228 " AND ( " + accWhere
+ " OR " + synWhere
+ ")";
2229 queryString
= String
.format(queryString
, (includeEntity ?
"c":"c.uuid, c.titleCache") , clazzParam
.getSimpleName());
2231 //Matchmode and identifier
2232 if (identifier
!= null){
2233 if (matchmode
== null || matchmode
== MatchMode
.EXACT
){
2234 queryString
+= " AND ids.identifier = '" + identifier
+ "'";
2236 queryString
+= " AND ids.identifier LIKE '" + matchmode
.queryStringFrom(identifier
) + "'";
2239 if (identifierType
!= null){
2240 queryString
+= " AND ids.type = :type";
2243 queryString
+=" ORDER BY ids.type.uuid, ids.identifier, c.uuid ";
2245 Query query
= getSession().createQuery(queryString
);
2248 if (identifierType
!= null){
2249 query
.setEntity("type", identifierType
);
2253 setPagingParameter(query
, pageSize
, pageNumber
);
2255 List
<Object
[]> results
= query
.list();
2258 List
<S
> entities
= new ArrayList
<S
>();
2259 for (Object
[] result
: results
){
2260 entities
.add((S
)result
[2]);
2262 defaultBeanInitializer
.initializeAll(entities
, propertyPaths
);